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
32#include "llvm/Analysis/DDG.h"
53#include "llvm/Analysis/Lint.h"
142#include "llvm/CodeGen/PEI.h"
185#include "llvm/IR/DebugInfo.h"
186#include "llvm/IR/Dominators.h"
187#include "llvm/IR/PassManager.h"
189#include "llvm/IR/Verifier.h"
192#include "llvm/Support/CodeGen.h"
194#include "llvm/Support/Debug.h"
195#include "llvm/Support/Error.h"
198#include "llvm/Support/Regex.h"
388#include <optional>
389
390using namespace llvm;
391
393 "print-pipeline-passes",
394 cl::desc("Print a '-passes' compatible string describing the pipeline "
395 "(best-effort only)."));
396
397AnalysisKey NoOpModuleAnalysis::Key;
398AnalysisKey NoOpCGSCCAnalysis::Key;
399AnalysisKey NoOpFunctionAnalysis::Key;
400AnalysisKey NoOpLoopAnalysis::Key;
401
402namespace {
403
404// Passes for testing crashes.
405// DO NOT USE THIS EXCEPT FOR TESTING!
406class TriggerCrashModulePass : public PassInfoMixin<TriggerCrashModulePass> {
407public:
408 PreservedAnalyses run(Module &, ModuleAnalysisManager &) {
409 abort();
410 return PreservedAnalyses::all();
411 }
412 static StringRef name() { return "TriggerCrashModulePass"; }
413};
414
415class TriggerCrashFunctionPass
416 : public PassInfoMixin<TriggerCrashFunctionPass> {
417public:
418 PreservedAnalyses run(Function &, FunctionAnalysisManager &) {
419 abort();
420 return PreservedAnalyses::all();
421 }
422 static StringRef name() { return "TriggerCrashFunctionPass"; }
423};
424
425// A pass for testing message reporting of -verify-each failures.
426// DO NOT USE THIS EXCEPT FOR TESTING!
427class TriggerVerifierErrorPass
428 : public PassInfoMixin<TriggerVerifierErrorPass> {
429public:
430 PreservedAnalyses run(Module &M, ModuleAnalysisManager &) {
431 // Intentionally break the Module by creating an alias without setting the
432 // aliasee.
433 auto *PtrTy = PointerType::getUnqual(M.getContext());
434 GlobalAlias::create(PtrTy, PtrTy->getAddressSpace(),
435 GlobalValue::LinkageTypes::InternalLinkage,
436 "__bad_alias", nullptr, &M);
438 }
439
440 PreservedAnalyses run(Function &F, FunctionAnalysisManager &) {
441 // Intentionally break the Function by inserting a terminator
442 // instruction in the middle of a basic block.
443 BasicBlock &BB = F.getEntryBlock();
444 new UnreachableInst(F.getContext(), BB.getTerminator()->getIterator());
446 }
447
448 PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &) {
449 // Intentionally create a virtual register and set NoVRegs property.
450 auto &MRI = MF.getRegInfo();
452 MF.getProperties().setNoVRegs();
453 return PreservedAnalyses::all();
454 }
455
456 static StringRef name() { return "TriggerVerifierErrorPass"; }
457};
458
459// A pass requires all MachineFunctionProperties.
460// DO NOT USE THIS EXCEPT FOR TESTING!
461class RequireAllMachineFunctionPropertiesPass
462 : public PassInfoMixin<RequireAllMachineFunctionPropertiesPass> {
463public:
464 PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &) {
465 MFPropsModifier _(*this, MF);
467 }
468
469 static MachineFunctionProperties getRequiredProperties() {
470 return MachineFunctionProperties()
471 .setFailedISel()
472 .setFailsVerification()
473 .setIsSSA()
474 .setLegalized()
475 .setNoPHIs()
476 .setNoVRegs()
477 .setRegBankSelected()
478 .setSelected()
479 .setTiedOpsRewritten()
480 .setTracksDebugUserValues()
481 .setTracksLiveness();
482 }
483 static StringRef name() { return "RequireAllMachineFunctionPropertiesPass"; }
484};
485
486} // namespace
487
488static std::optional<OptimizationLevel> parseOptLevel(StringRef S) {
490 .Case("O0", OptimizationLevel::O0)
496 .Default(std::nullopt);
497}
498
500 std::optional<OptimizationLevel> OptLevel = parseOptLevel(S);
501 if (OptLevel)
502 return *OptLevel;
504 formatv("invalid optimization level '{}'", S).str(),
506}
507
509 std::optional<PGOOptions> PGOOpt,
512 : TM(TM), PTO(PTO), PGOOpt(PGOOpt), PIC(PIC), FS(std::move(FS)) {
513 if (TM)
514 TM->registerPassBuilderCallbacks(*this);
515 if (PIC) {
516 PIC->registerClassToPassNameCallback([this, PIC]() {
517 // MSVC requires this to be captured if it's used inside decltype.
518 // Other compilers consider it an unused lambda capture.
519 (void)this;
520#define MODULE_PASS(NAME, CREATE_PASS) \
521 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
522#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
523 PIC->addClassToPassName(CLASS, NAME);
524#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
525 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
526#define FUNCTION_PASS(NAME, CREATE_PASS) \
527 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
528#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
529 PIC->addClassToPassName(CLASS, NAME);
530#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
531 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
532#define LOOPNEST_PASS(NAME, CREATE_PASS) \
533 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
534#define LOOP_PASS(NAME, CREATE_PASS) \
535 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
536#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
537 PIC->addClassToPassName(CLASS, NAME);
538#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
539 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
540#define CGSCC_PASS(NAME, CREATE_PASS) \
541 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
542#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
543 PIC->addClassToPassName(CLASS, NAME);
544#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
545 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
546#include "PassRegistry.def"
547
548#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
549 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
550#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
551 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
552#define MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, \
553 PARAMS) \
554 PIC->addClassToPassName(CLASS, NAME);
555#include "llvm/Passes/MachinePassRegistry.def"
556 });
557 }
558
559 // Module-level callbacks without LTO phase
561 [this](StringRef Name, ModulePassManager &PM,
563#define MODULE_CALLBACK(NAME, INVOKE) \
564 if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
565 auto L = PassBuilder::parsePassParameters(parseOptLevelParam, Name, NAME); \
566 if (!L) { \
567 errs() << NAME ": " << toString(L.takeError()) << '\n'; \
568 return false; \
569 } \
570 INVOKE(PM, L.get()); \
571 return true; \
572 }
573#include "PassRegistry.def"
574 return false;
575 });
576
577 // Module-level callbacks with LTO phase (use Phase::None for string API)
579 [this](StringRef Name, ModulePassManager &PM,
581#define MODULE_LTO_CALLBACK(NAME, INVOKE) \
582 if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
583 auto L = PassBuilder::parsePassParameters(parseOptLevelParam, Name, NAME); \
584 if (!L) { \
585 errs() << NAME ": " << toString(L.takeError()) << '\n'; \
586 return false; \
587 } \
588 INVOKE(PM, L.get(), ThinOrFullLTOPhase::None); \
589 return true; \
590 }
591#include "PassRegistry.def"
592 return false;
593 });
594
595 // Function-level callbacks
597 [this](StringRef Name, FunctionPassManager &PM,
599#define FUNCTION_CALLBACK(NAME, INVOKE) \
600 if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
601 auto L = PassBuilder::parsePassParameters(parseOptLevelParam, Name, NAME); \
602 if (!L) { \
603 errs() << NAME ": " << toString(L.takeError()) << '\n'; \
604 return false; \
605 } \
606 INVOKE(PM, L.get()); \
607 return true; \
608 }
609#include "PassRegistry.def"
610 return false;
611 });
612
613 // CGSCC-level callbacks
615 [this](StringRef Name, CGSCCPassManager &PM,
617#define CGSCC_CALLBACK(NAME, INVOKE) \
618 if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
619 auto L = PassBuilder::parsePassParameters(parseOptLevelParam, Name, NAME); \
620 if (!L) { \
621 errs() << NAME ": " << toString(L.takeError()) << '\n'; \
622 return false; \
623 } \
624 INVOKE(PM, L.get()); \
625 return true; \
626 }
627#include "PassRegistry.def"
628 return false;
629 });
630
631 // Loop-level callbacks
633 [this](StringRef Name, LoopPassManager &PM,
635#define LOOP_CALLBACK(NAME, INVOKE) \
636 if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
637 auto L = PassBuilder::parsePassParameters(parseOptLevelParam, Name, NAME); \
638 if (!L) { \
639 errs() << NAME ": " << toString(L.takeError()) << '\n'; \
640 return false; \
641 } \
642 INVOKE(PM, L.get()); \
643 return true; \
644 }
645#include "PassRegistry.def"
646 return false;
647 });
648}
649
651#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
652 MAM.registerPass([&] { return CREATE_PASS; });
653#include "PassRegistry.def"
654
655 for (auto &C : ModuleAnalysisRegistrationCallbacks)
656 C(MAM);
657}
658
660#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
661 CGAM.registerPass([&] { return CREATE_PASS; });
662#include "PassRegistry.def"
663
664 for (auto &C : CGSCCAnalysisRegistrationCallbacks)
665 C(CGAM);
666}
667
669 // We almost always want the default alias analysis pipeline.
670 // If a user wants a different one, they can register their own before calling
671 // registerFunctionAnalyses().
672 FAM.registerPass([&] { return buildDefaultAAPipeline(); });
673
674#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
675 if constexpr (std::is_constructible_v< \
676 std::remove_reference_t<decltype(CREATE_PASS)>, \
677 const TargetMachine &>) { \
678 if (TM) \
679 FAM.registerPass([&] { return CREATE_PASS; }); \
680 } else { \
681 FAM.registerPass([&] { return CREATE_PASS; }); \
682 }
683#include "PassRegistry.def"
684
685 for (auto &C : FunctionAnalysisRegistrationCallbacks)
686 C(FAM);
687}
688
691
692#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
693 MFAM.registerPass([&] { return CREATE_PASS; });
694#include "llvm/Passes/MachinePassRegistry.def"
695
696 for (auto &C : MachineFunctionAnalysisRegistrationCallbacks)
697 C(MFAM);
698}
699
701#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
702 LAM.registerPass([&] { return CREATE_PASS; });
703#include "PassRegistry.def"
704
705 for (auto &C : LoopAnalysisRegistrationCallbacks)
706 C(LAM);
707}
708
709static std::optional<std::pair<bool, bool>>
711 std::pair<bool, bool> Params;
712 if (!Name.consume_front("function"))
713 return std::nullopt;
714 if (Name.empty())
715 return Params;
716 if (!Name.consume_front("<") || !Name.consume_back(">"))
717 return std::nullopt;
718 while (!Name.empty()) {
719 auto [Front, Back] = Name.split(';');
720 Name = Back;
721 if (Front == "eager-inv")
722 Params.first = true;
723 else if (Front == "no-rerun")
724 Params.second = true;
725 else
726 return std::nullopt;
727 }
728 return Params;
729}
730
731static std::optional<int> parseDevirtPassName(StringRef Name) {
732 if (!Name.consume_front("devirt<") || !Name.consume_back(">"))
733 return std::nullopt;
734 int Count;
735 if (Name.getAsInteger(0, Count) || Count < 0)
736 return std::nullopt;
737 return Count;
738}
739
741 StringRef OptionName,
743 bool Result = false;
744 while (!Params.empty()) {
745 StringRef ParamName;
746 std::tie(ParamName, Params) = Params.split(';');
747
748 if (ParamName == OptionName) {
749 Result = true;
750 } else {
752 formatv("invalid {} pass parameter '{}'", PassName, ParamName).str(),
754 }
755 }
756 return Result;
757}
758
759namespace {
760
761/// Parser of parameters for HardwareLoops pass.
762Expected<HardwareLoopOptions> parseHardwareLoopOptions(StringRef Params) {
763 HardwareLoopOptions HardwareLoopOpts;
764
765 while (!Params.empty()) {
766 StringRef ParamName;
767 std::tie(ParamName, Params) = Params.split(';');
768 if (ParamName.consume_front("hardware-loop-decrement=")) {
769 int Count;
770 if (ParamName.getAsInteger(0, Count))
772 formatv("invalid HardwareLoopPass parameter '{}'", ParamName).str(),
774 HardwareLoopOpts.setDecrement(Count);
775 continue;
776 }
777 if (ParamName.consume_front("hardware-loop-counter-bitwidth=")) {
778 int Count;
779 if (ParamName.getAsInteger(0, Count))
781 formatv("invalid HardwareLoopPass parameter '{}'", ParamName).str(),
783 HardwareLoopOpts.setCounterBitwidth(Count);
784 continue;
785 }
786 if (ParamName == "force-hardware-loops") {
787 HardwareLoopOpts.setForce(true);
788 } else if (ParamName == "force-hardware-loop-phi") {
789 HardwareLoopOpts.setForcePhi(true);
790 } else if (ParamName == "force-nested-hardware-loop") {
791 HardwareLoopOpts.setForceNested(true);
792 } else if (ParamName == "force-hardware-loop-guard") {
793 HardwareLoopOpts.setForceGuard(true);
794 } else {
796 formatv("invalid HardwarePass parameter '{}'", ParamName).str(),
798 }
799 }
800 return HardwareLoopOpts;
801}
802
803/// Parser of parameters for Lint pass.
804Expected<bool> parseLintOptions(StringRef Params) {
805 return PassBuilder::parseSinglePassOption(Params, "abort-on-error",
806 "LintPass");
807}
808
809/// Parser of parameters for LoopUnroll pass.
810Expected<LoopUnrollOptions> parseLoopUnrollOptions(StringRef Params) {
811 LoopUnrollOptions UnrollOpts;
812 while (!Params.empty()) {
813 StringRef ParamName;
814 std::tie(ParamName, Params) = Params.split(';');
815 std::optional<OptimizationLevel> OptLevel = parseOptLevel(ParamName);
816 // Don't accept -Os/-Oz.
817 if (OptLevel && !OptLevel->isOptimizingForSize()) {
818 UnrollOpts.setOptLevel(OptLevel->getSpeedupLevel());
819 continue;
820 }
821 if (ParamName.consume_front("full-unroll-max=")) {
822 int Count;
823 if (ParamName.getAsInteger(0, Count))
825 formatv("invalid LoopUnrollPass parameter '{}'", ParamName).str(),
827 UnrollOpts.setFullUnrollMaxCount(Count);
828 continue;
829 }
830
831 bool Enable = !ParamName.consume_front("no-");
832 if (ParamName == "partial") {
833 UnrollOpts.setPartial(Enable);
834 } else if (ParamName == "peeling") {
835 UnrollOpts.setPeeling(Enable);
836 } else if (ParamName == "profile-peeling") {
837 UnrollOpts.setProfileBasedPeeling(Enable);
838 } else if (ParamName == "runtime") {
839 UnrollOpts.setRuntime(Enable);
840 } else if (ParamName == "upperbound") {
841 UnrollOpts.setUpperBound(Enable);
842 } else {
844 formatv("invalid LoopUnrollPass parameter '{}'", ParamName).str(),
846 }
847 }
848 return UnrollOpts;
849}
850
851Expected<bool> parseGlobalDCEPassOptions(StringRef Params) {
853 Params, "vfe-linkage-unit-visibility", "GlobalDCE");
854}
855
856Expected<bool> parseCGProfilePassOptions(StringRef Params) {
857 return PassBuilder::parseSinglePassOption(Params, "in-lto-post-link",
858 "CGProfile");
859}
860
861Expected<bool> parseInlinerPassOptions(StringRef Params) {
862 return PassBuilder::parseSinglePassOption(Params, "only-mandatory",
863 "InlinerPass");
864}
865
866Expected<bool> parseCoroSplitPassOptions(StringRef Params) {
867 return PassBuilder::parseSinglePassOption(Params, "reuse-storage",
868 "CoroSplitPass");
869}
870
871Expected<bool> parsePostOrderFunctionAttrsPassOptions(StringRef Params) {
873 Params, "skip-non-recursive-function-attrs", "PostOrderFunctionAttrs");
874}
875
876Expected<CFGuardPass::Mechanism> parseCFGuardPassOptions(StringRef Params) {
877 if (Params.empty())
879
880 auto [Param, RHS] = Params.split(';');
881 if (!RHS.empty())
883 formatv("too many CFGuardPass parameters '{}'", Params).str(),
885
886 if (Param == "check")
888 if (Param == "dispatch")
890
892 formatv("invalid CFGuardPass mechanism: '{}'", Param).str(),
894}
895
896Expected<bool> parseEarlyCSEPassOptions(StringRef Params) {
897 return PassBuilder::parseSinglePassOption(Params, "memssa", "EarlyCSE");
898}
899
900Expected<bool> parseEntryExitInstrumenterPassOptions(StringRef Params) {
901 return PassBuilder::parseSinglePassOption(Params, "post-inline",
902 "EntryExitInstrumenter");
903}
904
905Expected<bool> parseDropUnnecessaryAssumesPassOptions(StringRef Params) {
906 return PassBuilder::parseSinglePassOption(Params, "drop-deref",
907 "DropUnnecessaryAssumes");
908}
909
910Expected<bool> parseLoopExtractorPassOptions(StringRef Params) {
911 return PassBuilder::parseSinglePassOption(Params, "single", "LoopExtractor");
912}
913
914Expected<bool> parseLowerMatrixIntrinsicsPassOptions(StringRef Params) {
915 return PassBuilder::parseSinglePassOption(Params, "minimal",
916 "LowerMatrixIntrinsics");
917}
918
919Expected<IRNormalizerOptions> parseIRNormalizerPassOptions(StringRef Params) {
921 while (!Params.empty()) {
922 StringRef ParamName;
923 std::tie(ParamName, Params) = Params.split(';');
924
925 bool Enable = !ParamName.consume_front("no-");
926 if (ParamName == "preserve-order")
927 Result.PreserveOrder = Enable;
928 else if (ParamName == "rename-all")
929 Result.RenameAll = Enable;
930 else if (ParamName == "fold-all") // FIXME: Name mismatch
931 Result.FoldPreOutputs = Enable;
932 else if (ParamName == "reorder-operands")
933 Result.ReorderOperands = Enable;
934 else {
936 formatv("invalid normalize pass parameter '{}'", ParamName).str(),
938 }
939 }
940
941 return Result;
942}
943
944Expected<AddressSanitizerOptions> parseASanPassOptions(StringRef Params) {
946 while (!Params.empty()) {
947 StringRef ParamName;
948 std::tie(ParamName, Params) = Params.split(';');
949
950 if (ParamName == "kernel") {
951 Result.CompileKernel = true;
952 } else if (ParamName == "use-after-scope") {
953 Result.UseAfterScope = true;
954 } else {
956 formatv("invalid AddressSanitizer pass parameter '{}'", ParamName)
957 .str(),
959 }
960 }
961 return Result;
962}
963
964Expected<HWAddressSanitizerOptions> parseHWASanPassOptions(StringRef Params) {
966 while (!Params.empty()) {
967 StringRef ParamName;
968 std::tie(ParamName, Params) = Params.split(';');
969
970 if (ParamName == "recover") {
971 Result.Recover = true;
972 } else if (ParamName == "kernel") {
973 Result.CompileKernel = true;
974 } else {
976 formatv("invalid HWAddressSanitizer pass parameter '{}'", ParamName)
977 .str(),
979 }
980 }
981 return Result;
982}
983
984Expected<EmbedBitcodeOptions> parseEmbedBitcodePassOptions(StringRef Params) {
986 while (!Params.empty()) {
987 StringRef ParamName;
988 std::tie(ParamName, Params) = Params.split(';');
989
990 if (ParamName == "thinlto") {
991 Result.IsThinLTO = true;
992 } else if (ParamName == "emit-summary") {
993 Result.EmitLTOSummary = true;
994 } else {
996 formatv("invalid EmbedBitcode pass parameter '{}'", ParamName).str(),
998 }
999 }
1000 return Result;
1001}
1002
1004parseLowerAllowCheckPassOptions(StringRef Params) {
1006 while (!Params.empty()) {
1007 StringRef ParamName;
1008 std::tie(ParamName, Params) = Params.split(';');
1009
1010 // Format is <cutoffs[1,2,3]=70000;cutoffs[5,6,8]=90000>
1011 //
1012 // Parsing allows duplicate indices (last one takes precedence).
1013 // It would technically be in spec to specify
1014 // cutoffs[0]=70000,cutoffs[1]=90000,cutoffs[0]=80000,...
1015 if (ParamName.starts_with("cutoffs[")) {
1016 StringRef IndicesStr;
1017 StringRef CutoffStr;
1018
1019 std::tie(IndicesStr, CutoffStr) = ParamName.split("]=");
1020 // cutoffs[1,2,3
1021 // 70000
1022
1023 int cutoff;
1024 if (CutoffStr.getAsInteger(0, cutoff))
1026 formatv("invalid LowerAllowCheck pass cutoffs parameter '{}' ({})",
1027 CutoffStr, Params)
1028 .str(),
1030
1031 if (!IndicesStr.consume_front("cutoffs[") || IndicesStr == "")
1033 formatv("invalid LowerAllowCheck pass index parameter '{}' ({})",
1034 IndicesStr, CutoffStr)
1035 .str(),
1037
1038 while (IndicesStr != "") {
1039 StringRef firstIndexStr;
1040 std::tie(firstIndexStr, IndicesStr) = IndicesStr.split('|');
1041
1042 unsigned int index;
1043 if (firstIndexStr.getAsInteger(0, index))
1045 formatv(
1046 "invalid LowerAllowCheck pass index parameter '{}' ({}) {}",
1047 firstIndexStr, IndicesStr)
1048 .str(),
1050
1051 // In the common case (sequentially increasing indices), we will issue
1052 // O(n) resize requests. We assume the underlying data structure has
1053 // O(1) runtime for each added element.
1054 if (index >= Result.cutoffs.size())
1055 Result.cutoffs.resize(index + 1, 0);
1056
1057 Result.cutoffs[index] = cutoff;
1058 }
1059 } else if (ParamName.starts_with("runtime_check")) {
1060 StringRef ValueString;
1061 std::tie(std::ignore, ValueString) = ParamName.split("=");
1062 int runtime_check;
1063 if (ValueString.getAsInteger(0, runtime_check)) {
1065 formatv("invalid LowerAllowCheck pass runtime_check parameter '{}' "
1066 "({})",
1067 ValueString, Params)
1068 .str(),
1070 }
1071 Result.runtime_check = runtime_check;
1072 } else {
1074 formatv("invalid LowerAllowCheck pass parameter '{}'", ParamName)
1075 .str(),
1077 }
1078 }
1079
1080 return Result;
1081}
1082
1083Expected<MemorySanitizerOptions> parseMSanPassOptions(StringRef Params) {
1085 while (!Params.empty()) {
1086 StringRef ParamName;
1087 std::tie(ParamName, Params) = Params.split(';');
1088
1089 if (ParamName == "recover") {
1090 Result.Recover = true;
1091 } else if (ParamName == "kernel") {
1092 Result.Kernel = true;
1093 } else if (ParamName.consume_front("track-origins=")) {
1094 if (ParamName.getAsInteger(0, Result.TrackOrigins))
1096 formatv("invalid argument to MemorySanitizer pass track-origins "
1097 "parameter: '{}'",
1098 ParamName)
1099 .str(),
1101 } else if (ParamName == "eager-checks") {
1102 Result.EagerChecks = true;
1103 } else {
1105 formatv("invalid MemorySanitizer pass parameter '{}'", ParamName)
1106 .str(),
1108 }
1109 }
1110 return Result;
1111}
1112
1113Expected<AllocTokenOptions> parseAllocTokenPassOptions(StringRef Params) {
1115 while (!Params.empty()) {
1116 StringRef ParamName;
1117 std::tie(ParamName, Params) = Params.split(';');
1118
1119 if (ParamName.consume_front("mode=")) {
1120 if (auto Mode = getAllocTokenModeFromString(ParamName))
1121 Result.Mode = *Mode;
1122 else
1124 formatv("invalid argument to AllocToken pass mode "
1125 "parameter: '{}'",
1126 ParamName)
1127 .str(),
1129 } else {
1131 formatv("invalid AllocToken pass parameter '{}'", ParamName).str(),
1133 }
1134 }
1135 return Result;
1136}
1137
1138/// Parser of parameters for SimplifyCFG pass.
1139Expected<SimplifyCFGOptions> parseSimplifyCFGOptions(StringRef Params) {
1141 while (!Params.empty()) {
1142 StringRef ParamName;
1143 std::tie(ParamName, Params) = Params.split(';');
1144
1145 bool Enable = !ParamName.consume_front("no-");
1146 if (ParamName == "speculate-blocks") {
1147 Result.speculateBlocks(Enable);
1148 } else if (ParamName == "simplify-cond-branch") {
1149 Result.setSimplifyCondBranch(Enable);
1150 } else if (ParamName == "forward-switch-cond") {
1151 Result.forwardSwitchCondToPhi(Enable);
1152 } else if (ParamName == "switch-range-to-icmp") {
1153 Result.convertSwitchRangeToICmp(Enable);
1154 } else if (ParamName == "switch-to-arithmetic") {
1155 Result.convertSwitchToArithmetic(Enable);
1156 } else if (ParamName == "switch-to-lookup") {
1157 Result.convertSwitchToLookupTable(Enable);
1158 } else if (ParamName == "keep-loops") {
1159 Result.needCanonicalLoops(Enable);
1160 } else if (ParamName == "hoist-common-insts") {
1161 Result.hoistCommonInsts(Enable);
1162 } else if (ParamName == "hoist-loads-stores-with-cond-faulting") {
1163 Result.hoistLoadsStoresWithCondFaulting(Enable);
1164 } else if (ParamName == "sink-common-insts") {
1165 Result.sinkCommonInsts(Enable);
1166 } else if (ParamName == "speculate-unpredictables") {
1167 Result.speculateUnpredictables(Enable);
1168 } else if (Enable && ParamName.consume_front("bonus-inst-threshold=")) {
1169 APInt BonusInstThreshold;
1170 if (ParamName.getAsInteger(0, BonusInstThreshold))
1172 formatv("invalid argument to SimplifyCFG pass bonus-threshold "
1173 "parameter: '{}'",
1174 ParamName)
1175 .str(),
1177 Result.bonusInstThreshold(BonusInstThreshold.getSExtValue());
1178 } else {
1180 formatv("invalid SimplifyCFG pass parameter '{}'", ParamName).str(),
1182 }
1183 }
1184 return Result;
1185}
1186
1187Expected<InstCombineOptions> parseInstCombineOptions(StringRef Params) {
1189 // When specifying "instcombine" in -passes enable fix-point verification by
1190 // default, as this is what most tests should use.
1191 Result.setVerifyFixpoint(true);
1192 while (!Params.empty()) {
1193 StringRef ParamName;
1194 std::tie(ParamName, Params) = Params.split(';');
1195
1196 bool Enable = !ParamName.consume_front("no-");
1197 if (ParamName == "verify-fixpoint") {
1198 Result.setVerifyFixpoint(Enable);
1199 } else if (Enable && ParamName.consume_front("max-iterations=")) {
1200 APInt MaxIterations;
1201 if (ParamName.getAsInteger(0, MaxIterations))
1203 formatv("invalid argument to InstCombine pass max-iterations "
1204 "parameter: '{}'",
1205 ParamName)
1206 .str(),
1208 Result.setMaxIterations((unsigned)MaxIterations.getZExtValue());
1209 } else {
1211 formatv("invalid InstCombine pass parameter '{}'", ParamName).str(),
1213 }
1214 }
1215 return Result;
1216}
1217
1218/// Parser of parameters for LoopVectorize pass.
1219Expected<LoopVectorizeOptions> parseLoopVectorizeOptions(StringRef Params) {
1221 while (!Params.empty()) {
1222 StringRef ParamName;
1223 std::tie(ParamName, Params) = Params.split(';');
1224
1225 bool Enable = !ParamName.consume_front("no-");
1226 if (ParamName == "interleave-forced-only") {
1228 } else if (ParamName == "vectorize-forced-only") {
1230 } else {
1232 formatv("invalid LoopVectorize parameter '{}'", ParamName).str(),
1234 }
1235 }
1236 return Opts;
1237}
1238
1239Expected<std::pair<bool, bool>> parseLoopUnswitchOptions(StringRef Params) {
1240 std::pair<bool, bool> Result = {false, true};
1241 while (!Params.empty()) {
1242 StringRef ParamName;
1243 std::tie(ParamName, Params) = Params.split(';');
1244
1245 bool Enable = !ParamName.consume_front("no-");
1246 if (ParamName == "nontrivial") {
1247 Result.first = Enable;
1248 } else if (ParamName == "trivial") {
1249 Result.second = Enable;
1250 } else {
1252 formatv("invalid LoopUnswitch pass parameter '{}'", ParamName).str(),
1254 }
1255 }
1256 return Result;
1257}
1258
1259Expected<LICMOptions> parseLICMOptions(StringRef Params) {
1261 while (!Params.empty()) {
1262 StringRef ParamName;
1263 std::tie(ParamName, Params) = Params.split(';');
1264
1265 bool Enable = !ParamName.consume_front("no-");
1266 if (ParamName == "allowspeculation") {
1267 Result.AllowSpeculation = Enable;
1268 } else {
1270 formatv("invalid LICM pass parameter '{}'", ParamName).str(),
1272 }
1273 }
1274 return Result;
1275}
1276
1277struct LoopRotateOptions {
1278 bool EnableHeaderDuplication = true;
1279 bool PrepareForLTO = false;
1280 bool CheckExitCount = false;
1281};
1282
1283Expected<LoopRotateOptions> parseLoopRotateOptions(StringRef Params) {
1284 LoopRotateOptions Result;
1285 while (!Params.empty()) {
1286 StringRef ParamName;
1287 std::tie(ParamName, Params) = Params.split(';');
1288
1289 bool Enable = !ParamName.consume_front("no-");
1290 if (ParamName == "header-duplication") {
1291 Result.EnableHeaderDuplication = Enable;
1292 } else if (ParamName == "prepare-for-lto") {
1293 Result.PrepareForLTO = Enable;
1294 } else if (ParamName == "check-exit-count") {
1295 Result.CheckExitCount = Enable;
1296 } else {
1298 formatv("invalid LoopRotate pass parameter '{}'", ParamName).str(),
1300 }
1301 }
1302 return Result;
1303}
1304
1305Expected<bool> parseMergedLoadStoreMotionOptions(StringRef Params) {
1306 bool Result = false;
1307 while (!Params.empty()) {
1308 StringRef ParamName;
1309 std::tie(ParamName, Params) = Params.split(';');
1310
1311 bool Enable = !ParamName.consume_front("no-");
1312 if (ParamName == "split-footer-bb") {
1313 Result = Enable;
1314 } else {
1316 formatv("invalid MergedLoadStoreMotion pass parameter '{}'",
1317 ParamName)
1318 .str(),
1320 }
1321 }
1322 return Result;
1323}
1324
1325Expected<GVNOptions> parseGVNOptions(StringRef Params) {
1327 while (!Params.empty()) {
1328 StringRef ParamName;
1329 std::tie(ParamName, Params) = Params.split(';');
1330
1331 bool Enable = !ParamName.consume_front("no-");
1332 if (ParamName == "pre") {
1333 Result.setPRE(Enable);
1334 } else if (ParamName == "load-pre") {
1335 Result.setLoadPRE(Enable);
1336 } else if (ParamName == "split-backedge-load-pre") {
1337 Result.setLoadPRESplitBackedge(Enable);
1338 } else if (ParamName == "memdep") {
1339 // MemDep and MemorySSA are mutually exclusive.
1340 Result.setMemDep(Enable);
1341 Result.setMemorySSA(!Enable);
1342 } else if (ParamName == "memoryssa") {
1343 // MemDep and MemorySSA are mutually exclusive.
1344 Result.setMemorySSA(Enable);
1345 Result.setMemDep(!Enable);
1346 } else {
1348 formatv("invalid GVN pass parameter '{}'", ParamName).str(),
1350 }
1351 }
1352 return Result;
1353}
1354
1355Expected<IPSCCPOptions> parseIPSCCPOptions(StringRef Params) {
1357 while (!Params.empty()) {
1358 StringRef ParamName;
1359 std::tie(ParamName, Params) = Params.split(';');
1360
1361 bool Enable = !ParamName.consume_front("no-");
1362 if (ParamName == "func-spec")
1363 Result.setFuncSpec(Enable);
1364 else
1366 formatv("invalid IPSCCP pass parameter '{}'", ParamName).str(),
1368 }
1369 return Result;
1370}
1371
1372Expected<ScalarizerPassOptions> parseScalarizerOptions(StringRef Params) {
1374 while (!Params.empty()) {
1375 StringRef ParamName;
1376 std::tie(ParamName, Params) = Params.split(';');
1377
1378 if (ParamName.consume_front("min-bits=")) {
1379 if (ParamName.getAsInteger(0, Result.ScalarizeMinBits)) {
1381 formatv("invalid argument to Scalarizer pass min-bits "
1382 "parameter: '{}'",
1383 ParamName)
1384 .str(),
1386 }
1387
1388 continue;
1389 }
1390
1391 bool Enable = !ParamName.consume_front("no-");
1392 if (ParamName == "load-store")
1393 Result.ScalarizeLoadStore = Enable;
1394 else if (ParamName == "variable-insert-extract")
1395 Result.ScalarizeVariableInsertExtract = Enable;
1396 else {
1398 formatv("invalid Scalarizer pass parameter '{}'", ParamName).str(),
1400 }
1401 }
1402
1403 return Result;
1404}
1405
1406Expected<SROAOptions> parseSROAOptions(StringRef Params) {
1407 if (Params.empty() || Params == "modify-cfg")
1409 if (Params == "preserve-cfg")
1412 formatv("invalid SROA pass parameter '{}' (either preserve-cfg or "
1413 "modify-cfg can be specified)",
1414 Params)
1415 .str(),
1417}
1418
1420parseStackLifetimeOptions(StringRef Params) {
1422 while (!Params.empty()) {
1423 StringRef ParamName;
1424 std::tie(ParamName, Params) = Params.split(';');
1425
1426 if (ParamName == "may") {
1428 } else if (ParamName == "must") {
1430 } else {
1432 formatv("invalid StackLifetime parameter '{}'", ParamName).str(),
1434 }
1435 }
1436 return Result;
1437}
1438
1439Expected<bool> parseDependenceAnalysisPrinterOptions(StringRef Params) {
1440 return PassBuilder::parseSinglePassOption(Params, "normalized-results",
1441 "DependenceAnalysisPrinter");
1442}
1443
1444Expected<bool> parseSeparateConstOffsetFromGEPPassOptions(StringRef Params) {
1445 return PassBuilder::parseSinglePassOption(Params, "lower-gep",
1446 "SeparateConstOffsetFromGEP");
1447}
1448
1449Expected<bool> parseStructurizeCFGPassOptions(StringRef Params) {
1450 return PassBuilder::parseSinglePassOption(Params, "skip-uniform-regions",
1451 "StructurizeCFG");
1452}
1453
1455parseFunctionSimplificationPipelineOptions(StringRef Params) {
1456 std::optional<OptimizationLevel> L = parseOptLevel(Params);
1457 if (!L || *L == OptimizationLevel::O0) {
1459 formatv("invalid function-simplification parameter '{}'", Params).str(),
1461 };
1462 return *L;
1463}
1464
1465Expected<bool> parseMemorySSAPrinterPassOptions(StringRef Params) {
1466 return PassBuilder::parseSinglePassOption(Params, "no-ensure-optimized-uses",
1467 "MemorySSAPrinterPass");
1468}
1469
1470Expected<bool> parseSpeculativeExecutionPassOptions(StringRef Params) {
1471 return PassBuilder::parseSinglePassOption(Params, "only-if-divergent-target",
1472 "SpeculativeExecutionPass");
1473}
1474
1475Expected<std::string> parseMemProfUsePassOptions(StringRef Params) {
1476 std::string Result;
1477 while (!Params.empty()) {
1478 StringRef ParamName;
1479 std::tie(ParamName, Params) = Params.split(';');
1480
1481 if (ParamName.consume_front("profile-filename=")) {
1482 Result = ParamName.str();
1483 } else {
1485 formatv("invalid MemProfUse pass parameter '{}'", ParamName).str(),
1487 }
1488 }
1489 return Result;
1490}
1491
1493parseStructuralHashPrinterPassOptions(StringRef Params) {
1494 if (Params.empty())
1496 if (Params == "detailed")
1498 if (Params == "call-target-ignored")
1501 formatv("invalid structural hash printer parameter '{}'", Params).str(),
1503}
1504
1505Expected<bool> parseWinEHPrepareOptions(StringRef Params) {
1506 return PassBuilder::parseSinglePassOption(Params, "demote-catchswitch-only",
1507 "WinEHPreparePass");
1508}
1509
1510Expected<GlobalMergeOptions> parseGlobalMergeOptions(StringRef Params) {
1512 while (!Params.empty()) {
1513 StringRef ParamName;
1514 std::tie(ParamName, Params) = Params.split(';');
1515
1516 bool Enable = !ParamName.consume_front("no-");
1517 if (ParamName == "group-by-use")
1518 Result.GroupByUse = Enable;
1519 else if (ParamName == "ignore-single-use")
1520 Result.IgnoreSingleUse = Enable;
1521 else if (ParamName == "merge-const")
1522 Result.MergeConstantGlobals = Enable;
1523 else if (ParamName == "merge-const-aggressive")
1524 Result.MergeConstAggressive = Enable;
1525 else if (ParamName == "merge-external")
1526 Result.MergeExternal = Enable;
1527 else if (ParamName.consume_front("max-offset=")) {
1528 if (ParamName.getAsInteger(0, Result.MaxOffset))
1530 formatv("invalid GlobalMergePass parameter '{}'", ParamName).str(),
1532 } else {
1534 formatv("invalid global-merge pass parameter '{}'", Params).str(),
1536 }
1537 }
1538 return Result;
1539}
1540
1541Expected<SmallVector<std::string, 0>> parseInternalizeGVs(StringRef Params) {
1542 SmallVector<std::string, 1> PreservedGVs;
1543 while (!Params.empty()) {
1544 StringRef ParamName;
1545 std::tie(ParamName, Params) = Params.split(';');
1546
1547 if (ParamName.consume_front("preserve-gv=")) {
1548 PreservedGVs.push_back(ParamName.str());
1549 } else {
1551 formatv("invalid Internalize pass parameter '{}'", ParamName).str(),
1553 }
1554 }
1555
1556 return Expected<SmallVector<std::string, 0>>(std::move(PreservedGVs));
1557}
1558
1560parseRegAllocFastPassOptions(PassBuilder &PB, StringRef Params) {
1562 while (!Params.empty()) {
1563 StringRef ParamName;
1564 std::tie(ParamName, Params) = Params.split(';');
1565
1566 if (ParamName.consume_front("filter=")) {
1567 std::optional<RegAllocFilterFunc> Filter =
1568 PB.parseRegAllocFilter(ParamName);
1569 if (!Filter) {
1571 formatv("invalid regallocfast register filter '{}'", ParamName)
1572 .str(),
1574 }
1575 Opts.Filter = *Filter;
1576 Opts.FilterName = ParamName;
1577 continue;
1578 }
1579
1580 if (ParamName == "no-clear-vregs") {
1581 Opts.ClearVRegs = false;
1582 continue;
1583 }
1584
1586 formatv("invalid regallocfast pass parameter '{}'", ParamName).str(),
1588 }
1589 return Opts;
1590}
1591
1593parseBoundsCheckingOptions(StringRef Params) {
1595 while (!Params.empty()) {
1596 StringRef ParamName;
1597 std::tie(ParamName, Params) = Params.split(';');
1598 if (ParamName == "trap") {
1599 Options.Rt = std::nullopt;
1600 } else if (ParamName == "rt") {
1601 Options.Rt = {
1602 /*MinRuntime=*/false,
1603 /*MayReturn=*/true,
1604 /*HandlerPreserveAllRegs=*/false,
1605 };
1606 } else if (ParamName == "rt-abort") {
1607 Options.Rt = {
1608 /*MinRuntime=*/false,
1609 /*MayReturn=*/false,
1610 /*HandlerPreserveAllRegs=*/false,
1611 };
1612 } else if (ParamName == "min-rt") {
1613 Options.Rt = {
1614 /*MinRuntime=*/true,
1615 /*MayReturn=*/true,
1616 /*HandlerPreserveAllRegs=*/false,
1617 };
1618 } else if (ParamName == "min-rt-abort") {
1619 Options.Rt = {
1620 /*MinRuntime=*/true,
1621 /*MayReturn=*/false,
1622 /*HandlerPreserveAllRegs=*/false,
1623 };
1624 } else if (ParamName == "merge") {
1625 Options.Merge = true;
1626 } else if (ParamName == "handler-preserve-all-regs") {
1627 if (Options.Rt)
1628 Options.Rt->HandlerPreserveAllRegs = true;
1629 } else {
1630 StringRef ParamEQ;
1631 StringRef Val;
1632 std::tie(ParamEQ, Val) = ParamName.split('=');
1633 int8_t Id;
1634 if (ParamEQ == "guard" && !Val.getAsInteger(0, Id)) {
1635 Options.GuardKind = Id;
1636 } else {
1638 formatv("invalid BoundsChecking pass parameter '{}'", ParamName)
1639 .str(),
1641 }
1642 }
1643 }
1644 return Options;
1645}
1646
1647Expected<CodeGenOptLevel> parseExpandIRInstsOptions(StringRef Param) {
1648 if (Param.empty())
1649 return CodeGenOptLevel::None;
1650
1651 // Parse a CodeGenOptLevel, e.g. "O1", "O2", "O3".
1652 auto [Prefix, Digit] = Param.split('O');
1653
1654 uint8_t N;
1655 if (!Prefix.empty() || Digit.getAsInteger(10, N))
1656 return createStringError("invalid expand-ir-insts pass parameter '%s'",
1657 Param.str().c_str());
1658
1659 std::optional<CodeGenOptLevel> Level = CodeGenOpt::getLevel(N);
1660 if (!Level.has_value())
1661 return createStringError(
1662 "invalid optimization level for expand-ir-insts pass: %s",
1663 Digit.str().c_str());
1664
1665 return *Level;
1666}
1667
1669parseRegAllocGreedyFilterFunc(PassBuilder &PB, StringRef Params) {
1670 if (Params.empty() || Params == "all")
1671 return RAGreedyPass::Options();
1672
1673 std::optional<RegAllocFilterFunc> Filter = PB.parseRegAllocFilter(Params);
1674 if (Filter)
1675 return RAGreedyPass::Options{*Filter, Params};
1676
1678 formatv("invalid regallocgreedy register filter '{}'", Params).str(),
1680}
1681
1682Expected<bool> parseMachineSinkingPassOptions(StringRef Params) {
1683 return PassBuilder::parseSinglePassOption(Params, "enable-sink-fold",
1684 "MachineSinkingPass");
1685}
1686
1687Expected<bool> parseMachineBlockPlacementPassOptions(StringRef Params) {
1688 bool AllowTailMerge = true;
1689 if (!Params.empty()) {
1690 AllowTailMerge = !Params.consume_front("no-");
1691 if (Params != "tail-merge")
1693 formatv("invalid MachineBlockPlacementPass parameter '{}'", Params)
1694 .str(),
1696 }
1697 return AllowTailMerge;
1698}
1699
1700Expected<bool> parseVirtRegRewriterPassOptions(StringRef Params) {
1701 bool ClearVirtRegs = true;
1702 if (!Params.empty()) {
1703 ClearVirtRegs = !Params.consume_front("no-");
1704 if (Params != "clear-vregs")
1706 formatv("invalid VirtRegRewriter pass parameter '{}'", Params).str(),
1708 }
1709 return ClearVirtRegs;
1710}
1711
1712struct FatLTOOptions {
1713 OptimizationLevel OptLevel;
1714 bool ThinLTO = false;
1715 bool EmitSummary = false;
1716};
1717
1718Expected<FatLTOOptions> parseFatLTOOptions(StringRef Params) {
1719 FatLTOOptions Result;
1720 bool HaveOptLevel = false;
1721 while (!Params.empty()) {
1722 StringRef ParamName;
1723 std::tie(ParamName, Params) = Params.split(';');
1724
1725 if (ParamName == "thinlto") {
1726 Result.ThinLTO = true;
1727 } else if (ParamName == "emit-summary") {
1728 Result.EmitSummary = true;
1729 } else if (std::optional<OptimizationLevel> OptLevel =
1730 parseOptLevel(ParamName)) {
1731 Result.OptLevel = *OptLevel;
1732 HaveOptLevel = true;
1733 } else {
1735 formatv("invalid fatlto-pre-link pass parameter '{}'", ParamName)
1736 .str(),
1738 }
1739 }
1740 if (!HaveOptLevel)
1742 "missing optimization level for fatlto-pre-link pipeline",
1744 return Result;
1745}
1746
1747} // namespace
1748
1749/// Tests whether registered callbacks will accept a given pass name.
1750///
1751/// When parsing a pipeline text, the type of the outermost pipeline may be
1752/// omitted, in which case the type is automatically determined from the first
1753/// pass name in the text. This may be a name that is handled through one of the
1754/// callbacks. We check this through the oridinary parsing callbacks by setting
1755/// up a dummy PassManager in order to not force the client to also handle this
1756/// type of query.
1757template <typename PassManagerT, typename CallbacksT>
1758static bool callbacksAcceptPassName(StringRef Name, CallbacksT &Callbacks) {
1759 if (!Callbacks.empty()) {
1760 PassManagerT DummyPM;
1761 for (auto &CB : Callbacks)
1762 if (CB(Name, DummyPM, {}))
1763 return true;
1764 }
1765 return false;
1766}
1767
1768template <typename CallbacksT>
1769static bool isModulePassName(StringRef Name, CallbacksT &Callbacks) {
1770 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1771
1772 // Explicitly handle pass manager names.
1773 if (Name == "module")
1774 return true;
1775 if (Name == "cgscc")
1776 return true;
1777 if (NameNoBracket == "function")
1778 return true;
1779 if (Name == "coro-cond")
1780 return true;
1781
1782#define MODULE_PASS(NAME, CREATE_PASS) \
1783 if (Name == NAME) \
1784 return true;
1785#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1786 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1787 return true;
1788#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
1789 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1790 return true;
1791#include "PassRegistry.def"
1792
1793 return callbacksAcceptPassName<ModulePassManager>(Name, Callbacks);
1794}
1795
1796template <typename CallbacksT>
1797static bool isCGSCCPassName(StringRef Name, CallbacksT &Callbacks) {
1798 // Explicitly handle pass manager names.
1799 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1800 if (Name == "cgscc")
1801 return true;
1802 if (NameNoBracket == "function")
1803 return true;
1804
1805 // Explicitly handle custom-parsed pass names.
1806 if (parseDevirtPassName(Name))
1807 return true;
1808
1809#define CGSCC_PASS(NAME, CREATE_PASS) \
1810 if (Name == NAME) \
1811 return true;
1812#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1813 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1814 return true;
1815#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
1816 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1817 return true;
1818#include "PassRegistry.def"
1819
1820 return callbacksAcceptPassName<CGSCCPassManager>(Name, Callbacks);
1821}
1822
1823template <typename CallbacksT>
1824static bool isFunctionPassName(StringRef Name, CallbacksT &Callbacks) {
1825 // Explicitly handle pass manager names.
1826 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1827 if (NameNoBracket == "function")
1828 return true;
1829 if (Name == "loop" || Name == "loop-mssa" || Name == "machine-function")
1830 return true;
1831
1832#define FUNCTION_PASS(NAME, CREATE_PASS) \
1833 if (Name == NAME) \
1834 return true;
1835#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1836 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1837 return true;
1838#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1839 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1840 return true;
1841#include "PassRegistry.def"
1842
1843 return callbacksAcceptPassName<FunctionPassManager>(Name, Callbacks);
1844}
1845
1846template <typename CallbacksT>
1847static bool isMachineFunctionPassName(StringRef Name, CallbacksT &Callbacks) {
1848 // Explicitly handle pass manager names.
1849 if (Name == "machine-function")
1850 return true;
1851
1852#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
1853 if (Name == NAME) \
1854 return true;
1855#define MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, \
1856 PARAMS) \
1857 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1858 return true;
1859
1860#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1861 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1862 return true;
1863
1864#include "llvm/Passes/MachinePassRegistry.def"
1865
1867}
1868
1869template <typename CallbacksT>
1870static bool isLoopNestPassName(StringRef Name, CallbacksT &Callbacks,
1871 bool &UseMemorySSA) {
1872 UseMemorySSA = false;
1873
1874 if (PassBuilder::checkParametrizedPassName(Name, "lnicm")) {
1875 UseMemorySSA = true;
1876 return true;
1877 }
1878
1879#define LOOPNEST_PASS(NAME, CREATE_PASS) \
1880 if (Name == NAME) \
1881 return true;
1882#include "PassRegistry.def"
1883
1884 return callbacksAcceptPassName<LoopPassManager>(Name, Callbacks);
1885}
1886
1887template <typename CallbacksT>
1888static bool isLoopPassName(StringRef Name, CallbacksT &Callbacks,
1889 bool &UseMemorySSA) {
1890 UseMemorySSA = false;
1891
1892 if (PassBuilder::checkParametrizedPassName(Name, "licm")) {
1893 UseMemorySSA = true;
1894 return true;
1895 }
1896
1897#define LOOP_PASS(NAME, CREATE_PASS) \
1898 if (Name == NAME) \
1899 return true;
1900#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1901 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1902 return true;
1903#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
1904 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1905 return true;
1906#include "PassRegistry.def"
1907
1908 return callbacksAcceptPassName<LoopPassManager>(Name, Callbacks);
1909}
1910
1911std::optional<std::vector<PassBuilder::PipelineElement>>
1912PassBuilder::parsePipelineText(StringRef Text) {
1913 std::vector<PipelineElement> ResultPipeline;
1914
1915 SmallVector<std::vector<PipelineElement> *, 4> PipelineStack = {
1916 &ResultPipeline};
1917 for (;;) {
1918 std::vector<PipelineElement> &Pipeline = *PipelineStack.back();
1919 size_t Pos = Text.find_first_of(",()");
1920 Pipeline.push_back({Text.substr(0, Pos), {}});
1921
1922 // If we have a single terminating name, we're done.
1923 if (Pos == Text.npos)
1924 break;
1925
1926 char Sep = Text[Pos];
1927 Text = Text.substr(Pos + 1);
1928 if (Sep == ',')
1929 // Just a name ending in a comma, continue.
1930 continue;
1931
1932 if (Sep == '(') {
1933 // Push the inner pipeline onto the stack to continue processing.
1934 PipelineStack.push_back(&Pipeline.back().InnerPipeline);
1935 continue;
1936 }
1937
1938 assert(Sep == ')' && "Bogus separator!");
1939 // When handling the close parenthesis, we greedily consume them to avoid
1940 // empty strings in the pipeline.
1941 do {
1942 // If we try to pop the outer pipeline we have unbalanced parentheses.
1943 if (PipelineStack.size() == 1)
1944 return std::nullopt;
1945
1946 PipelineStack.pop_back();
1947 } while (Text.consume_front(")"));
1948
1949 // Check if we've finished parsing.
1950 if (Text.empty())
1951 break;
1952
1953 // Otherwise, the end of an inner pipeline always has to be followed by
1954 // a comma, and then we can continue.
1955 if (!Text.consume_front(","))
1956 return std::nullopt;
1957 }
1958
1959 if (PipelineStack.size() > 1)
1960 // Unbalanced paretheses.
1961 return std::nullopt;
1962
1963 assert(PipelineStack.back() == &ResultPipeline &&
1964 "Wrong pipeline at the bottom of the stack!");
1965 return {std::move(ResultPipeline)};
1966}
1967
1970 // This is consistent with old pass manager invoked via opt, but
1971 // inconsistent with clang. Clang doesn't enable loop vectorization
1972 // but does enable slp vectorization at Oz.
1973 PTO.LoopVectorization = L.getSpeedupLevel() > 1 && L != OptimizationLevel::Oz;
1974 PTO.SLPVectorization = L.getSpeedupLevel() > 1 && L != OptimizationLevel::Oz;
1975}
1976
1977Error PassBuilder::parseModulePass(ModulePassManager &MPM,
1978 const PipelineElement &E) {
1979 auto &Name = E.Name;
1980 auto &InnerPipeline = E.InnerPipeline;
1981
1982 // First handle complex passes like the pass managers which carry pipelines.
1983 if (!InnerPipeline.empty()) {
1984 if (Name == "module") {
1985 ModulePassManager NestedMPM;
1986 if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline))
1987 return Err;
1988 MPM.addPass(std::move(NestedMPM));
1989 return Error::success();
1990 }
1991 if (Name == "coro-cond") {
1992 ModulePassManager NestedMPM;
1993 if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline))
1994 return Err;
1995 MPM.addPass(CoroConditionalWrapper(std::move(NestedMPM)));
1996 return Error::success();
1997 }
1998 if (Name == "cgscc") {
1999 CGSCCPassManager CGPM;
2000 if (auto Err = parseCGSCCPassPipeline(CGPM, InnerPipeline))
2001 return Err;
2003 return Error::success();
2004 }
2005 if (auto Params = parseFunctionPipelineName(Name)) {
2006 if (Params->second)
2008 "cannot have a no-rerun module to function adaptor",
2011 if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline))
2012 return Err;
2013 MPM.addPass(
2014 createModuleToFunctionPassAdaptor(std::move(FPM), Params->first));
2015 return Error::success();
2016 }
2017
2018 for (auto &C : ModulePipelineParsingCallbacks)
2019 if (C(Name, MPM, InnerPipeline))
2020 return Error::success();
2021
2022 // Normal passes can't have pipelines.
2024 formatv("invalid use of '{}' pass as module pipeline", Name).str(),
2026 ;
2027 }
2028
2029 // Finally expand the basic registered passes from the .inc file.
2030#define MODULE_PASS(NAME, CREATE_PASS) \
2031 if (Name == NAME) { \
2032 MPM.addPass(CREATE_PASS); \
2033 return Error::success(); \
2034 }
2035#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2036 if (checkParametrizedPassName(Name, NAME)) { \
2037 auto Params = parsePassParameters(PARSER, Name, NAME); \
2038 if (!Params) \
2039 return Params.takeError(); \
2040 MPM.addPass(CREATE_PASS(Params.get())); \
2041 return Error::success(); \
2042 }
2043#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
2044 if (Name == "require<" NAME ">") { \
2045 MPM.addPass( \
2046 RequireAnalysisPass< \
2047 std::remove_reference_t<decltype(CREATE_PASS)>, Module>()); \
2048 return Error::success(); \
2049 } \
2050 if (Name == "invalidate<" NAME ">") { \
2051 MPM.addPass(InvalidateAnalysisPass< \
2052 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2053 return Error::success(); \
2054 }
2055#define CGSCC_PASS(NAME, CREATE_PASS) \
2056 if (Name == NAME) { \
2057 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(CREATE_PASS)); \
2058 return Error::success(); \
2059 }
2060#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2061 if (checkParametrizedPassName(Name, NAME)) { \
2062 auto Params = parsePassParameters(PARSER, Name, NAME); \
2063 if (!Params) \
2064 return Params.takeError(); \
2065 MPM.addPass( \
2066 createModuleToPostOrderCGSCCPassAdaptor(CREATE_PASS(Params.get()))); \
2067 return Error::success(); \
2068 }
2069#define FUNCTION_PASS(NAME, CREATE_PASS) \
2070 if (Name == NAME) { \
2071 if constexpr (std::is_constructible_v< \
2072 std::remove_reference_t<decltype(CREATE_PASS)>, \
2073 const TargetMachine &>) { \
2074 if (!TM) \
2075 return make_error<StringError>( \
2076 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2077 inconvertibleErrorCode()); \
2078 } \
2079 MPM.addPass(createModuleToFunctionPassAdaptor(CREATE_PASS)); \
2080 return Error::success(); \
2081 }
2082#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2083 if (checkParametrizedPassName(Name, NAME)) { \
2084 auto Params = parsePassParameters(PARSER, Name, NAME); \
2085 if (!Params) \
2086 return Params.takeError(); \
2087 auto CreatePass = CREATE_PASS; \
2088 if constexpr (std::is_constructible_v< \
2089 std::remove_reference_t<decltype(CreatePass( \
2090 Params.get()))>, \
2091 const TargetMachine &, \
2092 std::remove_reference_t<decltype(Params.get())>>) { \
2093 if (!TM) { \
2094 return make_error<StringError>( \
2095 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2096 inconvertibleErrorCode()); \
2097 } \
2098 } \
2099 MPM.addPass(createModuleToFunctionPassAdaptor(CREATE_PASS(Params.get()))); \
2100 return Error::success(); \
2101 }
2102#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2103 if (Name == NAME) { \
2104 MPM.addPass(createModuleToFunctionPassAdaptor( \
2105 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2106 return Error::success(); \
2107 }
2108#define LOOP_PASS(NAME, CREATE_PASS) \
2109 if (Name == NAME) { \
2110 MPM.addPass(createModuleToFunctionPassAdaptor( \
2111 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2112 return Error::success(); \
2113 }
2114#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2115 if (checkParametrizedPassName(Name, NAME)) { \
2116 auto Params = parsePassParameters(PARSER, Name, NAME); \
2117 if (!Params) \
2118 return Params.takeError(); \
2119 MPM.addPass(createModuleToFunctionPassAdaptor( \
2120 createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), false))); \
2121 return Error::success(); \
2122 }
2123#include "PassRegistry.def"
2124
2125 for (auto &C : ModulePipelineParsingCallbacks)
2126 if (C(Name, MPM, InnerPipeline))
2127 return Error::success();
2129 formatv("unknown module pass '{}'", Name).str(),
2131}
2132
2133Error PassBuilder::parseCGSCCPass(CGSCCPassManager &CGPM,
2134 const PipelineElement &E) {
2135 auto &Name = E.Name;
2136 auto &InnerPipeline = E.InnerPipeline;
2137
2138 // First handle complex passes like the pass managers which carry pipelines.
2139 if (!InnerPipeline.empty()) {
2140 if (Name == "cgscc") {
2141 CGSCCPassManager NestedCGPM;
2142 if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline))
2143 return Err;
2144 // Add the nested pass manager with the appropriate adaptor.
2145 CGPM.addPass(std::move(NestedCGPM));
2146 return Error::success();
2147 }
2148 if (auto Params = parseFunctionPipelineName(Name)) {
2150 if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline))
2151 return Err;
2152 // Add the nested pass manager with the appropriate adaptor.
2154 std::move(FPM), Params->first, Params->second));
2155 return Error::success();
2156 }
2157 if (auto MaxRepetitions = parseDevirtPassName(Name)) {
2158 CGSCCPassManager NestedCGPM;
2159 if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline))
2160 return Err;
2161 CGPM.addPass(
2162 createDevirtSCCRepeatedPass(std::move(NestedCGPM), *MaxRepetitions));
2163 return Error::success();
2164 }
2165
2166 for (auto &C : CGSCCPipelineParsingCallbacks)
2167 if (C(Name, CGPM, InnerPipeline))
2168 return Error::success();
2169
2170 // Normal passes can't have pipelines.
2172 formatv("invalid use of '{}' pass as cgscc pipeline", Name).str(),
2174 }
2175
2176// Now expand the basic registered passes from the .inc file.
2177#define CGSCC_PASS(NAME, CREATE_PASS) \
2178 if (Name == NAME) { \
2179 CGPM.addPass(CREATE_PASS); \
2180 return Error::success(); \
2181 }
2182#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2183 if (checkParametrizedPassName(Name, NAME)) { \
2184 auto Params = parsePassParameters(PARSER, Name, NAME); \
2185 if (!Params) \
2186 return Params.takeError(); \
2187 CGPM.addPass(CREATE_PASS(Params.get())); \
2188 return Error::success(); \
2189 }
2190#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
2191 if (Name == "require<" NAME ">") { \
2192 CGPM.addPass(RequireAnalysisPass< \
2193 std::remove_reference_t<decltype(CREATE_PASS)>, \
2194 LazyCallGraph::SCC, CGSCCAnalysisManager, LazyCallGraph &, \
2195 CGSCCUpdateResult &>()); \
2196 return Error::success(); \
2197 } \
2198 if (Name == "invalidate<" NAME ">") { \
2199 CGPM.addPass(InvalidateAnalysisPass< \
2200 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2201 return Error::success(); \
2202 }
2203#define FUNCTION_PASS(NAME, CREATE_PASS) \
2204 if (Name == NAME) { \
2205 if constexpr (std::is_constructible_v< \
2206 std::remove_reference_t<decltype(CREATE_PASS)>, \
2207 const TargetMachine &>) { \
2208 if (!TM) \
2209 return make_error<StringError>( \
2210 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2211 inconvertibleErrorCode()); \
2212 } \
2213 CGPM.addPass(createCGSCCToFunctionPassAdaptor(CREATE_PASS)); \
2214 return Error::success(); \
2215 }
2216#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2217 if (checkParametrizedPassName(Name, NAME)) { \
2218 auto Params = parsePassParameters(PARSER, Name, NAME); \
2219 if (!Params) \
2220 return Params.takeError(); \
2221 auto CreatePass = CREATE_PASS; \
2222 if constexpr (std::is_constructible_v< \
2223 std::remove_reference_t<decltype(CreatePass( \
2224 Params.get()))>, \
2225 const TargetMachine &, \
2226 std::remove_reference_t<decltype(Params.get())>>) { \
2227 if (!TM) { \
2228 return make_error<StringError>( \
2229 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2230 inconvertibleErrorCode()); \
2231 } \
2232 } \
2233 CGPM.addPass(createCGSCCToFunctionPassAdaptor(CREATE_PASS(Params.get()))); \
2234 return Error::success(); \
2235 }
2236#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2237 if (Name == NAME) { \
2238 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
2239 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2240 return Error::success(); \
2241 }
2242#define LOOP_PASS(NAME, CREATE_PASS) \
2243 if (Name == NAME) { \
2244 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
2245 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2246 return Error::success(); \
2247 }
2248#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2249 if (checkParametrizedPassName(Name, NAME)) { \
2250 auto Params = parsePassParameters(PARSER, Name, NAME); \
2251 if (!Params) \
2252 return Params.takeError(); \
2253 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
2254 createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), false))); \
2255 return Error::success(); \
2256 }
2257#include "PassRegistry.def"
2258
2259 for (auto &C : CGSCCPipelineParsingCallbacks)
2260 if (C(Name, CGPM, InnerPipeline))
2261 return Error::success();
2262 return make_error<StringError>(formatv("unknown cgscc pass '{}'", Name).str(),
2264}
2265
2266Error PassBuilder::parseFunctionPass(FunctionPassManager &FPM,
2267 const PipelineElement &E) {
2268 auto &Name = E.Name;
2269 auto &InnerPipeline = E.InnerPipeline;
2270
2271 // First handle complex passes like the pass managers which carry pipelines.
2272 if (!InnerPipeline.empty()) {
2273 if (Name == "function") {
2274 FunctionPassManager NestedFPM;
2275 if (auto Err = parseFunctionPassPipeline(NestedFPM, InnerPipeline))
2276 return Err;
2277 // Add the nested pass manager with the appropriate adaptor.
2278 FPM.addPass(std::move(NestedFPM));
2279 return Error::success();
2280 }
2281 if (Name == "loop" || Name == "loop-mssa") {
2282 LoopPassManager LPM;
2283 if (auto Err = parseLoopPassPipeline(LPM, InnerPipeline))
2284 return Err;
2285 // Add the nested pass manager with the appropriate adaptor.
2286 bool UseMemorySSA = (Name == "loop-mssa");
2287 FPM.addPass(
2288 createFunctionToLoopPassAdaptor(std::move(LPM), UseMemorySSA));
2289 return Error::success();
2290 }
2291 if (Name == "machine-function") {
2293 if (auto Err = parseMachinePassPipeline(MFPM, InnerPipeline))
2294 return Err;
2296 return Error::success();
2297 }
2298
2299 for (auto &C : FunctionPipelineParsingCallbacks)
2300 if (C(Name, FPM, InnerPipeline))
2301 return Error::success();
2302
2303 // Normal passes can't have pipelines.
2305 formatv("invalid use of '{}' pass as function pipeline", Name).str(),
2307 }
2308
2309// Now expand the basic registered passes from the .inc file.
2310#define FUNCTION_PASS(NAME, CREATE_PASS) \
2311 if (Name == NAME) { \
2312 if constexpr (std::is_constructible_v< \
2313 std::remove_reference_t<decltype(CREATE_PASS)>, \
2314 const TargetMachine &>) { \
2315 if (!TM) \
2316 return make_error<StringError>( \
2317 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2318 inconvertibleErrorCode()); \
2319 } \
2320 FPM.addPass(CREATE_PASS); \
2321 return Error::success(); \
2322 }
2323#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2324 if (checkParametrizedPassName(Name, NAME)) { \
2325 auto Params = parsePassParameters(PARSER, Name, NAME); \
2326 if (!Params) \
2327 return Params.takeError(); \
2328 auto CreatePass = CREATE_PASS; \
2329 if constexpr (std::is_constructible_v< \
2330 std::remove_reference_t<decltype(CreatePass( \
2331 Params.get()))>, \
2332 const TargetMachine &, \
2333 std::remove_reference_t<decltype(Params.get())>>) { \
2334 if (!TM) { \
2335 return make_error<StringError>( \
2336 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2337 inconvertibleErrorCode()); \
2338 } \
2339 } \
2340 FPM.addPass(CREATE_PASS(Params.get())); \
2341 return Error::success(); \
2342 }
2343#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
2344 if (Name == "require<" NAME ">") { \
2345 if constexpr (std::is_constructible_v< \
2346 std::remove_reference_t<decltype(CREATE_PASS)>, \
2347 const TargetMachine &>) { \
2348 if (!TM) \
2349 return make_error<StringError>( \
2350 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2351 inconvertibleErrorCode()); \
2352 } \
2353 FPM.addPass( \
2354 RequireAnalysisPass<std::remove_reference_t<decltype(CREATE_PASS)>, \
2355 Function>()); \
2356 return Error::success(); \
2357 } \
2358 if (Name == "invalidate<" NAME ">") { \
2359 FPM.addPass(InvalidateAnalysisPass< \
2360 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2361 return Error::success(); \
2362 }
2363// FIXME: UseMemorySSA is set to false. Maybe we could do things like:
2364// bool UseMemorySSA = !("canon-freeze" || "loop-predication" ||
2365// "guard-widening");
2366// The risk is that it may become obsolete if we're not careful.
2367#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2368 if (Name == NAME) { \
2369 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS, false)); \
2370 return Error::success(); \
2371 }
2372#define LOOP_PASS(NAME, CREATE_PASS) \
2373 if (Name == NAME) { \
2374 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS, false)); \
2375 return Error::success(); \
2376 }
2377#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2378 if (checkParametrizedPassName(Name, NAME)) { \
2379 auto Params = parsePassParameters(PARSER, Name, NAME); \
2380 if (!Params) \
2381 return Params.takeError(); \
2382 FPM.addPass( \
2383 createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), false)); \
2384 return Error::success(); \
2385 }
2386#include "PassRegistry.def"
2387
2388 for (auto &C : FunctionPipelineParsingCallbacks)
2389 if (C(Name, FPM, InnerPipeline))
2390 return Error::success();
2392 formatv("unknown function pass '{}'", Name).str(),
2394}
2395
2396Error PassBuilder::parseLoopPass(LoopPassManager &LPM,
2397 const PipelineElement &E) {
2398 StringRef Name = E.Name;
2399 auto &InnerPipeline = E.InnerPipeline;
2400
2401 // First handle complex passes like the pass managers which carry pipelines.
2402 if (!InnerPipeline.empty()) {
2403 if (Name == "loop") {
2404 LoopPassManager NestedLPM;
2405 if (auto Err = parseLoopPassPipeline(NestedLPM, InnerPipeline))
2406 return Err;
2407 // Add the nested pass manager with the appropriate adaptor.
2408 LPM.addPass(std::move(NestedLPM));
2409 return Error::success();
2410 }
2411
2412 for (auto &C : LoopPipelineParsingCallbacks)
2413 if (C(Name, LPM, InnerPipeline))
2414 return Error::success();
2415
2416 // Normal passes can't have pipelines.
2418 formatv("invalid use of '{}' pass as loop pipeline", Name).str(),
2420 }
2421
2422// Now expand the basic registered passes from the .inc file.
2423#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2424 if (Name == NAME) { \
2425 LPM.addPass(CREATE_PASS); \
2426 return Error::success(); \
2427 }
2428#define LOOP_PASS(NAME, CREATE_PASS) \
2429 if (Name == NAME) { \
2430 LPM.addPass(CREATE_PASS); \
2431 return Error::success(); \
2432 }
2433#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2434 if (checkParametrizedPassName(Name, NAME)) { \
2435 auto Params = parsePassParameters(PARSER, Name, NAME); \
2436 if (!Params) \
2437 return Params.takeError(); \
2438 LPM.addPass(CREATE_PASS(Params.get())); \
2439 return Error::success(); \
2440 }
2441#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
2442 if (Name == "require<" NAME ">") { \
2443 LPM.addPass(RequireAnalysisPass< \
2444 std::remove_reference_t<decltype(CREATE_PASS)>, Loop, \
2445 LoopAnalysisManager, LoopStandardAnalysisResults &, \
2446 LPMUpdater &>()); \
2447 return Error::success(); \
2448 } \
2449 if (Name == "invalidate<" NAME ">") { \
2450 LPM.addPass(InvalidateAnalysisPass< \
2451 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2452 return Error::success(); \
2453 }
2454#include "PassRegistry.def"
2455
2456 for (auto &C : LoopPipelineParsingCallbacks)
2457 if (C(Name, LPM, InnerPipeline))
2458 return Error::success();
2459 return make_error<StringError>(formatv("unknown loop pass '{}'", Name).str(),
2461}
2462
2463Error PassBuilder::parseMachinePass(MachineFunctionPassManager &MFPM,
2464 const PipelineElement &E) {
2465 StringRef Name = E.Name;
2466 // Handle any nested pass managers.
2467 if (!E.InnerPipeline.empty()) {
2468 if (E.Name == "machine-function") {
2470 if (auto Err = parseMachinePassPipeline(NestedPM, E.InnerPipeline))
2471 return Err;
2472 MFPM.addPass(std::move(NestedPM));
2473 return Error::success();
2474 }
2475 return make_error<StringError>("invalid pipeline",
2477 }
2478
2479#define MACHINE_MODULE_PASS(NAME, CREATE_PASS) \
2480 if (Name == NAME) { \
2481 MFPM.addPass(CREATE_PASS); \
2482 return Error::success(); \
2483 }
2484#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
2485 if (Name == NAME) { \
2486 MFPM.addPass(CREATE_PASS); \
2487 return Error::success(); \
2488 }
2489#define MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, \
2490 PARAMS) \
2491 if (checkParametrizedPassName(Name, NAME)) { \
2492 auto Params = parsePassParameters(PARSER, Name, NAME); \
2493 if (!Params) \
2494 return Params.takeError(); \
2495 MFPM.addPass(CREATE_PASS(Params.get())); \
2496 return Error::success(); \
2497 }
2498#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
2499 if (Name == "require<" NAME ">") { \
2500 MFPM.addPass( \
2501 RequireAnalysisPass<std::remove_reference_t<decltype(CREATE_PASS)>, \
2502 MachineFunction>()); \
2503 return Error::success(); \
2504 } \
2505 if (Name == "invalidate<" NAME ">") { \
2506 MFPM.addPass(InvalidateAnalysisPass< \
2507 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2508 return Error::success(); \
2509 }
2510#include "llvm/Passes/MachinePassRegistry.def"
2511
2512 for (auto &C : MachineFunctionPipelineParsingCallbacks)
2513 if (C(Name, MFPM, E.InnerPipeline))
2514 return Error::success();
2516 formatv("unknown machine pass '{}'", Name).str(),
2518}
2519
2520bool PassBuilder::parseAAPassName(AAManager &AA, StringRef Name) {
2521#define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
2522 if (Name == NAME) { \
2523 AA.registerModuleAnalysis< \
2524 std::remove_reference_t<decltype(CREATE_PASS)>>(); \
2525 return true; \
2526 }
2527#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
2528 if (Name == NAME) { \
2529 AA.registerFunctionAnalysis< \
2530 std::remove_reference_t<decltype(CREATE_PASS)>>(); \
2531 return true; \
2532 }
2533#include "PassRegistry.def"
2534
2535 for (auto &C : AAParsingCallbacks)
2536 if (C(Name, AA))
2537 return true;
2538 return false;
2539}
2540
2541Error PassBuilder::parseMachinePassPipeline(
2543 for (const auto &Element : Pipeline) {
2544 if (auto Err = parseMachinePass(MFPM, Element))
2545 return Err;
2546 }
2547 return Error::success();
2548}
2549
2550Error PassBuilder::parseLoopPassPipeline(LoopPassManager &LPM,
2551 ArrayRef<PipelineElement> Pipeline) {
2552 for (const auto &Element : Pipeline) {
2553 if (auto Err = parseLoopPass(LPM, Element))
2554 return Err;
2555 }
2556 return Error::success();
2557}
2558
2559Error PassBuilder::parseFunctionPassPipeline(
2561 for (const auto &Element : Pipeline) {
2562 if (auto Err = parseFunctionPass(FPM, Element))
2563 return Err;
2564 }
2565 return Error::success();
2566}
2567
2568Error PassBuilder::parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
2569 ArrayRef<PipelineElement> Pipeline) {
2570 for (const auto &Element : Pipeline) {
2571 if (auto Err = parseCGSCCPass(CGPM, Element))
2572 return Err;
2573 }
2574 return Error::success();
2575}
2576
2582 MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });
2583 MAM.registerPass([&] { return CGSCCAnalysisManagerModuleProxy(CGAM); });
2584 CGAM.registerPass([&] { return ModuleAnalysisManagerCGSCCProxy(MAM); });
2585 FAM.registerPass([&] { return CGSCCAnalysisManagerFunctionProxy(CGAM); });
2586 FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); });
2587 FAM.registerPass([&] { return LoopAnalysisManagerFunctionProxy(LAM); });
2588 LAM.registerPass([&] { return FunctionAnalysisManagerLoopProxy(FAM); });
2589 if (MFAM) {
2590 MAM.registerPass(
2591 [&] { return MachineFunctionAnalysisManagerModuleProxy(*MFAM); });
2592 FAM.registerPass(
2593 [&] { return MachineFunctionAnalysisManagerFunctionProxy(*MFAM); });
2594 MFAM->registerPass(
2596 MFAM->registerPass(
2598 }
2599}
2600
2601Error PassBuilder::parseModulePassPipeline(ModulePassManager &MPM,
2602 ArrayRef<PipelineElement> Pipeline) {
2603 for (const auto &Element : Pipeline) {
2604 if (auto Err = parseModulePass(MPM, Element))
2605 return Err;
2606 }
2607 return Error::success();
2608}
2609
2610// Primary pass pipeline description parsing routine for a \c ModulePassManager
2611// FIXME: Should this routine accept a TargetMachine or require the caller to
2612// pre-populate the analysis managers with target-specific stuff?
2614 StringRef PipelineText) {
2615 auto Pipeline = parsePipelineText(PipelineText);
2616 if (!Pipeline || Pipeline->empty())
2618 formatv("invalid pipeline '{}'", PipelineText).str(),
2620
2621 // If the first name isn't at the module layer, wrap the pipeline up
2622 // automatically.
2623 StringRef FirstName = Pipeline->front().Name;
2624
2625 if (!isModulePassName(FirstName, ModulePipelineParsingCallbacks)) {
2626 bool UseMemorySSA;
2627 if (isCGSCCPassName(FirstName, CGSCCPipelineParsingCallbacks)) {
2628 Pipeline = {{"cgscc", std::move(*Pipeline)}};
2629 } else if (isFunctionPassName(FirstName,
2630 FunctionPipelineParsingCallbacks)) {
2631 Pipeline = {{"function", std::move(*Pipeline)}};
2632 } else if (isLoopNestPassName(FirstName, LoopPipelineParsingCallbacks,
2633 UseMemorySSA)) {
2634 Pipeline = {{"function", {{UseMemorySSA ? "loop-mssa" : "loop",
2635 std::move(*Pipeline)}}}};
2636 } else if (isLoopPassName(FirstName, LoopPipelineParsingCallbacks,
2637 UseMemorySSA)) {
2638 Pipeline = {{"function", {{UseMemorySSA ? "loop-mssa" : "loop",
2639 std::move(*Pipeline)}}}};
2640 } else if (isMachineFunctionPassName(
2641 FirstName, MachineFunctionPipelineParsingCallbacks)) {
2642 Pipeline = {{"function", {{"machine-function", std::move(*Pipeline)}}}};
2643 } else {
2644 for (auto &C : TopLevelPipelineParsingCallbacks)
2645 if (C(MPM, *Pipeline))
2646 return Error::success();
2647
2648 // Unknown pass or pipeline name!
2649 auto &InnerPipeline = Pipeline->front().InnerPipeline;
2651 formatv("unknown {} name '{}'",
2652 (InnerPipeline.empty() ? "pass" : "pipeline"), FirstName)
2653 .str(),
2655 }
2656 }
2657
2658 if (auto Err = parseModulePassPipeline(MPM, *Pipeline))
2659 return Err;
2660 return Error::success();
2661}
2662
2663// Primary pass pipeline description parsing routine for a \c CGSCCPassManager
2665 StringRef PipelineText) {
2666 auto Pipeline = parsePipelineText(PipelineText);
2667 if (!Pipeline || Pipeline->empty())
2669 formatv("invalid pipeline '{}'", PipelineText).str(),
2671
2672 StringRef FirstName = Pipeline->front().Name;
2673 if (!isCGSCCPassName(FirstName, CGSCCPipelineParsingCallbacks))
2675 formatv("unknown cgscc pass '{}' in pipeline '{}'", FirstName,
2676 PipelineText)
2677 .str(),
2679
2680 if (auto Err = parseCGSCCPassPipeline(CGPM, *Pipeline))
2681 return Err;
2682 return Error::success();
2683}
2684
2685// Primary pass pipeline description parsing routine for a \c
2686// FunctionPassManager
2688 StringRef PipelineText) {
2689 auto Pipeline = parsePipelineText(PipelineText);
2690 if (!Pipeline || Pipeline->empty())
2692 formatv("invalid pipeline '{}'", PipelineText).str(),
2694
2695 StringRef FirstName = Pipeline->front().Name;
2696 if (!isFunctionPassName(FirstName, FunctionPipelineParsingCallbacks))
2698 formatv("unknown function pass '{}' in pipeline '{}'", FirstName,
2699 PipelineText)
2700 .str(),
2702
2703 if (auto Err = parseFunctionPassPipeline(FPM, *Pipeline))
2704 return Err;
2705 return Error::success();
2706}
2707
2708// Primary pass pipeline description parsing routine for a \c LoopPassManager
2710 StringRef PipelineText) {
2711 auto Pipeline = parsePipelineText(PipelineText);
2712 if (!Pipeline || Pipeline->empty())
2714 formatv("invalid pipeline '{}'", PipelineText).str(),
2716
2717 if (auto Err = parseLoopPassPipeline(CGPM, *Pipeline))
2718 return Err;
2719
2720 return Error::success();
2721}
2722
2724 StringRef PipelineText) {
2725 auto Pipeline = parsePipelineText(PipelineText);
2726 if (!Pipeline || Pipeline->empty())
2728 formatv("invalid machine pass pipeline '{}'", PipelineText).str(),
2730
2731 if (auto Err = parseMachinePassPipeline(MFPM, *Pipeline))
2732 return Err;
2733
2734 return Error::success();
2735}
2736
2738 // If the pipeline just consists of the word 'default' just replace the AA
2739 // manager with our default one.
2740 if (PipelineText == "default") {
2742 return Error::success();
2743 }
2744
2745 while (!PipelineText.empty()) {
2746 StringRef Name;
2747 std::tie(Name, PipelineText) = PipelineText.split(',');
2748 if (!parseAAPassName(AA, Name))
2750 formatv("unknown alias analysis name '{}'", Name).str(),
2752 }
2753
2754 return Error::success();
2755}
2756
2757std::optional<RegAllocFilterFunc>
2759 if (FilterName == "all")
2760 return nullptr;
2761 for (auto &C : RegClassFilterParsingCallbacks)
2762 if (auto F = C(FilterName))
2763 return F;
2764 return std::nullopt;
2765}
2766
2768 OS << " " << PassName << "\n";
2769}
2771 raw_ostream &OS) {
2772 OS << " " << PassName << "<" << Params << ">\n";
2773}
2774
2776 // TODO: print pass descriptions when they are available
2777
2778 OS << "Module passes:\n";
2779#define MODULE_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2780#include "PassRegistry.def"
2781
2782 OS << "Module passes with params:\n";
2783#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2784 printPassName(NAME, PARAMS, OS);
2785#include "PassRegistry.def"
2786
2787 OS << "Module analyses:\n";
2788#define MODULE_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2789#include "PassRegistry.def"
2790
2791 OS << "Module alias analyses:\n";
2792#define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2793#include "PassRegistry.def"
2794
2795 OS << "CGSCC passes:\n";
2796#define CGSCC_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2797#include "PassRegistry.def"
2798
2799 OS << "CGSCC passes with params:\n";
2800#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2801 printPassName(NAME, PARAMS, OS);
2802#include "PassRegistry.def"
2803
2804 OS << "CGSCC analyses:\n";
2805#define CGSCC_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2806#include "PassRegistry.def"
2807
2808 OS << "Function passes:\n";
2809#define FUNCTION_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2810#include "PassRegistry.def"
2811
2812 OS << "Function passes with params:\n";
2813#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2814 printPassName(NAME, PARAMS, OS);
2815#include "PassRegistry.def"
2816
2817 OS << "Function analyses:\n";
2818#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2819#include "PassRegistry.def"
2820
2821 OS << "Function alias analyses:\n";
2822#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2823#include "PassRegistry.def"
2824
2825 OS << "LoopNest passes:\n";
2826#define LOOPNEST_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2827#include "PassRegistry.def"
2828
2829 OS << "Loop passes:\n";
2830#define LOOP_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2831#include "PassRegistry.def"
2832
2833 OS << "Loop passes with params:\n";
2834#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2835 printPassName(NAME, PARAMS, OS);
2836#include "PassRegistry.def"
2837
2838 OS << "Loop analyses:\n";
2839#define LOOP_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2840#include "PassRegistry.def"
2841
2842 OS << "Machine module passes (WIP):\n";
2843#define MACHINE_MODULE_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2844#include "llvm/Passes/MachinePassRegistry.def"
2845
2846 OS << "Machine function passes (WIP):\n";
2847#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2848#include "llvm/Passes/MachinePassRegistry.def"
2849
2850 OS << "Machine function analyses (WIP):\n";
2851#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2852#include "llvm/Passes/MachinePassRegistry.def"
2853}
2854
2856 const std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>)>
2857 &C) {
2858 TopLevelPipelineParsingCallbacks.push_back(C);
2859}
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.
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 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
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 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 void printPassName(StringRef PassName, 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...
static const char * name
This file provides the interface for LLVM's Scalar Replacement of Aggregates pass.
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...
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[]
Value * RHS
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:1555
int64_t getSExtValue() const
Get sign extended value.
Definition APInt.h:1577
bool registerPass(PassBuilderT &&PassBuilder)
Register an analysis pass with the manager.
ArrayRef - 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 if the block is well formed or null if the block is not well forme...
Definition BasicBlock.h:233
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:613
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".
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 Oz
A very specialized mode that will optimize for code size at any and all costs.
static LLVM_ABI const OptimizationLevel O0
Disable as many optimizations as possible.
static LLVM_ABI const OptimizationLevel Os
Similar to O2 but tries to optimize for small code size instead of fast execution without triggering ...
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.
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
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
str - 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
empty - Check if the string is empty.
Definition StringRef.h:140
char front() const
front - Get the first character in the string.
Definition StringRef.h:146
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)
Primary interface to the complete machine description for the target machine.
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
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
This is an optimization pass for GlobalISel generic memory operations.
Definition Types.h:26
OuterAnalysisManagerProxy< CGSCCAnalysisManager, Function > CGSCCAnalysisManagerFunctionProxy
A proxy from a CGSCCAnalysisManager to a Function.
OuterAnalysisManagerProxy< ModuleAnalysisManager, MachineFunction > ModuleAnalysisManagerMachineFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
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:1305
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.
LLVM_ABI cl::opt< bool > PrintPipelinePasses
Common option used by multiple tools to print pipeline passes.
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
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 >
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1917
PassManager< MachineFunction > MachineFunctionPassManager
Convenience typedef for a pass manager over functions.
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...
@ 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
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:870
#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:78
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 to automatically provide informational APIs needed for passes.
Definition PassManager.h:70