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