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