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"
211#include "llvm/IR/DebugInfo.h"
212#include "llvm/IR/Dominators.h"
213#include "llvm/IR/PassManager.h"
215#include "llvm/IR/Verifier.h"
219#include "llvm/Support/CodeGen.h"
221#include "llvm/Support/Debug.h"
222#include "llvm/Support/Error.h"
226#include "llvm/Support/Regex.h"
420#include <optional>
421
422using namespace llvm;
423
427 "print-pipeline-passes", cl::ValueOptional,
428 cl::desc(
429 "Print string describing the pipeline (best-effort only).\n"
430 " - =text\tPrint a '-passes' compatible string describing the "
431 "pipeline.\n"
432 " - =tree\tPrint a tree-like structure describing the pipeline."));
433
435 cl::Option &O, StringRef ArgName, StringRef Arg,
436 std::optional<PrintPipelinePassesFormat> &Val) {
437 std::optional<PrintPipelinePassesFormat> Format =
442 .Default(std::nullopt);
443
444 if (!Format)
445 return O.error(formatv(
446 "'{0}' value invalid for print-pipeline-passes argument!", Arg));
447
448 Val = Format;
449 return false;
450}
451
454 switch (Format) {
456 OS << Pipeline;
457 break;
459 int IndentLevel = 0;
460 for (char C : Pipeline) {
461 switch (C) {
462 case '(':
463 ++IndentLevel;
464 OS << formatv("\n{0}", fmt_repeat(" ", IndentLevel));
465 break;
466 case ')':
467 --IndentLevel;
468 assert(IndentLevel >= 0 && "Invalid pipeline string!");
469 break;
470 case ',':
471 OS << formatv("\n{0}", fmt_repeat(" ", IndentLevel));
472 break;
473 default:
474 OS << C;
475 }
476 }
477 break;
478 }
479 }
480}
481
482AnalysisKey NoOpModuleAnalysis::Key;
483AnalysisKey NoOpCGSCCAnalysis::Key;
484AnalysisKey NoOpFunctionAnalysis::Key;
485AnalysisKey NoOpLoopAnalysis::Key;
486
487namespace {
488
489bool applyMIRDebugify(DIBuilder &DIB, Function &F, ModuleAnalysisManager &AM) {
492 .getManager();
493
495 DIB, F, [&](Function &Func) -> MachineFunction * {
497 FAM.getCachedResult<MachineFunctionAnalysis>(Func);
498 return MFA ? &MFA->getMF() : nullptr;
499 });
500}
501
502// A pass for testing message reporting of -verify-each failures.
503// DO NOT USE THIS EXCEPT FOR TESTING!
504class TriggerVerifierErrorPass
505 : public OptionalPassInfoMixin<TriggerVerifierErrorPass> {
506public:
507 PreservedAnalyses run(Module &M, ModuleAnalysisManager &) {
508 // Intentionally break the Module by creating an alias without setting the
509 // aliasee.
510 auto *PtrTy = PointerType::getUnqual(M.getContext());
511 GlobalAlias::create(PtrTy, PtrTy->getAddressSpace(),
512 GlobalValue::LinkageTypes::InternalLinkage,
513 "__bad_alias", nullptr, &M);
515 }
516
517 PreservedAnalyses run(Function &F, FunctionAnalysisManager &) {
518 // Intentionally break the Function by inserting a terminator
519 // instruction in the middle of a basic block.
520 BasicBlock &BB = F.getEntryBlock();
521 new UnreachableInst(F.getContext(), BB.getTerminator()->getIterator());
523 }
524
525 PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &) {
526 // Intentionally create a virtual register and set NoVRegs property.
527 auto &MRI = MF.getRegInfo();
529 MF.getProperties().setNoVRegs();
530 return PreservedAnalyses::all();
531 }
532
533 static StringRef name() { return "TriggerVerifierErrorPass"; }
534};
535
536// A pass requires all MachineFunctionProperties.
537// DO NOT USE THIS EXCEPT FOR TESTING!
538class RequireAllMachineFunctionPropertiesPass
539 : public OptionalPassInfoMixin<RequireAllMachineFunctionPropertiesPass> {
540public:
541 PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &) {
542 MFPropsModifier _(*this, MF);
544 }
545
546 static MachineFunctionProperties getRequiredProperties() {
547 return MachineFunctionProperties()
548 .setFailedISel()
549 .setFailsVerification()
550 .setIsSSA()
551 .setLegalized()
552 .setNoPHIs()
553 .setNoVRegs()
554 .setRegBankSelected()
555 .setSelected()
556 .setTiedOpsRewritten()
557 .setTracksDebugUserValues()
558 .setTracksLiveness();
559 }
560 static StringRef name() { return "RequireAllMachineFunctionPropertiesPass"; }
561};
562
563} // namespace
564
565static std::optional<OptimizationLevel> parseOptLevel(StringRef S) {
566 if (S == "Os" || S == "Oz")
568 Twine("The optimization level \"") + S +
569 "\" is no longer supported. Use O2 in conjunction with the " +
570 (S == "Os" ? "optsize" : "minsize") + " attribute instead.");
571
573 .Case("O0", OptimizationLevel::O0)
577 .Default(std::nullopt);
578}
579
581 std::optional<OptimizationLevel> OptLevel = parseOptLevel(S);
582 if (OptLevel)
583 return *OptLevel;
585 formatv("invalid optimization level '{}'", S).str(),
587}
588
590 std::optional<PGOOptions> PGOOpt,
593 : TM(TM), PTO(PTO), PGOOpt(PGOOpt), PIC(PIC), FS(std::move(FS)) {
594 if (TM)
595 TM->registerPassBuilderCallbacks(*this);
596 if (PIC) {
597 PIC->registerClassToPassNameCallback([this, PIC]() {
598 // MSVC requires this to be captured if it's used inside decltype.
599 // Other compilers consider it an unused lambda capture.
600 (void)this;
601#define MODULE_PASS(NAME, CREATE_PASS) \
602 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
603#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
604 PIC->addClassToPassName(CLASS, NAME);
605#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
606 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
607#define FUNCTION_PASS(NAME, CREATE_PASS) \
608 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
609#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
610 PIC->addClassToPassName(CLASS, NAME);
611#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
612 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
613#define LOOPNEST_PASS(NAME, CREATE_PASS) \
614 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
615#define LOOP_PASS(NAME, CREATE_PASS) \
616 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
617#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
618 PIC->addClassToPassName(CLASS, NAME);
619#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
620 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
621#define CGSCC_PASS(NAME, CREATE_PASS) \
622 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
623#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
624 PIC->addClassToPassName(CLASS, NAME);
625#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
626 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
627#include "PassRegistry.def"
628
629#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
630 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
631#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
632 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
633#define MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, \
634 PARAMS) \
635 PIC->addClassToPassName(CLASS, NAME);
636#include "llvm/Passes/MachinePassRegistry.def"
637 });
638 }
639
640 // Module-level callbacks without LTO phase
642 [this](StringRef Name, ModulePassManager &PM,
644#define MODULE_CALLBACK(NAME, INVOKE) \
645 if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
646 auto L = PassBuilder::parsePassParameters(parseOptLevelParam, Name, NAME); \
647 if (!L) { \
648 errs() << NAME ": " << toString(L.takeError()) << '\n'; \
649 return false; \
650 } \
651 INVOKE(PM, L.get()); \
652 return true; \
653 }
654#include "PassRegistry.def"
655 return false;
656 });
657
658 // Module-level callbacks with LTO phase (use Phase::None for string API)
660 [this](StringRef Name, ModulePassManager &PM,
662#define MODULE_LTO_CALLBACK(NAME, INVOKE) \
663 if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
664 auto L = PassBuilder::parsePassParameters(parseOptLevelParam, Name, NAME); \
665 if (!L) { \
666 errs() << NAME ": " << toString(L.takeError()) << '\n'; \
667 return false; \
668 } \
669 INVOKE(PM, L.get(), ThinOrFullLTOPhase::None); \
670 return true; \
671 }
672#include "PassRegistry.def"
673 return false;
674 });
675
676 // Function-level callbacks
678 [this](StringRef Name, FunctionPassManager &PM,
680#define FUNCTION_CALLBACK(NAME, INVOKE) \
681 if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
682 auto L = PassBuilder::parsePassParameters(parseOptLevelParam, Name, NAME); \
683 if (!L) { \
684 errs() << NAME ": " << toString(L.takeError()) << '\n'; \
685 return false; \
686 } \
687 INVOKE(PM, L.get()); \
688 return true; \
689 }
690#include "PassRegistry.def"
691 return false;
692 });
693
694 // CGSCC-level callbacks
696 [this](StringRef Name, CGSCCPassManager &PM,
698#define CGSCC_CALLBACK(NAME, INVOKE) \
699 if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
700 auto L = PassBuilder::parsePassParameters(parseOptLevelParam, Name, NAME); \
701 if (!L) { \
702 errs() << NAME ": " << toString(L.takeError()) << '\n'; \
703 return false; \
704 } \
705 INVOKE(PM, L.get()); \
706 return true; \
707 }
708#include "PassRegistry.def"
709 return false;
710 });
711
712 // Loop-level callbacks
714 [this](StringRef Name, LoopPassManager &PM,
716#define LOOP_CALLBACK(NAME, INVOKE) \
717 if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
718 auto L = PassBuilder::parsePassParameters(parseOptLevelParam, Name, NAME); \
719 if (!L) { \
720 errs() << NAME ": " << toString(L.takeError()) << '\n'; \
721 return false; \
722 } \
723 INVOKE(PM, L.get()); \
724 return true; \
725 }
726#include "PassRegistry.def"
727 return false;
728 });
729}
730
732#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
733 MAM.registerPass([&] { return CREATE_PASS; });
734#include "PassRegistry.def"
735
736 for (auto &C : ModuleAnalysisRegistrationCallbacks)
737 C(MAM);
738}
739
741#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
742 CGAM.registerPass([&] { return CREATE_PASS; });
743#include "PassRegistry.def"
744
745 for (auto &C : CGSCCAnalysisRegistrationCallbacks)
746 C(CGAM);
747}
748
750 // We almost always want the default alias analysis pipeline.
751 // If a user wants a different one, they can register their own before calling
752 // registerFunctionAnalyses().
753 FAM.registerPass([&] { return buildDefaultAAPipeline(); });
754
755#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
756 if constexpr (std::is_constructible_v< \
757 std::remove_reference_t<decltype(CREATE_PASS)>, \
758 const TargetMachine &>) { \
759 if (TM) \
760 FAM.registerPass([&] { return CREATE_PASS; }); \
761 } else { \
762 FAM.registerPass([&] { return CREATE_PASS; }); \
763 }
764#include "PassRegistry.def"
765
766 for (auto &C : FunctionAnalysisRegistrationCallbacks)
767 C(FAM);
768}
769
772
773#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
774 MFAM.registerPass([&] { return CREATE_PASS; });
775#include "llvm/Passes/MachinePassRegistry.def"
776
777 for (auto &C : MachineFunctionAnalysisRegistrationCallbacks)
778 C(MFAM);
779}
780
782#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
783 LAM.registerPass([&] { return CREATE_PASS; });
784#include "PassRegistry.def"
785
786 for (auto &C : LoopAnalysisRegistrationCallbacks)
787 C(LAM);
788}
789
790static std::optional<std::pair<bool, bool>>
792 std::pair<bool, bool> Params;
793 if (!Name.consume_front("function"))
794 return std::nullopt;
795 if (Name.empty())
796 return Params;
797 if (!Name.consume_front("<") || !Name.consume_back(">"))
798 return std::nullopt;
799 while (!Name.empty()) {
800 auto [Front, Back] = Name.split(';');
801 Name = Back;
802 if (Front == "eager-inv")
803 Params.first = true;
804 else if (Front == "no-rerun")
805 Params.second = true;
806 else
807 return std::nullopt;
808 }
809 return Params;
810}
811
812static std::optional<int> parseDevirtPassName(StringRef Name) {
813 if (!Name.consume_front("devirt<") || !Name.consume_back(">"))
814 return std::nullopt;
815 int Count;
816 if (Name.getAsInteger(0, Count) || Count < 0)
817 return std::nullopt;
818 return Count;
819}
820
822 StringRef OptionName,
824 bool Result = false;
825 while (!Params.empty()) {
826 StringRef ParamName;
827 std::tie(ParamName, Params) = Params.split(';');
828
829 if (ParamName == OptionName) {
830 Result = true;
831 } else {
833 formatv("invalid {} pass parameter '{}'", PassName, ParamName).str(),
835 }
836 }
837 return Result;
838}
839
840namespace {
841
842/// Parser of parameters for HardwareLoops pass.
843Expected<HardwareLoopOptions> parseHardwareLoopOptions(StringRef Params) {
844 HardwareLoopOptions HardwareLoopOpts;
845
846 while (!Params.empty()) {
847 StringRef ParamName;
848 std::tie(ParamName, Params) = Params.split(';');
849 if (ParamName.consume_front("hardware-loop-decrement=")) {
850 int Count;
851 if (ParamName.getAsInteger(0, Count))
853 formatv("invalid HardwareLoopPass parameter '{}'", ParamName).str(),
855 HardwareLoopOpts.setDecrement(Count);
856 continue;
857 }
858 if (ParamName.consume_front("hardware-loop-counter-bitwidth=")) {
859 int Count;
860 if (ParamName.getAsInteger(0, Count))
862 formatv("invalid HardwareLoopPass parameter '{}'", ParamName).str(),
864 HardwareLoopOpts.setCounterBitwidth(Count);
865 continue;
866 }
867 if (ParamName == "force-hardware-loops") {
868 HardwareLoopOpts.setForce(true);
869 } else if (ParamName == "force-hardware-loop-phi") {
870 HardwareLoopOpts.setForcePhi(true);
871 } else if (ParamName == "force-nested-hardware-loop") {
872 HardwareLoopOpts.setForceNested(true);
873 } else if (ParamName == "force-hardware-loop-guard") {
874 HardwareLoopOpts.setForceGuard(true);
875 } else {
877 formatv("invalid HardwarePass parameter '{}'", ParamName).str(),
879 }
880 }
881 return HardwareLoopOpts;
882}
883
884/// Parser of parameters for Lint pass.
885Expected<bool> parseLintOptions(StringRef Params) {
886 return PassBuilder::parseSinglePassOption(Params, "abort-on-error",
887 "LintPass");
888}
889
890/// Parser of parameters for FunctionPropertiesStatistics pass.
891Expected<bool> parseFunctionPropertiesStatisticsOptions(StringRef Params) {
892 return PassBuilder::parseSinglePassOption(Params, "pre-opt",
893 "FunctionPropertiesStatisticsPass");
894}
895
896/// Parser of parameters for InstCount pass.
897Expected<bool> parseInstCountOptions(StringRef Params) {
898 return PassBuilder::parseSinglePassOption(Params, "pre-opt", "InstCountPass");
899}
900
901Expected<bool> parseInferAddressSpacesPassOptions(StringRef Params) {
903 Params, "assume-default-is-flat-addrspace", "InferAddressSpacesPass");
904}
905
906/// Parser of parameters for LoopUnroll pass.
907Expected<LoopUnrollOptions> parseLoopUnrollOptions(StringRef Params) {
908 LoopUnrollOptions UnrollOpts;
909 while (!Params.empty()) {
910 StringRef ParamName;
911 std::tie(ParamName, Params) = Params.split(';');
912 std::optional<OptimizationLevel> OptLevel = parseOptLevel(ParamName);
913 if (OptLevel) {
914 UnrollOpts.setOptLevel(static_cast<int>(*OptLevel));
915 continue;
916 }
917 if (ParamName.consume_front("full-unroll-max=")) {
918 int Count;
919 if (ParamName.getAsInteger(0, Count))
921 formatv("invalid LoopUnrollPass parameter '{}'", ParamName).str(),
923 UnrollOpts.setFullUnrollMaxCount(Count);
924 continue;
925 }
926
927 bool Enable = !ParamName.consume_front("no-");
928 if (ParamName == "partial") {
929 UnrollOpts.setPartial(Enable);
930 } else if (ParamName == "peeling") {
931 UnrollOpts.setPeeling(Enable);
932 } else if (ParamName == "profile-peeling") {
933 UnrollOpts.setProfileBasedPeeling(Enable);
934 } else if (ParamName == "runtime") {
935 UnrollOpts.setRuntime(Enable);
936 } else if (ParamName == "upperbound") {
937 UnrollOpts.setUpperBound(Enable);
938 } else if (ParamName == "prepare-for-lto") {
939 UnrollOpts.setPrepareForLTO(Enable);
940 } else {
942 formatv("invalid LoopUnrollPass parameter '{}'", ParamName).str(),
944 }
945 }
946 return UnrollOpts;
947}
948
949Expected<bool> parseGlobalDCEPassOptions(StringRef Params) {
951 Params, "vfe-linkage-unit-visibility", "GlobalDCE");
952}
953
954Expected<bool> parseCGProfilePassOptions(StringRef Params) {
955 return PassBuilder::parseSinglePassOption(Params, "in-lto-post-link",
956 "CGProfile");
957}
958
959Expected<bool> parseInlinerPassOptions(StringRef Params) {
960 return PassBuilder::parseSinglePassOption(Params, "only-mandatory",
961 "InlinerPass");
962}
963
964Expected<bool> parseCoroSplitPassOptions(StringRef Params) {
965 return PassBuilder::parseSinglePassOption(Params, "reuse-storage",
966 "CoroSplitPass");
967}
968
969Expected<bool> parsePostOrderFunctionAttrsPassOptions(StringRef Params) {
971 Params, "skip-non-recursive-function-attrs", "PostOrderFunctionAttrs");
972}
973
974Expected<bool> parseEarlyCSEPassOptions(StringRef Params) {
975 return PassBuilder::parseSinglePassOption(Params, "memssa", "EarlyCSE");
976}
977
978Expected<bool> parseEntryExitInstrumenterPassOptions(StringRef Params) {
979 return PassBuilder::parseSinglePassOption(Params, "post-inline",
980 "EntryExitInstrumenter");
981}
982
983Expected<bool> parseDropUnnecessaryAssumesPassOptions(StringRef Params) {
984 return PassBuilder::parseSinglePassOption(Params, "drop-deref",
985 "DropUnnecessaryAssumes");
986}
987
988Expected<bool> parseLowerMatrixIntrinsicsPassOptions(StringRef Params) {
989 return PassBuilder::parseSinglePassOption(Params, "minimal",
990 "LowerMatrixIntrinsics");
991}
992
993Expected<IRNormalizerOptions> parseIRNormalizerPassOptions(StringRef Params) {
995 while (!Params.empty()) {
996 StringRef ParamName;
997 std::tie(ParamName, Params) = Params.split(';');
998
999 bool Enable = !ParamName.consume_front("no-");
1000 if (ParamName == "preserve-order")
1001 Result.PreserveOrder = Enable;
1002 else if (ParamName == "rename-all")
1003 Result.RenameAll = Enable;
1004 else if (ParamName == "fold-all") // FIXME: Name mismatch
1005 Result.FoldPreOutputs = Enable;
1006 else if (ParamName == "reorder-operands")
1007 Result.ReorderOperands = Enable;
1008 else {
1010 formatv("invalid normalize pass parameter '{}'", ParamName).str(),
1012 }
1013 }
1014
1015 return Result;
1016}
1017
1018Expected<AddressSanitizerOptions> parseASanPassOptions(StringRef Params) {
1020 while (!Params.empty()) {
1021 StringRef ParamName;
1022 std::tie(ParamName, Params) = Params.split(';');
1023
1024 if (ParamName == "kernel") {
1025 Result.CompileKernel = true;
1026 } else if (ParamName == "use-after-scope") {
1027 Result.UseAfterScope = true;
1028 } else {
1030 formatv("invalid AddressSanitizer pass parameter '{}'", ParamName)
1031 .str(),
1033 }
1034 }
1035 return Result;
1036}
1037
1038Expected<HWAddressSanitizerOptions> parseHWASanPassOptions(StringRef Params) {
1040 while (!Params.empty()) {
1041 StringRef ParamName;
1042 std::tie(ParamName, Params) = Params.split(';');
1043
1044 if (ParamName == "recover") {
1045 Result.Recover = true;
1046 } else if (ParamName == "kernel") {
1047 Result.CompileKernel = true;
1048 } else {
1050 formatv("invalid HWAddressSanitizer pass parameter '{}'", ParamName)
1051 .str(),
1053 }
1054 }
1055 return Result;
1056}
1057
1059parseDropTypeTestsPassOptions(StringRef Params) {
1061 while (!Params.empty()) {
1062 StringRef ParamName;
1063 std::tie(ParamName, Params) = Params.split(';');
1064
1065 if (ParamName == "all") {
1067 } else if (ParamName == "assume") {
1069 } else {
1071 formatv("invalid DropTypeTestsPass parameter '{}'", ParamName).str(),
1073 }
1074 }
1075 return Result;
1076}
1077
1078Expected<EmbedBitcodeOptions> parseEmbedBitcodePassOptions(StringRef Params) {
1080 while (!Params.empty()) {
1081 StringRef ParamName;
1082 std::tie(ParamName, Params) = Params.split(';');
1083
1084 if (ParamName == "thinlto") {
1085 Result.IsThinLTO = true;
1086 } else if (ParamName == "emit-summary") {
1087 Result.EmitLTOSummary = true;
1088 } else {
1090 formatv("invalid EmbedBitcode pass parameter '{}'", ParamName).str(),
1092 }
1093 }
1094 return Result;
1095}
1096
1098parseLowerAllowCheckPassOptions(StringRef Params) {
1100 while (!Params.empty()) {
1101 StringRef ParamName;
1102 std::tie(ParamName, Params) = Params.split(';');
1103
1104 // Format is <cutoffs[1,2,3]=70000;cutoffs[5,6,8]=90000>
1105 //
1106 // Parsing allows duplicate indices (last one takes precedence).
1107 // It would technically be in spec to specify
1108 // cutoffs[0]=70000,cutoffs[1]=90000,cutoffs[0]=80000,...
1109 if (ParamName.starts_with("cutoffs[")) {
1110 StringRef IndicesStr;
1111 StringRef CutoffStr;
1112
1113 std::tie(IndicesStr, CutoffStr) = ParamName.split("]=");
1114 // cutoffs[1,2,3
1115 // 70000
1116
1117 int cutoff;
1118 if (CutoffStr.getAsInteger(0, cutoff))
1120 formatv("invalid LowerAllowCheck pass cutoffs parameter '{}' ({})",
1121 CutoffStr, Params)
1122 .str(),
1124
1125 if (!IndicesStr.consume_front("cutoffs[") || IndicesStr == "")
1127 formatv("invalid LowerAllowCheck pass index parameter '{}' ({})",
1128 IndicesStr, CutoffStr)
1129 .str(),
1131
1132 while (IndicesStr != "") {
1133 StringRef firstIndexStr;
1134 std::tie(firstIndexStr, IndicesStr) = IndicesStr.split('|');
1135
1136 unsigned int index;
1137 if (firstIndexStr.getAsInteger(0, index))
1139 formatv(
1140 "invalid LowerAllowCheck pass index parameter '{}' ({}) {}",
1141 firstIndexStr, IndicesStr)
1142 .str(),
1144
1145 // In the common case (sequentially increasing indices), we will issue
1146 // O(n) resize requests. We assume the underlying data structure has
1147 // O(1) runtime for each added element.
1148 if (index >= Result.cutoffs.size())
1149 Result.cutoffs.resize(index + 1, 0);
1150
1151 Result.cutoffs[index] = cutoff;
1152 }
1153 } else if (ParamName.starts_with("runtime_check")) {
1154 StringRef ValueString;
1155 std::tie(std::ignore, ValueString) = ParamName.split("=");
1156 int runtime_check;
1157 if (ValueString.getAsInteger(0, runtime_check)) {
1159 formatv("invalid LowerAllowCheck pass runtime_check parameter '{}' "
1160 "({})",
1161 ValueString, Params)
1162 .str(),
1164 }
1165 Result.runtime_check = runtime_check;
1166 } else {
1168 formatv("invalid LowerAllowCheck pass parameter '{}'", ParamName)
1169 .str(),
1171 }
1172 }
1173
1174 return Result;
1175}
1176
1177Expected<MemorySanitizerOptions> parseMSanPassOptions(StringRef Params) {
1179 while (!Params.empty()) {
1180 StringRef ParamName;
1181 std::tie(ParamName, Params) = Params.split(';');
1182
1183 if (ParamName == "recover") {
1184 Result.Recover = true;
1185 } else if (ParamName == "kernel") {
1186 Result.Kernel = true;
1187 } else if (ParamName.consume_front("track-origins=")) {
1188 if (ParamName.getAsInteger(0, Result.TrackOrigins))
1190 formatv("invalid argument to MemorySanitizer pass track-origins "
1191 "parameter: '{}'",
1192 ParamName)
1193 .str(),
1195 } else if (ParamName == "eager-checks") {
1196 Result.EagerChecks = true;
1197 } else {
1199 formatv("invalid MemorySanitizer pass parameter '{}'", ParamName)
1200 .str(),
1202 }
1203 }
1204 return Result;
1205}
1206
1207Expected<AllocTokenOptions> parseAllocTokenPassOptions(StringRef Params) {
1209 while (!Params.empty()) {
1210 StringRef ParamName;
1211 std::tie(ParamName, Params) = Params.split(';');
1212
1213 if (ParamName.consume_front("mode=")) {
1214 if (auto Mode = getAllocTokenModeFromString(ParamName))
1215 Result.Mode = *Mode;
1216 else
1218 formatv("invalid argument to AllocToken pass mode "
1219 "parameter: '{}'",
1220 ParamName)
1221 .str(),
1223 } else {
1225 formatv("invalid AllocToken pass parameter '{}'", ParamName).str(),
1227 }
1228 }
1229 return Result;
1230}
1231
1232/// Parser of parameters for SimplifyCFG pass.
1233Expected<SimplifyCFGOptions> parseSimplifyCFGOptions(StringRef Params) {
1235 while (!Params.empty()) {
1236 StringRef ParamName;
1237 std::tie(ParamName, Params) = Params.split(';');
1238
1239 bool Enable = !ParamName.consume_front("no-");
1240 if (ParamName == "speculate-blocks") {
1241 Result.speculateBlocks(Enable);
1242 } else if (ParamName == "simplify-cond-branch") {
1243 Result.setSimplifyCondBranch(Enable);
1244 } else if (ParamName == "forward-switch-cond") {
1245 Result.forwardSwitchCondToPhi(Enable);
1246 } else if (ParamName == "switch-range-to-icmp") {
1247 Result.convertSwitchRangeToICmp(Enable);
1248 } else if (ParamName == "switch-to-arithmetic") {
1249 Result.convertSwitchToArithmetic(Enable);
1250 } else if (ParamName == "switch-to-lookup") {
1251 Result.convertSwitchToLookupTable(Enable);
1252 } else if (ParamName == "keep-loops") {
1253 Result.needCanonicalLoops(Enable);
1254 } else if (ParamName == "hoist-common-insts") {
1255 Result.hoistCommonInsts(Enable);
1256 } else if (ParamName == "hoist-loads-stores-with-cond-faulting") {
1257 Result.hoistLoadsStoresWithCondFaulting(Enable);
1258 } else if (ParamName == "sink-common-insts") {
1259 Result.sinkCommonInsts(Enable);
1260 } else if (ParamName == "speculate-unpredictables") {
1261 Result.speculateUnpredictables(Enable);
1262 } else if (Enable && ParamName.consume_front("bonus-inst-threshold=")) {
1263 APInt BonusInstThreshold;
1264 if (ParamName.getAsInteger(0, BonusInstThreshold))
1266 formatv("invalid argument to SimplifyCFG pass bonus-threshold "
1267 "parameter: '{}'",
1268 ParamName)
1269 .str(),
1271 Result.bonusInstThreshold(BonusInstThreshold.getSExtValue());
1272 } else {
1274 formatv("invalid SimplifyCFG pass parameter '{}'", ParamName).str(),
1276 }
1277 }
1278 return Result;
1279}
1280
1281Expected<InstCombineOptions> parseInstCombineOptions(StringRef Params) {
1283 // When specifying "instcombine" in -passes enable fix-point verification by
1284 // default, as this is what most tests should use.
1285 Result.setVerifyFixpoint(true);
1286 while (!Params.empty()) {
1287 StringRef ParamName;
1288 std::tie(ParamName, Params) = Params.split(';');
1289
1290 bool Enable = !ParamName.consume_front("no-");
1291 if (ParamName == "verify-fixpoint") {
1292 Result.setVerifyFixpoint(Enable);
1293 } else if (Enable && ParamName.consume_front("max-iterations=")) {
1294 APInt MaxIterations;
1295 if (ParamName.getAsInteger(0, MaxIterations))
1297 formatv("invalid argument to InstCombine pass max-iterations "
1298 "parameter: '{}'",
1299 ParamName)
1300 .str(),
1302 Result.setMaxIterations((unsigned)MaxIterations.getZExtValue());
1303 } else {
1305 formatv("invalid InstCombine pass parameter '{}'", ParamName).str(),
1307 }
1308 }
1309 return Result;
1310}
1311
1312/// Parser of parameters for LoopVectorize pass.
1313Expected<LoopVectorizeOptions> parseLoopVectorizeOptions(StringRef Params) {
1315 while (!Params.empty()) {
1316 StringRef ParamName;
1317 std::tie(ParamName, Params) = Params.split(';');
1318
1319 bool Enable = !ParamName.consume_front("no-");
1320 if (ParamName == "interleave-forced-only") {
1322 } else if (ParamName == "vectorize-forced-only") {
1324 } else {
1326 formatv("invalid LoopVectorize parameter '{}'", ParamName).str(),
1328 }
1329 }
1330 return Opts;
1331}
1332
1333Expected<std::pair<bool, bool>> parseLoopUnswitchOptions(StringRef Params) {
1334 std::pair<bool, bool> Result = {false, true};
1335 while (!Params.empty()) {
1336 StringRef ParamName;
1337 std::tie(ParamName, Params) = Params.split(';');
1338
1339 bool Enable = !ParamName.consume_front("no-");
1340 if (ParamName == "nontrivial") {
1341 Result.first = Enable;
1342 } else if (ParamName == "trivial") {
1343 Result.second = Enable;
1344 } else {
1346 formatv("invalid LoopUnswitch pass parameter '{}'", ParamName).str(),
1348 }
1349 }
1350 return Result;
1351}
1352
1353Expected<LICMOptions> parseLICMOptions(StringRef Params) {
1355 while (!Params.empty()) {
1356 StringRef ParamName;
1357 std::tie(ParamName, Params) = Params.split(';');
1358
1359 bool Enable = !ParamName.consume_front("no-");
1360 if (ParamName == "allowspeculation") {
1361 Result.AllowSpeculation = Enable;
1362 } else {
1364 formatv("invalid LICM pass parameter '{}'", ParamName).str(),
1366 }
1367 }
1368 return Result;
1369}
1370
1371struct LoopRotateOptions {
1372 bool EnableHeaderDuplication = true;
1373 bool PrepareForLTO = false;
1374 bool CheckExitCount = false;
1375};
1376
1377Expected<LoopRotateOptions> parseLoopRotateOptions(StringRef Params) {
1378 LoopRotateOptions Result;
1379 while (!Params.empty()) {
1380 StringRef ParamName;
1381 std::tie(ParamName, Params) = Params.split(';');
1382
1383 bool Enable = !ParamName.consume_front("no-");
1384 if (ParamName == "header-duplication") {
1385 Result.EnableHeaderDuplication = Enable;
1386 } else if (ParamName == "prepare-for-lto") {
1387 Result.PrepareForLTO = Enable;
1388 } else if (ParamName == "check-exit-count") {
1389 Result.CheckExitCount = Enable;
1390 } else {
1392 formatv("invalid LoopRotate pass parameter '{}'", ParamName).str(),
1394 }
1395 }
1396 return Result;
1397}
1398
1399Expected<bool> parseMergedLoadStoreMotionOptions(StringRef Params) {
1400 bool Result = false;
1401 while (!Params.empty()) {
1402 StringRef ParamName;
1403 std::tie(ParamName, Params) = Params.split(';');
1404
1405 bool Enable = !ParamName.consume_front("no-");
1406 if (ParamName == "split-footer-bb") {
1407 Result = Enable;
1408 } else {
1410 formatv("invalid MergedLoadStoreMotion pass parameter '{}'",
1411 ParamName)
1412 .str(),
1414 }
1415 }
1416 return Result;
1417}
1418
1419Expected<GVNOptions> parseGVNOptions(StringRef Params) {
1421 while (!Params.empty()) {
1422 StringRef ParamName;
1423 std::tie(ParamName, Params) = Params.split(';');
1424
1425 bool Enable = !ParamName.consume_front("no-");
1426 if (ParamName == "scalar-pre") {
1427 Result.setScalarPRE(Enable);
1428 } else if (ParamName == "load-pre") {
1429 Result.setLoadPRE(Enable);
1430 } else if (ParamName == "split-backedge-load-pre") {
1431 Result.setLoadPRESplitBackedge(Enable);
1432 } else if (ParamName == "memdep") {
1433 // MemDep and MemorySSA are mutually exclusive.
1434 Result.setMemDep(Enable);
1435 Result.setMemorySSA(!Enable);
1436 } else if (ParamName == "memoryssa") {
1437 // MemDep and MemorySSA are mutually exclusive.
1438 Result.setMemorySSA(Enable);
1439 Result.setMemDep(!Enable);
1440 } else {
1442 formatv("invalid GVN pass parameter '{}'", ParamName).str(),
1444 }
1445 }
1446 return Result;
1447}
1448
1449Expected<IPSCCPOptions> parseIPSCCPOptions(StringRef Params) {
1451 while (!Params.empty()) {
1452 StringRef ParamName;
1453 std::tie(ParamName, Params) = Params.split(';');
1454
1455 bool Enable = !ParamName.consume_front("no-");
1456 if (ParamName == "func-spec")
1457 Result.setFuncSpec(Enable);
1458 else
1460 formatv("invalid IPSCCP pass parameter '{}'", ParamName).str(),
1462 }
1463 return Result;
1464}
1465
1466Expected<ScalarizerPassOptions> parseScalarizerOptions(StringRef Params) {
1468 while (!Params.empty()) {
1469 StringRef ParamName;
1470 std::tie(ParamName, Params) = Params.split(';');
1471
1472 if (ParamName.consume_front("min-bits=")) {
1473 if (ParamName.getAsInteger(0, Result.ScalarizeMinBits)) {
1475 formatv("invalid argument to Scalarizer pass min-bits "
1476 "parameter: '{}'",
1477 ParamName)
1478 .str(),
1480 }
1481
1482 continue;
1483 }
1484
1485 bool Enable = !ParamName.consume_front("no-");
1486 if (ParamName == "load-store")
1487 Result.ScalarizeLoadStore = Enable;
1488 else if (ParamName == "variable-insert-extract")
1489 Result.ScalarizeVariableInsertExtract = Enable;
1490 else {
1492 formatv("invalid Scalarizer pass parameter '{}'", ParamName).str(),
1494 }
1495 }
1496
1497 return Result;
1498}
1499
1500Expected<SROAOptions> parseSROAOptions(StringRef Params) {
1502 bool SawCFGOption = false;
1503 while (!Params.empty()) {
1504 StringRef ParamName;
1505 std::tie(ParamName, Params) = Params.split(';');
1506
1507 if (ParamName == "modify-cfg") {
1508 if (SawCFGOption)
1509 return make_error<StringError>("multiple SROA CFG options specified",
1512 SawCFGOption = true;
1513 } else if (ParamName == "preserve-cfg") {
1514 if (SawCFGOption)
1515 return make_error<StringError>("multiple SROA CFG options specified",
1518 SawCFGOption = true;
1519 } else if (ParamName == "aggregate-to-vector") {
1520 Result.AggregateToVector = true;
1521 } else {
1523 formatv("invalid SROA pass parameter '{}' (expected preserve-cfg, "
1524 "modify-cfg, or aggregate-to-vector)",
1525 ParamName)
1526 .str(),
1528 }
1529 }
1530 return Result;
1531}
1532
1534parseStackLifetimeOptions(StringRef Params) {
1536 while (!Params.empty()) {
1537 StringRef ParamName;
1538 std::tie(ParamName, Params) = Params.split(';');
1539
1540 if (ParamName == "may") {
1542 } else if (ParamName == "must") {
1544 } else {
1546 formatv("invalid StackLifetime parameter '{}'", ParamName).str(),
1548 }
1549 }
1550 return Result;
1551}
1552
1553Expected<bool> parseDependenceAnalysisPrinterOptions(StringRef Params) {
1554 return PassBuilder::parseSinglePassOption(Params, "normalized-results",
1555 "DependenceAnalysisPrinter");
1556}
1557
1558Expected<bool> parseSeparateConstOffsetFromGEPPassOptions(StringRef Params) {
1559 return PassBuilder::parseSinglePassOption(Params, "lower-gep",
1560 "SeparateConstOffsetFromGEP");
1561}
1562
1563Expected<bool> parseStructurizeCFGPassOptions(StringRef Params) {
1564 return PassBuilder::parseSinglePassOption(Params, "skip-uniform-regions",
1565 "StructurizeCFG");
1566}
1567
1569parseFunctionSimplificationPipelineOptions(StringRef Params) {
1570 std::optional<OptimizationLevel> L = parseOptLevel(Params);
1571 if (!L || *L == OptimizationLevel::O0) {
1573 formatv("invalid function-simplification parameter '{}'", Params).str(),
1575 };
1576 return *L;
1577}
1578
1579Expected<bool> parseMemorySSAPrinterPassOptions(StringRef Params) {
1580 return PassBuilder::parseSinglePassOption(Params, "no-ensure-optimized-uses",
1581 "MemorySSAPrinterPass");
1582}
1583
1584Expected<bool> parseSpeculativeExecutionPassOptions(StringRef Params) {
1585 return PassBuilder::parseSinglePassOption(Params, "only-if-divergent-target",
1586 "SpeculativeExecutionPass");
1587}
1588
1589Expected<std::string> parseMemProfUsePassOptions(StringRef Params) {
1590 std::string Result;
1591 while (!Params.empty()) {
1592 StringRef ParamName;
1593 std::tie(ParamName, Params) = Params.split(';');
1594
1595 if (ParamName.consume_front("profile-filename=")) {
1596 Result = ParamName.str();
1597 } else {
1599 formatv("invalid MemProfUse pass parameter '{}'", ParamName).str(),
1601 }
1602 }
1603 return Result;
1604}
1605
1607parseStructuralHashPrinterPassOptions(StringRef Params) {
1608 if (Params.empty())
1610 if (Params == "detailed")
1612 if (Params == "call-target-ignored")
1615 formatv("invalid structural hash printer parameter '{}'", Params).str(),
1617}
1618
1619Expected<bool> parseWinEHPrepareOptions(StringRef Params) {
1620 return PassBuilder::parseSinglePassOption(Params, "demote-catchswitch-only",
1621 "WinEHPreparePass");
1622}
1623
1624Expected<GlobalMergeOptions> parseGlobalMergeOptions(StringRef Params) {
1626 while (!Params.empty()) {
1627 StringRef ParamName;
1628 std::tie(ParamName, Params) = Params.split(';');
1629
1630 bool Enable = !ParamName.consume_front("no-");
1631 if (ParamName == "group-by-use")
1632 Result.GroupByUse = Enable;
1633 else if (ParamName == "ignore-single-use")
1634 Result.IgnoreSingleUse = Enable;
1635 else if (ParamName == "merge-const")
1636 Result.MergeConstantGlobals = Enable;
1637 else if (ParamName == "merge-const-aggressive")
1638 Result.MergeConstAggressive = Enable;
1639 else if (ParamName == "merge-external")
1640 Result.MergeExternal = Enable;
1641 else if (ParamName.consume_front("max-offset=")) {
1642 if (ParamName.getAsInteger(0, Result.MaxOffset))
1644 formatv("invalid GlobalMergePass parameter '{}'", ParamName).str(),
1646 } else {
1648 formatv("invalid global-merge pass parameter '{}'", Params).str(),
1650 }
1651 }
1652 return Result;
1653}
1654
1655Expected<SmallVector<std::string, 0>> parseInternalizeGVs(StringRef Params) {
1656 SmallVector<std::string, 1> PreservedGVs;
1657 while (!Params.empty()) {
1658 StringRef ParamName;
1659 std::tie(ParamName, Params) = Params.split(';');
1660
1661 if (ParamName.consume_front("preserve-gv=")) {
1662 PreservedGVs.push_back(ParamName.str());
1663 } else {
1665 formatv("invalid Internalize pass parameter '{}'", ParamName).str(),
1667 }
1668 }
1669
1670 return Expected<SmallVector<std::string, 0>>(std::move(PreservedGVs));
1671}
1672
1674parseRegAllocFastPassOptions(PassBuilder &PB, StringRef Params) {
1676 while (!Params.empty()) {
1677 StringRef ParamName;
1678 std::tie(ParamName, Params) = Params.split(';');
1679
1680 if (ParamName.consume_front("filter=")) {
1681 std::optional<RegAllocFilterFunc> Filter =
1682 PB.parseRegAllocFilter(ParamName);
1683 if (!Filter) {
1685 formatv("invalid regallocfast register filter '{}'", ParamName)
1686 .str(),
1688 }
1689 Opts.Filter = *Filter;
1690 Opts.FilterName = ParamName;
1691 continue;
1692 }
1693
1694 if (ParamName == "no-clear-vregs") {
1695 Opts.ClearVRegs = false;
1696 continue;
1697 }
1698
1700 formatv("invalid regallocfast pass parameter '{}'", ParamName).str(),
1702 }
1703 return Opts;
1704}
1705
1707parseBoundsCheckingOptions(StringRef Params) {
1709 while (!Params.empty()) {
1710 StringRef ParamName;
1711 std::tie(ParamName, Params) = Params.split(';');
1712 if (ParamName == "trap") {
1713 Options.Rt = std::nullopt;
1714 } else if (ParamName == "rt") {
1715 Options.Rt = {
1716 /*MinRuntime=*/false,
1717 /*MayReturn=*/true,
1718 /*HandlerPreserveAllRegs=*/false,
1719 };
1720 } else if (ParamName == "rt-abort") {
1721 Options.Rt = {
1722 /*MinRuntime=*/false,
1723 /*MayReturn=*/false,
1724 /*HandlerPreserveAllRegs=*/false,
1725 };
1726 } else if (ParamName == "min-rt") {
1727 Options.Rt = {
1728 /*MinRuntime=*/true,
1729 /*MayReturn=*/true,
1730 /*HandlerPreserveAllRegs=*/false,
1731 };
1732 } else if (ParamName == "min-rt-abort") {
1733 Options.Rt = {
1734 /*MinRuntime=*/true,
1735 /*MayReturn=*/false,
1736 /*HandlerPreserveAllRegs=*/false,
1737 };
1738 } else if (ParamName == "merge") {
1739 Options.Merge = true;
1740 } else if (ParamName == "handler-preserve-all-regs") {
1741 if (Options.Rt)
1742 Options.Rt->HandlerPreserveAllRegs = true;
1743 } else {
1744 StringRef ParamEQ;
1745 StringRef Val;
1746 std::tie(ParamEQ, Val) = ParamName.split('=');
1747 int8_t Id;
1748 if (ParamEQ == "guard" && !Val.getAsInteger(0, Id)) {
1749 Options.GuardKind = Id;
1750 } else {
1752 formatv("invalid BoundsChecking pass parameter '{}'", ParamName)
1753 .str(),
1755 }
1756 }
1757 }
1758 return Options;
1759}
1760
1761Expected<CodeGenOptLevel> parseExpandIRInstsOptions(StringRef Param) {
1762 if (Param.empty())
1763 return CodeGenOptLevel::None;
1764
1765 // Parse a CodeGenOptLevel, e.g. "O1", "O2", "O3".
1766 auto [Prefix, Digit] = Param.split('O');
1767
1768 uint8_t N;
1769 if (!Prefix.empty() || Digit.getAsInteger(10, N))
1770 return createStringError("invalid expand-ir-insts pass parameter '%s'",
1771 Param.str().c_str());
1772
1773 std::optional<CodeGenOptLevel> Level = CodeGenOpt::getLevel(N);
1774 if (!Level.has_value())
1775 return createStringError(
1776 "invalid optimization level for expand-ir-insts pass: %s",
1777 Digit.str().c_str());
1778
1779 return *Level;
1780}
1781
1783parseRegAllocGreedyFilterFunc(PassBuilder &PB, StringRef Params) {
1784 if (Params.empty() || Params == "all")
1785 return RAGreedyPass::Options();
1786
1787 std::optional<RegAllocFilterFunc> Filter = PB.parseRegAllocFilter(Params);
1788 if (Filter)
1789 return RAGreedyPass::Options{*Filter, Params};
1790
1792 formatv("invalid regallocgreedy register filter '{}'", Params).str(),
1794}
1795
1796Expected<bool> parseMachineSinkingPassOptions(StringRef Params) {
1797 return PassBuilder::parseSinglePassOption(Params, "enable-sink-fold",
1798 "MachineSinkingPass");
1799}
1800
1801Expected<bool> parseMachineBlockPlacementPassOptions(StringRef Params) {
1802 bool AllowTailMerge = true;
1803 if (!Params.empty()) {
1804 AllowTailMerge = !Params.consume_front("no-");
1805 if (Params != "tail-merge")
1807 formatv("invalid MachineBlockPlacementPass parameter '{}'", Params)
1808 .str(),
1810 }
1811 return AllowTailMerge;
1812}
1813
1814Expected<bool> parseVirtRegRewriterPassOptions(StringRef Params) {
1815 bool ClearVirtRegs = true;
1816 if (!Params.empty()) {
1817 ClearVirtRegs = !Params.consume_front("no-");
1818 if (Params != "clear-vregs")
1820 formatv("invalid VirtRegRewriter pass parameter '{}'", Params).str(),
1822 }
1823 return ClearVirtRegs;
1824}
1825
1826struct FatLTOOptions {
1827 OptimizationLevel OptLevel;
1828 bool ThinLTO = false;
1829 bool EmitSummary = false;
1830};
1831
1832Expected<FatLTOOptions> parseFatLTOOptions(StringRef Params) {
1833 FatLTOOptions Result;
1834 bool HaveOptLevel = false;
1835 while (!Params.empty()) {
1836 StringRef ParamName;
1837 std::tie(ParamName, Params) = Params.split(';');
1838
1839 if (ParamName == "thinlto") {
1840 Result.ThinLTO = true;
1841 } else if (ParamName == "emit-summary") {
1842 Result.EmitSummary = true;
1843 } else if (std::optional<OptimizationLevel> OptLevel =
1844 parseOptLevel(ParamName)) {
1845 Result.OptLevel = *OptLevel;
1846 HaveOptLevel = true;
1847 } else {
1849 formatv("invalid fatlto-pre-link pass parameter '{}'", ParamName)
1850 .str(),
1852 }
1853 }
1854 if (!HaveOptLevel)
1856 "missing optimization level for fatlto-pre-link pipeline",
1858 return Result;
1859}
1860
1861} // namespace
1862
1863/// Tests whether registered callbacks will accept a given pass name.
1864///
1865/// When parsing a pipeline text, the type of the outermost pipeline may be
1866/// omitted, in which case the type is automatically determined from the first
1867/// pass name in the text. This may be a name that is handled through one of the
1868/// callbacks. We check this through the oridinary parsing callbacks by setting
1869/// up a dummy PassManager in order to not force the client to also handle this
1870/// type of query.
1871template <typename PassManagerT, typename CallbacksT>
1872static bool callbacksAcceptPassName(StringRef Name, CallbacksT &Callbacks) {
1873 if (!Callbacks.empty()) {
1874 PassManagerT DummyPM;
1875 for (auto &CB : Callbacks)
1876 if (CB(Name, DummyPM, {}))
1877 return true;
1878 }
1879 return false;
1880}
1881
1882template <typename CallbacksT>
1883static bool isModulePassName(StringRef Name, CallbacksT &Callbacks) {
1884 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1885
1886 // Explicitly handle pass manager names.
1887 if (Name == "module")
1888 return true;
1889 if (Name == "cgscc")
1890 return true;
1891 if (NameNoBracket == "function")
1892 return true;
1893 if (Name == "coro-cond")
1894 return true;
1895
1896#define MODULE_PASS(NAME, CREATE_PASS) \
1897 if (Name == NAME) \
1898 return true;
1899#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1900 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1901 return true;
1902#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
1903 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1904 return true;
1905#include "PassRegistry.def"
1906
1907 return callbacksAcceptPassName<ModulePassManager>(Name, Callbacks);
1908}
1909
1910template <typename CallbacksT>
1911static bool isCGSCCPassName(StringRef Name, CallbacksT &Callbacks) {
1912 // Explicitly handle pass manager names.
1913 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1914 if (Name == "cgscc")
1915 return true;
1916 if (NameNoBracket == "function")
1917 return true;
1918
1919 // Explicitly handle custom-parsed pass names.
1920 if (parseDevirtPassName(Name))
1921 return true;
1922
1923#define CGSCC_PASS(NAME, CREATE_PASS) \
1924 if (Name == NAME) \
1925 return true;
1926#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1927 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1928 return true;
1929#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
1930 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1931 return true;
1932#include "PassRegistry.def"
1933
1934 return callbacksAcceptPassName<CGSCCPassManager>(Name, Callbacks);
1935}
1936
1937template <typename CallbacksT>
1938static bool isFunctionPassName(StringRef Name, CallbacksT &Callbacks) {
1939 // Explicitly handle pass manager names.
1940 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1941 if (NameNoBracket == "function")
1942 return true;
1943 if (Name == "loop" || Name == "loop-mssa" || Name == "machine-function")
1944 return true;
1945
1946#define FUNCTION_PASS(NAME, CREATE_PASS) \
1947 if (Name == NAME) \
1948 return true;
1949#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1950 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1951 return true;
1952#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1953 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1954 return true;
1955#include "PassRegistry.def"
1956
1957 return callbacksAcceptPassName<FunctionPassManager>(Name, Callbacks);
1958}
1959
1960template <typename CallbacksT>
1961static bool isMachineFunctionPassName(StringRef Name, CallbacksT &Callbacks) {
1962 // Explicitly handle pass manager names.
1963 if (Name == "machine-function")
1964 return true;
1965
1966#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
1967 if (Name == NAME) \
1968 return true;
1969#define MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, \
1970 PARAMS) \
1971 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1972 return true;
1973
1974#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1975 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1976 return true;
1977
1978#include "llvm/Passes/MachinePassRegistry.def"
1979
1981}
1982
1983template <typename CallbacksT>
1984static bool isLoopNestPassName(StringRef Name, CallbacksT &Callbacks,
1985 bool &UseMemorySSA) {
1986 UseMemorySSA = false;
1987
1988 if (PassBuilder::checkParametrizedPassName(Name, "lnicm")) {
1989 UseMemorySSA = true;
1990 return true;
1991 }
1992
1993#define LOOPNEST_PASS(NAME, CREATE_PASS) \
1994 if (Name == NAME) \
1995 return true;
1996#include "PassRegistry.def"
1997
1998 return callbacksAcceptPassName<LoopPassManager>(Name, Callbacks);
1999}
2000
2001template <typename CallbacksT>
2002static bool isLoopPassName(StringRef Name, CallbacksT &Callbacks,
2003 bool &UseMemorySSA) {
2004 UseMemorySSA = false;
2005
2006 if (PassBuilder::checkParametrizedPassName(Name, "licm")) {
2007 UseMemorySSA = true;
2008 return true;
2009 }
2010
2011#define LOOP_PASS(NAME, CREATE_PASS) \
2012 if (Name == NAME) \
2013 return true;
2014#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2015 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
2016 return true;
2017#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
2018 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
2019 return true;
2020#include "PassRegistry.def"
2021
2022 return callbacksAcceptPassName<LoopPassManager>(Name, Callbacks);
2023}
2024
2025std::optional<std::vector<PassBuilder::PipelineElement>>
2026PassBuilder::parsePipelineText(StringRef Text) {
2027 std::vector<PipelineElement> ResultPipeline;
2028
2029 SmallVector<std::vector<PipelineElement> *, 4> PipelineStack = {
2030 &ResultPipeline};
2031 for (;;) {
2032 std::vector<PipelineElement> &Pipeline = *PipelineStack.back();
2033 size_t Pos = Text.find_first_of(",()");
2034 Pipeline.push_back({Text.substr(0, Pos), {}});
2035
2036 // If we have a single terminating name, we're done.
2037 if (Pos == Text.npos)
2038 break;
2039
2040 char Sep = Text[Pos];
2041 Text = Text.substr(Pos + 1);
2042 if (Sep == ',')
2043 // Just a name ending in a comma, continue.
2044 continue;
2045
2046 if (Sep == '(') {
2047 // Push the inner pipeline onto the stack to continue processing.
2048 PipelineStack.push_back(&Pipeline.back().InnerPipeline);
2049 continue;
2050 }
2051
2052 assert(Sep == ')' && "Bogus separator!");
2053 // When handling the close parenthesis, we greedily consume them to avoid
2054 // empty strings in the pipeline.
2055 do {
2056 // If we try to pop the outer pipeline we have unbalanced parentheses.
2057 if (PipelineStack.size() == 1)
2058 return std::nullopt;
2059
2060 PipelineStack.pop_back();
2061 } while (Text.consume_front(")"));
2062
2063 // Check if we've finished parsing.
2064 if (Text.empty())
2065 break;
2066
2067 // Otherwise, the end of an inner pipeline always has to be followed by
2068 // a comma, and then we can continue.
2069 if (!Text.consume_front(","))
2070 return std::nullopt;
2071 }
2072
2073 if (PipelineStack.size() > 1)
2074 // Unbalanced paretheses.
2075 return std::nullopt;
2076
2077 assert(PipelineStack.back() == &ResultPipeline &&
2078 "Wrong pipeline at the bottom of the stack!");
2079 return {std::move(ResultPipeline)};
2080}
2081
2087
2088Error PassBuilder::parseModulePass(ModulePassManager &MPM,
2089 const PipelineElement &E) {
2090 auto &Name = E.Name;
2091 auto &InnerPipeline = E.InnerPipeline;
2092
2093 // First handle complex passes like the pass managers which carry pipelines.
2094 if (!InnerPipeline.empty()) {
2095 if (Name == "module") {
2096 ModulePassManager NestedMPM;
2097 if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline))
2098 return Err;
2099 MPM.addPass(std::move(NestedMPM));
2100 return Error::success();
2101 }
2102 if (Name == "coro-cond") {
2103 ModulePassManager NestedMPM;
2104 if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline))
2105 return Err;
2106 MPM.addPass(CoroConditionalWrapper(std::move(NestedMPM)));
2107 return Error::success();
2108 }
2109 if (Name == "cgscc") {
2110 CGSCCPassManager CGPM;
2111 if (auto Err = parseCGSCCPassPipeline(CGPM, InnerPipeline))
2112 return Err;
2114 return Error::success();
2115 }
2116 if (auto Params = parseFunctionPipelineName(Name)) {
2117 if (Params->second)
2119 "cannot have a no-rerun module to function adaptor",
2122 if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline))
2123 return Err;
2124 MPM.addPass(
2125 createModuleToFunctionPassAdaptor(std::move(FPM), Params->first));
2126 return Error::success();
2127 }
2128
2129 for (auto &C : ModulePipelineParsingCallbacks)
2130 if (C(Name, MPM, InnerPipeline))
2131 return Error::success();
2132
2133 // Normal passes can't have pipelines.
2135 formatv("invalid use of '{}' pass as module pipeline", Name).str(),
2137 ;
2138 }
2139
2140 // Finally expand the basic registered passes from the .inc file.
2141#define MODULE_PASS(NAME, CREATE_PASS) \
2142 if (Name == NAME) { \
2143 MPM.addPass(CREATE_PASS); \
2144 return Error::success(); \
2145 }
2146#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2147 if (checkParametrizedPassName(Name, NAME)) { \
2148 auto Params = parsePassParameters(PARSER, Name, NAME); \
2149 if (!Params) \
2150 return Params.takeError(); \
2151 MPM.addPass(CREATE_PASS(Params.get())); \
2152 return Error::success(); \
2153 }
2154#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
2155 if (Name == "require<" NAME ">") { \
2156 MPM.addPass( \
2157 RequireAnalysisPass< \
2158 std::remove_reference_t<decltype(CREATE_PASS)>, Module>()); \
2159 return Error::success(); \
2160 } \
2161 if (Name == "invalidate<" NAME ">") { \
2162 MPM.addPass(InvalidateAnalysisPass< \
2163 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2164 return Error::success(); \
2165 }
2166#define CGSCC_PASS(NAME, CREATE_PASS) \
2167 if (Name == NAME) { \
2168 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(CREATE_PASS)); \
2169 return Error::success(); \
2170 }
2171#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2172 if (checkParametrizedPassName(Name, NAME)) { \
2173 auto Params = parsePassParameters(PARSER, Name, NAME); \
2174 if (!Params) \
2175 return Params.takeError(); \
2176 MPM.addPass( \
2177 createModuleToPostOrderCGSCCPassAdaptor(CREATE_PASS(Params.get()))); \
2178 return Error::success(); \
2179 }
2180#define FUNCTION_PASS(NAME, CREATE_PASS) \
2181 if (Name == NAME) { \
2182 if constexpr (std::is_constructible_v< \
2183 std::remove_reference_t<decltype(CREATE_PASS)>, \
2184 const TargetMachine &>) { \
2185 if (!TM) \
2186 return make_error<StringError>( \
2187 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2188 inconvertibleErrorCode()); \
2189 } \
2190 MPM.addPass(createModuleToFunctionPassAdaptor(CREATE_PASS)); \
2191 return Error::success(); \
2192 }
2193#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2194 if (checkParametrizedPassName(Name, NAME)) { \
2195 auto Params = parsePassParameters(PARSER, Name, NAME); \
2196 if (!Params) \
2197 return Params.takeError(); \
2198 auto CreatePass = CREATE_PASS; \
2199 if constexpr (std::is_constructible_v< \
2200 std::remove_reference_t<decltype(CreatePass( \
2201 Params.get()))>, \
2202 const TargetMachine &, \
2203 std::remove_reference_t<decltype(Params.get())>>) { \
2204 if (!TM) { \
2205 return make_error<StringError>( \
2206 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2207 inconvertibleErrorCode()); \
2208 } \
2209 } \
2210 MPM.addPass(createModuleToFunctionPassAdaptor(CREATE_PASS(Params.get()))); \
2211 return Error::success(); \
2212 }
2213#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2214 if (Name == NAME) { \
2215 MPM.addPass(createModuleToFunctionPassAdaptor( \
2216 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2217 return Error::success(); \
2218 }
2219#define LOOP_PASS(NAME, CREATE_PASS) \
2220 if (Name == NAME) { \
2221 MPM.addPass(createModuleToFunctionPassAdaptor( \
2222 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2223 return Error::success(); \
2224 }
2225#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2226 if (checkParametrizedPassName(Name, NAME)) { \
2227 auto Params = parsePassParameters(PARSER, Name, NAME); \
2228 if (!Params) \
2229 return Params.takeError(); \
2230 MPM.addPass(createModuleToFunctionPassAdaptor( \
2231 createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), false))); \
2232 return Error::success(); \
2233 }
2234#include "PassRegistry.def"
2235
2236 for (auto &C : ModulePipelineParsingCallbacks)
2237 if (C(Name, MPM, InnerPipeline))
2238 return Error::success();
2240 formatv("unknown module pass '{}'", Name).str(),
2242}
2243
2244Error PassBuilder::parseCGSCCPass(CGSCCPassManager &CGPM,
2245 const PipelineElement &E) {
2246 auto &Name = E.Name;
2247 auto &InnerPipeline = E.InnerPipeline;
2248
2249 // First handle complex passes like the pass managers which carry pipelines.
2250 if (!InnerPipeline.empty()) {
2251 if (Name == "cgscc") {
2252 CGSCCPassManager NestedCGPM;
2253 if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline))
2254 return Err;
2255 // Add the nested pass manager with the appropriate adaptor.
2256 CGPM.addPass(std::move(NestedCGPM));
2257 return Error::success();
2258 }
2259 if (auto Params = parseFunctionPipelineName(Name)) {
2261 if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline))
2262 return Err;
2263 // Add the nested pass manager with the appropriate adaptor.
2265 std::move(FPM), Params->first, Params->second));
2266 return Error::success();
2267 }
2268 if (auto MaxRepetitions = parseDevirtPassName(Name)) {
2269 CGSCCPassManager NestedCGPM;
2270 if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline))
2271 return Err;
2272 CGPM.addPass(
2273 createDevirtSCCRepeatedPass(std::move(NestedCGPM), *MaxRepetitions));
2274 return Error::success();
2275 }
2276
2277 for (auto &C : CGSCCPipelineParsingCallbacks)
2278 if (C(Name, CGPM, InnerPipeline))
2279 return Error::success();
2280
2281 // Normal passes can't have pipelines.
2283 formatv("invalid use of '{}' pass as cgscc pipeline", Name).str(),
2285 }
2286
2287// Now expand the basic registered passes from the .inc file.
2288#define CGSCC_PASS(NAME, CREATE_PASS) \
2289 if (Name == NAME) { \
2290 CGPM.addPass(CREATE_PASS); \
2291 return Error::success(); \
2292 }
2293#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2294 if (checkParametrizedPassName(Name, NAME)) { \
2295 auto Params = parsePassParameters(PARSER, Name, NAME); \
2296 if (!Params) \
2297 return Params.takeError(); \
2298 CGPM.addPass(CREATE_PASS(Params.get())); \
2299 return Error::success(); \
2300 }
2301#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
2302 if (Name == "require<" NAME ">") { \
2303 CGPM.addPass(RequireAnalysisPass< \
2304 std::remove_reference_t<decltype(CREATE_PASS)>, \
2305 LazyCallGraph::SCC, CGSCCAnalysisManager, LazyCallGraph &, \
2306 CGSCCUpdateResult &>()); \
2307 return Error::success(); \
2308 } \
2309 if (Name == "invalidate<" NAME ">") { \
2310 CGPM.addPass(InvalidateAnalysisPass< \
2311 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2312 return Error::success(); \
2313 }
2314#define FUNCTION_PASS(NAME, CREATE_PASS) \
2315 if (Name == NAME) { \
2316 if constexpr (std::is_constructible_v< \
2317 std::remove_reference_t<decltype(CREATE_PASS)>, \
2318 const TargetMachine &>) { \
2319 if (!TM) \
2320 return make_error<StringError>( \
2321 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2322 inconvertibleErrorCode()); \
2323 } \
2324 CGPM.addPass(createCGSCCToFunctionPassAdaptor(CREATE_PASS)); \
2325 return Error::success(); \
2326 }
2327#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2328 if (checkParametrizedPassName(Name, NAME)) { \
2329 auto Params = parsePassParameters(PARSER, Name, NAME); \
2330 if (!Params) \
2331 return Params.takeError(); \
2332 auto CreatePass = CREATE_PASS; \
2333 if constexpr (std::is_constructible_v< \
2334 std::remove_reference_t<decltype(CreatePass( \
2335 Params.get()))>, \
2336 const TargetMachine &, \
2337 std::remove_reference_t<decltype(Params.get())>>) { \
2338 if (!TM) { \
2339 return make_error<StringError>( \
2340 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2341 inconvertibleErrorCode()); \
2342 } \
2343 } \
2344 CGPM.addPass(createCGSCCToFunctionPassAdaptor(CREATE_PASS(Params.get()))); \
2345 return Error::success(); \
2346 }
2347#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2348 if (Name == NAME) { \
2349 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
2350 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2351 return Error::success(); \
2352 }
2353#define LOOP_PASS(NAME, CREATE_PASS) \
2354 if (Name == NAME) { \
2355 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
2356 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2357 return Error::success(); \
2358 }
2359#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2360 if (checkParametrizedPassName(Name, NAME)) { \
2361 auto Params = parsePassParameters(PARSER, Name, NAME); \
2362 if (!Params) \
2363 return Params.takeError(); \
2364 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
2365 createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), false))); \
2366 return Error::success(); \
2367 }
2368#include "PassRegistry.def"
2369
2370 for (auto &C : CGSCCPipelineParsingCallbacks)
2371 if (C(Name, CGPM, InnerPipeline))
2372 return Error::success();
2373 return make_error<StringError>(formatv("unknown cgscc pass '{}'", Name).str(),
2375}
2376
2377Error PassBuilder::parseFunctionPass(FunctionPassManager &FPM,
2378 const PipelineElement &E) {
2379 auto &Name = E.Name;
2380 auto &InnerPipeline = E.InnerPipeline;
2381
2382 // First handle complex passes like the pass managers which carry pipelines.
2383 if (!InnerPipeline.empty()) {
2384 if (Name == "function") {
2385 FunctionPassManager NestedFPM;
2386 if (auto Err = parseFunctionPassPipeline(NestedFPM, InnerPipeline))
2387 return Err;
2388 // Add the nested pass manager with the appropriate adaptor.
2389 FPM.addPass(std::move(NestedFPM));
2390 return Error::success();
2391 }
2392 if (Name == "loop" || Name == "loop-mssa") {
2393 LoopPassManager LPM;
2394 if (auto Err = parseLoopPassPipeline(LPM, InnerPipeline))
2395 return Err;
2396 // Add the nested pass manager with the appropriate adaptor.
2397 bool UseMemorySSA = (Name == "loop-mssa");
2398 FPM.addPass(
2399 createFunctionToLoopPassAdaptor(std::move(LPM), UseMemorySSA));
2400 return Error::success();
2401 }
2402 if (Name == "machine-function") {
2404 if (auto Err = parseMachinePassPipeline(MFPM, InnerPipeline))
2405 return Err;
2407 return Error::success();
2408 }
2409
2410 for (auto &C : FunctionPipelineParsingCallbacks)
2411 if (C(Name, FPM, InnerPipeline))
2412 return Error::success();
2413
2414 // Normal passes can't have pipelines.
2416 formatv("invalid use of '{}' pass as function pipeline", Name).str(),
2418 }
2419
2420// Now expand the basic registered passes from the .inc file.
2421#define FUNCTION_PASS(NAME, CREATE_PASS) \
2422 if (Name == NAME) { \
2423 if constexpr (std::is_constructible_v< \
2424 std::remove_reference_t<decltype(CREATE_PASS)>, \
2425 const TargetMachine &>) { \
2426 if (!TM) \
2427 return make_error<StringError>( \
2428 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2429 inconvertibleErrorCode()); \
2430 } \
2431 FPM.addPass(CREATE_PASS); \
2432 return Error::success(); \
2433 }
2434#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2435 if (checkParametrizedPassName(Name, NAME)) { \
2436 auto Params = parsePassParameters(PARSER, Name, NAME); \
2437 if (!Params) \
2438 return Params.takeError(); \
2439 auto CreatePass = CREATE_PASS; \
2440 if constexpr (std::is_constructible_v< \
2441 std::remove_reference_t<decltype(CreatePass( \
2442 Params.get()))>, \
2443 const TargetMachine &, \
2444 std::remove_reference_t<decltype(Params.get())>>) { \
2445 if (!TM) { \
2446 return make_error<StringError>( \
2447 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2448 inconvertibleErrorCode()); \
2449 } \
2450 } \
2451 FPM.addPass(CREATE_PASS(Params.get())); \
2452 return Error::success(); \
2453 }
2454#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
2455 if (Name == "require<" NAME ">") { \
2456 if constexpr (std::is_constructible_v< \
2457 std::remove_reference_t<decltype(CREATE_PASS)>, \
2458 const TargetMachine &>) { \
2459 if (!TM) \
2460 return make_error<StringError>( \
2461 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2462 inconvertibleErrorCode()); \
2463 } \
2464 FPM.addPass( \
2465 RequireAnalysisPass<std::remove_reference_t<decltype(CREATE_PASS)>, \
2466 Function>()); \
2467 return Error::success(); \
2468 } \
2469 if (Name == "invalidate<" NAME ">") { \
2470 FPM.addPass(InvalidateAnalysisPass< \
2471 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2472 return Error::success(); \
2473 }
2474// FIXME: UseMemorySSA is set to false. Maybe we could do things like:
2475// bool UseMemorySSA = !("canon-freeze" || "loop-predication" ||
2476// "guard-widening");
2477// The risk is that it may become obsolete if we're not careful.
2478#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2479 if (Name == NAME) { \
2480 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS, false)); \
2481 return Error::success(); \
2482 }
2483#define LOOP_PASS(NAME, CREATE_PASS) \
2484 if (Name == NAME) { \
2485 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS, false)); \
2486 return Error::success(); \
2487 }
2488#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2489 if (checkParametrizedPassName(Name, NAME)) { \
2490 auto Params = parsePassParameters(PARSER, Name, NAME); \
2491 if (!Params) \
2492 return Params.takeError(); \
2493 FPM.addPass( \
2494 createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), false)); \
2495 return Error::success(); \
2496 }
2497#include "PassRegistry.def"
2498
2499 for (auto &C : FunctionPipelineParsingCallbacks)
2500 if (C(Name, FPM, InnerPipeline))
2501 return Error::success();
2503 formatv("unknown function pass '{}'", Name).str(),
2505}
2506
2507Error PassBuilder::parseLoopPass(LoopPassManager &LPM,
2508 const PipelineElement &E) {
2509 StringRef Name = E.Name;
2510 auto &InnerPipeline = E.InnerPipeline;
2511
2512 // First handle complex passes like the pass managers which carry pipelines.
2513 if (!InnerPipeline.empty()) {
2514 if (Name == "loop") {
2515 LoopPassManager NestedLPM;
2516 if (auto Err = parseLoopPassPipeline(NestedLPM, InnerPipeline))
2517 return Err;
2518 // Add the nested pass manager with the appropriate adaptor.
2519 LPM.addPass(std::move(NestedLPM));
2520 return Error::success();
2521 }
2522
2523 for (auto &C : LoopPipelineParsingCallbacks)
2524 if (C(Name, LPM, InnerPipeline))
2525 return Error::success();
2526
2527 // Normal passes can't have pipelines.
2529 formatv("invalid use of '{}' pass as loop pipeline", Name).str(),
2531 }
2532
2533// Now expand the basic registered passes from the .inc file.
2534#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2535 if (Name == NAME) { \
2536 LPM.addPass(CREATE_PASS); \
2537 return Error::success(); \
2538 }
2539#define LOOP_PASS(NAME, CREATE_PASS) \
2540 if (Name == NAME) { \
2541 LPM.addPass(CREATE_PASS); \
2542 return Error::success(); \
2543 }
2544#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2545 if (checkParametrizedPassName(Name, NAME)) { \
2546 auto Params = parsePassParameters(PARSER, Name, NAME); \
2547 if (!Params) \
2548 return Params.takeError(); \
2549 LPM.addPass(CREATE_PASS(Params.get())); \
2550 return Error::success(); \
2551 }
2552#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
2553 if (Name == "require<" NAME ">") { \
2554 LPM.addPass(RequireAnalysisPass< \
2555 std::remove_reference_t<decltype(CREATE_PASS)>, Loop, \
2556 LoopAnalysisManager, LoopStandardAnalysisResults &, \
2557 LPMUpdater &>()); \
2558 return Error::success(); \
2559 } \
2560 if (Name == "invalidate<" NAME ">") { \
2561 LPM.addPass(InvalidateAnalysisPass< \
2562 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2563 return Error::success(); \
2564 }
2565#include "PassRegistry.def"
2566
2567 for (auto &C : LoopPipelineParsingCallbacks)
2568 if (C(Name, LPM, InnerPipeline))
2569 return Error::success();
2570 return make_error<StringError>(formatv("unknown loop pass '{}'", Name).str(),
2572}
2573
2574Error PassBuilder::parseMachinePass(MachineFunctionPassManager &MFPM,
2575 const PipelineElement &E) {
2576 StringRef Name = E.Name;
2577 // Handle any nested pass managers.
2578 if (!E.InnerPipeline.empty()) {
2579 if (E.Name == "machine-function") {
2581 if (auto Err = parseMachinePassPipeline(NestedPM, E.InnerPipeline))
2582 return Err;
2583 MFPM.addPass(std::move(NestedPM));
2584 return Error::success();
2585 }
2586 return make_error<StringError>("invalid pipeline",
2588 }
2589
2590#define MACHINE_MODULE_PASS(NAME, CREATE_PASS) \
2591 if (Name == NAME) { \
2592 MFPM.addPass(CREATE_PASS); \
2593 return Error::success(); \
2594 }
2595#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
2596 if (Name == NAME) { \
2597 MFPM.addPass(CREATE_PASS); \
2598 return Error::success(); \
2599 }
2600#define MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, \
2601 PARAMS) \
2602 if (checkParametrizedPassName(Name, NAME)) { \
2603 auto Params = parsePassParameters(PARSER, Name, NAME); \
2604 if (!Params) \
2605 return Params.takeError(); \
2606 MFPM.addPass(CREATE_PASS(Params.get())); \
2607 return Error::success(); \
2608 }
2609#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
2610 if (Name == "require<" NAME ">") { \
2611 MFPM.addPass( \
2612 RequireAnalysisPass<std::remove_reference_t<decltype(CREATE_PASS)>, \
2613 MachineFunction>()); \
2614 return Error::success(); \
2615 } \
2616 if (Name == "invalidate<" NAME ">") { \
2617 MFPM.addPass(InvalidateAnalysisPass< \
2618 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2619 return Error::success(); \
2620 }
2621#include "llvm/Passes/MachinePassRegistry.def"
2622
2623 for (auto &C : MachineFunctionPipelineParsingCallbacks)
2624 if (C(Name, MFPM, E.InnerPipeline))
2625 return Error::success();
2627 formatv("unknown machine pass '{}'", Name).str(),
2629}
2630
2631bool PassBuilder::parseAAPassName(AAManager &AA, StringRef Name) {
2632#define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
2633 if (Name == NAME) { \
2634 AA.registerModuleAnalysis< \
2635 std::remove_reference_t<decltype(CREATE_PASS)>>(); \
2636 return true; \
2637 }
2638#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
2639 if (Name == NAME) { \
2640 AA.registerFunctionAnalysis< \
2641 std::remove_reference_t<decltype(CREATE_PASS)>>(); \
2642 return true; \
2643 }
2644#include "PassRegistry.def"
2645
2646 for (auto &C : AAParsingCallbacks)
2647 if (C(Name, AA))
2648 return true;
2649 return false;
2650}
2651
2652Error PassBuilder::parseMachinePassPipeline(
2654 for (const auto &Element : Pipeline) {
2655 if (auto Err = parseMachinePass(MFPM, Element))
2656 return Err;
2657 }
2658 return Error::success();
2659}
2660
2661Error PassBuilder::parseLoopPassPipeline(LoopPassManager &LPM,
2662 ArrayRef<PipelineElement> Pipeline) {
2663 for (const auto &Element : Pipeline) {
2664 if (auto Err = parseLoopPass(LPM, Element))
2665 return Err;
2666 }
2667 return Error::success();
2668}
2669
2670Error PassBuilder::parseFunctionPassPipeline(
2672 for (const auto &Element : Pipeline) {
2673 if (auto Err = parseFunctionPass(FPM, Element))
2674 return Err;
2675 }
2676 return Error::success();
2677}
2678
2679Error PassBuilder::parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
2680 ArrayRef<PipelineElement> Pipeline) {
2681 for (const auto &Element : Pipeline) {
2682 if (auto Err = parseCGSCCPass(CGPM, Element))
2683 return Err;
2684 }
2685 return Error::success();
2686}
2687
2693 MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });
2694 MAM.registerPass([&] { return CGSCCAnalysisManagerModuleProxy(CGAM); });
2695 CGAM.registerPass([&] { return ModuleAnalysisManagerCGSCCProxy(MAM); });
2696 FAM.registerPass([&] { return CGSCCAnalysisManagerFunctionProxy(CGAM); });
2697 FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); });
2698 FAM.registerPass([&] { return LoopAnalysisManagerFunctionProxy(LAM); });
2699 LAM.registerPass([&] { return FunctionAnalysisManagerLoopProxy(FAM); });
2700 if (MFAM) {
2701 MAM.registerPass(
2702 [&] { return MachineFunctionAnalysisManagerModuleProxy(*MFAM); });
2703 FAM.registerPass(
2704 [&] { return MachineFunctionAnalysisManagerFunctionProxy(*MFAM); });
2705 MFAM->registerPass(
2707 MFAM->registerPass(
2709 }
2710}
2711
2712Error PassBuilder::parseModulePassPipeline(ModulePassManager &MPM,
2713 ArrayRef<PipelineElement> Pipeline) {
2714 for (const auto &Element : Pipeline) {
2715 if (auto Err = parseModulePass(MPM, Element))
2716 return Err;
2717 }
2718 return Error::success();
2719}
2720
2721// Primary pass pipeline description parsing routine for a \c ModulePassManager
2722// FIXME: Should this routine accept a TargetMachine or require the caller to
2723// pre-populate the analysis managers with target-specific stuff?
2725 StringRef PipelineText) {
2726 auto Pipeline = parsePipelineText(PipelineText);
2727 if (!Pipeline || Pipeline->empty())
2729 formatv("invalid pipeline '{}'", PipelineText).str(),
2731
2732 // If the first name isn't at the module layer, wrap the pipeline up
2733 // automatically.
2734 StringRef FirstName = Pipeline->front().Name;
2735
2736 if (!isModulePassName(FirstName, ModulePipelineParsingCallbacks)) {
2737 bool UseMemorySSA;
2738 if (isCGSCCPassName(FirstName, CGSCCPipelineParsingCallbacks)) {
2739 Pipeline = {{"cgscc", std::move(*Pipeline)}};
2740 } else if (isFunctionPassName(FirstName,
2741 FunctionPipelineParsingCallbacks)) {
2742 Pipeline = {{"function", std::move(*Pipeline)}};
2743 } else if (isLoopNestPassName(FirstName, LoopPipelineParsingCallbacks,
2744 UseMemorySSA)) {
2745 Pipeline = {{"function", {{UseMemorySSA ? "loop-mssa" : "loop",
2746 std::move(*Pipeline)}}}};
2747 } else if (isLoopPassName(FirstName, LoopPipelineParsingCallbacks,
2748 UseMemorySSA)) {
2749 Pipeline = {{"function", {{UseMemorySSA ? "loop-mssa" : "loop",
2750 std::move(*Pipeline)}}}};
2751 } else if (isMachineFunctionPassName(
2752 FirstName, MachineFunctionPipelineParsingCallbacks)) {
2753 Pipeline = {{"function", {{"machine-function", std::move(*Pipeline)}}}};
2754 } else {
2755 for (auto &C : TopLevelPipelineParsingCallbacks)
2756 if (C(MPM, *Pipeline))
2757 return Error::success();
2758
2759 // Unknown pass or pipeline name!
2760 auto &InnerPipeline = Pipeline->front().InnerPipeline;
2762 formatv("unknown {} name '{}'",
2763 (InnerPipeline.empty() ? "pass" : "pipeline"), FirstName)
2764 .str(),
2766 }
2767 }
2768
2769 if (auto Err = parseModulePassPipeline(MPM, *Pipeline))
2770 return Err;
2771 return Error::success();
2772}
2773
2774// Primary pass pipeline description parsing routine for a \c CGSCCPassManager
2776 StringRef PipelineText) {
2777 auto Pipeline = parsePipelineText(PipelineText);
2778 if (!Pipeline || Pipeline->empty())
2780 formatv("invalid pipeline '{}'", PipelineText).str(),
2782
2783 StringRef FirstName = Pipeline->front().Name;
2784 if (!isCGSCCPassName(FirstName, CGSCCPipelineParsingCallbacks))
2786 formatv("unknown cgscc pass '{}' in pipeline '{}'", FirstName,
2787 PipelineText)
2788 .str(),
2790
2791 if (auto Err = parseCGSCCPassPipeline(CGPM, *Pipeline))
2792 return Err;
2793 return Error::success();
2794}
2795
2796// Primary pass pipeline description parsing routine for a \c
2797// FunctionPassManager
2799 StringRef PipelineText) {
2800 auto Pipeline = parsePipelineText(PipelineText);
2801 if (!Pipeline || Pipeline->empty())
2803 formatv("invalid pipeline '{}'", PipelineText).str(),
2805
2806 StringRef FirstName = Pipeline->front().Name;
2807 if (!isFunctionPassName(FirstName, FunctionPipelineParsingCallbacks))
2809 formatv("unknown function pass '{}' in pipeline '{}'", FirstName,
2810 PipelineText)
2811 .str(),
2813
2814 if (auto Err = parseFunctionPassPipeline(FPM, *Pipeline))
2815 return Err;
2816 return Error::success();
2817}
2818
2819// Primary pass pipeline description parsing routine for a \c LoopPassManager
2821 StringRef PipelineText) {
2822 auto Pipeline = parsePipelineText(PipelineText);
2823 if (!Pipeline || Pipeline->empty())
2825 formatv("invalid pipeline '{}'", PipelineText).str(),
2827
2828 if (auto Err = parseLoopPassPipeline(CGPM, *Pipeline))
2829 return Err;
2830
2831 return Error::success();
2832}
2833
2835 StringRef PipelineText) {
2836 auto Pipeline = parsePipelineText(PipelineText);
2837 if (!Pipeline || Pipeline->empty())
2839 formatv("invalid machine pass pipeline '{}'", PipelineText).str(),
2841
2842 if (auto Err = parseMachinePassPipeline(MFPM, *Pipeline))
2843 return Err;
2844
2845 return Error::success();
2846}
2847
2849 // If the pipeline just consists of the word 'default' just replace the AA
2850 // manager with our default one.
2851 if (PipelineText == "default") {
2853 return Error::success();
2854 }
2855
2856 while (!PipelineText.empty()) {
2857 StringRef Name;
2858 std::tie(Name, PipelineText) = PipelineText.split(',');
2859 if (!parseAAPassName(AA, Name))
2861 formatv("unknown alias analysis name '{}'", Name).str(),
2863 }
2864
2865 return Error::success();
2866}
2867
2868std::optional<RegAllocFilterFunc>
2870 if (FilterName == "all")
2871 return nullptr;
2872 for (auto &C : RegClassFilterParsingCallbacks)
2873 if (auto F = C(FilterName))
2874 return F;
2875 return std::nullopt;
2876}
2877
2879 raw_ostream &OS) {
2880 for (StringRef PassName : PassNames)
2881 OS << " " << PassName << '\n';
2882}
2883
2884LLVM_ATTRIBUTE_NOINLINE static void
2886 auto I = PassNames.begin();
2887 auto End = PassNames.end();
2888 while (I != End) {
2889 StringRef Name = *I;
2890 ++I;
2891 assert(I != End);
2892 StringRef Params = *I;
2893 ++I;
2894 OS << " " << Name << '<' << Params << ">\n";
2895 }
2896}
2897
2899 // TODO: print pass descriptions when they are available
2900
2901 OS << "Module passes:\n";
2902 static constexpr char ModulePassNames[] = {"\0"
2903#define MODULE_PASS(NAME, CREATE_PASS) NAME "\0"
2904#include "PassRegistry.def"
2905 };
2906 printPassNameList(StringTable(ModulePassNames), OS);
2907
2908 OS << "Module passes with params:\n";
2909 static constexpr char ModulePassNamesWithParams[] = {"\0"
2910#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2911 NAME "\0" PARAMS "\0"
2912#include "PassRegistry.def"
2913 };
2914 printPassNameListWithParams(StringTable(ModulePassNamesWithParams), OS);
2915
2916 OS << "Module analyses:\n";
2917 static constexpr char ModuleAnalysisNames[] = {"\0"
2918#define MODULE_ANALYSIS(NAME, CREATE_PASS) NAME "\0"
2919#include "PassRegistry.def"
2920 };
2921 printPassNameList(StringTable(ModuleAnalysisNames), OS);
2922
2923 OS << "Module alias analyses:\n";
2924 static constexpr char ModuleAliasAnalysisNames[] = {"\0"
2925#define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) NAME "\0"
2926#include "PassRegistry.def"
2927 };
2928 printPassNameList(StringTable(ModuleAliasAnalysisNames), OS);
2929
2930 OS << "CGSCC passes:\n";
2931 static constexpr char CGSCCPassNames[] = {"\0"
2932#define CGSCC_PASS(NAME, CREATE_PASS) NAME "\0"
2933#include "PassRegistry.def"
2934 };
2935 printPassNameList(StringTable(CGSCCPassNames), OS);
2936
2937 OS << "CGSCC passes with params:\n";
2938 static constexpr char CGSCCPassNamesWithParams[] = {"\0"
2939#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2940 NAME "\0" PARAMS "\0"
2941#include "PassRegistry.def"
2942 };
2943 printPassNameListWithParams(StringTable(CGSCCPassNamesWithParams), OS);
2944
2945 OS << "CGSCC analyses:\n";
2946 static constexpr char CGSCCAnalysisNames[] = {"\0"
2947#define CGSCC_ANALYSIS(NAME, CREATE_PASS) NAME "\0"
2948#include "PassRegistry.def"
2949 };
2950 printPassNameList(StringTable(CGSCCAnalysisNames), OS);
2951
2952 OS << "Function passes:\n";
2953 static constexpr char FunctionPassNames[] = {"\0"
2954#define FUNCTION_PASS(NAME, CREATE_PASS) NAME "\0"
2955#include "PassRegistry.def"
2956 };
2957 printPassNameList(StringTable(FunctionPassNames), OS);
2958
2959 OS << "Function passes with params:\n";
2960 static constexpr char FunctionPassNamesWithParams[] = {"\0"
2961#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2962 NAME "\0" PARAMS "\0"
2963#include "PassRegistry.def"
2964 };
2965 printPassNameListWithParams(StringTable(FunctionPassNamesWithParams), OS);
2966
2967 OS << "Function analyses:\n";
2968 static constexpr char FunctionAnalysisNames[] = {"\0"
2969#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) NAME "\0"
2970#include "PassRegistry.def"
2971 };
2972 printPassNameList(StringTable(FunctionAnalysisNames), OS);
2973
2974 OS << "Function alias analyses:\n";
2975 static constexpr char FunctionAliasAnalysisNames[] = {"\0"
2976#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) NAME "\0"
2977#include "PassRegistry.def"
2978 };
2979 printPassNameList(StringTable(FunctionAliasAnalysisNames), OS);
2980
2981 OS << "LoopNest passes:\n";
2982 static constexpr char LoopNestPassNames[] = {"\0"
2983#define LOOPNEST_PASS(NAME, CREATE_PASS) NAME "\0"
2984#include "PassRegistry.def"
2985 };
2986 printPassNameList(StringTable(LoopNestPassNames), OS);
2987
2988 OS << "Loop passes:\n";
2989 static constexpr char LoopPassNames[] = {"\0"
2990#define LOOP_PASS(NAME, CREATE_PASS) NAME "\0"
2991#include "PassRegistry.def"
2992 };
2993 printPassNameList(StringTable(LoopPassNames), OS);
2994
2995 OS << "Loop passes with params:\n";
2996 static constexpr char LoopPassNamesWithParams[] = {"\0"
2997#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2998 NAME "\0" PARAMS "\0"
2999#include "PassRegistry.def"
3000 };
3001 printPassNameListWithParams(StringTable(LoopPassNamesWithParams), OS);
3002
3003 OS << "Loop analyses:\n";
3004 static constexpr char LoopAnalysisNames[] = {"\0"
3005#define LOOP_ANALYSIS(NAME, CREATE_PASS) NAME "\0"
3006#include "PassRegistry.def"
3007 };
3008 printPassNameList(StringTable(LoopAnalysisNames), OS);
3009
3010 OS << "Machine module passes (WIP):\n";
3011 static constexpr char MachineModulePassNames[] = {"\0"
3012#define MACHINE_MODULE_PASS(NAME, CREATE_PASS) NAME "\0"
3013#include "llvm/Passes/MachinePassRegistry.def"
3014 };
3015 printPassNameList(StringTable(MachineModulePassNames), OS);
3016
3017 OS << "Machine function passes (WIP):\n";
3018 static constexpr char MachineFunctionPassNames[] = {"\0"
3019#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) NAME "\0"
3020#include "llvm/Passes/MachinePassRegistry.def"
3021 };
3022 printPassNameList(StringTable(MachineFunctionPassNames), OS);
3023
3024 OS << "Machine function analyses (WIP):\n";
3025 static constexpr char MachineFunctionAnalysisNames[] = {"\0"
3026#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) NAME "\0"
3027#include "llvm/Passes/MachinePassRegistry.def"
3028 };
3029 printPassNameList(StringTable(MachineFunctionAnalysisNames), OS);
3030}
3031
3033 const std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>)>
3034 &C) {
3035 TopLevelPipelineParsingCallbacks.push_back(C);
3036}
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 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:1561
int64_t getSExtValue() const
Get sign extended value.
Definition APInt.h:1583
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)