LLVM 23.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"
53#include "llvm/Analysis/Lint.h"
143#include "llvm/CodeGen/PEI.h"
186#include "llvm/IR/DebugInfo.h"
187#include "llvm/IR/Dominators.h"
188#include "llvm/IR/PassManager.h"
190#include "llvm/IR/Verifier.h"
193#include "llvm/Support/CodeGen.h"
195#include "llvm/Support/Debug.h"
196#include "llvm/Support/Error.h"
199#include "llvm/Support/Regex.h"
391#include <optional>
392
393using namespace llvm;
394
396 "print-pipeline-passes",
397 cl::desc("Print a '-passes' compatible string describing the pipeline "
398 "(best-effort only)."));
399
400AnalysisKey NoOpModuleAnalysis::Key;
401AnalysisKey NoOpCGSCCAnalysis::Key;
402AnalysisKey NoOpFunctionAnalysis::Key;
403AnalysisKey NoOpLoopAnalysis::Key;
404
405namespace {
406
407// Passes for testing crashes.
408// DO NOT USE THIS EXCEPT FOR TESTING!
409class TriggerCrashModulePass : public PassInfoMixin<TriggerCrashModulePass> {
410public:
411 PreservedAnalyses run(Module &, ModuleAnalysisManager &) {
412 abort();
413 return PreservedAnalyses::all();
414 }
415 static StringRef name() { return "TriggerCrashModulePass"; }
416};
417
418class TriggerCrashFunctionPass
419 : public PassInfoMixin<TriggerCrashFunctionPass> {
420public:
421 PreservedAnalyses run(Function &, FunctionAnalysisManager &) {
422 abort();
423 return PreservedAnalyses::all();
424 }
425 static StringRef name() { return "TriggerCrashFunctionPass"; }
426};
427
428// A pass for testing message reporting of -verify-each failures.
429// DO NOT USE THIS EXCEPT FOR TESTING!
430class TriggerVerifierErrorPass
431 : public PassInfoMixin<TriggerVerifierErrorPass> {
432public:
433 PreservedAnalyses run(Module &M, ModuleAnalysisManager &) {
434 // Intentionally break the Module by creating an alias without setting the
435 // aliasee.
436 auto *PtrTy = PointerType::getUnqual(M.getContext());
437 GlobalAlias::create(PtrTy, PtrTy->getAddressSpace(),
438 GlobalValue::LinkageTypes::InternalLinkage,
439 "__bad_alias", nullptr, &M);
441 }
442
443 PreservedAnalyses run(Function &F, FunctionAnalysisManager &) {
444 // Intentionally break the Function by inserting a terminator
445 // instruction in the middle of a basic block.
446 BasicBlock &BB = F.getEntryBlock();
447 new UnreachableInst(F.getContext(), BB.getTerminator()->getIterator());
449 }
450
451 PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &) {
452 // Intentionally create a virtual register and set NoVRegs property.
453 auto &MRI = MF.getRegInfo();
455 MF.getProperties().setNoVRegs();
456 return PreservedAnalyses::all();
457 }
458
459 static StringRef name() { return "TriggerVerifierErrorPass"; }
460};
461
462// A pass requires all MachineFunctionProperties.
463// DO NOT USE THIS EXCEPT FOR TESTING!
464class RequireAllMachineFunctionPropertiesPass
465 : public PassInfoMixin<RequireAllMachineFunctionPropertiesPass> {
466public:
467 PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &) {
468 MFPropsModifier _(*this, MF);
470 }
471
472 static MachineFunctionProperties getRequiredProperties() {
473 return MachineFunctionProperties()
474 .setFailedISel()
475 .setFailsVerification()
476 .setIsSSA()
477 .setLegalized()
478 .setNoPHIs()
479 .setNoVRegs()
480 .setRegBankSelected()
481 .setSelected()
482 .setTiedOpsRewritten()
483 .setTracksDebugUserValues()
484 .setTracksLiveness();
485 }
486 static StringRef name() { return "RequireAllMachineFunctionPropertiesPass"; }
487};
488
489} // namespace
490
491static std::optional<OptimizationLevel> parseOptLevel(StringRef S) {
492 if (S == "Os" || S == "Oz")
494 Twine("The optimization level \"") + S +
495 "\" is no longer supported. Use O2 in conjunction with the " +
496 (S == "Os" ? "optsize" : "minsize") + " attribute instead.");
497
499 .Case("O0", OptimizationLevel::O0)
503 .Default(std::nullopt);
504}
505
507 std::optional<OptimizationLevel> OptLevel = parseOptLevel(S);
508 if (OptLevel)
509 return *OptLevel;
511 formatv("invalid optimization level '{}'", S).str(),
513}
514
516 std::optional<PGOOptions> PGOOpt,
519 : TM(TM), PTO(PTO), PGOOpt(PGOOpt), PIC(PIC), FS(std::move(FS)) {
520 if (TM)
521 TM->registerPassBuilderCallbacks(*this);
522 if (PIC) {
523 PIC->registerClassToPassNameCallback([this, PIC]() {
524 // MSVC requires this to be captured if it's used inside decltype.
525 // Other compilers consider it an unused lambda capture.
526 (void)this;
527#define MODULE_PASS(NAME, CREATE_PASS) \
528 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
529#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
530 PIC->addClassToPassName(CLASS, NAME);
531#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
532 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
533#define FUNCTION_PASS(NAME, CREATE_PASS) \
534 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
535#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
536 PIC->addClassToPassName(CLASS, NAME);
537#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
538 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
539#define LOOPNEST_PASS(NAME, CREATE_PASS) \
540 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
541#define LOOP_PASS(NAME, CREATE_PASS) \
542 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
543#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
544 PIC->addClassToPassName(CLASS, NAME);
545#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
546 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
547#define CGSCC_PASS(NAME, CREATE_PASS) \
548 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
549#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
550 PIC->addClassToPassName(CLASS, NAME);
551#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
552 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
553#include "PassRegistry.def"
554
555#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
556 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
557#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
558 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
559#define MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, \
560 PARAMS) \
561 PIC->addClassToPassName(CLASS, NAME);
562#include "llvm/Passes/MachinePassRegistry.def"
563 });
564 }
565
566 // Module-level callbacks without LTO phase
568 [this](StringRef Name, ModulePassManager &PM,
570#define MODULE_CALLBACK(NAME, INVOKE) \
571 if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
572 auto L = PassBuilder::parsePassParameters(parseOptLevelParam, Name, NAME); \
573 if (!L) { \
574 errs() << NAME ": " << toString(L.takeError()) << '\n'; \
575 return false; \
576 } \
577 INVOKE(PM, L.get()); \
578 return true; \
579 }
580#include "PassRegistry.def"
581 return false;
582 });
583
584 // Module-level callbacks with LTO phase (use Phase::None for string API)
586 [this](StringRef Name, ModulePassManager &PM,
588#define MODULE_LTO_CALLBACK(NAME, INVOKE) \
589 if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
590 auto L = PassBuilder::parsePassParameters(parseOptLevelParam, Name, NAME); \
591 if (!L) { \
592 errs() << NAME ": " << toString(L.takeError()) << '\n'; \
593 return false; \
594 } \
595 INVOKE(PM, L.get(), ThinOrFullLTOPhase::None); \
596 return true; \
597 }
598#include "PassRegistry.def"
599 return false;
600 });
601
602 // Function-level callbacks
604 [this](StringRef Name, FunctionPassManager &PM,
606#define FUNCTION_CALLBACK(NAME, INVOKE) \
607 if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
608 auto L = PassBuilder::parsePassParameters(parseOptLevelParam, Name, NAME); \
609 if (!L) { \
610 errs() << NAME ": " << toString(L.takeError()) << '\n'; \
611 return false; \
612 } \
613 INVOKE(PM, L.get()); \
614 return true; \
615 }
616#include "PassRegistry.def"
617 return false;
618 });
619
620 // CGSCC-level callbacks
622 [this](StringRef Name, CGSCCPassManager &PM,
624#define CGSCC_CALLBACK(NAME, INVOKE) \
625 if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
626 auto L = PassBuilder::parsePassParameters(parseOptLevelParam, Name, NAME); \
627 if (!L) { \
628 errs() << NAME ": " << toString(L.takeError()) << '\n'; \
629 return false; \
630 } \
631 INVOKE(PM, L.get()); \
632 return true; \
633 }
634#include "PassRegistry.def"
635 return false;
636 });
637
638 // Loop-level callbacks
640 [this](StringRef Name, LoopPassManager &PM,
642#define LOOP_CALLBACK(NAME, INVOKE) \
643 if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
644 auto L = PassBuilder::parsePassParameters(parseOptLevelParam, Name, NAME); \
645 if (!L) { \
646 errs() << NAME ": " << toString(L.takeError()) << '\n'; \
647 return false; \
648 } \
649 INVOKE(PM, L.get()); \
650 return true; \
651 }
652#include "PassRegistry.def"
653 return false;
654 });
655}
656
658#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
659 MAM.registerPass([&] { return CREATE_PASS; });
660#include "PassRegistry.def"
661
662 for (auto &C : ModuleAnalysisRegistrationCallbacks)
663 C(MAM);
664}
665
667#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
668 CGAM.registerPass([&] { return CREATE_PASS; });
669#include "PassRegistry.def"
670
671 for (auto &C : CGSCCAnalysisRegistrationCallbacks)
672 C(CGAM);
673}
674
676 // We almost always want the default alias analysis pipeline.
677 // If a user wants a different one, they can register their own before calling
678 // registerFunctionAnalyses().
679 FAM.registerPass([&] { return buildDefaultAAPipeline(); });
680
681#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
682 if constexpr (std::is_constructible_v< \
683 std::remove_reference_t<decltype(CREATE_PASS)>, \
684 const TargetMachine &>) { \
685 if (TM) \
686 FAM.registerPass([&] { return CREATE_PASS; }); \
687 } else { \
688 FAM.registerPass([&] { return CREATE_PASS; }); \
689 }
690#include "PassRegistry.def"
691
692 for (auto &C : FunctionAnalysisRegistrationCallbacks)
693 C(FAM);
694}
695
698
699#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
700 MFAM.registerPass([&] { return CREATE_PASS; });
701#include "llvm/Passes/MachinePassRegistry.def"
702
703 for (auto &C : MachineFunctionAnalysisRegistrationCallbacks)
704 C(MFAM);
705}
706
708#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
709 LAM.registerPass([&] { return CREATE_PASS; });
710#include "PassRegistry.def"
711
712 for (auto &C : LoopAnalysisRegistrationCallbacks)
713 C(LAM);
714}
715
716static std::optional<std::pair<bool, bool>>
718 std::pair<bool, bool> Params;
719 if (!Name.consume_front("function"))
720 return std::nullopt;
721 if (Name.empty())
722 return Params;
723 if (!Name.consume_front("<") || !Name.consume_back(">"))
724 return std::nullopt;
725 while (!Name.empty()) {
726 auto [Front, Back] = Name.split(';');
727 Name = Back;
728 if (Front == "eager-inv")
729 Params.first = true;
730 else if (Front == "no-rerun")
731 Params.second = true;
732 else
733 return std::nullopt;
734 }
735 return Params;
736}
737
738static std::optional<int> parseDevirtPassName(StringRef Name) {
739 if (!Name.consume_front("devirt<") || !Name.consume_back(">"))
740 return std::nullopt;
741 int Count;
742 if (Name.getAsInteger(0, Count) || Count < 0)
743 return std::nullopt;
744 return Count;
745}
746
748 StringRef OptionName,
750 bool Result = false;
751 while (!Params.empty()) {
752 StringRef ParamName;
753 std::tie(ParamName, Params) = Params.split(';');
754
755 if (ParamName == OptionName) {
756 Result = true;
757 } else {
759 formatv("invalid {} pass parameter '{}'", PassName, ParamName).str(),
761 }
762 }
763 return Result;
764}
765
766namespace {
767
768/// Parser of parameters for HardwareLoops pass.
769Expected<HardwareLoopOptions> parseHardwareLoopOptions(StringRef Params) {
770 HardwareLoopOptions HardwareLoopOpts;
771
772 while (!Params.empty()) {
773 StringRef ParamName;
774 std::tie(ParamName, Params) = Params.split(';');
775 if (ParamName.consume_front("hardware-loop-decrement=")) {
776 int Count;
777 if (ParamName.getAsInteger(0, Count))
779 formatv("invalid HardwareLoopPass parameter '{}'", ParamName).str(),
781 HardwareLoopOpts.setDecrement(Count);
782 continue;
783 }
784 if (ParamName.consume_front("hardware-loop-counter-bitwidth=")) {
785 int Count;
786 if (ParamName.getAsInteger(0, Count))
788 formatv("invalid HardwareLoopPass parameter '{}'", ParamName).str(),
790 HardwareLoopOpts.setCounterBitwidth(Count);
791 continue;
792 }
793 if (ParamName == "force-hardware-loops") {
794 HardwareLoopOpts.setForce(true);
795 } else if (ParamName == "force-hardware-loop-phi") {
796 HardwareLoopOpts.setForcePhi(true);
797 } else if (ParamName == "force-nested-hardware-loop") {
798 HardwareLoopOpts.setForceNested(true);
799 } else if (ParamName == "force-hardware-loop-guard") {
800 HardwareLoopOpts.setForceGuard(true);
801 } else {
803 formatv("invalid HardwarePass parameter '{}'", ParamName).str(),
805 }
806 }
807 return HardwareLoopOpts;
808}
809
810/// Parser of parameters for Lint pass.
811Expected<bool> parseLintOptions(StringRef Params) {
812 return PassBuilder::parseSinglePassOption(Params, "abort-on-error",
813 "LintPass");
814}
815
816/// Parser of parameters for FunctionPropertiesStatistics pass.
817Expected<bool> parseFunctionPropertiesStatisticsOptions(StringRef Params) {
818 return PassBuilder::parseSinglePassOption(Params, "pre-opt",
819 "FunctionPropertiesStatisticsPass");
820}
821
822/// Parser of parameters for InstCount pass.
823Expected<bool> parseInstCountOptions(StringRef Params) {
824 return PassBuilder::parseSinglePassOption(Params, "pre-opt", "InstCountPass");
825}
826
827/// Parser of parameters for LoopUnroll pass.
828Expected<LoopUnrollOptions> parseLoopUnrollOptions(StringRef Params) {
829 LoopUnrollOptions UnrollOpts;
830 while (!Params.empty()) {
831 StringRef ParamName;
832 std::tie(ParamName, Params) = Params.split(';');
833 std::optional<OptimizationLevel> OptLevel = parseOptLevel(ParamName);
834 if (OptLevel) {
835 UnrollOpts.setOptLevel(OptLevel->getSpeedupLevel());
836 continue;
837 }
838 if (ParamName.consume_front("full-unroll-max=")) {
839 int Count;
840 if (ParamName.getAsInteger(0, Count))
842 formatv("invalid LoopUnrollPass parameter '{}'", ParamName).str(),
844 UnrollOpts.setFullUnrollMaxCount(Count);
845 continue;
846 }
847
848 bool Enable = !ParamName.consume_front("no-");
849 if (ParamName == "partial") {
850 UnrollOpts.setPartial(Enable);
851 } else if (ParamName == "peeling") {
852 UnrollOpts.setPeeling(Enable);
853 } else if (ParamName == "profile-peeling") {
854 UnrollOpts.setProfileBasedPeeling(Enable);
855 } else if (ParamName == "runtime") {
856 UnrollOpts.setRuntime(Enable);
857 } else if (ParamName == "upperbound") {
858 UnrollOpts.setUpperBound(Enable);
859 } else {
861 formatv("invalid LoopUnrollPass parameter '{}'", ParamName).str(),
863 }
864 }
865 return UnrollOpts;
866}
867
868Expected<bool> parseGlobalDCEPassOptions(StringRef Params) {
870 Params, "vfe-linkage-unit-visibility", "GlobalDCE");
871}
872
873Expected<bool> parseCGProfilePassOptions(StringRef Params) {
874 return PassBuilder::parseSinglePassOption(Params, "in-lto-post-link",
875 "CGProfile");
876}
877
878Expected<bool> parseInlinerPassOptions(StringRef Params) {
879 return PassBuilder::parseSinglePassOption(Params, "only-mandatory",
880 "InlinerPass");
881}
882
883Expected<bool> parseCoroSplitPassOptions(StringRef Params) {
884 return PassBuilder::parseSinglePassOption(Params, "reuse-storage",
885 "CoroSplitPass");
886}
887
888Expected<bool> parsePostOrderFunctionAttrsPassOptions(StringRef Params) {
890 Params, "skip-non-recursive-function-attrs", "PostOrderFunctionAttrs");
891}
892
893Expected<bool> parseEarlyCSEPassOptions(StringRef Params) {
894 return PassBuilder::parseSinglePassOption(Params, "memssa", "EarlyCSE");
895}
896
897Expected<bool> parseEntryExitInstrumenterPassOptions(StringRef Params) {
898 return PassBuilder::parseSinglePassOption(Params, "post-inline",
899 "EntryExitInstrumenter");
900}
901
902Expected<bool> parseDropUnnecessaryAssumesPassOptions(StringRef Params) {
903 return PassBuilder::parseSinglePassOption(Params, "drop-deref",
904 "DropUnnecessaryAssumes");
905}
906
907Expected<bool> parseLoopExtractorPassOptions(StringRef Params) {
908 return PassBuilder::parseSinglePassOption(Params, "single", "LoopExtractor");
909}
910
911Expected<bool> parseLowerMatrixIntrinsicsPassOptions(StringRef Params) {
912 return PassBuilder::parseSinglePassOption(Params, "minimal",
913 "LowerMatrixIntrinsics");
914}
915
916Expected<IRNormalizerOptions> parseIRNormalizerPassOptions(StringRef Params) {
918 while (!Params.empty()) {
919 StringRef ParamName;
920 std::tie(ParamName, Params) = Params.split(';');
921
922 bool Enable = !ParamName.consume_front("no-");
923 if (ParamName == "preserve-order")
924 Result.PreserveOrder = Enable;
925 else if (ParamName == "rename-all")
926 Result.RenameAll = Enable;
927 else if (ParamName == "fold-all") // FIXME: Name mismatch
928 Result.FoldPreOutputs = Enable;
929 else if (ParamName == "reorder-operands")
930 Result.ReorderOperands = Enable;
931 else {
933 formatv("invalid normalize pass parameter '{}'", ParamName).str(),
935 }
936 }
937
938 return Result;
939}
940
941Expected<AddressSanitizerOptions> parseASanPassOptions(StringRef Params) {
943 while (!Params.empty()) {
944 StringRef ParamName;
945 std::tie(ParamName, Params) = Params.split(';');
946
947 if (ParamName == "kernel") {
948 Result.CompileKernel = true;
949 } else if (ParamName == "use-after-scope") {
950 Result.UseAfterScope = true;
951 } else {
953 formatv("invalid AddressSanitizer pass parameter '{}'", ParamName)
954 .str(),
956 }
957 }
958 return Result;
959}
960
961Expected<HWAddressSanitizerOptions> parseHWASanPassOptions(StringRef Params) {
963 while (!Params.empty()) {
964 StringRef ParamName;
965 std::tie(ParamName, Params) = Params.split(';');
966
967 if (ParamName == "recover") {
968 Result.Recover = true;
969 } else if (ParamName == "kernel") {
970 Result.CompileKernel = true;
971 } else {
973 formatv("invalid HWAddressSanitizer pass parameter '{}'", ParamName)
974 .str(),
976 }
977 }
978 return Result;
979}
980
982parseDropTypeTestsPassOptions(StringRef Params) {
984 while (!Params.empty()) {
985 StringRef ParamName;
986 std::tie(ParamName, Params) = Params.split(';');
987
988 if (ParamName == "all") {
990 } else if (ParamName == "assume") {
992 } else {
994 formatv("invalid DropTypeTestsPass parameter '{}'", ParamName).str(),
996 }
997 }
998 return Result;
999}
1000
1001Expected<EmbedBitcodeOptions> parseEmbedBitcodePassOptions(StringRef Params) {
1003 while (!Params.empty()) {
1004 StringRef ParamName;
1005 std::tie(ParamName, Params) = Params.split(';');
1006
1007 if (ParamName == "thinlto") {
1008 Result.IsThinLTO = true;
1009 } else if (ParamName == "emit-summary") {
1010 Result.EmitLTOSummary = true;
1011 } else {
1013 formatv("invalid EmbedBitcode pass parameter '{}'", ParamName).str(),
1015 }
1016 }
1017 return Result;
1018}
1019
1021parseLowerAllowCheckPassOptions(StringRef Params) {
1023 while (!Params.empty()) {
1024 StringRef ParamName;
1025 std::tie(ParamName, Params) = Params.split(';');
1026
1027 // Format is <cutoffs[1,2,3]=70000;cutoffs[5,6,8]=90000>
1028 //
1029 // Parsing allows duplicate indices (last one takes precedence).
1030 // It would technically be in spec to specify
1031 // cutoffs[0]=70000,cutoffs[1]=90000,cutoffs[0]=80000,...
1032 if (ParamName.starts_with("cutoffs[")) {
1033 StringRef IndicesStr;
1034 StringRef CutoffStr;
1035
1036 std::tie(IndicesStr, CutoffStr) = ParamName.split("]=");
1037 // cutoffs[1,2,3
1038 // 70000
1039
1040 int cutoff;
1041 if (CutoffStr.getAsInteger(0, cutoff))
1043 formatv("invalid LowerAllowCheck pass cutoffs parameter '{}' ({})",
1044 CutoffStr, Params)
1045 .str(),
1047
1048 if (!IndicesStr.consume_front("cutoffs[") || IndicesStr == "")
1050 formatv("invalid LowerAllowCheck pass index parameter '{}' ({})",
1051 IndicesStr, CutoffStr)
1052 .str(),
1054
1055 while (IndicesStr != "") {
1056 StringRef firstIndexStr;
1057 std::tie(firstIndexStr, IndicesStr) = IndicesStr.split('|');
1058
1059 unsigned int index;
1060 if (firstIndexStr.getAsInteger(0, index))
1062 formatv(
1063 "invalid LowerAllowCheck pass index parameter '{}' ({}) {}",
1064 firstIndexStr, IndicesStr)
1065 .str(),
1067
1068 // In the common case (sequentially increasing indices), we will issue
1069 // O(n) resize requests. We assume the underlying data structure has
1070 // O(1) runtime for each added element.
1071 if (index >= Result.cutoffs.size())
1072 Result.cutoffs.resize(index + 1, 0);
1073
1074 Result.cutoffs[index] = cutoff;
1075 }
1076 } else if (ParamName.starts_with("runtime_check")) {
1077 StringRef ValueString;
1078 std::tie(std::ignore, ValueString) = ParamName.split("=");
1079 int runtime_check;
1080 if (ValueString.getAsInteger(0, runtime_check)) {
1082 formatv("invalid LowerAllowCheck pass runtime_check parameter '{}' "
1083 "({})",
1084 ValueString, Params)
1085 .str(),
1087 }
1088 Result.runtime_check = runtime_check;
1089 } else {
1091 formatv("invalid LowerAllowCheck pass parameter '{}'", ParamName)
1092 .str(),
1094 }
1095 }
1096
1097 return Result;
1098}
1099
1100Expected<MemorySanitizerOptions> parseMSanPassOptions(StringRef Params) {
1102 while (!Params.empty()) {
1103 StringRef ParamName;
1104 std::tie(ParamName, Params) = Params.split(';');
1105
1106 if (ParamName == "recover") {
1107 Result.Recover = true;
1108 } else if (ParamName == "kernel") {
1109 Result.Kernel = true;
1110 } else if (ParamName.consume_front("track-origins=")) {
1111 if (ParamName.getAsInteger(0, Result.TrackOrigins))
1113 formatv("invalid argument to MemorySanitizer pass track-origins "
1114 "parameter: '{}'",
1115 ParamName)
1116 .str(),
1118 } else if (ParamName == "eager-checks") {
1119 Result.EagerChecks = true;
1120 } else {
1122 formatv("invalid MemorySanitizer pass parameter '{}'", ParamName)
1123 .str(),
1125 }
1126 }
1127 return Result;
1128}
1129
1130Expected<AllocTokenOptions> parseAllocTokenPassOptions(StringRef Params) {
1132 while (!Params.empty()) {
1133 StringRef ParamName;
1134 std::tie(ParamName, Params) = Params.split(';');
1135
1136 if (ParamName.consume_front("mode=")) {
1137 if (auto Mode = getAllocTokenModeFromString(ParamName))
1138 Result.Mode = *Mode;
1139 else
1141 formatv("invalid argument to AllocToken pass mode "
1142 "parameter: '{}'",
1143 ParamName)
1144 .str(),
1146 } else {
1148 formatv("invalid AllocToken pass parameter '{}'", ParamName).str(),
1150 }
1151 }
1152 return Result;
1153}
1154
1155/// Parser of parameters for SimplifyCFG pass.
1156Expected<SimplifyCFGOptions> parseSimplifyCFGOptions(StringRef Params) {
1158 while (!Params.empty()) {
1159 StringRef ParamName;
1160 std::tie(ParamName, Params) = Params.split(';');
1161
1162 bool Enable = !ParamName.consume_front("no-");
1163 if (ParamName == "speculate-blocks") {
1164 Result.speculateBlocks(Enable);
1165 } else if (ParamName == "simplify-cond-branch") {
1166 Result.setSimplifyCondBranch(Enable);
1167 } else if (ParamName == "forward-switch-cond") {
1168 Result.forwardSwitchCondToPhi(Enable);
1169 } else if (ParamName == "switch-range-to-icmp") {
1170 Result.convertSwitchRangeToICmp(Enable);
1171 } else if (ParamName == "switch-to-arithmetic") {
1172 Result.convertSwitchToArithmetic(Enable);
1173 } else if (ParamName == "switch-to-lookup") {
1174 Result.convertSwitchToLookupTable(Enable);
1175 } else if (ParamName == "keep-loops") {
1176 Result.needCanonicalLoops(Enable);
1177 } else if (ParamName == "hoist-common-insts") {
1178 Result.hoistCommonInsts(Enable);
1179 } else if (ParamName == "hoist-loads-stores-with-cond-faulting") {
1180 Result.hoistLoadsStoresWithCondFaulting(Enable);
1181 } else if (ParamName == "sink-common-insts") {
1182 Result.sinkCommonInsts(Enable);
1183 } else if (ParamName == "speculate-unpredictables") {
1184 Result.speculateUnpredictables(Enable);
1185 } else if (Enable && ParamName.consume_front("bonus-inst-threshold=")) {
1186 APInt BonusInstThreshold;
1187 if (ParamName.getAsInteger(0, BonusInstThreshold))
1189 formatv("invalid argument to SimplifyCFG pass bonus-threshold "
1190 "parameter: '{}'",
1191 ParamName)
1192 .str(),
1194 Result.bonusInstThreshold(BonusInstThreshold.getSExtValue());
1195 } else {
1197 formatv("invalid SimplifyCFG pass parameter '{}'", ParamName).str(),
1199 }
1200 }
1201 return Result;
1202}
1203
1204Expected<InstCombineOptions> parseInstCombineOptions(StringRef Params) {
1206 // When specifying "instcombine" in -passes enable fix-point verification by
1207 // default, as this is what most tests should use.
1208 Result.setVerifyFixpoint(true);
1209 while (!Params.empty()) {
1210 StringRef ParamName;
1211 std::tie(ParamName, Params) = Params.split(';');
1212
1213 bool Enable = !ParamName.consume_front("no-");
1214 if (ParamName == "verify-fixpoint") {
1215 Result.setVerifyFixpoint(Enable);
1216 } else if (Enable && ParamName.consume_front("max-iterations=")) {
1217 APInt MaxIterations;
1218 if (ParamName.getAsInteger(0, MaxIterations))
1220 formatv("invalid argument to InstCombine pass max-iterations "
1221 "parameter: '{}'",
1222 ParamName)
1223 .str(),
1225 Result.setMaxIterations((unsigned)MaxIterations.getZExtValue());
1226 } else {
1228 formatv("invalid InstCombine pass parameter '{}'", ParamName).str(),
1230 }
1231 }
1232 return Result;
1233}
1234
1235/// Parser of parameters for LoopVectorize pass.
1236Expected<LoopVectorizeOptions> parseLoopVectorizeOptions(StringRef Params) {
1238 while (!Params.empty()) {
1239 StringRef ParamName;
1240 std::tie(ParamName, Params) = Params.split(';');
1241
1242 bool Enable = !ParamName.consume_front("no-");
1243 if (ParamName == "interleave-forced-only") {
1245 } else if (ParamName == "vectorize-forced-only") {
1247 } else {
1249 formatv("invalid LoopVectorize parameter '{}'", ParamName).str(),
1251 }
1252 }
1253 return Opts;
1254}
1255
1256Expected<std::pair<bool, bool>> parseLoopUnswitchOptions(StringRef Params) {
1257 std::pair<bool, bool> Result = {false, true};
1258 while (!Params.empty()) {
1259 StringRef ParamName;
1260 std::tie(ParamName, Params) = Params.split(';');
1261
1262 bool Enable = !ParamName.consume_front("no-");
1263 if (ParamName == "nontrivial") {
1264 Result.first = Enable;
1265 } else if (ParamName == "trivial") {
1266 Result.second = Enable;
1267 } else {
1269 formatv("invalid LoopUnswitch pass parameter '{}'", ParamName).str(),
1271 }
1272 }
1273 return Result;
1274}
1275
1276Expected<LICMOptions> parseLICMOptions(StringRef Params) {
1278 while (!Params.empty()) {
1279 StringRef ParamName;
1280 std::tie(ParamName, Params) = Params.split(';');
1281
1282 bool Enable = !ParamName.consume_front("no-");
1283 if (ParamName == "allowspeculation") {
1284 Result.AllowSpeculation = Enable;
1285 } else {
1287 formatv("invalid LICM pass parameter '{}'", ParamName).str(),
1289 }
1290 }
1291 return Result;
1292}
1293
1294struct LoopRotateOptions {
1295 bool EnableHeaderDuplication = true;
1296 bool PrepareForLTO = false;
1297 bool CheckExitCount = false;
1298};
1299
1300Expected<LoopRotateOptions> parseLoopRotateOptions(StringRef Params) {
1301 LoopRotateOptions Result;
1302 while (!Params.empty()) {
1303 StringRef ParamName;
1304 std::tie(ParamName, Params) = Params.split(';');
1305
1306 bool Enable = !ParamName.consume_front("no-");
1307 if (ParamName == "header-duplication") {
1308 Result.EnableHeaderDuplication = Enable;
1309 } else if (ParamName == "prepare-for-lto") {
1310 Result.PrepareForLTO = Enable;
1311 } else if (ParamName == "check-exit-count") {
1312 Result.CheckExitCount = Enable;
1313 } else {
1315 formatv("invalid LoopRotate pass parameter '{}'", ParamName).str(),
1317 }
1318 }
1319 return Result;
1320}
1321
1322Expected<bool> parseMergedLoadStoreMotionOptions(StringRef Params) {
1323 bool Result = false;
1324 while (!Params.empty()) {
1325 StringRef ParamName;
1326 std::tie(ParamName, Params) = Params.split(';');
1327
1328 bool Enable = !ParamName.consume_front("no-");
1329 if (ParamName == "split-footer-bb") {
1330 Result = Enable;
1331 } else {
1333 formatv("invalid MergedLoadStoreMotion pass parameter '{}'",
1334 ParamName)
1335 .str(),
1337 }
1338 }
1339 return Result;
1340}
1341
1342Expected<GVNOptions> parseGVNOptions(StringRef Params) {
1344 while (!Params.empty()) {
1345 StringRef ParamName;
1346 std::tie(ParamName, Params) = Params.split(';');
1347
1348 bool Enable = !ParamName.consume_front("no-");
1349 if (ParamName == "pre") {
1350 Result.setPRE(Enable);
1351 } else if (ParamName == "load-pre") {
1352 Result.setLoadPRE(Enable);
1353 } else if (ParamName == "split-backedge-load-pre") {
1354 Result.setLoadPRESplitBackedge(Enable);
1355 } else if (ParamName == "memdep") {
1356 // MemDep and MemorySSA are mutually exclusive.
1357 Result.setMemDep(Enable);
1358 Result.setMemorySSA(!Enable);
1359 } else if (ParamName == "memoryssa") {
1360 // MemDep and MemorySSA are mutually exclusive.
1361 Result.setMemorySSA(Enable);
1362 Result.setMemDep(!Enable);
1363 } else {
1365 formatv("invalid GVN pass parameter '{}'", ParamName).str(),
1367 }
1368 }
1369 return Result;
1370}
1371
1372Expected<IPSCCPOptions> parseIPSCCPOptions(StringRef Params) {
1374 while (!Params.empty()) {
1375 StringRef ParamName;
1376 std::tie(ParamName, Params) = Params.split(';');
1377
1378 bool Enable = !ParamName.consume_front("no-");
1379 if (ParamName == "func-spec")
1380 Result.setFuncSpec(Enable);
1381 else
1383 formatv("invalid IPSCCP pass parameter '{}'", ParamName).str(),
1385 }
1386 return Result;
1387}
1388
1389Expected<ScalarizerPassOptions> parseScalarizerOptions(StringRef Params) {
1391 while (!Params.empty()) {
1392 StringRef ParamName;
1393 std::tie(ParamName, Params) = Params.split(';');
1394
1395 if (ParamName.consume_front("min-bits=")) {
1396 if (ParamName.getAsInteger(0, Result.ScalarizeMinBits)) {
1398 formatv("invalid argument to Scalarizer pass min-bits "
1399 "parameter: '{}'",
1400 ParamName)
1401 .str(),
1403 }
1404
1405 continue;
1406 }
1407
1408 bool Enable = !ParamName.consume_front("no-");
1409 if (ParamName == "load-store")
1410 Result.ScalarizeLoadStore = Enable;
1411 else if (ParamName == "variable-insert-extract")
1412 Result.ScalarizeVariableInsertExtract = Enable;
1413 else {
1415 formatv("invalid Scalarizer pass parameter '{}'", ParamName).str(),
1417 }
1418 }
1419
1420 return Result;
1421}
1422
1423Expected<SROAOptions> parseSROAOptions(StringRef Params) {
1424 if (Params.empty() || Params == "modify-cfg")
1426 if (Params == "preserve-cfg")
1429 formatv("invalid SROA pass parameter '{}' (either preserve-cfg or "
1430 "modify-cfg can be specified)",
1431 Params)
1432 .str(),
1434}
1435
1437parseStackLifetimeOptions(StringRef Params) {
1439 while (!Params.empty()) {
1440 StringRef ParamName;
1441 std::tie(ParamName, Params) = Params.split(';');
1442
1443 if (ParamName == "may") {
1445 } else if (ParamName == "must") {
1447 } else {
1449 formatv("invalid StackLifetime parameter '{}'", ParamName).str(),
1451 }
1452 }
1453 return Result;
1454}
1455
1456Expected<bool> parseDependenceAnalysisPrinterOptions(StringRef Params) {
1457 return PassBuilder::parseSinglePassOption(Params, "normalized-results",
1458 "DependenceAnalysisPrinter");
1459}
1460
1461Expected<bool> parseSeparateConstOffsetFromGEPPassOptions(StringRef Params) {
1462 return PassBuilder::parseSinglePassOption(Params, "lower-gep",
1463 "SeparateConstOffsetFromGEP");
1464}
1465
1466Expected<bool> parseStructurizeCFGPassOptions(StringRef Params) {
1467 return PassBuilder::parseSinglePassOption(Params, "skip-uniform-regions",
1468 "StructurizeCFG");
1469}
1470
1472parseFunctionSimplificationPipelineOptions(StringRef Params) {
1473 std::optional<OptimizationLevel> L = parseOptLevel(Params);
1474 if (!L || *L == OptimizationLevel::O0) {
1476 formatv("invalid function-simplification parameter '{}'", Params).str(),
1478 };
1479 return *L;
1480}
1481
1482Expected<bool> parseMemorySSAPrinterPassOptions(StringRef Params) {
1483 return PassBuilder::parseSinglePassOption(Params, "no-ensure-optimized-uses",
1484 "MemorySSAPrinterPass");
1485}
1486
1487Expected<bool> parseSpeculativeExecutionPassOptions(StringRef Params) {
1488 return PassBuilder::parseSinglePassOption(Params, "only-if-divergent-target",
1489 "SpeculativeExecutionPass");
1490}
1491
1492Expected<std::string> parseMemProfUsePassOptions(StringRef Params) {
1493 std::string Result;
1494 while (!Params.empty()) {
1495 StringRef ParamName;
1496 std::tie(ParamName, Params) = Params.split(';');
1497
1498 if (ParamName.consume_front("profile-filename=")) {
1499 Result = ParamName.str();
1500 } else {
1502 formatv("invalid MemProfUse pass parameter '{}'", ParamName).str(),
1504 }
1505 }
1506 return Result;
1507}
1508
1510parseStructuralHashPrinterPassOptions(StringRef Params) {
1511 if (Params.empty())
1513 if (Params == "detailed")
1515 if (Params == "call-target-ignored")
1518 formatv("invalid structural hash printer parameter '{}'", Params).str(),
1520}
1521
1522Expected<bool> parseWinEHPrepareOptions(StringRef Params) {
1523 return PassBuilder::parseSinglePassOption(Params, "demote-catchswitch-only",
1524 "WinEHPreparePass");
1525}
1526
1527Expected<GlobalMergeOptions> parseGlobalMergeOptions(StringRef Params) {
1529 while (!Params.empty()) {
1530 StringRef ParamName;
1531 std::tie(ParamName, Params) = Params.split(';');
1532
1533 bool Enable = !ParamName.consume_front("no-");
1534 if (ParamName == "group-by-use")
1535 Result.GroupByUse = Enable;
1536 else if (ParamName == "ignore-single-use")
1537 Result.IgnoreSingleUse = Enable;
1538 else if (ParamName == "merge-const")
1539 Result.MergeConstantGlobals = Enable;
1540 else if (ParamName == "merge-const-aggressive")
1541 Result.MergeConstAggressive = Enable;
1542 else if (ParamName == "merge-external")
1543 Result.MergeExternal = Enable;
1544 else if (ParamName.consume_front("max-offset=")) {
1545 if (ParamName.getAsInteger(0, Result.MaxOffset))
1547 formatv("invalid GlobalMergePass parameter '{}'", ParamName).str(),
1549 } else {
1551 formatv("invalid global-merge pass parameter '{}'", Params).str(),
1553 }
1554 }
1555 return Result;
1556}
1557
1558Expected<SmallVector<std::string, 0>> parseInternalizeGVs(StringRef Params) {
1559 SmallVector<std::string, 1> PreservedGVs;
1560 while (!Params.empty()) {
1561 StringRef ParamName;
1562 std::tie(ParamName, Params) = Params.split(';');
1563
1564 if (ParamName.consume_front("preserve-gv=")) {
1565 PreservedGVs.push_back(ParamName.str());
1566 } else {
1568 formatv("invalid Internalize pass parameter '{}'", ParamName).str(),
1570 }
1571 }
1572
1573 return Expected<SmallVector<std::string, 0>>(std::move(PreservedGVs));
1574}
1575
1577parseRegAllocFastPassOptions(PassBuilder &PB, StringRef Params) {
1579 while (!Params.empty()) {
1580 StringRef ParamName;
1581 std::tie(ParamName, Params) = Params.split(';');
1582
1583 if (ParamName.consume_front("filter=")) {
1584 std::optional<RegAllocFilterFunc> Filter =
1585 PB.parseRegAllocFilter(ParamName);
1586 if (!Filter) {
1588 formatv("invalid regallocfast register filter '{}'", ParamName)
1589 .str(),
1591 }
1592 Opts.Filter = *Filter;
1593 Opts.FilterName = ParamName;
1594 continue;
1595 }
1596
1597 if (ParamName == "no-clear-vregs") {
1598 Opts.ClearVRegs = false;
1599 continue;
1600 }
1601
1603 formatv("invalid regallocfast pass parameter '{}'", ParamName).str(),
1605 }
1606 return Opts;
1607}
1608
1610parseBoundsCheckingOptions(StringRef Params) {
1612 while (!Params.empty()) {
1613 StringRef ParamName;
1614 std::tie(ParamName, Params) = Params.split(';');
1615 if (ParamName == "trap") {
1616 Options.Rt = std::nullopt;
1617 } else if (ParamName == "rt") {
1618 Options.Rt = {
1619 /*MinRuntime=*/false,
1620 /*MayReturn=*/true,
1621 /*HandlerPreserveAllRegs=*/false,
1622 };
1623 } else if (ParamName == "rt-abort") {
1624 Options.Rt = {
1625 /*MinRuntime=*/false,
1626 /*MayReturn=*/false,
1627 /*HandlerPreserveAllRegs=*/false,
1628 };
1629 } else if (ParamName == "min-rt") {
1630 Options.Rt = {
1631 /*MinRuntime=*/true,
1632 /*MayReturn=*/true,
1633 /*HandlerPreserveAllRegs=*/false,
1634 };
1635 } else if (ParamName == "min-rt-abort") {
1636 Options.Rt = {
1637 /*MinRuntime=*/true,
1638 /*MayReturn=*/false,
1639 /*HandlerPreserveAllRegs=*/false,
1640 };
1641 } else if (ParamName == "merge") {
1642 Options.Merge = true;
1643 } else if (ParamName == "handler-preserve-all-regs") {
1644 if (Options.Rt)
1645 Options.Rt->HandlerPreserveAllRegs = true;
1646 } else {
1647 StringRef ParamEQ;
1648 StringRef Val;
1649 std::tie(ParamEQ, Val) = ParamName.split('=');
1650 int8_t Id;
1651 if (ParamEQ == "guard" && !Val.getAsInteger(0, Id)) {
1652 Options.GuardKind = Id;
1653 } else {
1655 formatv("invalid BoundsChecking pass parameter '{}'", ParamName)
1656 .str(),
1658 }
1659 }
1660 }
1661 return Options;
1662}
1663
1664Expected<CodeGenOptLevel> parseExpandIRInstsOptions(StringRef Param) {
1665 if (Param.empty())
1666 return CodeGenOptLevel::None;
1667
1668 // Parse a CodeGenOptLevel, e.g. "O1", "O2", "O3".
1669 auto [Prefix, Digit] = Param.split('O');
1670
1671 uint8_t N;
1672 if (!Prefix.empty() || Digit.getAsInteger(10, N))
1673 return createStringError("invalid expand-ir-insts pass parameter '%s'",
1674 Param.str().c_str());
1675
1676 std::optional<CodeGenOptLevel> Level = CodeGenOpt::getLevel(N);
1677 if (!Level.has_value())
1678 return createStringError(
1679 "invalid optimization level for expand-ir-insts pass: %s",
1680 Digit.str().c_str());
1681
1682 return *Level;
1683}
1684
1686parseRegAllocGreedyFilterFunc(PassBuilder &PB, StringRef Params) {
1687 if (Params.empty() || Params == "all")
1688 return RAGreedyPass::Options();
1689
1690 std::optional<RegAllocFilterFunc> Filter = PB.parseRegAllocFilter(Params);
1691 if (Filter)
1692 return RAGreedyPass::Options{*Filter, Params};
1693
1695 formatv("invalid regallocgreedy register filter '{}'", Params).str(),
1697}
1698
1699Expected<bool> parseMachineSinkingPassOptions(StringRef Params) {
1700 return PassBuilder::parseSinglePassOption(Params, "enable-sink-fold",
1701 "MachineSinkingPass");
1702}
1703
1704Expected<bool> parseMachineBlockPlacementPassOptions(StringRef Params) {
1705 bool AllowTailMerge = true;
1706 if (!Params.empty()) {
1707 AllowTailMerge = !Params.consume_front("no-");
1708 if (Params != "tail-merge")
1710 formatv("invalid MachineBlockPlacementPass parameter '{}'", Params)
1711 .str(),
1713 }
1714 return AllowTailMerge;
1715}
1716
1717Expected<bool> parseVirtRegRewriterPassOptions(StringRef Params) {
1718 bool ClearVirtRegs = true;
1719 if (!Params.empty()) {
1720 ClearVirtRegs = !Params.consume_front("no-");
1721 if (Params != "clear-vregs")
1723 formatv("invalid VirtRegRewriter pass parameter '{}'", Params).str(),
1725 }
1726 return ClearVirtRegs;
1727}
1728
1729struct FatLTOOptions {
1730 OptimizationLevel OptLevel;
1731 bool ThinLTO = false;
1732 bool EmitSummary = false;
1733};
1734
1735Expected<FatLTOOptions> parseFatLTOOptions(StringRef Params) {
1736 FatLTOOptions Result;
1737 bool HaveOptLevel = false;
1738 while (!Params.empty()) {
1739 StringRef ParamName;
1740 std::tie(ParamName, Params) = Params.split(';');
1741
1742 if (ParamName == "thinlto") {
1743 Result.ThinLTO = true;
1744 } else if (ParamName == "emit-summary") {
1745 Result.EmitSummary = true;
1746 } else if (std::optional<OptimizationLevel> OptLevel =
1747 parseOptLevel(ParamName)) {
1748 Result.OptLevel = *OptLevel;
1749 HaveOptLevel = true;
1750 } else {
1752 formatv("invalid fatlto-pre-link pass parameter '{}'", ParamName)
1753 .str(),
1755 }
1756 }
1757 if (!HaveOptLevel)
1759 "missing optimization level for fatlto-pre-link pipeline",
1761 return Result;
1762}
1763
1764} // namespace
1765
1766/// Tests whether registered callbacks will accept a given pass name.
1767///
1768/// When parsing a pipeline text, the type of the outermost pipeline may be
1769/// omitted, in which case the type is automatically determined from the first
1770/// pass name in the text. This may be a name that is handled through one of the
1771/// callbacks. We check this through the oridinary parsing callbacks by setting
1772/// up a dummy PassManager in order to not force the client to also handle this
1773/// type of query.
1774template <typename PassManagerT, typename CallbacksT>
1775static bool callbacksAcceptPassName(StringRef Name, CallbacksT &Callbacks) {
1776 if (!Callbacks.empty()) {
1777 PassManagerT DummyPM;
1778 for (auto &CB : Callbacks)
1779 if (CB(Name, DummyPM, {}))
1780 return true;
1781 }
1782 return false;
1783}
1784
1785template <typename CallbacksT>
1786static bool isModulePassName(StringRef Name, CallbacksT &Callbacks) {
1787 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1788
1789 // Explicitly handle pass manager names.
1790 if (Name == "module")
1791 return true;
1792 if (Name == "cgscc")
1793 return true;
1794 if (NameNoBracket == "function")
1795 return true;
1796 if (Name == "coro-cond")
1797 return true;
1798
1799#define MODULE_PASS(NAME, CREATE_PASS) \
1800 if (Name == NAME) \
1801 return true;
1802#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1803 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1804 return true;
1805#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
1806 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1807 return true;
1808#include "PassRegistry.def"
1809
1810 return callbacksAcceptPassName<ModulePassManager>(Name, Callbacks);
1811}
1812
1813template <typename CallbacksT>
1814static bool isCGSCCPassName(StringRef Name, CallbacksT &Callbacks) {
1815 // Explicitly handle pass manager names.
1816 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1817 if (Name == "cgscc")
1818 return true;
1819 if (NameNoBracket == "function")
1820 return true;
1821
1822 // Explicitly handle custom-parsed pass names.
1823 if (parseDevirtPassName(Name))
1824 return true;
1825
1826#define CGSCC_PASS(NAME, CREATE_PASS) \
1827 if (Name == NAME) \
1828 return true;
1829#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1830 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1831 return true;
1832#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
1833 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1834 return true;
1835#include "PassRegistry.def"
1836
1837 return callbacksAcceptPassName<CGSCCPassManager>(Name, Callbacks);
1838}
1839
1840template <typename CallbacksT>
1841static bool isFunctionPassName(StringRef Name, CallbacksT &Callbacks) {
1842 // Explicitly handle pass manager names.
1843 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1844 if (NameNoBracket == "function")
1845 return true;
1846 if (Name == "loop" || Name == "loop-mssa" || Name == "machine-function")
1847 return true;
1848
1849#define FUNCTION_PASS(NAME, CREATE_PASS) \
1850 if (Name == NAME) \
1851 return true;
1852#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1853 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1854 return true;
1855#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1856 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1857 return true;
1858#include "PassRegistry.def"
1859
1860 return callbacksAcceptPassName<FunctionPassManager>(Name, Callbacks);
1861}
1862
1863template <typename CallbacksT>
1864static bool isMachineFunctionPassName(StringRef Name, CallbacksT &Callbacks) {
1865 // Explicitly handle pass manager names.
1866 if (Name == "machine-function")
1867 return true;
1868
1869#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
1870 if (Name == NAME) \
1871 return true;
1872#define MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, \
1873 PARAMS) \
1874 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1875 return true;
1876
1877#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1878 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1879 return true;
1880
1881#include "llvm/Passes/MachinePassRegistry.def"
1882
1884}
1885
1886template <typename CallbacksT>
1887static bool isLoopNestPassName(StringRef Name, CallbacksT &Callbacks,
1888 bool &UseMemorySSA) {
1889 UseMemorySSA = false;
1890
1891 if (PassBuilder::checkParametrizedPassName(Name, "lnicm")) {
1892 UseMemorySSA = true;
1893 return true;
1894 }
1895
1896#define LOOPNEST_PASS(NAME, CREATE_PASS) \
1897 if (Name == NAME) \
1898 return true;
1899#include "PassRegistry.def"
1900
1901 return callbacksAcceptPassName<LoopPassManager>(Name, Callbacks);
1902}
1903
1904template <typename CallbacksT>
1905static bool isLoopPassName(StringRef Name, CallbacksT &Callbacks,
1906 bool &UseMemorySSA) {
1907 UseMemorySSA = false;
1908
1909 if (PassBuilder::checkParametrizedPassName(Name, "licm")) {
1910 UseMemorySSA = true;
1911 return true;
1912 }
1913
1914#define LOOP_PASS(NAME, CREATE_PASS) \
1915 if (Name == NAME) \
1916 return true;
1917#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1918 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1919 return true;
1920#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
1921 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1922 return true;
1923#include "PassRegistry.def"
1924
1925 return callbacksAcceptPassName<LoopPassManager>(Name, Callbacks);
1926}
1927
1928std::optional<std::vector<PassBuilder::PipelineElement>>
1929PassBuilder::parsePipelineText(StringRef Text) {
1930 std::vector<PipelineElement> ResultPipeline;
1931
1932 SmallVector<std::vector<PipelineElement> *, 4> PipelineStack = {
1933 &ResultPipeline};
1934 for (;;) {
1935 std::vector<PipelineElement> &Pipeline = *PipelineStack.back();
1936 size_t Pos = Text.find_first_of(",()");
1937 Pipeline.push_back({Text.substr(0, Pos), {}});
1938
1939 // If we have a single terminating name, we're done.
1940 if (Pos == Text.npos)
1941 break;
1942
1943 char Sep = Text[Pos];
1944 Text = Text.substr(Pos + 1);
1945 if (Sep == ',')
1946 // Just a name ending in a comma, continue.
1947 continue;
1948
1949 if (Sep == '(') {
1950 // Push the inner pipeline onto the stack to continue processing.
1951 PipelineStack.push_back(&Pipeline.back().InnerPipeline);
1952 continue;
1953 }
1954
1955 assert(Sep == ')' && "Bogus separator!");
1956 // When handling the close parenthesis, we greedily consume them to avoid
1957 // empty strings in the pipeline.
1958 do {
1959 // If we try to pop the outer pipeline we have unbalanced parentheses.
1960 if (PipelineStack.size() == 1)
1961 return std::nullopt;
1962
1963 PipelineStack.pop_back();
1964 } while (Text.consume_front(")"));
1965
1966 // Check if we've finished parsing.
1967 if (Text.empty())
1968 break;
1969
1970 // Otherwise, the end of an inner pipeline always has to be followed by
1971 // a comma, and then we can continue.
1972 if (!Text.consume_front(","))
1973 return std::nullopt;
1974 }
1975
1976 if (PipelineStack.size() > 1)
1977 // Unbalanced paretheses.
1978 return std::nullopt;
1979
1980 assert(PipelineStack.back() == &ResultPipeline &&
1981 "Wrong pipeline at the bottom of the stack!");
1982 return {std::move(ResultPipeline)};
1983}
1984
1987 PTO.LoopVectorization = L.getSpeedupLevel() > 1;
1988 PTO.SLPVectorization = L.getSpeedupLevel() > 1;
1989}
1990
1991Error PassBuilder::parseModulePass(ModulePassManager &MPM,
1992 const PipelineElement &E) {
1993 auto &Name = E.Name;
1994 auto &InnerPipeline = E.InnerPipeline;
1995
1996 // First handle complex passes like the pass managers which carry pipelines.
1997 if (!InnerPipeline.empty()) {
1998 if (Name == "module") {
1999 ModulePassManager NestedMPM;
2000 if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline))
2001 return Err;
2002 MPM.addPass(std::move(NestedMPM));
2003 return Error::success();
2004 }
2005 if (Name == "coro-cond") {
2006 ModulePassManager NestedMPM;
2007 if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline))
2008 return Err;
2009 MPM.addPass(CoroConditionalWrapper(std::move(NestedMPM)));
2010 return Error::success();
2011 }
2012 if (Name == "cgscc") {
2013 CGSCCPassManager CGPM;
2014 if (auto Err = parseCGSCCPassPipeline(CGPM, InnerPipeline))
2015 return Err;
2017 return Error::success();
2018 }
2019 if (auto Params = parseFunctionPipelineName(Name)) {
2020 if (Params->second)
2022 "cannot have a no-rerun module to function adaptor",
2025 if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline))
2026 return Err;
2027 MPM.addPass(
2028 createModuleToFunctionPassAdaptor(std::move(FPM), Params->first));
2029 return Error::success();
2030 }
2031
2032 for (auto &C : ModulePipelineParsingCallbacks)
2033 if (C(Name, MPM, InnerPipeline))
2034 return Error::success();
2035
2036 // Normal passes can't have pipelines.
2038 formatv("invalid use of '{}' pass as module pipeline", Name).str(),
2040 ;
2041 }
2042
2043 // Finally expand the basic registered passes from the .inc file.
2044#define MODULE_PASS(NAME, CREATE_PASS) \
2045 if (Name == NAME) { \
2046 MPM.addPass(CREATE_PASS); \
2047 return Error::success(); \
2048 }
2049#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2050 if (checkParametrizedPassName(Name, NAME)) { \
2051 auto Params = parsePassParameters(PARSER, Name, NAME); \
2052 if (!Params) \
2053 return Params.takeError(); \
2054 MPM.addPass(CREATE_PASS(Params.get())); \
2055 return Error::success(); \
2056 }
2057#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
2058 if (Name == "require<" NAME ">") { \
2059 MPM.addPass( \
2060 RequireAnalysisPass< \
2061 std::remove_reference_t<decltype(CREATE_PASS)>, Module>()); \
2062 return Error::success(); \
2063 } \
2064 if (Name == "invalidate<" NAME ">") { \
2065 MPM.addPass(InvalidateAnalysisPass< \
2066 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2067 return Error::success(); \
2068 }
2069#define CGSCC_PASS(NAME, CREATE_PASS) \
2070 if (Name == NAME) { \
2071 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(CREATE_PASS)); \
2072 return Error::success(); \
2073 }
2074#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2075 if (checkParametrizedPassName(Name, NAME)) { \
2076 auto Params = parsePassParameters(PARSER, Name, NAME); \
2077 if (!Params) \
2078 return Params.takeError(); \
2079 MPM.addPass( \
2080 createModuleToPostOrderCGSCCPassAdaptor(CREATE_PASS(Params.get()))); \
2081 return Error::success(); \
2082 }
2083#define FUNCTION_PASS(NAME, CREATE_PASS) \
2084 if (Name == NAME) { \
2085 if constexpr (std::is_constructible_v< \
2086 std::remove_reference_t<decltype(CREATE_PASS)>, \
2087 const TargetMachine &>) { \
2088 if (!TM) \
2089 return make_error<StringError>( \
2090 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2091 inconvertibleErrorCode()); \
2092 } \
2093 MPM.addPass(createModuleToFunctionPassAdaptor(CREATE_PASS)); \
2094 return Error::success(); \
2095 }
2096#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2097 if (checkParametrizedPassName(Name, NAME)) { \
2098 auto Params = parsePassParameters(PARSER, Name, NAME); \
2099 if (!Params) \
2100 return Params.takeError(); \
2101 auto CreatePass = CREATE_PASS; \
2102 if constexpr (std::is_constructible_v< \
2103 std::remove_reference_t<decltype(CreatePass( \
2104 Params.get()))>, \
2105 const TargetMachine &, \
2106 std::remove_reference_t<decltype(Params.get())>>) { \
2107 if (!TM) { \
2108 return make_error<StringError>( \
2109 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2110 inconvertibleErrorCode()); \
2111 } \
2112 } \
2113 MPM.addPass(createModuleToFunctionPassAdaptor(CREATE_PASS(Params.get()))); \
2114 return Error::success(); \
2115 }
2116#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2117 if (Name == NAME) { \
2118 MPM.addPass(createModuleToFunctionPassAdaptor( \
2119 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2120 return Error::success(); \
2121 }
2122#define LOOP_PASS(NAME, CREATE_PASS) \
2123 if (Name == NAME) { \
2124 MPM.addPass(createModuleToFunctionPassAdaptor( \
2125 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2126 return Error::success(); \
2127 }
2128#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2129 if (checkParametrizedPassName(Name, NAME)) { \
2130 auto Params = parsePassParameters(PARSER, Name, NAME); \
2131 if (!Params) \
2132 return Params.takeError(); \
2133 MPM.addPass(createModuleToFunctionPassAdaptor( \
2134 createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), false))); \
2135 return Error::success(); \
2136 }
2137#include "PassRegistry.def"
2138
2139 for (auto &C : ModulePipelineParsingCallbacks)
2140 if (C(Name, MPM, InnerPipeline))
2141 return Error::success();
2143 formatv("unknown module pass '{}'", Name).str(),
2145}
2146
2147Error PassBuilder::parseCGSCCPass(CGSCCPassManager &CGPM,
2148 const PipelineElement &E) {
2149 auto &Name = E.Name;
2150 auto &InnerPipeline = E.InnerPipeline;
2151
2152 // First handle complex passes like the pass managers which carry pipelines.
2153 if (!InnerPipeline.empty()) {
2154 if (Name == "cgscc") {
2155 CGSCCPassManager NestedCGPM;
2156 if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline))
2157 return Err;
2158 // Add the nested pass manager with the appropriate adaptor.
2159 CGPM.addPass(std::move(NestedCGPM));
2160 return Error::success();
2161 }
2162 if (auto Params = parseFunctionPipelineName(Name)) {
2164 if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline))
2165 return Err;
2166 // Add the nested pass manager with the appropriate adaptor.
2168 std::move(FPM), Params->first, Params->second));
2169 return Error::success();
2170 }
2171 if (auto MaxRepetitions = parseDevirtPassName(Name)) {
2172 CGSCCPassManager NestedCGPM;
2173 if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline))
2174 return Err;
2175 CGPM.addPass(
2176 createDevirtSCCRepeatedPass(std::move(NestedCGPM), *MaxRepetitions));
2177 return Error::success();
2178 }
2179
2180 for (auto &C : CGSCCPipelineParsingCallbacks)
2181 if (C(Name, CGPM, InnerPipeline))
2182 return Error::success();
2183
2184 // Normal passes can't have pipelines.
2186 formatv("invalid use of '{}' pass as cgscc pipeline", Name).str(),
2188 }
2189
2190// Now expand the basic registered passes from the .inc file.
2191#define CGSCC_PASS(NAME, CREATE_PASS) \
2192 if (Name == NAME) { \
2193 CGPM.addPass(CREATE_PASS); \
2194 return Error::success(); \
2195 }
2196#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2197 if (checkParametrizedPassName(Name, NAME)) { \
2198 auto Params = parsePassParameters(PARSER, Name, NAME); \
2199 if (!Params) \
2200 return Params.takeError(); \
2201 CGPM.addPass(CREATE_PASS(Params.get())); \
2202 return Error::success(); \
2203 }
2204#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
2205 if (Name == "require<" NAME ">") { \
2206 CGPM.addPass(RequireAnalysisPass< \
2207 std::remove_reference_t<decltype(CREATE_PASS)>, \
2208 LazyCallGraph::SCC, CGSCCAnalysisManager, LazyCallGraph &, \
2209 CGSCCUpdateResult &>()); \
2210 return Error::success(); \
2211 } \
2212 if (Name == "invalidate<" NAME ">") { \
2213 CGPM.addPass(InvalidateAnalysisPass< \
2214 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2215 return Error::success(); \
2216 }
2217#define FUNCTION_PASS(NAME, CREATE_PASS) \
2218 if (Name == NAME) { \
2219 if constexpr (std::is_constructible_v< \
2220 std::remove_reference_t<decltype(CREATE_PASS)>, \
2221 const TargetMachine &>) { \
2222 if (!TM) \
2223 return make_error<StringError>( \
2224 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2225 inconvertibleErrorCode()); \
2226 } \
2227 CGPM.addPass(createCGSCCToFunctionPassAdaptor(CREATE_PASS)); \
2228 return Error::success(); \
2229 }
2230#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2231 if (checkParametrizedPassName(Name, NAME)) { \
2232 auto Params = parsePassParameters(PARSER, Name, NAME); \
2233 if (!Params) \
2234 return Params.takeError(); \
2235 auto CreatePass = CREATE_PASS; \
2236 if constexpr (std::is_constructible_v< \
2237 std::remove_reference_t<decltype(CreatePass( \
2238 Params.get()))>, \
2239 const TargetMachine &, \
2240 std::remove_reference_t<decltype(Params.get())>>) { \
2241 if (!TM) { \
2242 return make_error<StringError>( \
2243 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2244 inconvertibleErrorCode()); \
2245 } \
2246 } \
2247 CGPM.addPass(createCGSCCToFunctionPassAdaptor(CREATE_PASS(Params.get()))); \
2248 return Error::success(); \
2249 }
2250#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2251 if (Name == NAME) { \
2252 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
2253 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2254 return Error::success(); \
2255 }
2256#define LOOP_PASS(NAME, CREATE_PASS) \
2257 if (Name == NAME) { \
2258 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
2259 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2260 return Error::success(); \
2261 }
2262#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2263 if (checkParametrizedPassName(Name, NAME)) { \
2264 auto Params = parsePassParameters(PARSER, Name, NAME); \
2265 if (!Params) \
2266 return Params.takeError(); \
2267 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
2268 createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), false))); \
2269 return Error::success(); \
2270 }
2271#include "PassRegistry.def"
2272
2273 for (auto &C : CGSCCPipelineParsingCallbacks)
2274 if (C(Name, CGPM, InnerPipeline))
2275 return Error::success();
2276 return make_error<StringError>(formatv("unknown cgscc pass '{}'", Name).str(),
2278}
2279
2280Error PassBuilder::parseFunctionPass(FunctionPassManager &FPM,
2281 const PipelineElement &E) {
2282 auto &Name = E.Name;
2283 auto &InnerPipeline = E.InnerPipeline;
2284
2285 // First handle complex passes like the pass managers which carry pipelines.
2286 if (!InnerPipeline.empty()) {
2287 if (Name == "function") {
2288 FunctionPassManager NestedFPM;
2289 if (auto Err = parseFunctionPassPipeline(NestedFPM, InnerPipeline))
2290 return Err;
2291 // Add the nested pass manager with the appropriate adaptor.
2292 FPM.addPass(std::move(NestedFPM));
2293 return Error::success();
2294 }
2295 if (Name == "loop" || Name == "loop-mssa") {
2296 LoopPassManager LPM;
2297 if (auto Err = parseLoopPassPipeline(LPM, InnerPipeline))
2298 return Err;
2299 // Add the nested pass manager with the appropriate adaptor.
2300 bool UseMemorySSA = (Name == "loop-mssa");
2301 FPM.addPass(
2302 createFunctionToLoopPassAdaptor(std::move(LPM), UseMemorySSA));
2303 return Error::success();
2304 }
2305 if (Name == "machine-function") {
2307 if (auto Err = parseMachinePassPipeline(MFPM, InnerPipeline))
2308 return Err;
2310 return Error::success();
2311 }
2312
2313 for (auto &C : FunctionPipelineParsingCallbacks)
2314 if (C(Name, FPM, InnerPipeline))
2315 return Error::success();
2316
2317 // Normal passes can't have pipelines.
2319 formatv("invalid use of '{}' pass as function pipeline", Name).str(),
2321 }
2322
2323// Now expand the basic registered passes from the .inc file.
2324#define FUNCTION_PASS(NAME, CREATE_PASS) \
2325 if (Name == NAME) { \
2326 if constexpr (std::is_constructible_v< \
2327 std::remove_reference_t<decltype(CREATE_PASS)>, \
2328 const TargetMachine &>) { \
2329 if (!TM) \
2330 return make_error<StringError>( \
2331 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2332 inconvertibleErrorCode()); \
2333 } \
2334 FPM.addPass(CREATE_PASS); \
2335 return Error::success(); \
2336 }
2337#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2338 if (checkParametrizedPassName(Name, NAME)) { \
2339 auto Params = parsePassParameters(PARSER, Name, NAME); \
2340 if (!Params) \
2341 return Params.takeError(); \
2342 auto CreatePass = CREATE_PASS; \
2343 if constexpr (std::is_constructible_v< \
2344 std::remove_reference_t<decltype(CreatePass( \
2345 Params.get()))>, \
2346 const TargetMachine &, \
2347 std::remove_reference_t<decltype(Params.get())>>) { \
2348 if (!TM) { \
2349 return make_error<StringError>( \
2350 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2351 inconvertibleErrorCode()); \
2352 } \
2353 } \
2354 FPM.addPass(CREATE_PASS(Params.get())); \
2355 return Error::success(); \
2356 }
2357#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
2358 if (Name == "require<" NAME ">") { \
2359 if constexpr (std::is_constructible_v< \
2360 std::remove_reference_t<decltype(CREATE_PASS)>, \
2361 const TargetMachine &>) { \
2362 if (!TM) \
2363 return make_error<StringError>( \
2364 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2365 inconvertibleErrorCode()); \
2366 } \
2367 FPM.addPass( \
2368 RequireAnalysisPass<std::remove_reference_t<decltype(CREATE_PASS)>, \
2369 Function>()); \
2370 return Error::success(); \
2371 } \
2372 if (Name == "invalidate<" NAME ">") { \
2373 FPM.addPass(InvalidateAnalysisPass< \
2374 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2375 return Error::success(); \
2376 }
2377// FIXME: UseMemorySSA is set to false. Maybe we could do things like:
2378// bool UseMemorySSA = !("canon-freeze" || "loop-predication" ||
2379// "guard-widening");
2380// The risk is that it may become obsolete if we're not careful.
2381#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2382 if (Name == NAME) { \
2383 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS, false)); \
2384 return Error::success(); \
2385 }
2386#define LOOP_PASS(NAME, CREATE_PASS) \
2387 if (Name == NAME) { \
2388 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS, false)); \
2389 return Error::success(); \
2390 }
2391#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2392 if (checkParametrizedPassName(Name, NAME)) { \
2393 auto Params = parsePassParameters(PARSER, Name, NAME); \
2394 if (!Params) \
2395 return Params.takeError(); \
2396 FPM.addPass( \
2397 createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), false)); \
2398 return Error::success(); \
2399 }
2400#include "PassRegistry.def"
2401
2402 for (auto &C : FunctionPipelineParsingCallbacks)
2403 if (C(Name, FPM, InnerPipeline))
2404 return Error::success();
2406 formatv("unknown function pass '{}'", Name).str(),
2408}
2409
2410Error PassBuilder::parseLoopPass(LoopPassManager &LPM,
2411 const PipelineElement &E) {
2412 StringRef Name = E.Name;
2413 auto &InnerPipeline = E.InnerPipeline;
2414
2415 // First handle complex passes like the pass managers which carry pipelines.
2416 if (!InnerPipeline.empty()) {
2417 if (Name == "loop") {
2418 LoopPassManager NestedLPM;
2419 if (auto Err = parseLoopPassPipeline(NestedLPM, InnerPipeline))
2420 return Err;
2421 // Add the nested pass manager with the appropriate adaptor.
2422 LPM.addPass(std::move(NestedLPM));
2423 return Error::success();
2424 }
2425
2426 for (auto &C : LoopPipelineParsingCallbacks)
2427 if (C(Name, LPM, InnerPipeline))
2428 return Error::success();
2429
2430 // Normal passes can't have pipelines.
2432 formatv("invalid use of '{}' pass as loop pipeline", Name).str(),
2434 }
2435
2436// Now expand the basic registered passes from the .inc file.
2437#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2438 if (Name == NAME) { \
2439 LPM.addPass(CREATE_PASS); \
2440 return Error::success(); \
2441 }
2442#define LOOP_PASS(NAME, CREATE_PASS) \
2443 if (Name == NAME) { \
2444 LPM.addPass(CREATE_PASS); \
2445 return Error::success(); \
2446 }
2447#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2448 if (checkParametrizedPassName(Name, NAME)) { \
2449 auto Params = parsePassParameters(PARSER, Name, NAME); \
2450 if (!Params) \
2451 return Params.takeError(); \
2452 LPM.addPass(CREATE_PASS(Params.get())); \
2453 return Error::success(); \
2454 }
2455#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
2456 if (Name == "require<" NAME ">") { \
2457 LPM.addPass(RequireAnalysisPass< \
2458 std::remove_reference_t<decltype(CREATE_PASS)>, Loop, \
2459 LoopAnalysisManager, LoopStandardAnalysisResults &, \
2460 LPMUpdater &>()); \
2461 return Error::success(); \
2462 } \
2463 if (Name == "invalidate<" NAME ">") { \
2464 LPM.addPass(InvalidateAnalysisPass< \
2465 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2466 return Error::success(); \
2467 }
2468#include "PassRegistry.def"
2469
2470 for (auto &C : LoopPipelineParsingCallbacks)
2471 if (C(Name, LPM, InnerPipeline))
2472 return Error::success();
2473 return make_error<StringError>(formatv("unknown loop pass '{}'", Name).str(),
2475}
2476
2477Error PassBuilder::parseMachinePass(MachineFunctionPassManager &MFPM,
2478 const PipelineElement &E) {
2479 StringRef Name = E.Name;
2480 // Handle any nested pass managers.
2481 if (!E.InnerPipeline.empty()) {
2482 if (E.Name == "machine-function") {
2484 if (auto Err = parseMachinePassPipeline(NestedPM, E.InnerPipeline))
2485 return Err;
2486 MFPM.addPass(std::move(NestedPM));
2487 return Error::success();
2488 }
2489 return make_error<StringError>("invalid pipeline",
2491 }
2492
2493#define MACHINE_MODULE_PASS(NAME, CREATE_PASS) \
2494 if (Name == NAME) { \
2495 MFPM.addPass(CREATE_PASS); \
2496 return Error::success(); \
2497 }
2498#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
2499 if (Name == NAME) { \
2500 MFPM.addPass(CREATE_PASS); \
2501 return Error::success(); \
2502 }
2503#define MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, \
2504 PARAMS) \
2505 if (checkParametrizedPassName(Name, NAME)) { \
2506 auto Params = parsePassParameters(PARSER, Name, NAME); \
2507 if (!Params) \
2508 return Params.takeError(); \
2509 MFPM.addPass(CREATE_PASS(Params.get())); \
2510 return Error::success(); \
2511 }
2512#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
2513 if (Name == "require<" NAME ">") { \
2514 MFPM.addPass( \
2515 RequireAnalysisPass<std::remove_reference_t<decltype(CREATE_PASS)>, \
2516 MachineFunction>()); \
2517 return Error::success(); \
2518 } \
2519 if (Name == "invalidate<" NAME ">") { \
2520 MFPM.addPass(InvalidateAnalysisPass< \
2521 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2522 return Error::success(); \
2523 }
2524#include "llvm/Passes/MachinePassRegistry.def"
2525
2526 for (auto &C : MachineFunctionPipelineParsingCallbacks)
2527 if (C(Name, MFPM, E.InnerPipeline))
2528 return Error::success();
2530 formatv("unknown machine pass '{}'", Name).str(),
2532}
2533
2534bool PassBuilder::parseAAPassName(AAManager &AA, StringRef Name) {
2535#define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
2536 if (Name == NAME) { \
2537 AA.registerModuleAnalysis< \
2538 std::remove_reference_t<decltype(CREATE_PASS)>>(); \
2539 return true; \
2540 }
2541#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
2542 if (Name == NAME) { \
2543 AA.registerFunctionAnalysis< \
2544 std::remove_reference_t<decltype(CREATE_PASS)>>(); \
2545 return true; \
2546 }
2547#include "PassRegistry.def"
2548
2549 for (auto &C : AAParsingCallbacks)
2550 if (C(Name, AA))
2551 return true;
2552 return false;
2553}
2554
2555Error PassBuilder::parseMachinePassPipeline(
2557 for (const auto &Element : Pipeline) {
2558 if (auto Err = parseMachinePass(MFPM, Element))
2559 return Err;
2560 }
2561 return Error::success();
2562}
2563
2564Error PassBuilder::parseLoopPassPipeline(LoopPassManager &LPM,
2565 ArrayRef<PipelineElement> Pipeline) {
2566 for (const auto &Element : Pipeline) {
2567 if (auto Err = parseLoopPass(LPM, Element))
2568 return Err;
2569 }
2570 return Error::success();
2571}
2572
2573Error PassBuilder::parseFunctionPassPipeline(
2575 for (const auto &Element : Pipeline) {
2576 if (auto Err = parseFunctionPass(FPM, Element))
2577 return Err;
2578 }
2579 return Error::success();
2580}
2581
2582Error PassBuilder::parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
2583 ArrayRef<PipelineElement> Pipeline) {
2584 for (const auto &Element : Pipeline) {
2585 if (auto Err = parseCGSCCPass(CGPM, Element))
2586 return Err;
2587 }
2588 return Error::success();
2589}
2590
2596 MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });
2597 MAM.registerPass([&] { return CGSCCAnalysisManagerModuleProxy(CGAM); });
2598 CGAM.registerPass([&] { return ModuleAnalysisManagerCGSCCProxy(MAM); });
2599 FAM.registerPass([&] { return CGSCCAnalysisManagerFunctionProxy(CGAM); });
2600 FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); });
2601 FAM.registerPass([&] { return LoopAnalysisManagerFunctionProxy(LAM); });
2602 LAM.registerPass([&] { return FunctionAnalysisManagerLoopProxy(FAM); });
2603 if (MFAM) {
2604 MAM.registerPass(
2605 [&] { return MachineFunctionAnalysisManagerModuleProxy(*MFAM); });
2606 FAM.registerPass(
2607 [&] { return MachineFunctionAnalysisManagerFunctionProxy(*MFAM); });
2608 MFAM->registerPass(
2610 MFAM->registerPass(
2612 }
2613}
2614
2615Error PassBuilder::parseModulePassPipeline(ModulePassManager &MPM,
2616 ArrayRef<PipelineElement> Pipeline) {
2617 for (const auto &Element : Pipeline) {
2618 if (auto Err = parseModulePass(MPM, Element))
2619 return Err;
2620 }
2621 return Error::success();
2622}
2623
2624// Primary pass pipeline description parsing routine for a \c ModulePassManager
2625// FIXME: Should this routine accept a TargetMachine or require the caller to
2626// pre-populate the analysis managers with target-specific stuff?
2628 StringRef PipelineText) {
2629 auto Pipeline = parsePipelineText(PipelineText);
2630 if (!Pipeline || Pipeline->empty())
2632 formatv("invalid pipeline '{}'", PipelineText).str(),
2634
2635 // If the first name isn't at the module layer, wrap the pipeline up
2636 // automatically.
2637 StringRef FirstName = Pipeline->front().Name;
2638
2639 if (!isModulePassName(FirstName, ModulePipelineParsingCallbacks)) {
2640 bool UseMemorySSA;
2641 if (isCGSCCPassName(FirstName, CGSCCPipelineParsingCallbacks)) {
2642 Pipeline = {{"cgscc", std::move(*Pipeline)}};
2643 } else if (isFunctionPassName(FirstName,
2644 FunctionPipelineParsingCallbacks)) {
2645 Pipeline = {{"function", std::move(*Pipeline)}};
2646 } else if (isLoopNestPassName(FirstName, LoopPipelineParsingCallbacks,
2647 UseMemorySSA)) {
2648 Pipeline = {{"function", {{UseMemorySSA ? "loop-mssa" : "loop",
2649 std::move(*Pipeline)}}}};
2650 } else if (isLoopPassName(FirstName, LoopPipelineParsingCallbacks,
2651 UseMemorySSA)) {
2652 Pipeline = {{"function", {{UseMemorySSA ? "loop-mssa" : "loop",
2653 std::move(*Pipeline)}}}};
2654 } else if (isMachineFunctionPassName(
2655 FirstName, MachineFunctionPipelineParsingCallbacks)) {
2656 Pipeline = {{"function", {{"machine-function", std::move(*Pipeline)}}}};
2657 } else {
2658 for (auto &C : TopLevelPipelineParsingCallbacks)
2659 if (C(MPM, *Pipeline))
2660 return Error::success();
2661
2662 // Unknown pass or pipeline name!
2663 auto &InnerPipeline = Pipeline->front().InnerPipeline;
2665 formatv("unknown {} name '{}'",
2666 (InnerPipeline.empty() ? "pass" : "pipeline"), FirstName)
2667 .str(),
2669 }
2670 }
2671
2672 if (auto Err = parseModulePassPipeline(MPM, *Pipeline))
2673 return Err;
2674 return Error::success();
2675}
2676
2677// Primary pass pipeline description parsing routine for a \c CGSCCPassManager
2679 StringRef PipelineText) {
2680 auto Pipeline = parsePipelineText(PipelineText);
2681 if (!Pipeline || Pipeline->empty())
2683 formatv("invalid pipeline '{}'", PipelineText).str(),
2685
2686 StringRef FirstName = Pipeline->front().Name;
2687 if (!isCGSCCPassName(FirstName, CGSCCPipelineParsingCallbacks))
2689 formatv("unknown cgscc pass '{}' in pipeline '{}'", FirstName,
2690 PipelineText)
2691 .str(),
2693
2694 if (auto Err = parseCGSCCPassPipeline(CGPM, *Pipeline))
2695 return Err;
2696 return Error::success();
2697}
2698
2699// Primary pass pipeline description parsing routine for a \c
2700// FunctionPassManager
2702 StringRef PipelineText) {
2703 auto Pipeline = parsePipelineText(PipelineText);
2704 if (!Pipeline || Pipeline->empty())
2706 formatv("invalid pipeline '{}'", PipelineText).str(),
2708
2709 StringRef FirstName = Pipeline->front().Name;
2710 if (!isFunctionPassName(FirstName, FunctionPipelineParsingCallbacks))
2712 formatv("unknown function pass '{}' in pipeline '{}'", FirstName,
2713 PipelineText)
2714 .str(),
2716
2717 if (auto Err = parseFunctionPassPipeline(FPM, *Pipeline))
2718 return Err;
2719 return Error::success();
2720}
2721
2722// Primary pass pipeline description parsing routine for a \c LoopPassManager
2724 StringRef PipelineText) {
2725 auto Pipeline = parsePipelineText(PipelineText);
2726 if (!Pipeline || Pipeline->empty())
2728 formatv("invalid pipeline '{}'", PipelineText).str(),
2730
2731 if (auto Err = parseLoopPassPipeline(CGPM, *Pipeline))
2732 return Err;
2733
2734 return Error::success();
2735}
2736
2738 StringRef PipelineText) {
2739 auto Pipeline = parsePipelineText(PipelineText);
2740 if (!Pipeline || Pipeline->empty())
2742 formatv("invalid machine pass pipeline '{}'", PipelineText).str(),
2744
2745 if (auto Err = parseMachinePassPipeline(MFPM, *Pipeline))
2746 return Err;
2747
2748 return Error::success();
2749}
2750
2752 // If the pipeline just consists of the word 'default' just replace the AA
2753 // manager with our default one.
2754 if (PipelineText == "default") {
2756 return Error::success();
2757 }
2758
2759 while (!PipelineText.empty()) {
2760 StringRef Name;
2761 std::tie(Name, PipelineText) = PipelineText.split(',');
2762 if (!parseAAPassName(AA, Name))
2764 formatv("unknown alias analysis name '{}'", Name).str(),
2766 }
2767
2768 return Error::success();
2769}
2770
2771std::optional<RegAllocFilterFunc>
2773 if (FilterName == "all")
2774 return nullptr;
2775 for (auto &C : RegClassFilterParsingCallbacks)
2776 if (auto F = C(FilterName))
2777 return F;
2778 return std::nullopt;
2779}
2780
2782 OS << " " << PassName << "\n";
2783}
2785 raw_ostream &OS) {
2786 OS << " " << PassName << "<" << Params << ">\n";
2787}
2788
2790 // TODO: print pass descriptions when they are available
2791
2792 OS << "Module passes:\n";
2793#define MODULE_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2794#include "PassRegistry.def"
2795
2796 OS << "Module passes with params:\n";
2797#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2798 printPassName(NAME, PARAMS, OS);
2799#include "PassRegistry.def"
2800
2801 OS << "Module analyses:\n";
2802#define MODULE_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2803#include "PassRegistry.def"
2804
2805 OS << "Module alias analyses:\n";
2806#define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2807#include "PassRegistry.def"
2808
2809 OS << "CGSCC passes:\n";
2810#define CGSCC_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2811#include "PassRegistry.def"
2812
2813 OS << "CGSCC passes with params:\n";
2814#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2815 printPassName(NAME, PARAMS, OS);
2816#include "PassRegistry.def"
2817
2818 OS << "CGSCC analyses:\n";
2819#define CGSCC_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2820#include "PassRegistry.def"
2821
2822 OS << "Function passes:\n";
2823#define FUNCTION_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2824#include "PassRegistry.def"
2825
2826 OS << "Function passes with params:\n";
2827#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2828 printPassName(NAME, PARAMS, OS);
2829#include "PassRegistry.def"
2830
2831 OS << "Function analyses:\n";
2832#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2833#include "PassRegistry.def"
2834
2835 OS << "Function alias analyses:\n";
2836#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2837#include "PassRegistry.def"
2838
2839 OS << "LoopNest passes:\n";
2840#define LOOPNEST_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2841#include "PassRegistry.def"
2842
2843 OS << "Loop passes:\n";
2844#define LOOP_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2845#include "PassRegistry.def"
2846
2847 OS << "Loop passes with params:\n";
2848#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2849 printPassName(NAME, PARAMS, OS);
2850#include "PassRegistry.def"
2851
2852 OS << "Loop analyses:\n";
2853#define LOOP_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2854#include "PassRegistry.def"
2855
2856 OS << "Machine module passes (WIP):\n";
2857#define MACHINE_MODULE_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2858#include "llvm/Passes/MachinePassRegistry.def"
2859
2860 OS << "Machine function passes (WIP):\n";
2861#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2862#include "llvm/Passes/MachinePassRegistry.def"
2863
2864 OS << "Machine function analyses (WIP):\n";
2865#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2866#include "llvm/Passes/MachinePassRegistry.def"
2867}
2868
2870 const std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>)>
2871 &C) {
2872 TopLevelPipelineParsingCallbacks.push_back(C);
2873}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
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.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
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.
Provides analysis for continuously CSEing during GISel passes.
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...
Analysis that tracks defined/used subregister lanes across COPY instructions and instructions that ge...
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.
Provides analysis for querying information about KnownBits during GISel passes.
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.
#define _
AcceleratorCodeSelection - Identify all functions reachable from a kernel, removing those that are un...
This file defines the IR2Vec vocabulary analysis(IR2VecVocabAnalysis), the core ir2vec::Embedder inte...
This file defines passes to print out IR in various granularities.
This header defines various interfaces for pass management in LLVM.
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.
static LVOptions Options
Definition LVOptions.cpp:25
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:54
Machine Check Debug Module
Machine IR instance of the generic uniformity analysis.
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
LoopAnalysisManager LAM
FunctionAnalysisManager FAM
ModuleAnalysisManager MAM
if(PassOpts->AAPipeline)
PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &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 bool isLoopNestPassName(StringRef Name, CallbacksT &Callbacks, bool &UseMemorySSA)
static bool isMachineFunctionPassName(StringRef Name, CallbacksT &Callbacks)
static Expected< OptimizationLevel > parseOptLevelParam(StringRef S)
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 void setupOptionsForPipelineAlias(PipelineTuningOptions &PTO, OptimizationLevel L)
This file implements the PredicateInfo analysis, which creates an Extended SSA form for operations us...
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
This pass is required to take advantage of the interprocedural register allocation infrastructure.
This file implements relative lookup table converter that converts lookup tables to relative lookup t...
This file provides the interface for LLVM's Scalar Replacement of Aggregates pass.
static const char * name
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...
This pass strips convergence intrinsics and operand bundles as those are only useful when modifying t...
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[]
A manager for alias analyses.
Class for arbitrary precision integers.
Definition APInt.h:78
uint64_t getZExtValue() const
Get zero extended value.
Definition APInt.h:1563
int64_t getSExtValue() const
Get sign extended value.
Definition APInt.h:1585
bool registerPass(PassBuilderT &&PassBuilder)
Register an analysis pass with the manager.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Definition BasicBlock.h:237
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
Tagged union holding either a T or a Error.
Definition Error.h:485
static LLVM_ABI 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:621
A smart pointer to a reference-counted object that inherits from RefCountedBase or ThreadSafeRefCount...
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const MachineFunctionProperties & getProperties() const
Get the function properties.
LLVM_ABI Register createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
static LLVM_ABI const OptimizationLevel O3
Optimize for fast execution as much as possible.
static LLVM_ABI const OptimizationLevel O0
Disable as many optimizations as possible.
static LLVM_ABI const OptimizationLevel O2
Optimize for fast execution as much as possible without triggering significant incremental compile ti...
static LLVM_ABI const OptimizationLevel O1
Optimize quickly without destroying debuggability.
This class provides access to building LLVM's passes.
LLVM_ABI void printPassNames(raw_ostream &OS)
Print pass names.
static bool checkParametrizedPassName(StringRef Name, StringRef PassName)
LLVM_ABI AAManager buildDefaultAAPipeline()
Build the default AAManager with the default alias analysis pipeline registered.
LLVM_ABI Error parseAAPipeline(AAManager &AA, StringRef PipelineText)
Parse a textual alias analysis pipeline into the provided AA manager.
LLVM_ABI void registerLoopAnalyses(LoopAnalysisManager &LAM)
Registers all available loop analysis passes.
LLVM_ABI std::optional< RegAllocFilterFunc > parseRegAllocFilter(StringRef RegAllocFilterName)
Parse RegAllocFilterName to get RegAllocFilterFunc.
LLVM_ABI void crossRegisterProxies(LoopAnalysisManager &LAM, FunctionAnalysisManager &FAM, CGSCCAnalysisManager &CGAM, ModuleAnalysisManager &MAM, MachineFunctionAnalysisManager *MFAM=nullptr)
Cross register the analysis managers through their proxies.
LLVM_ABI PassBuilder(TargetMachine *TM=nullptr, PipelineTuningOptions PTO=PipelineTuningOptions(), std::optional< PGOOptions > PGOOpt=std::nullopt, PassInstrumentationCallbacks *PIC=nullptr, IntrusiveRefCntPtr< vfs::FileSystem > FS=vfs::getRealFileSystem())
LLVM_ABI Error parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText)
Parse a textual pass pipeline description into a ModulePassManager.
void registerPipelineParsingCallback(const std::function< bool(StringRef Name, CGSCCPassManager &, ArrayRef< PipelineElement >)> &C)
{{@ Register pipeline parsing callbacks with this pass builder instance.
LLVM_ABI void registerModuleAnalyses(ModuleAnalysisManager &MAM)
Registers all available module analysis passes.
LLVM_ABI void registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM)
Registers all available CGSCC analysis passes.
static LLVM_ABI Expected< bool > parseSinglePassOption(StringRef Params, StringRef OptionName, StringRef PassName)
Handle passes only accept one bool-valued parameter.
LLVM_ABI void registerMachineFunctionAnalyses(MachineFunctionAnalysisManager &MFAM)
Registers all available machine function analysis passes.
LLVM_ABI void registerParseTopLevelPipelineCallback(const std::function< bool(ModulePassManager &, ArrayRef< PipelineElement >)> &C)
Register a callback for a top-level pipeline entry.
LLVM_ABI 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<!std::is_same_v< PassT, PassManager > > addPass(PassT &&Pass)
Tunable parameters for passes in the default pipelines.
Definition PassBuilder.h:41
bool SLPVectorization
Tuning option to enable/disable slp loop vectorization, set based on opt level.
Definition PassBuilder.h:56
bool LoopVectorization
Tuning option to enable/disable loop vectorization, set based on opt level.
Definition PassBuilder.h:52
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition Analysis.h:115
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition StringRef.h:730
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
Definition StringRef.h:490
std::string str() const
str - Get the contents as an std::string.
Definition StringRef.h:222
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition StringRef.h:258
constexpr bool empty() const
empty - Check if the string is empty.
Definition StringRef.h:140
char front() const
front - Get the first character in the string.
Definition StringRef.h:146
bool consume_front(char Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
Definition StringRef.h:655
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
Primary interface to the complete machine description for the target machine.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
self_iterator getIterator()
Definition ilist_node.h:123
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
Interfaces for registering analysis passes, producing common pass manager configurations,...
Abstract Attribute helper functions.
Definition Attributor.h:165
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
std::optional< CodeGenOptLevel > getLevel(int OL)
Get the Level identified by the integer OL.
Definition CodeGen.h:93
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:81
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
DropTestKind
Specifies how to drop type tests.
@ All
Drop only llvm.assumes using type test value.
This is an optimization pass for GlobalISel generic memory operations.
OuterAnalysisManagerProxy< CGSCCAnalysisManager, Function > CGSCCAnalysisManagerFunctionProxy
A proxy from a CGSCCAnalysisManager to a Function.
OuterAnalysisManagerProxy< ModuleAnalysisManager, MachineFunction > ModuleAnalysisManagerMachineFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
ModuleToFunctionPassAdaptor createModuleToFunctionPassAdaptor(FunctionPassT &&Pass, bool EagerlyInvalidate=false)
A function to deduce a function pass type and wrap it in the templated adaptor.
DevirtSCCRepeatedPass createDevirtSCCRepeatedPass(CGSCCPassT &&Pass, int MaxIterations)
A function to deduce a function pass type and wrap it in the templated adaptor.
OuterAnalysisManagerProxy< ModuleAnalysisManager, Function > ModuleAnalysisManagerFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition Error.cpp:94
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
InnerAnalysisManagerProxy< LoopAnalysisManager, Function > LoopAnalysisManagerFunctionProxy
A proxy from a LoopAnalysisManager to a Function.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition Error.h:1321
PassManager< LazyCallGraph::SCC, CGSCCAnalysisManager, LazyCallGraph &, CGSCCUpdateResult & > CGSCCPassManager
The CGSCC pass manager.
AnalysisManager< LazyCallGraph::SCC, LazyCallGraph & > CGSCCAnalysisManager
The CGSCC analysis manager.
AnalysisManager< Loop, LoopStandardAnalysisResults & > LoopAnalysisManager
The loop analysis manager.
PassManager< Loop, LoopAnalysisManager, LoopStandardAnalysisResults &, LPMUpdater & > LoopPassManager
The Loop pass manager.
ModuleToPostOrderCGSCCPassAdaptor createModuleToPostOrderCGSCCPassAdaptor(CGSCCPassT &&Pass)
A function to deduce a function pass type and wrap it in the templated adaptor.
LLVM_ABI cl::opt< bool > PrintPipelinePasses
Common option used by multiple tools to print pipeline passes.
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
FunctionToLoopPassAdaptor createFunctionToLoopPassAdaptor(LoopPassT &&Pass, bool UseMemorySSA=false)
A function to deduce a loop 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.
FunctionToMachineFunctionPassAdaptor createFunctionToMachineFunctionPassAdaptor(MachineFunctionPassT &&Pass)
PassManager< Module > ModulePassManager
Convenience typedef for a pass manager over modules.
FunctionAddr VTableAddr Count
Definition InstrProf.h:139
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
InnerAnalysisManagerProxy< MachineFunctionAnalysisManager, Function > MachineFunctionAnalysisManagerFunctionProxy
OuterAnalysisManagerProxy< FunctionAnalysisManager, Loop, LoopStandardAnalysisResults & > FunctionAnalysisManagerLoopProxy
A proxy from a FunctionAnalysisManager to a Loop.
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
Definition Error.h:340
OuterAnalysisManagerProxy< ModuleAnalysisManager, LazyCallGraph::SCC, LazyCallGraph & > ModuleAnalysisManagerCGSCCProxy
A proxy from a ModuleAnalysisManager to an SCC.
InnerAnalysisManagerProxy< MachineFunctionAnalysisManager, Module > MachineFunctionAnalysisManagerModuleProxy
InnerAnalysisManagerProxy< CGSCCAnalysisManager, Module > CGSCCAnalysisManagerModuleProxy
A proxy from a CGSCCAnalysisManager to a Module.
PassManager< Function > FunctionPassManager
Convenience typedef for a pass manager over functions.
MFPropsModifier(PassT &P, MachineFunction &MF) -> MFPropsModifier< PassT >
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1917
PassManager< MachineFunction > MachineFunctionPassManager
Convenience typedef for a pass manager over functions.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI std::optional< AllocTokenMode > getAllocTokenModeFromString(StringRef Name)
Returns the AllocTokenMode from its canonical string name; if an invalid name was provided returns nu...
@ Detailed
Hash with opcode only.
@ CallTargetIgnored
Hash with opcode and operands.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition MIRParser.h:39
@ Enable
Enable colors.
Definition WithColor.h:47
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Definition Error.cpp:177
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:870
#define N
A special type used by analysis passes to provide an address that identifies that particular analysis...
Definition Analysis.h:29
A set of parameters to control various transforms performed by GVN pass.
Definition GVN.h:78
HardwareLoopOptions & setForceNested(bool Force)
HardwareLoopOptions & setDecrement(unsigned Count)
HardwareLoopOptions & setForceGuard(bool Force)
HardwareLoopOptions & setForce(bool Force)
HardwareLoopOptions & setCounterBitwidth(unsigned Width)
HardwareLoopOptions & setForcePhi(bool Force)
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:70