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<bool> parseWinEHPrepareOptions(StringRef Params) {
1621 return PassBuilder::parseSinglePassOption(Params, "demote-catchswitch-only",
1622 "WinEHPreparePass");
1623}
1624
1625Expected<GlobalMergeOptions> parseGlobalMergeOptions(StringRef Params) {
1627 while (!Params.empty()) {
1628 StringRef ParamName;
1629 std::tie(ParamName, Params) = Params.split(';');
1630
1631 bool Enable = !ParamName.consume_front("no-");
1632 if (ParamName == "group-by-use")
1633 Result.GroupByUse = Enable;
1634 else if (ParamName == "ignore-single-use")
1635 Result.IgnoreSingleUse = Enable;
1636 else if (ParamName == "merge-const")
1637 Result.MergeConstantGlobals = Enable;
1638 else if (ParamName == "merge-const-aggressive")
1639 Result.MergeConstAggressive = Enable;
1640 else if (ParamName == "merge-external")
1641 Result.MergeExternal = Enable;
1642 else if (ParamName.consume_front("max-offset=")) {
1643 if (ParamName.getAsInteger(0, Result.MaxOffset))
1645 formatv("invalid GlobalMergePass parameter '{}'", ParamName).str(),
1647 } else {
1649 formatv("invalid global-merge pass parameter '{}'", Params).str(),
1651 }
1652 }
1653 return Result;
1654}
1655
1656Expected<SmallVector<std::string, 0>> parseInternalizeGVs(StringRef Params) {
1657 SmallVector<std::string, 1> PreservedGVs;
1658 while (!Params.empty()) {
1659 StringRef ParamName;
1660 std::tie(ParamName, Params) = Params.split(';');
1661
1662 if (ParamName.consume_front("preserve-gv=")) {
1663 PreservedGVs.push_back(ParamName.str());
1664 } else {
1666 formatv("invalid Internalize pass parameter '{}'", ParamName).str(),
1668 }
1669 }
1670
1671 return Expected<SmallVector<std::string, 0>>(std::move(PreservedGVs));
1672}
1673
1675parseRegAllocFastPassOptions(PassBuilder &PB, StringRef Params) {
1677 while (!Params.empty()) {
1678 StringRef ParamName;
1679 std::tie(ParamName, Params) = Params.split(';');
1680
1681 if (ParamName.consume_front("filter=")) {
1682 std::optional<RegAllocFilterFunc> Filter =
1683 PB.parseRegAllocFilter(ParamName);
1684 if (!Filter) {
1686 formatv("invalid regallocfast register filter '{}'", ParamName)
1687 .str(),
1689 }
1690 Opts.Filter = *Filter;
1691 Opts.FilterName = ParamName;
1692 continue;
1693 }
1694
1695 if (ParamName == "no-clear-vregs") {
1696 Opts.ClearVRegs = false;
1697 continue;
1698 }
1699
1701 formatv("invalid regallocfast pass parameter '{}'", ParamName).str(),
1703 }
1704 return Opts;
1705}
1706
1708parseBoundsCheckingOptions(StringRef Params) {
1710 while (!Params.empty()) {
1711 StringRef ParamName;
1712 std::tie(ParamName, Params) = Params.split(';');
1713 if (ParamName == "trap") {
1714 Options.Rt = std::nullopt;
1715 } else if (ParamName == "rt") {
1716 Options.Rt = {
1717 /*MinRuntime=*/false,
1718 /*MayReturn=*/true,
1719 /*HandlerPreserveAllRegs=*/false,
1720 };
1721 } else if (ParamName == "rt-abort") {
1722 Options.Rt = {
1723 /*MinRuntime=*/false,
1724 /*MayReturn=*/false,
1725 /*HandlerPreserveAllRegs=*/false,
1726 };
1727 } else if (ParamName == "min-rt") {
1728 Options.Rt = {
1729 /*MinRuntime=*/true,
1730 /*MayReturn=*/true,
1731 /*HandlerPreserveAllRegs=*/false,
1732 };
1733 } else if (ParamName == "min-rt-abort") {
1734 Options.Rt = {
1735 /*MinRuntime=*/true,
1736 /*MayReturn=*/false,
1737 /*HandlerPreserveAllRegs=*/false,
1738 };
1739 } else if (ParamName == "merge") {
1740 Options.Merge = true;
1741 } else if (ParamName == "handler-preserve-all-regs") {
1742 if (Options.Rt)
1743 Options.Rt->HandlerPreserveAllRegs = true;
1744 } else {
1745 StringRef ParamEQ;
1746 StringRef Val;
1747 std::tie(ParamEQ, Val) = ParamName.split('=');
1748 int8_t Id;
1749 if (ParamEQ == "guard" && !Val.getAsInteger(0, Id)) {
1750 Options.GuardKind = Id;
1751 } else {
1753 formatv("invalid BoundsChecking pass parameter '{}'", ParamName)
1754 .str(),
1756 }
1757 }
1758 }
1759 return Options;
1760}
1761
1762Expected<CodeGenOptLevel> parseExpandIRInstsOptions(StringRef Param) {
1763 if (Param.empty())
1764 return CodeGenOptLevel::None;
1765
1766 // Parse a CodeGenOptLevel, e.g. "O1", "O2", "O3".
1767 auto [Prefix, Digit] = Param.split('O');
1768
1769 uint8_t N;
1770 if (!Prefix.empty() || Digit.getAsInteger(10, N))
1771 return createStringError("invalid expand-ir-insts pass parameter '%s'",
1772 Param.str().c_str());
1773
1774 std::optional<CodeGenOptLevel> Level = CodeGenOpt::getLevel(N);
1775 if (!Level.has_value())
1776 return createStringError(
1777 "invalid optimization level for expand-ir-insts pass: %s",
1778 Digit.str().c_str());
1779
1780 return *Level;
1781}
1782
1784parseRegAllocGreedyFilterFunc(PassBuilder &PB, StringRef Params) {
1785 if (Params.empty() || Params == "all")
1786 return RAGreedyPass::Options();
1787
1788 std::optional<RegAllocFilterFunc> Filter = PB.parseRegAllocFilter(Params);
1789 if (Filter)
1790 return RAGreedyPass::Options{*Filter, Params};
1791
1793 formatv("invalid regallocgreedy register filter '{}'", Params).str(),
1795}
1796
1797Expected<bool> parseMachineSinkingPassOptions(StringRef Params) {
1798 return PassBuilder::parseSinglePassOption(Params, "enable-sink-fold",
1799 "MachineSinkingPass");
1800}
1801
1802Expected<bool> parseMachineBlockPlacementPassOptions(StringRef Params) {
1803 bool AllowTailMerge = true;
1804 if (!Params.empty()) {
1805 AllowTailMerge = !Params.consume_front("no-");
1806 if (Params != "tail-merge")
1808 formatv("invalid MachineBlockPlacementPass parameter '{}'", Params)
1809 .str(),
1811 }
1812 return AllowTailMerge;
1813}
1814
1815Expected<bool> parseVirtRegRewriterPassOptions(StringRef Params) {
1816 bool ClearVirtRegs = true;
1817 if (!Params.empty()) {
1818 ClearVirtRegs = !Params.consume_front("no-");
1819 if (Params != "clear-vregs")
1821 formatv("invalid VirtRegRewriter pass parameter '{}'", Params).str(),
1823 }
1824 return ClearVirtRegs;
1825}
1826
1827struct FatLTOOptions {
1828 OptimizationLevel OptLevel;
1829 bool ThinLTO = false;
1830 bool EmitSummary = false;
1831};
1832
1833Expected<FatLTOOptions> parseFatLTOOptions(StringRef Params) {
1834 FatLTOOptions Result;
1835 bool HaveOptLevel = false;
1836 while (!Params.empty()) {
1837 StringRef ParamName;
1838 std::tie(ParamName, Params) = Params.split(';');
1839
1840 if (ParamName == "thinlto") {
1841 Result.ThinLTO = true;
1842 } else if (ParamName == "emit-summary") {
1843 Result.EmitSummary = true;
1844 } else if (std::optional<OptimizationLevel> OptLevel =
1845 parseOptLevel(ParamName)) {
1846 Result.OptLevel = *OptLevel;
1847 HaveOptLevel = true;
1848 } else {
1850 formatv("invalid fatlto-pre-link pass parameter '{}'", ParamName)
1851 .str(),
1853 }
1854 }
1855 if (!HaveOptLevel)
1857 "missing optimization level for fatlto-pre-link pipeline",
1859 return Result;
1860}
1861
1862} // namespace
1863
1864/// Tests whether registered callbacks will accept a given pass name.
1865///
1866/// When parsing a pipeline text, the type of the outermost pipeline may be
1867/// omitted, in which case the type is automatically determined from the first
1868/// pass name in the text. This may be a name that is handled through one of the
1869/// callbacks. We check this through the oridinary parsing callbacks by setting
1870/// up a dummy PassManager in order to not force the client to also handle this
1871/// type of query.
1872template <typename PassManagerT, typename CallbacksT>
1873static bool callbacksAcceptPassName(StringRef Name, CallbacksT &Callbacks) {
1874 if (!Callbacks.empty()) {
1875 PassManagerT DummyPM;
1876 for (auto &CB : Callbacks)
1877 if (CB(Name, DummyPM, {}))
1878 return true;
1879 }
1880 return false;
1881}
1882
1883template <typename CallbacksT>
1884static bool isModulePassName(StringRef Name, CallbacksT &Callbacks) {
1885 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1886
1887 // Explicitly handle pass manager names.
1888 if (Name == "module")
1889 return true;
1890 if (Name == "cgscc")
1891 return true;
1892 if (NameNoBracket == "function")
1893 return true;
1894 if (Name == "coro-cond")
1895 return true;
1896
1897#define MODULE_PASS(NAME, CREATE_PASS) \
1898 if (Name == NAME) \
1899 return true;
1900#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1901 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1902 return true;
1903#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
1904 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1905 return true;
1906#include "PassRegistry.def"
1907
1908 return callbacksAcceptPassName<ModulePassManager>(Name, Callbacks);
1909}
1910
1911template <typename CallbacksT>
1912static bool isCGSCCPassName(StringRef Name, CallbacksT &Callbacks) {
1913 // Explicitly handle pass manager names.
1914 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1915 if (Name == "cgscc")
1916 return true;
1917 if (NameNoBracket == "function")
1918 return true;
1919
1920 // Explicitly handle custom-parsed pass names.
1921 if (parseDevirtPassName(Name))
1922 return true;
1923
1924#define CGSCC_PASS(NAME, CREATE_PASS) \
1925 if (Name == NAME) \
1926 return true;
1927#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1928 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1929 return true;
1930#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
1931 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1932 return true;
1933#include "PassRegistry.def"
1934
1935 return callbacksAcceptPassName<CGSCCPassManager>(Name, Callbacks);
1936}
1937
1938template <typename CallbacksT>
1939static bool isFunctionPassName(StringRef Name, CallbacksT &Callbacks) {
1940 // Explicitly handle pass manager names.
1941 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1942 if (NameNoBracket == "function")
1943 return true;
1944 if (Name == "loop" || Name == "loop-mssa" || Name == "machine-function")
1945 return true;
1946
1947#define FUNCTION_PASS(NAME, CREATE_PASS) \
1948 if (Name == NAME) \
1949 return true;
1950#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1951 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1952 return true;
1953#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1954 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1955 return true;
1956#include "PassRegistry.def"
1957
1958 return callbacksAcceptPassName<FunctionPassManager>(Name, Callbacks);
1959}
1960
1961template <typename CallbacksT>
1962static bool isMachineFunctionPassName(StringRef Name, CallbacksT &Callbacks) {
1963 // Explicitly handle pass manager names.
1964 if (Name == "machine-function")
1965 return true;
1966
1967#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
1968 if (Name == NAME) \
1969 return true;
1970#define MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, \
1971 PARAMS) \
1972 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1973 return true;
1974
1975#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1976 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1977 return true;
1978
1979#include "llvm/Passes/MachinePassRegistry.def"
1980
1982}
1983
1984template <typename CallbacksT>
1985static bool isLoopNestPassName(StringRef Name, CallbacksT &Callbacks,
1986 bool &UseMemorySSA) {
1987 UseMemorySSA = false;
1988
1989 if (PassBuilder::checkParametrizedPassName(Name, "lnicm")) {
1990 UseMemorySSA = true;
1991 return true;
1992 }
1993
1994#define LOOPNEST_PASS(NAME, CREATE_PASS) \
1995 if (Name == NAME) \
1996 return true;
1997#include "PassRegistry.def"
1998
1999 return callbacksAcceptPassName<LoopPassManager>(Name, Callbacks);
2000}
2001
2002template <typename CallbacksT>
2003static bool isLoopPassName(StringRef Name, CallbacksT &Callbacks,
2004 bool &UseMemorySSA) {
2005 UseMemorySSA = false;
2006
2007 if (PassBuilder::checkParametrizedPassName(Name, "licm")) {
2008 UseMemorySSA = true;
2009 return true;
2010 }
2011
2012#define LOOP_PASS(NAME, CREATE_PASS) \
2013 if (Name == NAME) \
2014 return true;
2015#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2016 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
2017 return true;
2018#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
2019 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
2020 return true;
2021#include "PassRegistry.def"
2022
2023 return callbacksAcceptPassName<LoopPassManager>(Name, Callbacks);
2024}
2025
2026std::optional<std::vector<PassBuilder::PipelineElement>>
2027PassBuilder::parsePipelineText(StringRef Text) {
2028 std::vector<PipelineElement> ResultPipeline;
2029
2030 SmallVector<std::vector<PipelineElement> *, 4> PipelineStack = {
2031 &ResultPipeline};
2032 for (;;) {
2033 std::vector<PipelineElement> &Pipeline = *PipelineStack.back();
2034 size_t Pos = Text.find_first_of(",()");
2035 Pipeline.push_back({Text.substr(0, Pos), {}});
2036
2037 // If we have a single terminating name, we're done.
2038 if (Pos == Text.npos)
2039 break;
2040
2041 char Sep = Text[Pos];
2042 Text = Text.substr(Pos + 1);
2043 if (Sep == ',')
2044 // Just a name ending in a comma, continue.
2045 continue;
2046
2047 if (Sep == '(') {
2048 // Push the inner pipeline onto the stack to continue processing.
2049 PipelineStack.push_back(&Pipeline.back().InnerPipeline);
2050 continue;
2051 }
2052
2053 assert(Sep == ')' && "Bogus separator!");
2054 // When handling the close parenthesis, we greedily consume them to avoid
2055 // empty strings in the pipeline.
2056 do {
2057 // If we try to pop the outer pipeline we have unbalanced parentheses.
2058 if (PipelineStack.size() == 1)
2059 return std::nullopt;
2060
2061 PipelineStack.pop_back();
2062 } while (Text.consume_front(")"));
2063
2064 // Check if we've finished parsing.
2065 if (Text.empty())
2066 break;
2067
2068 // Otherwise, the end of an inner pipeline always has to be followed by
2069 // a comma, and then we can continue.
2070 if (!Text.consume_front(","))
2071 return std::nullopt;
2072 }
2073
2074 if (PipelineStack.size() > 1)
2075 // Unbalanced paretheses.
2076 return std::nullopt;
2077
2078 assert(PipelineStack.back() == &ResultPipeline &&
2079 "Wrong pipeline at the bottom of the stack!");
2080 return {std::move(ResultPipeline)};
2081}
2082
2088
2089Error PassBuilder::parseModulePass(ModulePassManager &MPM,
2090 const PipelineElement &E) {
2091 auto &Name = E.Name;
2092 auto &InnerPipeline = E.InnerPipeline;
2093
2094 // First handle complex passes like the pass managers which carry pipelines.
2095 if (!InnerPipeline.empty()) {
2096 if (Name == "module") {
2097 ModulePassManager NestedMPM;
2098 if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline))
2099 return Err;
2100 MPM.addPass(std::move(NestedMPM));
2101 return Error::success();
2102 }
2103 if (Name == "coro-cond") {
2104 ModulePassManager NestedMPM;
2105 if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline))
2106 return Err;
2107 MPM.addPass(CoroConditionalWrapper(std::move(NestedMPM)));
2108 return Error::success();
2109 }
2110 if (Name == "cgscc") {
2111 CGSCCPassManager CGPM;
2112 if (auto Err = parseCGSCCPassPipeline(CGPM, InnerPipeline))
2113 return Err;
2115 return Error::success();
2116 }
2117 if (auto Params = parseFunctionPipelineName(Name)) {
2118 if (Params->second)
2120 "cannot have a no-rerun module to function adaptor",
2123 if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline))
2124 return Err;
2125 MPM.addPass(
2126 createModuleToFunctionPassAdaptor(std::move(FPM), Params->first));
2127 return Error::success();
2128 }
2129
2130 for (auto &C : ModulePipelineParsingCallbacks)
2131 if (C(Name, MPM, InnerPipeline))
2132 return Error::success();
2133
2134 // Normal passes can't have pipelines.
2136 formatv("invalid use of '{}' pass as module pipeline", Name).str(),
2138 ;
2139 }
2140
2141 // Finally expand the basic registered passes from the .inc file.
2142#define MODULE_PASS(NAME, CREATE_PASS) \
2143 if (Name == NAME) { \
2144 MPM.addPass(CREATE_PASS); \
2145 return Error::success(); \
2146 }
2147#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2148 if (checkParametrizedPassName(Name, NAME)) { \
2149 auto Params = parsePassParameters(PARSER, Name, NAME); \
2150 if (!Params) \
2151 return Params.takeError(); \
2152 MPM.addPass(CREATE_PASS(Params.get())); \
2153 return Error::success(); \
2154 }
2155#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
2156 if (Name == "require<" NAME ">") { \
2157 MPM.addPass( \
2158 RequireAnalysisPass< \
2159 std::remove_reference_t<decltype(CREATE_PASS)>, Module>()); \
2160 return Error::success(); \
2161 } \
2162 if (Name == "invalidate<" NAME ">") { \
2163 MPM.addPass(InvalidateAnalysisPass< \
2164 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2165 return Error::success(); \
2166 }
2167#define CGSCC_PASS(NAME, CREATE_PASS) \
2168 if (Name == NAME) { \
2169 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(CREATE_PASS)); \
2170 return Error::success(); \
2171 }
2172#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2173 if (checkParametrizedPassName(Name, NAME)) { \
2174 auto Params = parsePassParameters(PARSER, Name, NAME); \
2175 if (!Params) \
2176 return Params.takeError(); \
2177 MPM.addPass( \
2178 createModuleToPostOrderCGSCCPassAdaptor(CREATE_PASS(Params.get()))); \
2179 return Error::success(); \
2180 }
2181#define FUNCTION_PASS(NAME, CREATE_PASS) \
2182 if (Name == NAME) { \
2183 if constexpr (std::is_constructible_v< \
2184 std::remove_reference_t<decltype(CREATE_PASS)>, \
2185 const TargetMachine &>) { \
2186 if (!TM) \
2187 return make_error<StringError>( \
2188 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2189 inconvertibleErrorCode()); \
2190 } \
2191 MPM.addPass(createModuleToFunctionPassAdaptor(CREATE_PASS)); \
2192 return Error::success(); \
2193 }
2194#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2195 if (checkParametrizedPassName(Name, NAME)) { \
2196 auto Params = parsePassParameters(PARSER, Name, NAME); \
2197 if (!Params) \
2198 return Params.takeError(); \
2199 auto CreatePass = CREATE_PASS; \
2200 if constexpr (std::is_constructible_v< \
2201 std::remove_reference_t<decltype(CreatePass( \
2202 Params.get()))>, \
2203 const TargetMachine &, \
2204 std::remove_reference_t<decltype(Params.get())>>) { \
2205 if (!TM) { \
2206 return make_error<StringError>( \
2207 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2208 inconvertibleErrorCode()); \
2209 } \
2210 } \
2211 MPM.addPass(createModuleToFunctionPassAdaptor(CREATE_PASS(Params.get()))); \
2212 return Error::success(); \
2213 }
2214#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2215 if (Name == NAME) { \
2216 MPM.addPass(createModuleToFunctionPassAdaptor( \
2217 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2218 return Error::success(); \
2219 }
2220#define LOOP_PASS(NAME, CREATE_PASS) \
2221 if (Name == NAME) { \
2222 MPM.addPass(createModuleToFunctionPassAdaptor( \
2223 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2224 return Error::success(); \
2225 }
2226#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2227 if (checkParametrizedPassName(Name, NAME)) { \
2228 auto Params = parsePassParameters(PARSER, Name, NAME); \
2229 if (!Params) \
2230 return Params.takeError(); \
2231 MPM.addPass(createModuleToFunctionPassAdaptor( \
2232 createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), false))); \
2233 return Error::success(); \
2234 }
2235#include "PassRegistry.def"
2236
2237 for (auto &C : ModulePipelineParsingCallbacks)
2238 if (C(Name, MPM, InnerPipeline))
2239 return Error::success();
2241 formatv("unknown module pass '{}'", Name).str(),
2243}
2244
2245Error PassBuilder::parseCGSCCPass(CGSCCPassManager &CGPM,
2246 const PipelineElement &E) {
2247 auto &Name = E.Name;
2248 auto &InnerPipeline = E.InnerPipeline;
2249
2250 // First handle complex passes like the pass managers which carry pipelines.
2251 if (!InnerPipeline.empty()) {
2252 if (Name == "cgscc") {
2253 CGSCCPassManager NestedCGPM;
2254 if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline))
2255 return Err;
2256 // Add the nested pass manager with the appropriate adaptor.
2257 CGPM.addPass(std::move(NestedCGPM));
2258 return Error::success();
2259 }
2260 if (auto Params = parseFunctionPipelineName(Name)) {
2262 if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline))
2263 return Err;
2264 // Add the nested pass manager with the appropriate adaptor.
2266 std::move(FPM), Params->first, Params->second));
2267 return Error::success();
2268 }
2269 if (auto MaxRepetitions = parseDevirtPassName(Name)) {
2270 CGSCCPassManager NestedCGPM;
2271 if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline))
2272 return Err;
2273 CGPM.addPass(
2274 createDevirtSCCRepeatedPass(std::move(NestedCGPM), *MaxRepetitions));
2275 return Error::success();
2276 }
2277
2278 for (auto &C : CGSCCPipelineParsingCallbacks)
2279 if (C(Name, CGPM, InnerPipeline))
2280 return Error::success();
2281
2282 // Normal passes can't have pipelines.
2284 formatv("invalid use of '{}' pass as cgscc pipeline", Name).str(),
2286 }
2287
2288// Now expand the basic registered passes from the .inc file.
2289#define CGSCC_PASS(NAME, CREATE_PASS) \
2290 if (Name == NAME) { \
2291 CGPM.addPass(CREATE_PASS); \
2292 return Error::success(); \
2293 }
2294#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2295 if (checkParametrizedPassName(Name, NAME)) { \
2296 auto Params = parsePassParameters(PARSER, Name, NAME); \
2297 if (!Params) \
2298 return Params.takeError(); \
2299 CGPM.addPass(CREATE_PASS(Params.get())); \
2300 return Error::success(); \
2301 }
2302#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
2303 if (Name == "require<" NAME ">") { \
2304 CGPM.addPass(RequireAnalysisPass< \
2305 std::remove_reference_t<decltype(CREATE_PASS)>, \
2306 LazyCallGraph::SCC, CGSCCAnalysisManager, LazyCallGraph &, \
2307 CGSCCUpdateResult &>()); \
2308 return Error::success(); \
2309 } \
2310 if (Name == "invalidate<" NAME ">") { \
2311 CGPM.addPass(InvalidateAnalysisPass< \
2312 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2313 return Error::success(); \
2314 }
2315#define FUNCTION_PASS(NAME, CREATE_PASS) \
2316 if (Name == NAME) { \
2317 if constexpr (std::is_constructible_v< \
2318 std::remove_reference_t<decltype(CREATE_PASS)>, \
2319 const TargetMachine &>) { \
2320 if (!TM) \
2321 return make_error<StringError>( \
2322 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2323 inconvertibleErrorCode()); \
2324 } \
2325 CGPM.addPass(createCGSCCToFunctionPassAdaptor(CREATE_PASS)); \
2326 return Error::success(); \
2327 }
2328#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2329 if (checkParametrizedPassName(Name, NAME)) { \
2330 auto Params = parsePassParameters(PARSER, Name, NAME); \
2331 if (!Params) \
2332 return Params.takeError(); \
2333 auto CreatePass = CREATE_PASS; \
2334 if constexpr (std::is_constructible_v< \
2335 std::remove_reference_t<decltype(CreatePass( \
2336 Params.get()))>, \
2337 const TargetMachine &, \
2338 std::remove_reference_t<decltype(Params.get())>>) { \
2339 if (!TM) { \
2340 return make_error<StringError>( \
2341 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2342 inconvertibleErrorCode()); \
2343 } \
2344 } \
2345 CGPM.addPass(createCGSCCToFunctionPassAdaptor(CREATE_PASS(Params.get()))); \
2346 return Error::success(); \
2347 }
2348#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2349 if (Name == NAME) { \
2350 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
2351 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2352 return Error::success(); \
2353 }
2354#define LOOP_PASS(NAME, CREATE_PASS) \
2355 if (Name == NAME) { \
2356 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
2357 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2358 return Error::success(); \
2359 }
2360#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2361 if (checkParametrizedPassName(Name, NAME)) { \
2362 auto Params = parsePassParameters(PARSER, Name, NAME); \
2363 if (!Params) \
2364 return Params.takeError(); \
2365 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
2366 createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), false))); \
2367 return Error::success(); \
2368 }
2369#include "PassRegistry.def"
2370
2371 for (auto &C : CGSCCPipelineParsingCallbacks)
2372 if (C(Name, CGPM, InnerPipeline))
2373 return Error::success();
2374 return make_error<StringError>(formatv("unknown cgscc pass '{}'", Name).str(),
2376}
2377
2378Error PassBuilder::parseFunctionPass(FunctionPassManager &FPM,
2379 const PipelineElement &E) {
2380 auto &Name = E.Name;
2381 auto &InnerPipeline = E.InnerPipeline;
2382
2383 // First handle complex passes like the pass managers which carry pipelines.
2384 if (!InnerPipeline.empty()) {
2385 if (Name == "function") {
2386 FunctionPassManager NestedFPM;
2387 if (auto Err = parseFunctionPassPipeline(NestedFPM, InnerPipeline))
2388 return Err;
2389 // Add the nested pass manager with the appropriate adaptor.
2390 FPM.addPass(std::move(NestedFPM));
2391 return Error::success();
2392 }
2393 if (Name == "loop" || Name == "loop-mssa") {
2394 LoopPassManager LPM;
2395 if (auto Err = parseLoopPassPipeline(LPM, InnerPipeline))
2396 return Err;
2397 // Add the nested pass manager with the appropriate adaptor.
2398 bool UseMemorySSA = (Name == "loop-mssa");
2399 FPM.addPass(
2400 createFunctionToLoopPassAdaptor(std::move(LPM), UseMemorySSA));
2401 return Error::success();
2402 }
2403 if (Name == "machine-function") {
2405 if (auto Err = parseMachinePassPipeline(MFPM, InnerPipeline))
2406 return Err;
2408 return Error::success();
2409 }
2410
2411 for (auto &C : FunctionPipelineParsingCallbacks)
2412 if (C(Name, FPM, InnerPipeline))
2413 return Error::success();
2414
2415 // Normal passes can't have pipelines.
2417 formatv("invalid use of '{}' pass as function pipeline", Name).str(),
2419 }
2420
2421// Now expand the basic registered passes from the .inc file.
2422#define FUNCTION_PASS(NAME, CREATE_PASS) \
2423 if (Name == NAME) { \
2424 if constexpr (std::is_constructible_v< \
2425 std::remove_reference_t<decltype(CREATE_PASS)>, \
2426 const TargetMachine &>) { \
2427 if (!TM) \
2428 return make_error<StringError>( \
2429 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2430 inconvertibleErrorCode()); \
2431 } \
2432 FPM.addPass(CREATE_PASS); \
2433 return Error::success(); \
2434 }
2435#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2436 if (checkParametrizedPassName(Name, NAME)) { \
2437 auto Params = parsePassParameters(PARSER, Name, NAME); \
2438 if (!Params) \
2439 return Params.takeError(); \
2440 auto CreatePass = CREATE_PASS; \
2441 if constexpr (std::is_constructible_v< \
2442 std::remove_reference_t<decltype(CreatePass( \
2443 Params.get()))>, \
2444 const TargetMachine &, \
2445 std::remove_reference_t<decltype(Params.get())>>) { \
2446 if (!TM) { \
2447 return make_error<StringError>( \
2448 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2449 inconvertibleErrorCode()); \
2450 } \
2451 } \
2452 FPM.addPass(CREATE_PASS(Params.get())); \
2453 return Error::success(); \
2454 }
2455#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
2456 if (Name == "require<" NAME ">") { \
2457 if constexpr (std::is_constructible_v< \
2458 std::remove_reference_t<decltype(CREATE_PASS)>, \
2459 const TargetMachine &>) { \
2460 if (!TM) \
2461 return make_error<StringError>( \
2462 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2463 inconvertibleErrorCode()); \
2464 } \
2465 FPM.addPass( \
2466 RequireAnalysisPass<std::remove_reference_t<decltype(CREATE_PASS)>, \
2467 Function>()); \
2468 return Error::success(); \
2469 } \
2470 if (Name == "invalidate<" NAME ">") { \
2471 FPM.addPass(InvalidateAnalysisPass< \
2472 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2473 return Error::success(); \
2474 }
2475// FIXME: UseMemorySSA is set to false. Maybe we could do things like:
2476// bool UseMemorySSA = !("canon-freeze" || "loop-predication" ||
2477// "guard-widening");
2478// The risk is that it may become obsolete if we're not careful.
2479#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2480 if (Name == NAME) { \
2481 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS, false)); \
2482 return Error::success(); \
2483 }
2484#define LOOP_PASS(NAME, CREATE_PASS) \
2485 if (Name == NAME) { \
2486 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS, false)); \
2487 return Error::success(); \
2488 }
2489#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2490 if (checkParametrizedPassName(Name, NAME)) { \
2491 auto Params = parsePassParameters(PARSER, Name, NAME); \
2492 if (!Params) \
2493 return Params.takeError(); \
2494 FPM.addPass( \
2495 createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), false)); \
2496 return Error::success(); \
2497 }
2498#include "PassRegistry.def"
2499
2500 for (auto &C : FunctionPipelineParsingCallbacks)
2501 if (C(Name, FPM, InnerPipeline))
2502 return Error::success();
2504 formatv("unknown function pass '{}'", Name).str(),
2506}
2507
2508Error PassBuilder::parseLoopPass(LoopPassManager &LPM,
2509 const PipelineElement &E) {
2510 StringRef Name = E.Name;
2511 auto &InnerPipeline = E.InnerPipeline;
2512
2513 // First handle complex passes like the pass managers which carry pipelines.
2514 if (!InnerPipeline.empty()) {
2515 if (Name == "loop") {
2516 LoopPassManager NestedLPM;
2517 if (auto Err = parseLoopPassPipeline(NestedLPM, InnerPipeline))
2518 return Err;
2519 // Add the nested pass manager with the appropriate adaptor.
2520 LPM.addPass(std::move(NestedLPM));
2521 return Error::success();
2522 }
2523
2524 for (auto &C : LoopPipelineParsingCallbacks)
2525 if (C(Name, LPM, InnerPipeline))
2526 return Error::success();
2527
2528 // Normal passes can't have pipelines.
2530 formatv("invalid use of '{}' pass as loop pipeline", Name).str(),
2532 }
2533
2534// Now expand the basic registered passes from the .inc file.
2535#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2536 if (Name == NAME) { \
2537 LPM.addPass(CREATE_PASS); \
2538 return Error::success(); \
2539 }
2540#define LOOP_PASS(NAME, CREATE_PASS) \
2541 if (Name == NAME) { \
2542 LPM.addPass(CREATE_PASS); \
2543 return Error::success(); \
2544 }
2545#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2546 if (checkParametrizedPassName(Name, NAME)) { \
2547 auto Params = parsePassParameters(PARSER, Name, NAME); \
2548 if (!Params) \
2549 return Params.takeError(); \
2550 LPM.addPass(CREATE_PASS(Params.get())); \
2551 return Error::success(); \
2552 }
2553#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
2554 if (Name == "require<" NAME ">") { \
2555 LPM.addPass(RequireAnalysisPass< \
2556 std::remove_reference_t<decltype(CREATE_PASS)>, Loop, \
2557 LoopAnalysisManager, LoopStandardAnalysisResults &, \
2558 LPMUpdater &>()); \
2559 return Error::success(); \
2560 } \
2561 if (Name == "invalidate<" NAME ">") { \
2562 LPM.addPass(InvalidateAnalysisPass< \
2563 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2564 return Error::success(); \
2565 }
2566#include "PassRegistry.def"
2567
2568 for (auto &C : LoopPipelineParsingCallbacks)
2569 if (C(Name, LPM, InnerPipeline))
2570 return Error::success();
2571 return make_error<StringError>(formatv("unknown loop pass '{}'", Name).str(),
2573}
2574
2575Error PassBuilder::parseMachinePass(MachineFunctionPassManager &MFPM,
2576 const PipelineElement &E) {
2577 StringRef Name = E.Name;
2578 // Handle any nested pass managers.
2579 if (!E.InnerPipeline.empty()) {
2580 if (E.Name == "machine-function") {
2582 if (auto Err = parseMachinePassPipeline(NestedPM, E.InnerPipeline))
2583 return Err;
2584 MFPM.addPass(std::move(NestedPM));
2585 return Error::success();
2586 }
2587 return make_error<StringError>("invalid pipeline",
2589 }
2590
2591#define MACHINE_MODULE_PASS(NAME, CREATE_PASS) \
2592 if (Name == NAME) { \
2593 MFPM.addPass(CREATE_PASS); \
2594 return Error::success(); \
2595 }
2596#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
2597 if (Name == NAME) { \
2598 MFPM.addPass(CREATE_PASS); \
2599 return Error::success(); \
2600 }
2601#define MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, \
2602 PARAMS) \
2603 if (checkParametrizedPassName(Name, NAME)) { \
2604 auto Params = parsePassParameters(PARSER, Name, NAME); \
2605 if (!Params) \
2606 return Params.takeError(); \
2607 MFPM.addPass(CREATE_PASS(Params.get())); \
2608 return Error::success(); \
2609 }
2610#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
2611 if (Name == "require<" NAME ">") { \
2612 MFPM.addPass( \
2613 RequireAnalysisPass<std::remove_reference_t<decltype(CREATE_PASS)>, \
2614 MachineFunction>()); \
2615 return Error::success(); \
2616 } \
2617 if (Name == "invalidate<" NAME ">") { \
2618 MFPM.addPass(InvalidateAnalysisPass< \
2619 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2620 return Error::success(); \
2621 }
2622#include "llvm/Passes/MachinePassRegistry.def"
2623
2624 for (auto &C : MachineFunctionPipelineParsingCallbacks)
2625 if (C(Name, MFPM, E.InnerPipeline))
2626 return Error::success();
2628 formatv("unknown machine pass '{}'", Name).str(),
2630}
2631
2632bool PassBuilder::parseAAPassName(AAManager &AA, StringRef Name) {
2633#define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
2634 if (Name == NAME) { \
2635 AA.registerModuleAnalysis< \
2636 std::remove_reference_t<decltype(CREATE_PASS)>>(); \
2637 return true; \
2638 }
2639#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
2640 if (Name == NAME) { \
2641 AA.registerFunctionAnalysis< \
2642 std::remove_reference_t<decltype(CREATE_PASS)>>(); \
2643 return true; \
2644 }
2645#include "PassRegistry.def"
2646
2647 for (auto &C : AAParsingCallbacks)
2648 if (C(Name, AA))
2649 return true;
2650 return false;
2651}
2652
2653Error PassBuilder::parseMachinePassPipeline(
2655 for (const auto &Element : Pipeline) {
2656 if (auto Err = parseMachinePass(MFPM, Element))
2657 return Err;
2658 }
2659 return Error::success();
2660}
2661
2662Error PassBuilder::parseLoopPassPipeline(LoopPassManager &LPM,
2663 ArrayRef<PipelineElement> Pipeline) {
2664 for (const auto &Element : Pipeline) {
2665 if (auto Err = parseLoopPass(LPM, Element))
2666 return Err;
2667 }
2668 return Error::success();
2669}
2670
2671Error PassBuilder::parseFunctionPassPipeline(
2673 for (const auto &Element : Pipeline) {
2674 if (auto Err = parseFunctionPass(FPM, Element))
2675 return Err;
2676 }
2677 return Error::success();
2678}
2679
2680Error PassBuilder::parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
2681 ArrayRef<PipelineElement> Pipeline) {
2682 for (const auto &Element : Pipeline) {
2683 if (auto Err = parseCGSCCPass(CGPM, Element))
2684 return Err;
2685 }
2686 return Error::success();
2687}
2688
2694 MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });
2695 MAM.registerPass([&] { return CGSCCAnalysisManagerModuleProxy(CGAM); });
2696 CGAM.registerPass([&] { return ModuleAnalysisManagerCGSCCProxy(MAM); });
2697 FAM.registerPass([&] { return CGSCCAnalysisManagerFunctionProxy(CGAM); });
2698 FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); });
2699 FAM.registerPass([&] { return LoopAnalysisManagerFunctionProxy(LAM); });
2700 LAM.registerPass([&] { return FunctionAnalysisManagerLoopProxy(FAM); });
2701 if (MFAM) {
2702 MAM.registerPass(
2703 [&] { return MachineFunctionAnalysisManagerModuleProxy(*MFAM); });
2704 FAM.registerPass(
2705 [&] { return MachineFunctionAnalysisManagerFunctionProxy(*MFAM); });
2706 MFAM->registerPass(
2708 MFAM->registerPass(
2710 }
2711}
2712
2713Error PassBuilder::parseModulePassPipeline(ModulePassManager &MPM,
2714 ArrayRef<PipelineElement> Pipeline) {
2715 for (const auto &Element : Pipeline) {
2716 if (auto Err = parseModulePass(MPM, Element))
2717 return Err;
2718 }
2719 return Error::success();
2720}
2721
2722// Primary pass pipeline description parsing routine for a \c ModulePassManager
2723// FIXME: Should this routine accept a TargetMachine or require the caller to
2724// pre-populate the analysis managers with target-specific stuff?
2726 StringRef PipelineText) {
2727 auto Pipeline = parsePipelineText(PipelineText);
2728 if (!Pipeline || Pipeline->empty())
2730 formatv("invalid pipeline '{}'", PipelineText).str(),
2732
2733 // If the first name isn't at the module layer, wrap the pipeline up
2734 // automatically.
2735 StringRef FirstName = Pipeline->front().Name;
2736
2737 if (!isModulePassName(FirstName, ModulePipelineParsingCallbacks)) {
2738 bool UseMemorySSA;
2739 if (isCGSCCPassName(FirstName, CGSCCPipelineParsingCallbacks)) {
2740 Pipeline = {{"cgscc", std::move(*Pipeline)}};
2741 } else if (isFunctionPassName(FirstName,
2742 FunctionPipelineParsingCallbacks)) {
2743 Pipeline = {{"function", std::move(*Pipeline)}};
2744 } else if (isLoopNestPassName(FirstName, LoopPipelineParsingCallbacks,
2745 UseMemorySSA)) {
2746 Pipeline = {{"function", {{UseMemorySSA ? "loop-mssa" : "loop",
2747 std::move(*Pipeline)}}}};
2748 } else if (isLoopPassName(FirstName, LoopPipelineParsingCallbacks,
2749 UseMemorySSA)) {
2750 Pipeline = {{"function", {{UseMemorySSA ? "loop-mssa" : "loop",
2751 std::move(*Pipeline)}}}};
2752 } else if (isMachineFunctionPassName(
2753 FirstName, MachineFunctionPipelineParsingCallbacks)) {
2754 Pipeline = {{"function", {{"machine-function", std::move(*Pipeline)}}}};
2755 } else {
2756 for (auto &C : TopLevelPipelineParsingCallbacks)
2757 if (C(MPM, *Pipeline))
2758 return Error::success();
2759
2760 // Unknown pass or pipeline name!
2761 auto &InnerPipeline = Pipeline->front().InnerPipeline;
2763 formatv("unknown {} name '{}'",
2764 (InnerPipeline.empty() ? "pass" : "pipeline"), FirstName)
2765 .str(),
2767 }
2768 }
2769
2770 if (auto Err = parseModulePassPipeline(MPM, *Pipeline))
2771 return Err;
2772 return Error::success();
2773}
2774
2775// Primary pass pipeline description parsing routine for a \c CGSCCPassManager
2777 StringRef PipelineText) {
2778 auto Pipeline = parsePipelineText(PipelineText);
2779 if (!Pipeline || Pipeline->empty())
2781 formatv("invalid pipeline '{}'", PipelineText).str(),
2783
2784 StringRef FirstName = Pipeline->front().Name;
2785 if (!isCGSCCPassName(FirstName, CGSCCPipelineParsingCallbacks))
2787 formatv("unknown cgscc pass '{}' in pipeline '{}'", FirstName,
2788 PipelineText)
2789 .str(),
2791
2792 if (auto Err = parseCGSCCPassPipeline(CGPM, *Pipeline))
2793 return Err;
2794 return Error::success();
2795}
2796
2797// Primary pass pipeline description parsing routine for a \c
2798// FunctionPassManager
2800 StringRef PipelineText) {
2801 auto Pipeline = parsePipelineText(PipelineText);
2802 if (!Pipeline || Pipeline->empty())
2804 formatv("invalid pipeline '{}'", PipelineText).str(),
2806
2807 StringRef FirstName = Pipeline->front().Name;
2808 if (!isFunctionPassName(FirstName, FunctionPipelineParsingCallbacks))
2810 formatv("unknown function pass '{}' in pipeline '{}'", FirstName,
2811 PipelineText)
2812 .str(),
2814
2815 if (auto Err = parseFunctionPassPipeline(FPM, *Pipeline))
2816 return Err;
2817 return Error::success();
2818}
2819
2820// Primary pass pipeline description parsing routine for a \c LoopPassManager
2822 StringRef PipelineText) {
2823 auto Pipeline = parsePipelineText(PipelineText);
2824 if (!Pipeline || Pipeline->empty())
2826 formatv("invalid pipeline '{}'", PipelineText).str(),
2828
2829 if (auto Err = parseLoopPassPipeline(CGPM, *Pipeline))
2830 return Err;
2831
2832 return Error::success();
2833}
2834
2836 StringRef PipelineText) {
2837 auto Pipeline = parsePipelineText(PipelineText);
2838 if (!Pipeline || Pipeline->empty())
2840 formatv("invalid machine pass pipeline '{}'", PipelineText).str(),
2842
2843 if (auto Err = parseMachinePassPipeline(MFPM, *Pipeline))
2844 return Err;
2845
2846 return Error::success();
2847}
2848
2850 // If the pipeline just consists of the word 'default' just replace the AA
2851 // manager with our default one.
2852 if (PipelineText == "default") {
2854 return Error::success();
2855 }
2856
2857 while (!PipelineText.empty()) {
2858 StringRef Name;
2859 std::tie(Name, PipelineText) = PipelineText.split(',');
2860 if (!parseAAPassName(AA, Name))
2862 formatv("unknown alias analysis name '{}'", Name).str(),
2864 }
2865
2866 return Error::success();
2867}
2868
2869std::optional<RegAllocFilterFunc>
2871 if (FilterName == "all")
2872 return nullptr;
2873 for (auto &C : RegClassFilterParsingCallbacks)
2874 if (auto F = C(FilterName))
2875 return F;
2876 return std::nullopt;
2877}
2878
2880 raw_ostream &OS) {
2881 for (StringRef PassName : PassNames)
2882 OS << " " << PassName << '\n';
2883}
2884
2885LLVM_ATTRIBUTE_NOINLINE static void
2887 auto I = PassNames.begin();
2888 auto End = PassNames.end();
2889 while (I != End) {
2890 StringRef Name = *I;
2891 ++I;
2892 assert(I != End);
2893 StringRef Params = *I;
2894 ++I;
2895 OS << " " << Name << '<' << Params << ">\n";
2896 }
2897}
2898
2900 // TODO: print pass descriptions when they are available
2901
2902 OS << "Module passes:\n";
2903 static constexpr char ModulePassNames[] = {"\0"
2904#define MODULE_PASS(NAME, CREATE_PASS) NAME "\0"
2905#include "PassRegistry.def"
2906 };
2907 printPassNameList(StringTable(ModulePassNames), OS);
2908
2909 OS << "Module passes with params:\n";
2910 static constexpr char ModulePassNamesWithParams[] = {"\0"
2911#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2912 NAME "\0" PARAMS "\0"
2913#include "PassRegistry.def"
2914 };
2915 printPassNameListWithParams(StringTable(ModulePassNamesWithParams), OS);
2916
2917 OS << "Module analyses:\n";
2918 static constexpr char ModuleAnalysisNames[] = {"\0"
2919#define MODULE_ANALYSIS(NAME, CREATE_PASS) NAME "\0"
2920#include "PassRegistry.def"
2921 };
2922 printPassNameList(StringTable(ModuleAnalysisNames), OS);
2923
2924 OS << "Module alias analyses:\n";
2925 static constexpr char ModuleAliasAnalysisNames[] = {"\0"
2926#define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) NAME "\0"
2927#include "PassRegistry.def"
2928 };
2929 printPassNameList(StringTable(ModuleAliasAnalysisNames), OS);
2930
2931 OS << "CGSCC passes:\n";
2932 static constexpr char CGSCCPassNames[] = {"\0"
2933#define CGSCC_PASS(NAME, CREATE_PASS) NAME "\0"
2934#include "PassRegistry.def"
2935 };
2936 printPassNameList(StringTable(CGSCCPassNames), OS);
2937
2938 OS << "CGSCC passes with params:\n";
2939 static constexpr char CGSCCPassNamesWithParams[] = {"\0"
2940#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2941 NAME "\0" PARAMS "\0"
2942#include "PassRegistry.def"
2943 };
2944 printPassNameListWithParams(StringTable(CGSCCPassNamesWithParams), OS);
2945
2946 OS << "CGSCC analyses:\n";
2947 static constexpr char CGSCCAnalysisNames[] = {"\0"
2948#define CGSCC_ANALYSIS(NAME, CREATE_PASS) NAME "\0"
2949#include "PassRegistry.def"
2950 };
2951 printPassNameList(StringTable(CGSCCAnalysisNames), OS);
2952
2953 OS << "Function passes:\n";
2954 static constexpr char FunctionPassNames[] = {"\0"
2955#define FUNCTION_PASS(NAME, CREATE_PASS) NAME "\0"
2956#include "PassRegistry.def"
2957 };
2958 printPassNameList(StringTable(FunctionPassNames), OS);
2959
2960 OS << "Function passes with params:\n";
2961 static constexpr char FunctionPassNamesWithParams[] = {"\0"
2962#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2963 NAME "\0" PARAMS "\0"
2964#include "PassRegistry.def"
2965 };
2966 printPassNameListWithParams(StringTable(FunctionPassNamesWithParams), OS);
2967
2968 OS << "Function analyses:\n";
2969 static constexpr char FunctionAnalysisNames[] = {"\0"
2970#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) NAME "\0"
2971#include "PassRegistry.def"
2972 };
2973 printPassNameList(StringTable(FunctionAnalysisNames), OS);
2974
2975 OS << "Function alias analyses:\n";
2976 static constexpr char FunctionAliasAnalysisNames[] = {"\0"
2977#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) NAME "\0"
2978#include "PassRegistry.def"
2979 };
2980 printPassNameList(StringTable(FunctionAliasAnalysisNames), OS);
2981
2982 OS << "LoopNest passes:\n";
2983 static constexpr char LoopNestPassNames[] = {"\0"
2984#define LOOPNEST_PASS(NAME, CREATE_PASS) NAME "\0"
2985#include "PassRegistry.def"
2986 };
2987 printPassNameList(StringTable(LoopNestPassNames), OS);
2988
2989 OS << "Loop passes:\n";
2990 static constexpr char LoopPassNames[] = {"\0"
2991#define LOOP_PASS(NAME, CREATE_PASS) NAME "\0"
2992#include "PassRegistry.def"
2993 };
2994 printPassNameList(StringTable(LoopPassNames), OS);
2995
2996 OS << "Loop passes with params:\n";
2997 static constexpr char LoopPassNamesWithParams[] = {"\0"
2998#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2999 NAME "\0" PARAMS "\0"
3000#include "PassRegistry.def"
3001 };
3002 printPassNameListWithParams(StringTable(LoopPassNamesWithParams), OS);
3003
3004 OS << "Loop analyses:\n";
3005 static constexpr char LoopAnalysisNames[] = {"\0"
3006#define LOOP_ANALYSIS(NAME, CREATE_PASS) NAME "\0"
3007#include "PassRegistry.def"
3008 };
3009 printPassNameList(StringTable(LoopAnalysisNames), OS);
3010
3011 OS << "Machine module passes (WIP):\n";
3012 static constexpr char MachineModulePassNames[] = {"\0"
3013#define MACHINE_MODULE_PASS(NAME, CREATE_PASS) NAME "\0"
3014#include "llvm/Passes/MachinePassRegistry.def"
3015 };
3016 printPassNameList(StringTable(MachineModulePassNames), OS);
3017
3018 OS << "Machine function passes (WIP):\n";
3019 static constexpr char MachineFunctionPassNames[] = {"\0"
3020#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) NAME "\0"
3021#include "llvm/Passes/MachinePassRegistry.def"
3022 };
3023 printPassNameList(StringTable(MachineFunctionPassNames), OS);
3024
3025 OS << "Machine function analyses (WIP):\n";
3026 static constexpr char MachineFunctionAnalysisNames[] = {"\0"
3027#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) NAME "\0"
3028#include "llvm/Passes/MachinePassRegistry.def"
3029 };
3030 printPassNameList(StringTable(MachineFunctionAnalysisNames), OS);
3031}
3032
3034 const std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>)>
3035 &C) {
3036 TopLevelPipelineParsingCallbacks.push_back(C);
3037}
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)