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