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