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