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