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