LLVM 23.0.0git
PassBuilder.cpp
Go to the documentation of this file.
1//===- Parsing and selection of pass pipelines ----------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8/// \file
9///
10/// This file provides the implementation of the PassBuilder based on our
11/// static pass registry as well as related functionality. It also provides
12/// helpers to aid in analyzing, debugging, and testing passes and pass
13/// pipelines.
14///
15//===----------------------------------------------------------------------===//
16
33#include "llvm/Analysis/DDG.h"
54#include "llvm/Analysis/Lint.h"
116#include "llvm/CodeGen/KCFI.h"
152#include "llvm/CodeGen/PEI.h"
197#include "llvm/IR/DebugInfo.h"
198#include "llvm/IR/Dominators.h"
199#include "llvm/IR/PassManager.h"
201#include "llvm/IR/Verifier.h"
204#include "llvm/Support/CodeGen.h"
206#include "llvm/Support/Debug.h"
207#include "llvm/Support/Error.h"
211#include "llvm/Support/Regex.h"
406#include <optional>
407
408using namespace llvm;
409
413 "print-pipeline-passes", cl::ValueOptional,
414 cl::desc(
415 "Print string describing the pipeline (best-effort only).\n"
416 " - =text\tPrint a '-passes' compatible string describing the "
417 "pipeline.\n"
418 " - =tree\tPrint a tree-like structure describing the pipeline."));
419
421 cl::Option &O, StringRef ArgName, StringRef Arg,
422 std::optional<PrintPipelinePassesFormat> &Val) {
423 std::optional<PrintPipelinePassesFormat> Format =
428 .Default(std::nullopt);
429
430 if (!Format)
431 return O.error(formatv(
432 "'{0}' value invalid for print-pipeline-passes argument!", Arg));
433
434 Val = Format;
435 return false;
436}
437
440 switch (Format) {
442 OS << Pipeline;
443 break;
445 int IndentLevel = 0;
446 for (char C : Pipeline) {
447 switch (C) {
448 case '(':
449 ++IndentLevel;
450 OS << formatv("\n{0}", fmt_repeat(" ", IndentLevel));
451 break;
452 case ')':
453 --IndentLevel;
454 assert(IndentLevel >= 0 && "Invalid pipeline string!");
455 break;
456 case ',':
457 OS << formatv("\n{0}", fmt_repeat(" ", IndentLevel));
458 break;
459 default:
460 OS << C;
461 }
462 }
463 break;
464 }
465 }
466}
467
468AnalysisKey NoOpModuleAnalysis::Key;
469AnalysisKey NoOpCGSCCAnalysis::Key;
470AnalysisKey NoOpFunctionAnalysis::Key;
471AnalysisKey NoOpLoopAnalysis::Key;
472
473namespace {
474
475bool applyMIRDebugify(DIBuilder &DIB, Function &F, ModuleAnalysisManager &AM) {
478 .getManager();
479
481 DIB, F, [&](Function &Func) -> MachineFunction * {
483 FAM.getCachedResult<MachineFunctionAnalysis>(Func);
484 return MFA ? &MFA->getMF() : nullptr;
485 });
486}
487
488// A pass for testing message reporting of -verify-each failures.
489// DO NOT USE THIS EXCEPT FOR TESTING!
490class TriggerVerifierErrorPass
491 : public OptionalPassInfoMixin<TriggerVerifierErrorPass> {
492public:
493 PreservedAnalyses run(Module &M, ModuleAnalysisManager &) {
494 // Intentionally break the Module by creating an alias without setting the
495 // aliasee.
496 auto *PtrTy = PointerType::getUnqual(M.getContext());
497 GlobalAlias::create(PtrTy, PtrTy->getAddressSpace(),
498 GlobalValue::LinkageTypes::InternalLinkage,
499 "__bad_alias", nullptr, &M);
501 }
502
503 PreservedAnalyses run(Function &F, FunctionAnalysisManager &) {
504 // Intentionally break the Function by inserting a terminator
505 // instruction in the middle of a basic block.
506 BasicBlock &BB = F.getEntryBlock();
507 new UnreachableInst(F.getContext(), BB.getTerminator()->getIterator());
509 }
510
511 PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &) {
512 // Intentionally create a virtual register and set NoVRegs property.
513 auto &MRI = MF.getRegInfo();
515 MF.getProperties().setNoVRegs();
516 return PreservedAnalyses::all();
517 }
518
519 static StringRef name() { return "TriggerVerifierErrorPass"; }
520};
521
522// A pass requires all MachineFunctionProperties.
523// DO NOT USE THIS EXCEPT FOR TESTING!
524class RequireAllMachineFunctionPropertiesPass
525 : public OptionalPassInfoMixin<RequireAllMachineFunctionPropertiesPass> {
526public:
527 PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &) {
528 MFPropsModifier _(*this, MF);
530 }
531
532 static MachineFunctionProperties getRequiredProperties() {
533 return MachineFunctionProperties()
534 .setFailedISel()
535 .setFailsVerification()
536 .setIsSSA()
537 .setLegalized()
538 .setNoPHIs()
539 .setNoVRegs()
540 .setRegBankSelected()
541 .setSelected()
542 .setTiedOpsRewritten()
543 .setTracksDebugUserValues()
544 .setTracksLiveness();
545 }
546 static StringRef name() { return "RequireAllMachineFunctionPropertiesPass"; }
547};
548
549} // namespace
550
551static std::optional<OptimizationLevel> parseOptLevel(StringRef S) {
552 if (S == "Os" || S == "Oz")
554 Twine("The optimization level \"") + S +
555 "\" is no longer supported. Use O2 in conjunction with the " +
556 (S == "Os" ? "optsize" : "minsize") + " attribute instead.");
557
559 .Case("O0", OptimizationLevel::O0)
563 .Default(std::nullopt);
564}
565
567 std::optional<OptimizationLevel> OptLevel = parseOptLevel(S);
568 if (OptLevel)
569 return *OptLevel;
571 formatv("invalid optimization level '{}'", S).str(),
573}
574
576 std::optional<PGOOptions> PGOOpt,
579 : TM(TM), PTO(PTO), 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
887/// Parser of parameters for LoopUnroll pass.
888Expected<LoopUnrollOptions> parseLoopUnrollOptions(StringRef Params) {
889 LoopUnrollOptions UnrollOpts;
890 while (!Params.empty()) {
891 StringRef ParamName;
892 std::tie(ParamName, Params) = Params.split(';');
893 std::optional<OptimizationLevel> OptLevel = parseOptLevel(ParamName);
894 if (OptLevel) {
895 UnrollOpts.setOptLevel(OptLevel->getSpeedupLevel());
896 continue;
897 }
898 if (ParamName.consume_front("full-unroll-max=")) {
899 int Count;
900 if (ParamName.getAsInteger(0, Count))
902 formatv("invalid LoopUnrollPass parameter '{}'", ParamName).str(),
904 UnrollOpts.setFullUnrollMaxCount(Count);
905 continue;
906 }
907
908 bool Enable = !ParamName.consume_front("no-");
909 if (ParamName == "partial") {
910 UnrollOpts.setPartial(Enable);
911 } else if (ParamName == "peeling") {
912 UnrollOpts.setPeeling(Enable);
913 } else if (ParamName == "profile-peeling") {
914 UnrollOpts.setProfileBasedPeeling(Enable);
915 } else if (ParamName == "runtime") {
916 UnrollOpts.setRuntime(Enable);
917 } else if (ParamName == "upperbound") {
918 UnrollOpts.setUpperBound(Enable);
919 } else {
921 formatv("invalid LoopUnrollPass parameter '{}'", ParamName).str(),
923 }
924 }
925 return UnrollOpts;
926}
927
928Expected<bool> parseGlobalDCEPassOptions(StringRef Params) {
930 Params, "vfe-linkage-unit-visibility", "GlobalDCE");
931}
932
933Expected<bool> parseCGProfilePassOptions(StringRef Params) {
934 return PassBuilder::parseSinglePassOption(Params, "in-lto-post-link",
935 "CGProfile");
936}
937
938Expected<bool> parseInlinerPassOptions(StringRef Params) {
939 return PassBuilder::parseSinglePassOption(Params, "only-mandatory",
940 "InlinerPass");
941}
942
943Expected<bool> parseCoroSplitPassOptions(StringRef Params) {
944 return PassBuilder::parseSinglePassOption(Params, "reuse-storage",
945 "CoroSplitPass");
946}
947
948Expected<bool> parsePostOrderFunctionAttrsPassOptions(StringRef Params) {
950 Params, "skip-non-recursive-function-attrs", "PostOrderFunctionAttrs");
951}
952
953Expected<bool> parseEarlyCSEPassOptions(StringRef Params) {
954 return PassBuilder::parseSinglePassOption(Params, "memssa", "EarlyCSE");
955}
956
957Expected<bool> parseEntryExitInstrumenterPassOptions(StringRef Params) {
958 return PassBuilder::parseSinglePassOption(Params, "post-inline",
959 "EntryExitInstrumenter");
960}
961
962Expected<bool> parseDropUnnecessaryAssumesPassOptions(StringRef Params) {
963 return PassBuilder::parseSinglePassOption(Params, "drop-deref",
964 "DropUnnecessaryAssumes");
965}
966
967Expected<bool> parseLoopExtractorPassOptions(StringRef Params) {
968 return PassBuilder::parseSinglePassOption(Params, "single", "LoopExtractor");
969}
970
971Expected<bool> parseLowerMatrixIntrinsicsPassOptions(StringRef Params) {
972 return PassBuilder::parseSinglePassOption(Params, "minimal",
973 "LowerMatrixIntrinsics");
974}
975
976Expected<IRNormalizerOptions> parseIRNormalizerPassOptions(StringRef Params) {
978 while (!Params.empty()) {
979 StringRef ParamName;
980 std::tie(ParamName, Params) = Params.split(';');
981
982 bool Enable = !ParamName.consume_front("no-");
983 if (ParamName == "preserve-order")
984 Result.PreserveOrder = Enable;
985 else if (ParamName == "rename-all")
986 Result.RenameAll = Enable;
987 else if (ParamName == "fold-all") // FIXME: Name mismatch
988 Result.FoldPreOutputs = Enable;
989 else if (ParamName == "reorder-operands")
990 Result.ReorderOperands = Enable;
991 else {
993 formatv("invalid normalize pass parameter '{}'", ParamName).str(),
995 }
996 }
997
998 return Result;
999}
1000
1001Expected<AddressSanitizerOptions> parseASanPassOptions(StringRef Params) {
1003 while (!Params.empty()) {
1004 StringRef ParamName;
1005 std::tie(ParamName, Params) = Params.split(';');
1006
1007 if (ParamName == "kernel") {
1008 Result.CompileKernel = true;
1009 } else if (ParamName == "use-after-scope") {
1010 Result.UseAfterScope = true;
1011 } else {
1013 formatv("invalid AddressSanitizer pass parameter '{}'", ParamName)
1014 .str(),
1016 }
1017 }
1018 return Result;
1019}
1020
1021Expected<HWAddressSanitizerOptions> parseHWASanPassOptions(StringRef Params) {
1023 while (!Params.empty()) {
1024 StringRef ParamName;
1025 std::tie(ParamName, Params) = Params.split(';');
1026
1027 if (ParamName == "recover") {
1028 Result.Recover = true;
1029 } else if (ParamName == "kernel") {
1030 Result.CompileKernel = true;
1031 } else {
1033 formatv("invalid HWAddressSanitizer pass parameter '{}'", ParamName)
1034 .str(),
1036 }
1037 }
1038 return Result;
1039}
1040
1042parseDropTypeTestsPassOptions(StringRef Params) {
1044 while (!Params.empty()) {
1045 StringRef ParamName;
1046 std::tie(ParamName, Params) = Params.split(';');
1047
1048 if (ParamName == "all") {
1050 } else if (ParamName == "assume") {
1052 } else {
1054 formatv("invalid DropTypeTestsPass parameter '{}'", ParamName).str(),
1056 }
1057 }
1058 return Result;
1059}
1060
1061Expected<EmbedBitcodeOptions> parseEmbedBitcodePassOptions(StringRef Params) {
1063 while (!Params.empty()) {
1064 StringRef ParamName;
1065 std::tie(ParamName, Params) = Params.split(';');
1066
1067 if (ParamName == "thinlto") {
1068 Result.IsThinLTO = true;
1069 } else if (ParamName == "emit-summary") {
1070 Result.EmitLTOSummary = true;
1071 } else {
1073 formatv("invalid EmbedBitcode pass parameter '{}'", ParamName).str(),
1075 }
1076 }
1077 return Result;
1078}
1079
1081parseLowerAllowCheckPassOptions(StringRef Params) {
1083 while (!Params.empty()) {
1084 StringRef ParamName;
1085 std::tie(ParamName, Params) = Params.split(';');
1086
1087 // Format is <cutoffs[1,2,3]=70000;cutoffs[5,6,8]=90000>
1088 //
1089 // Parsing allows duplicate indices (last one takes precedence).
1090 // It would technically be in spec to specify
1091 // cutoffs[0]=70000,cutoffs[1]=90000,cutoffs[0]=80000,...
1092 if (ParamName.starts_with("cutoffs[")) {
1093 StringRef IndicesStr;
1094 StringRef CutoffStr;
1095
1096 std::tie(IndicesStr, CutoffStr) = ParamName.split("]=");
1097 // cutoffs[1,2,3
1098 // 70000
1099
1100 int cutoff;
1101 if (CutoffStr.getAsInteger(0, cutoff))
1103 formatv("invalid LowerAllowCheck pass cutoffs parameter '{}' ({})",
1104 CutoffStr, Params)
1105 .str(),
1107
1108 if (!IndicesStr.consume_front("cutoffs[") || IndicesStr == "")
1110 formatv("invalid LowerAllowCheck pass index parameter '{}' ({})",
1111 IndicesStr, CutoffStr)
1112 .str(),
1114
1115 while (IndicesStr != "") {
1116 StringRef firstIndexStr;
1117 std::tie(firstIndexStr, IndicesStr) = IndicesStr.split('|');
1118
1119 unsigned int index;
1120 if (firstIndexStr.getAsInteger(0, index))
1122 formatv(
1123 "invalid LowerAllowCheck pass index parameter '{}' ({}) {}",
1124 firstIndexStr, IndicesStr)
1125 .str(),
1127
1128 // In the common case (sequentially increasing indices), we will issue
1129 // O(n) resize requests. We assume the underlying data structure has
1130 // O(1) runtime for each added element.
1131 if (index >= Result.cutoffs.size())
1132 Result.cutoffs.resize(index + 1, 0);
1133
1134 Result.cutoffs[index] = cutoff;
1135 }
1136 } else if (ParamName.starts_with("runtime_check")) {
1137 StringRef ValueString;
1138 std::tie(std::ignore, ValueString) = ParamName.split("=");
1139 int runtime_check;
1140 if (ValueString.getAsInteger(0, runtime_check)) {
1142 formatv("invalid LowerAllowCheck pass runtime_check parameter '{}' "
1143 "({})",
1144 ValueString, Params)
1145 .str(),
1147 }
1148 Result.runtime_check = runtime_check;
1149 } else {
1151 formatv("invalid LowerAllowCheck pass parameter '{}'", ParamName)
1152 .str(),
1154 }
1155 }
1156
1157 return Result;
1158}
1159
1160Expected<MemorySanitizerOptions> parseMSanPassOptions(StringRef Params) {
1162 while (!Params.empty()) {
1163 StringRef ParamName;
1164 std::tie(ParamName, Params) = Params.split(';');
1165
1166 if (ParamName == "recover") {
1167 Result.Recover = true;
1168 } else if (ParamName == "kernel") {
1169 Result.Kernel = true;
1170 } else if (ParamName.consume_front("track-origins=")) {
1171 if (ParamName.getAsInteger(0, Result.TrackOrigins))
1173 formatv("invalid argument to MemorySanitizer pass track-origins "
1174 "parameter: '{}'",
1175 ParamName)
1176 .str(),
1178 } else if (ParamName == "eager-checks") {
1179 Result.EagerChecks = true;
1180 } else {
1182 formatv("invalid MemorySanitizer pass parameter '{}'", ParamName)
1183 .str(),
1185 }
1186 }
1187 return Result;
1188}
1189
1190Expected<AllocTokenOptions> parseAllocTokenPassOptions(StringRef Params) {
1192 while (!Params.empty()) {
1193 StringRef ParamName;
1194 std::tie(ParamName, Params) = Params.split(';');
1195
1196 if (ParamName.consume_front("mode=")) {
1197 if (auto Mode = getAllocTokenModeFromString(ParamName))
1198 Result.Mode = *Mode;
1199 else
1201 formatv("invalid argument to AllocToken pass mode "
1202 "parameter: '{}'",
1203 ParamName)
1204 .str(),
1206 } else {
1208 formatv("invalid AllocToken pass parameter '{}'", ParamName).str(),
1210 }
1211 }
1212 return Result;
1213}
1214
1215/// Parser of parameters for SimplifyCFG pass.
1216Expected<SimplifyCFGOptions> parseSimplifyCFGOptions(StringRef Params) {
1218 while (!Params.empty()) {
1219 StringRef ParamName;
1220 std::tie(ParamName, Params) = Params.split(';');
1221
1222 bool Enable = !ParamName.consume_front("no-");
1223 if (ParamName == "speculate-blocks") {
1224 Result.speculateBlocks(Enable);
1225 } else if (ParamName == "simplify-cond-branch") {
1226 Result.setSimplifyCondBranch(Enable);
1227 } else if (ParamName == "forward-switch-cond") {
1228 Result.forwardSwitchCondToPhi(Enable);
1229 } else if (ParamName == "switch-range-to-icmp") {
1230 Result.convertSwitchRangeToICmp(Enable);
1231 } else if (ParamName == "switch-to-arithmetic") {
1232 Result.convertSwitchToArithmetic(Enable);
1233 } else if (ParamName == "switch-to-lookup") {
1234 Result.convertSwitchToLookupTable(Enable);
1235 } else if (ParamName == "keep-loops") {
1236 Result.needCanonicalLoops(Enable);
1237 } else if (ParamName == "hoist-common-insts") {
1238 Result.hoistCommonInsts(Enable);
1239 } else if (ParamName == "hoist-loads-stores-with-cond-faulting") {
1240 Result.hoistLoadsStoresWithCondFaulting(Enable);
1241 } else if (ParamName == "sink-common-insts") {
1242 Result.sinkCommonInsts(Enable);
1243 } else if (ParamName == "speculate-unpredictables") {
1244 Result.speculateUnpredictables(Enable);
1245 } else if (Enable && ParamName.consume_front("bonus-inst-threshold=")) {
1246 APInt BonusInstThreshold;
1247 if (ParamName.getAsInteger(0, BonusInstThreshold))
1249 formatv("invalid argument to SimplifyCFG pass bonus-threshold "
1250 "parameter: '{}'",
1251 ParamName)
1252 .str(),
1254 Result.bonusInstThreshold(BonusInstThreshold.getSExtValue());
1255 } else {
1257 formatv("invalid SimplifyCFG pass parameter '{}'", ParamName).str(),
1259 }
1260 }
1261 return Result;
1262}
1263
1264Expected<InstCombineOptions> parseInstCombineOptions(StringRef Params) {
1266 // When specifying "instcombine" in -passes enable fix-point verification by
1267 // default, as this is what most tests should use.
1268 Result.setVerifyFixpoint(true);
1269 while (!Params.empty()) {
1270 StringRef ParamName;
1271 std::tie(ParamName, Params) = Params.split(';');
1272
1273 bool Enable = !ParamName.consume_front("no-");
1274 if (ParamName == "verify-fixpoint") {
1275 Result.setVerifyFixpoint(Enable);
1276 } else if (Enable && ParamName.consume_front("max-iterations=")) {
1277 APInt MaxIterations;
1278 if (ParamName.getAsInteger(0, MaxIterations))
1280 formatv("invalid argument to InstCombine pass max-iterations "
1281 "parameter: '{}'",
1282 ParamName)
1283 .str(),
1285 Result.setMaxIterations((unsigned)MaxIterations.getZExtValue());
1286 } else {
1288 formatv("invalid InstCombine pass parameter '{}'", ParamName).str(),
1290 }
1291 }
1292 return Result;
1293}
1294
1295/// Parser of parameters for LoopVectorize pass.
1296Expected<LoopVectorizeOptions> parseLoopVectorizeOptions(StringRef Params) {
1298 while (!Params.empty()) {
1299 StringRef ParamName;
1300 std::tie(ParamName, Params) = Params.split(';');
1301
1302 bool Enable = !ParamName.consume_front("no-");
1303 if (ParamName == "interleave-forced-only") {
1305 } else if (ParamName == "vectorize-forced-only") {
1307 } else {
1309 formatv("invalid LoopVectorize parameter '{}'", ParamName).str(),
1311 }
1312 }
1313 return Opts;
1314}
1315
1316Expected<std::pair<bool, bool>> parseLoopUnswitchOptions(StringRef Params) {
1317 std::pair<bool, bool> Result = {false, true};
1318 while (!Params.empty()) {
1319 StringRef ParamName;
1320 std::tie(ParamName, Params) = Params.split(';');
1321
1322 bool Enable = !ParamName.consume_front("no-");
1323 if (ParamName == "nontrivial") {
1324 Result.first = Enable;
1325 } else if (ParamName == "trivial") {
1326 Result.second = Enable;
1327 } else {
1329 formatv("invalid LoopUnswitch pass parameter '{}'", ParamName).str(),
1331 }
1332 }
1333 return Result;
1334}
1335
1336Expected<LICMOptions> parseLICMOptions(StringRef Params) {
1338 while (!Params.empty()) {
1339 StringRef ParamName;
1340 std::tie(ParamName, Params) = Params.split(';');
1341
1342 bool Enable = !ParamName.consume_front("no-");
1343 if (ParamName == "allowspeculation") {
1344 Result.AllowSpeculation = Enable;
1345 } else {
1347 formatv("invalid LICM pass parameter '{}'", ParamName).str(),
1349 }
1350 }
1351 return Result;
1352}
1353
1354struct LoopRotateOptions {
1355 bool EnableHeaderDuplication = true;
1356 bool PrepareForLTO = false;
1357 bool CheckExitCount = false;
1358};
1359
1360Expected<LoopRotateOptions> parseLoopRotateOptions(StringRef Params) {
1361 LoopRotateOptions Result;
1362 while (!Params.empty()) {
1363 StringRef ParamName;
1364 std::tie(ParamName, Params) = Params.split(';');
1365
1366 bool Enable = !ParamName.consume_front("no-");
1367 if (ParamName == "header-duplication") {
1368 Result.EnableHeaderDuplication = Enable;
1369 } else if (ParamName == "prepare-for-lto") {
1370 Result.PrepareForLTO = Enable;
1371 } else if (ParamName == "check-exit-count") {
1372 Result.CheckExitCount = Enable;
1373 } else {
1375 formatv("invalid LoopRotate pass parameter '{}'", ParamName).str(),
1377 }
1378 }
1379 return Result;
1380}
1381
1382Expected<bool> parseMergedLoadStoreMotionOptions(StringRef Params) {
1383 bool Result = false;
1384 while (!Params.empty()) {
1385 StringRef ParamName;
1386 std::tie(ParamName, Params) = Params.split(';');
1387
1388 bool Enable = !ParamName.consume_front("no-");
1389 if (ParamName == "split-footer-bb") {
1390 Result = Enable;
1391 } else {
1393 formatv("invalid MergedLoadStoreMotion pass parameter '{}'",
1394 ParamName)
1395 .str(),
1397 }
1398 }
1399 return Result;
1400}
1401
1402Expected<GVNOptions> parseGVNOptions(StringRef Params) {
1404 while (!Params.empty()) {
1405 StringRef ParamName;
1406 std::tie(ParamName, Params) = Params.split(';');
1407
1408 bool Enable = !ParamName.consume_front("no-");
1409 if (ParamName == "scalar-pre") {
1410 Result.setScalarPRE(Enable);
1411 } else if (ParamName == "load-pre") {
1412 Result.setLoadPRE(Enable);
1413 } else if (ParamName == "split-backedge-load-pre") {
1414 Result.setLoadPRESplitBackedge(Enable);
1415 } else if (ParamName == "memdep") {
1416 // MemDep and MemorySSA are mutually exclusive.
1417 Result.setMemDep(Enable);
1418 Result.setMemorySSA(!Enable);
1419 } else if (ParamName == "memoryssa") {
1420 // MemDep and MemorySSA are mutually exclusive.
1421 Result.setMemorySSA(Enable);
1422 Result.setMemDep(!Enable);
1423 } else {
1425 formatv("invalid GVN pass parameter '{}'", ParamName).str(),
1427 }
1428 }
1429 return Result;
1430}
1431
1432Expected<IPSCCPOptions> parseIPSCCPOptions(StringRef Params) {
1434 while (!Params.empty()) {
1435 StringRef ParamName;
1436 std::tie(ParamName, Params) = Params.split(';');
1437
1438 bool Enable = !ParamName.consume_front("no-");
1439 if (ParamName == "func-spec")
1440 Result.setFuncSpec(Enable);
1441 else
1443 formatv("invalid IPSCCP pass parameter '{}'", ParamName).str(),
1445 }
1446 return Result;
1447}
1448
1449Expected<ScalarizerPassOptions> parseScalarizerOptions(StringRef Params) {
1451 while (!Params.empty()) {
1452 StringRef ParamName;
1453 std::tie(ParamName, Params) = Params.split(';');
1454
1455 if (ParamName.consume_front("min-bits=")) {
1456 if (ParamName.getAsInteger(0, Result.ScalarizeMinBits)) {
1458 formatv("invalid argument to Scalarizer pass min-bits "
1459 "parameter: '{}'",
1460 ParamName)
1461 .str(),
1463 }
1464
1465 continue;
1466 }
1467
1468 bool Enable = !ParamName.consume_front("no-");
1469 if (ParamName == "load-store")
1470 Result.ScalarizeLoadStore = Enable;
1471 else if (ParamName == "variable-insert-extract")
1472 Result.ScalarizeVariableInsertExtract = Enable;
1473 else {
1475 formatv("invalid Scalarizer pass parameter '{}'", ParamName).str(),
1477 }
1478 }
1479
1480 return Result;
1481}
1482
1483Expected<SROAOptions> parseSROAOptions(StringRef Params) {
1485 bool SawCFGOption = false;
1486 while (!Params.empty()) {
1487 StringRef ParamName;
1488 std::tie(ParamName, Params) = Params.split(';');
1489
1490 if (ParamName == "modify-cfg") {
1491 if (SawCFGOption)
1492 return make_error<StringError>("multiple SROA CFG options specified",
1495 SawCFGOption = true;
1496 } else if (ParamName == "preserve-cfg") {
1497 if (SawCFGOption)
1498 return make_error<StringError>("multiple SROA CFG options specified",
1501 SawCFGOption = true;
1502 } else if (ParamName == "aggregate-to-vector") {
1503 Result.AggregateToVector = true;
1504 } else {
1506 formatv("invalid SROA pass parameter '{}' (expected preserve-cfg, "
1507 "modify-cfg, or aggregate-to-vector)",
1508 ParamName)
1509 .str(),
1511 }
1512 }
1513 return Result;
1514}
1515
1517parseStackLifetimeOptions(StringRef Params) {
1519 while (!Params.empty()) {
1520 StringRef ParamName;
1521 std::tie(ParamName, Params) = Params.split(';');
1522
1523 if (ParamName == "may") {
1525 } else if (ParamName == "must") {
1527 } else {
1529 formatv("invalid StackLifetime parameter '{}'", ParamName).str(),
1531 }
1532 }
1533 return Result;
1534}
1535
1536Expected<bool> parseDependenceAnalysisPrinterOptions(StringRef Params) {
1537 return PassBuilder::parseSinglePassOption(Params, "normalized-results",
1538 "DependenceAnalysisPrinter");
1539}
1540
1541Expected<bool> parseSeparateConstOffsetFromGEPPassOptions(StringRef Params) {
1542 return PassBuilder::parseSinglePassOption(Params, "lower-gep",
1543 "SeparateConstOffsetFromGEP");
1544}
1545
1546Expected<bool> parseStructurizeCFGPassOptions(StringRef Params) {
1547 return PassBuilder::parseSinglePassOption(Params, "skip-uniform-regions",
1548 "StructurizeCFG");
1549}
1550
1552parseFunctionSimplificationPipelineOptions(StringRef Params) {
1553 std::optional<OptimizationLevel> L = parseOptLevel(Params);
1554 if (!L || *L == OptimizationLevel::O0) {
1556 formatv("invalid function-simplification parameter '{}'", Params).str(),
1558 };
1559 return *L;
1560}
1561
1562Expected<bool> parseMemorySSAPrinterPassOptions(StringRef Params) {
1563 return PassBuilder::parseSinglePassOption(Params, "no-ensure-optimized-uses",
1564 "MemorySSAPrinterPass");
1565}
1566
1567Expected<bool> parseSpeculativeExecutionPassOptions(StringRef Params) {
1568 return PassBuilder::parseSinglePassOption(Params, "only-if-divergent-target",
1569 "SpeculativeExecutionPass");
1570}
1571
1572Expected<std::string> parseMemProfUsePassOptions(StringRef Params) {
1573 std::string Result;
1574 while (!Params.empty()) {
1575 StringRef ParamName;
1576 std::tie(ParamName, Params) = Params.split(';');
1577
1578 if (ParamName.consume_front("profile-filename=")) {
1579 Result = ParamName.str();
1580 } else {
1582 formatv("invalid MemProfUse pass parameter '{}'", ParamName).str(),
1584 }
1585 }
1586 return Result;
1587}
1588
1590parseStructuralHashPrinterPassOptions(StringRef Params) {
1591 if (Params.empty())
1593 if (Params == "detailed")
1595 if (Params == "call-target-ignored")
1598 formatv("invalid structural hash printer parameter '{}'", Params).str(),
1600}
1601
1602Expected<bool> parseWinEHPrepareOptions(StringRef Params) {
1603 return PassBuilder::parseSinglePassOption(Params, "demote-catchswitch-only",
1604 "WinEHPreparePass");
1605}
1606
1607Expected<GlobalMergeOptions> parseGlobalMergeOptions(StringRef Params) {
1609 while (!Params.empty()) {
1610 StringRef ParamName;
1611 std::tie(ParamName, Params) = Params.split(';');
1612
1613 bool Enable = !ParamName.consume_front("no-");
1614 if (ParamName == "group-by-use")
1615 Result.GroupByUse = Enable;
1616 else if (ParamName == "ignore-single-use")
1617 Result.IgnoreSingleUse = Enable;
1618 else if (ParamName == "merge-const")
1619 Result.MergeConstantGlobals = Enable;
1620 else if (ParamName == "merge-const-aggressive")
1621 Result.MergeConstAggressive = Enable;
1622 else if (ParamName == "merge-external")
1623 Result.MergeExternal = Enable;
1624 else if (ParamName.consume_front("max-offset=")) {
1625 if (ParamName.getAsInteger(0, Result.MaxOffset))
1627 formatv("invalid GlobalMergePass parameter '{}'", ParamName).str(),
1629 } else {
1631 formatv("invalid global-merge pass parameter '{}'", Params).str(),
1633 }
1634 }
1635 return Result;
1636}
1637
1638Expected<SmallVector<std::string, 0>> parseInternalizeGVs(StringRef Params) {
1639 SmallVector<std::string, 1> PreservedGVs;
1640 while (!Params.empty()) {
1641 StringRef ParamName;
1642 std::tie(ParamName, Params) = Params.split(';');
1643
1644 if (ParamName.consume_front("preserve-gv=")) {
1645 PreservedGVs.push_back(ParamName.str());
1646 } else {
1648 formatv("invalid Internalize pass parameter '{}'", ParamName).str(),
1650 }
1651 }
1652
1653 return Expected<SmallVector<std::string, 0>>(std::move(PreservedGVs));
1654}
1655
1657parseRegAllocFastPassOptions(PassBuilder &PB, StringRef Params) {
1659 while (!Params.empty()) {
1660 StringRef ParamName;
1661 std::tie(ParamName, Params) = Params.split(';');
1662
1663 if (ParamName.consume_front("filter=")) {
1664 std::optional<RegAllocFilterFunc> Filter =
1665 PB.parseRegAllocFilter(ParamName);
1666 if (!Filter) {
1668 formatv("invalid regallocfast register filter '{}'", ParamName)
1669 .str(),
1671 }
1672 Opts.Filter = *Filter;
1673 Opts.FilterName = ParamName;
1674 continue;
1675 }
1676
1677 if (ParamName == "no-clear-vregs") {
1678 Opts.ClearVRegs = false;
1679 continue;
1680 }
1681
1683 formatv("invalid regallocfast pass parameter '{}'", ParamName).str(),
1685 }
1686 return Opts;
1687}
1688
1690parseBoundsCheckingOptions(StringRef Params) {
1692 while (!Params.empty()) {
1693 StringRef ParamName;
1694 std::tie(ParamName, Params) = Params.split(';');
1695 if (ParamName == "trap") {
1696 Options.Rt = std::nullopt;
1697 } else if (ParamName == "rt") {
1698 Options.Rt = {
1699 /*MinRuntime=*/false,
1700 /*MayReturn=*/true,
1701 /*HandlerPreserveAllRegs=*/false,
1702 };
1703 } else if (ParamName == "rt-abort") {
1704 Options.Rt = {
1705 /*MinRuntime=*/false,
1706 /*MayReturn=*/false,
1707 /*HandlerPreserveAllRegs=*/false,
1708 };
1709 } else if (ParamName == "min-rt") {
1710 Options.Rt = {
1711 /*MinRuntime=*/true,
1712 /*MayReturn=*/true,
1713 /*HandlerPreserveAllRegs=*/false,
1714 };
1715 } else if (ParamName == "min-rt-abort") {
1716 Options.Rt = {
1717 /*MinRuntime=*/true,
1718 /*MayReturn=*/false,
1719 /*HandlerPreserveAllRegs=*/false,
1720 };
1721 } else if (ParamName == "merge") {
1722 Options.Merge = true;
1723 } else if (ParamName == "handler-preserve-all-regs") {
1724 if (Options.Rt)
1725 Options.Rt->HandlerPreserveAllRegs = true;
1726 } else {
1727 StringRef ParamEQ;
1728 StringRef Val;
1729 std::tie(ParamEQ, Val) = ParamName.split('=');
1730 int8_t Id;
1731 if (ParamEQ == "guard" && !Val.getAsInteger(0, Id)) {
1732 Options.GuardKind = Id;
1733 } else {
1735 formatv("invalid BoundsChecking pass parameter '{}'", ParamName)
1736 .str(),
1738 }
1739 }
1740 }
1741 return Options;
1742}
1743
1744Expected<CodeGenOptLevel> parseExpandIRInstsOptions(StringRef Param) {
1745 if (Param.empty())
1746 return CodeGenOptLevel::None;
1747
1748 // Parse a CodeGenOptLevel, e.g. "O1", "O2", "O3".
1749 auto [Prefix, Digit] = Param.split('O');
1750
1751 uint8_t N;
1752 if (!Prefix.empty() || Digit.getAsInteger(10, N))
1753 return createStringError("invalid expand-ir-insts pass parameter '%s'",
1754 Param.str().c_str());
1755
1756 std::optional<CodeGenOptLevel> Level = CodeGenOpt::getLevel(N);
1757 if (!Level.has_value())
1758 return createStringError(
1759 "invalid optimization level for expand-ir-insts pass: %s",
1760 Digit.str().c_str());
1761
1762 return *Level;
1763}
1764
1766parseRegAllocGreedyFilterFunc(PassBuilder &PB, StringRef Params) {
1767 if (Params.empty() || Params == "all")
1768 return RAGreedyPass::Options();
1769
1770 std::optional<RegAllocFilterFunc> Filter = PB.parseRegAllocFilter(Params);
1771 if (Filter)
1772 return RAGreedyPass::Options{*Filter, Params};
1773
1775 formatv("invalid regallocgreedy register filter '{}'", Params).str(),
1777}
1778
1779Expected<bool> parseMachineSinkingPassOptions(StringRef Params) {
1780 return PassBuilder::parseSinglePassOption(Params, "enable-sink-fold",
1781 "MachineSinkingPass");
1782}
1783
1784Expected<bool> parseMachineBlockPlacementPassOptions(StringRef Params) {
1785 bool AllowTailMerge = true;
1786 if (!Params.empty()) {
1787 AllowTailMerge = !Params.consume_front("no-");
1788 if (Params != "tail-merge")
1790 formatv("invalid MachineBlockPlacementPass parameter '{}'", Params)
1791 .str(),
1793 }
1794 return AllowTailMerge;
1795}
1796
1797Expected<bool> parseVirtRegRewriterPassOptions(StringRef Params) {
1798 bool ClearVirtRegs = true;
1799 if (!Params.empty()) {
1800 ClearVirtRegs = !Params.consume_front("no-");
1801 if (Params != "clear-vregs")
1803 formatv("invalid VirtRegRewriter pass parameter '{}'", Params).str(),
1805 }
1806 return ClearVirtRegs;
1807}
1808
1809struct FatLTOOptions {
1810 OptimizationLevel OptLevel;
1811 bool ThinLTO = false;
1812 bool EmitSummary = false;
1813};
1814
1815Expected<FatLTOOptions> parseFatLTOOptions(StringRef Params) {
1816 FatLTOOptions Result;
1817 bool HaveOptLevel = false;
1818 while (!Params.empty()) {
1819 StringRef ParamName;
1820 std::tie(ParamName, Params) = Params.split(';');
1821
1822 if (ParamName == "thinlto") {
1823 Result.ThinLTO = true;
1824 } else if (ParamName == "emit-summary") {
1825 Result.EmitSummary = true;
1826 } else if (std::optional<OptimizationLevel> OptLevel =
1827 parseOptLevel(ParamName)) {
1828 Result.OptLevel = *OptLevel;
1829 HaveOptLevel = true;
1830 } else {
1832 formatv("invalid fatlto-pre-link pass parameter '{}'", ParamName)
1833 .str(),
1835 }
1836 }
1837 if (!HaveOptLevel)
1839 "missing optimization level for fatlto-pre-link pipeline",
1841 return Result;
1842}
1843
1844} // namespace
1845
1846/// Tests whether registered callbacks will accept a given pass name.
1847///
1848/// When parsing a pipeline text, the type of the outermost pipeline may be
1849/// omitted, in which case the type is automatically determined from the first
1850/// pass name in the text. This may be a name that is handled through one of the
1851/// callbacks. We check this through the oridinary parsing callbacks by setting
1852/// up a dummy PassManager in order to not force the client to also handle this
1853/// type of query.
1854template <typename PassManagerT, typename CallbacksT>
1855static bool callbacksAcceptPassName(StringRef Name, CallbacksT &Callbacks) {
1856 if (!Callbacks.empty()) {
1857 PassManagerT DummyPM;
1858 for (auto &CB : Callbacks)
1859 if (CB(Name, DummyPM, {}))
1860 return true;
1861 }
1862 return false;
1863}
1864
1865template <typename CallbacksT>
1866static bool isModulePassName(StringRef Name, CallbacksT &Callbacks) {
1867 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1868
1869 // Explicitly handle pass manager names.
1870 if (Name == "module")
1871 return true;
1872 if (Name == "cgscc")
1873 return true;
1874 if (NameNoBracket == "function")
1875 return true;
1876 if (Name == "coro-cond")
1877 return true;
1878
1879#define MODULE_PASS(NAME, CREATE_PASS) \
1880 if (Name == NAME) \
1881 return true;
1882#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1883 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1884 return true;
1885#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
1886 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1887 return true;
1888#include "PassRegistry.def"
1889
1890 return callbacksAcceptPassName<ModulePassManager>(Name, Callbacks);
1891}
1892
1893template <typename CallbacksT>
1894static bool isCGSCCPassName(StringRef Name, CallbacksT &Callbacks) {
1895 // Explicitly handle pass manager names.
1896 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1897 if (Name == "cgscc")
1898 return true;
1899 if (NameNoBracket == "function")
1900 return true;
1901
1902 // Explicitly handle custom-parsed pass names.
1903 if (parseDevirtPassName(Name))
1904 return true;
1905
1906#define CGSCC_PASS(NAME, CREATE_PASS) \
1907 if (Name == NAME) \
1908 return true;
1909#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1910 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1911 return true;
1912#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
1913 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1914 return true;
1915#include "PassRegistry.def"
1916
1917 return callbacksAcceptPassName<CGSCCPassManager>(Name, Callbacks);
1918}
1919
1920template <typename CallbacksT>
1921static bool isFunctionPassName(StringRef Name, CallbacksT &Callbacks) {
1922 // Explicitly handle pass manager names.
1923 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1924 if (NameNoBracket == "function")
1925 return true;
1926 if (Name == "loop" || Name == "loop-mssa" || Name == "machine-function")
1927 return true;
1928
1929#define FUNCTION_PASS(NAME, CREATE_PASS) \
1930 if (Name == NAME) \
1931 return true;
1932#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1933 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1934 return true;
1935#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1936 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1937 return true;
1938#include "PassRegistry.def"
1939
1940 return callbacksAcceptPassName<FunctionPassManager>(Name, Callbacks);
1941}
1942
1943template <typename CallbacksT>
1944static bool isMachineFunctionPassName(StringRef Name, CallbacksT &Callbacks) {
1945 // Explicitly handle pass manager names.
1946 if (Name == "machine-function")
1947 return true;
1948
1949#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
1950 if (Name == NAME) \
1951 return true;
1952#define MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, \
1953 PARAMS) \
1954 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1955 return true;
1956
1957#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1958 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1959 return true;
1960
1961#include "llvm/Passes/MachinePassRegistry.def"
1962
1964}
1965
1966template <typename CallbacksT>
1967static bool isLoopNestPassName(StringRef Name, CallbacksT &Callbacks,
1968 bool &UseMemorySSA) {
1969 UseMemorySSA = false;
1970
1971 if (PassBuilder::checkParametrizedPassName(Name, "lnicm")) {
1972 UseMemorySSA = true;
1973 return true;
1974 }
1975
1976#define LOOPNEST_PASS(NAME, CREATE_PASS) \
1977 if (Name == NAME) \
1978 return true;
1979#include "PassRegistry.def"
1980
1981 return callbacksAcceptPassName<LoopPassManager>(Name, Callbacks);
1982}
1983
1984template <typename CallbacksT>
1985static bool isLoopPassName(StringRef Name, CallbacksT &Callbacks,
1986 bool &UseMemorySSA) {
1987 UseMemorySSA = false;
1988
1989 if (PassBuilder::checkParametrizedPassName(Name, "licm")) {
1990 UseMemorySSA = true;
1991 return true;
1992 }
1993
1994#define LOOP_PASS(NAME, CREATE_PASS) \
1995 if (Name == NAME) \
1996 return true;
1997#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1998 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1999 return true;
2000#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
2001 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
2002 return true;
2003#include "PassRegistry.def"
2004
2005 return callbacksAcceptPassName<LoopPassManager>(Name, Callbacks);
2006}
2007
2008std::optional<std::vector<PassBuilder::PipelineElement>>
2009PassBuilder::parsePipelineText(StringRef Text) {
2010 std::vector<PipelineElement> ResultPipeline;
2011
2012 SmallVector<std::vector<PipelineElement> *, 4> PipelineStack = {
2013 &ResultPipeline};
2014 for (;;) {
2015 std::vector<PipelineElement> &Pipeline = *PipelineStack.back();
2016 size_t Pos = Text.find_first_of(",()");
2017 Pipeline.push_back({Text.substr(0, Pos), {}});
2018
2019 // If we have a single terminating name, we're done.
2020 if (Pos == Text.npos)
2021 break;
2022
2023 char Sep = Text[Pos];
2024 Text = Text.substr(Pos + 1);
2025 if (Sep == ',')
2026 // Just a name ending in a comma, continue.
2027 continue;
2028
2029 if (Sep == '(') {
2030 // Push the inner pipeline onto the stack to continue processing.
2031 PipelineStack.push_back(&Pipeline.back().InnerPipeline);
2032 continue;
2033 }
2034
2035 assert(Sep == ')' && "Bogus separator!");
2036 // When handling the close parenthesis, we greedily consume them to avoid
2037 // empty strings in the pipeline.
2038 do {
2039 // If we try to pop the outer pipeline we have unbalanced parentheses.
2040 if (PipelineStack.size() == 1)
2041 return std::nullopt;
2042
2043 PipelineStack.pop_back();
2044 } while (Text.consume_front(")"));
2045
2046 // Check if we've finished parsing.
2047 if (Text.empty())
2048 break;
2049
2050 // Otherwise, the end of an inner pipeline always has to be followed by
2051 // a comma, and then we can continue.
2052 if (!Text.consume_front(","))
2053 return std::nullopt;
2054 }
2055
2056 if (PipelineStack.size() > 1)
2057 // Unbalanced paretheses.
2058 return std::nullopt;
2059
2060 assert(PipelineStack.back() == &ResultPipeline &&
2061 "Wrong pipeline at the bottom of the stack!");
2062 return {std::move(ResultPipeline)};
2063}
2064
2067 PTO.LoopVectorization = L.getSpeedupLevel() > 1;
2068 PTO.SLPVectorization = L.getSpeedupLevel() > 1;
2069}
2070
2071Error PassBuilder::parseModulePass(ModulePassManager &MPM,
2072 const PipelineElement &E) {
2073 auto &Name = E.Name;
2074 auto &InnerPipeline = E.InnerPipeline;
2075
2076 // First handle complex passes like the pass managers which carry pipelines.
2077 if (!InnerPipeline.empty()) {
2078 if (Name == "module") {
2079 ModulePassManager NestedMPM;
2080 if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline))
2081 return Err;
2082 MPM.addPass(std::move(NestedMPM));
2083 return Error::success();
2084 }
2085 if (Name == "coro-cond") {
2086 ModulePassManager NestedMPM;
2087 if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline))
2088 return Err;
2089 MPM.addPass(CoroConditionalWrapper(std::move(NestedMPM)));
2090 return Error::success();
2091 }
2092 if (Name == "cgscc") {
2093 CGSCCPassManager CGPM;
2094 if (auto Err = parseCGSCCPassPipeline(CGPM, InnerPipeline))
2095 return Err;
2097 return Error::success();
2098 }
2099 if (auto Params = parseFunctionPipelineName(Name)) {
2100 if (Params->second)
2102 "cannot have a no-rerun module to function adaptor",
2105 if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline))
2106 return Err;
2107 MPM.addPass(
2108 createModuleToFunctionPassAdaptor(std::move(FPM), Params->first));
2109 return Error::success();
2110 }
2111
2112 for (auto &C : ModulePipelineParsingCallbacks)
2113 if (C(Name, MPM, InnerPipeline))
2114 return Error::success();
2115
2116 // Normal passes can't have pipelines.
2118 formatv("invalid use of '{}' pass as module pipeline", Name).str(),
2120 ;
2121 }
2122
2123 // Finally expand the basic registered passes from the .inc file.
2124#define MODULE_PASS(NAME, CREATE_PASS) \
2125 if (Name == NAME) { \
2126 MPM.addPass(CREATE_PASS); \
2127 return Error::success(); \
2128 }
2129#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2130 if (checkParametrizedPassName(Name, NAME)) { \
2131 auto Params = parsePassParameters(PARSER, Name, NAME); \
2132 if (!Params) \
2133 return Params.takeError(); \
2134 MPM.addPass(CREATE_PASS(Params.get())); \
2135 return Error::success(); \
2136 }
2137#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
2138 if (Name == "require<" NAME ">") { \
2139 MPM.addPass( \
2140 RequireAnalysisPass< \
2141 std::remove_reference_t<decltype(CREATE_PASS)>, Module>()); \
2142 return Error::success(); \
2143 } \
2144 if (Name == "invalidate<" NAME ">") { \
2145 MPM.addPass(InvalidateAnalysisPass< \
2146 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2147 return Error::success(); \
2148 }
2149#define CGSCC_PASS(NAME, CREATE_PASS) \
2150 if (Name == NAME) { \
2151 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(CREATE_PASS)); \
2152 return Error::success(); \
2153 }
2154#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2155 if (checkParametrizedPassName(Name, NAME)) { \
2156 auto Params = parsePassParameters(PARSER, Name, NAME); \
2157 if (!Params) \
2158 return Params.takeError(); \
2159 MPM.addPass( \
2160 createModuleToPostOrderCGSCCPassAdaptor(CREATE_PASS(Params.get()))); \
2161 return Error::success(); \
2162 }
2163#define FUNCTION_PASS(NAME, CREATE_PASS) \
2164 if (Name == NAME) { \
2165 if constexpr (std::is_constructible_v< \
2166 std::remove_reference_t<decltype(CREATE_PASS)>, \
2167 const TargetMachine &>) { \
2168 if (!TM) \
2169 return make_error<StringError>( \
2170 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2171 inconvertibleErrorCode()); \
2172 } \
2173 MPM.addPass(createModuleToFunctionPassAdaptor(CREATE_PASS)); \
2174 return Error::success(); \
2175 }
2176#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2177 if (checkParametrizedPassName(Name, NAME)) { \
2178 auto Params = parsePassParameters(PARSER, Name, NAME); \
2179 if (!Params) \
2180 return Params.takeError(); \
2181 auto CreatePass = CREATE_PASS; \
2182 if constexpr (std::is_constructible_v< \
2183 std::remove_reference_t<decltype(CreatePass( \
2184 Params.get()))>, \
2185 const TargetMachine &, \
2186 std::remove_reference_t<decltype(Params.get())>>) { \
2187 if (!TM) { \
2188 return make_error<StringError>( \
2189 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2190 inconvertibleErrorCode()); \
2191 } \
2192 } \
2193 MPM.addPass(createModuleToFunctionPassAdaptor(CREATE_PASS(Params.get()))); \
2194 return Error::success(); \
2195 }
2196#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2197 if (Name == NAME) { \
2198 MPM.addPass(createModuleToFunctionPassAdaptor( \
2199 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2200 return Error::success(); \
2201 }
2202#define LOOP_PASS(NAME, CREATE_PASS) \
2203 if (Name == NAME) { \
2204 MPM.addPass(createModuleToFunctionPassAdaptor( \
2205 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2206 return Error::success(); \
2207 }
2208#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2209 if (checkParametrizedPassName(Name, NAME)) { \
2210 auto Params = parsePassParameters(PARSER, Name, NAME); \
2211 if (!Params) \
2212 return Params.takeError(); \
2213 MPM.addPass(createModuleToFunctionPassAdaptor( \
2214 createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), false))); \
2215 return Error::success(); \
2216 }
2217#include "PassRegistry.def"
2218
2219 for (auto &C : ModulePipelineParsingCallbacks)
2220 if (C(Name, MPM, InnerPipeline))
2221 return Error::success();
2223 formatv("unknown module pass '{}'", Name).str(),
2225}
2226
2227Error PassBuilder::parseCGSCCPass(CGSCCPassManager &CGPM,
2228 const PipelineElement &E) {
2229 auto &Name = E.Name;
2230 auto &InnerPipeline = E.InnerPipeline;
2231
2232 // First handle complex passes like the pass managers which carry pipelines.
2233 if (!InnerPipeline.empty()) {
2234 if (Name == "cgscc") {
2235 CGSCCPassManager NestedCGPM;
2236 if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline))
2237 return Err;
2238 // Add the nested pass manager with the appropriate adaptor.
2239 CGPM.addPass(std::move(NestedCGPM));
2240 return Error::success();
2241 }
2242 if (auto Params = parseFunctionPipelineName(Name)) {
2244 if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline))
2245 return Err;
2246 // Add the nested pass manager with the appropriate adaptor.
2248 std::move(FPM), Params->first, Params->second));
2249 return Error::success();
2250 }
2251 if (auto MaxRepetitions = parseDevirtPassName(Name)) {
2252 CGSCCPassManager NestedCGPM;
2253 if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline))
2254 return Err;
2255 CGPM.addPass(
2256 createDevirtSCCRepeatedPass(std::move(NestedCGPM), *MaxRepetitions));
2257 return Error::success();
2258 }
2259
2260 for (auto &C : CGSCCPipelineParsingCallbacks)
2261 if (C(Name, CGPM, InnerPipeline))
2262 return Error::success();
2263
2264 // Normal passes can't have pipelines.
2266 formatv("invalid use of '{}' pass as cgscc pipeline", Name).str(),
2268 }
2269
2270// Now expand the basic registered passes from the .inc file.
2271#define CGSCC_PASS(NAME, CREATE_PASS) \
2272 if (Name == NAME) { \
2273 CGPM.addPass(CREATE_PASS); \
2274 return Error::success(); \
2275 }
2276#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2277 if (checkParametrizedPassName(Name, NAME)) { \
2278 auto Params = parsePassParameters(PARSER, Name, NAME); \
2279 if (!Params) \
2280 return Params.takeError(); \
2281 CGPM.addPass(CREATE_PASS(Params.get())); \
2282 return Error::success(); \
2283 }
2284#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
2285 if (Name == "require<" NAME ">") { \
2286 CGPM.addPass(RequireAnalysisPass< \
2287 std::remove_reference_t<decltype(CREATE_PASS)>, \
2288 LazyCallGraph::SCC, CGSCCAnalysisManager, LazyCallGraph &, \
2289 CGSCCUpdateResult &>()); \
2290 return Error::success(); \
2291 } \
2292 if (Name == "invalidate<" NAME ">") { \
2293 CGPM.addPass(InvalidateAnalysisPass< \
2294 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2295 return Error::success(); \
2296 }
2297#define FUNCTION_PASS(NAME, CREATE_PASS) \
2298 if (Name == NAME) { \
2299 if constexpr (std::is_constructible_v< \
2300 std::remove_reference_t<decltype(CREATE_PASS)>, \
2301 const TargetMachine &>) { \
2302 if (!TM) \
2303 return make_error<StringError>( \
2304 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2305 inconvertibleErrorCode()); \
2306 } \
2307 CGPM.addPass(createCGSCCToFunctionPassAdaptor(CREATE_PASS)); \
2308 return Error::success(); \
2309 }
2310#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2311 if (checkParametrizedPassName(Name, NAME)) { \
2312 auto Params = parsePassParameters(PARSER, Name, NAME); \
2313 if (!Params) \
2314 return Params.takeError(); \
2315 auto CreatePass = CREATE_PASS; \
2316 if constexpr (std::is_constructible_v< \
2317 std::remove_reference_t<decltype(CreatePass( \
2318 Params.get()))>, \
2319 const TargetMachine &, \
2320 std::remove_reference_t<decltype(Params.get())>>) { \
2321 if (!TM) { \
2322 return make_error<StringError>( \
2323 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2324 inconvertibleErrorCode()); \
2325 } \
2326 } \
2327 CGPM.addPass(createCGSCCToFunctionPassAdaptor(CREATE_PASS(Params.get()))); \
2328 return Error::success(); \
2329 }
2330#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2331 if (Name == NAME) { \
2332 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
2333 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2334 return Error::success(); \
2335 }
2336#define LOOP_PASS(NAME, CREATE_PASS) \
2337 if (Name == NAME) { \
2338 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
2339 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2340 return Error::success(); \
2341 }
2342#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2343 if (checkParametrizedPassName(Name, NAME)) { \
2344 auto Params = parsePassParameters(PARSER, Name, NAME); \
2345 if (!Params) \
2346 return Params.takeError(); \
2347 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
2348 createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), false))); \
2349 return Error::success(); \
2350 }
2351#include "PassRegistry.def"
2352
2353 for (auto &C : CGSCCPipelineParsingCallbacks)
2354 if (C(Name, CGPM, InnerPipeline))
2355 return Error::success();
2356 return make_error<StringError>(formatv("unknown cgscc pass '{}'", Name).str(),
2358}
2359
2360Error PassBuilder::parseFunctionPass(FunctionPassManager &FPM,
2361 const PipelineElement &E) {
2362 auto &Name = E.Name;
2363 auto &InnerPipeline = E.InnerPipeline;
2364
2365 // First handle complex passes like the pass managers which carry pipelines.
2366 if (!InnerPipeline.empty()) {
2367 if (Name == "function") {
2368 FunctionPassManager NestedFPM;
2369 if (auto Err = parseFunctionPassPipeline(NestedFPM, InnerPipeline))
2370 return Err;
2371 // Add the nested pass manager with the appropriate adaptor.
2372 FPM.addPass(std::move(NestedFPM));
2373 return Error::success();
2374 }
2375 if (Name == "loop" || Name == "loop-mssa") {
2376 LoopPassManager LPM;
2377 if (auto Err = parseLoopPassPipeline(LPM, InnerPipeline))
2378 return Err;
2379 // Add the nested pass manager with the appropriate adaptor.
2380 bool UseMemorySSA = (Name == "loop-mssa");
2381 FPM.addPass(
2382 createFunctionToLoopPassAdaptor(std::move(LPM), UseMemorySSA));
2383 return Error::success();
2384 }
2385 if (Name == "machine-function") {
2387 if (auto Err = parseMachinePassPipeline(MFPM, InnerPipeline))
2388 return Err;
2390 return Error::success();
2391 }
2392
2393 for (auto &C : FunctionPipelineParsingCallbacks)
2394 if (C(Name, FPM, InnerPipeline))
2395 return Error::success();
2396
2397 // Normal passes can't have pipelines.
2399 formatv("invalid use of '{}' pass as function pipeline", Name).str(),
2401 }
2402
2403// Now expand the basic registered passes from the .inc file.
2404#define FUNCTION_PASS(NAME, CREATE_PASS) \
2405 if (Name == NAME) { \
2406 if constexpr (std::is_constructible_v< \
2407 std::remove_reference_t<decltype(CREATE_PASS)>, \
2408 const TargetMachine &>) { \
2409 if (!TM) \
2410 return make_error<StringError>( \
2411 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2412 inconvertibleErrorCode()); \
2413 } \
2414 FPM.addPass(CREATE_PASS); \
2415 return Error::success(); \
2416 }
2417#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2418 if (checkParametrizedPassName(Name, NAME)) { \
2419 auto Params = parsePassParameters(PARSER, Name, NAME); \
2420 if (!Params) \
2421 return Params.takeError(); \
2422 auto CreatePass = CREATE_PASS; \
2423 if constexpr (std::is_constructible_v< \
2424 std::remove_reference_t<decltype(CreatePass( \
2425 Params.get()))>, \
2426 const TargetMachine &, \
2427 std::remove_reference_t<decltype(Params.get())>>) { \
2428 if (!TM) { \
2429 return make_error<StringError>( \
2430 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2431 inconvertibleErrorCode()); \
2432 } \
2433 } \
2434 FPM.addPass(CREATE_PASS(Params.get())); \
2435 return Error::success(); \
2436 }
2437#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
2438 if (Name == "require<" NAME ">") { \
2439 if constexpr (std::is_constructible_v< \
2440 std::remove_reference_t<decltype(CREATE_PASS)>, \
2441 const TargetMachine &>) { \
2442 if (!TM) \
2443 return make_error<StringError>( \
2444 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2445 inconvertibleErrorCode()); \
2446 } \
2447 FPM.addPass( \
2448 RequireAnalysisPass<std::remove_reference_t<decltype(CREATE_PASS)>, \
2449 Function>()); \
2450 return Error::success(); \
2451 } \
2452 if (Name == "invalidate<" NAME ">") { \
2453 FPM.addPass(InvalidateAnalysisPass< \
2454 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2455 return Error::success(); \
2456 }
2457// FIXME: UseMemorySSA is set to false. Maybe we could do things like:
2458// bool UseMemorySSA = !("canon-freeze" || "loop-predication" ||
2459// "guard-widening");
2460// The risk is that it may become obsolete if we're not careful.
2461#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2462 if (Name == NAME) { \
2463 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS, false)); \
2464 return Error::success(); \
2465 }
2466#define LOOP_PASS(NAME, CREATE_PASS) \
2467 if (Name == NAME) { \
2468 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS, false)); \
2469 return Error::success(); \
2470 }
2471#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2472 if (checkParametrizedPassName(Name, NAME)) { \
2473 auto Params = parsePassParameters(PARSER, Name, NAME); \
2474 if (!Params) \
2475 return Params.takeError(); \
2476 FPM.addPass( \
2477 createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), false)); \
2478 return Error::success(); \
2479 }
2480#include "PassRegistry.def"
2481
2482 for (auto &C : FunctionPipelineParsingCallbacks)
2483 if (C(Name, FPM, InnerPipeline))
2484 return Error::success();
2486 formatv("unknown function pass '{}'", Name).str(),
2488}
2489
2490Error PassBuilder::parseLoopPass(LoopPassManager &LPM,
2491 const PipelineElement &E) {
2492 StringRef Name = E.Name;
2493 auto &InnerPipeline = E.InnerPipeline;
2494
2495 // First handle complex passes like the pass managers which carry pipelines.
2496 if (!InnerPipeline.empty()) {
2497 if (Name == "loop") {
2498 LoopPassManager NestedLPM;
2499 if (auto Err = parseLoopPassPipeline(NestedLPM, InnerPipeline))
2500 return Err;
2501 // Add the nested pass manager with the appropriate adaptor.
2502 LPM.addPass(std::move(NestedLPM));
2503 return Error::success();
2504 }
2505
2506 for (auto &C : LoopPipelineParsingCallbacks)
2507 if (C(Name, LPM, InnerPipeline))
2508 return Error::success();
2509
2510 // Normal passes can't have pipelines.
2512 formatv("invalid use of '{}' pass as loop pipeline", Name).str(),
2514 }
2515
2516// Now expand the basic registered passes from the .inc file.
2517#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2518 if (Name == NAME) { \
2519 LPM.addPass(CREATE_PASS); \
2520 return Error::success(); \
2521 }
2522#define LOOP_PASS(NAME, CREATE_PASS) \
2523 if (Name == NAME) { \
2524 LPM.addPass(CREATE_PASS); \
2525 return Error::success(); \
2526 }
2527#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2528 if (checkParametrizedPassName(Name, NAME)) { \
2529 auto Params = parsePassParameters(PARSER, Name, NAME); \
2530 if (!Params) \
2531 return Params.takeError(); \
2532 LPM.addPass(CREATE_PASS(Params.get())); \
2533 return Error::success(); \
2534 }
2535#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
2536 if (Name == "require<" NAME ">") { \
2537 LPM.addPass(RequireAnalysisPass< \
2538 std::remove_reference_t<decltype(CREATE_PASS)>, Loop, \
2539 LoopAnalysisManager, LoopStandardAnalysisResults &, \
2540 LPMUpdater &>()); \
2541 return Error::success(); \
2542 } \
2543 if (Name == "invalidate<" NAME ">") { \
2544 LPM.addPass(InvalidateAnalysisPass< \
2545 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2546 return Error::success(); \
2547 }
2548#include "PassRegistry.def"
2549
2550 for (auto &C : LoopPipelineParsingCallbacks)
2551 if (C(Name, LPM, InnerPipeline))
2552 return Error::success();
2553 return make_error<StringError>(formatv("unknown loop pass '{}'", Name).str(),
2555}
2556
2557Error PassBuilder::parseMachinePass(MachineFunctionPassManager &MFPM,
2558 const PipelineElement &E) {
2559 StringRef Name = E.Name;
2560 // Handle any nested pass managers.
2561 if (!E.InnerPipeline.empty()) {
2562 if (E.Name == "machine-function") {
2564 if (auto Err = parseMachinePassPipeline(NestedPM, E.InnerPipeline))
2565 return Err;
2566 MFPM.addPass(std::move(NestedPM));
2567 return Error::success();
2568 }
2569 return make_error<StringError>("invalid pipeline",
2571 }
2572
2573#define MACHINE_MODULE_PASS(NAME, CREATE_PASS) \
2574 if (Name == NAME) { \
2575 MFPM.addPass(CREATE_PASS); \
2576 return Error::success(); \
2577 }
2578#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
2579 if (Name == NAME) { \
2580 MFPM.addPass(CREATE_PASS); \
2581 return Error::success(); \
2582 }
2583#define MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, \
2584 PARAMS) \
2585 if (checkParametrizedPassName(Name, NAME)) { \
2586 auto Params = parsePassParameters(PARSER, Name, NAME); \
2587 if (!Params) \
2588 return Params.takeError(); \
2589 MFPM.addPass(CREATE_PASS(Params.get())); \
2590 return Error::success(); \
2591 }
2592#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
2593 if (Name == "require<" NAME ">") { \
2594 MFPM.addPass( \
2595 RequireAnalysisPass<std::remove_reference_t<decltype(CREATE_PASS)>, \
2596 MachineFunction>()); \
2597 return Error::success(); \
2598 } \
2599 if (Name == "invalidate<" NAME ">") { \
2600 MFPM.addPass(InvalidateAnalysisPass< \
2601 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2602 return Error::success(); \
2603 }
2604#include "llvm/Passes/MachinePassRegistry.def"
2605
2606 for (auto &C : MachineFunctionPipelineParsingCallbacks)
2607 if (C(Name, MFPM, E.InnerPipeline))
2608 return Error::success();
2610 formatv("unknown machine pass '{}'", Name).str(),
2612}
2613
2614bool PassBuilder::parseAAPassName(AAManager &AA, StringRef Name) {
2615#define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
2616 if (Name == NAME) { \
2617 AA.registerModuleAnalysis< \
2618 std::remove_reference_t<decltype(CREATE_PASS)>>(); \
2619 return true; \
2620 }
2621#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
2622 if (Name == NAME) { \
2623 AA.registerFunctionAnalysis< \
2624 std::remove_reference_t<decltype(CREATE_PASS)>>(); \
2625 return true; \
2626 }
2627#include "PassRegistry.def"
2628
2629 for (auto &C : AAParsingCallbacks)
2630 if (C(Name, AA))
2631 return true;
2632 return false;
2633}
2634
2635Error PassBuilder::parseMachinePassPipeline(
2637 for (const auto &Element : Pipeline) {
2638 if (auto Err = parseMachinePass(MFPM, Element))
2639 return Err;
2640 }
2641 return Error::success();
2642}
2643
2644Error PassBuilder::parseLoopPassPipeline(LoopPassManager &LPM,
2645 ArrayRef<PipelineElement> Pipeline) {
2646 for (const auto &Element : Pipeline) {
2647 if (auto Err = parseLoopPass(LPM, Element))
2648 return Err;
2649 }
2650 return Error::success();
2651}
2652
2653Error PassBuilder::parseFunctionPassPipeline(
2655 for (const auto &Element : Pipeline) {
2656 if (auto Err = parseFunctionPass(FPM, Element))
2657 return Err;
2658 }
2659 return Error::success();
2660}
2661
2662Error PassBuilder::parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
2663 ArrayRef<PipelineElement> Pipeline) {
2664 for (const auto &Element : Pipeline) {
2665 if (auto Err = parseCGSCCPass(CGPM, Element))
2666 return Err;
2667 }
2668 return Error::success();
2669}
2670
2676 MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });
2677 MAM.registerPass([&] { return CGSCCAnalysisManagerModuleProxy(CGAM); });
2678 CGAM.registerPass([&] { return ModuleAnalysisManagerCGSCCProxy(MAM); });
2679 FAM.registerPass([&] { return CGSCCAnalysisManagerFunctionProxy(CGAM); });
2680 FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); });
2681 FAM.registerPass([&] { return LoopAnalysisManagerFunctionProxy(LAM); });
2682 LAM.registerPass([&] { return FunctionAnalysisManagerLoopProxy(FAM); });
2683 if (MFAM) {
2684 MAM.registerPass(
2685 [&] { return MachineFunctionAnalysisManagerModuleProxy(*MFAM); });
2686 FAM.registerPass(
2687 [&] { return MachineFunctionAnalysisManagerFunctionProxy(*MFAM); });
2688 MFAM->registerPass(
2690 MFAM->registerPass(
2692 }
2693}
2694
2695Error PassBuilder::parseModulePassPipeline(ModulePassManager &MPM,
2696 ArrayRef<PipelineElement> Pipeline) {
2697 for (const auto &Element : Pipeline) {
2698 if (auto Err = parseModulePass(MPM, Element))
2699 return Err;
2700 }
2701 return Error::success();
2702}
2703
2704// Primary pass pipeline description parsing routine for a \c ModulePassManager
2705// FIXME: Should this routine accept a TargetMachine or require the caller to
2706// pre-populate the analysis managers with target-specific stuff?
2708 StringRef PipelineText) {
2709 auto Pipeline = parsePipelineText(PipelineText);
2710 if (!Pipeline || Pipeline->empty())
2712 formatv("invalid pipeline '{}'", PipelineText).str(),
2714
2715 // If the first name isn't at the module layer, wrap the pipeline up
2716 // automatically.
2717 StringRef FirstName = Pipeline->front().Name;
2718
2719 if (!isModulePassName(FirstName, ModulePipelineParsingCallbacks)) {
2720 bool UseMemorySSA;
2721 if (isCGSCCPassName(FirstName, CGSCCPipelineParsingCallbacks)) {
2722 Pipeline = {{"cgscc", std::move(*Pipeline)}};
2723 } else if (isFunctionPassName(FirstName,
2724 FunctionPipelineParsingCallbacks)) {
2725 Pipeline = {{"function", std::move(*Pipeline)}};
2726 } else if (isLoopNestPassName(FirstName, LoopPipelineParsingCallbacks,
2727 UseMemorySSA)) {
2728 Pipeline = {{"function", {{UseMemorySSA ? "loop-mssa" : "loop",
2729 std::move(*Pipeline)}}}};
2730 } else if (isLoopPassName(FirstName, LoopPipelineParsingCallbacks,
2731 UseMemorySSA)) {
2732 Pipeline = {{"function", {{UseMemorySSA ? "loop-mssa" : "loop",
2733 std::move(*Pipeline)}}}};
2734 } else if (isMachineFunctionPassName(
2735 FirstName, MachineFunctionPipelineParsingCallbacks)) {
2736 Pipeline = {{"function", {{"machine-function", std::move(*Pipeline)}}}};
2737 } else {
2738 for (auto &C : TopLevelPipelineParsingCallbacks)
2739 if (C(MPM, *Pipeline))
2740 return Error::success();
2741
2742 // Unknown pass or pipeline name!
2743 auto &InnerPipeline = Pipeline->front().InnerPipeline;
2745 formatv("unknown {} name '{}'",
2746 (InnerPipeline.empty() ? "pass" : "pipeline"), FirstName)
2747 .str(),
2749 }
2750 }
2751
2752 if (auto Err = parseModulePassPipeline(MPM, *Pipeline))
2753 return Err;
2754 return Error::success();
2755}
2756
2757// Primary pass pipeline description parsing routine for a \c CGSCCPassManager
2759 StringRef PipelineText) {
2760 auto Pipeline = parsePipelineText(PipelineText);
2761 if (!Pipeline || Pipeline->empty())
2763 formatv("invalid pipeline '{}'", PipelineText).str(),
2765
2766 StringRef FirstName = Pipeline->front().Name;
2767 if (!isCGSCCPassName(FirstName, CGSCCPipelineParsingCallbacks))
2769 formatv("unknown cgscc pass '{}' in pipeline '{}'", FirstName,
2770 PipelineText)
2771 .str(),
2773
2774 if (auto Err = parseCGSCCPassPipeline(CGPM, *Pipeline))
2775 return Err;
2776 return Error::success();
2777}
2778
2779// Primary pass pipeline description parsing routine for a \c
2780// FunctionPassManager
2782 StringRef PipelineText) {
2783 auto Pipeline = parsePipelineText(PipelineText);
2784 if (!Pipeline || Pipeline->empty())
2786 formatv("invalid pipeline '{}'", PipelineText).str(),
2788
2789 StringRef FirstName = Pipeline->front().Name;
2790 if (!isFunctionPassName(FirstName, FunctionPipelineParsingCallbacks))
2792 formatv("unknown function pass '{}' in pipeline '{}'", FirstName,
2793 PipelineText)
2794 .str(),
2796
2797 if (auto Err = parseFunctionPassPipeline(FPM, *Pipeline))
2798 return Err;
2799 return Error::success();
2800}
2801
2802// Primary pass pipeline description parsing routine for a \c LoopPassManager
2804 StringRef PipelineText) {
2805 auto Pipeline = parsePipelineText(PipelineText);
2806 if (!Pipeline || Pipeline->empty())
2808 formatv("invalid pipeline '{}'", PipelineText).str(),
2810
2811 if (auto Err = parseLoopPassPipeline(CGPM, *Pipeline))
2812 return Err;
2813
2814 return Error::success();
2815}
2816
2818 StringRef PipelineText) {
2819 auto Pipeline = parsePipelineText(PipelineText);
2820 if (!Pipeline || Pipeline->empty())
2822 formatv("invalid machine pass pipeline '{}'", PipelineText).str(),
2824
2825 if (auto Err = parseMachinePassPipeline(MFPM, *Pipeline))
2826 return Err;
2827
2828 return Error::success();
2829}
2830
2832 // If the pipeline just consists of the word 'default' just replace the AA
2833 // manager with our default one.
2834 if (PipelineText == "default") {
2836 return Error::success();
2837 }
2838
2839 while (!PipelineText.empty()) {
2840 StringRef Name;
2841 std::tie(Name, PipelineText) = PipelineText.split(',');
2842 if (!parseAAPassName(AA, Name))
2844 formatv("unknown alias analysis name '{}'", Name).str(),
2846 }
2847
2848 return Error::success();
2849}
2850
2851std::optional<RegAllocFilterFunc>
2853 if (FilterName == "all")
2854 return nullptr;
2855 for (auto &C : RegClassFilterParsingCallbacks)
2856 if (auto F = C(FilterName))
2857 return F;
2858 return std::nullopt;
2859}
2860
2862 raw_ostream &OS) {
2863 for (StringRef PassName : drop_begin(PassNames))
2864 OS << " " << PassName << '\n';
2865}
2866
2867LLVM_ATTRIBUTE_NOINLINE static void
2869 auto I = PassNames.begin();
2870 auto End = PassNames.end();
2871 ++I;
2872 while (I != End) {
2873 StringRef Name = *I;
2874 ++I;
2875 assert(I != End);
2876 StringRef Params = *I;
2877 ++I;
2878 OS << " " << Name << '<' << Params << ">\n";
2879 }
2880}
2881
2883 // TODO: print pass descriptions when they are available
2884
2885 OS << "Module passes:\n";
2886 static constexpr char ModulePassNames[] = {"\0"
2887#define MODULE_PASS(NAME, CREATE_PASS) NAME "\0"
2888#include "PassRegistry.def"
2889 };
2890 printPassNameList(StringTable(ModulePassNames), OS);
2891
2892 OS << "Module passes with params:\n";
2893 static constexpr char ModulePassNamesWithParams[] = {"\0"
2894#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2895 NAME "\0" PARAMS "\0"
2896#include "PassRegistry.def"
2897 };
2898 printPassNameListWithParams(StringTable(ModulePassNamesWithParams), OS);
2899
2900 OS << "Module analyses:\n";
2901 static constexpr char ModuleAnalysisNames[] = {"\0"
2902#define MODULE_ANALYSIS(NAME, CREATE_PASS) NAME "\0"
2903#include "PassRegistry.def"
2904 };
2905 printPassNameList(StringTable(ModuleAnalysisNames), OS);
2906
2907 OS << "Module alias analyses:\n";
2908 static constexpr char ModuleAliasAnalysisNames[] = {"\0"
2909#define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) NAME "\0"
2910#include "PassRegistry.def"
2911 };
2912 printPassNameList(StringTable(ModuleAliasAnalysisNames), OS);
2913
2914 OS << "CGSCC passes:\n";
2915 static constexpr char CGSCCPassNames[] = {"\0"
2916#define CGSCC_PASS(NAME, CREATE_PASS) NAME "\0"
2917#include "PassRegistry.def"
2918 };
2919 printPassNameList(StringTable(CGSCCPassNames), OS);
2920
2921 OS << "CGSCC passes with params:\n";
2922 static constexpr char CGSCCPassNamesWithParams[] = {"\0"
2923#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2924 NAME "\0" PARAMS "\0"
2925#include "PassRegistry.def"
2926 };
2927 printPassNameListWithParams(StringTable(CGSCCPassNamesWithParams), OS);
2928
2929 OS << "CGSCC analyses:\n";
2930 static constexpr char CGSCCAnalysisNames[] = {"\0"
2931#define CGSCC_ANALYSIS(NAME, CREATE_PASS) NAME "\0"
2932#include "PassRegistry.def"
2933 };
2934 printPassNameList(StringTable(CGSCCAnalysisNames), OS);
2935
2936 OS << "Function passes:\n";
2937 static constexpr char FunctionPassNames[] = {"\0"
2938#define FUNCTION_PASS(NAME, CREATE_PASS) NAME "\0"
2939#include "PassRegistry.def"
2940 };
2941 printPassNameList(StringTable(FunctionPassNames), OS);
2942
2943 OS << "Function passes with params:\n";
2944 static constexpr char FunctionPassNamesWithParams[] = {"\0"
2945#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2946 NAME "\0" PARAMS "\0"
2947#include "PassRegistry.def"
2948 };
2949 printPassNameListWithParams(StringTable(FunctionPassNamesWithParams), OS);
2950
2951 OS << "Function analyses:\n";
2952 static constexpr char FunctionAnalysisNames[] = {"\0"
2953#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) NAME "\0"
2954#include "PassRegistry.def"
2955 };
2956 printPassNameList(StringTable(FunctionAnalysisNames), OS);
2957
2958 OS << "Function alias analyses:\n";
2959 static constexpr char FunctionAliasAnalysisNames[] = {"\0"
2960#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) NAME "\0"
2961#include "PassRegistry.def"
2962 };
2963 printPassNameList(StringTable(FunctionAliasAnalysisNames), OS);
2964
2965 OS << "LoopNest passes:\n";
2966 static constexpr char LoopNestPassNames[] = {"\0"
2967#define LOOPNEST_PASS(NAME, CREATE_PASS) NAME "\0"
2968#include "PassRegistry.def"
2969 };
2970 printPassNameList(StringTable(LoopNestPassNames), OS);
2971
2972 OS << "Loop passes:\n";
2973 static constexpr char LoopPassNames[] = {"\0"
2974#define LOOP_PASS(NAME, CREATE_PASS) NAME "\0"
2975#include "PassRegistry.def"
2976 };
2977 printPassNameList(StringTable(LoopPassNames), OS);
2978
2979 OS << "Loop passes with params:\n";
2980 static constexpr char LoopPassNamesWithParams[] = {"\0"
2981#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2982 NAME "\0" PARAMS "\0"
2983#include "PassRegistry.def"
2984 };
2985 printPassNameListWithParams(StringTable(LoopPassNamesWithParams), OS);
2986
2987 OS << "Loop analyses:\n";
2988 static constexpr char LoopAnalysisNames[] = {"\0"
2989#define LOOP_ANALYSIS(NAME, CREATE_PASS) NAME "\0"
2990#include "PassRegistry.def"
2991 };
2992 printPassNameList(StringTable(LoopAnalysisNames), OS);
2993
2994 OS << "Machine module passes (WIP):\n";
2995 static constexpr char MachineModulePassNames[] = {"\0"
2996#define MACHINE_MODULE_PASS(NAME, CREATE_PASS) NAME "\0"
2997#include "llvm/Passes/MachinePassRegistry.def"
2998 };
2999 printPassNameList(StringTable(MachineModulePassNames), OS);
3000
3001 OS << "Machine function passes (WIP):\n";
3002 static constexpr char MachineFunctionPassNames[] = {"\0"
3003#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) NAME "\0"
3004#include "llvm/Passes/MachinePassRegistry.def"
3005 };
3006 printPassNameList(StringTable(MachineFunctionPassNames), OS);
3007
3008 OS << "Machine function analyses (WIP):\n";
3009 static constexpr char MachineFunctionAnalysisNames[] = {"\0"
3010#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) NAME "\0"
3011#include "llvm/Passes/MachinePassRegistry.def"
3012 };
3013 printPassNameList(StringTable(MachineFunctionAnalysisNames), OS);
3014}
3015
3017 const std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>)>
3018 &C) {
3019 TopLevelPipelineParsingCallbacks.push_back(C);
3020}
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< 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:348
This file declares an analysis pass that computes CycleInfo for LLVM IR, specialized from GenericCycl...
Analysis that tracks defined/used subregister lanes across COPY instructions and instructions that ge...
This file provides the interface for a simple, fast CSE pass.
This file provides a pass which clones the current module and runs the provided pass pipeline on the ...
Super simple passes to force specific function attrs from the commandline into the IR for debugging p...
Provides passes for computing function attributes based on interprocedural analyses.
This file provides the interface for the GCOV style profiler pass.
Provides analysis for querying information about KnownBits during GISel passes.
This file provides the interface for LLVM's Global Value Numbering pass which eliminates fully redund...
This is the interface for a simple mod/ref and alias analysis over globals.
Defines an IR pass for the creation of hardware loops.
#define _
AcceleratorCodeSelection - Identify all functions reachable from a kernel, removing those that are un...
This file defines the IR2Vec vocabulary analysis(IR2VecVocabAnalysis), the core ir2vec::Embedder inte...
This file defines passes to print out IR in various granularities.
This header defines various interfaces for pass management in LLVM.
Interfaces for passes which infer implicit function attributes from the name and signature of functio...
This file provides the primary interface to the instcombine pass.
Defines passes for running instruction simplification across chunks of IR.
This file provides the interface for LLVM's PGO Instrumentation lowering pass.
This file contains the declaration of the InterleavedAccessPass class, its corresponding pass name is...
See the comments on JumpThreadingPass.
static LVOptions Options
Definition LVOptions.cpp:25
Implements a lazy call graph analysis and related passes for the new pass manager.
This file defines the interface for the loop cache analysis.
This file provides the interface for LLVM's Loop Data Prefetching Pass.
This file implements the Loop Fusion pass.
This header defines the LoopLoadEliminationPass object.
This file defines the interface for the loop nest analysis.
This header provides classes for managing a pipeline of passes over loops in LLVM IR.
This file provides the interface for the pass responsible for removing expensive ubsan checks.
The header file for the LowerConstantIntrinsics pass as used by the new pass manager.
The header file for the LowerExpectIntrinsic pass as used by the new pass manager.
#define F(x, y, z)
Definition MD5.cpp:54
#define I(x, y, z)
Definition MD5.cpp:57
Machine Check Debug Module
This file contains the declaration of the CheckDebugMachineModulePass class, used by the new pass man...
Machine IR instance of the generic uniformity analysis.
This file exposes an interface to building/using memory SSA to walk memory instructions using a use/d...
This pass performs merges of loads and stores on both sides of a.
This is the interface to build a ModuleSummaryIndex for a module.
Contains a collection of routines for determining if a given instruction is guaranteed to execute if ...
This file provides the interface for LLVM's Global Value Numbering pass.
This file declares a simple ARC-aware AliasAnalysis using special knowledge of Objective C to enhance...
This header enumerates the LLVM-provided high-level optimization levels.
This file provides the interface for IR based instrumentation passes ( (profile-gen,...
CGSCCAnalysisManager CGAM
LoopAnalysisManager LAM
FunctionAnalysisManager FAM
ModuleAnalysisManager MAM
if(PassOpts->AAPipeline)
PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC)
static bool isModulePassName(StringRef Name, CallbacksT &Callbacks)
static bool callbacksAcceptPassName(StringRef Name, CallbacksT &Callbacks)
Tests whether registered callbacks will accept a given pass name.
static std::optional< int > parseDevirtPassName(StringRef Name)
static LLVM_ATTRIBUTE_NOINLINE void printPassNameList(StringTable PassNames, raw_ostream &OS)
static bool isLoopNestPassName(StringRef Name, CallbacksT &Callbacks, bool &UseMemorySSA)
static bool isMachineFunctionPassName(StringRef Name, CallbacksT &Callbacks)
static Expected< OptimizationLevel > parseOptLevelParam(StringRef S)
static std::optional< OptimizationLevel > parseOptLevel(StringRef S)
static bool isLoopPassName(StringRef Name, CallbacksT &Callbacks, bool &UseMemorySSA)
static std::optional< std::pair< bool, bool > > parseFunctionPipelineName(StringRef Name)
static bool isCGSCCPassName(StringRef Name, CallbacksT &Callbacks)
static LLVM_ATTRIBUTE_NOINLINE void printPassNameListWithParams(StringTable PassNames, raw_ostream &OS)
static bool isFunctionPassName(StringRef Name, CallbacksT &Callbacks)
static void setupOptionsForPipelineAlias(PipelineTuningOptions &PTO, OptimizationLevel L)
This file implements the PredicateInfo analysis, which creates an Extended SSA form for operations us...
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
This pass is required to take advantage of the interprocedural register allocation infrastructure.
This file implements relative lookup table converter that converts lookup tables to relative lookup t...
This file provides the interface for LLVM's Scalar Replacement of Aggregates pass.
static const char * name
This file provides the interface for the pseudo probe implementation for AutoFDO.
This file provides the interface for the sampled PGO loader pass.
This is the interface for a SCEV-based alias analysis.
This pass converts vector operations into scalar operations (or, optionally, operations on smaller ve...
This is the interface for a metadata-based scoped no-alias analysis.
This file contains the declaration of the SelectOptimizePass class, its corresponding pass name is se...
This file provides the interface for the pass responsible for both simplifying and canonicalizing the...
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
This pass strips convergence intrinsics and operand bundles as those are only useful when modifying t...
Target-Independent Code Generator Pass Configuration Options pass.
This pass exposes codegen information to IR-level passes.
This is the interface for a metadata-based TBAA.
Defines an IR pass for type promotion.
LLVM IR instance of the generic uniformity analysis.
static const char PassName[]
A manager for alias analyses.
Class for arbitrary precision integers.
Definition APInt.h:78
uint64_t getZExtValue() const
Get zero extended value.
Definition APInt.h:1565
int64_t getSExtValue() const
Get sign extended value.
Definition APInt.h:1587
bool registerPass(PassBuilderT &&PassBuilder)
Register an analysis pass with the manager.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Definition BasicBlock.h:237
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
Tagged union holding either a T or a Error.
Definition Error.h:485
static LLVM_ABI GlobalAlias * create(Type *Ty, unsigned AddressSpace, LinkageTypes Linkage, const Twine &Name, Constant *Aliasee, Module *Parent)
If a parent module is specified, the alias is automatically inserted into the end of the specified mo...
Definition Globals.cpp:692
A smart pointer to a reference-counted object that inherits from RefCountedBase or ThreadSafeRefCount...
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
This analysis create MachineFunction for given Function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const MachineFunctionProperties & getProperties() const
Get the function properties.
LLVM_ABI Register createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
static LLVM_ABI const OptimizationLevel O3
Optimize for fast execution as much as possible.
static LLVM_ABI const OptimizationLevel O0
Disable as many optimizations as possible.
static LLVM_ABI const OptimizationLevel O2
Optimize for fast execution as much as possible without triggering significant incremental compile ti...
static LLVM_ABI const OptimizationLevel O1
Optimize quickly without destroying debuggability.
This class provides access to building LLVM's passes.
LLVM_ABI void printPassNames(raw_ostream &OS)
Print pass names.
static bool checkParametrizedPassName(StringRef Name, StringRef PassName)
LLVM_ABI AAManager buildDefaultAAPipeline()
Build the default AAManager with the default alias analysis pipeline registered.
LLVM_ABI Error parseAAPipeline(AAManager &AA, StringRef PipelineText)
Parse a textual alias analysis pipeline into the provided AA manager.
LLVM_ABI void registerLoopAnalyses(LoopAnalysisManager &LAM)
Registers all available loop analysis passes.
LLVM_ABI std::optional< RegAllocFilterFunc > parseRegAllocFilter(StringRef RegAllocFilterName)
Parse RegAllocFilterName to get RegAllocFilterFunc.
LLVM_ABI void crossRegisterProxies(LoopAnalysisManager &LAM, FunctionAnalysisManager &FAM, CGSCCAnalysisManager &CGAM, ModuleAnalysisManager &MAM, MachineFunctionAnalysisManager *MFAM=nullptr)
Cross register the analysis managers through their proxies.
LLVM_ABI PassBuilder(TargetMachine *TM=nullptr, PipelineTuningOptions PTO=PipelineTuningOptions(), std::optional< PGOOptions > PGOOpt=std::nullopt, PassInstrumentationCallbacks *PIC=nullptr, IntrusiveRefCntPtr< vfs::FileSystem > FS=vfs::getRealFileSystem())
LLVM_ABI Error parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText)
Parse a textual pass pipeline description into a ModulePassManager.
void registerPipelineParsingCallback(const std::function< bool(StringRef Name, CGSCCPassManager &, ArrayRef< PipelineElement >)> &C)
{{@ Register pipeline parsing callbacks with this pass builder instance.
LLVM_ABI void registerModuleAnalyses(ModuleAnalysisManager &MAM)
Registers all available module analysis passes.
LLVM_ABI void registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM)
Registers all available CGSCC analysis passes.
static LLVM_ABI Expected< bool > parseSinglePassOption(StringRef Params, StringRef OptionName, StringRef PassName)
Handle passes only accept one bool-valued parameter.
LLVM_ABI void registerMachineFunctionAnalyses(MachineFunctionAnalysisManager &MFAM)
Registers all available machine function analysis passes.
LLVM_ABI void registerParseTopLevelPipelineCallback(const std::function< bool(ModulePassManager &, ArrayRef< PipelineElement >)> &C)
Register a callback for a top-level pipeline entry.
LLVM_ABI void registerFunctionAnalyses(FunctionAnalysisManager &FAM)
Registers all available function analysis passes.
This class manages callbacks registration, as well as provides a way for PassInstrumentation to pass ...
LLVM_ATTRIBUTE_MINSIZE std::enable_if_t<!std::is_same_v< PassT, PassManager > > addPass(PassT &&Pass)
Tunable parameters for passes in the default pipelines.
Definition PassBuilder.h:41
bool SLPVectorization
Tuning option to enable/disable slp loop vectorization, set based on opt level.
Definition PassBuilder.h:56
bool LoopVectorization
Tuning option to enable/disable loop vectorization, set based on opt level.
Definition PassBuilder.h:52
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition Analysis.h:115
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
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
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
std::optional< CodeGenOptLevel > getLevel(int OL)
Get the Level identified by the integer OL.
Definition CodeGen.h:93
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:81
DXILDebugInfoMap run(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.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition STLExtras.h:315
OuterAnalysisManagerProxy< CGSCCAnalysisManager, Function > CGSCCAnalysisManagerFunctionProxy
A proxy from a CGSCCAnalysisManager to a Function.
OuterAnalysisManagerProxy< ModuleAnalysisManager, MachineFunction > ModuleAnalysisManagerMachineFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
LLVM_ABI cl::opt< std::optional< PrintPipelinePassesFormat >, false, PrintPipelinePassesFormatParser > PrintPipelinePasses
Common option used by multiple tools to print pipeline passes.
ModuleToFunctionPassAdaptor createModuleToFunctionPassAdaptor(FunctionPassT &&Pass, bool EagerlyInvalidate=false)
A function to deduce a function pass type and wrap it in the templated adaptor.
DevirtSCCRepeatedPass createDevirtSCCRepeatedPass(CGSCCPassT &&Pass, int MaxIterations)
A function to deduce a function pass type and wrap it in the templated adaptor.
OuterAnalysisManagerProxy< ModuleAnalysisManager, Function > ModuleAnalysisManagerFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition Error.cpp:94
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
InnerAnalysisManagerProxy< LoopAnalysisManager, Function > LoopAnalysisManagerFunctionProxy
A proxy from a LoopAnalysisManager to a Function.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition Error.h:1321
PassManager< LazyCallGraph::SCC, CGSCCAnalysisManager, LazyCallGraph &, CGSCCUpdateResult & > CGSCCPassManager
The CGSCC pass manager.
AnalysisManager< LazyCallGraph::SCC, LazyCallGraph & > CGSCCAnalysisManager
The CGSCC analysis manager.
AnalysisManager< Loop, LoopStandardAnalysisResults & > LoopAnalysisManager
The loop analysis manager.
PassManager< Loop, LoopAnalysisManager, LoopStandardAnalysisResults &, LPMUpdater & > LoopPassManager
The Loop pass manager.
ModuleToPostOrderCGSCCPassAdaptor createModuleToPostOrderCGSCCPassAdaptor(CGSCCPassT &&Pass)
A function to deduce a function pass type and wrap it in the templated adaptor.
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
FunctionToLoopPassAdaptor createFunctionToLoopPassAdaptor(LoopPassT &&Pass, bool UseMemorySSA=false)
A function to deduce a loop pass type and wrap it in the templated adaptor.
CGSCCToFunctionPassAdaptor createCGSCCToFunctionPassAdaptor(FunctionPassT &&Pass, bool EagerlyInvalidate=false, bool NoRerun=false)
A function to deduce a function pass type and wrap it in the templated adaptor.
FunctionToMachineFunctionPassAdaptor createFunctionToMachineFunctionPassAdaptor(MachineFunctionPassT &&Pass)
PassManager< Module > ModulePassManager
Convenience typedef for a pass manager over modules.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
InnerAnalysisManagerProxy< MachineFunctionAnalysisManager, Function > MachineFunctionAnalysisManagerFunctionProxy
OuterAnalysisManagerProxy< FunctionAnalysisManager, Loop, LoopStandardAnalysisResults & > FunctionAnalysisManagerLoopProxy
A proxy from a FunctionAnalysisManager to a Loop.
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
Definition Error.h:340
support::detail::RepeatAdapter< T > fmt_repeat(T &&Item, size_t Count)
OuterAnalysisManagerProxy< ModuleAnalysisManager, LazyCallGraph::SCC, LazyCallGraph & > ModuleAnalysisManagerCGSCCProxy
A proxy from a ModuleAnalysisManager to an SCC.
InnerAnalysisManagerProxy< MachineFunctionAnalysisManager, Module > MachineFunctionAnalysisManagerModuleProxy
RelativeUniformCounterPtr ValuesPtrExpr VTableAddr Count
Definition InstrProf.h:145
InnerAnalysisManagerProxy< CGSCCAnalysisManager, Module > CGSCCAnalysisManagerModuleProxy
A proxy from a CGSCCAnalysisManager to a Module.
PassManager< Function > FunctionPassManager
Convenience typedef for a pass manager over functions.
MFPropsModifier(PassT &P, MachineFunction &MF) -> MFPropsModifier< PassT >
LLVM_ABI void printFormattedPipelinePasses(raw_ostream &OS, StringRef Pipeline, PrintPipelinePassesFormat Format=PrintPipelinePassesFormat::Text)
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1917
PassManager< MachineFunction > MachineFunctionPassManager
Convenience typedef for a pass manager over functions.
LLVM_ABI bool applyDebugifyMetadataToMachineFunction(DIBuilder &DIB, Function &F, llvm::function_ref< MachineFunction *(Function &)> GetMF)
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI std::optional< AllocTokenMode > getAllocTokenModeFromString(StringRef Name)
Returns the AllocTokenMode from its canonical string name; if an invalid name was provided returns nu...
PrintPipelinePassesFormat
@ Detailed
Hash with opcode only.
@ CallTargetIgnored
Hash with opcode and operands.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition MIRParser.h:39
@ Enable
Enable colors.
Definition WithColor.h:47
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Definition Error.cpp:177
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:860
#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:81
HardwareLoopOptions & setForceNested(bool Force)
HardwareLoopOptions & setDecrement(unsigned Count)
HardwareLoopOptions & setForceGuard(bool Force)
HardwareLoopOptions & setForce(bool Force)
HardwareLoopOptions & setCounterBitwidth(unsigned Width)
HardwareLoopOptions & setForcePhi(bool Force)
A set of parameters to control various transforms performed by IPSCCP pass.
Definition SCCP.h:35
A set of parameters used to control various transforms performed by the LoopUnroll pass.
LoopUnrollOptions & setPeeling(bool Peeling)
Enables or disables loop peeling.
LoopUnrollOptions & setOptLevel(int O)
LoopUnrollOptions & setPartial(bool Partial)
Enables or disables partial unrolling.
LoopUnrollOptions & setFullUnrollMaxCount(unsigned O)
LoopUnrollOptions & setUpperBound(bool UpperBound)
Enables or disables the use of trip count upper bound in loop unrolling.
LoopUnrollOptions & setRuntime(bool Runtime)
Enables or disables unrolling of loops with runtime trip count.
LoopUnrollOptions & setProfileBasedPeeling(int O)
LoopVectorizeOptions & setVectorizeOnlyWhenForced(bool Value)
LoopVectorizeOptions & setInterleaveOnlyWhenForced(bool Value)
A CRTP mix-in for passes that can be skipped.
LLVM_ABI bool parse(cl::Option &O, StringRef ArgName, StringRef ArgValue, std::optional< PrintPipelinePassesFormat > &Val)