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