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