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