LLVM 24.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
18#include "PassesOptions.h"
34#include "llvm/Analysis/DDG.h"
56#include "llvm/Analysis/Lint.h"
129#include "llvm/CodeGen/KCFI.h"
167#include "llvm/CodeGen/PEI.h"
215#include "llvm/IR/DebugInfo.h"
216#include "llvm/IR/Dominators.h"
217#include "llvm/IR/PassManager.h"
219#include "llvm/IR/Verifier.h"
223#include "llvm/Support/CodeGen.h"
224#include "llvm/Support/Debug.h"
225#include "llvm/Support/Error.h"
229#include "llvm/Support/Regex.h"
425#include <optional>
426
427using namespace llvm;
428
429std::optional<PrintPipelinePassesFormat>
431 return Opts.print_pipeline_passes;
432}
433
436 switch (Format) {
438 OS << Pipeline;
439 break;
441 int IndentLevel = 0;
442 for (char C : Pipeline) {
443 switch (C) {
444 case '(':
445 ++IndentLevel;
446 OS << formatv("\n{0}", fmt_repeat(" ", IndentLevel));
447 break;
448 case ')':
449 --IndentLevel;
450 assert(IndentLevel >= 0 && "Invalid pipeline string!");
451 break;
452 case ',':
453 OS << formatv("\n{0}", fmt_repeat(" ", IndentLevel));
454 break;
455 default:
456 OS << C;
457 }
458 }
459 break;
460 }
461 }
462}
463
464AnalysisKey NoOpModuleAnalysis::Key;
465AnalysisKey NoOpCGSCCAnalysis::Key;
466AnalysisKey NoOpFunctionAnalysis::Key;
467AnalysisKey NoOpLoopAnalysis::Key;
468
469namespace {
470
471bool applyMIRDebugify(DIBuilder &DIB, Function &F, ModuleAnalysisManager &AM) {
474 .getManager();
475
477 DIB, F, [&](Function &Func) -> MachineFunction * {
479 FAM.getCachedResult<MachineFunctionAnalysis>(Func);
480 return MFA ? &MFA->getMF() : nullptr;
481 });
482}
483
484// A pass for testing message reporting of -verify-each failures.
485// DO NOT USE THIS EXCEPT FOR TESTING!
486class TriggerVerifierErrorPass
487 : public OptionalPassInfoMixin<TriggerVerifierErrorPass> {
488public:
489 PreservedAnalyses run(Module &M, ModuleAnalysisManager &) {
490 // Intentionally break the Module by creating an alias without setting the
491 // aliasee.
492 auto *PtrTy = PointerType::getUnqual(M.getContext());
493 GlobalAlias::create(PtrTy, PtrTy->getAddressSpace(),
494 GlobalValue::LinkageTypes::InternalLinkage,
495 "__bad_alias", nullptr, &M);
497 }
498
499 PreservedAnalyses run(Function &F, FunctionAnalysisManager &) {
500 // Intentionally break the Function by inserting a terminator
501 // instruction in the middle of a basic block.
502 BasicBlock &BB = F.getEntryBlock();
503 new UnreachableInst(F.getContext(), BB.getTerminator()->getIterator());
505 }
506
507 PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &) {
508 // Intentionally create a virtual register and set NoVRegs property.
509 auto &MRI = MF.getRegInfo();
511 MF.getProperties().setNoVRegs();
512 return PreservedAnalyses::all();
513 }
514
515 static StringRef name() { return "TriggerVerifierErrorPass"; }
516};
517
518// A pass requires all MachineFunctionProperties.
519// DO NOT USE THIS EXCEPT FOR TESTING!
520class RequireAllMachineFunctionPropertiesPass
521 : public OptionalPassInfoMixin<RequireAllMachineFunctionPropertiesPass> {
522public:
523 PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &) {
524 MFPropsModifier _(*this, MF);
526 }
527
528 static MachineFunctionProperties getRequiredProperties() {
529 return MachineFunctionProperties()
530 .setFailedISel()
531 .setFailsVerification()
532 .setIsSSA()
533 .setLegalized()
534 .setNoPHIs()
535 .setNoVRegs()
536 .setRegBankSelected()
537 .setSelected()
538 .setTiedOpsRewritten()
539 .setTracksDebugUserValues()
540 .setTracksLiveness();
541 }
542 static StringRef name() { return "RequireAllMachineFunctionPropertiesPass"; }
543};
544
545} // namespace
546
547static std::optional<OptimizationLevel> parseOptLevel(StringRef S) {
548 if (S == "Os" || S == "Oz")
550 Twine("The optimization level \"") + S +
551 "\" is no longer supported. Use O2 in conjunction with the " +
552 (S == "Os" ? "optsize" : "minsize") + " attribute instead.");
553
555 .Case("O0", OptimizationLevel::O0)
559 .Default(std::nullopt);
560}
561
563 std::optional<OptimizationLevel> OptLevel = parseOptLevel(S);
564 if (OptLevel)
565 return *OptLevel;
567 formatv("invalid optimization level '{}'", S).str(),
569}
570
572 std::optional<PipelineTuningOptions> PTO,
573 std::optional<PGOOptions> PGOOpt,
576 : Context(Context), Opts(getPassesOptions(Context)), TM(TM),
577 PTO(PTO ? *PTO : PipelineTuningOptions(&Context.getLibraryOptions())),
578 PGOOpt(PGOOpt), PIC(PIC), FS(std::move(FS)) {
579 if (TM)
580 TM->registerPassBuilderCallbacks(*this);
581 if (PIC) {
582 PIC->registerClassToPassNameCallback([this, PIC]() {
583 // MSVC requires this to be captured if it's used inside decltype.
584 // Other compilers consider it an unused lambda capture.
585 (void)this;
586#define MODULE_PASS(NAME, CREATE_PASS) \
587 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
588#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
589 PIC->addClassToPassName(CLASS, NAME);
590#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
591 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
592#define FUNCTION_PASS(NAME, CREATE_PASS) \
593 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
594#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
595 PIC->addClassToPassName(CLASS, NAME);
596#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
597 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
598#define LOOPNEST_PASS(NAME, CREATE_PASS) \
599 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
600#define LOOP_PASS(NAME, CREATE_PASS) \
601 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
602#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
603 PIC->addClassToPassName(CLASS, NAME);
604#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
605 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
606#define CGSCC_PASS(NAME, CREATE_PASS) \
607 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
608#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
609 PIC->addClassToPassName(CLASS, NAME);
610#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
611 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
612#include "PassRegistry.def"
613
614#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
615 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
616#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
617 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
618#define MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, \
619 PARAMS) \
620 PIC->addClassToPassName(CLASS, NAME);
621#include "llvm/Passes/MachinePassRegistry.def"
622 });
623 }
624
625 // Module-level callbacks without LTO phase
627 [this](StringRef Name, ModulePassManager &PM,
629#define MODULE_CALLBACK(NAME, INVOKE) \
630 if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
631 auto L = PassBuilder::parsePassParameters(parseOptLevelParam, Name, NAME); \
632 if (!L) { \
633 errs() << NAME ": " << toString(L.takeError()) << '\n'; \
634 return false; \
635 } \
636 INVOKE(PM, L.get()); \
637 return true; \
638 }
639#include "PassRegistry.def"
640 return false;
641 });
642
643 // Module-level callbacks with LTO phase (use Phase::None for string API)
645 [this](StringRef Name, ModulePassManager &PM,
647#define MODULE_LTO_CALLBACK(NAME, INVOKE) \
648 if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
649 auto L = PassBuilder::parsePassParameters(parseOptLevelParam, Name, NAME); \
650 if (!L) { \
651 errs() << NAME ": " << toString(L.takeError()) << '\n'; \
652 return false; \
653 } \
654 INVOKE(PM, L.get(), ThinOrFullLTOPhase::None); \
655 return true; \
656 }
657#include "PassRegistry.def"
658 return false;
659 });
660
661 // Function-level callbacks
663 [this](StringRef Name, FunctionPassManager &PM,
665#define FUNCTION_CALLBACK(NAME, INVOKE) \
666 if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
667 auto L = PassBuilder::parsePassParameters(parseOptLevelParam, Name, NAME); \
668 if (!L) { \
669 errs() << NAME ": " << toString(L.takeError()) << '\n'; \
670 return false; \
671 } \
672 INVOKE(PM, L.get()); \
673 return true; \
674 }
675#include "PassRegistry.def"
676 return false;
677 });
678
679 // CGSCC-level callbacks
681 [this](StringRef Name, CGSCCPassManager &PM,
683#define CGSCC_CALLBACK(NAME, INVOKE) \
684 if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
685 auto L = PassBuilder::parsePassParameters(parseOptLevelParam, Name, NAME); \
686 if (!L) { \
687 errs() << NAME ": " << toString(L.takeError()) << '\n'; \
688 return false; \
689 } \
690 INVOKE(PM, L.get()); \
691 return true; \
692 }
693#include "PassRegistry.def"
694 return false;
695 });
696
697 // Loop-level callbacks
699 [this](StringRef Name, LoopPassManager &PM,
701#define LOOP_CALLBACK(NAME, INVOKE) \
702 if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
703 auto L = PassBuilder::parsePassParameters(parseOptLevelParam, Name, NAME); \
704 if (!L) { \
705 errs() << NAME ": " << toString(L.takeError()) << '\n'; \
706 return false; \
707 } \
708 INVOKE(PM, L.get()); \
709 return true; \
710 }
711#include "PassRegistry.def"
712 return false;
713 });
714}
715
717#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
718 MAM.registerPass([&] { return CREATE_PASS; });
719#include "PassRegistry.def"
720
721 for (auto &C : ModuleAnalysisRegistrationCallbacks)
722 C(MAM);
723}
724
726#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
727 CGAM.registerPass([&] { return CREATE_PASS; });
728#include "PassRegistry.def"
729
730 for (auto &C : CGSCCAnalysisRegistrationCallbacks)
731 C(CGAM);
732}
733
735 // We almost always want the default alias analysis pipeline.
736 // If a user wants a different one, they can register their own before calling
737 // registerFunctionAnalyses().
738 FAM.registerPass([&] { return buildDefaultAAPipeline(); });
739
740#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
741 if constexpr (std::is_constructible_v< \
742 std::remove_reference_t<decltype(CREATE_PASS)>, \
743 const TargetMachine &>) { \
744 if (TM) \
745 FAM.registerPass([&] { return CREATE_PASS; }); \
746 } else { \
747 FAM.registerPass([&] { return CREATE_PASS; }); \
748 }
749#include "PassRegistry.def"
750
751 for (auto &C : FunctionAnalysisRegistrationCallbacks)
752 C(FAM);
753}
754
757
758#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
759 MFAM.registerPass([&] { return CREATE_PASS; });
760#include "llvm/Passes/MachinePassRegistry.def"
761
762 for (auto &C : MachineFunctionAnalysisRegistrationCallbacks)
763 C(MFAM);
764}
765
767#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
768 LAM.registerPass([&] { return CREATE_PASS; });
769#include "PassRegistry.def"
770
771 for (auto &C : LoopAnalysisRegistrationCallbacks)
772 C(LAM);
773}
774
775static std::optional<std::pair<bool, bool>>
777 std::pair<bool, bool> Params;
778 if (!Name.consume_front("function"))
779 return std::nullopt;
780 if (Name.empty())
781 return Params;
782 if (!Name.consume_front("<") || !Name.consume_back(">"))
783 return std::nullopt;
784 while (!Name.empty()) {
785 auto [Front, Back] = Name.split(';');
786 Name = Back;
787 if (Front == "eager-inv")
788 Params.first = true;
789 else if (Front == "no-rerun")
790 Params.second = true;
791 else
792 return std::nullopt;
793 }
794 return Params;
795}
796
797static std::optional<int> parseDevirtPassName(StringRef Name) {
798 if (!Name.consume_front("devirt<") || !Name.consume_back(">"))
799 return std::nullopt;
800 int Count;
801 if (Name.getAsInteger(0, Count) || Count < 0)
802 return std::nullopt;
803 return Count;
804}
805
807 StringRef OptionName,
809 bool Result = false;
810 while (!Params.empty()) {
811 StringRef ParamName;
812 std::tie(ParamName, Params) = Params.split(';');
813
814 if (ParamName == OptionName) {
815 Result = true;
816 } else {
818 formatv("invalid {} pass parameter '{}'", PassName, ParamName).str(),
820 }
821 }
822 return Result;
823}
824
825namespace {
826
827/// Parser of parameters for HardwareLoops pass.
828Expected<HardwareLoopOptions> parseHardwareLoopOptions(StringRef Params) {
829 HardwareLoopOptions HardwareLoopOpts;
830
831 while (!Params.empty()) {
832 StringRef ParamName;
833 std::tie(ParamName, Params) = Params.split(';');
834 if (ParamName.consume_front("hardware-loop-decrement=")) {
835 int Count;
836 if (ParamName.getAsInteger(0, Count))
838 formatv("invalid HardwareLoopPass parameter '{}'", ParamName).str(),
840 HardwareLoopOpts.setDecrement(Count);
841 continue;
842 }
843 if (ParamName.consume_front("hardware-loop-counter-bitwidth=")) {
844 int Count;
845 if (ParamName.getAsInteger(0, Count))
847 formatv("invalid HardwareLoopPass parameter '{}'", ParamName).str(),
849 HardwareLoopOpts.setCounterBitwidth(Count);
850 continue;
851 }
852 if (ParamName == "force-hardware-loops") {
853 HardwareLoopOpts.setForce(true);
854 } else if (ParamName == "force-hardware-loop-phi") {
855 HardwareLoopOpts.setForcePhi(true);
856 } else if (ParamName == "force-nested-hardware-loop") {
857 HardwareLoopOpts.setForceNested(true);
858 } else if (ParamName == "force-hardware-loop-guard") {
859 HardwareLoopOpts.setForceGuard(true);
860 } else {
862 formatv("invalid HardwarePass parameter '{}'", ParamName).str(),
864 }
865 }
866 return HardwareLoopOpts;
867}
868
869/// Parser of parameters for Lint pass.
870Expected<bool> parseLintOptions(StringRef Params) {
871 return PassBuilder::parseSinglePassOption(Params, "abort-on-error",
872 "LintPass");
873}
874
875/// Parser of parameters for FunctionPropertiesStatistics pass.
876Expected<bool> parseFunctionPropertiesStatisticsOptions(StringRef Params) {
877 return PassBuilder::parseSinglePassOption(Params, "pre-opt",
878 "FunctionPropertiesStatisticsPass");
879}
880
881/// Parser of parameters for InstCount pass.
882Expected<bool> parseInstCountOptions(StringRef Params) {
883 return PassBuilder::parseSinglePassOption(Params, "pre-opt", "InstCountPass");
884}
885
886Expected<bool> parseInferAddressSpacesPassOptions(StringRef Params) {
888 Params, "assume-default-is-flat-addrspace", "InferAddressSpacesPass");
889}
890
891/// Parser of parameters for LoopUnroll pass.
892Expected<LoopUnrollOptions> parseLoopUnrollOptions(StringRef Params) {
893 LoopUnrollOptions UnrollOpts;
894 while (!Params.empty()) {
895 StringRef ParamName;
896 std::tie(ParamName, Params) = Params.split(';');
897 std::optional<OptimizationLevel> OptLevel = parseOptLevel(ParamName);
898 if (OptLevel) {
899 UnrollOpts.setOptLevel(static_cast<int>(*OptLevel));
900 continue;
901 }
902 if (ParamName.consume_front("full-unroll-max=")) {
903 int Count;
904 if (ParamName.getAsInteger(0, Count))
906 formatv("invalid LoopUnrollPass parameter '{}'", ParamName).str(),
908 UnrollOpts.setFullUnrollMaxCount(Count);
909 continue;
910 }
911
912 bool Enable = !ParamName.consume_front("no-");
913 if (ParamName == "partial") {
914 UnrollOpts.setPartial(Enable);
915 } else if (ParamName == "peeling") {
916 UnrollOpts.setPeeling(Enable);
917 } else if (ParamName == "profile-peeling") {
918 UnrollOpts.setProfileBasedPeeling(Enable);
919 } else if (ParamName == "runtime") {
920 UnrollOpts.setRuntime(Enable);
921 } else if (ParamName == "upperbound") {
922 UnrollOpts.setUpperBound(Enable);
923 } else if (ParamName == "prepare-for-lto") {
924 UnrollOpts.setPrepareForLTO(Enable);
925 } else {
927 formatv("invalid LoopUnrollPass parameter '{}'", ParamName).str(),
929 }
930 }
931 return UnrollOpts;
932}
933
934Expected<bool> parseGlobalDCEPassOptions(StringRef Params) {
936 Params, "vfe-linkage-unit-visibility", "GlobalDCE");
937}
938
939Expected<bool> parseCGProfilePassOptions(StringRef Params) {
940 return PassBuilder::parseSinglePassOption(Params, "in-lto-post-link",
941 "CGProfile");
942}
943
944Expected<bool> parseInlinerPassOptions(StringRef Params) {
945 return PassBuilder::parseSinglePassOption(Params, "only-mandatory",
946 "InlinerPass");
947}
948
949Expected<bool> parseCoroSplitPassOptions(StringRef Params) {
950 return PassBuilder::parseSinglePassOption(Params, "reuse-storage",
951 "CoroSplitPass");
952}
953
954Expected<bool> parsePostOrderFunctionAttrsPassOptions(StringRef Params) {
956 Params, "skip-non-recursive-function-attrs", "PostOrderFunctionAttrs");
957}
958
959Expected<bool> parseEarlyCSEPassOptions(StringRef Params) {
960 return PassBuilder::parseSinglePassOption(Params, "memssa", "EarlyCSE");
961}
962
963Expected<bool> parseEntryExitInstrumenterPassOptions(StringRef Params) {
964 return PassBuilder::parseSinglePassOption(Params, "post-inline",
965 "EntryExitInstrumenter");
966}
967
968Expected<bool> parseDropUnnecessaryAssumesPassOptions(StringRef Params) {
969 return PassBuilder::parseSinglePassOption(Params, "drop-deref",
970 "DropUnnecessaryAssumes");
971}
972
973Expected<bool> parseLowerMatrixIntrinsicsPassOptions(StringRef Params) {
974 return PassBuilder::parseSinglePassOption(Params, "minimal",
975 "LowerMatrixIntrinsics");
976}
977
978Expected<IRNormalizerOptions> parseIRNormalizerPassOptions(StringRef Params) {
980 while (!Params.empty()) {
981 StringRef ParamName;
982 std::tie(ParamName, Params) = Params.split(';');
983
984 bool Enable = !ParamName.consume_front("no-");
985 if (ParamName == "preserve-order")
986 Result.PreserveOrder = Enable;
987 else if (ParamName == "rename-all")
988 Result.RenameAll = Enable;
989 else if (ParamName == "fold-all") // FIXME: Name mismatch
990 Result.FoldPreOutputs = Enable;
991 else if (ParamName == "reorder-operands")
992 Result.ReorderOperands = Enable;
993 else {
995 formatv("invalid normalize pass parameter '{}'", ParamName).str(),
997 }
998 }
999
1000 return Result;
1001}
1002
1003Expected<AddressSanitizerOptions> parseASanPassOptions(StringRef Params) {
1005 while (!Params.empty()) {
1006 StringRef ParamName;
1007 std::tie(ParamName, Params) = Params.split(';');
1008
1009 if (ParamName == "kernel") {
1010 Result.CompileKernel = true;
1011 } else if (ParamName == "use-after-scope") {
1012 Result.UseAfterScope = true;
1013 } else {
1015 formatv("invalid AddressSanitizer pass parameter '{}'", ParamName)
1016 .str(),
1018 }
1019 }
1020 return Result;
1021}
1022
1023Expected<HWAddressSanitizerOptions> parseHWASanPassOptions(StringRef Params) {
1025 while (!Params.empty()) {
1026 StringRef ParamName;
1027 std::tie(ParamName, Params) = Params.split(';');
1028
1029 if (ParamName == "recover") {
1030 Result.Recover = true;
1031 } else if (ParamName == "kernel") {
1032 Result.CompileKernel = true;
1033 } else {
1035 formatv("invalid HWAddressSanitizer pass parameter '{}'", ParamName)
1036 .str(),
1038 }
1039 }
1040 return Result;
1041}
1042
1044parseDropTypeTestsPassOptions(StringRef Params) {
1046 while (!Params.empty()) {
1047 StringRef ParamName;
1048 std::tie(ParamName, Params) = Params.split(';');
1049
1050 if (ParamName == "all") {
1052 } else if (ParamName == "assume") {
1054 } else {
1056 formatv("invalid DropTypeTestsPass parameter '{}'", ParamName).str(),
1058 }
1059 }
1060 return Result;
1061}
1062
1063Expected<EmbedBitcodeOptions> parseEmbedBitcodePassOptions(StringRef Params) {
1065 while (!Params.empty()) {
1066 StringRef ParamName;
1067 std::tie(ParamName, Params) = Params.split(';');
1068
1069 if (ParamName == "thinlto") {
1070 Result.IsThinLTO = true;
1071 } else if (ParamName == "emit-summary") {
1072 Result.EmitLTOSummary = true;
1073 } else {
1075 formatv("invalid EmbedBitcode pass parameter '{}'", ParamName).str(),
1077 }
1078 }
1079 return Result;
1080}
1081
1083parseLowerAllowCheckPassOptions(StringRef Params) {
1085 while (!Params.empty()) {
1086 StringRef ParamName;
1087 std::tie(ParamName, Params) = Params.split(';');
1088
1089 // Format is <cutoffs[1,2,3]=70000;cutoffs[5,6,8]=90000>
1090 //
1091 // Parsing allows duplicate indices (last one takes precedence).
1092 // It would technically be in spec to specify
1093 // cutoffs[0]=70000,cutoffs[1]=90000,cutoffs[0]=80000,...
1094 if (ParamName.starts_with("cutoffs[")) {
1095 StringRef IndicesStr;
1096 StringRef CutoffStr;
1097
1098 std::tie(IndicesStr, CutoffStr) = ParamName.split("]=");
1099 // cutoffs[1,2,3
1100 // 70000
1101
1102 int cutoff;
1103 if (CutoffStr.getAsInteger(0, cutoff))
1105 formatv("invalid LowerAllowCheck pass cutoffs parameter '{}' ({})",
1106 CutoffStr, Params)
1107 .str(),
1109
1110 if (!IndicesStr.consume_front("cutoffs[") || IndicesStr == "")
1112 formatv("invalid LowerAllowCheck pass index parameter '{}' ({})",
1113 IndicesStr, CutoffStr)
1114 .str(),
1116
1117 while (IndicesStr != "") {
1118 StringRef firstIndexStr;
1119 std::tie(firstIndexStr, IndicesStr) = IndicesStr.split('|');
1120
1121 unsigned int index;
1122 if (firstIndexStr.getAsInteger(0, index))
1124 formatv(
1125 "invalid LowerAllowCheck pass index parameter '{}' ({}) {}",
1126 firstIndexStr, IndicesStr)
1127 .str(),
1129
1130 // In the common case (sequentially increasing indices), we will issue
1131 // O(n) resize requests. We assume the underlying data structure has
1132 // O(1) runtime for each added element.
1133 if (index >= Result.cutoffs.size())
1134 Result.cutoffs.resize(index + 1, 0);
1135
1136 Result.cutoffs[index] = cutoff;
1137 }
1138 } else if (ParamName.starts_with("runtime_check")) {
1139 StringRef ValueString;
1140 std::tie(std::ignore, ValueString) = ParamName.split("=");
1141 int runtime_check;
1142 if (ValueString.getAsInteger(0, runtime_check)) {
1144 formatv("invalid LowerAllowCheck pass runtime_check parameter '{}' "
1145 "({})",
1146 ValueString, Params)
1147 .str(),
1149 }
1150 Result.runtime_check = runtime_check;
1151 } else {
1153 formatv("invalid LowerAllowCheck pass parameter '{}'", ParamName)
1154 .str(),
1156 }
1157 }
1158
1159 return Result;
1160}
1161
1162Expected<MemorySanitizerOptions> parseMSanPassOptions(StringRef Params) {
1164 while (!Params.empty()) {
1165 StringRef ParamName;
1166 std::tie(ParamName, Params) = Params.split(';');
1167
1168 if (ParamName == "recover") {
1169 Result.Recover = true;
1170 } else if (ParamName == "kernel") {
1171 Result.Kernel = true;
1172 } else if (ParamName.consume_front("track-origins=")) {
1173 if (ParamName.getAsInteger(0, Result.TrackOrigins))
1175 formatv("invalid argument to MemorySanitizer pass track-origins "
1176 "parameter: '{}'",
1177 ParamName)
1178 .str(),
1180 } else if (ParamName == "eager-checks") {
1181 Result.EagerChecks = true;
1182 } else {
1184 formatv("invalid MemorySanitizer pass parameter '{}'", ParamName)
1185 .str(),
1187 }
1188 }
1189 return Result;
1190}
1191
1192Expected<AllocTokenOptions> parseAllocTokenPassOptions(StringRef Params) {
1194 while (!Params.empty()) {
1195 StringRef ParamName;
1196 std::tie(ParamName, Params) = Params.split(';');
1197
1198 if (ParamName.consume_front("mode=")) {
1199 if (auto Mode = getAllocTokenModeFromString(ParamName))
1200 Result.Mode = *Mode;
1201 else
1203 formatv("invalid argument to AllocToken pass mode "
1204 "parameter: '{}'",
1205 ParamName)
1206 .str(),
1208 } else {
1210 formatv("invalid AllocToken pass parameter '{}'", ParamName).str(),
1212 }
1213 }
1214 return Result;
1215}
1216
1217/// Parser of parameters for SimplifyCFG pass.
1218Expected<SimplifyCFGOptions> parseSimplifyCFGOptions(StringRef Params) {
1220 while (!Params.empty()) {
1221 StringRef ParamName;
1222 std::tie(ParamName, Params) = Params.split(';');
1223
1224 bool Enable = !ParamName.consume_front("no-");
1225 if (ParamName == "speculate-blocks") {
1226 Result.speculateBlocks(Enable);
1227 } else if (ParamName == "simplify-cond-branch") {
1228 Result.setSimplifyCondBranch(Enable);
1229 } else if (ParamName == "forward-switch-cond") {
1230 Result.forwardSwitchCondToPhi(Enable);
1231 } else if (ParamName == "switch-range-to-icmp") {
1232 Result.convertSwitchRangeToICmp(Enable);
1233 } else if (ParamName == "switch-to-arithmetic") {
1234 Result.convertSwitchToArithmetic(Enable);
1235 } else if (ParamName == "switch-to-lookup") {
1236 Result.convertSwitchToLookupTable(Enable);
1237 } else if (ParamName == "keep-loops") {
1238 Result.needCanonicalLoops(Enable);
1239 } else if (ParamName == "hoist-common-insts") {
1240 Result.hoistCommonInsts(Enable);
1241 } else if (ParamName == "hoist-loads-stores-with-cond-faulting") {
1242 Result.hoistLoadsStoresWithCondFaulting(Enable);
1243 } else if (ParamName == "sink-common-insts") {
1244 Result.sinkCommonInsts(Enable);
1245 } else if (ParamName == "speculate-unpredictables") {
1246 Result.speculateUnpredictables(Enable);
1247 } else if (Enable && ParamName.consume_front("bonus-inst-threshold=")) {
1248 APInt BonusInstThreshold;
1249 if (ParamName.getAsInteger(0, BonusInstThreshold))
1251 formatv("invalid argument to SimplifyCFG pass bonus-threshold "
1252 "parameter: '{}'",
1253 ParamName)
1254 .str(),
1256 Result.bonusInstThreshold(BonusInstThreshold.getSExtValue());
1257 } else {
1259 formatv("invalid SimplifyCFG pass parameter '{}'", ParamName).str(),
1261 }
1262 }
1263 return Result;
1264}
1265
1266Expected<InstCombineOptions> parseInstCombineOptions(StringRef Params) {
1268 // When specifying "instcombine" in -passes enable fix-point verification by
1269 // default, as this is what most tests should use.
1270 Result.setVerifyFixpoint(true);
1271 while (!Params.empty()) {
1272 StringRef ParamName;
1273 std::tie(ParamName, Params) = Params.split(';');
1274
1275 bool Enable = !ParamName.consume_front("no-");
1276 if (ParamName == "verify-fixpoint") {
1277 Result.setVerifyFixpoint(Enable);
1278 } else if (Enable && ParamName.consume_front("max-iterations=")) {
1279 APInt MaxIterations;
1280 if (ParamName.getAsInteger(0, MaxIterations))
1282 formatv("invalid argument to InstCombine pass max-iterations "
1283 "parameter: '{}'",
1284 ParamName)
1285 .str(),
1287 Result.setMaxIterations((unsigned)MaxIterations.getZExtValue());
1288 } else {
1290 formatv("invalid InstCombine pass parameter '{}'", ParamName).str(),
1292 }
1293 }
1294 return Result;
1295}
1296
1297/// Parser of parameters for LoopVectorize pass.
1298Expected<LoopVectorizeOptions> parseLoopVectorizeOptions(StringRef Params) {
1300 while (!Params.empty()) {
1301 StringRef ParamName;
1302 std::tie(ParamName, Params) = Params.split(';');
1303
1304 bool Enable = !ParamName.consume_front("no-");
1305 if (ParamName == "interleave-forced-only") {
1307 } else if (ParamName == "vectorize-forced-only") {
1309 } else {
1311 formatv("invalid LoopVectorize parameter '{}'", ParamName).str(),
1313 }
1314 }
1315 return Opts;
1316}
1317
1318Expected<std::pair<bool, bool>> parseLoopUnswitchOptions(StringRef Params) {
1319 std::pair<bool, bool> Result = {false, true};
1320 while (!Params.empty()) {
1321 StringRef ParamName;
1322 std::tie(ParamName, Params) = Params.split(';');
1323
1324 bool Enable = !ParamName.consume_front("no-");
1325 if (ParamName == "nontrivial") {
1326 Result.first = Enable;
1327 } else if (ParamName == "trivial") {
1328 Result.second = Enable;
1329 } else {
1331 formatv("invalid LoopUnswitch pass parameter '{}'", ParamName).str(),
1333 }
1334 }
1335 return Result;
1336}
1337
1338Expected<LICMOptions> parseLICMOptions(StringRef Params) {
1340 while (!Params.empty()) {
1341 StringRef ParamName;
1342 std::tie(ParamName, Params) = Params.split(';');
1343
1344 bool Enable = !ParamName.consume_front("no-");
1345 if (ParamName == "allowspeculation") {
1346 Result.AllowSpeculation = Enable;
1347 } else {
1349 formatv("invalid LICM pass parameter '{}'", ParamName).str(),
1351 }
1352 }
1353 return Result;
1354}
1355
1356struct LoopRotateOptions {
1357 bool EnableHeaderDuplication = true;
1358 bool PrepareForLTO = false;
1359 bool CheckExitCount = false;
1360};
1361
1362Expected<LoopRotateOptions> parseLoopRotateOptions(StringRef Params) {
1363 LoopRotateOptions Result;
1364 while (!Params.empty()) {
1365 StringRef ParamName;
1366 std::tie(ParamName, Params) = Params.split(';');
1367
1368 bool Enable = !ParamName.consume_front("no-");
1369 if (ParamName == "header-duplication") {
1370 Result.EnableHeaderDuplication = Enable;
1371 } else if (ParamName == "prepare-for-lto") {
1372 Result.PrepareForLTO = Enable;
1373 } else if (ParamName == "check-exit-count") {
1374 Result.CheckExitCount = Enable;
1375 } else {
1377 formatv("invalid LoopRotate pass parameter '{}'", ParamName).str(),
1379 }
1380 }
1381 return Result;
1382}
1383
1384Expected<bool> parseMergedLoadStoreMotionOptions(StringRef Params) {
1385 bool Result = false;
1386 while (!Params.empty()) {
1387 StringRef ParamName;
1388 std::tie(ParamName, Params) = Params.split(';');
1389
1390 bool Enable = !ParamName.consume_front("no-");
1391 if (ParamName == "split-footer-bb") {
1392 Result = Enable;
1393 } else {
1395 formatv("invalid MergedLoadStoreMotion pass parameter '{}'",
1396 ParamName)
1397 .str(),
1399 }
1400 }
1401 return Result;
1402}
1403
1404Expected<GVNOptions> parseGVNOptions(StringRef Params) {
1406 while (!Params.empty()) {
1407 StringRef ParamName;
1408 std::tie(ParamName, Params) = Params.split(';');
1409
1410 bool Enable = !ParamName.consume_front("no-");
1411 if (ParamName == "scalar-pre") {
1412 Result.setScalarPRE(Enable);
1413 } else if (ParamName == "load-pre") {
1414 Result.setLoadPRE(Enable);
1415 } else if (ParamName == "split-backedge-load-pre") {
1416 Result.setLoadPRESplitBackedge(Enable);
1417 } else if (ParamName == "memdep") {
1418 // MemDep and MemorySSA are mutually exclusive.
1419 Result.setMemDep(Enable);
1420 Result.setMemorySSA(!Enable);
1421 } else if (ParamName == "memoryssa") {
1422 // MemDep and MemorySSA are mutually exclusive.
1423 Result.setMemorySSA(Enable);
1424 Result.setMemDep(!Enable);
1425 } else {
1427 formatv("invalid GVN pass parameter '{}'", ParamName).str(),
1429 }
1430 }
1431 return Result;
1432}
1433
1434Expected<IPSCCPOptions> parseIPSCCPOptions(StringRef Params) {
1436 while (!Params.empty()) {
1437 StringRef ParamName;
1438 std::tie(ParamName, Params) = Params.split(';');
1439
1440 bool Enable = !ParamName.consume_front("no-");
1441 if (ParamName == "func-spec")
1442 Result.setFuncSpec(Enable);
1443 else
1445 formatv("invalid IPSCCP pass parameter '{}'", ParamName).str(),
1447 }
1448 return Result;
1449}
1450
1451Expected<ScalarizerPassOptions> parseScalarizerOptions(StringRef Params) {
1453 while (!Params.empty()) {
1454 StringRef ParamName;
1455 std::tie(ParamName, Params) = Params.split(';');
1456
1457 if (ParamName.consume_front("min-bits=")) {
1458 if (ParamName.getAsInteger(0, Result.ScalarizeMinBits)) {
1460 formatv("invalid argument to Scalarizer pass min-bits "
1461 "parameter: '{}'",
1462 ParamName)
1463 .str(),
1465 }
1466
1467 continue;
1468 }
1469
1470 bool Enable = !ParamName.consume_front("no-");
1471 if (ParamName == "load-store")
1472 Result.ScalarizeLoadStore = Enable;
1473 else if (ParamName == "variable-insert-extract")
1474 Result.ScalarizeVariableInsertExtract = Enable;
1475 else {
1477 formatv("invalid Scalarizer pass parameter '{}'", ParamName).str(),
1479 }
1480 }
1481
1482 return Result;
1483}
1484
1485Expected<SROAOptions> parseSROAOptions(StringRef Params) {
1487 bool SawCFGOption = false;
1488 while (!Params.empty()) {
1489 StringRef ParamName;
1490 std::tie(ParamName, Params) = Params.split(';');
1491
1492 if (ParamName == "modify-cfg") {
1493 if (SawCFGOption)
1494 return make_error<StringError>("multiple SROA CFG options specified",
1497 SawCFGOption = true;
1498 } else if (ParamName == "preserve-cfg") {
1499 if (SawCFGOption)
1500 return make_error<StringError>("multiple SROA CFG options specified",
1503 SawCFGOption = true;
1504 } else if (ParamName == "aggregate-to-vector") {
1505 Result.AggregateToVector = true;
1506 } else {
1508 formatv("invalid SROA pass parameter '{}' (expected preserve-cfg, "
1509 "modify-cfg, or aggregate-to-vector)",
1510 ParamName)
1511 .str(),
1513 }
1514 }
1515 return Result;
1516}
1517
1519parseStackLifetimeOptions(StringRef Params) {
1521 while (!Params.empty()) {
1522 StringRef ParamName;
1523 std::tie(ParamName, Params) = Params.split(';');
1524
1525 if (ParamName == "may") {
1527 } else if (ParamName == "must") {
1529 } else {
1531 formatv("invalid StackLifetime parameter '{}'", ParamName).str(),
1533 }
1534 }
1535 return Result;
1536}
1537
1538Expected<bool> parseDependenceAnalysisPrinterOptions(StringRef Params) {
1539 return PassBuilder::parseSinglePassOption(Params, "normalized-results",
1540 "DependenceAnalysisPrinter");
1541}
1542
1543Expected<bool> parseSeparateConstOffsetFromGEPPassOptions(StringRef Params) {
1544 return PassBuilder::parseSinglePassOption(Params, "lower-gep",
1545 "SeparateConstOffsetFromGEP");
1546}
1547
1548Expected<bool> parseStructurizeCFGPassOptions(StringRef Params) {
1549 return PassBuilder::parseSinglePassOption(Params, "skip-uniform-regions",
1550 "StructurizeCFG");
1551}
1552
1554parseFunctionSimplificationPipelineOptions(StringRef Params) {
1555 std::optional<OptimizationLevel> L = parseOptLevel(Params);
1556 if (!L || *L == OptimizationLevel::O0) {
1558 formatv("invalid function-simplification parameter '{}'", Params).str(),
1560 };
1561 return *L;
1562}
1563
1564Expected<bool> parseMemorySSAPrinterPassOptions(StringRef Params) {
1565 return PassBuilder::parseSinglePassOption(Params, "no-ensure-optimized-uses",
1566 "MemorySSAPrinterPass");
1567}
1568
1569Expected<bool> parseSpeculativeExecutionPassOptions(StringRef Params) {
1570 return PassBuilder::parseSinglePassOption(Params, "only-if-divergent-target",
1571 "SpeculativeExecutionPass");
1572}
1573
1574Expected<std::string> parseMemProfUsePassOptions(StringRef Params) {
1575 std::string Result;
1576 while (!Params.empty()) {
1577 StringRef ParamName;
1578 std::tie(ParamName, Params) = Params.split(';');
1579
1580 if (ParamName.consume_front("profile-filename=")) {
1581 Result = ParamName.str();
1582 } else {
1584 formatv("invalid MemProfUse pass parameter '{}'", ParamName).str(),
1586 }
1587 }
1588 return Result;
1589}
1590
1592parseStructuralHashPrinterPassOptions(StringRef Params) {
1593 if (Params.empty())
1595 if (Params == "detailed")
1597 if (Params == "call-target-ignored")
1600 formatv("invalid structural hash printer parameter '{}'", Params).str(),
1602}
1603
1604Expected<GlobalMergeOptions> parseGlobalMergeOptions(StringRef Params) {
1606 while (!Params.empty()) {
1607 StringRef ParamName;
1608 std::tie(ParamName, Params) = Params.split(';');
1609
1610 bool Enable = !ParamName.consume_front("no-");
1611 if (ParamName == "group-by-use")
1612 Result.GroupByUse = Enable;
1613 else if (ParamName == "ignore-single-use")
1614 Result.IgnoreSingleUse = Enable;
1615 else if (ParamName == "merge-const")
1616 Result.MergeConstantGlobals = Enable;
1617 else if (ParamName == "merge-const-aggressive")
1618 Result.MergeConstAggressive = Enable;
1619 else if (ParamName == "merge-external")
1620 Result.MergeExternal = Enable;
1621 else if (ParamName.consume_front("max-offset=")) {
1622 if (ParamName.getAsInteger(0, Result.MaxOffset))
1624 formatv("invalid GlobalMergePass parameter '{}'", ParamName).str(),
1626 } else {
1628 formatv("invalid global-merge pass parameter '{}'", Params).str(),
1630 }
1631 }
1632 return Result;
1633}
1634
1635Expected<SmallVector<std::string, 0>> parseInternalizeGVs(StringRef Params) {
1636 SmallVector<std::string, 1> PreservedGVs;
1637 while (!Params.empty()) {
1638 StringRef ParamName;
1639 std::tie(ParamName, Params) = Params.split(';');
1640
1641 if (ParamName.consume_front("preserve-gv=")) {
1642 PreservedGVs.push_back(ParamName.str());
1643 } else {
1645 formatv("invalid Internalize pass parameter '{}'", ParamName).str(),
1647 }
1648 }
1649
1650 return Expected<SmallVector<std::string, 0>>(std::move(PreservedGVs));
1651}
1652
1654parseRegAllocFastPassOptions(PassBuilder &PB, StringRef Params) {
1656 while (!Params.empty()) {
1657 StringRef ParamName;
1658 std::tie(ParamName, Params) = Params.split(';');
1659
1660 if (ParamName.consume_front("filter=")) {
1661 std::optional<RegAllocFilterFunc> Filter =
1662 PB.parseRegAllocFilter(ParamName);
1663 if (!Filter) {
1665 formatv("invalid regallocfast register filter '{}'", ParamName)
1666 .str(),
1668 }
1669 Opts.Filter = *Filter;
1670 Opts.FilterName = ParamName;
1671 continue;
1672 }
1673
1674 if (ParamName == "no-clear-vregs") {
1675 Opts.ClearVRegs = false;
1676 continue;
1677 }
1678
1680 formatv("invalid regallocfast pass parameter '{}'", ParamName).str(),
1682 }
1683 return Opts;
1684}
1685
1687parseBoundsCheckingOptions(StringRef Params) {
1689 while (!Params.empty()) {
1690 StringRef ParamName;
1691 std::tie(ParamName, Params) = Params.split(';');
1692 if (ParamName == "trap") {
1693 Options.Rt = std::nullopt;
1694 } else if (ParamName == "rt") {
1695 Options.Rt = {
1696 /*MinRuntime=*/false,
1697 /*MayReturn=*/true,
1698 /*HandlerPreserveAllRegs=*/false,
1699 };
1700 } else if (ParamName == "rt-abort") {
1701 Options.Rt = {
1702 /*MinRuntime=*/false,
1703 /*MayReturn=*/false,
1704 /*HandlerPreserveAllRegs=*/false,
1705 };
1706 } else if (ParamName == "min-rt") {
1707 Options.Rt = {
1708 /*MinRuntime=*/true,
1709 /*MayReturn=*/true,
1710 /*HandlerPreserveAllRegs=*/false,
1711 };
1712 } else if (ParamName == "min-rt-abort") {
1713 Options.Rt = {
1714 /*MinRuntime=*/true,
1715 /*MayReturn=*/false,
1716 /*HandlerPreserveAllRegs=*/false,
1717 };
1718 } else if (ParamName == "merge") {
1719 Options.Merge = true;
1720 } else if (ParamName == "handler-preserve-all-regs") {
1721 if (Options.Rt)
1722 Options.Rt->HandlerPreserveAllRegs = true;
1723 } else {
1724 StringRef ParamEQ;
1725 StringRef Val;
1726 std::tie(ParamEQ, Val) = ParamName.split('=');
1727 int8_t Id;
1728 if (ParamEQ == "guard" && !Val.getAsInteger(0, Id)) {
1729 Options.GuardKind = Id;
1730 } else {
1732 formatv("invalid BoundsChecking pass parameter '{}'", ParamName)
1733 .str(),
1735 }
1736 }
1737 }
1738 return Options;
1739}
1740
1741Expected<CodeGenOptLevel> parseExpandIRInstsOptions(StringRef Param) {
1742 if (Param.empty())
1743 return CodeGenOptLevel::None;
1744
1745 // Parse a CodeGenOptLevel, e.g. "O1", "O2", "O3".
1746 auto [Prefix, Digit] = Param.split('O');
1747
1748 uint8_t N;
1749 if (!Prefix.empty() || Digit.getAsInteger(10, N))
1750 return createStringError("invalid expand-ir-insts pass parameter '%s'",
1751 Param.str().c_str());
1752
1753 std::optional<CodeGenOptLevel> Level = CodeGenOpt::getLevel(N);
1754 if (!Level.has_value())
1755 return createStringError(
1756 "invalid optimization level for expand-ir-insts pass: %s",
1757 Digit.str().c_str());
1758
1759 return *Level;
1760}
1761
1763parseRegAllocGreedyFilterFunc(PassBuilder &PB, StringRef Params) {
1764 if (Params.empty() || Params == "all")
1765 return RAGreedyPass::Options();
1766
1767 std::optional<RegAllocFilterFunc> Filter = PB.parseRegAllocFilter(Params);
1768 if (Filter)
1769 return RAGreedyPass::Options{*Filter, Params};
1770
1772 formatv("invalid regallocgreedy register filter '{}'", Params).str(),
1774}
1775
1776Expected<bool> parseMachineSinkingPassOptions(StringRef Params) {
1777 return PassBuilder::parseSinglePassOption(Params, "enable-sink-fold",
1778 "MachineSinkingPass");
1779}
1780
1781Expected<bool> parseMachineBlockPlacementPassOptions(StringRef Params) {
1782 bool AllowTailMerge = true;
1783 if (!Params.empty()) {
1784 AllowTailMerge = !Params.consume_front("no-");
1785 if (Params != "tail-merge")
1787 formatv("invalid MachineBlockPlacementPass parameter '{}'", Params)
1788 .str(),
1790 }
1791 return AllowTailMerge;
1792}
1793
1794Expected<bool> parseVirtRegRewriterPassOptions(StringRef Params) {
1795 bool ClearVirtRegs = true;
1796 if (!Params.empty()) {
1797 ClearVirtRegs = !Params.consume_front("no-");
1798 if (Params != "clear-vregs")
1800 formatv("invalid VirtRegRewriter pass parameter '{}'", Params).str(),
1802 }
1803 return ClearVirtRegs;
1804}
1805
1806struct FatLTOOptions {
1807 OptimizationLevel OptLevel;
1808 bool ThinLTO = false;
1809 bool EmitSummary = false;
1810};
1811
1812Expected<FatLTOOptions> parseFatLTOOptions(StringRef Params) {
1813 FatLTOOptions Result;
1814 bool HaveOptLevel = false;
1815 while (!Params.empty()) {
1816 StringRef ParamName;
1817 std::tie(ParamName, Params) = Params.split(';');
1818
1819 if (ParamName == "thinlto") {
1820 Result.ThinLTO = true;
1821 } else if (ParamName == "emit-summary") {
1822 Result.EmitSummary = true;
1823 } else if (std::optional<OptimizationLevel> OptLevel =
1824 parseOptLevel(ParamName)) {
1825 Result.OptLevel = *OptLevel;
1826 HaveOptLevel = true;
1827 } else {
1829 formatv("invalid fatlto-pre-link pass parameter '{}'", ParamName)
1830 .str(),
1832 }
1833 }
1834 if (!HaveOptLevel)
1836 "missing optimization level for fatlto-pre-link pipeline",
1838 return Result;
1839}
1840
1841} // namespace
1842
1843/// Tests whether registered callbacks will accept a given pass name.
1844///
1845/// When parsing a pipeline text, the type of the outermost pipeline may be
1846/// omitted, in which case the type is automatically determined from the first
1847/// pass name in the text. This may be a name that is handled through one of the
1848/// callbacks. We check this through the oridinary parsing callbacks by setting
1849/// up a dummy PassManager in order to not force the client to also handle this
1850/// type of query.
1851template <typename PassManagerT, typename CallbacksT>
1852static bool callbacksAcceptPassName(StringRef Name, CallbacksT &Callbacks) {
1853 if (!Callbacks.empty()) {
1854 PassManagerT DummyPM;
1855 for (auto &CB : Callbacks)
1856 if (CB(Name, DummyPM, {}))
1857 return true;
1858 }
1859 return false;
1860}
1861
1862template <typename CallbacksT>
1863static bool isModulePassName(StringRef Name, CallbacksT &Callbacks) {
1864 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1865
1866 // Explicitly handle pass manager names.
1867 if (Name == "module")
1868 return true;
1869 if (Name == "cgscc")
1870 return true;
1871 if (NameNoBracket == "function")
1872 return true;
1873 if (Name == "coro-cond")
1874 return true;
1875
1876#define MODULE_PASS(NAME, CREATE_PASS) \
1877 if (Name == NAME) \
1878 return true;
1879#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1880 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1881 return true;
1882#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
1883 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1884 return true;
1885#include "PassRegistry.def"
1886
1887 return callbacksAcceptPassName<ModulePassManager>(Name, Callbacks);
1888}
1889
1890template <typename CallbacksT>
1891static bool isCGSCCPassName(StringRef Name, CallbacksT &Callbacks) {
1892 // Explicitly handle pass manager names.
1893 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1894 if (Name == "cgscc")
1895 return true;
1896 if (NameNoBracket == "function")
1897 return true;
1898
1899 // Explicitly handle custom-parsed pass names.
1900 if (parseDevirtPassName(Name))
1901 return true;
1902
1903#define CGSCC_PASS(NAME, CREATE_PASS) \
1904 if (Name == NAME) \
1905 return true;
1906#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1907 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1908 return true;
1909#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
1910 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1911 return true;
1912#include "PassRegistry.def"
1913
1914 return callbacksAcceptPassName<CGSCCPassManager>(Name, Callbacks);
1915}
1916
1917template <typename CallbacksT>
1918static bool isFunctionPassName(StringRef Name, CallbacksT &Callbacks) {
1919 // Explicitly handle pass manager names.
1920 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1921 if (NameNoBracket == "function")
1922 return true;
1923 if (Name == "loop" || Name == "loop-mssa" || Name == "machine-function")
1924 return true;
1925
1926#define FUNCTION_PASS(NAME, CREATE_PASS) \
1927 if (Name == NAME) \
1928 return true;
1929#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1930 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1931 return true;
1932#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1933 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1934 return true;
1935#include "PassRegistry.def"
1936
1937 return callbacksAcceptPassName<FunctionPassManager>(Name, Callbacks);
1938}
1939
1940template <typename CallbacksT>
1941static bool isMachineFunctionPassName(StringRef Name, CallbacksT &Callbacks) {
1942 // Explicitly handle pass manager names.
1943 if (Name == "machine-function")
1944 return true;
1945
1946#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
1947 if (Name == NAME) \
1948 return true;
1949#define MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, \
1950 PARAMS) \
1951 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1952 return true;
1953
1954#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1955 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1956 return true;
1957
1958#include "llvm/Passes/MachinePassRegistry.def"
1959
1961}
1962
1963template <typename CallbacksT>
1964static bool isLoopNestPassName(StringRef Name, CallbacksT &Callbacks,
1965 bool &UseMemorySSA) {
1966 UseMemorySSA = false;
1967
1968 if (PassBuilder::checkParametrizedPassName(Name, "lnicm")) {
1969 UseMemorySSA = true;
1970 return true;
1971 }
1972
1973#define LOOPNEST_PASS(NAME, CREATE_PASS) \
1974 if (Name == NAME) \
1975 return true;
1976#include "PassRegistry.def"
1977
1978 return callbacksAcceptPassName<LoopPassManager>(Name, Callbacks);
1979}
1980
1981template <typename CallbacksT>
1982static bool isLoopPassName(StringRef Name, CallbacksT &Callbacks,
1983 bool &UseMemorySSA) {
1984 UseMemorySSA = false;
1985
1986 if (PassBuilder::checkParametrizedPassName(Name, "licm")) {
1987 UseMemorySSA = true;
1988 return true;
1989 }
1990
1991#define LOOP_PASS(NAME, CREATE_PASS) \
1992 if (Name == NAME) \
1993 return true;
1994#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1995 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1996 return true;
1997#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
1998 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1999 return true;
2000#include "PassRegistry.def"
2001
2002 return callbacksAcceptPassName<LoopPassManager>(Name, Callbacks);
2003}
2004
2005std::optional<std::vector<PassBuilder::PipelineElement>>
2006PassBuilder::parsePipelineText(StringRef Text) {
2007 std::vector<PipelineElement> ResultPipeline;
2008
2009 SmallVector<std::vector<PipelineElement> *, 4> PipelineStack = {
2010 &ResultPipeline};
2011 for (;;) {
2012 std::vector<PipelineElement> &Pipeline = *PipelineStack.back();
2013 size_t Pos = Text.find_first_of(",()");
2014 Pipeline.push_back({Text.substr(0, Pos), {}});
2015
2016 // If we have a single terminating name, we're done.
2017 if (Pos == Text.npos)
2018 break;
2019
2020 char Sep = Text[Pos];
2021 Text = Text.substr(Pos + 1);
2022 if (Sep == ',')
2023 // Just a name ending in a comma, continue.
2024 continue;
2025
2026 if (Sep == '(') {
2027 // Push the inner pipeline onto the stack to continue processing.
2028 PipelineStack.push_back(&Pipeline.back().InnerPipeline);
2029 continue;
2030 }
2031
2032 assert(Sep == ')' && "Bogus separator!");
2033 // When handling the close parenthesis, we greedily consume them to avoid
2034 // empty strings in the pipeline.
2035 do {
2036 // If we try to pop the outer pipeline we have unbalanced parentheses.
2037 if (PipelineStack.size() == 1)
2038 return std::nullopt;
2039
2040 PipelineStack.pop_back();
2041 } while (Text.consume_front(")"));
2042
2043 // Check if we've finished parsing.
2044 if (Text.empty())
2045 break;
2046
2047 // Otherwise, the end of an inner pipeline always has to be followed by
2048 // a comma, and then we can continue.
2049 if (!Text.consume_front(","))
2050 return std::nullopt;
2051 }
2052
2053 if (PipelineStack.size() > 1)
2054 // Unbalanced paretheses.
2055 return std::nullopt;
2056
2057 assert(PipelineStack.back() == &ResultPipeline &&
2058 "Wrong pipeline at the bottom of the stack!");
2059 return {std::move(ResultPipeline)};
2060}
2061
2067
2068Error PassBuilder::parseModulePass(ModulePassManager &MPM,
2069 const PipelineElement &E) {
2070 auto &Name = E.Name;
2071 auto &InnerPipeline = E.InnerPipeline;
2072
2073 // First handle complex passes like the pass managers which carry pipelines.
2074 if (!InnerPipeline.empty()) {
2075 if (Name == "module") {
2076 ModulePassManager NestedMPM;
2077 if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline))
2078 return Err;
2079 MPM.addPass(std::move(NestedMPM));
2080 return Error::success();
2081 }
2082 if (Name == "coro-cond") {
2083 ModulePassManager NestedMPM;
2084 if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline))
2085 return Err;
2086 MPM.addPass(CoroConditionalWrapper(std::move(NestedMPM)));
2087 return Error::success();
2088 }
2089 if (Name == "cgscc") {
2090 CGSCCPassManager CGPM;
2091 if (auto Err = parseCGSCCPassPipeline(CGPM, InnerPipeline))
2092 return Err;
2094 return Error::success();
2095 }
2096 if (auto Params = parseFunctionPipelineName(Name)) {
2097 if (Params->second)
2099 "cannot have a no-rerun module to function adaptor",
2102 if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline))
2103 return Err;
2104 MPM.addPass(
2105 createModuleToFunctionPassAdaptor(std::move(FPM), Params->first));
2106 return Error::success();
2107 }
2108
2109 for (auto &C : ModulePipelineParsingCallbacks)
2110 if (C(Name, MPM, InnerPipeline))
2111 return Error::success();
2112
2113 // Normal passes can't have pipelines.
2115 formatv("invalid use of '{}' pass as module pipeline", Name).str(),
2117 ;
2118 }
2119
2120 // Finally expand the basic registered passes from the .inc file.
2121#define MODULE_PASS(NAME, CREATE_PASS) \
2122 if (Name == NAME) { \
2123 MPM.addPass(CREATE_PASS); \
2124 return Error::success(); \
2125 }
2126#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2127 if (checkParametrizedPassName(Name, NAME)) { \
2128 auto Params = parsePassParameters(PARSER, Name, NAME); \
2129 if (!Params) \
2130 return Params.takeError(); \
2131 MPM.addPass(CREATE_PASS(Params.get())); \
2132 return Error::success(); \
2133 }
2134#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
2135 if (Name == "require<" NAME ">") { \
2136 MPM.addPass( \
2137 RequireAnalysisPass< \
2138 std::remove_reference_t<decltype(CREATE_PASS)>, Module>()); \
2139 return Error::success(); \
2140 } \
2141 if (Name == "invalidate<" NAME ">") { \
2142 MPM.addPass(InvalidateAnalysisPass< \
2143 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2144 return Error::success(); \
2145 }
2146#define CGSCC_PASS(NAME, CREATE_PASS) \
2147 if (Name == NAME) { \
2148 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(CREATE_PASS)); \
2149 return Error::success(); \
2150 }
2151#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2152 if (checkParametrizedPassName(Name, NAME)) { \
2153 auto Params = parsePassParameters(PARSER, Name, NAME); \
2154 if (!Params) \
2155 return Params.takeError(); \
2156 MPM.addPass( \
2157 createModuleToPostOrderCGSCCPassAdaptor(CREATE_PASS(Params.get()))); \
2158 return Error::success(); \
2159 }
2160#define FUNCTION_PASS(NAME, CREATE_PASS) \
2161 if (Name == NAME) { \
2162 if constexpr (std::is_constructible_v< \
2163 std::remove_reference_t<decltype(CREATE_PASS)>, \
2164 const TargetMachine &>) { \
2165 if (!TM) \
2166 return make_error<StringError>( \
2167 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2168 inconvertibleErrorCode()); \
2169 } \
2170 MPM.addPass(createModuleToFunctionPassAdaptor(CREATE_PASS)); \
2171 return Error::success(); \
2172 }
2173#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2174 if (checkParametrizedPassName(Name, NAME)) { \
2175 auto Params = parsePassParameters(PARSER, Name, NAME); \
2176 if (!Params) \
2177 return Params.takeError(); \
2178 auto CreatePass = CREATE_PASS; \
2179 if constexpr (std::is_constructible_v< \
2180 std::remove_reference_t<decltype(CreatePass( \
2181 Params.get()))>, \
2182 const TargetMachine &, \
2183 std::remove_reference_t<decltype(Params.get())>>) { \
2184 if (!TM) { \
2185 return make_error<StringError>( \
2186 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2187 inconvertibleErrorCode()); \
2188 } \
2189 } \
2190 MPM.addPass(createModuleToFunctionPassAdaptor(CREATE_PASS(Params.get()))); \
2191 return Error::success(); \
2192 }
2193#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2194 if (Name == NAME) { \
2195 MPM.addPass(createModuleToFunctionPassAdaptor( \
2196 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2197 return Error::success(); \
2198 }
2199#define LOOP_PASS(NAME, CREATE_PASS) \
2200 if (Name == NAME) { \
2201 MPM.addPass(createModuleToFunctionPassAdaptor( \
2202 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2203 return Error::success(); \
2204 }
2205#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2206 if (checkParametrizedPassName(Name, NAME)) { \
2207 auto Params = parsePassParameters(PARSER, Name, NAME); \
2208 if (!Params) \
2209 return Params.takeError(); \
2210 MPM.addPass(createModuleToFunctionPassAdaptor( \
2211 createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), false))); \
2212 return Error::success(); \
2213 }
2214#include "PassRegistry.def"
2215
2216 for (auto &C : ModulePipelineParsingCallbacks)
2217 if (C(Name, MPM, InnerPipeline))
2218 return Error::success();
2220 formatv("unknown module pass '{}'", Name).str(),
2222}
2223
2224Error PassBuilder::parseCGSCCPass(CGSCCPassManager &CGPM,
2225 const PipelineElement &E) {
2226 auto &Name = E.Name;
2227 auto &InnerPipeline = E.InnerPipeline;
2228
2229 // First handle complex passes like the pass managers which carry pipelines.
2230 if (!InnerPipeline.empty()) {
2231 if (Name == "cgscc") {
2232 CGSCCPassManager NestedCGPM;
2233 if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline))
2234 return Err;
2235 // Add the nested pass manager with the appropriate adaptor.
2236 CGPM.addPass(std::move(NestedCGPM));
2237 return Error::success();
2238 }
2239 if (auto Params = parseFunctionPipelineName(Name)) {
2241 if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline))
2242 return Err;
2243 // Add the nested pass manager with the appropriate adaptor.
2245 std::move(FPM), Params->first, Params->second));
2246 return Error::success();
2247 }
2248 if (auto MaxRepetitions = parseDevirtPassName(Name)) {
2249 CGSCCPassManager NestedCGPM;
2250 if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline))
2251 return Err;
2252 CGPM.addPass(
2253 createDevirtSCCRepeatedPass(std::move(NestedCGPM), *MaxRepetitions));
2254 return Error::success();
2255 }
2256
2257 for (auto &C : CGSCCPipelineParsingCallbacks)
2258 if (C(Name, CGPM, InnerPipeline))
2259 return Error::success();
2260
2261 // Normal passes can't have pipelines.
2263 formatv("invalid use of '{}' pass as cgscc pipeline", Name).str(),
2265 }
2266
2267// Now expand the basic registered passes from the .inc file.
2268#define CGSCC_PASS(NAME, CREATE_PASS) \
2269 if (Name == NAME) { \
2270 CGPM.addPass(CREATE_PASS); \
2271 return Error::success(); \
2272 }
2273#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2274 if (checkParametrizedPassName(Name, NAME)) { \
2275 auto Params = parsePassParameters(PARSER, Name, NAME); \
2276 if (!Params) \
2277 return Params.takeError(); \
2278 CGPM.addPass(CREATE_PASS(Params.get())); \
2279 return Error::success(); \
2280 }
2281#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
2282 if (Name == "require<" NAME ">") { \
2283 CGPM.addPass(RequireAnalysisPass< \
2284 std::remove_reference_t<decltype(CREATE_PASS)>, \
2285 LazyCallGraph::SCC, CGSCCAnalysisManager, LazyCallGraph &, \
2286 CGSCCUpdateResult &>()); \
2287 return Error::success(); \
2288 } \
2289 if (Name == "invalidate<" NAME ">") { \
2290 CGPM.addPass(InvalidateAnalysisPass< \
2291 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2292 return Error::success(); \
2293 }
2294#define FUNCTION_PASS(NAME, CREATE_PASS) \
2295 if (Name == NAME) { \
2296 if constexpr (std::is_constructible_v< \
2297 std::remove_reference_t<decltype(CREATE_PASS)>, \
2298 const TargetMachine &>) { \
2299 if (!TM) \
2300 return make_error<StringError>( \
2301 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2302 inconvertibleErrorCode()); \
2303 } \
2304 CGPM.addPass(createCGSCCToFunctionPassAdaptor(CREATE_PASS)); \
2305 return Error::success(); \
2306 }
2307#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2308 if (checkParametrizedPassName(Name, NAME)) { \
2309 auto Params = parsePassParameters(PARSER, Name, NAME); \
2310 if (!Params) \
2311 return Params.takeError(); \
2312 auto CreatePass = CREATE_PASS; \
2313 if constexpr (std::is_constructible_v< \
2314 std::remove_reference_t<decltype(CreatePass( \
2315 Params.get()))>, \
2316 const TargetMachine &, \
2317 std::remove_reference_t<decltype(Params.get())>>) { \
2318 if (!TM) { \
2319 return make_error<StringError>( \
2320 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2321 inconvertibleErrorCode()); \
2322 } \
2323 } \
2324 CGPM.addPass(createCGSCCToFunctionPassAdaptor(CREATE_PASS(Params.get()))); \
2325 return Error::success(); \
2326 }
2327#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2328 if (Name == NAME) { \
2329 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
2330 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2331 return Error::success(); \
2332 }
2333#define LOOP_PASS(NAME, CREATE_PASS) \
2334 if (Name == NAME) { \
2335 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
2336 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2337 return Error::success(); \
2338 }
2339#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2340 if (checkParametrizedPassName(Name, NAME)) { \
2341 auto Params = parsePassParameters(PARSER, Name, NAME); \
2342 if (!Params) \
2343 return Params.takeError(); \
2344 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
2345 createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), false))); \
2346 return Error::success(); \
2347 }
2348#include "PassRegistry.def"
2349
2350 for (auto &C : CGSCCPipelineParsingCallbacks)
2351 if (C(Name, CGPM, InnerPipeline))
2352 return Error::success();
2353 return make_error<StringError>(formatv("unknown cgscc pass '{}'", Name).str(),
2355}
2356
2357Error PassBuilder::parseFunctionPass(FunctionPassManager &FPM,
2358 const PipelineElement &E) {
2359 auto &Name = E.Name;
2360 auto &InnerPipeline = E.InnerPipeline;
2361
2362 // First handle complex passes like the pass managers which carry pipelines.
2363 if (!InnerPipeline.empty()) {
2364 if (Name == "function") {
2365 FunctionPassManager NestedFPM;
2366 if (auto Err = parseFunctionPassPipeline(NestedFPM, InnerPipeline))
2367 return Err;
2368 // Add the nested pass manager with the appropriate adaptor.
2369 FPM.addPass(std::move(NestedFPM));
2370 return Error::success();
2371 }
2372 if (Name == "loop" || Name == "loop-mssa") {
2373 LoopPassManager LPM;
2374 if (auto Err = parseLoopPassPipeline(LPM, InnerPipeline))
2375 return Err;
2376 // Add the nested pass manager with the appropriate adaptor.
2377 bool UseMemorySSA = (Name == "loop-mssa");
2378 FPM.addPass(
2379 createFunctionToLoopPassAdaptor(std::move(LPM), UseMemorySSA));
2380 return Error::success();
2381 }
2382 if (Name == "machine-function") {
2384 if (auto Err = parseMachinePassPipeline(MFPM, InnerPipeline))
2385 return Err;
2387 return Error::success();
2388 }
2389
2390 for (auto &C : FunctionPipelineParsingCallbacks)
2391 if (C(Name, FPM, InnerPipeline))
2392 return Error::success();
2393
2394 // Normal passes can't have pipelines.
2396 formatv("invalid use of '{}' pass as function pipeline", Name).str(),
2398 }
2399
2400// Now expand the basic registered passes from the .inc file.
2401#define FUNCTION_PASS(NAME, CREATE_PASS) \
2402 if (Name == NAME) { \
2403 if constexpr (std::is_constructible_v< \
2404 std::remove_reference_t<decltype(CREATE_PASS)>, \
2405 const TargetMachine &>) { \
2406 if (!TM) \
2407 return make_error<StringError>( \
2408 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2409 inconvertibleErrorCode()); \
2410 } \
2411 FPM.addPass(CREATE_PASS); \
2412 return Error::success(); \
2413 }
2414#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2415 if (checkParametrizedPassName(Name, NAME)) { \
2416 auto Params = parsePassParameters(PARSER, Name, NAME); \
2417 if (!Params) \
2418 return Params.takeError(); \
2419 auto CreatePass = CREATE_PASS; \
2420 if constexpr (std::is_constructible_v< \
2421 std::remove_reference_t<decltype(CreatePass( \
2422 Params.get()))>, \
2423 const TargetMachine &, \
2424 std::remove_reference_t<decltype(Params.get())>>) { \
2425 if (!TM) { \
2426 return make_error<StringError>( \
2427 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2428 inconvertibleErrorCode()); \
2429 } \
2430 } \
2431 FPM.addPass(CREATE_PASS(Params.get())); \
2432 return Error::success(); \
2433 }
2434#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
2435 if (Name == "require<" NAME ">") { \
2436 if constexpr (std::is_constructible_v< \
2437 std::remove_reference_t<decltype(CREATE_PASS)>, \
2438 const TargetMachine &>) { \
2439 if (!TM) \
2440 return make_error<StringError>( \
2441 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2442 inconvertibleErrorCode()); \
2443 } \
2444 FPM.addPass( \
2445 RequireAnalysisPass<std::remove_reference_t<decltype(CREATE_PASS)>, \
2446 Function>()); \
2447 return Error::success(); \
2448 } \
2449 if (Name == "invalidate<" NAME ">") { \
2450 FPM.addPass(InvalidateAnalysisPass< \
2451 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2452 return Error::success(); \
2453 }
2454// FIXME: UseMemorySSA is set to false. Maybe we could do things like:
2455// bool UseMemorySSA = !("canon-freeze" || "loop-predication" ||
2456// "guard-widening");
2457// The risk is that it may become obsolete if we're not careful.
2458#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2459 if (Name == NAME) { \
2460 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS, false)); \
2461 return Error::success(); \
2462 }
2463#define LOOP_PASS(NAME, CREATE_PASS) \
2464 if (Name == NAME) { \
2465 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS, false)); \
2466 return Error::success(); \
2467 }
2468#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2469 if (checkParametrizedPassName(Name, NAME)) { \
2470 auto Params = parsePassParameters(PARSER, Name, NAME); \
2471 if (!Params) \
2472 return Params.takeError(); \
2473 FPM.addPass( \
2474 createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), false)); \
2475 return Error::success(); \
2476 }
2477#include "PassRegistry.def"
2478
2479 for (auto &C : FunctionPipelineParsingCallbacks)
2480 if (C(Name, FPM, InnerPipeline))
2481 return Error::success();
2483 formatv("unknown function pass '{}'", Name).str(),
2485}
2486
2487Error PassBuilder::parseLoopPass(LoopPassManager &LPM,
2488 const PipelineElement &E) {
2489 StringRef Name = E.Name;
2490 auto &InnerPipeline = E.InnerPipeline;
2491
2492 // First handle complex passes like the pass managers which carry pipelines.
2493 if (!InnerPipeline.empty()) {
2494 if (Name == "loop") {
2495 LoopPassManager NestedLPM;
2496 if (auto Err = parseLoopPassPipeline(NestedLPM, InnerPipeline))
2497 return Err;
2498 // Add the nested pass manager with the appropriate adaptor.
2499 LPM.addPass(std::move(NestedLPM));
2500 return Error::success();
2501 }
2502
2503 for (auto &C : LoopPipelineParsingCallbacks)
2504 if (C(Name, LPM, InnerPipeline))
2505 return Error::success();
2506
2507 // Normal passes can't have pipelines.
2509 formatv("invalid use of '{}' pass as loop pipeline", Name).str(),
2511 }
2512
2513// Now expand the basic registered passes from the .inc file.
2514#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2515 if (Name == NAME) { \
2516 LPM.addPass(CREATE_PASS); \
2517 return Error::success(); \
2518 }
2519#define LOOP_PASS(NAME, CREATE_PASS) \
2520 if (Name == NAME) { \
2521 LPM.addPass(CREATE_PASS); \
2522 return Error::success(); \
2523 }
2524#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2525 if (checkParametrizedPassName(Name, NAME)) { \
2526 auto Params = parsePassParameters(PARSER, Name, NAME); \
2527 if (!Params) \
2528 return Params.takeError(); \
2529 LPM.addPass(CREATE_PASS(Params.get())); \
2530 return Error::success(); \
2531 }
2532#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
2533 if (Name == "require<" NAME ">") { \
2534 LPM.addPass(RequireAnalysisPass< \
2535 std::remove_reference_t<decltype(CREATE_PASS)>, Loop, \
2536 LoopAnalysisManager, LoopStandardAnalysisResults &, \
2537 LPMUpdater &>()); \
2538 return Error::success(); \
2539 } \
2540 if (Name == "invalidate<" NAME ">") { \
2541 LPM.addPass(InvalidateAnalysisPass< \
2542 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2543 return Error::success(); \
2544 }
2545#include "PassRegistry.def"
2546
2547 for (auto &C : LoopPipelineParsingCallbacks)
2548 if (C(Name, LPM, InnerPipeline))
2549 return Error::success();
2550 return make_error<StringError>(formatv("unknown loop pass '{}'", Name).str(),
2552}
2553
2554Error PassBuilder::parseMachinePass(MachineFunctionPassManager &MFPM,
2555 const PipelineElement &E) {
2556 StringRef Name = E.Name;
2557 // Handle any nested pass managers.
2558 if (!E.InnerPipeline.empty()) {
2559 if (E.Name == "machine-function") {
2561 if (auto Err = parseMachinePassPipeline(NestedPM, E.InnerPipeline))
2562 return Err;
2563 MFPM.addPass(std::move(NestedPM));
2564 return Error::success();
2565 }
2566 return make_error<StringError>("invalid pipeline",
2568 }
2569
2570#define MACHINE_MODULE_PASS(NAME, CREATE_PASS) \
2571 if (Name == NAME) { \
2572 MFPM.addPass(CREATE_PASS); \
2573 return Error::success(); \
2574 }
2575#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
2576 if (Name == NAME) { \
2577 MFPM.addPass(CREATE_PASS); \
2578 return Error::success(); \
2579 }
2580#define MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, \
2581 PARAMS) \
2582 if (checkParametrizedPassName(Name, NAME)) { \
2583 auto Params = parsePassParameters(PARSER, Name, NAME); \
2584 if (!Params) \
2585 return Params.takeError(); \
2586 MFPM.addPass(CREATE_PASS(Params.get())); \
2587 return Error::success(); \
2588 }
2589#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
2590 if (Name == "require<" NAME ">") { \
2591 MFPM.addPass( \
2592 RequireAnalysisPass<std::remove_reference_t<decltype(CREATE_PASS)>, \
2593 MachineFunction>()); \
2594 return Error::success(); \
2595 } \
2596 if (Name == "invalidate<" NAME ">") { \
2597 MFPM.addPass(InvalidateAnalysisPass< \
2598 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2599 return Error::success(); \
2600 }
2601#include "llvm/Passes/MachinePassRegistry.def"
2602
2603 for (auto &C : MachineFunctionPipelineParsingCallbacks)
2604 if (C(Name, MFPM, E.InnerPipeline))
2605 return Error::success();
2607 formatv("unknown machine pass '{}'", Name).str(),
2609}
2610
2611bool PassBuilder::parseAAPassName(AAManager &AA, StringRef Name) {
2612#define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
2613 if (Name == NAME) { \
2614 AA.registerModuleAnalysis< \
2615 std::remove_reference_t<decltype(CREATE_PASS)>>(); \
2616 return true; \
2617 }
2618#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
2619 if (Name == NAME) { \
2620 AA.registerFunctionAnalysis< \
2621 std::remove_reference_t<decltype(CREATE_PASS)>>(); \
2622 return true; \
2623 }
2624#include "PassRegistry.def"
2625
2626 for (auto &C : AAParsingCallbacks)
2627 if (C(Name, AA))
2628 return true;
2629 return false;
2630}
2631
2632Error PassBuilder::parseMachinePassPipeline(
2634 for (const auto &Element : Pipeline) {
2635 if (auto Err = parseMachinePass(MFPM, Element))
2636 return Err;
2637 }
2638 return Error::success();
2639}
2640
2641Error PassBuilder::parseLoopPassPipeline(LoopPassManager &LPM,
2642 ArrayRef<PipelineElement> Pipeline) {
2643 for (const auto &Element : Pipeline) {
2644 if (auto Err = parseLoopPass(LPM, Element))
2645 return Err;
2646 }
2647 return Error::success();
2648}
2649
2650Error PassBuilder::parseFunctionPassPipeline(
2652 for (const auto &Element : Pipeline) {
2653 if (auto Err = parseFunctionPass(FPM, Element))
2654 return Err;
2655 }
2656 return Error::success();
2657}
2658
2659Error PassBuilder::parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
2660 ArrayRef<PipelineElement> Pipeline) {
2661 for (const auto &Element : Pipeline) {
2662 if (auto Err = parseCGSCCPass(CGPM, Element))
2663 return Err;
2664 }
2665 return Error::success();
2666}
2667
2673 MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });
2674 MAM.registerPass([&] { return CGSCCAnalysisManagerModuleProxy(CGAM); });
2675 CGAM.registerPass([&] { return ModuleAnalysisManagerCGSCCProxy(MAM); });
2676 FAM.registerPass([&] { return CGSCCAnalysisManagerFunctionProxy(CGAM); });
2677 FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); });
2678 FAM.registerPass([&] { return LoopAnalysisManagerFunctionProxy(LAM); });
2679 LAM.registerPass([&] { return FunctionAnalysisManagerLoopProxy(FAM); });
2680 if (MFAM) {
2681 MAM.registerPass(
2682 [&] { return MachineFunctionAnalysisManagerModuleProxy(*MFAM); });
2683 FAM.registerPass(
2684 [&] { return MachineFunctionAnalysisManagerFunctionProxy(*MFAM); });
2685 MFAM->registerPass(
2687 MFAM->registerPass(
2689 }
2690}
2691
2692Error PassBuilder::parseModulePassPipeline(ModulePassManager &MPM,
2693 ArrayRef<PipelineElement> Pipeline) {
2694 for (const auto &Element : Pipeline) {
2695 if (auto Err = parseModulePass(MPM, Element))
2696 return Err;
2697 }
2698 return Error::success();
2699}
2700
2701// Primary pass pipeline description parsing routine for a \c ModulePassManager
2702// FIXME: Should this routine accept a TargetMachine or require the caller to
2703// pre-populate the analysis managers with target-specific stuff?
2705 StringRef PipelineText) {
2706 auto Pipeline = parsePipelineText(PipelineText);
2707 if (!Pipeline || Pipeline->empty())
2709 formatv("invalid pipeline '{}'", PipelineText).str(),
2711
2712 // If the first name isn't at the module layer, wrap the pipeline up
2713 // automatically.
2714 StringRef FirstName = Pipeline->front().Name;
2715
2716 if (!isModulePassName(FirstName, ModulePipelineParsingCallbacks)) {
2717 bool UseMemorySSA;
2718 if (isCGSCCPassName(FirstName, CGSCCPipelineParsingCallbacks)) {
2719 Pipeline = {{"cgscc", std::move(*Pipeline)}};
2720 } else if (isFunctionPassName(FirstName,
2721 FunctionPipelineParsingCallbacks)) {
2722 Pipeline = {{"function", std::move(*Pipeline)}};
2723 } else if (isLoopNestPassName(FirstName, LoopPipelineParsingCallbacks,
2724 UseMemorySSA)) {
2725 Pipeline = {{"function", {{UseMemorySSA ? "loop-mssa" : "loop",
2726 std::move(*Pipeline)}}}};
2727 } else if (isLoopPassName(FirstName, LoopPipelineParsingCallbacks,
2728 UseMemorySSA)) {
2729 Pipeline = {{"function", {{UseMemorySSA ? "loop-mssa" : "loop",
2730 std::move(*Pipeline)}}}};
2731 } else if (isMachineFunctionPassName(
2732 FirstName, MachineFunctionPipelineParsingCallbacks)) {
2733 Pipeline = {{"function", {{"machine-function", std::move(*Pipeline)}}}};
2734 } else {
2735 for (auto &C : TopLevelPipelineParsingCallbacks)
2736 if (C(MPM, *Pipeline))
2737 return Error::success();
2738
2739 // Unknown pass or pipeline name!
2740 auto &InnerPipeline = Pipeline->front().InnerPipeline;
2742 formatv("unknown {} name '{}'",
2743 (InnerPipeline.empty() ? "pass" : "pipeline"), FirstName)
2744 .str(),
2746 }
2747 }
2748
2749 if (auto Err = parseModulePassPipeline(MPM, *Pipeline))
2750 return Err;
2751 return Error::success();
2752}
2753
2754// Primary pass pipeline description parsing routine for a \c CGSCCPassManager
2756 StringRef PipelineText) {
2757 auto Pipeline = parsePipelineText(PipelineText);
2758 if (!Pipeline || Pipeline->empty())
2760 formatv("invalid pipeline '{}'", PipelineText).str(),
2762
2763 StringRef FirstName = Pipeline->front().Name;
2764 if (!isCGSCCPassName(FirstName, CGSCCPipelineParsingCallbacks))
2766 formatv("unknown cgscc pass '{}' in pipeline '{}'", FirstName,
2767 PipelineText)
2768 .str(),
2770
2771 if (auto Err = parseCGSCCPassPipeline(CGPM, *Pipeline))
2772 return Err;
2773 return Error::success();
2774}
2775
2776// Primary pass pipeline description parsing routine for a \c
2777// FunctionPassManager
2779 StringRef PipelineText) {
2780 auto Pipeline = parsePipelineText(PipelineText);
2781 if (!Pipeline || Pipeline->empty())
2783 formatv("invalid pipeline '{}'", PipelineText).str(),
2785
2786 StringRef FirstName = Pipeline->front().Name;
2787 if (!isFunctionPassName(FirstName, FunctionPipelineParsingCallbacks))
2789 formatv("unknown function pass '{}' in pipeline '{}'", FirstName,
2790 PipelineText)
2791 .str(),
2793
2794 if (auto Err = parseFunctionPassPipeline(FPM, *Pipeline))
2795 return Err;
2796 return Error::success();
2797}
2798
2799// Primary pass pipeline description parsing routine for a \c LoopPassManager
2801 StringRef PipelineText) {
2802 auto Pipeline = parsePipelineText(PipelineText);
2803 if (!Pipeline || Pipeline->empty())
2805 formatv("invalid pipeline '{}'", PipelineText).str(),
2807
2808 if (auto Err = parseLoopPassPipeline(CGPM, *Pipeline))
2809 return Err;
2810
2811 return Error::success();
2812}
2813
2815 StringRef PipelineText) {
2816 auto Pipeline = parsePipelineText(PipelineText);
2817 if (!Pipeline || Pipeline->empty())
2819 formatv("invalid machine pass pipeline '{}'", PipelineText).str(),
2821
2822 if (auto Err = parseMachinePassPipeline(MFPM, *Pipeline))
2823 return Err;
2824
2825 return Error::success();
2826}
2827
2829 // If the pipeline just consists of the word 'default' just replace the AA
2830 // manager with our default one.
2831 if (PipelineText == "default") {
2833 return Error::success();
2834 }
2835
2836 while (!PipelineText.empty()) {
2837 StringRef Name;
2838 std::tie(Name, PipelineText) = PipelineText.split(',');
2839 if (!parseAAPassName(AA, Name))
2841 formatv("unknown alias analysis name '{}'", Name).str(),
2843 }
2844
2845 return Error::success();
2846}
2847
2848std::optional<RegAllocFilterFunc>
2850 if (FilterName == "all")
2851 return nullptr;
2852 for (auto &C : RegClassFilterParsingCallbacks)
2853 if (auto F = C(FilterName))
2854 return F;
2855 return std::nullopt;
2856}
2857
2859 raw_ostream &OS) {
2860 for (StringRef PassName : PassNames)
2861 OS << " " << PassName << '\n';
2862}
2863
2864LLVM_ATTRIBUTE_NOINLINE static void
2866 auto I = PassNames.begin();
2867 auto End = PassNames.end();
2868 while (I != End) {
2869 StringRef Name = *I;
2870 ++I;
2871 assert(I != End);
2872 StringRef Params = *I;
2873 ++I;
2874 OS << " " << Name << '<' << Params << ">\n";
2875 }
2876}
2877
2879 // TODO: print pass descriptions when they are available
2880
2881 OS << "Module passes:\n";
2882 static constexpr char ModulePassNames[] = {"\0"
2883#define MODULE_PASS(NAME, CREATE_PASS) NAME "\0"
2884#include "PassRegistry.def"
2885 };
2886 printPassNameList(StringTable(ModulePassNames), OS);
2887
2888 OS << "Module passes with params:\n";
2889 static constexpr char ModulePassNamesWithParams[] = {"\0"
2890#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2891 NAME "\0" PARAMS "\0"
2892#include "PassRegistry.def"
2893 };
2894 printPassNameListWithParams(StringTable(ModulePassNamesWithParams), OS);
2895
2896 OS << "Module analyses:\n";
2897 static constexpr char ModuleAnalysisNames[] = {"\0"
2898#define MODULE_ANALYSIS(NAME, CREATE_PASS) NAME "\0"
2899#include "PassRegistry.def"
2900 };
2901 printPassNameList(StringTable(ModuleAnalysisNames), OS);
2902
2903 OS << "Module alias analyses:\n";
2904 static constexpr char ModuleAliasAnalysisNames[] = {"\0"
2905#define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) NAME "\0"
2906#include "PassRegistry.def"
2907 };
2908 printPassNameList(StringTable(ModuleAliasAnalysisNames), OS);
2909
2910 OS << "CGSCC passes:\n";
2911 static constexpr char CGSCCPassNames[] = {"\0"
2912#define CGSCC_PASS(NAME, CREATE_PASS) NAME "\0"
2913#include "PassRegistry.def"
2914 };
2915 printPassNameList(StringTable(CGSCCPassNames), OS);
2916
2917 OS << "CGSCC passes with params:\n";
2918 static constexpr char CGSCCPassNamesWithParams[] = {"\0"
2919#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2920 NAME "\0" PARAMS "\0"
2921#include "PassRegistry.def"
2922 };
2923 printPassNameListWithParams(StringTable(CGSCCPassNamesWithParams), OS);
2924
2925 OS << "CGSCC analyses:\n";
2926 static constexpr char CGSCCAnalysisNames[] = {"\0"
2927#define CGSCC_ANALYSIS(NAME, CREATE_PASS) NAME "\0"
2928#include "PassRegistry.def"
2929 };
2930 printPassNameList(StringTable(CGSCCAnalysisNames), OS);
2931
2932 OS << "Function passes:\n";
2933 static constexpr char FunctionPassNames[] = {"\0"
2934#define FUNCTION_PASS(NAME, CREATE_PASS) NAME "\0"
2935#include "PassRegistry.def"
2936 };
2937 printPassNameList(StringTable(FunctionPassNames), OS);
2938
2939 OS << "Function passes with params:\n";
2940 static constexpr char FunctionPassNamesWithParams[] = {"\0"
2941#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2942 NAME "\0" PARAMS "\0"
2943#include "PassRegistry.def"
2944 };
2945 printPassNameListWithParams(StringTable(FunctionPassNamesWithParams), OS);
2946
2947 OS << "Function analyses:\n";
2948 static constexpr char FunctionAnalysisNames[] = {"\0"
2949#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) NAME "\0"
2950#include "PassRegistry.def"
2951 };
2952 printPassNameList(StringTable(FunctionAnalysisNames), OS);
2953
2954 OS << "Function alias analyses:\n";
2955 static constexpr char FunctionAliasAnalysisNames[] = {"\0"
2956#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) NAME "\0"
2957#include "PassRegistry.def"
2958 };
2959 printPassNameList(StringTable(FunctionAliasAnalysisNames), OS);
2960
2961 OS << "LoopNest passes:\n";
2962 static constexpr char LoopNestPassNames[] = {"\0"
2963#define LOOPNEST_PASS(NAME, CREATE_PASS) NAME "\0"
2964#include "PassRegistry.def"
2965 };
2966 printPassNameList(StringTable(LoopNestPassNames), OS);
2967
2968 OS << "Loop passes:\n";
2969 static constexpr char LoopPassNames[] = {"\0"
2970#define LOOP_PASS(NAME, CREATE_PASS) NAME "\0"
2971#include "PassRegistry.def"
2972 };
2973 printPassNameList(StringTable(LoopPassNames), OS);
2974
2975 OS << "Loop passes with params:\n";
2976 static constexpr char LoopPassNamesWithParams[] = {"\0"
2977#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2978 NAME "\0" PARAMS "\0"
2979#include "PassRegistry.def"
2980 };
2981 printPassNameListWithParams(StringTable(LoopPassNamesWithParams), OS);
2982
2983 OS << "Loop analyses:\n";
2984 static constexpr char LoopAnalysisNames[] = {"\0"
2985#define LOOP_ANALYSIS(NAME, CREATE_PASS) NAME "\0"
2986#include "PassRegistry.def"
2987 };
2988 printPassNameList(StringTable(LoopAnalysisNames), OS);
2989
2990 OS << "Machine module passes (WIP):\n";
2991 static constexpr char MachineModulePassNames[] = {"\0"
2992#define MACHINE_MODULE_PASS(NAME, CREATE_PASS) NAME "\0"
2993#include "llvm/Passes/MachinePassRegistry.def"
2994 };
2995 printPassNameList(StringTable(MachineModulePassNames), OS);
2996
2997 OS << "Machine function passes (WIP):\n";
2998 static constexpr char MachineFunctionPassNames[] = {"\0"
2999#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) NAME "\0"
3000#include "llvm/Passes/MachinePassRegistry.def"
3001 };
3002 printPassNameList(StringTable(MachineFunctionPassNames), OS);
3003
3004 OS << "Machine function analyses (WIP):\n";
3005 static constexpr char MachineFunctionAnalysisNames[] = {"\0"
3006#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) NAME "\0"
3007#include "llvm/Passes/MachinePassRegistry.def"
3008 };
3009 printPassNameList(StringTable(MachineFunctionAnalysisNames), OS);
3010}
3011
3013 const std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>)>
3014 &C) {
3015 TopLevelPipelineParsingCallbacks.push_back(C);
3016}
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.
This file contains the declaration of the BreakFalseDepsPass class, used to identify and avoid false ...
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
Contains definition of the base CFIFixup pass.
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 contains the declaration of the MachineKCFI class, which is a Machine Pass that implements ...
#define LLVM_ATTRIBUTE_NOINLINE
LLVM_ATTRIBUTE_NOINLINE - On compilers where we have a directive to do so, mark a method "not for inl...
Definition Compiler.h:366
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 the GVNHoist pass.
This file provides the interface for the GVNSink pass.
This file provides the interface for LLVM's Global Value Numbering pass which eliminates fully redund...
This is the interface for a simple mod/ref and alias analysis over globals.
Defines an IR pass for the creation of hardware loops.
#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 file declares the IRTranslator pass.
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 provides the interface for LLVM's Logical Scalar Replacement of Aggregates pass.
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
#define I(x, y, z)
Definition MD5.cpp:57
Machine Check Debug Module
This file contains the declaration of the CheckDebugMachineModulePass class, used by the new pass man...
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
PassBuilder PB(Mod->getContext(), Machine, PassOpts->PTO, std::nullopt, &PIC)
if(PassOpts->AAPipeline)
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 LLVM_ATTRIBUTE_NOINLINE void printPassNameList(StringTable PassNames, raw_ostream &OS)
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 LLVM_ATTRIBUTE_NOINLINE void printPassNameListWithParams(StringTable PassNames, 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...
MachineRegisterInfo & MRI
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 file describes the interface of the MachineFunctionPass responsible for assigning the generic vi...
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 contains the declaration of the ResetMachineFunctionPass class.
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:1560
int64_t getSExtValue() const
Get sign extended value.
Definition APInt.h:1582
bool registerPass(PassBuilderT &&PassBuilder)
Register an analysis pass with the manager.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
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:692
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".
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:76
This analysis create MachineFunction for given Function.
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.
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 Error parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText)
Parse a textual pass pipeline description into a ModulePassManager.
LLVM_ABI PassBuilder(LLVMContext &Context, TargetMachine *TM=nullptr, std::optional< PipelineTuningOptions > PTO=std::nullopt, std::optional< PGOOptions > PGOOpt=std::nullopt, PassInstrumentationCallbacks *PIC=nullptr, IntrusiveRefCntPtr< vfs::FileSystem > FS=vfs::getRealFileSystem())
The pipelines read the library options of Context, which must outlive the PassBuilder.
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 std::optional< PrintPipelinePassesFormat > getPrintPipelinePasses() const
The format -print-pipeline-passes requests, or std::nullopt if it is not given.
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:46
bool SLPVectorization
Tuning option to enable/disable slp loop vectorization, set based on opt level.
Definition PassBuilder.h:67
bool LoopVectorization
Tuning option to enable/disable loop vectorization, set based on opt level.
Definition PassBuilder.h:63
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.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition StringRef.h:736
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
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
Check if the string is empty.
Definition StringRef.h:141
char front() const
Get the first character in the string.
Definition StringRef.h:147
bool consume_front(char Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
Definition StringRef.h:661
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
A table of densely packed, null-terminated strings indexed by offset.
Definition StringTable.h:34
constexpr Iterator begin() const
constexpr Iterator end() const
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:164
std::optional< CodeGenOptLevel > getLevel(int OL)
Get the Level identified by the integer OL.
Definition CodeGen.h:238
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:83
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.
@ O1
Optimize quickly without destroying debuggability.
@ O0
Disable as many optimizations as possible.
@ O3
Optimize for fast execution as much as possible.
@ O2
Optimize for fast execution as much as possible without triggering significant incremental compile ti...
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.
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.
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
support::detail::RepeatAdapter< T > fmt_repeat(T &&Item, size_t Count)
OuterAnalysisManagerProxy< ModuleAnalysisManager, LazyCallGraph::SCC, LazyCallGraph & > ModuleAnalysisManagerCGSCCProxy
A proxy from a ModuleAnalysisManager to an SCC.
InnerAnalysisManagerProxy< MachineFunctionAnalysisManager, Module > MachineFunctionAnalysisManagerModuleProxy
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
Definition InstrProf.h:145
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 >
LLVM_ABI void printFormattedPipelinePasses(raw_ostream &OS, StringRef Pipeline, PrintPipelinePassesFormat Format=PrintPipelinePassesFormat::Text)
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:1933
PassManager< MachineFunction > MachineFunctionPassManager
Convenience typedef for a pass manager over functions.
LLVM_ABI bool applyDebugifyMetadataToMachineFunction(DIBuilder &DIB, Function &F, llvm::function_ref< MachineFunction *(Function &)> GetMF)
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...
@ End
Run the machine verifier once, at the end of the pipeline.
Definition CodeGen.h:267
const PassesOptions & getPassesOptions(const LLVMContext &C)
PrintPipelinePassesFormat
@ 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:878
#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:34
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 & setPrepareForLTO(bool V)
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 for passes that can be skipped.