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