LLVM 19.0.0git
PassBuilder.cpp
Go to the documentation of this file.
1//===- Parsing and selection of pass pipelines ----------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8/// \file
9///
10/// This file provides the implementation of the PassBuilder based on our
11/// static pass registry as well as related functionality. It also provides
12/// helpers to aid in analyzing, debugging, and testing passes and pass
13/// pipelines.
14///
15//===----------------------------------------------------------------------===//
16
32#include "llvm/Analysis/DDG.h"
48#include "llvm/Analysis/Lint.h"
107#include "llvm/IR/DebugInfo.h"
108#include "llvm/IR/Dominators.h"
109#include "llvm/IR/PassManager.h"
110#include "llvm/IR/PrintPasses.h"
112#include "llvm/IR/Verifier.h"
116#include "llvm/Support/Debug.h"
119#include "llvm/Support/Regex.h"
301#include <optional>
302
303using namespace llvm;
304
306 "^(default|thinlto-pre-link|thinlto|lto-pre-link|lto)<(O[0123sz])>$");
307
308namespace llvm {
310 "print-pipeline-passes",
311 cl::desc("Print a '-passes' compatible string describing the pipeline "
312 "(best-effort only)."));
313} // namespace llvm
314
315AnalysisKey NoOpModuleAnalysis::Key;
316AnalysisKey NoOpCGSCCAnalysis::Key;
317AnalysisKey NoOpFunctionAnalysis::Key;
318AnalysisKey NoOpLoopAnalysis::Key;
319
320namespace {
321
322/// Whether or not we should populate a PassInstrumentationCallbacks's class to
323/// pass name map.
324///
325/// This is for optimization purposes so we don't populate it if we never use
326/// it. This should be updated if new pass instrumentation wants to use the map.
327/// We currently only use this for --print-before/after.
328bool shouldPopulateClassToPassNames() {
329 return PrintPipelinePasses || !printBeforePasses().empty() ||
330 !printAfterPasses().empty() || !isFilterPassesEmpty() ||
332}
333
334// A pass for testing -print-on-crash.
335// DO NOT USE THIS EXCEPT FOR TESTING!
336class TriggerCrashPass : public PassInfoMixin<TriggerCrashPass> {
337public:
339 abort();
340 return PreservedAnalyses::all();
341 }
342 static StringRef name() { return "TriggerCrashPass"; }
343};
344
345// A pass for testing message reporting of -verify-each failures.
346// DO NOT USE THIS EXCEPT FOR TESTING!
347class TriggerVerifierErrorPass
348 : public PassInfoMixin<TriggerVerifierErrorPass> {
349public:
351 // Intentionally break the Module by creating an alias without setting the
352 // aliasee.
353 auto *PtrTy = llvm::PointerType::getUnqual(M.getContext());
354 GlobalAlias::create(PtrTy, PtrTy->getAddressSpace(),
355 GlobalValue::LinkageTypes::InternalLinkage,
356 "__bad_alias", nullptr, &M);
358 }
359
361 // Intentionally break the Function by inserting a terminator
362 // instruction in the middle of a basic block.
363 BasicBlock &BB = F.getEntryBlock();
364 new UnreachableInst(F.getContext(), BB.getTerminator()->getIterator());
366 }
367
369 // Intentionally create a virtual register and set NoVRegs property.
370 auto &MRI = MF.getRegInfo();
371 MRI.createGenericVirtualRegister(LLT::scalar(8));
372 MF.getProperties().set(MachineFunctionProperties::Property::NoVRegs);
373 return PreservedAnalyses::all();
374 }
375
376 static StringRef name() { return "TriggerVerifierErrorPass"; }
377};
378
379// A pass requires all MachineFunctionProperties.
380// DO NOT USE THIS EXCEPT FOR TESTING!
381class RequireAllMachineFunctionPropertiesPass
382 : public PassInfoMixin<RequireAllMachineFunctionPropertiesPass> {
383public:
386 }
387
388 static MachineFunctionProperties getRequiredProperties() {
390 MFProps.set(MachineFunctionProperties::Property::FailedISel);
391 MFProps.set(MachineFunctionProperties::Property::FailsVerification);
392 MFProps.set(MachineFunctionProperties::Property::IsSSA);
393 MFProps.set(MachineFunctionProperties::Property::Legalized);
394 MFProps.set(MachineFunctionProperties::Property::NoPHIs);
395 MFProps.set(MachineFunctionProperties::Property::NoVRegs);
396 MFProps.set(MachineFunctionProperties::Property::RegBankSelected);
397 MFProps.set(MachineFunctionProperties::Property::Selected);
398 MFProps.set(MachineFunctionProperties::Property::TiedOpsRewritten);
399 MFProps.set(MachineFunctionProperties::Property::TracksDebugUserValues);
400 MFProps.set(MachineFunctionProperties::Property::TracksLiveness);
401 return MFProps;
402 }
403 static StringRef name() { return "RequireAllMachineFunctionPropertiesPass"; }
404};
405
406} // namespace
407
409 std::optional<PGOOptions> PGOOpt,
411 : TM(TM), PTO(PTO), PGOOpt(PGOOpt), PIC(PIC) {
412 bool ShouldPopulateClassToPassNames = PIC && shouldPopulateClassToPassNames();
413 if (TM)
414 TM->registerPassBuilderCallbacks(*this, ShouldPopulateClassToPassNames);
415 if (ShouldPopulateClassToPassNames) {
416#define MODULE_PASS(NAME, CREATE_PASS) \
417 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
418#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
419 PIC->addClassToPassName(CLASS, NAME);
420#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
421 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
422#define FUNCTION_PASS(NAME, CREATE_PASS) \
423 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
424#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
425 PIC->addClassToPassName(CLASS, NAME);
426#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
427 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
428#define LOOPNEST_PASS(NAME, CREATE_PASS) \
429 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
430#define LOOP_PASS(NAME, CREATE_PASS) \
431 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
432#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
433 PIC->addClassToPassName(CLASS, NAME);
434#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
435 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
436#define CGSCC_PASS(NAME, CREATE_PASS) \
437 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
438#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
439 PIC->addClassToPassName(CLASS, NAME);
440#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
441 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
442#include "PassRegistry.def"
443
444#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
445 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
446#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
447 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
448#include "llvm/Passes/MachinePassRegistry.def"
449 }
450}
451
453#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
454 MAM.registerPass([&] { return CREATE_PASS; });
455#include "PassRegistry.def"
456
457 for (auto &C : ModuleAnalysisRegistrationCallbacks)
458 C(MAM);
459}
460
462#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
463 CGAM.registerPass([&] { return CREATE_PASS; });
464#include "PassRegistry.def"
465
466 for (auto &C : CGSCCAnalysisRegistrationCallbacks)
467 C(CGAM);
468}
469
471 // We almost always want the default alias analysis pipeline.
472 // If a user wants a different one, they can register their own before calling
473 // registerFunctionAnalyses().
474 FAM.registerPass([&] { return buildDefaultAAPipeline(); });
475
476#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
477 FAM.registerPass([&] { return CREATE_PASS; });
478#include "PassRegistry.def"
479
480 for (auto &C : FunctionAnalysisRegistrationCallbacks)
481 C(FAM);
482}
483
486
487#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
488 MFAM.registerPass([&] { return CREATE_PASS; });
489#include "llvm/Passes/MachinePassRegistry.def"
490
491 for (auto &C : MachineFunctionAnalysisRegistrationCallbacks)
492 C(MFAM);
493}
494
496#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
497 LAM.registerPass([&] { return CREATE_PASS; });
498#include "PassRegistry.def"
499
500 for (auto &C : LoopAnalysisRegistrationCallbacks)
501 C(LAM);
502}
503
504static std::optional<int> parseRepeatPassName(StringRef Name) {
505 if (!Name.consume_front("repeat<") || !Name.consume_back(">"))
506 return std::nullopt;
507 int Count;
508 if (Name.getAsInteger(0, Count) || Count <= 0)
509 return std::nullopt;
510 return Count;
511}
512
513static std::optional<std::pair<bool, bool>>
515 std::pair<bool, bool> Params;
516 if (!Name.consume_front("function"))
517 return std::nullopt;
518 if (Name.empty())
519 return Params;
520 if (!Name.consume_front("<") || !Name.consume_back(">"))
521 return std::nullopt;
522 while (!Name.empty()) {
523 auto [Front, Back] = Name.split(';');
524 Name = Back;
525 if (Front == "eager-inv")
526 Params.first = true;
527 else if (Front == "no-rerun")
528 Params.second = true;
529 else
530 return std::nullopt;
531 }
532 return Params;
533}
534
535static std::optional<int> parseDevirtPassName(StringRef Name) {
536 if (!Name.consume_front("devirt<") || !Name.consume_back(">"))
537 return std::nullopt;
538 int Count;
539 if (Name.getAsInteger(0, Count) || Count < 0)
540 return std::nullopt;
541 return Count;
542}
543
544static std::optional<OptimizationLevel> parseOptLevel(StringRef S) {
546 .Case("O0", OptimizationLevel::O0)
552 .Default(std::nullopt);
553}
554
556 StringRef OptionName,
558 bool Result = false;
559 while (!Params.empty()) {
560 StringRef ParamName;
561 std::tie(ParamName, Params) = Params.split(';');
562
563 if (ParamName == OptionName) {
564 Result = true;
565 } else {
566 return make_error<StringError>(
567 formatv("invalid {1} pass parameter '{0}' ", ParamName, PassName)
568 .str(),
570 }
571 }
572 return Result;
573}
574
575namespace {
576
577/// Parser of parameters for HardwareLoops pass.
578Expected<HardwareLoopOptions> parseHardwareLoopOptions(StringRef Params) {
579 HardwareLoopOptions HardwareLoopOpts;
580
581 while (!Params.empty()) {
582 StringRef ParamName;
583 std::tie(ParamName, Params) = Params.split(';');
584 if (ParamName.consume_front("hardware-loop-decrement=")) {
585 int Count;
586 if (ParamName.getAsInteger(0, Count))
587 return make_error<StringError>(
588 formatv("invalid HardwareLoopPass parameter '{0}' ", ParamName).str(),
590 HardwareLoopOpts.setDecrement(Count);
591 continue;
592 }
593 if (ParamName.consume_front("hardware-loop-counter-bitwidth=")) {
594 int Count;
595 if (ParamName.getAsInteger(0, Count))
596 return make_error<StringError>(
597 formatv("invalid HardwareLoopPass parameter '{0}' ", ParamName).str(),
599 HardwareLoopOpts.setCounterBitwidth(Count);
600 continue;
601 }
602 if (ParamName == "force-hardware-loops") {
603 HardwareLoopOpts.setForce(true);
604 } else if (ParamName == "force-hardware-loop-phi") {
605 HardwareLoopOpts.setForcePhi(true);
606 } else if (ParamName == "force-nested-hardware-loop") {
607 HardwareLoopOpts.setForceNested(true);
608 } else if (ParamName == "force-hardware-loop-guard") {
609 HardwareLoopOpts.setForceGuard(true);
610 } else {
611 return make_error<StringError>(
612 formatv("invalid HardwarePass parameter '{0}' ", ParamName).str(),
614 }
615 }
616 return HardwareLoopOpts;
617}
618
619/// Parser of parameters for LoopUnroll pass.
620Expected<LoopUnrollOptions> parseLoopUnrollOptions(StringRef Params) {
621 LoopUnrollOptions UnrollOpts;
622 while (!Params.empty()) {
623 StringRef ParamName;
624 std::tie(ParamName, Params) = Params.split(';');
625 std::optional<OptimizationLevel> OptLevel = parseOptLevel(ParamName);
626 // Don't accept -Os/-Oz.
627 if (OptLevel && !OptLevel->isOptimizingForSize()) {
628 UnrollOpts.setOptLevel(OptLevel->getSpeedupLevel());
629 continue;
630 }
631 if (ParamName.consume_front("full-unroll-max=")) {
632 int Count;
633 if (ParamName.getAsInteger(0, Count))
634 return make_error<StringError>(
635 formatv("invalid LoopUnrollPass parameter '{0}' ", ParamName).str(),
637 UnrollOpts.setFullUnrollMaxCount(Count);
638 continue;
639 }
640
641 bool Enable = !ParamName.consume_front("no-");
642 if (ParamName == "partial") {
643 UnrollOpts.setPartial(Enable);
644 } else if (ParamName == "peeling") {
645 UnrollOpts.setPeeling(Enable);
646 } else if (ParamName == "profile-peeling") {
647 UnrollOpts.setProfileBasedPeeling(Enable);
648 } else if (ParamName == "runtime") {
649 UnrollOpts.setRuntime(Enable);
650 } else if (ParamName == "upperbound") {
651 UnrollOpts.setUpperBound(Enable);
652 } else {
653 return make_error<StringError>(
654 formatv("invalid LoopUnrollPass parameter '{0}' ", ParamName).str(),
656 }
657 }
658 return UnrollOpts;
659}
660
661Expected<bool> parseGlobalDCEPassOptions(StringRef Params) {
663 Params, "vfe-linkage-unit-visibility", "GlobalDCE");
664}
665
666Expected<bool> parseCGProfilePassOptions(StringRef Params) {
667 return PassBuilder::parseSinglePassOption(Params, "in-lto-post-link",
668 "CGProfile");
669}
670
671Expected<bool> parseInlinerPassOptions(StringRef Params) {
672 return PassBuilder::parseSinglePassOption(Params, "only-mandatory",
673 "InlinerPass");
674}
675
676Expected<bool> parseCoroSplitPassOptions(StringRef Params) {
677 return PassBuilder::parseSinglePassOption(Params, "reuse-storage",
678 "CoroSplitPass");
679}
680
681Expected<bool> parsePostOrderFunctionAttrsPassOptions(StringRef Params) {
683 Params, "skip-non-recursive-function-attrs", "PostOrderFunctionAttrs");
684}
685
686Expected<CFGuardPass::Mechanism> parseCFGuardPassOptions(StringRef Params) {
687 if (Params.empty())
689
690 auto [Param, RHS] = Params.split(';');
691 if (!RHS.empty())
692 return make_error<StringError>(
693 formatv("too many CFGuardPass parameters '{0}' ", Params).str(),
695
696 if (Param == "check")
698 if (Param == "dispatch")
700
701 return make_error<StringError>(
702 formatv("invalid CFGuardPass mechanism: '{0}' ", Param).str(),
704}
705
706Expected<bool> parseEarlyCSEPassOptions(StringRef Params) {
707 return PassBuilder::parseSinglePassOption(Params, "memssa", "EarlyCSE");
708}
709
710Expected<bool> parseEntryExitInstrumenterPassOptions(StringRef Params) {
711 return PassBuilder::parseSinglePassOption(Params, "post-inline",
712 "EntryExitInstrumenter");
713}
714
715Expected<bool> parseLoopExtractorPassOptions(StringRef Params) {
716 return PassBuilder::parseSinglePassOption(Params, "single", "LoopExtractor");
717}
718
719Expected<bool> parseLowerMatrixIntrinsicsPassOptions(StringRef Params) {
720 return PassBuilder::parseSinglePassOption(Params, "minimal",
721 "LowerMatrixIntrinsics");
722}
723
724Expected<AddressSanitizerOptions> parseASanPassOptions(StringRef Params) {
726 while (!Params.empty()) {
727 StringRef ParamName;
728 std::tie(ParamName, Params) = Params.split(';');
729
730 if (ParamName == "kernel") {
731 Result.CompileKernel = true;
732 } else {
733 return make_error<StringError>(
734 formatv("invalid AddressSanitizer pass parameter '{0}' ", ParamName)
735 .str(),
737 }
738 }
739 return Result;
740}
741
742Expected<HWAddressSanitizerOptions> parseHWASanPassOptions(StringRef Params) {
744 while (!Params.empty()) {
745 StringRef ParamName;
746 std::tie(ParamName, Params) = Params.split(';');
747
748 if (ParamName == "recover") {
749 Result.Recover = true;
750 } else if (ParamName == "kernel") {
751 Result.CompileKernel = true;
752 } else {
753 return make_error<StringError>(
754 formatv("invalid HWAddressSanitizer pass parameter '{0}' ", ParamName)
755 .str(),
757 }
758 }
759 return Result;
760}
761
762Expected<EmbedBitcodeOptions> parseEmbedBitcodePassOptions(StringRef Params) {
764 while (!Params.empty()) {
765 StringRef ParamName;
766 std::tie(ParamName, Params) = Params.split(';');
767
768 if (ParamName == "thinlto") {
769 Result.IsThinLTO = true;
770 } else if (ParamName == "emit-summary") {
771 Result.EmitLTOSummary = true;
772 } else {
773 return make_error<StringError>(
774 formatv("invalid EmbedBitcode pass parameter '{0}' ", ParamName)
775 .str(),
777 }
778 }
779 return Result;
780}
781
782Expected<MemorySanitizerOptions> parseMSanPassOptions(StringRef Params) {
784 while (!Params.empty()) {
785 StringRef ParamName;
786 std::tie(ParamName, Params) = Params.split(';');
787
788 if (ParamName == "recover") {
789 Result.Recover = true;
790 } else if (ParamName == "kernel") {
791 Result.Kernel = true;
792 } else if (ParamName.consume_front("track-origins=")) {
793 if (ParamName.getAsInteger(0, Result.TrackOrigins))
794 return make_error<StringError>(
795 formatv("invalid argument to MemorySanitizer pass track-origins "
796 "parameter: '{0}' ",
797 ParamName)
798 .str(),
800 } else if (ParamName == "eager-checks") {
801 Result.EagerChecks = true;
802 } else {
803 return make_error<StringError>(
804 formatv("invalid MemorySanitizer pass parameter '{0}' ", ParamName)
805 .str(),
807 }
808 }
809 return Result;
810}
811
812/// Parser of parameters for SimplifyCFG pass.
813Expected<SimplifyCFGOptions> parseSimplifyCFGOptions(StringRef Params) {
815 while (!Params.empty()) {
816 StringRef ParamName;
817 std::tie(ParamName, Params) = Params.split(';');
818
819 bool Enable = !ParamName.consume_front("no-");
820 if (ParamName == "speculate-blocks") {
821 Result.speculateBlocks(Enable);
822 } else if (ParamName == "simplify-cond-branch") {
823 Result.setSimplifyCondBranch(Enable);
824 } else if (ParamName == "forward-switch-cond") {
825 Result.forwardSwitchCondToPhi(Enable);
826 } else if (ParamName == "switch-range-to-icmp") {
827 Result.convertSwitchRangeToICmp(Enable);
828 } else if (ParamName == "switch-to-lookup") {
829 Result.convertSwitchToLookupTable(Enable);
830 } else if (ParamName == "keep-loops") {
831 Result.needCanonicalLoops(Enable);
832 } else if (ParamName == "hoist-common-insts") {
833 Result.hoistCommonInsts(Enable);
834 } else if (ParamName == "sink-common-insts") {
835 Result.sinkCommonInsts(Enable);
836 } else if (Enable && ParamName.consume_front("bonus-inst-threshold=")) {
837 APInt BonusInstThreshold;
838 if (ParamName.getAsInteger(0, BonusInstThreshold))
839 return make_error<StringError>(
840 formatv("invalid argument to SimplifyCFG pass bonus-threshold "
841 "parameter: '{0}' ",
842 ParamName).str(),
844 Result.bonusInstThreshold(BonusInstThreshold.getSExtValue());
845 } else {
846 return make_error<StringError>(
847 formatv("invalid SimplifyCFG pass parameter '{0}' ", ParamName).str(),
849 }
850 }
851 return Result;
852}
853
854Expected<InstCombineOptions> parseInstCombineOptions(StringRef Params) {
856 // When specifying "instcombine" in -passes enable fix-point verification by
857 // default, as this is what most tests should use.
858 Result.setVerifyFixpoint(true);
859 while (!Params.empty()) {
860 StringRef ParamName;
861 std::tie(ParamName, Params) = Params.split(';');
862
863 bool Enable = !ParamName.consume_front("no-");
864 if (ParamName == "use-loop-info") {
865 Result.setUseLoopInfo(Enable);
866 } else if (ParamName == "verify-fixpoint") {
867 Result.setVerifyFixpoint(Enable);
868 } else if (Enable && ParamName.consume_front("max-iterations=")) {
869 APInt MaxIterations;
870 if (ParamName.getAsInteger(0, MaxIterations))
871 return make_error<StringError>(
872 formatv("invalid argument to InstCombine pass max-iterations "
873 "parameter: '{0}' ",
874 ParamName).str(),
876 Result.setMaxIterations((unsigned)MaxIterations.getZExtValue());
877 } else {
878 return make_error<StringError>(
879 formatv("invalid InstCombine pass parameter '{0}' ", ParamName).str(),
881 }
882 }
883 return Result;
884}
885
886/// Parser of parameters for LoopVectorize pass.
887Expected<LoopVectorizeOptions> parseLoopVectorizeOptions(StringRef Params) {
889 while (!Params.empty()) {
890 StringRef ParamName;
891 std::tie(ParamName, Params) = Params.split(';');
892
893 bool Enable = !ParamName.consume_front("no-");
894 if (ParamName == "interleave-forced-only") {
896 } else if (ParamName == "vectorize-forced-only") {
898 } else {
899 return make_error<StringError>(
900 formatv("invalid LoopVectorize parameter '{0}' ", ParamName).str(),
902 }
903 }
904 return Opts;
905}
906
907Expected<std::pair<bool, bool>> parseLoopUnswitchOptions(StringRef Params) {
908 std::pair<bool, bool> Result = {false, true};
909 while (!Params.empty()) {
910 StringRef ParamName;
911 std::tie(ParamName, Params) = Params.split(';');
912
913 bool Enable = !ParamName.consume_front("no-");
914 if (ParamName == "nontrivial") {
915 Result.first = Enable;
916 } else if (ParamName == "trivial") {
917 Result.second = Enable;
918 } else {
919 return make_error<StringError>(
920 formatv("invalid LoopUnswitch pass parameter '{0}' ", ParamName)
921 .str(),
923 }
924 }
925 return Result;
926}
927
928Expected<LICMOptions> parseLICMOptions(StringRef Params) {
930 while (!Params.empty()) {
931 StringRef ParamName;
932 std::tie(ParamName, Params) = Params.split(';');
933
934 bool Enable = !ParamName.consume_front("no-");
935 if (ParamName == "allowspeculation") {
936 Result.AllowSpeculation = Enable;
937 } else {
938 return make_error<StringError>(
939 formatv("invalid LICM pass parameter '{0}' ", ParamName).str(),
941 }
942 }
943 return Result;
944}
945
946Expected<std::pair<bool, bool>> parseLoopRotateOptions(StringRef Params) {
947 std::pair<bool, bool> Result = {true, false};
948 while (!Params.empty()) {
949 StringRef ParamName;
950 std::tie(ParamName, Params) = Params.split(';');
951
952 bool Enable = !ParamName.consume_front("no-");
953 if (ParamName == "header-duplication") {
954 Result.first = Enable;
955 } else if (ParamName == "prepare-for-lto") {
956 Result.second = Enable;
957 } else {
958 return make_error<StringError>(
959 formatv("invalid LoopRotate pass parameter '{0}' ", ParamName).str(),
961 }
962 }
963 return Result;
964}
965
966Expected<bool> parseMergedLoadStoreMotionOptions(StringRef Params) {
967 bool Result = false;
968 while (!Params.empty()) {
969 StringRef ParamName;
970 std::tie(ParamName, Params) = Params.split(';');
971
972 bool Enable = !ParamName.consume_front("no-");
973 if (ParamName == "split-footer-bb") {
974 Result = Enable;
975 } else {
976 return make_error<StringError>(
977 formatv("invalid MergedLoadStoreMotion pass parameter '{0}' ",
978 ParamName)
979 .str(),
981 }
982 }
983 return Result;
984}
985
986Expected<GVNOptions> parseGVNOptions(StringRef Params) {
988 while (!Params.empty()) {
989 StringRef ParamName;
990 std::tie(ParamName, Params) = Params.split(';');
991
992 bool Enable = !ParamName.consume_front("no-");
993 if (ParamName == "pre") {
994 Result.setPRE(Enable);
995 } else if (ParamName == "load-pre") {
996 Result.setLoadPRE(Enable);
997 } else if (ParamName == "split-backedge-load-pre") {
998 Result.setLoadPRESplitBackedge(Enable);
999 } else if (ParamName == "memdep") {
1000 Result.setMemDep(Enable);
1001 } else {
1002 return make_error<StringError>(
1003 formatv("invalid GVN pass parameter '{0}' ", ParamName).str(),
1005 }
1006 }
1007 return Result;
1008}
1009
1010Expected<IPSCCPOptions> parseIPSCCPOptions(StringRef Params) {
1012 while (!Params.empty()) {
1013 StringRef ParamName;
1014 std::tie(ParamName, Params) = Params.split(';');
1015
1016 bool Enable = !ParamName.consume_front("no-");
1017 if (ParamName == "func-spec")
1018 Result.setFuncSpec(Enable);
1019 else
1020 return make_error<StringError>(
1021 formatv("invalid IPSCCP pass parameter '{0}' ", ParamName).str(),
1023 }
1024 return Result;
1025}
1026
1027Expected<SROAOptions> parseSROAOptions(StringRef Params) {
1028 if (Params.empty() || Params == "modify-cfg")
1030 if (Params == "preserve-cfg")
1032 return make_error<StringError>(
1033 formatv("invalid SROA pass parameter '{0}' (either preserve-cfg or "
1034 "modify-cfg can be specified)",
1035 Params)
1036 .str(),
1038}
1039
1041parseStackLifetimeOptions(StringRef Params) {
1043 while (!Params.empty()) {
1044 StringRef ParamName;
1045 std::tie(ParamName, Params) = Params.split(';');
1046
1047 if (ParamName == "may") {
1049 } else if (ParamName == "must") {
1051 } else {
1052 return make_error<StringError>(
1053 formatv("invalid StackLifetime parameter '{0}' ", ParamName).str(),
1055 }
1056 }
1057 return Result;
1058}
1059
1060Expected<bool> parseDependenceAnalysisPrinterOptions(StringRef Params) {
1061 return PassBuilder::parseSinglePassOption(Params, "normalized-results",
1062 "DependenceAnalysisPrinter");
1063}
1064
1065Expected<bool> parseSeparateConstOffsetFromGEPPassOptions(StringRef Params) {
1066 return PassBuilder::parseSinglePassOption(Params, "lower-gep",
1067 "SeparateConstOffsetFromGEP");
1068}
1069
1071parseFunctionSimplificationPipelineOptions(StringRef Params) {
1072 std::optional<OptimizationLevel> L = parseOptLevel(Params);
1073 if (!L || *L == OptimizationLevel::O0) {
1074 return make_error<StringError>(
1075 formatv("invalid function-simplification parameter '{0}' ", Params)
1076 .str(),
1078 };
1079 return *L;
1080}
1081
1082Expected<bool> parseMemorySSAPrinterPassOptions(StringRef Params) {
1083 return PassBuilder::parseSinglePassOption(Params, "no-ensure-optimized-uses",
1084 "MemorySSAPrinterPass");
1085}
1086
1087Expected<bool> parseSpeculativeExecutionPassOptions(StringRef Params) {
1088 return PassBuilder::parseSinglePassOption(Params, "only-if-divergent-target",
1089 "SpeculativeExecutionPass");
1090}
1091
1092Expected<std::string> parseMemProfUsePassOptions(StringRef Params) {
1093 std::string Result;
1094 while (!Params.empty()) {
1095 StringRef ParamName;
1096 std::tie(ParamName, Params) = Params.split(';');
1097
1098 if (ParamName.consume_front("profile-filename=")) {
1099 Result = ParamName.str();
1100 } else {
1101 return make_error<StringError>(
1102 formatv("invalid MemProfUse pass parameter '{0}' ", ParamName).str(),
1104 }
1105 }
1106 return Result;
1107}
1108
1109Expected<bool> parseStructuralHashPrinterPassOptions(StringRef Params) {
1110 return PassBuilder::parseSinglePassOption(Params, "detailed",
1111 "StructuralHashPrinterPass");
1112}
1113
1114Expected<bool> parseWinEHPrepareOptions(StringRef Params) {
1115 return PassBuilder::parseSinglePassOption(Params, "demote-catchswitch-only",
1116 "WinEHPreparePass");
1117}
1118
1119Expected<GlobalMergeOptions> parseGlobalMergeOptions(StringRef Params) {
1121 while (!Params.empty()) {
1122 StringRef ParamName;
1123 std::tie(ParamName, Params) = Params.split(';');
1124
1125 bool Enable = !ParamName.consume_front("no-");
1126 if (ParamName == "group-by-use")
1127 Result.GroupByUse = Enable;
1128 else if (ParamName == "ignore-single-use")
1129 Result.IgnoreSingleUse = Enable;
1130 else if (ParamName == "merge-const")
1131 Result.MergeConst = Enable;
1132 else if (ParamName == "merge-external")
1133 Result.MergeExternal = Enable;
1134 else if (ParamName.consume_front("max-offset=")) {
1135 if (ParamName.getAsInteger(0, Result.MaxOffset))
1136 return make_error<StringError>(
1137 formatv("invalid GlobalMergePass parameter '{0}' ", ParamName)
1138 .str(),
1140 }
1141 }
1142 return Result;
1143}
1144
1145} // namespace
1146
1147/// Tests whether a pass name starts with a valid prefix for a default pipeline
1148/// alias.
1150 return Name.starts_with("default") || Name.starts_with("thinlto") ||
1151 Name.starts_with("lto");
1152}
1153
1154/// Tests whether registered callbacks will accept a given pass name.
1155///
1156/// When parsing a pipeline text, the type of the outermost pipeline may be
1157/// omitted, in which case the type is automatically determined from the first
1158/// pass name in the text. This may be a name that is handled through one of the
1159/// callbacks. We check this through the oridinary parsing callbacks by setting
1160/// up a dummy PassManager in order to not force the client to also handle this
1161/// type of query.
1162template <typename PassManagerT, typename CallbacksT>
1163static bool callbacksAcceptPassName(StringRef Name, CallbacksT &Callbacks) {
1164 if (!Callbacks.empty()) {
1165 PassManagerT DummyPM;
1166 for (auto &CB : Callbacks)
1167 if (CB(Name, DummyPM, {}))
1168 return true;
1169 }
1170 return false;
1171}
1172
1173template <typename CallbacksT>
1174static bool isModulePassName(StringRef Name, CallbacksT &Callbacks) {
1175 // Manually handle aliases for pre-configured pipeline fragments.
1178
1179 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1180
1181 // Explicitly handle pass manager names.
1182 if (Name == "module")
1183 return true;
1184 if (Name == "cgscc")
1185 return true;
1186 if (NameNoBracket == "function")
1187 return true;
1188 if (Name == "coro-cond")
1189 return true;
1190
1191 // Explicitly handle custom-parsed pass names.
1193 return true;
1194
1195#define MODULE_PASS(NAME, CREATE_PASS) \
1196 if (Name == NAME) \
1197 return true;
1198#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1199 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1200 return true;
1201#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
1202 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1203 return true;
1204#include "PassRegistry.def"
1205
1206 return callbacksAcceptPassName<ModulePassManager>(Name, Callbacks);
1207}
1208
1209template <typename CallbacksT>
1210static bool isCGSCCPassName(StringRef Name, CallbacksT &Callbacks) {
1211 // Explicitly handle pass manager names.
1212 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1213 if (Name == "cgscc")
1214 return true;
1215 if (NameNoBracket == "function")
1216 return true;
1217
1218 // Explicitly handle custom-parsed pass names.
1220 return true;
1222 return true;
1223
1224#define CGSCC_PASS(NAME, CREATE_PASS) \
1225 if (Name == NAME) \
1226 return true;
1227#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1228 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1229 return true;
1230#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
1231 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1232 return true;
1233#include "PassRegistry.def"
1234
1235 return callbacksAcceptPassName<CGSCCPassManager>(Name, Callbacks);
1236}
1237
1238template <typename CallbacksT>
1239static bool isFunctionPassName(StringRef Name, CallbacksT &Callbacks) {
1240 // Explicitly handle pass manager names.
1241 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1242 if (NameNoBracket == "function")
1243 return true;
1244 if (Name == "loop" || Name == "loop-mssa" || Name == "machine-function")
1245 return true;
1246
1247 // Explicitly handle custom-parsed pass names.
1249 return true;
1250
1251#define FUNCTION_PASS(NAME, CREATE_PASS) \
1252 if (Name == NAME) \
1253 return true;
1254#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1255 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1256 return true;
1257#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1258 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1259 return true;
1260#include "PassRegistry.def"
1261
1262 return callbacksAcceptPassName<FunctionPassManager>(Name, Callbacks);
1263}
1264
1265template <typename CallbacksT>
1266static bool isMachineFunctionPassName(StringRef Name, CallbacksT &Callbacks) {
1267 // Explicitly handle pass manager names.
1268 if (Name == "machine-function")
1269 return true;
1270
1271 // Explicitly handle custom-parsed pass names.
1273 return true;
1274
1275#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
1276 if (Name == NAME) \
1277 return true;
1278#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1279 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1280 return true;
1281
1282#include "llvm/Passes/MachinePassRegistry.def"
1283
1284 return callbacksAcceptPassName<MachineFunctionPassManager>(Name, Callbacks);
1285}
1286
1287template <typename CallbacksT>
1288static bool isLoopNestPassName(StringRef Name, CallbacksT &Callbacks,
1289 bool &UseMemorySSA) {
1290 UseMemorySSA = false;
1291
1292 // Explicitly handle custom-parsed pass names.
1294 return true;
1295
1297 UseMemorySSA = true;
1298 return true;
1299 }
1300
1301#define LOOPNEST_PASS(NAME, CREATE_PASS) \
1302 if (Name == NAME) \
1303 return true;
1304#include "PassRegistry.def"
1305
1306 return callbacksAcceptPassName<LoopPassManager>(Name, Callbacks);
1307}
1308
1309template <typename CallbacksT>
1310static bool isLoopPassName(StringRef Name, CallbacksT &Callbacks,
1311 bool &UseMemorySSA) {
1312 UseMemorySSA = false;
1313
1314 // Explicitly handle custom-parsed pass names.
1316 return true;
1317
1319 UseMemorySSA = true;
1320 return true;
1321 }
1322
1323#define LOOP_PASS(NAME, CREATE_PASS) \
1324 if (Name == NAME) \
1325 return true;
1326#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1327 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1328 return true;
1329#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
1330 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1331 return true;
1332#include "PassRegistry.def"
1333
1334 return callbacksAcceptPassName<LoopPassManager>(Name, Callbacks);
1335}
1336
1337std::optional<std::vector<PassBuilder::PipelineElement>>
1338PassBuilder::parsePipelineText(StringRef Text) {
1339 std::vector<PipelineElement> ResultPipeline;
1340
1341 SmallVector<std::vector<PipelineElement> *, 4> PipelineStack = {
1342 &ResultPipeline};
1343 for (;;) {
1344 std::vector<PipelineElement> &Pipeline = *PipelineStack.back();
1345 size_t Pos = Text.find_first_of(",()");
1346 Pipeline.push_back({Text.substr(0, Pos), {}});
1347
1348 // If we have a single terminating name, we're done.
1349 if (Pos == Text.npos)
1350 break;
1351
1352 char Sep = Text[Pos];
1353 Text = Text.substr(Pos + 1);
1354 if (Sep == ',')
1355 // Just a name ending in a comma, continue.
1356 continue;
1357
1358 if (Sep == '(') {
1359 // Push the inner pipeline onto the stack to continue processing.
1360 PipelineStack.push_back(&Pipeline.back().InnerPipeline);
1361 continue;
1362 }
1363
1364 assert(Sep == ')' && "Bogus separator!");
1365 // When handling the close parenthesis, we greedily consume them to avoid
1366 // empty strings in the pipeline.
1367 do {
1368 // If we try to pop the outer pipeline we have unbalanced parentheses.
1369 if (PipelineStack.size() == 1)
1370 return std::nullopt;
1371
1372 PipelineStack.pop_back();
1373 } while (Text.consume_front(")"));
1374
1375 // Check if we've finished parsing.
1376 if (Text.empty())
1377 break;
1378
1379 // Otherwise, the end of an inner pipeline always has to be followed by
1380 // a comma, and then we can continue.
1381 if (!Text.consume_front(","))
1382 return std::nullopt;
1383 }
1384
1385 if (PipelineStack.size() > 1)
1386 // Unbalanced paretheses.
1387 return std::nullopt;
1388
1389 assert(PipelineStack.back() == &ResultPipeline &&
1390 "Wrong pipeline at the bottom of the stack!");
1391 return {std::move(ResultPipeline)};
1392}
1393
1394Error PassBuilder::parseModulePass(ModulePassManager &MPM,
1395 const PipelineElement &E) {
1396 auto &Name = E.Name;
1397 auto &InnerPipeline = E.InnerPipeline;
1398
1399 // First handle complex passes like the pass managers which carry pipelines.
1400 if (!InnerPipeline.empty()) {
1401 if (Name == "module") {
1402 ModulePassManager NestedMPM;
1403 if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline))
1404 return Err;
1405 MPM.addPass(std::move(NestedMPM));
1406 return Error::success();
1407 }
1408 if (Name == "coro-cond") {
1409 ModulePassManager NestedMPM;
1410 if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline))
1411 return Err;
1412 MPM.addPass(CoroConditionalWrapper(std::move(NestedMPM)));
1413 return Error::success();
1414 }
1415 if (Name == "cgscc") {
1416 CGSCCPassManager CGPM;
1417 if (auto Err = parseCGSCCPassPipeline(CGPM, InnerPipeline))
1418 return Err;
1420 return Error::success();
1421 }
1422 if (auto Params = parseFunctionPipelineName(Name)) {
1423 if (Params->second)
1424 return make_error<StringError>(
1425 "cannot have a no-rerun module to function adaptor",
1428 if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline))
1429 return Err;
1430 MPM.addPass(
1431 createModuleToFunctionPassAdaptor(std::move(FPM), Params->first));
1432 return Error::success();
1433 }
1434 if (auto Count = parseRepeatPassName(Name)) {
1435 ModulePassManager NestedMPM;
1436 if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline))
1437 return Err;
1438 MPM.addPass(createRepeatedPass(*Count, std::move(NestedMPM)));
1439 return Error::success();
1440 }
1441
1442 for (auto &C : ModulePipelineParsingCallbacks)
1443 if (C(Name, MPM, InnerPipeline))
1444 return Error::success();
1445
1446 // Normal passes can't have pipelines.
1447 return make_error<StringError>(
1448 formatv("invalid use of '{0}' pass as module pipeline", Name).str(),
1450 ;
1451 }
1452
1453 // Manually handle aliases for pre-configured pipeline fragments.
1456 if (!DefaultAliasRegex.match(Name, &Matches))
1457 return make_error<StringError>(
1458 formatv("unknown default pipeline alias '{0}'", Name).str(),
1460
1461 assert(Matches.size() == 3 && "Must capture two matched strings!");
1462
1463 OptimizationLevel L = *parseOptLevel(Matches[2]);
1464
1465 // This is consistent with old pass manager invoked via opt, but
1466 // inconsistent with clang. Clang doesn't enable loop vectorization
1467 // but does enable slp vectorization at Oz.
1468 PTO.LoopVectorization =
1469 L.getSpeedupLevel() > 1 && L != OptimizationLevel::Oz;
1470 PTO.SLPVectorization =
1471 L.getSpeedupLevel() > 1 && L != OptimizationLevel::Oz;
1472
1473 if (Matches[1] == "default") {
1475 } else if (Matches[1] == "thinlto-pre-link") {
1477 } else if (Matches[1] == "thinlto") {
1479 } else if (Matches[1] == "lto-pre-link") {
1480 if (PTO.UnifiedLTO)
1481 // When UnifiedLTO is enabled, use the ThinLTO pre-link pipeline. This
1482 // avoids compile-time performance regressions and keeps the pre-link
1483 // LTO pipeline "unified" for both LTO modes.
1485 else
1487 } else {
1488 assert(Matches[1] == "lto" && "Not one of the matched options!");
1489 MPM.addPass(buildLTODefaultPipeline(L, nullptr));
1490 }
1491 return Error::success();
1492 }
1493
1494 // Finally expand the basic registered passes from the .inc file.
1495#define MODULE_PASS(NAME, CREATE_PASS) \
1496 if (Name == NAME) { \
1497 MPM.addPass(CREATE_PASS); \
1498 return Error::success(); \
1499 }
1500#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1501 if (checkParametrizedPassName(Name, NAME)) { \
1502 auto Params = parsePassParameters(PARSER, Name, NAME); \
1503 if (!Params) \
1504 return Params.takeError(); \
1505 MPM.addPass(CREATE_PASS(Params.get())); \
1506 return Error::success(); \
1507 }
1508#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
1509 if (Name == "require<" NAME ">") { \
1510 MPM.addPass( \
1511 RequireAnalysisPass< \
1512 std::remove_reference_t<decltype(CREATE_PASS)>, Module>()); \
1513 return Error::success(); \
1514 } \
1515 if (Name == "invalidate<" NAME ">") { \
1516 MPM.addPass(InvalidateAnalysisPass< \
1517 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
1518 return Error::success(); \
1519 }
1520#define CGSCC_PASS(NAME, CREATE_PASS) \
1521 if (Name == NAME) { \
1522 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(CREATE_PASS)); \
1523 return Error::success(); \
1524 }
1525#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1526 if (checkParametrizedPassName(Name, NAME)) { \
1527 auto Params = parsePassParameters(PARSER, Name, NAME); \
1528 if (!Params) \
1529 return Params.takeError(); \
1530 MPM.addPass( \
1531 createModuleToPostOrderCGSCCPassAdaptor(CREATE_PASS(Params.get()))); \
1532 return Error::success(); \
1533 }
1534#define FUNCTION_PASS(NAME, CREATE_PASS) \
1535 if (Name == NAME) { \
1536 MPM.addPass(createModuleToFunctionPassAdaptor(CREATE_PASS)); \
1537 return Error::success(); \
1538 }
1539#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1540 if (checkParametrizedPassName(Name, NAME)) { \
1541 auto Params = parsePassParameters(PARSER, Name, NAME); \
1542 if (!Params) \
1543 return Params.takeError(); \
1544 MPM.addPass(createModuleToFunctionPassAdaptor(CREATE_PASS(Params.get()))); \
1545 return Error::success(); \
1546 }
1547#define LOOPNEST_PASS(NAME, CREATE_PASS) \
1548 if (Name == NAME) { \
1549 MPM.addPass(createModuleToFunctionPassAdaptor( \
1550 createFunctionToLoopPassAdaptor(CREATE_PASS, false, false))); \
1551 return Error::success(); \
1552 }
1553#define LOOP_PASS(NAME, CREATE_PASS) \
1554 if (Name == NAME) { \
1555 MPM.addPass(createModuleToFunctionPassAdaptor( \
1556 createFunctionToLoopPassAdaptor(CREATE_PASS, false, false))); \
1557 return Error::success(); \
1558 }
1559#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1560 if (checkParametrizedPassName(Name, NAME)) { \
1561 auto Params = parsePassParameters(PARSER, Name, NAME); \
1562 if (!Params) \
1563 return Params.takeError(); \
1564 MPM.addPass( \
1565 createModuleToFunctionPassAdaptor(createFunctionToLoopPassAdaptor( \
1566 CREATE_PASS(Params.get()), false, false))); \
1567 return Error::success(); \
1568 }
1569#include "PassRegistry.def"
1570
1571 for (auto &C : ModulePipelineParsingCallbacks)
1572 if (C(Name, MPM, InnerPipeline))
1573 return Error::success();
1574 return make_error<StringError>(
1575 formatv("unknown module pass '{0}'", Name).str(),
1577}
1578
1579Error PassBuilder::parseCGSCCPass(CGSCCPassManager &CGPM,
1580 const PipelineElement &E) {
1581 auto &Name = E.Name;
1582 auto &InnerPipeline = E.InnerPipeline;
1583
1584 // First handle complex passes like the pass managers which carry pipelines.
1585 if (!InnerPipeline.empty()) {
1586 if (Name == "cgscc") {
1587 CGSCCPassManager NestedCGPM;
1588 if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline))
1589 return Err;
1590 // Add the nested pass manager with the appropriate adaptor.
1591 CGPM.addPass(std::move(NestedCGPM));
1592 return Error::success();
1593 }
1594 if (auto Params = parseFunctionPipelineName(Name)) {
1596 if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline))
1597 return Err;
1598 // Add the nested pass manager with the appropriate adaptor.
1600 std::move(FPM), Params->first, Params->second));
1601 return Error::success();
1602 }
1603 if (auto Count = parseRepeatPassName(Name)) {
1604 CGSCCPassManager NestedCGPM;
1605 if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline))
1606 return Err;
1607 CGPM.addPass(createRepeatedPass(*Count, std::move(NestedCGPM)));
1608 return Error::success();
1609 }
1610 if (auto MaxRepetitions = parseDevirtPassName(Name)) {
1611 CGSCCPassManager NestedCGPM;
1612 if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline))
1613 return Err;
1614 CGPM.addPass(
1615 createDevirtSCCRepeatedPass(std::move(NestedCGPM), *MaxRepetitions));
1616 return Error::success();
1617 }
1618
1619 for (auto &C : CGSCCPipelineParsingCallbacks)
1620 if (C(Name, CGPM, InnerPipeline))
1621 return Error::success();
1622
1623 // Normal passes can't have pipelines.
1624 return make_error<StringError>(
1625 formatv("invalid use of '{0}' pass as cgscc pipeline", Name).str(),
1627 }
1628
1629// Now expand the basic registered passes from the .inc file.
1630#define CGSCC_PASS(NAME, CREATE_PASS) \
1631 if (Name == NAME) { \
1632 CGPM.addPass(CREATE_PASS); \
1633 return Error::success(); \
1634 }
1635#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1636 if (checkParametrizedPassName(Name, NAME)) { \
1637 auto Params = parsePassParameters(PARSER, Name, NAME); \
1638 if (!Params) \
1639 return Params.takeError(); \
1640 CGPM.addPass(CREATE_PASS(Params.get())); \
1641 return Error::success(); \
1642 }
1643#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
1644 if (Name == "require<" NAME ">") { \
1645 CGPM.addPass(RequireAnalysisPass< \
1646 std::remove_reference_t<decltype(CREATE_PASS)>, \
1647 LazyCallGraph::SCC, CGSCCAnalysisManager, LazyCallGraph &, \
1648 CGSCCUpdateResult &>()); \
1649 return Error::success(); \
1650 } \
1651 if (Name == "invalidate<" NAME ">") { \
1652 CGPM.addPass(InvalidateAnalysisPass< \
1653 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
1654 return Error::success(); \
1655 }
1656#define FUNCTION_PASS(NAME, CREATE_PASS) \
1657 if (Name == NAME) { \
1658 CGPM.addPass(createCGSCCToFunctionPassAdaptor(CREATE_PASS)); \
1659 return Error::success(); \
1660 }
1661#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1662 if (checkParametrizedPassName(Name, NAME)) { \
1663 auto Params = parsePassParameters(PARSER, Name, NAME); \
1664 if (!Params) \
1665 return Params.takeError(); \
1666 CGPM.addPass(createCGSCCToFunctionPassAdaptor(CREATE_PASS(Params.get()))); \
1667 return Error::success(); \
1668 }
1669#define LOOPNEST_PASS(NAME, CREATE_PASS) \
1670 if (Name == NAME) { \
1671 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
1672 createFunctionToLoopPassAdaptor(CREATE_PASS, false, false))); \
1673 return Error::success(); \
1674 }
1675#define LOOP_PASS(NAME, CREATE_PASS) \
1676 if (Name == NAME) { \
1677 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
1678 createFunctionToLoopPassAdaptor(CREATE_PASS, false, false))); \
1679 return Error::success(); \
1680 }
1681#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1682 if (checkParametrizedPassName(Name, NAME)) { \
1683 auto Params = parsePassParameters(PARSER, Name, NAME); \
1684 if (!Params) \
1685 return Params.takeError(); \
1686 CGPM.addPass( \
1687 createCGSCCToFunctionPassAdaptor(createFunctionToLoopPassAdaptor( \
1688 CREATE_PASS(Params.get()), false, false))); \
1689 return Error::success(); \
1690 }
1691#include "PassRegistry.def"
1692
1693 for (auto &C : CGSCCPipelineParsingCallbacks)
1694 if (C(Name, CGPM, InnerPipeline))
1695 return Error::success();
1696 return make_error<StringError>(
1697 formatv("unknown cgscc pass '{0}'", Name).str(),
1699}
1700
1701Error PassBuilder::parseFunctionPass(FunctionPassManager &FPM,
1702 const PipelineElement &E) {
1703 auto &Name = E.Name;
1704 auto &InnerPipeline = E.InnerPipeline;
1705
1706 // First handle complex passes like the pass managers which carry pipelines.
1707 if (!InnerPipeline.empty()) {
1708 if (Name == "function") {
1709 FunctionPassManager NestedFPM;
1710 if (auto Err = parseFunctionPassPipeline(NestedFPM, InnerPipeline))
1711 return Err;
1712 // Add the nested pass manager with the appropriate adaptor.
1713 FPM.addPass(std::move(NestedFPM));
1714 return Error::success();
1715 }
1716 if (Name == "loop" || Name == "loop-mssa") {
1717 LoopPassManager LPM;
1718 if (auto Err = parseLoopPassPipeline(LPM, InnerPipeline))
1719 return Err;
1720 // Add the nested pass manager with the appropriate adaptor.
1721 bool UseMemorySSA = (Name == "loop-mssa");
1722 bool UseBFI = llvm::any_of(InnerPipeline, [](auto Pipeline) {
1723 return Pipeline.Name.contains("simple-loop-unswitch");
1724 });
1725 bool UseBPI = llvm::any_of(InnerPipeline, [](auto Pipeline) {
1726 return Pipeline.Name == "loop-predication";
1727 });
1728 FPM.addPass(createFunctionToLoopPassAdaptor(std::move(LPM), UseMemorySSA,
1729 UseBFI, UseBPI));
1730 return Error::success();
1731 }
1732 if (auto Count = parseRepeatPassName(Name)) {
1733 FunctionPassManager NestedFPM;
1734 if (auto Err = parseFunctionPassPipeline(NestedFPM, InnerPipeline))
1735 return Err;
1736 FPM.addPass(createRepeatedPass(*Count, std::move(NestedFPM)));
1737 return Error::success();
1738 }
1739 if (Name == "machine-function") {
1741 if (auto Err = parseMachinePassPipeline(MFPM, InnerPipeline))
1742 return Err;
1744 return Error::success();
1745 }
1746
1747 for (auto &C : FunctionPipelineParsingCallbacks)
1748 if (C(Name, FPM, InnerPipeline))
1749 return Error::success();
1750
1751 // Normal passes can't have pipelines.
1752 return make_error<StringError>(
1753 formatv("invalid use of '{0}' pass as function pipeline", Name).str(),
1755 }
1756
1757// Now expand the basic registered passes from the .inc file.
1758#define FUNCTION_PASS(NAME, CREATE_PASS) \
1759 if (Name == NAME) { \
1760 FPM.addPass(CREATE_PASS); \
1761 return Error::success(); \
1762 }
1763#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1764 if (checkParametrizedPassName(Name, NAME)) { \
1765 auto Params = parsePassParameters(PARSER, Name, NAME); \
1766 if (!Params) \
1767 return Params.takeError(); \
1768 FPM.addPass(CREATE_PASS(Params.get())); \
1769 return Error::success(); \
1770 }
1771#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1772 if (Name == "require<" NAME ">") { \
1773 FPM.addPass( \
1774 RequireAnalysisPass< \
1775 std::remove_reference_t<decltype(CREATE_PASS)>, Function>()); \
1776 return Error::success(); \
1777 } \
1778 if (Name == "invalidate<" NAME ">") { \
1779 FPM.addPass(InvalidateAnalysisPass< \
1780 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
1781 return Error::success(); \
1782 }
1783// FIXME: UseMemorySSA is set to false. Maybe we could do things like:
1784// bool UseMemorySSA = !("canon-freeze" || "loop-predication" ||
1785// "guard-widening");
1786// The risk is that it may become obsolete if we're not careful.
1787#define LOOPNEST_PASS(NAME, CREATE_PASS) \
1788 if (Name == NAME) { \
1789 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS, false, false)); \
1790 return Error::success(); \
1791 }
1792#define LOOP_PASS(NAME, CREATE_PASS) \
1793 if (Name == NAME) { \
1794 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS, false, false)); \
1795 return Error::success(); \
1796 }
1797#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1798 if (checkParametrizedPassName(Name, NAME)) { \
1799 auto Params = parsePassParameters(PARSER, Name, NAME); \
1800 if (!Params) \
1801 return Params.takeError(); \
1802 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), \
1803 false, false)); \
1804 return Error::success(); \
1805 }
1806#include "PassRegistry.def"
1807
1808 for (auto &C : FunctionPipelineParsingCallbacks)
1809 if (C(Name, FPM, InnerPipeline))
1810 return Error::success();
1811 return make_error<StringError>(
1812 formatv("unknown function pass '{0}'", Name).str(),
1814}
1815
1816Error PassBuilder::parseLoopPass(LoopPassManager &LPM,
1817 const PipelineElement &E) {
1818 StringRef Name = E.Name;
1819 auto &InnerPipeline = E.InnerPipeline;
1820
1821 // First handle complex passes like the pass managers which carry pipelines.
1822 if (!InnerPipeline.empty()) {
1823 if (Name == "loop") {
1824 LoopPassManager NestedLPM;
1825 if (auto Err = parseLoopPassPipeline(NestedLPM, InnerPipeline))
1826 return Err;
1827 // Add the nested pass manager with the appropriate adaptor.
1828 LPM.addPass(std::move(NestedLPM));
1829 return Error::success();
1830 }
1831 if (auto Count = parseRepeatPassName(Name)) {
1832 LoopPassManager NestedLPM;
1833 if (auto Err = parseLoopPassPipeline(NestedLPM, InnerPipeline))
1834 return Err;
1835 LPM.addPass(createRepeatedPass(*Count, std::move(NestedLPM)));
1836 return Error::success();
1837 }
1838
1839 for (auto &C : LoopPipelineParsingCallbacks)
1840 if (C(Name, LPM, InnerPipeline))
1841 return Error::success();
1842
1843 // Normal passes can't have pipelines.
1844 return make_error<StringError>(
1845 formatv("invalid use of '{0}' pass as loop pipeline", Name).str(),
1847 }
1848
1849// Now expand the basic registered passes from the .inc file.
1850#define LOOPNEST_PASS(NAME, CREATE_PASS) \
1851 if (Name == NAME) { \
1852 LPM.addPass(CREATE_PASS); \
1853 return Error::success(); \
1854 }
1855#define LOOP_PASS(NAME, CREATE_PASS) \
1856 if (Name == NAME) { \
1857 LPM.addPass(CREATE_PASS); \
1858 return Error::success(); \
1859 }
1860#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1861 if (checkParametrizedPassName(Name, NAME)) { \
1862 auto Params = parsePassParameters(PARSER, Name, NAME); \
1863 if (!Params) \
1864 return Params.takeError(); \
1865 LPM.addPass(CREATE_PASS(Params.get())); \
1866 return Error::success(); \
1867 }
1868#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
1869 if (Name == "require<" NAME ">") { \
1870 LPM.addPass(RequireAnalysisPass< \
1871 std::remove_reference_t<decltype(CREATE_PASS)>, Loop, \
1872 LoopAnalysisManager, LoopStandardAnalysisResults &, \
1873 LPMUpdater &>()); \
1874 return Error::success(); \
1875 } \
1876 if (Name == "invalidate<" NAME ">") { \
1877 LPM.addPass(InvalidateAnalysisPass< \
1878 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
1879 return Error::success(); \
1880 }
1881#include "PassRegistry.def"
1882
1883 for (auto &C : LoopPipelineParsingCallbacks)
1884 if (C(Name, LPM, InnerPipeline))
1885 return Error::success();
1886 return make_error<StringError>(formatv("unknown loop pass '{0}'", Name).str(),
1888}
1889
1890Error PassBuilder::parseMachinePass(MachineFunctionPassManager &MFPM,
1891 const PipelineElement &E) {
1892 StringRef Name = E.Name;
1893 if (!E.InnerPipeline.empty())
1894 return make_error<StringError>("invalid pipeline",
1896
1897#define MACHINE_MODULE_PASS(NAME, CREATE_PASS) \
1898 if (Name == NAME) { \
1899 MFPM.addPass(CREATE_PASS); \
1900 return Error::success(); \
1901 }
1902#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
1903 if (Name == NAME) { \
1904 MFPM.addPass(CREATE_PASS); \
1905 return Error::success(); \
1906 }
1907#include "llvm/Passes/MachinePassRegistry.def"
1908
1909 for (auto &C : MachineFunctionPipelineParsingCallbacks)
1910 if (C(Name, MFPM, E.InnerPipeline))
1911 return Error::success();
1912 return make_error<StringError>(
1913 formatv("unknown machine pass '{0}'", Name).str(),
1915}
1916
1917bool PassBuilder::parseAAPassName(AAManager &AA, StringRef Name) {
1918#define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
1919 if (Name == NAME) { \
1920 AA.registerModuleAnalysis< \
1921 std::remove_reference_t<decltype(CREATE_PASS)>>(); \
1922 return true; \
1923 }
1924#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
1925 if (Name == NAME) { \
1926 AA.registerFunctionAnalysis< \
1927 std::remove_reference_t<decltype(CREATE_PASS)>>(); \
1928 return true; \
1929 }
1930#include "PassRegistry.def"
1931
1932 for (auto &C : AAParsingCallbacks)
1933 if (C(Name, AA))
1934 return true;
1935 return false;
1936}
1937
1938Error PassBuilder::parseMachinePassPipeline(
1940 for (const auto &Element : Pipeline) {
1941 if (auto Err = parseMachinePass(MFPM, Element))
1942 return Err;
1943 }
1944 return Error::success();
1945}
1946
1947Error PassBuilder::parseLoopPassPipeline(LoopPassManager &LPM,
1948 ArrayRef<PipelineElement> Pipeline) {
1949 for (const auto &Element : Pipeline) {
1950 if (auto Err = parseLoopPass(LPM, Element))
1951 return Err;
1952 }
1953 return Error::success();
1954}
1955
1956Error PassBuilder::parseFunctionPassPipeline(
1958 for (const auto &Element : Pipeline) {
1959 if (auto Err = parseFunctionPass(FPM, Element))
1960 return Err;
1961 }
1962 return Error::success();
1963}
1964
1965Error PassBuilder::parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
1966 ArrayRef<PipelineElement> Pipeline) {
1967 for (const auto &Element : Pipeline) {
1968 if (auto Err = parseCGSCCPass(CGPM, Element))
1969 return Err;
1970 }
1971 return Error::success();
1972}
1973
1986 if (MFAM) {
1988 [&] { return MachineFunctionAnalysisManagerModuleProxy(*MFAM); });
1990 [&] { return MachineFunctionAnalysisManagerFunctionProxy(*MFAM); });
1991 MFAM->registerPass(
1993 MFAM->registerPass(
1995 }
1996}
1997
1998Error PassBuilder::parseModulePassPipeline(ModulePassManager &MPM,
1999 ArrayRef<PipelineElement> Pipeline) {
2000 for (const auto &Element : Pipeline) {
2001 if (auto Err = parseModulePass(MPM, Element))
2002 return Err;
2003 }
2004 return Error::success();
2005}
2006
2007// Primary pass pipeline description parsing routine for a \c ModulePassManager
2008// FIXME: Should this routine accept a TargetMachine or require the caller to
2009// pre-populate the analysis managers with target-specific stuff?
2011 StringRef PipelineText) {
2012 auto Pipeline = parsePipelineText(PipelineText);
2013 if (!Pipeline || Pipeline->empty())
2014 return make_error<StringError>(
2015 formatv("invalid pipeline '{0}'", PipelineText).str(),
2017
2018 // If the first name isn't at the module layer, wrap the pipeline up
2019 // automatically.
2020 StringRef FirstName = Pipeline->front().Name;
2021
2022 if (!isModulePassName(FirstName, ModulePipelineParsingCallbacks)) {
2023 bool UseMemorySSA;
2024 if (isCGSCCPassName(FirstName, CGSCCPipelineParsingCallbacks)) {
2025 Pipeline = {{"cgscc", std::move(*Pipeline)}};
2026 } else if (isFunctionPassName(FirstName,
2027 FunctionPipelineParsingCallbacks)) {
2028 Pipeline = {{"function", std::move(*Pipeline)}};
2029 } else if (isLoopNestPassName(FirstName, LoopPipelineParsingCallbacks,
2030 UseMemorySSA)) {
2031 Pipeline = {{"function", {{UseMemorySSA ? "loop-mssa" : "loop",
2032 std::move(*Pipeline)}}}};
2033 } else if (isLoopPassName(FirstName, LoopPipelineParsingCallbacks,
2034 UseMemorySSA)) {
2035 Pipeline = {{"function", {{UseMemorySSA ? "loop-mssa" : "loop",
2036 std::move(*Pipeline)}}}};
2037 } else if (isMachineFunctionPassName(
2038 FirstName, MachineFunctionPipelineParsingCallbacks)) {
2039 Pipeline = {{"function", {{"machine-function", std::move(*Pipeline)}}}};
2040 } else {
2041 for (auto &C : TopLevelPipelineParsingCallbacks)
2042 if (C(MPM, *Pipeline))
2043 return Error::success();
2044
2045 // Unknown pass or pipeline name!
2046 auto &InnerPipeline = Pipeline->front().InnerPipeline;
2047 return make_error<StringError>(
2048 formatv("unknown {0} name '{1}'",
2049 (InnerPipeline.empty() ? "pass" : "pipeline"), FirstName)
2050 .str(),
2052 }
2053 }
2054
2055 if (auto Err = parseModulePassPipeline(MPM, *Pipeline))
2056 return Err;
2057 return Error::success();
2058}
2059
2060// Primary pass pipeline description parsing routine for a \c CGSCCPassManager
2062 StringRef PipelineText) {
2063 auto Pipeline = parsePipelineText(PipelineText);
2064 if (!Pipeline || Pipeline->empty())
2065 return make_error<StringError>(
2066 formatv("invalid pipeline '{0}'", PipelineText).str(),
2068
2069 StringRef FirstName = Pipeline->front().Name;
2070 if (!isCGSCCPassName(FirstName, CGSCCPipelineParsingCallbacks))
2071 return make_error<StringError>(
2072 formatv("unknown cgscc pass '{0}' in pipeline '{1}'", FirstName,
2073 PipelineText)
2074 .str(),
2076
2077 if (auto Err = parseCGSCCPassPipeline(CGPM, *Pipeline))
2078 return Err;
2079 return Error::success();
2080}
2081
2082// Primary pass pipeline description parsing routine for a \c
2083// FunctionPassManager
2085 StringRef PipelineText) {
2086 auto Pipeline = parsePipelineText(PipelineText);
2087 if (!Pipeline || Pipeline->empty())
2088 return make_error<StringError>(
2089 formatv("invalid pipeline '{0}'", PipelineText).str(),
2091
2092 StringRef FirstName = Pipeline->front().Name;
2093 if (!isFunctionPassName(FirstName, FunctionPipelineParsingCallbacks))
2094 return make_error<StringError>(
2095 formatv("unknown function pass '{0}' in pipeline '{1}'", FirstName,
2096 PipelineText)
2097 .str(),
2099
2100 if (auto Err = parseFunctionPassPipeline(FPM, *Pipeline))
2101 return Err;
2102 return Error::success();
2103}
2104
2105// Primary pass pipeline description parsing routine for a \c LoopPassManager
2107 StringRef PipelineText) {
2108 auto Pipeline = parsePipelineText(PipelineText);
2109 if (!Pipeline || Pipeline->empty())
2110 return make_error<StringError>(
2111 formatv("invalid pipeline '{0}'", PipelineText).str(),
2113
2114 if (auto Err = parseLoopPassPipeline(CGPM, *Pipeline))
2115 return Err;
2116
2117 return Error::success();
2118}
2119
2121 StringRef PipelineText) {
2122 auto Pipeline = parsePipelineText(PipelineText);
2123 if (!Pipeline || Pipeline->empty())
2124 return make_error<StringError>(
2125 formatv("invalid machine pass pipeline '{0}'", PipelineText).str(),
2127
2128 if (auto Err = parseMachinePassPipeline(MFPM, *Pipeline))
2129 return Err;
2130
2131 return Error::success();
2132}
2133
2135 // If the pipeline just consists of the word 'default' just replace the AA
2136 // manager with our default one.
2137 if (PipelineText == "default") {
2139 return Error::success();
2140 }
2141
2142 while (!PipelineText.empty()) {
2144 std::tie(Name, PipelineText) = PipelineText.split(',');
2145 if (!parseAAPassName(AA, Name))
2146 return make_error<StringError>(
2147 formatv("unknown alias analysis name '{0}'", Name).str(),
2149 }
2150
2151 return Error::success();
2152}
2153
2155 OS << " " << PassName << "\n";
2156}
2158 raw_ostream &OS) {
2159 OS << " " << PassName << "<" << Params << ">\n";
2160}
2161
2163 // TODO: print pass descriptions when they are available
2164
2165 OS << "Module passes:\n";
2166#define MODULE_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2167#include "PassRegistry.def"
2168
2169 OS << "Module passes with params:\n";
2170#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2171 printPassName(NAME, PARAMS, OS);
2172#include "PassRegistry.def"
2173
2174 OS << "Module analyses:\n";
2175#define MODULE_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2176#include "PassRegistry.def"
2177
2178 OS << "Module alias analyses:\n";
2179#define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2180#include "PassRegistry.def"
2181
2182 OS << "CGSCC passes:\n";
2183#define CGSCC_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2184#include "PassRegistry.def"
2185
2186 OS << "CGSCC passes with params:\n";
2187#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2188 printPassName(NAME, PARAMS, OS);
2189#include "PassRegistry.def"
2190
2191 OS << "CGSCC analyses:\n";
2192#define CGSCC_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2193#include "PassRegistry.def"
2194
2195 OS << "Function passes:\n";
2196#define FUNCTION_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2197#include "PassRegistry.def"
2198
2199 OS << "Function passes with params:\n";
2200#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2201 printPassName(NAME, PARAMS, OS);
2202#include "PassRegistry.def"
2203
2204 OS << "Function analyses:\n";
2205#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2206#include "PassRegistry.def"
2207
2208 OS << "Function alias analyses:\n";
2209#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2210#include "PassRegistry.def"
2211
2212 OS << "LoopNest passes:\n";
2213#define LOOPNEST_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2214#include "PassRegistry.def"
2215
2216 OS << "Loop passes:\n";
2217#define LOOP_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2218#include "PassRegistry.def"
2219
2220 OS << "Loop passes with params:\n";
2221#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2222 printPassName(NAME, PARAMS, OS);
2223#include "PassRegistry.def"
2224
2225 OS << "Loop analyses:\n";
2226#define LOOP_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2227#include "PassRegistry.def"
2228
2229 OS << "Machine module passes (WIP):\n";
2230#define MACHINE_MODULE_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2231#include "llvm/Passes/MachinePassRegistry.def"
2232
2233 OS << "Machine function passes (WIP):\n";
2234#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2235#include "llvm/Passes/MachinePassRegistry.def"
2236
2237 OS << "Machine function analyses (WIP):\n";
2238#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2239#include "llvm/Passes/MachinePassRegistry.def"
2240}
2241
2243 const std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>)>
2244 &C) {
2245 TopLevelPipelineParsingCallbacks.push_back(C);
2246}
unsigned const MachineRegisterInfo * MRI
AggressiveInstCombiner - Combine expression patterns to form expressions with fewer,...
This file implements a simple N^2 alias analysis accuracy evaluator.
Provides passes to inlining "always_inline" functions.
This is the interface for LLVM's primary stateless and local alias analysis.
This file provides the interface for LLVM's Call Graph Profile pass.
This header provides classes for managing passes over SCCs of the call graph.
This file provides interfaces used to build and manipulate a call graph, which is a very useful tool ...
Defines an IR pass for CodeGen Prepare.
This file declares an analysis pass that computes CycleInfo for LLVM IR, specialized from GenericCycl...
std::string Name
This file provides the interface for a simple, fast CSE pass.
This file provides a pass which clones the current module and runs the provided pass pipeline on the ...
Super simple passes to force specific function attrs from the commandline into the IR for debugging p...
Provides passes for computing function attributes based on interprocedural analyses.
This file provides the interface for the GCOV style profiler pass.
This file provides the interface for LLVM's Global Value Numbering pass which eliminates fully redund...
This is the interface for a simple mod/ref and alias analysis over globals.
Defines an IR pass for the creation of hardware loops.
AcceleratorCodeSelection - Identify all functions reachable from a kernel, removing those that are un...
This file defines passes to print out IR in various granularities.
Interfaces for passes which infer implicit function attributes from the name and signature of functio...
This file provides the primary interface to the instcombine pass.
Defines passes for running instruction simplification across chunks of IR.
This file provides the interface for LLVM's PGO Instrumentation lowering pass.
This file contains the declaration of the InterleavedAccessPass class, its corresponding pass name is...
See the comments on JumpThreadingPass.
Implements a lazy call graph analysis and related passes for the new pass manager.
This file defines the interface for the loop cache analysis.
This file provides the interface for LLVM's Loop Data Prefetching Pass.
This file implements the Loop Fusion pass.
This header defines the LoopLoadEliminationPass object.
This file defines the interface for the loop nest analysis.
This header provides classes for managing a pipeline of passes over loops in LLVM IR.
This file provides the interface for the pass responsible for removing expensive ubsan checks.
The header file for the LowerConstantIntrinsics pass as used by the new pass manager.
The header file for the LowerExpectIntrinsic pass as used by the new pass manager.
#define F(x, y, z)
Definition: MD5.cpp:55
UseBFI
Definition: MachineLICM.cpp:88
This file exposes an interface to building/using memory SSA to walk memory instructions using a use/d...
This pass performs merges of loads and stores on both sides of a.
This is the interface to build a ModuleSummaryIndex for a module.
Contains a collection of routines for determining if a given instruction is guaranteed to execute if ...
This file provides the interface for LLVM's Global Value Numbering pass.
This file declares a simple ARC-aware AliasAnalysis using special knowledge of Objective C to enhance...
This header enumerates the LLVM-provided high-level optimization levels.
This file provides the interface for IR based instrumentation passes ( (profile-gen,...
CGSCCAnalysisManager CGAM
ModulePassManager MPM
LoopAnalysisManager LAM
FunctionAnalysisManager FAM
ModuleAnalysisManager MAM
const char LLVMTargetMachineRef TM
PassInstrumentationCallbacks PIC
static bool isModulePassName(StringRef Name, CallbacksT &Callbacks)
static bool callbacksAcceptPassName(StringRef Name, CallbacksT &Callbacks)
Tests whether registered callbacks will accept a given pass name.
static std::optional< int > parseDevirtPassName(StringRef Name)
static std::optional< int > parseRepeatPassName(StringRef Name)
static bool startsWithDefaultPipelineAliasPrefix(StringRef Name)
Tests whether a pass name starts with a valid prefix for a default pipeline alias.
static bool isLoopNestPassName(StringRef Name, CallbacksT &Callbacks, bool &UseMemorySSA)
static bool isMachineFunctionPassName(StringRef Name, CallbacksT &Callbacks)
static std::optional< OptimizationLevel > parseOptLevel(StringRef S)
static bool isLoopPassName(StringRef Name, CallbacksT &Callbacks, bool &UseMemorySSA)
static std::optional< std::pair< bool, bool > > parseFunctionPipelineName(StringRef Name)
static bool isCGSCCPassName(StringRef Name, CallbacksT &Callbacks)
static void printPassName(StringRef PassName, raw_ostream &OS)
static bool isFunctionPassName(StringRef Name, CallbacksT &Callbacks)
static const Regex DefaultAliasRegex("^(default|thinlto-pre-link|thinlto|lto-pre-link|lto)<(O[0123sz])>$")
This header defines various interfaces for pass management in LLVM.
This file implements the PredicateInfo analysis, which creates an Extended SSA form for operations us...
This file implements relative lookup table converter that converts lookup tables to relative lookup t...
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file provides the interface for LLVM's Scalar Replacement of Aggregates pass.
raw_pwrite_stream & OS
This file provides the interface for the pseudo probe implementation for AutoFDO.
This file provides the interface for the sampled PGO loader pass.
This is the interface for a SCEV-based alias analysis.
This pass converts vector operations into scalar operations (or, optionally, operations on smaller ve...
This is the interface for a metadata-based scoped no-alias analysis.
This file contains the declaration of the SelectOptimizePass class, its corresponding pass name is se...
This file provides the interface for the pass responsible for both simplifying and canonicalizing the...
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
Target-Independent Code Generator Pass Configuration Options pass.
This pass exposes codegen information to IR-level passes.
This is the interface for a metadata-based TBAA.
Defines an IR pass for type promotion.
LLVM IR instance of the generic uniformity analysis.
static const char PassName[]
Value * RHS
A manager for alias analyses.
Class for arbitrary precision integers.
Definition: APInt.h:76
uint64_t getZExtValue() const
Get zero extended value.
Definition: APInt.h:1498
int64_t getSExtValue() const
Get sign extended value.
Definition: APInt.h:1520
A container for analyses that lazily runs them and caches their results.
Definition: PassManager.h:321
bool registerPass(PassBuilderT &&PassBuilder)
Register an analysis pass with the manager.
Definition: PassManager.h:535
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
LLVM Basic Block Representation.
Definition: BasicBlock.h:60
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Definition: BasicBlock.h:221
Lightweight error class with error context and mandatory checking.
Definition: Error.h:160
static ErrorSuccess success()
Create a success value.
Definition: Error.h:334
Tagged union holding either a T or a Error.
Definition: Error.h:474
static GlobalAlias * create(Type *Ty, unsigned AddressSpace, LinkageTypes Linkage, const Twine &Name, Constant *Aliasee, Module *Parent)
If a parent module is specified, the alias is automatically inserted into the end of the specified mo...
Definition: Globals.cpp:530
An analysis over an "outer" IR unit that provides access to an analysis manager over an "inner" IR un...
Definition: PassManager.h:631
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
Definition: LowLevelType.h:42
Properties which a MachineFunction may have at a given point in time.
MachineFunctionProperties & set(Property P)
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const MachineFunctionProperties & getProperties() const
Get the function properties.
A Module instance is used to store all the information related to an LLVM module.
Definition: Module.h:65
static const OptimizationLevel O3
Optimize for fast execution as much as possible.
static const OptimizationLevel Oz
A very specialized mode that will optimize for code size at any and all costs.
static const OptimizationLevel O0
Disable as many optimizations as possible.
static const OptimizationLevel Os
Similar to O2 but tries to optimize for small code size instead of fast execution without triggering ...
static const OptimizationLevel O2
Optimize for fast execution as much as possible without triggering significant incremental compile ti...
static const OptimizationLevel O1
Optimize quickly without destroying debuggability.
void printPassNames(raw_ostream &OS)
Print pass names.
static bool checkParametrizedPassName(StringRef Name, StringRef PassName)
Definition: PassBuilder.h:629
AAManager buildDefaultAAPipeline()
Build the default AAManager with the default alias analysis pipeline registered.
Error parseAAPipeline(AAManager &AA, StringRef PipelineText)
Parse a textual alias analysis pipeline into the provided AA manager.
ModulePassManager buildThinLTOPreLinkDefaultPipeline(OptimizationLevel Level)
Build a pre-link, ThinLTO-targeting default optimization pipeline to a pass manager.
PassBuilder(TargetMachine *TM=nullptr, PipelineTuningOptions PTO=PipelineTuningOptions(), std::optional< PGOOptions > PGOOpt=std::nullopt, PassInstrumentationCallbacks *PIC=nullptr)
void registerLoopAnalyses(LoopAnalysisManager &LAM)
Registers all available loop analysis passes.
void crossRegisterProxies(LoopAnalysisManager &LAM, FunctionAnalysisManager &FAM, CGSCCAnalysisManager &CGAM, ModuleAnalysisManager &MAM, MachineFunctionAnalysisManager *MFAM=nullptr)
Cross register the analysis managers through their proxies.
ModulePassManager buildPerModuleDefaultPipeline(OptimizationLevel Level, bool LTOPreLink=false)
Build a per-module default optimization pipeline.
Error parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText)
Parse a textual pass pipeline description into a ModulePassManager.
ModulePassManager buildLTODefaultPipeline(OptimizationLevel Level, ModuleSummaryIndex *ExportSummary)
Build an LTO default optimization pipeline to a pass manager.
ModulePassManager buildThinLTODefaultPipeline(OptimizationLevel Level, const ModuleSummaryIndex *ImportSummary)
Build a ThinLTO default optimization pipeline to a pass manager.
void registerModuleAnalyses(ModuleAnalysisManager &MAM)
Registers all available module analysis passes.
void registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM)
Registers all available CGSCC analysis passes.
static Expected< bool > parseSinglePassOption(StringRef Params, StringRef OptionName, StringRef PassName)
Handle passes only accept one bool-valued parameter.
void registerMachineFunctionAnalyses(MachineFunctionAnalysisManager &MFAM)
Registers all available machine function analysis passes.
void registerParseTopLevelPipelineCallback(const std::function< bool(ModulePassManager &, ArrayRef< PipelineElement >)> &C)
Register a callback for a top-level pipeline entry.
ModulePassManager buildLTOPreLinkDefaultPipeline(OptimizationLevel Level)
Build a pre-link, LTO-targeting default optimization pipeline to a pass manager.
void registerFunctionAnalyses(FunctionAnalysisManager &FAM)
Registers all available function analysis passes.
This class manages callbacks registration, as well as provides a way for PassInstrumentation to pass ...
LLVM_ATTRIBUTE_MINSIZE std::enable_if_t< is_detected< HasRunOnLoopT, PassT >::value > addPass(PassT &&Pass)
LLVM_ATTRIBUTE_MINSIZE void addPass(PassT &&Pass)
Definition: PassManager.h:249
Tunable parameters for passes in the default pipelines.
Definition: PassBuilder.h:42
bool SLPVectorization
Tuning option to enable/disable slp loop vectorization, set based on opt level.
Definition: PassBuilder.h:57
bool LoopVectorization
Tuning option to enable/disable loop vectorization, set based on opt level.
Definition: PassBuilder.h:53
static PointerType * getUnqual(Type *ElementType)
This constructs a pointer to an object of the specified type in the default address space (address sp...
Definition: DerivedTypes.h:662
A set of analyses that are preserved following a run of a transformation pass.
Definition: Analysis.h:109
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition: Analysis.h:112
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition: Analysis.h:115
bool match(StringRef String, SmallVectorImpl< StringRef > *Matches=nullptr, std::string *Error=nullptr) const
matches - Match the regex against a given String.
Definition: Regex.cpp:83
size_t size() const
Definition: SmallVector.h:91
void push_back(const T &Elt)
Definition: SmallVector.h:426
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1209
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition: StringRef.h:692
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
Definition: StringRef.h:462
std::string str() const
str - Get the contents as an std::string.
Definition: StringRef.h:222
constexpr bool empty() const
empty - Check if the string is empty.
Definition: StringRef.h:134
char front() const
front - Get the first character in the string.
Definition: StringRef.h:140
bool consume_front(StringRef Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
Definition: StringRef.h:627
A switch()-like statement whose cases are string literals.
Definition: StringSwitch.h:44
StringSwitch & Case(StringLiteral S, T Value)
Definition: StringSwitch.h:69
R Default(T Value)
Definition: StringSwitch.h:182
Primary interface to the complete machine description for the target machine.
Definition: TargetMachine.h:76
static bool hasLimitedCodeGenPipeline()
Returns true if one of the -start-after, -start-before, -stop-after or -stop-before options is set.
This function has undefined behavior.
self_iterator getIterator()
Definition: ilist_node.h:109
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition: raw_ostream.h:52
Interfaces for registering analysis passes, producing common pass manager configurations,...
@ C
The default llvm calling convention, compatible with C.
Definition: CallingConv.h:34
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
std::vector< std::string > printAfterPasses()
ModuleToFunctionPassAdaptor createModuleToFunctionPassAdaptor(FunctionPassT &&Pass, bool EagerlyInvalidate=false)
A function to deduce a function pass type and wrap it in the templated adaptor.
Definition: PassManager.h:916
RepeatedPass< PassT > createRepeatedPass(int Count, PassT &&P)
Definition: PassManager.h:1050
DevirtSCCRepeatedPass createDevirtSCCRepeatedPass(CGSCCPassT &&Pass, int MaxIterations)
A function to deduce a function pass type and wrap it in the templated adaptor.
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition: Error.cpp:90
auto formatv(const char *Fmt, Ts &&...Vals) -> formatv_object< decltype(std::make_tuple(support::detail::build_format_adapter(std::forward< Ts >(Vals))...))>
OuterAnalysisManagerProxy< ModuleAnalysisManager, MachineFunction > ModuleAnalysisManagerMachineFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
OuterAnalysisManagerProxy< ModuleAnalysisManager, Function > ModuleAnalysisManagerFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
Definition: PassManager.h:866
InnerAnalysisManagerProxy< MachineFunctionAnalysisManager, Module > MachineFunctionAnalysisManagerModuleProxy
OuterAnalysisManagerProxy< ModuleAnalysisManager, LazyCallGraph::SCC, LazyCallGraph & > ModuleAnalysisManagerCGSCCProxy
A proxy from a ModuleAnalysisManager to an SCC.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1729
std::vector< std::string > printBeforePasses()
ModuleToPostOrderCGSCCPassAdaptor createModuleToPostOrderCGSCCPassAdaptor(CGSCCPassT &&Pass)
A function to deduce a function pass type and wrap it in the templated adaptor.
CGSCCToFunctionPassAdaptor createCGSCCToFunctionPassAdaptor(FunctionPassT &&Pass, bool EagerlyInvalidate=false, bool NoRerun=false)
A function to deduce a function pass type and wrap it in the templated adaptor.
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
Definition: PassManager.h:712
FunctionToMachineFunctionPassAdaptor createFunctionToMachineFunctionPassAdaptor(MachineFunctionPassT &&Pass)
InnerAnalysisManagerProxy< MachineFunctionAnalysisManager, Function > MachineFunctionAnalysisManagerFunctionProxy
cl::opt< bool > PrintPipelinePasses("print-pipeline-passes", cl::desc("Print a '-passes' compatible string describing the pipeline " "(best-effort only)."))
OuterAnalysisManagerProxy< FunctionAnalysisManager, Loop, LoopStandardAnalysisResults & > FunctionAnalysisManagerLoopProxy
A proxy from a FunctionAnalysisManager to a Loop.
OuterAnalysisManagerProxy< CGSCCAnalysisManager, Function > CGSCCAnalysisManagerFunctionProxy
A proxy from a CGSCCAnalysisManager to a Function.
std::enable_if_t< is_detected< HasRunOnLoopT, LoopPassT >::value, FunctionToLoopPassAdaptor > createFunctionToLoopPassAdaptor(LoopPassT &&Pass, bool UseMemorySSA=false, bool UseBlockFrequencyInfo=false, bool UseBranchProbabilityInfo=false)
A function to deduce a loop pass type and wrap it in the templated adaptor.
bool isFilterPassesEmpty()
@ Enable
Enable colors.
A special type used by analysis passes to provide an address that identifies that particular analysis...
Definition: Analysis.h:26
A set of parameters to control various transforms performed by GVN pass.
Definition: GVN.h:74
HardwareLoopOptions & setForceNested(bool Force)
Definition: HardwareLoops.h:45
HardwareLoopOptions & setDecrement(unsigned Count)
Definition: HardwareLoops.h:29
HardwareLoopOptions & setForceGuard(bool Force)
Definition: HardwareLoops.h:49
HardwareLoopOptions & setForce(bool Force)
Definition: HardwareLoops.h:37
HardwareLoopOptions & setCounterBitwidth(unsigned Width)
Definition: HardwareLoops.h:33
HardwareLoopOptions & setForcePhi(bool Force)
Definition: HardwareLoops.h:41
A set of parameters to control various transforms performed by IPSCCP pass.
Definition: SCCP.h:35
A set of parameters used to control various transforms performed by the LoopUnroll pass.
LoopUnrollOptions & setPeeling(bool Peeling)
Enables or disables loop peeling.
LoopUnrollOptions & setOptLevel(int O)
LoopUnrollOptions & setPartial(bool Partial)
Enables or disables partial unrolling.
LoopUnrollOptions & setFullUnrollMaxCount(unsigned O)
LoopUnrollOptions & setUpperBound(bool UpperBound)
Enables or disables the use of trip count upper bound in loop unrolling.
LoopUnrollOptions & setRuntime(bool Runtime)
Enables or disables unrolling of loops with runtime trip count.
LoopUnrollOptions & setProfileBasedPeeling(int O)
LoopVectorizeOptions & setVectorizeOnlyWhenForced(bool Value)
LoopVectorizeOptions & setInterleaveOnlyWhenForced(bool Value)
A CRTP mix-in to automatically provide informational APIs needed for passes.
Definition: PassManager.h:74
static StringRef name()
Gets the name of the pass we are mixed into.
Definition: PassManager.h:76