LLVM 24.0.0git
PassBuilder.cpp
Go to the documentation of this file.
1//===- Parsing and selection of pass pipelines ----------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8/// \file
9///
10/// This file provides the implementation of the PassBuilder based on our
11/// static pass registry as well as related functionality. It also provides
12/// helpers to aid in analyzing, debugging, and testing passes and pass
13/// pipelines.
14///
15//===----------------------------------------------------------------------===//
16
18#include "PassesOptions.h"
34#include "llvm/Analysis/DDG.h"
56#include "llvm/Analysis/Lint.h"
129#include "llvm/CodeGen/KCFI.h"
167#include "llvm/CodeGen/PEI.h"
215#include "llvm/IR/DebugInfo.h"
216#include "llvm/IR/Dominators.h"
217#include "llvm/IR/PassManager.h"
219#include "llvm/IR/Verifier.h"
223#include "llvm/Support/CodeGen.h"
224#include "llvm/Support/Debug.h"
225#include "llvm/Support/Error.h"
229#include "llvm/Support/Regex.h"
425#include <optional>
426
427using namespace llvm;
428
429std::optional<PrintPipelinePassesFormat>
431 return Opts.print_pipeline_passes;
432}
433
436 switch (Format) {
438 OS << Pipeline;
439 break;
441 int IndentLevel = 0;
442 for (char C : Pipeline) {
443 switch (C) {
444 case '(':
445 ++IndentLevel;
446 OS << formatv("\n{0}", fmt_repeat(" ", IndentLevel));
447 break;
448 case ')':
449 --IndentLevel;
450 assert(IndentLevel >= 0 && "Invalid pipeline string!");
451 break;
452 case ',':
453 OS << formatv("\n{0}", fmt_repeat(" ", IndentLevel));
454 break;
455 default:
456 OS << C;
457 }
458 }
459 break;
460 }
461 }
462}
463
464AnalysisKey NoOpModuleAnalysis::Key;
465AnalysisKey NoOpCGSCCAnalysis::Key;
466AnalysisKey NoOpFunctionAnalysis::Key;
467AnalysisKey NoOpLoopAnalysis::Key;
468
469namespace {
470
471bool applyMIRDebugify(DIBuilder &DIB, Function &F, ModuleAnalysisManager &AM) {
474 .getManager();
475
477 DIB, F, [&](Function &Func) -> MachineFunction * {
479 FAM.getCachedResult<MachineFunctionAnalysis>(Func);
480 return MFA ? &MFA->getMF() : nullptr;
481 });
482}
483
484// A pass for testing message reporting of -verify-each failures.
485// DO NOT USE THIS EXCEPT FOR TESTING!
486class TriggerVerifierErrorPass
487 : public OptionalPassInfoMixin<TriggerVerifierErrorPass> {
488public:
489 PreservedAnalyses run(Module &M, ModuleAnalysisManager &) {
490 // Intentionally break the Module by creating an alias without setting the
491 // aliasee.
492 auto *PtrTy = PointerType::getUnqual(M.getContext());
493 GlobalAlias::create(PtrTy, PtrTy->getAddressSpace(),
494 GlobalValue::LinkageTypes::InternalLinkage,
495 "__bad_alias", nullptr, &M);
497 }
498
499 PreservedAnalyses run(Function &F, FunctionAnalysisManager &) {
500 // Intentionally break the Function by inserting a terminator
501 // instruction in the middle of a basic block.
502 BasicBlock &BB = F.getEntryBlock();
503 new UnreachableInst(F.getContext(), BB.getTerminator()->getIterator());
505 }
506
507 PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &) {
508 // Intentionally create a virtual register and set NoVRegs property.
509 auto &MRI = MF.getRegInfo();
511 MF.getProperties().setNoVRegs();
512 return PreservedAnalyses::all();
513 }
514
515 static StringRef name() { return "TriggerVerifierErrorPass"; }
516};
517
518// A pass requires all MachineFunctionProperties.
519// DO NOT USE THIS EXCEPT FOR TESTING!
520class RequireAllMachineFunctionPropertiesPass
521 : public OptionalPassInfoMixin<RequireAllMachineFunctionPropertiesPass> {
522public:
523 PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &) {
524 MFPropsModifier _(*this, MF);
526 }
527
528 static MachineFunctionProperties getRequiredProperties() {
529 return MachineFunctionProperties()
530 .setFailedISel()
531 .setFailsVerification()
532 .setIsSSA()
533 .setLegalized()
534 .setNoPHIs()
535 .setNoVRegs()
536 .setRegBankSelected()
537 .setSelected()
538 .setTiedOpsRewritten()
539 .setTracksDebugUserValues()
540 .setTracksLiveness();
541 }
542 static StringRef name() { return "RequireAllMachineFunctionPropertiesPass"; }
543};
544
545} // namespace
546
547static std::optional<OptimizationLevel> parseOptLevel(StringRef S) {
548 if (S == "Os" || S == "Oz")
550 Twine("The optimization level \"") + S +
551 "\" is no longer supported. Use O2 in conjunction with the " +
552 (S == "Os" ? "optsize" : "minsize") + " attribute instead.");
553
555 .Case("O0", OptimizationLevel::O0)
559 .Default(std::nullopt);
560}
561
563 std::optional<OptimizationLevel> OptLevel = parseOptLevel(S);
564 if (OptLevel)
565 return *OptLevel;
567 formatv("invalid optimization level '{}'", S).str(),
569}
570
572 std::optional<PipelineTuningOptions> PTO,
573 std::optional<PGOOptions> PGOOpt,
576 : Context(Context), Opts(Context.getLibraryOptions().get<PassesOptions>()),
577 TM(TM),
578 PTO(PTO ? *PTO : PipelineTuningOptions(&Context.getLibraryOptions())),
579 PGOOpt(PGOOpt), PIC(PIC), FS(std::move(FS)) {
580 if (TM)
581 TM->registerPassBuilderCallbacks(*this);
582 if (PIC) {
583 PIC->registerClassToPassNameCallback([this, PIC]() {
584 // MSVC requires this to be captured if it's used inside decltype.
585 // Other compilers consider it an unused lambda capture.
586 (void)this;
587#define MODULE_PASS(NAME, CREATE_PASS) \
588 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
589#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
590 PIC->addClassToPassName(CLASS, NAME);
591#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
592 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
593#define FUNCTION_PASS(NAME, CREATE_PASS) \
594 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
595#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
596 PIC->addClassToPassName(CLASS, NAME);
597#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
598 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
599#define LOOPNEST_PASS(NAME, CREATE_PASS) \
600 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
601#define LOOP_PASS(NAME, CREATE_PASS) \
602 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
603#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
604 PIC->addClassToPassName(CLASS, NAME);
605#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
606 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
607#define CGSCC_PASS(NAME, CREATE_PASS) \
608 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
609#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
610 PIC->addClassToPassName(CLASS, NAME);
611#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
612 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
613#include "PassRegistry.def"
614
615#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
616 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
617#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
618 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
619#define MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, \
620 PARAMS) \
621 PIC->addClassToPassName(CLASS, NAME);
622#include "llvm/Passes/MachinePassRegistry.def"
623 });
624 }
625
626 // Module-level callbacks without LTO phase
628 [this](StringRef Name, ModulePassManager &PM,
630#define MODULE_CALLBACK(NAME, INVOKE) \
631 if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
632 auto L = PassBuilder::parsePassParameters(parseOptLevelParam, Name, NAME); \
633 if (!L) { \
634 errs() << NAME ": " << toString(L.takeError()) << '\n'; \
635 return false; \
636 } \
637 INVOKE(PM, L.get()); \
638 return true; \
639 }
640#include "PassRegistry.def"
641 return false;
642 });
643
644 // Module-level callbacks with LTO phase (use Phase::None for string API)
646 [this](StringRef Name, ModulePassManager &PM,
648#define MODULE_LTO_CALLBACK(NAME, INVOKE) \
649 if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
650 auto L = PassBuilder::parsePassParameters(parseOptLevelParam, Name, NAME); \
651 if (!L) { \
652 errs() << NAME ": " << toString(L.takeError()) << '\n'; \
653 return false; \
654 } \
655 INVOKE(PM, L.get(), ThinOrFullLTOPhase::None); \
656 return true; \
657 }
658#include "PassRegistry.def"
659 return false;
660 });
661
662 // Function-level callbacks
664 [this](StringRef Name, FunctionPassManager &PM,
666#define FUNCTION_CALLBACK(NAME, INVOKE) \
667 if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
668 auto L = PassBuilder::parsePassParameters(parseOptLevelParam, Name, NAME); \
669 if (!L) { \
670 errs() << NAME ": " << toString(L.takeError()) << '\n'; \
671 return false; \
672 } \
673 INVOKE(PM, L.get()); \
674 return true; \
675 }
676#include "PassRegistry.def"
677 return false;
678 });
679
680 // CGSCC-level callbacks
682 [this](StringRef Name, CGSCCPassManager &PM,
684#define CGSCC_CALLBACK(NAME, INVOKE) \
685 if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
686 auto L = PassBuilder::parsePassParameters(parseOptLevelParam, Name, NAME); \
687 if (!L) { \
688 errs() << NAME ": " << toString(L.takeError()) << '\n'; \
689 return false; \
690 } \
691 INVOKE(PM, L.get()); \
692 return true; \
693 }
694#include "PassRegistry.def"
695 return false;
696 });
697
698 // Loop-level callbacks
700 [this](StringRef Name, LoopPassManager &PM,
702#define LOOP_CALLBACK(NAME, INVOKE) \
703 if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
704 auto L = PassBuilder::parsePassParameters(parseOptLevelParam, Name, NAME); \
705 if (!L) { \
706 errs() << NAME ": " << toString(L.takeError()) << '\n'; \
707 return false; \
708 } \
709 INVOKE(PM, L.get()); \
710 return true; \
711 }
712#include "PassRegistry.def"
713 return false;
714 });
715}
716
718#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
719 MAM.registerPass([&] { return CREATE_PASS; });
720#include "PassRegistry.def"
721
722 for (auto &C : ModuleAnalysisRegistrationCallbacks)
723 C(MAM);
724}
725
727#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
728 CGAM.registerPass([&] { return CREATE_PASS; });
729#include "PassRegistry.def"
730
731 for (auto &C : CGSCCAnalysisRegistrationCallbacks)
732 C(CGAM);
733}
734
736 // We almost always want the default alias analysis pipeline.
737 // If a user wants a different one, they can register their own before calling
738 // registerFunctionAnalyses().
739 FAM.registerPass([&] { return buildDefaultAAPipeline(); });
740
741#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
742 if constexpr (std::is_constructible_v< \
743 std::remove_reference_t<decltype(CREATE_PASS)>, \
744 const TargetMachine &>) { \
745 if (TM) \
746 FAM.registerPass([&] { return CREATE_PASS; }); \
747 } else { \
748 FAM.registerPass([&] { return CREATE_PASS; }); \
749 }
750#include "PassRegistry.def"
751
752 for (auto &C : FunctionAnalysisRegistrationCallbacks)
753 C(FAM);
754}
755
758
759#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
760 MFAM.registerPass([&] { return CREATE_PASS; });
761#include "llvm/Passes/MachinePassRegistry.def"
762
763 for (auto &C : MachineFunctionAnalysisRegistrationCallbacks)
764 C(MFAM);
765}
766
768#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
769 LAM.registerPass([&] { return CREATE_PASS; });
770#include "PassRegistry.def"
771
772 for (auto &C : LoopAnalysisRegistrationCallbacks)
773 C(LAM);
774}
775
776static std::optional<std::pair<bool, bool>>
778 std::pair<bool, bool> Params;
779 if (!Name.consume_front("function"))
780 return std::nullopt;
781 if (Name.empty())
782 return Params;
783 if (!Name.consume_front("<") || !Name.consume_back(">"))
784 return std::nullopt;
785 while (!Name.empty()) {
786 auto [Front, Back] = Name.split(';');
787 Name = Back;
788 if (Front == "eager-inv")
789 Params.first = true;
790 else if (Front == "no-rerun")
791 Params.second = true;
792 else
793 return std::nullopt;
794 }
795 return Params;
796}
797
798static std::optional<int> parseDevirtPassName(StringRef Name) {
799 if (!Name.consume_front("devirt<") || !Name.consume_back(">"))
800 return std::nullopt;
801 int Count;
802 if (Name.getAsInteger(0, Count) || Count < 0)
803 return std::nullopt;
804 return Count;
805}
806
808 StringRef OptionName,
810 bool Result = false;
811 while (!Params.empty()) {
812 StringRef ParamName;
813 std::tie(ParamName, Params) = Params.split(';');
814
815 if (ParamName == OptionName) {
816 Result = true;
817 } else {
819 formatv("invalid {} pass parameter '{}'", PassName, ParamName).str(),
821 }
822 }
823 return Result;
824}
825
826namespace {
827
828/// Parser of parameters for HardwareLoops pass.
829Expected<HardwareLoopOptions> parseHardwareLoopOptions(StringRef Params) {
830 HardwareLoopOptions HardwareLoopOpts;
831
832 while (!Params.empty()) {
833 StringRef ParamName;
834 std::tie(ParamName, Params) = Params.split(';');
835 if (ParamName.consume_front("hardware-loop-decrement=")) {
836 int Count;
837 if (ParamName.getAsInteger(0, Count))
839 formatv("invalid HardwareLoopPass parameter '{}'", ParamName).str(),
841 HardwareLoopOpts.setDecrement(Count);
842 continue;
843 }
844 if (ParamName.consume_front("hardware-loop-counter-bitwidth=")) {
845 int Count;
846 if (ParamName.getAsInteger(0, Count))
848 formatv("invalid HardwareLoopPass parameter '{}'", ParamName).str(),
850 HardwareLoopOpts.setCounterBitwidth(Count);
851 continue;
852 }
853 if (ParamName == "force-hardware-loops") {
854 HardwareLoopOpts.setForce(true);
855 } else if (ParamName == "force-hardware-loop-phi") {
856 HardwareLoopOpts.setForcePhi(true);
857 } else if (ParamName == "force-nested-hardware-loop") {
858 HardwareLoopOpts.setForceNested(true);
859 } else if (ParamName == "force-hardware-loop-guard") {
860 HardwareLoopOpts.setForceGuard(true);
861 } else {
863 formatv("invalid HardwarePass parameter '{}'", ParamName).str(),
865 }
866 }
867 return HardwareLoopOpts;
868}
869
870/// Parser of parameters for Lint pass.
871Expected<bool> parseLintOptions(StringRef Params) {
872 return PassBuilder::parseSinglePassOption(Params, "abort-on-error",
873 "LintPass");
874}
875
876/// Parser of parameters for FunctionPropertiesStatistics pass.
877Expected<bool> parseFunctionPropertiesStatisticsOptions(StringRef Params) {
878 return PassBuilder::parseSinglePassOption(Params, "pre-opt",
879 "FunctionPropertiesStatisticsPass");
880}
881
882/// Parser of parameters for InstCount pass.
883Expected<bool> parseInstCountOptions(StringRef Params) {
884 return PassBuilder::parseSinglePassOption(Params, "pre-opt", "InstCountPass");
885}
886
887Expected<bool> parseInferAddressSpacesPassOptions(StringRef Params) {
889 Params, "assume-default-is-flat-addrspace", "InferAddressSpacesPass");
890}
891
892/// Parser of parameters for LoopUnroll pass.
893Expected<LoopUnrollOptions> parseLoopUnrollOptions(StringRef Params) {
894 LoopUnrollOptions UnrollOpts;
895 while (!Params.empty()) {
896 StringRef ParamName;
897 std::tie(ParamName, Params) = Params.split(';');
898 std::optional<OptimizationLevel> OptLevel = parseOptLevel(ParamName);
899 if (OptLevel) {
900 UnrollOpts.setOptLevel(static_cast<int>(*OptLevel));
901 continue;
902 }
903 if (ParamName.consume_front("full-unroll-max=")) {
904 int Count;
905 if (ParamName.getAsInteger(0, Count))
907 formatv("invalid LoopUnrollPass parameter '{}'", ParamName).str(),
909 UnrollOpts.setFullUnrollMaxCount(Count);
910 continue;
911 }
912
913 bool Enable = !ParamName.consume_front("no-");
914 if (ParamName == "partial") {
915 UnrollOpts.setPartial(Enable);
916 } else if (ParamName == "peeling") {
917 UnrollOpts.setPeeling(Enable);
918 } else if (ParamName == "profile-peeling") {
919 UnrollOpts.setProfileBasedPeeling(Enable);
920 } else if (ParamName == "runtime") {
921 UnrollOpts.setRuntime(Enable);
922 } else if (ParamName == "upperbound") {
923 UnrollOpts.setUpperBound(Enable);
924 } else if (ParamName == "prepare-for-lto") {
925 UnrollOpts.setPrepareForLTO(Enable);
926 } else {
928 formatv("invalid LoopUnrollPass parameter '{}'", ParamName).str(),
930 }
931 }
932 return UnrollOpts;
933}
934
935Expected<bool> parseGlobalDCEPassOptions(StringRef Params) {
937 Params, "vfe-linkage-unit-visibility", "GlobalDCE");
938}
939
940Expected<bool> parseCGProfilePassOptions(StringRef Params) {
941 return PassBuilder::parseSinglePassOption(Params, "in-lto-post-link",
942 "CGProfile");
943}
944
945Expected<bool> parseInlinerPassOptions(StringRef Params) {
946 return PassBuilder::parseSinglePassOption(Params, "only-mandatory",
947 "InlinerPass");
948}
949
950Expected<bool> parseCoroSplitPassOptions(StringRef Params) {
951 return PassBuilder::parseSinglePassOption(Params, "reuse-storage",
952 "CoroSplitPass");
953}
954
955Expected<bool> parsePostOrderFunctionAttrsPassOptions(StringRef Params) {
957 Params, "skip-non-recursive-function-attrs", "PostOrderFunctionAttrs");
958}
959
960Expected<bool> parseEarlyCSEPassOptions(StringRef Params) {
961 return PassBuilder::parseSinglePassOption(Params, "memssa", "EarlyCSE");
962}
963
964Expected<bool> parseEntryExitInstrumenterPassOptions(StringRef Params) {
965 return PassBuilder::parseSinglePassOption(Params, "post-inline",
966 "EntryExitInstrumenter");
967}
968
969Expected<bool> parseDropUnnecessaryAssumesPassOptions(StringRef Params) {
970 return PassBuilder::parseSinglePassOption(Params, "drop-deref",
971 "DropUnnecessaryAssumes");
972}
973
974Expected<bool> parseLowerMatrixIntrinsicsPassOptions(StringRef Params) {
975 return PassBuilder::parseSinglePassOption(Params, "minimal",
976 "LowerMatrixIntrinsics");
977}
978
979Expected<IRNormalizerOptions> parseIRNormalizerPassOptions(StringRef Params) {
981 while (!Params.empty()) {
982 StringRef ParamName;
983 std::tie(ParamName, Params) = Params.split(';');
984
985 bool Enable = !ParamName.consume_front("no-");
986 if (ParamName == "preserve-order")
987 Result.PreserveOrder = Enable;
988 else if (ParamName == "rename-all")
989 Result.RenameAll = Enable;
990 else if (ParamName == "fold-all") // FIXME: Name mismatch
991 Result.FoldPreOutputs = Enable;
992 else if (ParamName == "reorder-operands")
993 Result.ReorderOperands = Enable;
994 else {
996 formatv("invalid normalize pass parameter '{}'", ParamName).str(),
998 }
999 }
1000
1001 return Result;
1002}
1003
1004Expected<AddressSanitizerOptions> parseASanPassOptions(StringRef Params) {
1006 while (!Params.empty()) {
1007 StringRef ParamName;
1008 std::tie(ParamName, Params) = Params.split(';');
1009
1010 if (ParamName == "kernel") {
1011 Result.CompileKernel = true;
1012 } else if (ParamName == "use-after-scope") {
1013 Result.UseAfterScope = true;
1014 } else {
1016 formatv("invalid AddressSanitizer pass parameter '{}'", ParamName)
1017 .str(),
1019 }
1020 }
1021 return Result;
1022}
1023
1024Expected<HWAddressSanitizerOptions> parseHWASanPassOptions(StringRef Params) {
1026 while (!Params.empty()) {
1027 StringRef ParamName;
1028 std::tie(ParamName, Params) = Params.split(';');
1029
1030 if (ParamName == "recover") {
1031 Result.Recover = true;
1032 } else if (ParamName == "kernel") {
1033 Result.CompileKernel = true;
1034 } else {
1036 formatv("invalid HWAddressSanitizer pass parameter '{}'", ParamName)
1037 .str(),
1039 }
1040 }
1041 return Result;
1042}
1043
1045parseDropTypeTestsPassOptions(StringRef Params) {
1047 while (!Params.empty()) {
1048 StringRef ParamName;
1049 std::tie(ParamName, Params) = Params.split(';');
1050
1051 if (ParamName == "all") {
1053 } else if (ParamName == "assume") {
1055 } else {
1057 formatv("invalid DropTypeTestsPass parameter '{}'", ParamName).str(),
1059 }
1060 }
1061 return Result;
1062}
1063
1064Expected<EmbedBitcodeOptions> parseEmbedBitcodePassOptions(StringRef Params) {
1066 while (!Params.empty()) {
1067 StringRef ParamName;
1068 std::tie(ParamName, Params) = Params.split(';');
1069
1070 if (ParamName == "thinlto") {
1071 Result.IsThinLTO = true;
1072 } else if (ParamName == "emit-summary") {
1073 Result.EmitLTOSummary = true;
1074 } else {
1076 formatv("invalid EmbedBitcode pass parameter '{}'", ParamName).str(),
1078 }
1079 }
1080 return Result;
1081}
1082
1084parseLowerAllowCheckPassOptions(StringRef Params) {
1086 while (!Params.empty()) {
1087 StringRef ParamName;
1088 std::tie(ParamName, Params) = Params.split(';');
1089
1090 // Format is <cutoffs[1,2,3]=70000;cutoffs[5,6,8]=90000>
1091 //
1092 // Parsing allows duplicate indices (last one takes precedence).
1093 // It would technically be in spec to specify
1094 // cutoffs[0]=70000,cutoffs[1]=90000,cutoffs[0]=80000,...
1095 if (ParamName.starts_with("cutoffs[")) {
1096 StringRef IndicesStr;
1097 StringRef CutoffStr;
1098
1099 std::tie(IndicesStr, CutoffStr) = ParamName.split("]=");
1100 // cutoffs[1,2,3
1101 // 70000
1102
1103 int cutoff;
1104 if (CutoffStr.getAsInteger(0, cutoff))
1106 formatv("invalid LowerAllowCheck pass cutoffs parameter '{}' ({})",
1107 CutoffStr, Params)
1108 .str(),
1110
1111 if (!IndicesStr.consume_front("cutoffs[") || IndicesStr == "")
1113 formatv("invalid LowerAllowCheck pass index parameter '{}' ({})",
1114 IndicesStr, CutoffStr)
1115 .str(),
1117
1118 while (IndicesStr != "") {
1119 StringRef firstIndexStr;
1120 std::tie(firstIndexStr, IndicesStr) = IndicesStr.split('|');
1121
1122 unsigned int index;
1123 if (firstIndexStr.getAsInteger(0, index))
1125 formatv(
1126 "invalid LowerAllowCheck pass index parameter '{}' ({}) {}",
1127 firstIndexStr, IndicesStr)
1128 .str(),
1130
1131 // In the common case (sequentially increasing indices), we will issue
1132 // O(n) resize requests. We assume the underlying data structure has
1133 // O(1) runtime for each added element.
1134 if (index >= Result.cutoffs.size())
1135 Result.cutoffs.resize(index + 1, 0);
1136
1137 Result.cutoffs[index] = cutoff;
1138 }
1139 } else if (ParamName.starts_with("runtime_check")) {
1140 StringRef ValueString;
1141 std::tie(std::ignore, ValueString) = ParamName.split("=");
1142 int runtime_check;
1143 if (ValueString.getAsInteger(0, runtime_check)) {
1145 formatv("invalid LowerAllowCheck pass runtime_check parameter '{}' "
1146 "({})",
1147 ValueString, Params)
1148 .str(),
1150 }
1151 Result.runtime_check = runtime_check;
1152 } else {
1154 formatv("invalid LowerAllowCheck pass parameter '{}'", ParamName)
1155 .str(),
1157 }
1158 }
1159
1160 return Result;
1161}
1162
1163Expected<MemorySanitizerOptions> parseMSanPassOptions(StringRef Params) {
1165 while (!Params.empty()) {
1166 StringRef ParamName;
1167 std::tie(ParamName, Params) = Params.split(';');
1168
1169 if (ParamName == "recover") {
1170 Result.Recover = true;
1171 } else if (ParamName == "kernel") {
1172 Result.Kernel = true;
1173 } else if (ParamName.consume_front("track-origins=")) {
1174 if (ParamName.getAsInteger(0, Result.TrackOrigins))
1176 formatv("invalid argument to MemorySanitizer pass track-origins "
1177 "parameter: '{}'",
1178 ParamName)
1179 .str(),
1181 } else if (ParamName == "eager-checks") {
1182 Result.EagerChecks = true;
1183 } else {
1185 formatv("invalid MemorySanitizer pass parameter '{}'", ParamName)
1186 .str(),
1188 }
1189 }
1190 return Result;
1191}
1192
1193Expected<AllocTokenOptions> parseAllocTokenPassOptions(StringRef Params) {
1195 while (!Params.empty()) {
1196 StringRef ParamName;
1197 std::tie(ParamName, Params) = Params.split(';');
1198
1199 if (ParamName.consume_front("mode=")) {
1200 if (auto Mode = getAllocTokenModeFromString(ParamName))
1201 Result.Mode = *Mode;
1202 else
1204 formatv("invalid argument to AllocToken pass mode "
1205 "parameter: '{}'",
1206 ParamName)
1207 .str(),
1209 } else {
1211 formatv("invalid AllocToken pass parameter '{}'", ParamName).str(),
1213 }
1214 }
1215 return Result;
1216}
1217
1218/// Parser of parameters for SimplifyCFG pass.
1219Expected<SimplifyCFGOptions> parseSimplifyCFGOptions(StringRef Params) {
1221 while (!Params.empty()) {
1222 StringRef ParamName;
1223 std::tie(ParamName, Params) = Params.split(';');
1224
1225 bool Enable = !ParamName.consume_front("no-");
1226 if (ParamName == "speculate-blocks") {
1227 Result.speculateBlocks(Enable);
1228 } else if (ParamName == "simplify-cond-branch") {
1229 Result.setSimplifyCondBranch(Enable);
1230 } else if (ParamName == "forward-switch-cond") {
1231 Result.forwardSwitchCondToPhi(Enable);
1232 } else if (ParamName == "switch-range-to-icmp") {
1233 Result.convertSwitchRangeToICmp(Enable);
1234 } else if (ParamName == "switch-to-arithmetic") {
1235 Result.convertSwitchToArithmetic(Enable);
1236 } else if (ParamName == "switch-to-lookup") {
1237 Result.convertSwitchToLookupTable(Enable);
1238 } else if (ParamName == "keep-loops") {
1239 Result.needCanonicalLoops(Enable);
1240 } else if (ParamName == "hoist-common-insts") {
1241 Result.hoistCommonInsts(Enable);
1242 } else if (ParamName == "hoist-loads-stores-with-cond-faulting") {
1243 Result.hoistLoadsStoresWithCondFaulting(Enable);
1244 } else if (ParamName == "sink-common-insts") {
1245 Result.sinkCommonInsts(Enable);
1246 } else if (ParamName == "speculate-unpredictables") {
1247 Result.speculateUnpredictables(Enable);
1248 } else if (Enable && ParamName.consume_front("bonus-inst-threshold=")) {
1249 APInt BonusInstThreshold;
1250 if (ParamName.getAsInteger(0, BonusInstThreshold))
1252 formatv("invalid argument to SimplifyCFG pass bonus-threshold "
1253 "parameter: '{}'",
1254 ParamName)
1255 .str(),
1257 Result.bonusInstThreshold(BonusInstThreshold.getSExtValue());
1258 } else {
1260 formatv("invalid SimplifyCFG pass parameter '{}'", ParamName).str(),
1262 }
1263 }
1264 return Result;
1265}
1266
1267Expected<InstCombineOptions> parseInstCombineOptions(StringRef Params) {
1269 // When specifying "instcombine" in -passes enable fix-point verification by
1270 // default, as this is what most tests should use.
1271 Result.setVerifyFixpoint(true);
1272 while (!Params.empty()) {
1273 StringRef ParamName;
1274 std::tie(ParamName, Params) = Params.split(';');
1275
1276 bool Enable = !ParamName.consume_front("no-");
1277 if (ParamName == "verify-fixpoint") {
1278 Result.setVerifyFixpoint(Enable);
1279 } else if (Enable && ParamName.consume_front("max-iterations=")) {
1280 APInt MaxIterations;
1281 if (ParamName.getAsInteger(0, MaxIterations))
1283 formatv("invalid argument to InstCombine pass max-iterations "
1284 "parameter: '{}'",
1285 ParamName)
1286 .str(),
1288 Result.setMaxIterations((unsigned)MaxIterations.getZExtValue());
1289 } else {
1291 formatv("invalid InstCombine pass parameter '{}'", ParamName).str(),
1293 }
1294 }
1295 return Result;
1296}
1297
1298/// Parser of parameters for LoopVectorize pass.
1299Expected<LoopVectorizeOptions> parseLoopVectorizeOptions(StringRef Params) {
1301 while (!Params.empty()) {
1302 StringRef ParamName;
1303 std::tie(ParamName, Params) = Params.split(';');
1304
1305 bool Enable = !ParamName.consume_front("no-");
1306 if (ParamName == "interleave-forced-only") {
1308 } else if (ParamName == "vectorize-forced-only") {
1310 } else {
1312 formatv("invalid LoopVectorize parameter '{}'", ParamName).str(),
1314 }
1315 }
1316 return Opts;
1317}
1318
1319Expected<std::pair<bool, bool>> parseLoopUnswitchOptions(StringRef Params) {
1320 std::pair<bool, bool> Result = {false, true};
1321 while (!Params.empty()) {
1322 StringRef ParamName;
1323 std::tie(ParamName, Params) = Params.split(';');
1324
1325 bool Enable = !ParamName.consume_front("no-");
1326 if (ParamName == "nontrivial") {
1327 Result.first = Enable;
1328 } else if (ParamName == "trivial") {
1329 Result.second = Enable;
1330 } else {
1332 formatv("invalid LoopUnswitch pass parameter '{}'", ParamName).str(),
1334 }
1335 }
1336 return Result;
1337}
1338
1339Expected<LICMOptions> parseLICMOptions(StringRef Params) {
1341 while (!Params.empty()) {
1342 StringRef ParamName;
1343 std::tie(ParamName, Params) = Params.split(';');
1344
1345 bool Enable = !ParamName.consume_front("no-");
1346 if (ParamName == "allowspeculation") {
1347 Result.AllowSpeculation = Enable;
1348 } else {
1350 formatv("invalid LICM pass parameter '{}'", ParamName).str(),
1352 }
1353 }
1354 return Result;
1355}
1356
1357struct LoopRotateOptions {
1358 bool EnableHeaderDuplication = true;
1359 bool PrepareForLTO = false;
1360 bool CheckExitCount = false;
1361};
1362
1363Expected<LoopRotateOptions> parseLoopRotateOptions(StringRef Params) {
1364 LoopRotateOptions Result;
1365 while (!Params.empty()) {
1366 StringRef ParamName;
1367 std::tie(ParamName, Params) = Params.split(';');
1368
1369 bool Enable = !ParamName.consume_front("no-");
1370 if (ParamName == "header-duplication") {
1371 Result.EnableHeaderDuplication = Enable;
1372 } else if (ParamName == "prepare-for-lto") {
1373 Result.PrepareForLTO = Enable;
1374 } else if (ParamName == "check-exit-count") {
1375 Result.CheckExitCount = Enable;
1376 } else {
1378 formatv("invalid LoopRotate pass parameter '{}'", ParamName).str(),
1380 }
1381 }
1382 return Result;
1383}
1384
1385Expected<bool> parseMergedLoadStoreMotionOptions(StringRef Params) {
1386 bool Result = false;
1387 while (!Params.empty()) {
1388 StringRef ParamName;
1389 std::tie(ParamName, Params) = Params.split(';');
1390
1391 bool Enable = !ParamName.consume_front("no-");
1392 if (ParamName == "split-footer-bb") {
1393 Result = Enable;
1394 } else {
1396 formatv("invalid MergedLoadStoreMotion pass parameter '{}'",
1397 ParamName)
1398 .str(),
1400 }
1401 }
1402 return Result;
1403}
1404
1405Expected<GVNOptions> parseGVNOptions(StringRef Params) {
1407 while (!Params.empty()) {
1408 StringRef ParamName;
1409 std::tie(ParamName, Params) = Params.split(';');
1410
1411 bool Enable = !ParamName.consume_front("no-");
1412 if (ParamName == "scalar-pre") {
1413 Result.setScalarPRE(Enable);
1414 } else if (ParamName == "load-pre") {
1415 Result.setLoadPRE(Enable);
1416 } else if (ParamName == "split-backedge-load-pre") {
1417 Result.setLoadPRESplitBackedge(Enable);
1418 } else if (ParamName == "memdep") {
1419 // MemDep and MemorySSA are mutually exclusive.
1420 Result.setMemDep(Enable);
1421 Result.setMemorySSA(!Enable);
1422 } else if (ParamName == "memoryssa") {
1423 // MemDep and MemorySSA are mutually exclusive.
1424 Result.setMemorySSA(Enable);
1425 Result.setMemDep(!Enable);
1426 } else {
1428 formatv("invalid GVN pass parameter '{}'", ParamName).str(),
1430 }
1431 }
1432 return Result;
1433}
1434
1435Expected<IPSCCPOptions> parseIPSCCPOptions(StringRef Params) {
1437 while (!Params.empty()) {
1438 StringRef ParamName;
1439 std::tie(ParamName, Params) = Params.split(';');
1440
1441 bool Enable = !ParamName.consume_front("no-");
1442 if (ParamName == "func-spec")
1443 Result.setFuncSpec(Enable);
1444 else
1446 formatv("invalid IPSCCP pass parameter '{}'", ParamName).str(),
1448 }
1449 return Result;
1450}
1451
1452Expected<ScalarizerPassOptions> parseScalarizerOptions(StringRef Params) {
1454 while (!Params.empty()) {
1455 StringRef ParamName;
1456 std::tie(ParamName, Params) = Params.split(';');
1457
1458 if (ParamName.consume_front("min-bits=")) {
1459 if (ParamName.getAsInteger(0, Result.ScalarizeMinBits)) {
1461 formatv("invalid argument to Scalarizer pass min-bits "
1462 "parameter: '{}'",
1463 ParamName)
1464 .str(),
1466 }
1467
1468 continue;
1469 }
1470
1471 bool Enable = !ParamName.consume_front("no-");
1472 if (ParamName == "load-store")
1473 Result.ScalarizeLoadStore = Enable;
1474 else if (ParamName == "variable-insert-extract")
1475 Result.ScalarizeVariableInsertExtract = Enable;
1476 else {
1478 formatv("invalid Scalarizer pass parameter '{}'", ParamName).str(),
1480 }
1481 }
1482
1483 return Result;
1484}
1485
1486Expected<SROAOptions> parseSROAOptions(StringRef Params) {
1488 bool SawCFGOption = false;
1489 while (!Params.empty()) {
1490 StringRef ParamName;
1491 std::tie(ParamName, Params) = Params.split(';');
1492
1493 if (ParamName == "modify-cfg") {
1494 if (SawCFGOption)
1495 return make_error<StringError>("multiple SROA CFG options specified",
1498 SawCFGOption = true;
1499 } else if (ParamName == "preserve-cfg") {
1500 if (SawCFGOption)
1501 return make_error<StringError>("multiple SROA CFG options specified",
1504 SawCFGOption = true;
1505 } else if (ParamName == "aggregate-to-vector") {
1506 Result.AggregateToVector = true;
1507 } else {
1509 formatv("invalid SROA pass parameter '{}' (expected preserve-cfg, "
1510 "modify-cfg, or aggregate-to-vector)",
1511 ParamName)
1512 .str(),
1514 }
1515 }
1516 return Result;
1517}
1518
1520parseStackLifetimeOptions(StringRef Params) {
1522 while (!Params.empty()) {
1523 StringRef ParamName;
1524 std::tie(ParamName, Params) = Params.split(';');
1525
1526 if (ParamName == "may") {
1528 } else if (ParamName == "must") {
1530 } else {
1532 formatv("invalid StackLifetime parameter '{}'", ParamName).str(),
1534 }
1535 }
1536 return Result;
1537}
1538
1539Expected<bool> parseDependenceAnalysisPrinterOptions(StringRef Params) {
1540 return PassBuilder::parseSinglePassOption(Params, "normalized-results",
1541 "DependenceAnalysisPrinter");
1542}
1543
1544Expected<bool> parseSeparateConstOffsetFromGEPPassOptions(StringRef Params) {
1545 return PassBuilder::parseSinglePassOption(Params, "lower-gep",
1546 "SeparateConstOffsetFromGEP");
1547}
1548
1549Expected<bool> parseStructurizeCFGPassOptions(StringRef Params) {
1550 return PassBuilder::parseSinglePassOption(Params, "skip-uniform-regions",
1551 "StructurizeCFG");
1552}
1553
1555parseFunctionSimplificationPipelineOptions(StringRef Params) {
1556 std::optional<OptimizationLevel> L = parseOptLevel(Params);
1557 if (!L || *L == OptimizationLevel::O0) {
1559 formatv("invalid function-simplification parameter '{}'", Params).str(),
1561 };
1562 return *L;
1563}
1564
1565Expected<bool> parseMemorySSAPrinterPassOptions(StringRef Params) {
1566 return PassBuilder::parseSinglePassOption(Params, "no-ensure-optimized-uses",
1567 "MemorySSAPrinterPass");
1568}
1569
1570Expected<bool> parseSpeculativeExecutionPassOptions(StringRef Params) {
1571 return PassBuilder::parseSinglePassOption(Params, "only-if-divergent-target",
1572 "SpeculativeExecutionPass");
1573}
1574
1575Expected<std::string> parseMemProfUsePassOptions(StringRef Params) {
1576 std::string Result;
1577 while (!Params.empty()) {
1578 StringRef ParamName;
1579 std::tie(ParamName, Params) = Params.split(';');
1580
1581 if (ParamName.consume_front("profile-filename=")) {
1582 Result = ParamName.str();
1583 } else {
1585 formatv("invalid MemProfUse pass parameter '{}'", ParamName).str(),
1587 }
1588 }
1589 return Result;
1590}
1591
1593parseStructuralHashPrinterPassOptions(StringRef Params) {
1594 if (Params.empty())
1596 if (Params == "detailed")
1598 if (Params == "call-target-ignored")
1601 formatv("invalid structural hash printer parameter '{}'", Params).str(),
1603}
1604
1605Expected<GlobalMergeOptions> parseGlobalMergeOptions(StringRef Params) {
1607 while (!Params.empty()) {
1608 StringRef ParamName;
1609 std::tie(ParamName, Params) = Params.split(';');
1610
1611 bool Enable = !ParamName.consume_front("no-");
1612 if (ParamName == "group-by-use")
1613 Result.GroupByUse = Enable;
1614 else if (ParamName == "ignore-single-use")
1615 Result.IgnoreSingleUse = Enable;
1616 else if (ParamName == "merge-const")
1617 Result.MergeConstantGlobals = Enable;
1618 else if (ParamName == "merge-const-aggressive")
1619 Result.MergeConstAggressive = Enable;
1620 else if (ParamName == "merge-external")
1621 Result.MergeExternal = Enable;
1622 else if (ParamName.consume_front("max-offset=")) {
1623 if (ParamName.getAsInteger(0, Result.MaxOffset))
1625 formatv("invalid GlobalMergePass parameter '{}'", ParamName).str(),
1627 } else {
1629 formatv("invalid global-merge pass parameter '{}'", Params).str(),
1631 }
1632 }
1633 return Result;
1634}
1635
1636Expected<SmallVector<std::string, 0>> parseInternalizeGVs(StringRef Params) {
1637 SmallVector<std::string, 1> PreservedGVs;
1638 while (!Params.empty()) {
1639 StringRef ParamName;
1640 std::tie(ParamName, Params) = Params.split(';');
1641
1642 if (ParamName.consume_front("preserve-gv=")) {
1643 PreservedGVs.push_back(ParamName.str());
1644 } else {
1646 formatv("invalid Internalize pass parameter '{}'", ParamName).str(),
1648 }
1649 }
1650
1651 return Expected<SmallVector<std::string, 0>>(std::move(PreservedGVs));
1652}
1653
1655parseRegAllocFastPassOptions(PassBuilder &PB, StringRef Params) {
1657 while (!Params.empty()) {
1658 StringRef ParamName;
1659 std::tie(ParamName, Params) = Params.split(';');
1660
1661 if (ParamName.consume_front("filter=")) {
1662 std::optional<RegAllocFilterFunc> Filter =
1663 PB.parseRegAllocFilter(ParamName);
1664 if (!Filter) {
1666 formatv("invalid regallocfast register filter '{}'", ParamName)
1667 .str(),
1669 }
1670 Opts.Filter = *Filter;
1671 Opts.FilterName = ParamName;
1672 continue;
1673 }
1674
1675 if (ParamName == "no-clear-vregs") {
1676 Opts.ClearVRegs = false;
1677 continue;
1678 }
1679
1681 formatv("invalid regallocfast pass parameter '{}'", ParamName).str(),
1683 }
1684 return Opts;
1685}
1686
1688parseBoundsCheckingOptions(StringRef Params) {
1690 while (!Params.empty()) {
1691 StringRef ParamName;
1692 std::tie(ParamName, Params) = Params.split(';');
1693 if (ParamName == "trap") {
1694 Options.Rt = std::nullopt;
1695 } else if (ParamName == "rt") {
1696 Options.Rt = {
1697 /*MinRuntime=*/false,
1698 /*MayReturn=*/true,
1699 /*HandlerPreserveAllRegs=*/false,
1700 };
1701 } else if (ParamName == "rt-abort") {
1702 Options.Rt = {
1703 /*MinRuntime=*/false,
1704 /*MayReturn=*/false,
1705 /*HandlerPreserveAllRegs=*/false,
1706 };
1707 } else if (ParamName == "min-rt") {
1708 Options.Rt = {
1709 /*MinRuntime=*/true,
1710 /*MayReturn=*/true,
1711 /*HandlerPreserveAllRegs=*/false,
1712 };
1713 } else if (ParamName == "min-rt-abort") {
1714 Options.Rt = {
1715 /*MinRuntime=*/true,
1716 /*MayReturn=*/false,
1717 /*HandlerPreserveAllRegs=*/false,
1718 };
1719 } else if (ParamName == "merge") {
1720 Options.Merge = true;
1721 } else if (ParamName == "handler-preserve-all-regs") {
1722 if (Options.Rt)
1723 Options.Rt->HandlerPreserveAllRegs = true;
1724 } else {
1725 StringRef ParamEQ;
1726 StringRef Val;
1727 std::tie(ParamEQ, Val) = ParamName.split('=');
1728 int8_t Id;
1729 if (ParamEQ == "guard" && !Val.getAsInteger(0, Id)) {
1730 Options.GuardKind = Id;
1731 } else {
1733 formatv("invalid BoundsChecking pass parameter '{}'", ParamName)
1734 .str(),
1736 }
1737 }
1738 }
1739 return Options;
1740}
1741
1742Expected<CodeGenOptLevel> parseExpandIRInstsOptions(StringRef Param) {
1743 if (Param.empty())
1744 return CodeGenOptLevel::None;
1745
1746 // Parse a CodeGenOptLevel, e.g. "O1", "O2", "O3".
1747 auto [Prefix, Digit] = Param.split('O');
1748
1749 uint8_t N;
1750 if (!Prefix.empty() || Digit.getAsInteger(10, N))
1751 return createStringError("invalid expand-ir-insts pass parameter '%s'",
1752 Param.str().c_str());
1753
1754 std::optional<CodeGenOptLevel> Level = CodeGenOpt::getLevel(N);
1755 if (!Level.has_value())
1756 return createStringError(
1757 "invalid optimization level for expand-ir-insts pass: %s",
1758 Digit.str().c_str());
1759
1760 return *Level;
1761}
1762
1764parseRegAllocGreedyFilterFunc(PassBuilder &PB, StringRef Params) {
1765 if (Params.empty() || Params == "all")
1766 return RAGreedyPass::Options();
1767
1768 std::optional<RegAllocFilterFunc> Filter = PB.parseRegAllocFilter(Params);
1769 if (Filter)
1770 return RAGreedyPass::Options{*Filter, Params};
1771
1773 formatv("invalid regallocgreedy register filter '{}'", Params).str(),
1775}
1776
1777Expected<bool> parseMachineSinkingPassOptions(StringRef Params) {
1778 return PassBuilder::parseSinglePassOption(Params, "enable-sink-fold",
1779 "MachineSinkingPass");
1780}
1781
1782Expected<bool> parseMachineBlockPlacementPassOptions(StringRef Params) {
1783 bool AllowTailMerge = true;
1784 if (!Params.empty()) {
1785 AllowTailMerge = !Params.consume_front("no-");
1786 if (Params != "tail-merge")
1788 formatv("invalid MachineBlockPlacementPass parameter '{}'", Params)
1789 .str(),
1791 }
1792 return AllowTailMerge;
1793}
1794
1795Expected<bool> parseVirtRegRewriterPassOptions(StringRef Params) {
1796 bool ClearVirtRegs = true;
1797 if (!Params.empty()) {
1798 ClearVirtRegs = !Params.consume_front("no-");
1799 if (Params != "clear-vregs")
1801 formatv("invalid VirtRegRewriter pass parameter '{}'", Params).str(),
1803 }
1804 return ClearVirtRegs;
1805}
1806
1807struct FatLTOOptions {
1808 OptimizationLevel OptLevel;
1809 bool ThinLTO = false;
1810 bool EmitSummary = false;
1811};
1812
1813Expected<FatLTOOptions> parseFatLTOOptions(StringRef Params) {
1814 FatLTOOptions Result;
1815 bool HaveOptLevel = false;
1816 while (!Params.empty()) {
1817 StringRef ParamName;
1818 std::tie(ParamName, Params) = Params.split(';');
1819
1820 if (ParamName == "thinlto") {
1821 Result.ThinLTO = true;
1822 } else if (ParamName == "emit-summary") {
1823 Result.EmitSummary = true;
1824 } else if (std::optional<OptimizationLevel> OptLevel =
1825 parseOptLevel(ParamName)) {
1826 Result.OptLevel = *OptLevel;
1827 HaveOptLevel = true;
1828 } else {
1830 formatv("invalid fatlto-pre-link pass parameter '{}'", ParamName)
1831 .str(),
1833 }
1834 }
1835 if (!HaveOptLevel)
1837 "missing optimization level for fatlto-pre-link pipeline",
1839 return Result;
1840}
1841
1842} // namespace
1843
1844/// Tests whether registered callbacks will accept a given pass name.
1845///
1846/// When parsing a pipeline text, the type of the outermost pipeline may be
1847/// omitted, in which case the type is automatically determined from the first
1848/// pass name in the text. This may be a name that is handled through one of the
1849/// callbacks. We check this through the oridinary parsing callbacks by setting
1850/// up a dummy PassManager in order to not force the client to also handle this
1851/// type of query.
1852template <typename PassManagerT, typename CallbacksT>
1853static bool callbacksAcceptPassName(StringRef Name, CallbacksT &Callbacks) {
1854 if (!Callbacks.empty()) {
1855 PassManagerT DummyPM;
1856 for (auto &CB : Callbacks)
1857 if (CB(Name, DummyPM, {}))
1858 return true;
1859 }
1860 return false;
1861}
1862
1863template <typename CallbacksT>
1864static bool isModulePassName(StringRef Name, CallbacksT &Callbacks) {
1865 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1866
1867 // Explicitly handle pass manager names.
1868 if (Name == "module")
1869 return true;
1870 if (Name == "cgscc")
1871 return true;
1872 if (NameNoBracket == "function")
1873 return true;
1874 if (Name == "coro-cond")
1875 return true;
1876
1877#define MODULE_PASS(NAME, CREATE_PASS) \
1878 if (Name == NAME) \
1879 return true;
1880#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1881 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1882 return true;
1883#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
1884 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1885 return true;
1886#include "PassRegistry.def"
1887
1888 return callbacksAcceptPassName<ModulePassManager>(Name, Callbacks);
1889}
1890
1891template <typename CallbacksT>
1892static bool isCGSCCPassName(StringRef Name, CallbacksT &Callbacks) {
1893 // Explicitly handle pass manager names.
1894 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1895 if (Name == "cgscc")
1896 return true;
1897 if (NameNoBracket == "function")
1898 return true;
1899
1900 // Explicitly handle custom-parsed pass names.
1901 if (parseDevirtPassName(Name))
1902 return true;
1903
1904#define CGSCC_PASS(NAME, CREATE_PASS) \
1905 if (Name == NAME) \
1906 return true;
1907#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1908 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1909 return true;
1910#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
1911 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1912 return true;
1913#include "PassRegistry.def"
1914
1915 return callbacksAcceptPassName<CGSCCPassManager>(Name, Callbacks);
1916}
1917
1918template <typename CallbacksT>
1919static bool isFunctionPassName(StringRef Name, CallbacksT &Callbacks) {
1920 // Explicitly handle pass manager names.
1921 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1922 if (NameNoBracket == "function")
1923 return true;
1924 if (Name == "loop" || Name == "loop-mssa" || Name == "machine-function")
1925 return true;
1926
1927#define FUNCTION_PASS(NAME, CREATE_PASS) \
1928 if (Name == NAME) \
1929 return true;
1930#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1931 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1932 return true;
1933#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1934 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1935 return true;
1936#include "PassRegistry.def"
1937
1938 return callbacksAcceptPassName<FunctionPassManager>(Name, Callbacks);
1939}
1940
1941template <typename CallbacksT>
1942static bool isMachineFunctionPassName(StringRef Name, CallbacksT &Callbacks) {
1943 // Explicitly handle pass manager names.
1944 if (Name == "machine-function")
1945 return true;
1946
1947#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
1948 if (Name == NAME) \
1949 return true;
1950#define MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, \
1951 PARAMS) \
1952 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1953 return true;
1954
1955#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1956 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1957 return true;
1958
1959#include "llvm/Passes/MachinePassRegistry.def"
1960
1962}
1963
1964template <typename CallbacksT>
1965static bool isLoopNestPassName(StringRef Name, CallbacksT &Callbacks,
1966 bool &UseMemorySSA) {
1967 UseMemorySSA = false;
1968
1969 if (PassBuilder::checkParametrizedPassName(Name, "lnicm")) {
1970 UseMemorySSA = true;
1971 return true;
1972 }
1973
1974#define LOOPNEST_PASS(NAME, CREATE_PASS) \
1975 if (Name == NAME) \
1976 return true;
1977#include "PassRegistry.def"
1978
1979 return callbacksAcceptPassName<LoopPassManager>(Name, Callbacks);
1980}
1981
1982template <typename CallbacksT>
1983static bool isLoopPassName(StringRef Name, CallbacksT &Callbacks,
1984 bool &UseMemorySSA) {
1985 UseMemorySSA = false;
1986
1987 if (PassBuilder::checkParametrizedPassName(Name, "licm")) {
1988 UseMemorySSA = true;
1989 return true;
1990 }
1991
1992#define LOOP_PASS(NAME, CREATE_PASS) \
1993 if (Name == NAME) \
1994 return true;
1995#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1996 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1997 return true;
1998#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
1999 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
2000 return true;
2001#include "PassRegistry.def"
2002
2003 return callbacksAcceptPassName<LoopPassManager>(Name, Callbacks);
2004}
2005
2006std::optional<std::vector<PassBuilder::PipelineElement>>
2007PassBuilder::parsePipelineText(StringRef Text) {
2008 std::vector<PipelineElement> ResultPipeline;
2009
2010 SmallVector<std::vector<PipelineElement> *, 4> PipelineStack = {
2011 &ResultPipeline};
2012 for (;;) {
2013 std::vector<PipelineElement> &Pipeline = *PipelineStack.back();
2014 size_t Pos = Text.find_first_of(",()");
2015 Pipeline.push_back({Text.substr(0, Pos), {}});
2016
2017 // If we have a single terminating name, we're done.
2018 if (Pos == Text.npos)
2019 break;
2020
2021 char Sep = Text[Pos];
2022 Text = Text.substr(Pos + 1);
2023 if (Sep == ',')
2024 // Just a name ending in a comma, continue.
2025 continue;
2026
2027 if (Sep == '(') {
2028 // Push the inner pipeline onto the stack to continue processing.
2029 PipelineStack.push_back(&Pipeline.back().InnerPipeline);
2030 continue;
2031 }
2032
2033 assert(Sep == ')' && "Bogus separator!");
2034 // When handling the close parenthesis, we greedily consume them to avoid
2035 // empty strings in the pipeline.
2036 do {
2037 // If we try to pop the outer pipeline we have unbalanced parentheses.
2038 if (PipelineStack.size() == 1)
2039 return std::nullopt;
2040
2041 PipelineStack.pop_back();
2042 } while (Text.consume_front(")"));
2043
2044 // Check if we've finished parsing.
2045 if (Text.empty())
2046 break;
2047
2048 // Otherwise, the end of an inner pipeline always has to be followed by
2049 // a comma, and then we can continue.
2050 if (!Text.consume_front(","))
2051 return std::nullopt;
2052 }
2053
2054 if (PipelineStack.size() > 1)
2055 // Unbalanced paretheses.
2056 return std::nullopt;
2057
2058 assert(PipelineStack.back() == &ResultPipeline &&
2059 "Wrong pipeline at the bottom of the stack!");
2060 return {std::move(ResultPipeline)};
2061}
2062
2068
2069Error PassBuilder::parseModulePass(ModulePassManager &MPM,
2070 const PipelineElement &E) {
2071 auto &Name = E.Name;
2072 auto &InnerPipeline = E.InnerPipeline;
2073
2074 // First handle complex passes like the pass managers which carry pipelines.
2075 if (!InnerPipeline.empty()) {
2076 if (Name == "module") {
2077 ModulePassManager NestedMPM;
2078 if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline))
2079 return Err;
2080 MPM.addPass(std::move(NestedMPM));
2081 return Error::success();
2082 }
2083 if (Name == "coro-cond") {
2084 ModulePassManager NestedMPM;
2085 if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline))
2086 return Err;
2087 MPM.addPass(CoroConditionalWrapper(std::move(NestedMPM)));
2088 return Error::success();
2089 }
2090 if (Name == "cgscc") {
2091 CGSCCPassManager CGPM;
2092 if (auto Err = parseCGSCCPassPipeline(CGPM, InnerPipeline))
2093 return Err;
2095 return Error::success();
2096 }
2097 if (auto Params = parseFunctionPipelineName(Name)) {
2098 if (Params->second)
2100 "cannot have a no-rerun module to function adaptor",
2103 if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline))
2104 return Err;
2105 MPM.addPass(
2106 createModuleToFunctionPassAdaptor(std::move(FPM), Params->first));
2107 return Error::success();
2108 }
2109
2110 for (auto &C : ModulePipelineParsingCallbacks)
2111 if (C(Name, MPM, InnerPipeline))
2112 return Error::success();
2113
2114 // Normal passes can't have pipelines.
2116 formatv("invalid use of '{}' pass as module pipeline", Name).str(),
2118 ;
2119 }
2120
2121 // Finally expand the basic registered passes from the .inc file.
2122#define MODULE_PASS(NAME, CREATE_PASS) \
2123 if (Name == NAME) { \
2124 MPM.addPass(CREATE_PASS); \
2125 return Error::success(); \
2126 }
2127#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2128 if (checkParametrizedPassName(Name, NAME)) { \
2129 auto Params = parsePassParameters(PARSER, Name, NAME); \
2130 if (!Params) \
2131 return Params.takeError(); \
2132 MPM.addPass(CREATE_PASS(Params.get())); \
2133 return Error::success(); \
2134 }
2135#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
2136 if (Name == "require<" NAME ">") { \
2137 MPM.addPass( \
2138 RequireAnalysisPass< \
2139 std::remove_reference_t<decltype(CREATE_PASS)>, Module>()); \
2140 return Error::success(); \
2141 } \
2142 if (Name == "invalidate<" NAME ">") { \
2143 MPM.addPass(InvalidateAnalysisPass< \
2144 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2145 return Error::success(); \
2146 }
2147#define CGSCC_PASS(NAME, CREATE_PASS) \
2148 if (Name == NAME) { \
2149 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(CREATE_PASS)); \
2150 return Error::success(); \
2151 }
2152#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2153 if (checkParametrizedPassName(Name, NAME)) { \
2154 auto Params = parsePassParameters(PARSER, Name, NAME); \
2155 if (!Params) \
2156 return Params.takeError(); \
2157 MPM.addPass( \
2158 createModuleToPostOrderCGSCCPassAdaptor(CREATE_PASS(Params.get()))); \
2159 return Error::success(); \
2160 }
2161#define FUNCTION_PASS(NAME, CREATE_PASS) \
2162 if (Name == NAME) { \
2163 if constexpr (std::is_constructible_v< \
2164 std::remove_reference_t<decltype(CREATE_PASS)>, \
2165 const TargetMachine &>) { \
2166 if (!TM) \
2167 return make_error<StringError>( \
2168 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2169 inconvertibleErrorCode()); \
2170 } \
2171 MPM.addPass(createModuleToFunctionPassAdaptor(CREATE_PASS)); \
2172 return Error::success(); \
2173 }
2174#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2175 if (checkParametrizedPassName(Name, NAME)) { \
2176 auto Params = parsePassParameters(PARSER, Name, NAME); \
2177 if (!Params) \
2178 return Params.takeError(); \
2179 auto CreatePass = CREATE_PASS; \
2180 if constexpr (std::is_constructible_v< \
2181 std::remove_reference_t<decltype(CreatePass( \
2182 Params.get()))>, \
2183 const TargetMachine &, \
2184 std::remove_reference_t<decltype(Params.get())>>) { \
2185 if (!TM) { \
2186 return make_error<StringError>( \
2187 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2188 inconvertibleErrorCode()); \
2189 } \
2190 } \
2191 MPM.addPass(createModuleToFunctionPassAdaptor(CREATE_PASS(Params.get()))); \
2192 return Error::success(); \
2193 }
2194#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2195 if (Name == NAME) { \
2196 MPM.addPass(createModuleToFunctionPassAdaptor( \
2197 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2198 return Error::success(); \
2199 }
2200#define LOOP_PASS(NAME, CREATE_PASS) \
2201 if (Name == NAME) { \
2202 MPM.addPass(createModuleToFunctionPassAdaptor( \
2203 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2204 return Error::success(); \
2205 }
2206#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2207 if (checkParametrizedPassName(Name, NAME)) { \
2208 auto Params = parsePassParameters(PARSER, Name, NAME); \
2209 if (!Params) \
2210 return Params.takeError(); \
2211 MPM.addPass(createModuleToFunctionPassAdaptor( \
2212 createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), false))); \
2213 return Error::success(); \
2214 }
2215#include "PassRegistry.def"
2216
2217 for (auto &C : ModulePipelineParsingCallbacks)
2218 if (C(Name, MPM, InnerPipeline))
2219 return Error::success();
2221 formatv("unknown module pass '{}'", Name).str(),
2223}
2224
2225Error PassBuilder::parseCGSCCPass(CGSCCPassManager &CGPM,
2226 const PipelineElement &E) {
2227 auto &Name = E.Name;
2228 auto &InnerPipeline = E.InnerPipeline;
2229
2230 // First handle complex passes like the pass managers which carry pipelines.
2231 if (!InnerPipeline.empty()) {
2232 if (Name == "cgscc") {
2233 CGSCCPassManager NestedCGPM;
2234 if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline))
2235 return Err;
2236 // Add the nested pass manager with the appropriate adaptor.
2237 CGPM.addPass(std::move(NestedCGPM));
2238 return Error::success();
2239 }
2240 if (auto Params = parseFunctionPipelineName(Name)) {
2242 if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline))
2243 return Err;
2244 // Add the nested pass manager with the appropriate adaptor.
2246 std::move(FPM), Params->first, Params->second));
2247 return Error::success();
2248 }
2249 if (auto MaxRepetitions = parseDevirtPassName(Name)) {
2250 CGSCCPassManager NestedCGPM;
2251 if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline))
2252 return Err;
2253 CGPM.addPass(
2254 createDevirtSCCRepeatedPass(std::move(NestedCGPM), *MaxRepetitions));
2255 return Error::success();
2256 }
2257
2258 for (auto &C : CGSCCPipelineParsingCallbacks)
2259 if (C(Name, CGPM, InnerPipeline))
2260 return Error::success();
2261
2262 // Normal passes can't have pipelines.
2264 formatv("invalid use of '{}' pass as cgscc pipeline", Name).str(),
2266 }
2267
2268// Now expand the basic registered passes from the .inc file.
2269#define CGSCC_PASS(NAME, CREATE_PASS) \
2270 if (Name == NAME) { \
2271 CGPM.addPass(CREATE_PASS); \
2272 return Error::success(); \
2273 }
2274#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2275 if (checkParametrizedPassName(Name, NAME)) { \
2276 auto Params = parsePassParameters(PARSER, Name, NAME); \
2277 if (!Params) \
2278 return Params.takeError(); \
2279 CGPM.addPass(CREATE_PASS(Params.get())); \
2280 return Error::success(); \
2281 }
2282#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
2283 if (Name == "require<" NAME ">") { \
2284 CGPM.addPass(RequireAnalysisPass< \
2285 std::remove_reference_t<decltype(CREATE_PASS)>, \
2286 LazyCallGraph::SCC, CGSCCAnalysisManager, LazyCallGraph &, \
2287 CGSCCUpdateResult &>()); \
2288 return Error::success(); \
2289 } \
2290 if (Name == "invalidate<" NAME ">") { \
2291 CGPM.addPass(InvalidateAnalysisPass< \
2292 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2293 return Error::success(); \
2294 }
2295#define FUNCTION_PASS(NAME, CREATE_PASS) \
2296 if (Name == NAME) { \
2297 if constexpr (std::is_constructible_v< \
2298 std::remove_reference_t<decltype(CREATE_PASS)>, \
2299 const TargetMachine &>) { \
2300 if (!TM) \
2301 return make_error<StringError>( \
2302 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2303 inconvertibleErrorCode()); \
2304 } \
2305 CGPM.addPass(createCGSCCToFunctionPassAdaptor(CREATE_PASS)); \
2306 return Error::success(); \
2307 }
2308#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2309 if (checkParametrizedPassName(Name, NAME)) { \
2310 auto Params = parsePassParameters(PARSER, Name, NAME); \
2311 if (!Params) \
2312 return Params.takeError(); \
2313 auto CreatePass = CREATE_PASS; \
2314 if constexpr (std::is_constructible_v< \
2315 std::remove_reference_t<decltype(CreatePass( \
2316 Params.get()))>, \
2317 const TargetMachine &, \
2318 std::remove_reference_t<decltype(Params.get())>>) { \
2319 if (!TM) { \
2320 return make_error<StringError>( \
2321 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2322 inconvertibleErrorCode()); \
2323 } \
2324 } \
2325 CGPM.addPass(createCGSCCToFunctionPassAdaptor(CREATE_PASS(Params.get()))); \
2326 return Error::success(); \
2327 }
2328#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2329 if (Name == NAME) { \
2330 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
2331 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2332 return Error::success(); \
2333 }
2334#define LOOP_PASS(NAME, CREATE_PASS) \
2335 if (Name == NAME) { \
2336 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
2337 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2338 return Error::success(); \
2339 }
2340#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2341 if (checkParametrizedPassName(Name, NAME)) { \
2342 auto Params = parsePassParameters(PARSER, Name, NAME); \
2343 if (!Params) \
2344 return Params.takeError(); \
2345 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
2346 createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), false))); \
2347 return Error::success(); \
2348 }
2349#include "PassRegistry.def"
2350
2351 for (auto &C : CGSCCPipelineParsingCallbacks)
2352 if (C(Name, CGPM, InnerPipeline))
2353 return Error::success();
2354 return make_error<StringError>(formatv("unknown cgscc pass '{}'", Name).str(),
2356}
2357
2358Error PassBuilder::parseFunctionPass(FunctionPassManager &FPM,
2359 const PipelineElement &E) {
2360 auto &Name = E.Name;
2361 auto &InnerPipeline = E.InnerPipeline;
2362
2363 // First handle complex passes like the pass managers which carry pipelines.
2364 if (!InnerPipeline.empty()) {
2365 if (Name == "function") {
2366 FunctionPassManager NestedFPM;
2367 if (auto Err = parseFunctionPassPipeline(NestedFPM, InnerPipeline))
2368 return Err;
2369 // Add the nested pass manager with the appropriate adaptor.
2370 FPM.addPass(std::move(NestedFPM));
2371 return Error::success();
2372 }
2373 if (Name == "loop" || Name == "loop-mssa") {
2374 LoopPassManager LPM;
2375 if (auto Err = parseLoopPassPipeline(LPM, InnerPipeline))
2376 return Err;
2377 // Add the nested pass manager with the appropriate adaptor.
2378 bool UseMemorySSA = (Name == "loop-mssa");
2379 FPM.addPass(
2380 createFunctionToLoopPassAdaptor(std::move(LPM), UseMemorySSA));
2381 return Error::success();
2382 }
2383 if (Name == "machine-function") {
2385 if (auto Err = parseMachinePassPipeline(MFPM, InnerPipeline))
2386 return Err;
2388 return Error::success();
2389 }
2390
2391 for (auto &C : FunctionPipelineParsingCallbacks)
2392 if (C(Name, FPM, InnerPipeline))
2393 return Error::success();
2394
2395 // Normal passes can't have pipelines.
2397 formatv("invalid use of '{}' pass as function pipeline", Name).str(),
2399 }
2400
2401// Now expand the basic registered passes from the .inc file.
2402#define FUNCTION_PASS(NAME, CREATE_PASS) \
2403 if (Name == NAME) { \
2404 if constexpr (std::is_constructible_v< \
2405 std::remove_reference_t<decltype(CREATE_PASS)>, \
2406 const TargetMachine &>) { \
2407 if (!TM) \
2408 return make_error<StringError>( \
2409 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2410 inconvertibleErrorCode()); \
2411 } \
2412 FPM.addPass(CREATE_PASS); \
2413 return Error::success(); \
2414 }
2415#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2416 if (checkParametrizedPassName(Name, NAME)) { \
2417 auto Params = parsePassParameters(PARSER, Name, NAME); \
2418 if (!Params) \
2419 return Params.takeError(); \
2420 auto CreatePass = CREATE_PASS; \
2421 if constexpr (std::is_constructible_v< \
2422 std::remove_reference_t<decltype(CreatePass( \
2423 Params.get()))>, \
2424 const TargetMachine &, \
2425 std::remove_reference_t<decltype(Params.get())>>) { \
2426 if (!TM) { \
2427 return make_error<StringError>( \
2428 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2429 inconvertibleErrorCode()); \
2430 } \
2431 } \
2432 FPM.addPass(CREATE_PASS(Params.get())); \
2433 return Error::success(); \
2434 }
2435#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
2436 if (Name == "require<" NAME ">") { \
2437 if constexpr (std::is_constructible_v< \
2438 std::remove_reference_t<decltype(CREATE_PASS)>, \
2439 const TargetMachine &>) { \
2440 if (!TM) \
2441 return make_error<StringError>( \
2442 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2443 inconvertibleErrorCode()); \
2444 } \
2445 FPM.addPass( \
2446 RequireAnalysisPass<std::remove_reference_t<decltype(CREATE_PASS)>, \
2447 Function>()); \
2448 return Error::success(); \
2449 } \
2450 if (Name == "invalidate<" NAME ">") { \
2451 FPM.addPass(InvalidateAnalysisPass< \
2452 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2453 return Error::success(); \
2454 }
2455// FIXME: UseMemorySSA is set to false. Maybe we could do things like:
2456// bool UseMemorySSA = !("canon-freeze" || "loop-predication" ||
2457// "guard-widening");
2458// The risk is that it may become obsolete if we're not careful.
2459#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2460 if (Name == NAME) { \
2461 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS, false)); \
2462 return Error::success(); \
2463 }
2464#define LOOP_PASS(NAME, CREATE_PASS) \
2465 if (Name == NAME) { \
2466 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS, false)); \
2467 return Error::success(); \
2468 }
2469#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2470 if (checkParametrizedPassName(Name, NAME)) { \
2471 auto Params = parsePassParameters(PARSER, Name, NAME); \
2472 if (!Params) \
2473 return Params.takeError(); \
2474 FPM.addPass( \
2475 createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), false)); \
2476 return Error::success(); \
2477 }
2478#include "PassRegistry.def"
2479
2480 for (auto &C : FunctionPipelineParsingCallbacks)
2481 if (C(Name, FPM, InnerPipeline))
2482 return Error::success();
2484 formatv("unknown function pass '{}'", Name).str(),
2486}
2487
2488Error PassBuilder::parseLoopPass(LoopPassManager &LPM,
2489 const PipelineElement &E) {
2490 StringRef Name = E.Name;
2491 auto &InnerPipeline = E.InnerPipeline;
2492
2493 // First handle complex passes like the pass managers which carry pipelines.
2494 if (!InnerPipeline.empty()) {
2495 if (Name == "loop") {
2496 LoopPassManager NestedLPM;
2497 if (auto Err = parseLoopPassPipeline(NestedLPM, InnerPipeline))
2498 return Err;
2499 // Add the nested pass manager with the appropriate adaptor.
2500 LPM.addPass(std::move(NestedLPM));
2501 return Error::success();
2502 }
2503
2504 for (auto &C : LoopPipelineParsingCallbacks)
2505 if (C(Name, LPM, InnerPipeline))
2506 return Error::success();
2507
2508 // Normal passes can't have pipelines.
2510 formatv("invalid use of '{}' pass as loop pipeline", Name).str(),
2512 }
2513
2514// Now expand the basic registered passes from the .inc file.
2515#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2516 if (Name == NAME) { \
2517 LPM.addPass(CREATE_PASS); \
2518 return Error::success(); \
2519 }
2520#define LOOP_PASS(NAME, CREATE_PASS) \
2521 if (Name == NAME) { \
2522 LPM.addPass(CREATE_PASS); \
2523 return Error::success(); \
2524 }
2525#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2526 if (checkParametrizedPassName(Name, NAME)) { \
2527 auto Params = parsePassParameters(PARSER, Name, NAME); \
2528 if (!Params) \
2529 return Params.takeError(); \
2530 LPM.addPass(CREATE_PASS(Params.get())); \
2531 return Error::success(); \
2532 }
2533#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
2534 if (Name == "require<" NAME ">") { \
2535 LPM.addPass(RequireAnalysisPass< \
2536 std::remove_reference_t<decltype(CREATE_PASS)>, Loop, \
2537 LoopAnalysisManager, LoopStandardAnalysisResults &, \
2538 LPMUpdater &>()); \
2539 return Error::success(); \
2540 } \
2541 if (Name == "invalidate<" NAME ">") { \
2542 LPM.addPass(InvalidateAnalysisPass< \
2543 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2544 return Error::success(); \
2545 }
2546#include "PassRegistry.def"
2547
2548 for (auto &C : LoopPipelineParsingCallbacks)
2549 if (C(Name, LPM, InnerPipeline))
2550 return Error::success();
2551 return make_error<StringError>(formatv("unknown loop pass '{}'", Name).str(),
2553}
2554
2555Error PassBuilder::parseMachinePass(MachineFunctionPassManager &MFPM,
2556 const PipelineElement &E) {
2557 StringRef Name = E.Name;
2558 // Handle any nested pass managers.
2559 if (!E.InnerPipeline.empty()) {
2560 if (E.Name == "machine-function") {
2562 if (auto Err = parseMachinePassPipeline(NestedPM, E.InnerPipeline))
2563 return Err;
2564 MFPM.addPass(std::move(NestedPM));
2565 return Error::success();
2566 }
2567 return make_error<StringError>("invalid pipeline",
2569 }
2570
2571#define MACHINE_MODULE_PASS(NAME, CREATE_PASS) \
2572 if (Name == NAME) { \
2573 MFPM.addPass(CREATE_PASS); \
2574 return Error::success(); \
2575 }
2576#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
2577 if (Name == NAME) { \
2578 MFPM.addPass(CREATE_PASS); \
2579 return Error::success(); \
2580 }
2581#define MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, \
2582 PARAMS) \
2583 if (checkParametrizedPassName(Name, NAME)) { \
2584 auto Params = parsePassParameters(PARSER, Name, NAME); \
2585 if (!Params) \
2586 return Params.takeError(); \
2587 MFPM.addPass(CREATE_PASS(Params.get())); \
2588 return Error::success(); \
2589 }
2590#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
2591 if (Name == "require<" NAME ">") { \
2592 MFPM.addPass( \
2593 RequireAnalysisPass<std::remove_reference_t<decltype(CREATE_PASS)>, \
2594 MachineFunction>()); \
2595 return Error::success(); \
2596 } \
2597 if (Name == "invalidate<" NAME ">") { \
2598 MFPM.addPass(InvalidateAnalysisPass< \
2599 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2600 return Error::success(); \
2601 }
2602#include "llvm/Passes/MachinePassRegistry.def"
2603
2604 for (auto &C : MachineFunctionPipelineParsingCallbacks)
2605 if (C(Name, MFPM, E.InnerPipeline))
2606 return Error::success();
2608 formatv("unknown machine pass '{}'", Name).str(),
2610}
2611
2612bool PassBuilder::parseAAPassName(AAManager &AA, StringRef Name) {
2613#define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
2614 if (Name == NAME) { \
2615 AA.registerModuleAnalysis< \
2616 std::remove_reference_t<decltype(CREATE_PASS)>>(); \
2617 return true; \
2618 }
2619#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
2620 if (Name == NAME) { \
2621 AA.registerFunctionAnalysis< \
2622 std::remove_reference_t<decltype(CREATE_PASS)>>(); \
2623 return true; \
2624 }
2625#include "PassRegistry.def"
2626
2627 for (auto &C : AAParsingCallbacks)
2628 if (C(Name, AA))
2629 return true;
2630 return false;
2631}
2632
2633Error PassBuilder::parseMachinePassPipeline(
2635 for (const auto &Element : Pipeline) {
2636 if (auto Err = parseMachinePass(MFPM, Element))
2637 return Err;
2638 }
2639 return Error::success();
2640}
2641
2642Error PassBuilder::parseLoopPassPipeline(LoopPassManager &LPM,
2643 ArrayRef<PipelineElement> Pipeline) {
2644 for (const auto &Element : Pipeline) {
2645 if (auto Err = parseLoopPass(LPM, Element))
2646 return Err;
2647 }
2648 return Error::success();
2649}
2650
2651Error PassBuilder::parseFunctionPassPipeline(
2653 for (const auto &Element : Pipeline) {
2654 if (auto Err = parseFunctionPass(FPM, Element))
2655 return Err;
2656 }
2657 return Error::success();
2658}
2659
2660Error PassBuilder::parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
2661 ArrayRef<PipelineElement> Pipeline) {
2662 for (const auto &Element : Pipeline) {
2663 if (auto Err = parseCGSCCPass(CGPM, Element))
2664 return Err;
2665 }
2666 return Error::success();
2667}
2668
2674 MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });
2675 MAM.registerPass([&] { return CGSCCAnalysisManagerModuleProxy(CGAM); });
2676 CGAM.registerPass([&] { return ModuleAnalysisManagerCGSCCProxy(MAM); });
2677 FAM.registerPass([&] { return CGSCCAnalysisManagerFunctionProxy(CGAM); });
2678 FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); });
2679 FAM.registerPass([&] { return LoopAnalysisManagerFunctionProxy(LAM); });
2680 LAM.registerPass([&] { return FunctionAnalysisManagerLoopProxy(FAM); });
2681 if (MFAM) {
2682 MAM.registerPass(
2683 [&] { return MachineFunctionAnalysisManagerModuleProxy(*MFAM); });
2684 FAM.registerPass(
2685 [&] { return MachineFunctionAnalysisManagerFunctionProxy(*MFAM); });
2686 MFAM->registerPass(
2688 MFAM->registerPass(
2690 }
2691}
2692
2693Error PassBuilder::parseModulePassPipeline(ModulePassManager &MPM,
2694 ArrayRef<PipelineElement> Pipeline) {
2695 for (const auto &Element : Pipeline) {
2696 if (auto Err = parseModulePass(MPM, Element))
2697 return Err;
2698 }
2699 return Error::success();
2700}
2701
2702// Primary pass pipeline description parsing routine for a \c ModulePassManager
2703// FIXME: Should this routine accept a TargetMachine or require the caller to
2704// pre-populate the analysis managers with target-specific stuff?
2706 StringRef PipelineText) {
2707 auto Pipeline = parsePipelineText(PipelineText);
2708 if (!Pipeline || Pipeline->empty())
2710 formatv("invalid pipeline '{}'", PipelineText).str(),
2712
2713 // If the first name isn't at the module layer, wrap the pipeline up
2714 // automatically.
2715 StringRef FirstName = Pipeline->front().Name;
2716
2717 if (!isModulePassName(FirstName, ModulePipelineParsingCallbacks)) {
2718 bool UseMemorySSA;
2719 if (isCGSCCPassName(FirstName, CGSCCPipelineParsingCallbacks)) {
2720 Pipeline = {{"cgscc", std::move(*Pipeline)}};
2721 } else if (isFunctionPassName(FirstName,
2722 FunctionPipelineParsingCallbacks)) {
2723 Pipeline = {{"function", std::move(*Pipeline)}};
2724 } else if (isLoopNestPassName(FirstName, LoopPipelineParsingCallbacks,
2725 UseMemorySSA)) {
2726 Pipeline = {{"function", {{UseMemorySSA ? "loop-mssa" : "loop",
2727 std::move(*Pipeline)}}}};
2728 } else if (isLoopPassName(FirstName, LoopPipelineParsingCallbacks,
2729 UseMemorySSA)) {
2730 Pipeline = {{"function", {{UseMemorySSA ? "loop-mssa" : "loop",
2731 std::move(*Pipeline)}}}};
2732 } else if (isMachineFunctionPassName(
2733 FirstName, MachineFunctionPipelineParsingCallbacks)) {
2734 Pipeline = {{"function", {{"machine-function", std::move(*Pipeline)}}}};
2735 } else {
2736 for (auto &C : TopLevelPipelineParsingCallbacks)
2737 if (C(MPM, *Pipeline))
2738 return Error::success();
2739
2740 // Unknown pass or pipeline name!
2741 auto &InnerPipeline = Pipeline->front().InnerPipeline;
2743 formatv("unknown {} name '{}'",
2744 (InnerPipeline.empty() ? "pass" : "pipeline"), FirstName)
2745 .str(),
2747 }
2748 }
2749
2750 if (auto Err = parseModulePassPipeline(MPM, *Pipeline))
2751 return Err;
2752 return Error::success();
2753}
2754
2755// Primary pass pipeline description parsing routine for a \c CGSCCPassManager
2757 StringRef PipelineText) {
2758 auto Pipeline = parsePipelineText(PipelineText);
2759 if (!Pipeline || Pipeline->empty())
2761 formatv("invalid pipeline '{}'", PipelineText).str(),
2763
2764 StringRef FirstName = Pipeline->front().Name;
2765 if (!isCGSCCPassName(FirstName, CGSCCPipelineParsingCallbacks))
2767 formatv("unknown cgscc pass '{}' in pipeline '{}'", FirstName,
2768 PipelineText)
2769 .str(),
2771
2772 if (auto Err = parseCGSCCPassPipeline(CGPM, *Pipeline))
2773 return Err;
2774 return Error::success();
2775}
2776
2777// Primary pass pipeline description parsing routine for a \c
2778// FunctionPassManager
2780 StringRef PipelineText) {
2781 auto Pipeline = parsePipelineText(PipelineText);
2782 if (!Pipeline || Pipeline->empty())
2784 formatv("invalid pipeline '{}'", PipelineText).str(),
2786
2787 StringRef FirstName = Pipeline->front().Name;
2788 if (!isFunctionPassName(FirstName, FunctionPipelineParsingCallbacks))
2790 formatv("unknown function pass '{}' in pipeline '{}'", FirstName,
2791 PipelineText)
2792 .str(),
2794
2795 if (auto Err = parseFunctionPassPipeline(FPM, *Pipeline))
2796 return Err;
2797 return Error::success();
2798}
2799
2800// Primary pass pipeline description parsing routine for a \c LoopPassManager
2802 StringRef PipelineText) {
2803 auto Pipeline = parsePipelineText(PipelineText);
2804 if (!Pipeline || Pipeline->empty())
2806 formatv("invalid pipeline '{}'", PipelineText).str(),
2808
2809 if (auto Err = parseLoopPassPipeline(CGPM, *Pipeline))
2810 return Err;
2811
2812 return Error::success();
2813}
2814
2816 StringRef PipelineText) {
2817 auto Pipeline = parsePipelineText(PipelineText);
2818 if (!Pipeline || Pipeline->empty())
2820 formatv("invalid machine pass pipeline '{}'", PipelineText).str(),
2822
2823 if (auto Err = parseMachinePassPipeline(MFPM, *Pipeline))
2824 return Err;
2825
2826 return Error::success();
2827}
2828
2830 // If the pipeline just consists of the word 'default' just replace the AA
2831 // manager with our default one.
2832 if (PipelineText == "default") {
2834 return Error::success();
2835 }
2836
2837 while (!PipelineText.empty()) {
2838 StringRef Name;
2839 std::tie(Name, PipelineText) = PipelineText.split(',');
2840 if (!parseAAPassName(AA, Name))
2842 formatv("unknown alias analysis name '{}'", Name).str(),
2844 }
2845
2846 return Error::success();
2847}
2848
2849std::optional<RegAllocFilterFunc>
2851 if (FilterName == "all")
2852 return nullptr;
2853 for (auto &C : RegClassFilterParsingCallbacks)
2854 if (auto F = C(FilterName))
2855 return F;
2856 return std::nullopt;
2857}
2858
2860 raw_ostream &OS) {
2861 for (StringRef PassName : PassNames)
2862 OS << " " << PassName << '\n';
2863}
2864
2865LLVM_ATTRIBUTE_NOINLINE static void
2867 auto I = PassNames.begin();
2868 auto End = PassNames.end();
2869 while (I != End) {
2870 StringRef Name = *I;
2871 ++I;
2872 assert(I != End);
2873 StringRef Params = *I;
2874 ++I;
2875 OS << " " << Name << '<' << Params << ">\n";
2876 }
2877}
2878
2880 // TODO: print pass descriptions when they are available
2881
2882 OS << "Module passes:\n";
2883 static constexpr char ModulePassNames[] = {"\0"
2884#define MODULE_PASS(NAME, CREATE_PASS) NAME "\0"
2885#include "PassRegistry.def"
2886 };
2887 printPassNameList(StringTable(ModulePassNames), OS);
2888
2889 OS << "Module passes with params:\n";
2890 static constexpr char ModulePassNamesWithParams[] = {"\0"
2891#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2892 NAME "\0" PARAMS "\0"
2893#include "PassRegistry.def"
2894 };
2895 printPassNameListWithParams(StringTable(ModulePassNamesWithParams), OS);
2896
2897 OS << "Module analyses:\n";
2898 static constexpr char ModuleAnalysisNames[] = {"\0"
2899#define MODULE_ANALYSIS(NAME, CREATE_PASS) NAME "\0"
2900#include "PassRegistry.def"
2901 };
2902 printPassNameList(StringTable(ModuleAnalysisNames), OS);
2903
2904 OS << "Module alias analyses:\n";
2905 static constexpr char ModuleAliasAnalysisNames[] = {"\0"
2906#define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) NAME "\0"
2907#include "PassRegistry.def"
2908 };
2909 printPassNameList(StringTable(ModuleAliasAnalysisNames), OS);
2910
2911 OS << "CGSCC passes:\n";
2912 static constexpr char CGSCCPassNames[] = {"\0"
2913#define CGSCC_PASS(NAME, CREATE_PASS) NAME "\0"
2914#include "PassRegistry.def"
2915 };
2916 printPassNameList(StringTable(CGSCCPassNames), OS);
2917
2918 OS << "CGSCC passes with params:\n";
2919 static constexpr char CGSCCPassNamesWithParams[] = {"\0"
2920#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2921 NAME "\0" PARAMS "\0"
2922#include "PassRegistry.def"
2923 };
2924 printPassNameListWithParams(StringTable(CGSCCPassNamesWithParams), OS);
2925
2926 OS << "CGSCC analyses:\n";
2927 static constexpr char CGSCCAnalysisNames[] = {"\0"
2928#define CGSCC_ANALYSIS(NAME, CREATE_PASS) NAME "\0"
2929#include "PassRegistry.def"
2930 };
2931 printPassNameList(StringTable(CGSCCAnalysisNames), OS);
2932
2933 OS << "Function passes:\n";
2934 static constexpr char FunctionPassNames[] = {"\0"
2935#define FUNCTION_PASS(NAME, CREATE_PASS) NAME "\0"
2936#include "PassRegistry.def"
2937 };
2938 printPassNameList(StringTable(FunctionPassNames), OS);
2939
2940 OS << "Function passes with params:\n";
2941 static constexpr char FunctionPassNamesWithParams[] = {"\0"
2942#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2943 NAME "\0" PARAMS "\0"
2944#include "PassRegistry.def"
2945 };
2946 printPassNameListWithParams(StringTable(FunctionPassNamesWithParams), OS);
2947
2948 OS << "Function analyses:\n";
2949 static constexpr char FunctionAnalysisNames[] = {"\0"
2950#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) NAME "\0"
2951#include "PassRegistry.def"
2952 };
2953 printPassNameList(StringTable(FunctionAnalysisNames), OS);
2954
2955 OS << "Function alias analyses:\n";
2956 static constexpr char FunctionAliasAnalysisNames[] = {"\0"
2957#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) NAME "\0"
2958#include "PassRegistry.def"
2959 };
2960 printPassNameList(StringTable(FunctionAliasAnalysisNames), OS);
2961
2962 OS << "LoopNest passes:\n";
2963 static constexpr char LoopNestPassNames[] = {"\0"
2964#define LOOPNEST_PASS(NAME, CREATE_PASS) NAME "\0"
2965#include "PassRegistry.def"
2966 };
2967 printPassNameList(StringTable(LoopNestPassNames), OS);
2968
2969 OS << "Loop passes:\n";
2970 static constexpr char LoopPassNames[] = {"\0"
2971#define LOOP_PASS(NAME, CREATE_PASS) NAME "\0"
2972#include "PassRegistry.def"
2973 };
2974 printPassNameList(StringTable(LoopPassNames), OS);
2975
2976 OS << "Loop passes with params:\n";
2977 static constexpr char LoopPassNamesWithParams[] = {"\0"
2978#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2979 NAME "\0" PARAMS "\0"
2980#include "PassRegistry.def"
2981 };
2982 printPassNameListWithParams(StringTable(LoopPassNamesWithParams), OS);
2983
2984 OS << "Loop analyses:\n";
2985 static constexpr char LoopAnalysisNames[] = {"\0"
2986#define LOOP_ANALYSIS(NAME, CREATE_PASS) NAME "\0"
2987#include "PassRegistry.def"
2988 };
2989 printPassNameList(StringTable(LoopAnalysisNames), OS);
2990
2991 OS << "Machine module passes (WIP):\n";
2992 static constexpr char MachineModulePassNames[] = {"\0"
2993#define MACHINE_MODULE_PASS(NAME, CREATE_PASS) NAME "\0"
2994#include "llvm/Passes/MachinePassRegistry.def"
2995 };
2996 printPassNameList(StringTable(MachineModulePassNames), OS);
2997
2998 OS << "Machine function passes (WIP):\n";
2999 static constexpr char MachineFunctionPassNames[] = {"\0"
3000#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) NAME "\0"
3001#include "llvm/Passes/MachinePassRegistry.def"
3002 };
3003 printPassNameList(StringTable(MachineFunctionPassNames), OS);
3004
3005 OS << "Machine function analyses (WIP):\n";
3006 static constexpr char MachineFunctionAnalysisNames[] = {"\0"
3007#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) NAME "\0"
3008#include "llvm/Passes/MachinePassRegistry.def"
3009 };
3010 printPassNameList(StringTable(MachineFunctionAnalysisNames), OS);
3011}
3012
3014 const std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>)>
3015 &C) {
3016 TopLevelPipelineParsingCallbacks.push_back(C);
3017}
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:358
This file declares an analysis pass that computes CycleInfo for LLVM IR, specialized from GenericCycl...
Analysis that tracks defined/used subregister lanes across COPY instructions and instructions that ge...
This file provides the interface for a simple, fast CSE pass.
This file provides a pass which clones the current module and runs the provided pass pipeline on the ...
Super simple passes to force specific function attrs from the commandline into the IR for debugging p...
Provides passes for computing function attributes based on interprocedural analyses.
This file provides the interface for the GCOV style profiler pass.
Provides analysis for querying information about KnownBits during GISel passes.
This file provides the interface for the GVNHoist pass.
This file provides the interface for the GVNSink pass.
This file provides the interface for LLVM's Global Value Numbering pass which eliminates fully redund...
This is the interface for a simple mod/ref and alias analysis over globals.
Defines an IR pass for the creation of hardware loops.
#define _
AcceleratorCodeSelection - Identify all functions reachable from a kernel, removing those that are un...
This file defines the IR2Vec vocabulary analysis(IR2VecVocabAnalysis), the core ir2vec::Embedder inte...
This file defines passes to print out IR in various granularities.
This file declares the IRTranslator pass.
This header defines various interfaces for pass management in LLVM.
Interfaces for passes which infer implicit function attributes from the name and signature of functio...
This file provides the primary interface to the instcombine pass.
Defines passes for running instruction simplification across chunks of IR.
This file provides the interface for LLVM's PGO Instrumentation lowering pass.
This file contains the declaration of the InterleavedAccessPass class, its corresponding pass name is...
See the comments on JumpThreadingPass.
static LVOptions Options
Definition LVOptions.cpp:25
Implements a lazy call graph analysis and related passes for the new pass manager.
This file provides the interface for LLVM's Logical Scalar Replacement of Aggregates pass.
This file defines the interface for the loop cache analysis.
This file provides the interface for LLVM's Loop Data Prefetching Pass.
This file implements the Loop Fusion pass.
This header defines the LoopLoadEliminationPass object.
This file defines the interface for the loop nest analysis.
This header provides classes for managing a pipeline of passes over loops in LLVM IR.
This file provides the interface for the pass responsible for removing expensive ubsan checks.
The header file for the LowerConstantIntrinsics pass as used by the new pass manager.
The header file for the LowerExpectIntrinsic pass as used by the new pass manager.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Machine Check Debug Module
This file contains the declaration of the CheckDebugMachineModulePass class, used by the new pass man...
Machine IR instance of the generic uniformity analysis.
This file exposes an interface to building/using memory SSA to walk memory instructions using a use/d...
This pass performs merges of loads and stores on both sides of a.
This is the interface to build a ModuleSummaryIndex for a module.
Contains a collection of routines for determining if a given instruction is guaranteed to execute if ...
This file provides the interface for LLVM's Global Value Numbering pass.
This file declares a simple ARC-aware AliasAnalysis using special knowledge of Objective C to enhance...
This header enumerates the LLVM-provided high-level optimization levels.
This file provides the interface for IR based instrumentation passes ( (profile-gen,...
CGSCCAnalysisManager CGAM
LoopAnalysisManager LAM
FunctionAnalysisManager FAM
ModuleAnalysisManager MAM
PassBuilder PB(Mod->getContext(), Machine, PassOpts->PTO, std::nullopt, &PIC)
if(PassOpts->AAPipeline)
static bool isModulePassName(StringRef Name, CallbacksT &Callbacks)
static bool callbacksAcceptPassName(StringRef Name, CallbacksT &Callbacks)
Tests whether registered callbacks will accept a given pass name.
static std::optional< int > parseDevirtPassName(StringRef Name)
static LLVM_ATTRIBUTE_NOINLINE void printPassNameList(StringTable PassNames, raw_ostream &OS)
static bool isLoopNestPassName(StringRef Name, CallbacksT &Callbacks, bool &UseMemorySSA)
static bool isMachineFunctionPassName(StringRef Name, CallbacksT &Callbacks)
static Expected< OptimizationLevel > parseOptLevelParam(StringRef S)
static std::optional< OptimizationLevel > parseOptLevel(StringRef S)
static bool isLoopPassName(StringRef Name, CallbacksT &Callbacks, bool &UseMemorySSA)
static std::optional< std::pair< bool, bool > > parseFunctionPipelineName(StringRef Name)
static bool isCGSCCPassName(StringRef Name, CallbacksT &Callbacks)
static LLVM_ATTRIBUTE_NOINLINE void printPassNameListWithParams(StringTable PassNames, raw_ostream &OS)
static bool isFunctionPassName(StringRef Name, CallbacksT &Callbacks)
static void setupOptionsForPipelineAlias(PipelineTuningOptions &PTO, OptimizationLevel L)
This file implements the PredicateInfo analysis, which creates an Extended SSA form for operations us...
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
This file describes the interface of the MachineFunctionPass responsible for assigning the generic vi...
This pass is required to take advantage of the interprocedural register allocation infrastructure.
This file implements relative lookup table converter that converts lookup tables to relative lookup t...
This file contains the declaration of the ResetMachineFunctionPass class.
This file provides the interface for LLVM's Scalar Replacement of Aggregates pass.
static const char * name
This file provides the interface for the pseudo probe implementation for AutoFDO.
This file provides the interface for the sampled PGO loader pass.
This is the interface for a SCEV-based alias analysis.
This pass converts vector operations into scalar operations (or, optionally, operations on smaller ve...
This is the interface for a metadata-based scoped no-alias analysis.
This file contains the declaration of the SelectOptimizePass class, its corresponding pass name is se...
This file provides the interface for the pass responsible for both simplifying and canonicalizing the...
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
This pass strips convergence intrinsics and operand bundles as those are only useful when modifying t...
Target-Independent Code Generator Pass Configuration Options pass.
This pass exposes codegen information to IR-level passes.
This is the interface for a metadata-based TBAA.
Defines an IR pass for type promotion.
LLVM IR instance of the generic uniformity analysis.
static const char PassName[]
A manager for alias analyses.
Class for arbitrary precision integers.
Definition APInt.h:78
uint64_t getZExtValue() const
Get zero extended value.
Definition APInt.h:1560
int64_t getSExtValue() const
Get sign extended value.
Definition APInt.h:1582
bool registerPass(PassBuilderT &&PassBuilder)
Register an analysis pass with the manager.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Definition BasicBlock.h:237
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
Tagged union holding either a T or a Error.
Definition Error.h:485
static LLVM_ABI GlobalAlias * create(Type *Ty, unsigned AddressSpace, LinkageTypes Linkage, const Twine &Name, Constant *Aliasee, Module *Parent)
If a parent module is specified, the alias is automatically inserted into the end of the specified mo...
Definition Globals.cpp:692
A smart pointer to a reference-counted object that inherits from RefCountedBase or ThreadSafeRefCount...
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
This is an important class for using LLVM in a threaded context.
Definition LLVMContext.h:76
This analysis create MachineFunction for given Function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const MachineFunctionProperties & getProperties() const
Get the function properties.
LLVM_ABI Register createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
This class provides access to building LLVM's passes.
LLVM_ABI void printPassNames(raw_ostream &OS)
Print pass names.
static bool checkParametrizedPassName(StringRef Name, StringRef PassName)
LLVM_ABI AAManager buildDefaultAAPipeline()
Build the default AAManager with the default alias analysis pipeline registered.
LLVM_ABI Error parseAAPipeline(AAManager &AA, StringRef PipelineText)
Parse a textual alias analysis pipeline into the provided AA manager.
LLVM_ABI void registerLoopAnalyses(LoopAnalysisManager &LAM)
Registers all available loop analysis passes.
LLVM_ABI std::optional< RegAllocFilterFunc > parseRegAllocFilter(StringRef RegAllocFilterName)
Parse RegAllocFilterName to get RegAllocFilterFunc.
LLVM_ABI void crossRegisterProxies(LoopAnalysisManager &LAM, FunctionAnalysisManager &FAM, CGSCCAnalysisManager &CGAM, ModuleAnalysisManager &MAM, MachineFunctionAnalysisManager *MFAM=nullptr)
Cross register the analysis managers through their proxies.
LLVM_ABI Error parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText)
Parse a textual pass pipeline description into a ModulePassManager.
LLVM_ABI PassBuilder(LLVMContext &Context, TargetMachine *TM=nullptr, std::optional< PipelineTuningOptions > PTO=std::nullopt, std::optional< PGOOptions > PGOOpt=std::nullopt, PassInstrumentationCallbacks *PIC=nullptr, IntrusiveRefCntPtr< vfs::FileSystem > FS=vfs::getRealFileSystem())
The pipelines read the library options of Context, which must outlive the PassBuilder.
void registerPipelineParsingCallback(const std::function< bool(StringRef Name, CGSCCPassManager &, ArrayRef< PipelineElement >)> &C)
{{@ Register pipeline parsing callbacks with this pass builder instance.
LLVM_ABI void registerModuleAnalyses(ModuleAnalysisManager &MAM)
Registers all available module analysis passes.
LLVM_ABI std::optional< PrintPipelinePassesFormat > getPrintPipelinePasses() const
The format -print-pipeline-passes requests, or std::nullopt if it is not given.
LLVM_ABI void registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM)
Registers all available CGSCC analysis passes.
static LLVM_ABI Expected< bool > parseSinglePassOption(StringRef Params, StringRef OptionName, StringRef PassName)
Handle passes only accept one bool-valued parameter.
LLVM_ABI void registerMachineFunctionAnalyses(MachineFunctionAnalysisManager &MFAM)
Registers all available machine function analysis passes.
LLVM_ABI void registerParseTopLevelPipelineCallback(const std::function< bool(ModulePassManager &, ArrayRef< PipelineElement >)> &C)
Register a callback for a top-level pipeline entry.
LLVM_ABI void registerFunctionAnalyses(FunctionAnalysisManager &FAM)
Registers all available function analysis passes.
This class manages callbacks registration, as well as provides a way for PassInstrumentation to pass ...
LLVM_ATTRIBUTE_MINSIZE std::enable_if_t<!std::is_same_v< PassT, PassManager > > addPass(PassT &&Pass)
Tunable parameters for passes in the default pipelines.
Definition PassBuilder.h:46
bool SLPVectorization
Tuning option to enable/disable slp loop vectorization, set based on opt level.
Definition PassBuilder.h:67
bool LoopVectorization
Tuning option to enable/disable loop vectorization, set based on opt level.
Definition PassBuilder.h:63
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition Analysis.h:115
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition StringRef.h:736
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
Definition StringRef.h:490
std::string str() const
Get the contents as an std::string.
Definition StringRef.h:222
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition StringRef.h:258
constexpr bool empty() const
Check if the string is empty.
Definition StringRef.h:141
char front() const
Get the first character in the string.
Definition StringRef.h:147
bool consume_front(char Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
Definition StringRef.h:661
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
A table of densely packed, null-terminated strings indexed by offset.
Definition StringTable.h:34
constexpr Iterator begin() const
constexpr Iterator end() const
Primary interface to the complete machine description for the target machine.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
self_iterator getIterator()
Definition ilist_node.h:123
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
Interfaces for registering analysis passes, producing common pass manager configurations,...
Abstract Attribute helper functions.
Definition Attributor.h:165
std::optional< CodeGenOptLevel > getLevel(int OL)
Get the Level identified by the integer OL.
Definition CodeGen.h:238
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:83
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
DropTestKind
Specifies how to drop type tests.
@ All
Drop only llvm.assumes using type test value.
This is an optimization pass for GlobalISel generic memory operations.
OuterAnalysisManagerProxy< CGSCCAnalysisManager, Function > CGSCCAnalysisManagerFunctionProxy
A proxy from a CGSCCAnalysisManager to a Function.
OuterAnalysisManagerProxy< ModuleAnalysisManager, MachineFunction > ModuleAnalysisManagerMachineFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
ModuleToFunctionPassAdaptor createModuleToFunctionPassAdaptor(FunctionPassT &&Pass, bool EagerlyInvalidate=false)
A function to deduce a function pass type and wrap it in the templated adaptor.
DevirtSCCRepeatedPass createDevirtSCCRepeatedPass(CGSCCPassT &&Pass, int MaxIterations)
A function to deduce a function pass type and wrap it in the templated adaptor.
OuterAnalysisManagerProxy< ModuleAnalysisManager, Function > ModuleAnalysisManagerFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition Error.cpp:94
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
@ O1
Optimize quickly without destroying debuggability.
@ O0
Disable as many optimizations as possible.
@ O3
Optimize for fast execution as much as possible.
@ O2
Optimize for fast execution as much as possible without triggering significant incremental compile ti...
InnerAnalysisManagerProxy< LoopAnalysisManager, Function > LoopAnalysisManagerFunctionProxy
A proxy from a LoopAnalysisManager to a Function.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition Error.h:1321
PassManager< LazyCallGraph::SCC, CGSCCAnalysisManager, LazyCallGraph &, CGSCCUpdateResult & > CGSCCPassManager
The CGSCC pass manager.
AnalysisManager< LazyCallGraph::SCC, LazyCallGraph & > CGSCCAnalysisManager
The CGSCC analysis manager.
AnalysisManager< Loop, LoopStandardAnalysisResults & > LoopAnalysisManager
The loop analysis manager.
PassManager< Loop, LoopAnalysisManager, LoopStandardAnalysisResults &, LPMUpdater & > LoopPassManager
The Loop pass manager.
ModuleToPostOrderCGSCCPassAdaptor createModuleToPostOrderCGSCCPassAdaptor(CGSCCPassT &&Pass)
A function to deduce a function pass type and wrap it in the templated adaptor.
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
FunctionToLoopPassAdaptor createFunctionToLoopPassAdaptor(LoopPassT &&Pass, bool UseMemorySSA=false)
A function to deduce a loop pass type and wrap it in the templated adaptor.
CGSCCToFunctionPassAdaptor createCGSCCToFunctionPassAdaptor(FunctionPassT &&Pass, bool EagerlyInvalidate=false, bool NoRerun=false)
A function to deduce a function pass type and wrap it in the templated adaptor.
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
FunctionToMachineFunctionPassAdaptor createFunctionToMachineFunctionPassAdaptor(MachineFunctionPassT &&Pass)
PassManager< Module > ModulePassManager
Convenience typedef for a pass manager over modules.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
InnerAnalysisManagerProxy< MachineFunctionAnalysisManager, Function > MachineFunctionAnalysisManagerFunctionProxy
OuterAnalysisManagerProxy< FunctionAnalysisManager, Loop, LoopStandardAnalysisResults & > FunctionAnalysisManagerLoopProxy
A proxy from a FunctionAnalysisManager to a Loop.
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
Definition Error.h:340
support::detail::RepeatAdapter< T > fmt_repeat(T &&Item, size_t Count)
OuterAnalysisManagerProxy< ModuleAnalysisManager, LazyCallGraph::SCC, LazyCallGraph & > ModuleAnalysisManagerCGSCCProxy
A proxy from a ModuleAnalysisManager to an SCC.
InnerAnalysisManagerProxy< MachineFunctionAnalysisManager, Module > MachineFunctionAnalysisManagerModuleProxy
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
Definition InstrProf.h:145
InnerAnalysisManagerProxy< CGSCCAnalysisManager, Module > CGSCCAnalysisManagerModuleProxy
A proxy from a CGSCCAnalysisManager to a Module.
PassManager< Function > FunctionPassManager
Convenience typedef for a pass manager over functions.
MFPropsModifier(PassT &P, MachineFunction &MF) -> MFPropsModifier< PassT >
LLVM_ABI void printFormattedPipelinePasses(raw_ostream &OS, StringRef Pipeline, PrintPipelinePassesFormat Format=PrintPipelinePassesFormat::Text)
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1933
PassManager< MachineFunction > MachineFunctionPassManager
Convenience typedef for a pass manager over functions.
LLVM_ABI bool applyDebugifyMetadataToMachineFunction(DIBuilder &DIB, Function &F, llvm::function_ref< MachineFunction *(Function &)> GetMF)
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI std::optional< AllocTokenMode > getAllocTokenModeFromString(StringRef Name)
Returns the AllocTokenMode from its canonical string name; if an invalid name was provided returns nu...
@ End
Run the machine verifier once, at the end of the pipeline.
Definition CodeGen.h:267
PrintPipelinePassesFormat
@ Detailed
Hash with opcode only.
@ CallTargetIgnored
Hash with opcode and operands.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition MIRParser.h:39
@ Enable
Enable colors.
Definition WithColor.h:47
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Definition Error.cpp:177
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:878
#define N
A special type used by analysis passes to provide an address that identifies that particular analysis...
Definition Analysis.h:29
A set of parameters to control various transforms performed by GVN pass.
Definition GVN.h:34
HardwareLoopOptions & setForceNested(bool Force)
HardwareLoopOptions & setDecrement(unsigned Count)
HardwareLoopOptions & setForceGuard(bool Force)
HardwareLoopOptions & setForce(bool Force)
HardwareLoopOptions & setCounterBitwidth(unsigned Width)
HardwareLoopOptions & setForcePhi(bool Force)
A set of parameters to control various transforms performed by IPSCCP pass.
Definition SCCP.h:35
A set of parameters used to control various transforms performed by the LoopUnroll pass.
LoopUnrollOptions & setPeeling(bool Peeling)
Enables or disables loop peeling.
LoopUnrollOptions & setOptLevel(int O)
LoopUnrollOptions & setPartial(bool Partial)
Enables or disables partial unrolling.
LoopUnrollOptions & setFullUnrollMaxCount(unsigned O)
LoopUnrollOptions & setPrepareForLTO(bool V)
LoopUnrollOptions & setUpperBound(bool UpperBound)
Enables or disables the use of trip count upper bound in loop unrolling.
LoopUnrollOptions & setRuntime(bool Runtime)
Enables or disables unrolling of loops with runtime trip count.
LoopUnrollOptions & setProfileBasedPeeling(int O)
LoopVectorizeOptions & setVectorizeOnlyWhenForced(bool Value)
LoopVectorizeOptions & setInterleaveOnlyWhenForced(bool Value)
A CRTP mix-in for passes that can be skipped.