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