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"
112#include "llvm/CodeGen/KCFI.h"
146#include "llvm/CodeGen/PEI.h"
189#include "llvm/IR/DebugInfo.h"
190#include "llvm/IR/Dominators.h"
191#include "llvm/IR/PassManager.h"
193#include "llvm/IR/Verifier.h"
196#include "llvm/Support/CodeGen.h"
198#include "llvm/Support/Debug.h"
199#include "llvm/Support/Error.h"
202#include "llvm/Support/Regex.h"
395#include <optional>
396
397using namespace llvm;
398
400 "print-pipeline-passes",
401 cl::desc("Print a '-passes' compatible string describing the pipeline "
402 "(best-effort only)."));
403
404AnalysisKey NoOpModuleAnalysis::Key;
405AnalysisKey NoOpCGSCCAnalysis::Key;
406AnalysisKey NoOpFunctionAnalysis::Key;
407AnalysisKey NoOpLoopAnalysis::Key;
408
409namespace {
410
411bool applyMIRDebugify(DIBuilder &DIB, Function &F, ModuleAnalysisManager &AM) {
414 .getManager();
415
417 DIB, F, [&](Function &Func) -> MachineFunction * {
419 FAM.getCachedResult<MachineFunctionAnalysis>(Func);
420 return MFA ? &MFA->getMF() : nullptr;
421 });
422}
423
424// Passes for testing crashes.
425// DO NOT USE THIS EXCEPT FOR TESTING!
426class TriggerCrashModulePass
427 : public OptionalPassInfoMixin<TriggerCrashModulePass> {
428public:
429 PreservedAnalyses run(Module &, ModuleAnalysisManager &) {
430 abort();
431 return PreservedAnalyses::all();
432 }
433 static StringRef name() { return "TriggerCrashModulePass"; }
434};
435
436class TriggerCrashFunctionPass
437 : public OptionalPassInfoMixin<TriggerCrashFunctionPass> {
438public:
439 PreservedAnalyses run(Function &, FunctionAnalysisManager &) {
440 abort();
441 return PreservedAnalyses::all();
442 }
443 static StringRef name() { return "TriggerCrashFunctionPass"; }
444};
445
446// A pass for testing message reporting of -verify-each failures.
447// DO NOT USE THIS EXCEPT FOR TESTING!
448class TriggerVerifierErrorPass
449 : public OptionalPassInfoMixin<TriggerVerifierErrorPass> {
450public:
451 PreservedAnalyses run(Module &M, ModuleAnalysisManager &) {
452 // Intentionally break the Module by creating an alias without setting the
453 // aliasee.
454 auto *PtrTy = PointerType::getUnqual(M.getContext());
455 GlobalAlias::create(PtrTy, PtrTy->getAddressSpace(),
456 GlobalValue::LinkageTypes::InternalLinkage,
457 "__bad_alias", nullptr, &M);
459 }
460
461 PreservedAnalyses run(Function &F, FunctionAnalysisManager &) {
462 // Intentionally break the Function by inserting a terminator
463 // instruction in the middle of a basic block.
464 BasicBlock &BB = F.getEntryBlock();
465 new UnreachableInst(F.getContext(), BB.getTerminator()->getIterator());
467 }
468
469 PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &) {
470 // Intentionally create a virtual register and set NoVRegs property.
471 auto &MRI = MF.getRegInfo();
473 MF.getProperties().setNoVRegs();
474 return PreservedAnalyses::all();
475 }
476
477 static StringRef name() { return "TriggerVerifierErrorPass"; }
478};
479
480// A pass requires all MachineFunctionProperties.
481// DO NOT USE THIS EXCEPT FOR TESTING!
482class RequireAllMachineFunctionPropertiesPass
483 : public OptionalPassInfoMixin<RequireAllMachineFunctionPropertiesPass> {
484public:
485 PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &) {
486 MFPropsModifier _(*this, MF);
488 }
489
490 static MachineFunctionProperties getRequiredProperties() {
491 return MachineFunctionProperties()
492 .setFailedISel()
493 .setFailsVerification()
494 .setIsSSA()
495 .setLegalized()
496 .setNoPHIs()
497 .setNoVRegs()
498 .setRegBankSelected()
499 .setSelected()
500 .setTiedOpsRewritten()
501 .setTracksDebugUserValues()
502 .setTracksLiveness();
503 }
504 static StringRef name() { return "RequireAllMachineFunctionPropertiesPass"; }
505};
506
507} // namespace
508
509static std::optional<OptimizationLevel> parseOptLevel(StringRef S) {
510 if (S == "Os" || S == "Oz")
512 Twine("The optimization level \"") + S +
513 "\" is no longer supported. Use O2 in conjunction with the " +
514 (S == "Os" ? "optsize" : "minsize") + " attribute instead.");
515
517 .Case("O0", OptimizationLevel::O0)
521 .Default(std::nullopt);
522}
523
525 std::optional<OptimizationLevel> OptLevel = parseOptLevel(S);
526 if (OptLevel)
527 return *OptLevel;
529 formatv("invalid optimization level '{}'", S).str(),
531}
532
534 std::optional<PGOOptions> PGOOpt,
537 : TM(TM), PTO(PTO), PGOOpt(PGOOpt), PIC(PIC), FS(std::move(FS)) {
538 if (TM)
539 TM->registerPassBuilderCallbacks(*this);
540 if (PIC) {
541 PIC->registerClassToPassNameCallback([this, PIC]() {
542 // MSVC requires this to be captured if it's used inside decltype.
543 // Other compilers consider it an unused lambda capture.
544 (void)this;
545#define MODULE_PASS(NAME, CREATE_PASS) \
546 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
547#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
548 PIC->addClassToPassName(CLASS, NAME);
549#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
550 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
551#define FUNCTION_PASS(NAME, CREATE_PASS) \
552 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
553#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
554 PIC->addClassToPassName(CLASS, NAME);
555#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
556 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
557#define LOOPNEST_PASS(NAME, CREATE_PASS) \
558 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
559#define LOOP_PASS(NAME, CREATE_PASS) \
560 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
561#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
562 PIC->addClassToPassName(CLASS, NAME);
563#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
564 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
565#define CGSCC_PASS(NAME, CREATE_PASS) \
566 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
567#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
568 PIC->addClassToPassName(CLASS, NAME);
569#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
570 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
571#include "PassRegistry.def"
572
573#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
574 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
575#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
576 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
577#define MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, \
578 PARAMS) \
579 PIC->addClassToPassName(CLASS, NAME);
580#include "llvm/Passes/MachinePassRegistry.def"
581 });
582 }
583
584 // Module-level callbacks without LTO phase
586 [this](StringRef Name, ModulePassManager &PM,
588#define MODULE_CALLBACK(NAME, INVOKE) \
589 if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
590 auto L = PassBuilder::parsePassParameters(parseOptLevelParam, Name, NAME); \
591 if (!L) { \
592 errs() << NAME ": " << toString(L.takeError()) << '\n'; \
593 return false; \
594 } \
595 INVOKE(PM, L.get()); \
596 return true; \
597 }
598#include "PassRegistry.def"
599 return false;
600 });
601
602 // Module-level callbacks with LTO phase (use Phase::None for string API)
604 [this](StringRef Name, ModulePassManager &PM,
606#define MODULE_LTO_CALLBACK(NAME, INVOKE) \
607 if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
608 auto L = PassBuilder::parsePassParameters(parseOptLevelParam, Name, NAME); \
609 if (!L) { \
610 errs() << NAME ": " << toString(L.takeError()) << '\n'; \
611 return false; \
612 } \
613 INVOKE(PM, L.get(), ThinOrFullLTOPhase::None); \
614 return true; \
615 }
616#include "PassRegistry.def"
617 return false;
618 });
619
620 // Function-level callbacks
622 [this](StringRef Name, FunctionPassManager &PM,
624#define FUNCTION_CALLBACK(NAME, INVOKE) \
625 if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
626 auto L = PassBuilder::parsePassParameters(parseOptLevelParam, Name, NAME); \
627 if (!L) { \
628 errs() << NAME ": " << toString(L.takeError()) << '\n'; \
629 return false; \
630 } \
631 INVOKE(PM, L.get()); \
632 return true; \
633 }
634#include "PassRegistry.def"
635 return false;
636 });
637
638 // CGSCC-level callbacks
640 [this](StringRef Name, CGSCCPassManager &PM,
642#define CGSCC_CALLBACK(NAME, INVOKE) \
643 if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
644 auto L = PassBuilder::parsePassParameters(parseOptLevelParam, Name, NAME); \
645 if (!L) { \
646 errs() << NAME ": " << toString(L.takeError()) << '\n'; \
647 return false; \
648 } \
649 INVOKE(PM, L.get()); \
650 return true; \
651 }
652#include "PassRegistry.def"
653 return false;
654 });
655
656 // Loop-level callbacks
658 [this](StringRef Name, LoopPassManager &PM,
660#define LOOP_CALLBACK(NAME, INVOKE) \
661 if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
662 auto L = PassBuilder::parsePassParameters(parseOptLevelParam, Name, NAME); \
663 if (!L) { \
664 errs() << NAME ": " << toString(L.takeError()) << '\n'; \
665 return false; \
666 } \
667 INVOKE(PM, L.get()); \
668 return true; \
669 }
670#include "PassRegistry.def"
671 return false;
672 });
673}
674
676#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
677 MAM.registerPass([&] { return CREATE_PASS; });
678#include "PassRegistry.def"
679
680 for (auto &C : ModuleAnalysisRegistrationCallbacks)
681 C(MAM);
682}
683
685#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
686 CGAM.registerPass([&] { return CREATE_PASS; });
687#include "PassRegistry.def"
688
689 for (auto &C : CGSCCAnalysisRegistrationCallbacks)
690 C(CGAM);
691}
692
694 // We almost always want the default alias analysis pipeline.
695 // If a user wants a different one, they can register their own before calling
696 // registerFunctionAnalyses().
697 FAM.registerPass([&] { return buildDefaultAAPipeline(); });
698
699#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
700 if constexpr (std::is_constructible_v< \
701 std::remove_reference_t<decltype(CREATE_PASS)>, \
702 const TargetMachine &>) { \
703 if (TM) \
704 FAM.registerPass([&] { return CREATE_PASS; }); \
705 } else { \
706 FAM.registerPass([&] { return CREATE_PASS; }); \
707 }
708#include "PassRegistry.def"
709
710 for (auto &C : FunctionAnalysisRegistrationCallbacks)
711 C(FAM);
712}
713
716
717#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
718 MFAM.registerPass([&] { return CREATE_PASS; });
719#include "llvm/Passes/MachinePassRegistry.def"
720
721 for (auto &C : MachineFunctionAnalysisRegistrationCallbacks)
722 C(MFAM);
723}
724
726#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
727 LAM.registerPass([&] { return CREATE_PASS; });
728#include "PassRegistry.def"
729
730 for (auto &C : LoopAnalysisRegistrationCallbacks)
731 C(LAM);
732}
733
734static std::optional<std::pair<bool, bool>>
736 std::pair<bool, bool> Params;
737 if (!Name.consume_front("function"))
738 return std::nullopt;
739 if (Name.empty())
740 return Params;
741 if (!Name.consume_front("<") || !Name.consume_back(">"))
742 return std::nullopt;
743 while (!Name.empty()) {
744 auto [Front, Back] = Name.split(';');
745 Name = Back;
746 if (Front == "eager-inv")
747 Params.first = true;
748 else if (Front == "no-rerun")
749 Params.second = true;
750 else
751 return std::nullopt;
752 }
753 return Params;
754}
755
756static std::optional<int> parseDevirtPassName(StringRef Name) {
757 if (!Name.consume_front("devirt<") || !Name.consume_back(">"))
758 return std::nullopt;
759 int Count;
760 if (Name.getAsInteger(0, Count) || Count < 0)
761 return std::nullopt;
762 return Count;
763}
764
766 StringRef OptionName,
768 bool Result = false;
769 while (!Params.empty()) {
770 StringRef ParamName;
771 std::tie(ParamName, Params) = Params.split(';');
772
773 if (ParamName == OptionName) {
774 Result = true;
775 } else {
777 formatv("invalid {} pass parameter '{}'", PassName, ParamName).str(),
779 }
780 }
781 return Result;
782}
783
784namespace {
785
786/// Parser of parameters for HardwareLoops pass.
787Expected<HardwareLoopOptions> parseHardwareLoopOptions(StringRef Params) {
788 HardwareLoopOptions HardwareLoopOpts;
789
790 while (!Params.empty()) {
791 StringRef ParamName;
792 std::tie(ParamName, Params) = Params.split(';');
793 if (ParamName.consume_front("hardware-loop-decrement=")) {
794 int Count;
795 if (ParamName.getAsInteger(0, Count))
797 formatv("invalid HardwareLoopPass parameter '{}'", ParamName).str(),
799 HardwareLoopOpts.setDecrement(Count);
800 continue;
801 }
802 if (ParamName.consume_front("hardware-loop-counter-bitwidth=")) {
803 int Count;
804 if (ParamName.getAsInteger(0, Count))
806 formatv("invalid HardwareLoopPass parameter '{}'", ParamName).str(),
808 HardwareLoopOpts.setCounterBitwidth(Count);
809 continue;
810 }
811 if (ParamName == "force-hardware-loops") {
812 HardwareLoopOpts.setForce(true);
813 } else if (ParamName == "force-hardware-loop-phi") {
814 HardwareLoopOpts.setForcePhi(true);
815 } else if (ParamName == "force-nested-hardware-loop") {
816 HardwareLoopOpts.setForceNested(true);
817 } else if (ParamName == "force-hardware-loop-guard") {
818 HardwareLoopOpts.setForceGuard(true);
819 } else {
821 formatv("invalid HardwarePass parameter '{}'", ParamName).str(),
823 }
824 }
825 return HardwareLoopOpts;
826}
827
828/// Parser of parameters for Lint pass.
829Expected<bool> parseLintOptions(StringRef Params) {
830 return PassBuilder::parseSinglePassOption(Params, "abort-on-error",
831 "LintPass");
832}
833
834/// Parser of parameters for InstCount pass.
835Expected<bool> parseInstCountOptions(StringRef Params) {
836 return PassBuilder::parseSinglePassOption(Params, "pre-opt", "InstCountPass");
837}
838
839/// Parser of parameters for LoopUnroll pass.
840Expected<LoopUnrollOptions> parseLoopUnrollOptions(StringRef Params) {
841 LoopUnrollOptions UnrollOpts;
842 while (!Params.empty()) {
843 StringRef ParamName;
844 std::tie(ParamName, Params) = Params.split(';');
845 std::optional<OptimizationLevel> OptLevel = parseOptLevel(ParamName);
846 if (OptLevel) {
847 UnrollOpts.setOptLevel(OptLevel->getSpeedupLevel());
848 continue;
849 }
850 if (ParamName.consume_front("full-unroll-max=")) {
851 int Count;
852 if (ParamName.getAsInteger(0, Count))
854 formatv("invalid LoopUnrollPass parameter '{}'", ParamName).str(),
856 UnrollOpts.setFullUnrollMaxCount(Count);
857 continue;
858 }
859
860 bool Enable = !ParamName.consume_front("no-");
861 if (ParamName == "partial") {
862 UnrollOpts.setPartial(Enable);
863 } else if (ParamName == "peeling") {
864 UnrollOpts.setPeeling(Enable);
865 } else if (ParamName == "profile-peeling") {
866 UnrollOpts.setProfileBasedPeeling(Enable);
867 } else if (ParamName == "runtime") {
868 UnrollOpts.setRuntime(Enable);
869 } else if (ParamName == "upperbound") {
870 UnrollOpts.setUpperBound(Enable);
871 } else {
873 formatv("invalid LoopUnrollPass parameter '{}'", ParamName).str(),
875 }
876 }
877 return UnrollOpts;
878}
879
880Expected<bool> parseGlobalDCEPassOptions(StringRef Params) {
882 Params, "vfe-linkage-unit-visibility", "GlobalDCE");
883}
884
885Expected<bool> parseCGProfilePassOptions(StringRef Params) {
886 return PassBuilder::parseSinglePassOption(Params, "in-lto-post-link",
887 "CGProfile");
888}
889
890Expected<bool> parseInlinerPassOptions(StringRef Params) {
891 return PassBuilder::parseSinglePassOption(Params, "only-mandatory",
892 "InlinerPass");
893}
894
895Expected<bool> parseCoroSplitPassOptions(StringRef Params) {
896 return PassBuilder::parseSinglePassOption(Params, "reuse-storage",
897 "CoroSplitPass");
898}
899
900Expected<bool> parsePostOrderFunctionAttrsPassOptions(StringRef Params) {
902 Params, "skip-non-recursive-function-attrs", "PostOrderFunctionAttrs");
903}
904
905Expected<bool> parseEarlyCSEPassOptions(StringRef Params) {
906 return PassBuilder::parseSinglePassOption(Params, "memssa", "EarlyCSE");
907}
908
909Expected<bool> parseEntryExitInstrumenterPassOptions(StringRef Params) {
910 return PassBuilder::parseSinglePassOption(Params, "post-inline",
911 "EntryExitInstrumenter");
912}
913
914Expected<bool> parseDropUnnecessaryAssumesPassOptions(StringRef Params) {
915 return PassBuilder::parseSinglePassOption(Params, "drop-deref",
916 "DropUnnecessaryAssumes");
917}
918
919Expected<bool> parseLoopExtractorPassOptions(StringRef Params) {
920 return PassBuilder::parseSinglePassOption(Params, "single", "LoopExtractor");
921}
922
923Expected<bool> parseLowerMatrixIntrinsicsPassOptions(StringRef Params) {
924 return PassBuilder::parseSinglePassOption(Params, "minimal",
925 "LowerMatrixIntrinsics");
926}
927
928Expected<IRNormalizerOptions> parseIRNormalizerPassOptions(StringRef Params) {
930 while (!Params.empty()) {
931 StringRef ParamName;
932 std::tie(ParamName, Params) = Params.split(';');
933
934 bool Enable = !ParamName.consume_front("no-");
935 if (ParamName == "preserve-order")
936 Result.PreserveOrder = Enable;
937 else if (ParamName == "rename-all")
938 Result.RenameAll = Enable;
939 else if (ParamName == "fold-all") // FIXME: Name mismatch
940 Result.FoldPreOutputs = Enable;
941 else if (ParamName == "reorder-operands")
942 Result.ReorderOperands = Enable;
943 else {
945 formatv("invalid normalize pass parameter '{}'", ParamName).str(),
947 }
948 }
949
950 return Result;
951}
952
953Expected<AddressSanitizerOptions> parseASanPassOptions(StringRef Params) {
955 while (!Params.empty()) {
956 StringRef ParamName;
957 std::tie(ParamName, Params) = Params.split(';');
958
959 if (ParamName == "kernel") {
960 Result.CompileKernel = true;
961 } else if (ParamName == "use-after-scope") {
962 Result.UseAfterScope = true;
963 } else {
965 formatv("invalid AddressSanitizer pass parameter '{}'", ParamName)
966 .str(),
968 }
969 }
970 return Result;
971}
972
973Expected<HWAddressSanitizerOptions> parseHWASanPassOptions(StringRef Params) {
975 while (!Params.empty()) {
976 StringRef ParamName;
977 std::tie(ParamName, Params) = Params.split(';');
978
979 if (ParamName == "recover") {
980 Result.Recover = true;
981 } else if (ParamName == "kernel") {
982 Result.CompileKernel = true;
983 } else {
985 formatv("invalid HWAddressSanitizer pass parameter '{}'", ParamName)
986 .str(),
988 }
989 }
990 return Result;
991}
992
994parseDropTypeTestsPassOptions(StringRef Params) {
996 while (!Params.empty()) {
997 StringRef ParamName;
998 std::tie(ParamName, Params) = Params.split(';');
999
1000 if (ParamName == "all") {
1002 } else if (ParamName == "assume") {
1004 } else {
1006 formatv("invalid DropTypeTestsPass parameter '{}'", ParamName).str(),
1008 }
1009 }
1010 return Result;
1011}
1012
1013Expected<EmbedBitcodeOptions> parseEmbedBitcodePassOptions(StringRef Params) {
1015 while (!Params.empty()) {
1016 StringRef ParamName;
1017 std::tie(ParamName, Params) = Params.split(';');
1018
1019 if (ParamName == "thinlto") {
1020 Result.IsThinLTO = true;
1021 } else if (ParamName == "emit-summary") {
1022 Result.EmitLTOSummary = true;
1023 } else {
1025 formatv("invalid EmbedBitcode pass parameter '{}'", ParamName).str(),
1027 }
1028 }
1029 return Result;
1030}
1031
1033parseLowerAllowCheckPassOptions(StringRef Params) {
1035 while (!Params.empty()) {
1036 StringRef ParamName;
1037 std::tie(ParamName, Params) = Params.split(';');
1038
1039 // Format is <cutoffs[1,2,3]=70000;cutoffs[5,6,8]=90000>
1040 //
1041 // Parsing allows duplicate indices (last one takes precedence).
1042 // It would technically be in spec to specify
1043 // cutoffs[0]=70000,cutoffs[1]=90000,cutoffs[0]=80000,...
1044 if (ParamName.starts_with("cutoffs[")) {
1045 StringRef IndicesStr;
1046 StringRef CutoffStr;
1047
1048 std::tie(IndicesStr, CutoffStr) = ParamName.split("]=");
1049 // cutoffs[1,2,3
1050 // 70000
1051
1052 int cutoff;
1053 if (CutoffStr.getAsInteger(0, cutoff))
1055 formatv("invalid LowerAllowCheck pass cutoffs parameter '{}' ({})",
1056 CutoffStr, Params)
1057 .str(),
1059
1060 if (!IndicesStr.consume_front("cutoffs[") || IndicesStr == "")
1062 formatv("invalid LowerAllowCheck pass index parameter '{}' ({})",
1063 IndicesStr, CutoffStr)
1064 .str(),
1066
1067 while (IndicesStr != "") {
1068 StringRef firstIndexStr;
1069 std::tie(firstIndexStr, IndicesStr) = IndicesStr.split('|');
1070
1071 unsigned int index;
1072 if (firstIndexStr.getAsInteger(0, index))
1074 formatv(
1075 "invalid LowerAllowCheck pass index parameter '{}' ({}) {}",
1076 firstIndexStr, IndicesStr)
1077 .str(),
1079
1080 // In the common case (sequentially increasing indices), we will issue
1081 // O(n) resize requests. We assume the underlying data structure has
1082 // O(1) runtime for each added element.
1083 if (index >= Result.cutoffs.size())
1084 Result.cutoffs.resize(index + 1, 0);
1085
1086 Result.cutoffs[index] = cutoff;
1087 }
1088 } else if (ParamName.starts_with("runtime_check")) {
1089 StringRef ValueString;
1090 std::tie(std::ignore, ValueString) = ParamName.split("=");
1091 int runtime_check;
1092 if (ValueString.getAsInteger(0, runtime_check)) {
1094 formatv("invalid LowerAllowCheck pass runtime_check parameter '{}' "
1095 "({})",
1096 ValueString, Params)
1097 .str(),
1099 }
1100 Result.runtime_check = runtime_check;
1101 } else {
1103 formatv("invalid LowerAllowCheck pass parameter '{}'", ParamName)
1104 .str(),
1106 }
1107 }
1108
1109 return Result;
1110}
1111
1112Expected<MemorySanitizerOptions> parseMSanPassOptions(StringRef Params) {
1114 while (!Params.empty()) {
1115 StringRef ParamName;
1116 std::tie(ParamName, Params) = Params.split(';');
1117
1118 if (ParamName == "recover") {
1119 Result.Recover = true;
1120 } else if (ParamName == "kernel") {
1121 Result.Kernel = true;
1122 } else if (ParamName.consume_front("track-origins=")) {
1123 if (ParamName.getAsInteger(0, Result.TrackOrigins))
1125 formatv("invalid argument to MemorySanitizer pass track-origins "
1126 "parameter: '{}'",
1127 ParamName)
1128 .str(),
1130 } else if (ParamName == "eager-checks") {
1131 Result.EagerChecks = true;
1132 } else {
1134 formatv("invalid MemorySanitizer pass parameter '{}'", ParamName)
1135 .str(),
1137 }
1138 }
1139 return Result;
1140}
1141
1142Expected<AllocTokenOptions> parseAllocTokenPassOptions(StringRef Params) {
1144 while (!Params.empty()) {
1145 StringRef ParamName;
1146 std::tie(ParamName, Params) = Params.split(';');
1147
1148 if (ParamName.consume_front("mode=")) {
1149 if (auto Mode = getAllocTokenModeFromString(ParamName))
1150 Result.Mode = *Mode;
1151 else
1153 formatv("invalid argument to AllocToken pass mode "
1154 "parameter: '{}'",
1155 ParamName)
1156 .str(),
1158 } else {
1160 formatv("invalid AllocToken pass parameter '{}'", ParamName).str(),
1162 }
1163 }
1164 return Result;
1165}
1166
1167/// Parser of parameters for SimplifyCFG pass.
1168Expected<SimplifyCFGOptions> parseSimplifyCFGOptions(StringRef Params) {
1170 while (!Params.empty()) {
1171 StringRef ParamName;
1172 std::tie(ParamName, Params) = Params.split(';');
1173
1174 bool Enable = !ParamName.consume_front("no-");
1175 if (ParamName == "speculate-blocks") {
1176 Result.speculateBlocks(Enable);
1177 } else if (ParamName == "simplify-cond-branch") {
1178 Result.setSimplifyCondBranch(Enable);
1179 } else if (ParamName == "forward-switch-cond") {
1180 Result.forwardSwitchCondToPhi(Enable);
1181 } else if (ParamName == "switch-range-to-icmp") {
1182 Result.convertSwitchRangeToICmp(Enable);
1183 } else if (ParamName == "switch-to-arithmetic") {
1184 Result.convertSwitchToArithmetic(Enable);
1185 } else if (ParamName == "switch-to-lookup") {
1186 Result.convertSwitchToLookupTable(Enable);
1187 } else if (ParamName == "keep-loops") {
1188 Result.needCanonicalLoops(Enable);
1189 } else if (ParamName == "hoist-common-insts") {
1190 Result.hoistCommonInsts(Enable);
1191 } else if (ParamName == "hoist-loads-stores-with-cond-faulting") {
1192 Result.hoistLoadsStoresWithCondFaulting(Enable);
1193 } else if (ParamName == "sink-common-insts") {
1194 Result.sinkCommonInsts(Enable);
1195 } else if (ParamName == "speculate-unpredictables") {
1196 Result.speculateUnpredictables(Enable);
1197 } else if (Enable && ParamName.consume_front("bonus-inst-threshold=")) {
1198 APInt BonusInstThreshold;
1199 if (ParamName.getAsInteger(0, BonusInstThreshold))
1201 formatv("invalid argument to SimplifyCFG pass bonus-threshold "
1202 "parameter: '{}'",
1203 ParamName)
1204 .str(),
1206 Result.bonusInstThreshold(BonusInstThreshold.getSExtValue());
1207 } else {
1209 formatv("invalid SimplifyCFG pass parameter '{}'", ParamName).str(),
1211 }
1212 }
1213 return Result;
1214}
1215
1216Expected<InstCombineOptions> parseInstCombineOptions(StringRef Params) {
1218 // When specifying "instcombine" in -passes enable fix-point verification by
1219 // default, as this is what most tests should use.
1220 Result.setVerifyFixpoint(true);
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 == "verify-fixpoint") {
1227 Result.setVerifyFixpoint(Enable);
1228 } else if (Enable && ParamName.consume_front("max-iterations=")) {
1229 APInt MaxIterations;
1230 if (ParamName.getAsInteger(0, MaxIterations))
1232 formatv("invalid argument to InstCombine pass max-iterations "
1233 "parameter: '{}'",
1234 ParamName)
1235 .str(),
1237 Result.setMaxIterations((unsigned)MaxIterations.getZExtValue());
1238 } else {
1240 formatv("invalid InstCombine pass parameter '{}'", ParamName).str(),
1242 }
1243 }
1244 return Result;
1245}
1246
1247/// Parser of parameters for LoopVectorize pass.
1248Expected<LoopVectorizeOptions> parseLoopVectorizeOptions(StringRef Params) {
1250 while (!Params.empty()) {
1251 StringRef ParamName;
1252 std::tie(ParamName, Params) = Params.split(';');
1253
1254 bool Enable = !ParamName.consume_front("no-");
1255 if (ParamName == "interleave-forced-only") {
1257 } else if (ParamName == "vectorize-forced-only") {
1259 } else {
1261 formatv("invalid LoopVectorize parameter '{}'", ParamName).str(),
1263 }
1264 }
1265 return Opts;
1266}
1267
1268Expected<std::pair<bool, bool>> parseLoopUnswitchOptions(StringRef Params) {
1269 std::pair<bool, bool> Result = {false, true};
1270 while (!Params.empty()) {
1271 StringRef ParamName;
1272 std::tie(ParamName, Params) = Params.split(';');
1273
1274 bool Enable = !ParamName.consume_front("no-");
1275 if (ParamName == "nontrivial") {
1276 Result.first = Enable;
1277 } else if (ParamName == "trivial") {
1278 Result.second = Enable;
1279 } else {
1281 formatv("invalid LoopUnswitch pass parameter '{}'", ParamName).str(),
1283 }
1284 }
1285 return Result;
1286}
1287
1288Expected<LICMOptions> parseLICMOptions(StringRef Params) {
1290 while (!Params.empty()) {
1291 StringRef ParamName;
1292 std::tie(ParamName, Params) = Params.split(';');
1293
1294 bool Enable = !ParamName.consume_front("no-");
1295 if (ParamName == "allowspeculation") {
1296 Result.AllowSpeculation = Enable;
1297 } else {
1299 formatv("invalid LICM pass parameter '{}'", ParamName).str(),
1301 }
1302 }
1303 return Result;
1304}
1305
1306struct LoopRotateOptions {
1307 bool EnableHeaderDuplication = true;
1308 bool PrepareForLTO = false;
1309 bool CheckExitCount = false;
1310};
1311
1312Expected<LoopRotateOptions> parseLoopRotateOptions(StringRef Params) {
1313 LoopRotateOptions Result;
1314 while (!Params.empty()) {
1315 StringRef ParamName;
1316 std::tie(ParamName, Params) = Params.split(';');
1317
1318 bool Enable = !ParamName.consume_front("no-");
1319 if (ParamName == "header-duplication") {
1320 Result.EnableHeaderDuplication = Enable;
1321 } else if (ParamName == "prepare-for-lto") {
1322 Result.PrepareForLTO = Enable;
1323 } else if (ParamName == "check-exit-count") {
1324 Result.CheckExitCount = Enable;
1325 } else {
1327 formatv("invalid LoopRotate pass parameter '{}'", ParamName).str(),
1329 }
1330 }
1331 return Result;
1332}
1333
1334Expected<bool> parseMergedLoadStoreMotionOptions(StringRef Params) {
1335 bool Result = false;
1336 while (!Params.empty()) {
1337 StringRef ParamName;
1338 std::tie(ParamName, Params) = Params.split(';');
1339
1340 bool Enable = !ParamName.consume_front("no-");
1341 if (ParamName == "split-footer-bb") {
1342 Result = Enable;
1343 } else {
1345 formatv("invalid MergedLoadStoreMotion pass parameter '{}'",
1346 ParamName)
1347 .str(),
1349 }
1350 }
1351 return Result;
1352}
1353
1354Expected<GVNOptions> parseGVNOptions(StringRef Params) {
1356 while (!Params.empty()) {
1357 StringRef ParamName;
1358 std::tie(ParamName, Params) = Params.split(';');
1359
1360 bool Enable = !ParamName.consume_front("no-");
1361 if (ParamName == "scalar-pre") {
1362 Result.setScalarPRE(Enable);
1363 } else if (ParamName == "load-pre") {
1364 Result.setLoadPRE(Enable);
1365 } else if (ParamName == "split-backedge-load-pre") {
1366 Result.setLoadPRESplitBackedge(Enable);
1367 } else if (ParamName == "memdep") {
1368 // MemDep and MemorySSA are mutually exclusive.
1369 Result.setMemDep(Enable);
1370 Result.setMemorySSA(!Enable);
1371 } else if (ParamName == "memoryssa") {
1372 // MemDep and MemorySSA are mutually exclusive.
1373 Result.setMemorySSA(Enable);
1374 Result.setMemDep(!Enable);
1375 } else {
1377 formatv("invalid GVN pass parameter '{}'", ParamName).str(),
1379 }
1380 }
1381 return Result;
1382}
1383
1384Expected<IPSCCPOptions> parseIPSCCPOptions(StringRef Params) {
1386 while (!Params.empty()) {
1387 StringRef ParamName;
1388 std::tie(ParamName, Params) = Params.split(';');
1389
1390 bool Enable = !ParamName.consume_front("no-");
1391 if (ParamName == "func-spec")
1392 Result.setFuncSpec(Enable);
1393 else
1395 formatv("invalid IPSCCP pass parameter '{}'", ParamName).str(),
1397 }
1398 return Result;
1399}
1400
1401Expected<ScalarizerPassOptions> parseScalarizerOptions(StringRef Params) {
1403 while (!Params.empty()) {
1404 StringRef ParamName;
1405 std::tie(ParamName, Params) = Params.split(';');
1406
1407 if (ParamName.consume_front("min-bits=")) {
1408 if (ParamName.getAsInteger(0, Result.ScalarizeMinBits)) {
1410 formatv("invalid argument to Scalarizer pass min-bits "
1411 "parameter: '{}'",
1412 ParamName)
1413 .str(),
1415 }
1416
1417 continue;
1418 }
1419
1420 bool Enable = !ParamName.consume_front("no-");
1421 if (ParamName == "load-store")
1422 Result.ScalarizeLoadStore = Enable;
1423 else if (ParamName == "variable-insert-extract")
1424 Result.ScalarizeVariableInsertExtract = Enable;
1425 else {
1427 formatv("invalid Scalarizer pass parameter '{}'", ParamName).str(),
1429 }
1430 }
1431
1432 return Result;
1433}
1434
1435Expected<SROAOptions> parseSROAOptions(StringRef Params) {
1436 if (Params.empty() || Params == "modify-cfg")
1438 if (Params == "preserve-cfg")
1441 formatv("invalid SROA pass parameter '{}' (either preserve-cfg or "
1442 "modify-cfg can be specified)",
1443 Params)
1444 .str(),
1446}
1447
1449parseStackLifetimeOptions(StringRef Params) {
1451 while (!Params.empty()) {
1452 StringRef ParamName;
1453 std::tie(ParamName, Params) = Params.split(';');
1454
1455 if (ParamName == "may") {
1457 } else if (ParamName == "must") {
1459 } else {
1461 formatv("invalid StackLifetime parameter '{}'", ParamName).str(),
1463 }
1464 }
1465 return Result;
1466}
1467
1468Expected<bool> parseDependenceAnalysisPrinterOptions(StringRef Params) {
1469 return PassBuilder::parseSinglePassOption(Params, "normalized-results",
1470 "DependenceAnalysisPrinter");
1471}
1472
1473Expected<bool> parseSeparateConstOffsetFromGEPPassOptions(StringRef Params) {
1474 return PassBuilder::parseSinglePassOption(Params, "lower-gep",
1475 "SeparateConstOffsetFromGEP");
1476}
1477
1478Expected<bool> parseStructurizeCFGPassOptions(StringRef Params) {
1479 return PassBuilder::parseSinglePassOption(Params, "skip-uniform-regions",
1480 "StructurizeCFG");
1481}
1482
1484parseFunctionSimplificationPipelineOptions(StringRef Params) {
1485 std::optional<OptimizationLevel> L = parseOptLevel(Params);
1486 if (!L || *L == OptimizationLevel::O0) {
1488 formatv("invalid function-simplification parameter '{}'", Params).str(),
1490 };
1491 return *L;
1492}
1493
1494Expected<bool> parseMemorySSAPrinterPassOptions(StringRef Params) {
1495 return PassBuilder::parseSinglePassOption(Params, "no-ensure-optimized-uses",
1496 "MemorySSAPrinterPass");
1497}
1498
1499Expected<bool> parseSpeculativeExecutionPassOptions(StringRef Params) {
1500 return PassBuilder::parseSinglePassOption(Params, "only-if-divergent-target",
1501 "SpeculativeExecutionPass");
1502}
1503
1504Expected<std::string> parseMemProfUsePassOptions(StringRef Params) {
1505 std::string Result;
1506 while (!Params.empty()) {
1507 StringRef ParamName;
1508 std::tie(ParamName, Params) = Params.split(';');
1509
1510 if (ParamName.consume_front("profile-filename=")) {
1511 Result = ParamName.str();
1512 } else {
1514 formatv("invalid MemProfUse pass parameter '{}'", ParamName).str(),
1516 }
1517 }
1518 return Result;
1519}
1520
1522parseStructuralHashPrinterPassOptions(StringRef Params) {
1523 if (Params.empty())
1525 if (Params == "detailed")
1527 if (Params == "call-target-ignored")
1530 formatv("invalid structural hash printer parameter '{}'", Params).str(),
1532}
1533
1534Expected<bool> parseWinEHPrepareOptions(StringRef Params) {
1535 return PassBuilder::parseSinglePassOption(Params, "demote-catchswitch-only",
1536 "WinEHPreparePass");
1537}
1538
1539Expected<GlobalMergeOptions> parseGlobalMergeOptions(StringRef Params) {
1541 while (!Params.empty()) {
1542 StringRef ParamName;
1543 std::tie(ParamName, Params) = Params.split(';');
1544
1545 bool Enable = !ParamName.consume_front("no-");
1546 if (ParamName == "group-by-use")
1547 Result.GroupByUse = Enable;
1548 else if (ParamName == "ignore-single-use")
1549 Result.IgnoreSingleUse = Enable;
1550 else if (ParamName == "merge-const")
1551 Result.MergeConstantGlobals = Enable;
1552 else if (ParamName == "merge-const-aggressive")
1553 Result.MergeConstAggressive = Enable;
1554 else if (ParamName == "merge-external")
1555 Result.MergeExternal = Enable;
1556 else if (ParamName.consume_front("max-offset=")) {
1557 if (ParamName.getAsInteger(0, Result.MaxOffset))
1559 formatv("invalid GlobalMergePass parameter '{}'", ParamName).str(),
1561 } else {
1563 formatv("invalid global-merge pass parameter '{}'", Params).str(),
1565 }
1566 }
1567 return Result;
1568}
1569
1570Expected<SmallVector<std::string, 0>> parseInternalizeGVs(StringRef Params) {
1571 SmallVector<std::string, 1> PreservedGVs;
1572 while (!Params.empty()) {
1573 StringRef ParamName;
1574 std::tie(ParamName, Params) = Params.split(';');
1575
1576 if (ParamName.consume_front("preserve-gv=")) {
1577 PreservedGVs.push_back(ParamName.str());
1578 } else {
1580 formatv("invalid Internalize pass parameter '{}'", ParamName).str(),
1582 }
1583 }
1584
1585 return Expected<SmallVector<std::string, 0>>(std::move(PreservedGVs));
1586}
1587
1589parseRegAllocFastPassOptions(PassBuilder &PB, StringRef Params) {
1591 while (!Params.empty()) {
1592 StringRef ParamName;
1593 std::tie(ParamName, Params) = Params.split(';');
1594
1595 if (ParamName.consume_front("filter=")) {
1596 std::optional<RegAllocFilterFunc> Filter =
1597 PB.parseRegAllocFilter(ParamName);
1598 if (!Filter) {
1600 formatv("invalid regallocfast register filter '{}'", ParamName)
1601 .str(),
1603 }
1604 Opts.Filter = *Filter;
1605 Opts.FilterName = ParamName;
1606 continue;
1607 }
1608
1609 if (ParamName == "no-clear-vregs") {
1610 Opts.ClearVRegs = false;
1611 continue;
1612 }
1613
1615 formatv("invalid regallocfast pass parameter '{}'", ParamName).str(),
1617 }
1618 return Opts;
1619}
1620
1622parseBoundsCheckingOptions(StringRef Params) {
1624 while (!Params.empty()) {
1625 StringRef ParamName;
1626 std::tie(ParamName, Params) = Params.split(';');
1627 if (ParamName == "trap") {
1628 Options.Rt = std::nullopt;
1629 } else if (ParamName == "rt") {
1630 Options.Rt = {
1631 /*MinRuntime=*/false,
1632 /*MayReturn=*/true,
1633 /*HandlerPreserveAllRegs=*/false,
1634 };
1635 } else if (ParamName == "rt-abort") {
1636 Options.Rt = {
1637 /*MinRuntime=*/false,
1638 /*MayReturn=*/false,
1639 /*HandlerPreserveAllRegs=*/false,
1640 };
1641 } else if (ParamName == "min-rt") {
1642 Options.Rt = {
1643 /*MinRuntime=*/true,
1644 /*MayReturn=*/true,
1645 /*HandlerPreserveAllRegs=*/false,
1646 };
1647 } else if (ParamName == "min-rt-abort") {
1648 Options.Rt = {
1649 /*MinRuntime=*/true,
1650 /*MayReturn=*/false,
1651 /*HandlerPreserveAllRegs=*/false,
1652 };
1653 } else if (ParamName == "merge") {
1654 Options.Merge = true;
1655 } else if (ParamName == "handler-preserve-all-regs") {
1656 if (Options.Rt)
1657 Options.Rt->HandlerPreserveAllRegs = true;
1658 } else {
1659 StringRef ParamEQ;
1660 StringRef Val;
1661 std::tie(ParamEQ, Val) = ParamName.split('=');
1662 int8_t Id;
1663 if (ParamEQ == "guard" && !Val.getAsInteger(0, Id)) {
1664 Options.GuardKind = Id;
1665 } else {
1667 formatv("invalid BoundsChecking pass parameter '{}'", ParamName)
1668 .str(),
1670 }
1671 }
1672 }
1673 return Options;
1674}
1675
1676Expected<CodeGenOptLevel> parseExpandIRInstsOptions(StringRef Param) {
1677 if (Param.empty())
1678 return CodeGenOptLevel::None;
1679
1680 // Parse a CodeGenOptLevel, e.g. "O1", "O2", "O3".
1681 auto [Prefix, Digit] = Param.split('O');
1682
1683 uint8_t N;
1684 if (!Prefix.empty() || Digit.getAsInteger(10, N))
1685 return createStringError("invalid expand-ir-insts pass parameter '%s'",
1686 Param.str().c_str());
1687
1688 std::optional<CodeGenOptLevel> Level = CodeGenOpt::getLevel(N);
1689 if (!Level.has_value())
1690 return createStringError(
1691 "invalid optimization level for expand-ir-insts pass: %s",
1692 Digit.str().c_str());
1693
1694 return *Level;
1695}
1696
1698parseRegAllocGreedyFilterFunc(PassBuilder &PB, StringRef Params) {
1699 if (Params.empty() || Params == "all")
1700 return RAGreedyPass::Options();
1701
1702 std::optional<RegAllocFilterFunc> Filter = PB.parseRegAllocFilter(Params);
1703 if (Filter)
1704 return RAGreedyPass::Options{*Filter, Params};
1705
1707 formatv("invalid regallocgreedy register filter '{}'", Params).str(),
1709}
1710
1711Expected<bool> parseMachineSinkingPassOptions(StringRef Params) {
1712 return PassBuilder::parseSinglePassOption(Params, "enable-sink-fold",
1713 "MachineSinkingPass");
1714}
1715
1716Expected<bool> parseMachineBlockPlacementPassOptions(StringRef Params) {
1717 bool AllowTailMerge = true;
1718 if (!Params.empty()) {
1719 AllowTailMerge = !Params.consume_front("no-");
1720 if (Params != "tail-merge")
1722 formatv("invalid MachineBlockPlacementPass parameter '{}'", Params)
1723 .str(),
1725 }
1726 return AllowTailMerge;
1727}
1728
1729Expected<bool> parseVirtRegRewriterPassOptions(StringRef Params) {
1730 bool ClearVirtRegs = true;
1731 if (!Params.empty()) {
1732 ClearVirtRegs = !Params.consume_front("no-");
1733 if (Params != "clear-vregs")
1735 formatv("invalid VirtRegRewriter pass parameter '{}'", Params).str(),
1737 }
1738 return ClearVirtRegs;
1739}
1740
1741struct FatLTOOptions {
1742 OptimizationLevel OptLevel;
1743 bool ThinLTO = false;
1744 bool EmitSummary = false;
1745};
1746
1747Expected<FatLTOOptions> parseFatLTOOptions(StringRef Params) {
1748 FatLTOOptions Result;
1749 bool HaveOptLevel = false;
1750 while (!Params.empty()) {
1751 StringRef ParamName;
1752 std::tie(ParamName, Params) = Params.split(';');
1753
1754 if (ParamName == "thinlto") {
1755 Result.ThinLTO = true;
1756 } else if (ParamName == "emit-summary") {
1757 Result.EmitSummary = true;
1758 } else if (std::optional<OptimizationLevel> OptLevel =
1759 parseOptLevel(ParamName)) {
1760 Result.OptLevel = *OptLevel;
1761 HaveOptLevel = true;
1762 } else {
1764 formatv("invalid fatlto-pre-link pass parameter '{}'", ParamName)
1765 .str(),
1767 }
1768 }
1769 if (!HaveOptLevel)
1771 "missing optimization level for fatlto-pre-link pipeline",
1773 return Result;
1774}
1775
1776} // namespace
1777
1778/// Tests whether registered callbacks will accept a given pass name.
1779///
1780/// When parsing a pipeline text, the type of the outermost pipeline may be
1781/// omitted, in which case the type is automatically determined from the first
1782/// pass name in the text. This may be a name that is handled through one of the
1783/// callbacks. We check this through the oridinary parsing callbacks by setting
1784/// up a dummy PassManager in order to not force the client to also handle this
1785/// type of query.
1786template <typename PassManagerT, typename CallbacksT>
1787static bool callbacksAcceptPassName(StringRef Name, CallbacksT &Callbacks) {
1788 if (!Callbacks.empty()) {
1789 PassManagerT DummyPM;
1790 for (auto &CB : Callbacks)
1791 if (CB(Name, DummyPM, {}))
1792 return true;
1793 }
1794 return false;
1795}
1796
1797template <typename CallbacksT>
1798static bool isModulePassName(StringRef Name, CallbacksT &Callbacks) {
1799 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1800
1801 // Explicitly handle pass manager names.
1802 if (Name == "module")
1803 return true;
1804 if (Name == "cgscc")
1805 return true;
1806 if (NameNoBracket == "function")
1807 return true;
1808 if (Name == "coro-cond")
1809 return true;
1810
1811#define MODULE_PASS(NAME, CREATE_PASS) \
1812 if (Name == NAME) \
1813 return true;
1814#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1815 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1816 return true;
1817#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
1818 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1819 return true;
1820#include "PassRegistry.def"
1821
1822 return callbacksAcceptPassName<ModulePassManager>(Name, Callbacks);
1823}
1824
1825template <typename CallbacksT>
1826static bool isCGSCCPassName(StringRef Name, CallbacksT &Callbacks) {
1827 // Explicitly handle pass manager names.
1828 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1829 if (Name == "cgscc")
1830 return true;
1831 if (NameNoBracket == "function")
1832 return true;
1833
1834 // Explicitly handle custom-parsed pass names.
1835 if (parseDevirtPassName(Name))
1836 return true;
1837
1838#define CGSCC_PASS(NAME, CREATE_PASS) \
1839 if (Name == NAME) \
1840 return true;
1841#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1842 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1843 return true;
1844#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
1845 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1846 return true;
1847#include "PassRegistry.def"
1848
1849 return callbacksAcceptPassName<CGSCCPassManager>(Name, Callbacks);
1850}
1851
1852template <typename CallbacksT>
1853static bool isFunctionPassName(StringRef Name, CallbacksT &Callbacks) {
1854 // Explicitly handle pass manager names.
1855 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1856 if (NameNoBracket == "function")
1857 return true;
1858 if (Name == "loop" || Name == "loop-mssa" || Name == "machine-function")
1859 return true;
1860
1861#define FUNCTION_PASS(NAME, CREATE_PASS) \
1862 if (Name == NAME) \
1863 return true;
1864#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1865 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1866 return true;
1867#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1868 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1869 return true;
1870#include "PassRegistry.def"
1871
1872 return callbacksAcceptPassName<FunctionPassManager>(Name, Callbacks);
1873}
1874
1875template <typename CallbacksT>
1876static bool isMachineFunctionPassName(StringRef Name, CallbacksT &Callbacks) {
1877 // Explicitly handle pass manager names.
1878 if (Name == "machine-function")
1879 return true;
1880
1881#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
1882 if (Name == NAME) \
1883 return true;
1884#define MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, \
1885 PARAMS) \
1886 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1887 return true;
1888
1889#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1890 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1891 return true;
1892
1893#include "llvm/Passes/MachinePassRegistry.def"
1894
1896}
1897
1898template <typename CallbacksT>
1899static bool isLoopNestPassName(StringRef Name, CallbacksT &Callbacks,
1900 bool &UseMemorySSA) {
1901 UseMemorySSA = false;
1902
1903 if (PassBuilder::checkParametrizedPassName(Name, "lnicm")) {
1904 UseMemorySSA = true;
1905 return true;
1906 }
1907
1908#define LOOPNEST_PASS(NAME, CREATE_PASS) \
1909 if (Name == NAME) \
1910 return true;
1911#include "PassRegistry.def"
1912
1913 return callbacksAcceptPassName<LoopPassManager>(Name, Callbacks);
1914}
1915
1916template <typename CallbacksT>
1917static bool isLoopPassName(StringRef Name, CallbacksT &Callbacks,
1918 bool &UseMemorySSA) {
1919 UseMemorySSA = false;
1920
1921 if (PassBuilder::checkParametrizedPassName(Name, "licm")) {
1922 UseMemorySSA = true;
1923 return true;
1924 }
1925
1926#define LOOP_PASS(NAME, CREATE_PASS) \
1927 if (Name == NAME) \
1928 return true;
1929#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1930 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1931 return true;
1932#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
1933 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1934 return true;
1935#include "PassRegistry.def"
1936
1937 return callbacksAcceptPassName<LoopPassManager>(Name, Callbacks);
1938}
1939
1940std::optional<std::vector<PassBuilder::PipelineElement>>
1941PassBuilder::parsePipelineText(StringRef Text) {
1942 std::vector<PipelineElement> ResultPipeline;
1943
1944 SmallVector<std::vector<PipelineElement> *, 4> PipelineStack = {
1945 &ResultPipeline};
1946 for (;;) {
1947 std::vector<PipelineElement> &Pipeline = *PipelineStack.back();
1948 size_t Pos = Text.find_first_of(",()");
1949 Pipeline.push_back({Text.substr(0, Pos), {}});
1950
1951 // If we have a single terminating name, we're done.
1952 if (Pos == Text.npos)
1953 break;
1954
1955 char Sep = Text[Pos];
1956 Text = Text.substr(Pos + 1);
1957 if (Sep == ',')
1958 // Just a name ending in a comma, continue.
1959 continue;
1960
1961 if (Sep == '(') {
1962 // Push the inner pipeline onto the stack to continue processing.
1963 PipelineStack.push_back(&Pipeline.back().InnerPipeline);
1964 continue;
1965 }
1966
1967 assert(Sep == ')' && "Bogus separator!");
1968 // When handling the close parenthesis, we greedily consume them to avoid
1969 // empty strings in the pipeline.
1970 do {
1971 // If we try to pop the outer pipeline we have unbalanced parentheses.
1972 if (PipelineStack.size() == 1)
1973 return std::nullopt;
1974
1975 PipelineStack.pop_back();
1976 } while (Text.consume_front(")"));
1977
1978 // Check if we've finished parsing.
1979 if (Text.empty())
1980 break;
1981
1982 // Otherwise, the end of an inner pipeline always has to be followed by
1983 // a comma, and then we can continue.
1984 if (!Text.consume_front(","))
1985 return std::nullopt;
1986 }
1987
1988 if (PipelineStack.size() > 1)
1989 // Unbalanced paretheses.
1990 return std::nullopt;
1991
1992 assert(PipelineStack.back() == &ResultPipeline &&
1993 "Wrong pipeline at the bottom of the stack!");
1994 return {std::move(ResultPipeline)};
1995}
1996
1999 PTO.LoopVectorization = L.getSpeedupLevel() > 1;
2000 PTO.SLPVectorization = L.getSpeedupLevel() > 1;
2001}
2002
2003Error PassBuilder::parseModulePass(ModulePassManager &MPM,
2004 const PipelineElement &E) {
2005 auto &Name = E.Name;
2006 auto &InnerPipeline = E.InnerPipeline;
2007
2008 // First handle complex passes like the pass managers which carry pipelines.
2009 if (!InnerPipeline.empty()) {
2010 if (Name == "module") {
2011 ModulePassManager NestedMPM;
2012 if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline))
2013 return Err;
2014 MPM.addPass(std::move(NestedMPM));
2015 return Error::success();
2016 }
2017 if (Name == "coro-cond") {
2018 ModulePassManager NestedMPM;
2019 if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline))
2020 return Err;
2021 MPM.addPass(CoroConditionalWrapper(std::move(NestedMPM)));
2022 return Error::success();
2023 }
2024 if (Name == "cgscc") {
2025 CGSCCPassManager CGPM;
2026 if (auto Err = parseCGSCCPassPipeline(CGPM, InnerPipeline))
2027 return Err;
2029 return Error::success();
2030 }
2031 if (auto Params = parseFunctionPipelineName(Name)) {
2032 if (Params->second)
2034 "cannot have a no-rerun module to function adaptor",
2037 if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline))
2038 return Err;
2039 MPM.addPass(
2040 createModuleToFunctionPassAdaptor(std::move(FPM), Params->first));
2041 return Error::success();
2042 }
2043
2044 for (auto &C : ModulePipelineParsingCallbacks)
2045 if (C(Name, MPM, InnerPipeline))
2046 return Error::success();
2047
2048 // Normal passes can't have pipelines.
2050 formatv("invalid use of '{}' pass as module pipeline", Name).str(),
2052 ;
2053 }
2054
2055 // Finally expand the basic registered passes from the .inc file.
2056#define MODULE_PASS(NAME, CREATE_PASS) \
2057 if (Name == NAME) { \
2058 MPM.addPass(CREATE_PASS); \
2059 return Error::success(); \
2060 }
2061#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2062 if (checkParametrizedPassName(Name, NAME)) { \
2063 auto Params = parsePassParameters(PARSER, Name, NAME); \
2064 if (!Params) \
2065 return Params.takeError(); \
2066 MPM.addPass(CREATE_PASS(Params.get())); \
2067 return Error::success(); \
2068 }
2069#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
2070 if (Name == "require<" NAME ">") { \
2071 MPM.addPass( \
2072 RequireAnalysisPass< \
2073 std::remove_reference_t<decltype(CREATE_PASS)>, Module>()); \
2074 return Error::success(); \
2075 } \
2076 if (Name == "invalidate<" NAME ">") { \
2077 MPM.addPass(InvalidateAnalysisPass< \
2078 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2079 return Error::success(); \
2080 }
2081#define CGSCC_PASS(NAME, CREATE_PASS) \
2082 if (Name == NAME) { \
2083 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(CREATE_PASS)); \
2084 return Error::success(); \
2085 }
2086#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2087 if (checkParametrizedPassName(Name, NAME)) { \
2088 auto Params = parsePassParameters(PARSER, Name, NAME); \
2089 if (!Params) \
2090 return Params.takeError(); \
2091 MPM.addPass( \
2092 createModuleToPostOrderCGSCCPassAdaptor(CREATE_PASS(Params.get()))); \
2093 return Error::success(); \
2094 }
2095#define FUNCTION_PASS(NAME, CREATE_PASS) \
2096 if (Name == NAME) { \
2097 if constexpr (std::is_constructible_v< \
2098 std::remove_reference_t<decltype(CREATE_PASS)>, \
2099 const TargetMachine &>) { \
2100 if (!TM) \
2101 return make_error<StringError>( \
2102 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2103 inconvertibleErrorCode()); \
2104 } \
2105 MPM.addPass(createModuleToFunctionPassAdaptor(CREATE_PASS)); \
2106 return Error::success(); \
2107 }
2108#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2109 if (checkParametrizedPassName(Name, NAME)) { \
2110 auto Params = parsePassParameters(PARSER, Name, NAME); \
2111 if (!Params) \
2112 return Params.takeError(); \
2113 auto CreatePass = CREATE_PASS; \
2114 if constexpr (std::is_constructible_v< \
2115 std::remove_reference_t<decltype(CreatePass( \
2116 Params.get()))>, \
2117 const TargetMachine &, \
2118 std::remove_reference_t<decltype(Params.get())>>) { \
2119 if (!TM) { \
2120 return make_error<StringError>( \
2121 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2122 inconvertibleErrorCode()); \
2123 } \
2124 } \
2125 MPM.addPass(createModuleToFunctionPassAdaptor(CREATE_PASS(Params.get()))); \
2126 return Error::success(); \
2127 }
2128#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2129 if (Name == NAME) { \
2130 MPM.addPass(createModuleToFunctionPassAdaptor( \
2131 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2132 return Error::success(); \
2133 }
2134#define LOOP_PASS(NAME, CREATE_PASS) \
2135 if (Name == NAME) { \
2136 MPM.addPass(createModuleToFunctionPassAdaptor( \
2137 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2138 return Error::success(); \
2139 }
2140#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2141 if (checkParametrizedPassName(Name, NAME)) { \
2142 auto Params = parsePassParameters(PARSER, Name, NAME); \
2143 if (!Params) \
2144 return Params.takeError(); \
2145 MPM.addPass(createModuleToFunctionPassAdaptor( \
2146 createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), false))); \
2147 return Error::success(); \
2148 }
2149#include "PassRegistry.def"
2150
2151 for (auto &C : ModulePipelineParsingCallbacks)
2152 if (C(Name, MPM, InnerPipeline))
2153 return Error::success();
2155 formatv("unknown module pass '{}'", Name).str(),
2157}
2158
2159Error PassBuilder::parseCGSCCPass(CGSCCPassManager &CGPM,
2160 const PipelineElement &E) {
2161 auto &Name = E.Name;
2162 auto &InnerPipeline = E.InnerPipeline;
2163
2164 // First handle complex passes like the pass managers which carry pipelines.
2165 if (!InnerPipeline.empty()) {
2166 if (Name == "cgscc") {
2167 CGSCCPassManager NestedCGPM;
2168 if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline))
2169 return Err;
2170 // Add the nested pass manager with the appropriate adaptor.
2171 CGPM.addPass(std::move(NestedCGPM));
2172 return Error::success();
2173 }
2174 if (auto Params = parseFunctionPipelineName(Name)) {
2176 if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline))
2177 return Err;
2178 // Add the nested pass manager with the appropriate adaptor.
2180 std::move(FPM), Params->first, Params->second));
2181 return Error::success();
2182 }
2183 if (auto MaxRepetitions = parseDevirtPassName(Name)) {
2184 CGSCCPassManager NestedCGPM;
2185 if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline))
2186 return Err;
2187 CGPM.addPass(
2188 createDevirtSCCRepeatedPass(std::move(NestedCGPM), *MaxRepetitions));
2189 return Error::success();
2190 }
2191
2192 for (auto &C : CGSCCPipelineParsingCallbacks)
2193 if (C(Name, CGPM, InnerPipeline))
2194 return Error::success();
2195
2196 // Normal passes can't have pipelines.
2198 formatv("invalid use of '{}' pass as cgscc pipeline", Name).str(),
2200 }
2201
2202// Now expand the basic registered passes from the .inc file.
2203#define CGSCC_PASS(NAME, CREATE_PASS) \
2204 if (Name == NAME) { \
2205 CGPM.addPass(CREATE_PASS); \
2206 return Error::success(); \
2207 }
2208#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2209 if (checkParametrizedPassName(Name, NAME)) { \
2210 auto Params = parsePassParameters(PARSER, Name, NAME); \
2211 if (!Params) \
2212 return Params.takeError(); \
2213 CGPM.addPass(CREATE_PASS(Params.get())); \
2214 return Error::success(); \
2215 }
2216#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
2217 if (Name == "require<" NAME ">") { \
2218 CGPM.addPass(RequireAnalysisPass< \
2219 std::remove_reference_t<decltype(CREATE_PASS)>, \
2220 LazyCallGraph::SCC, CGSCCAnalysisManager, LazyCallGraph &, \
2221 CGSCCUpdateResult &>()); \
2222 return Error::success(); \
2223 } \
2224 if (Name == "invalidate<" NAME ">") { \
2225 CGPM.addPass(InvalidateAnalysisPass< \
2226 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2227 return Error::success(); \
2228 }
2229#define FUNCTION_PASS(NAME, CREATE_PASS) \
2230 if (Name == NAME) { \
2231 if constexpr (std::is_constructible_v< \
2232 std::remove_reference_t<decltype(CREATE_PASS)>, \
2233 const TargetMachine &>) { \
2234 if (!TM) \
2235 return make_error<StringError>( \
2236 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2237 inconvertibleErrorCode()); \
2238 } \
2239 CGPM.addPass(createCGSCCToFunctionPassAdaptor(CREATE_PASS)); \
2240 return Error::success(); \
2241 }
2242#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2243 if (checkParametrizedPassName(Name, NAME)) { \
2244 auto Params = parsePassParameters(PARSER, Name, NAME); \
2245 if (!Params) \
2246 return Params.takeError(); \
2247 auto CreatePass = CREATE_PASS; \
2248 if constexpr (std::is_constructible_v< \
2249 std::remove_reference_t<decltype(CreatePass( \
2250 Params.get()))>, \
2251 const TargetMachine &, \
2252 std::remove_reference_t<decltype(Params.get())>>) { \
2253 if (!TM) { \
2254 return make_error<StringError>( \
2255 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2256 inconvertibleErrorCode()); \
2257 } \
2258 } \
2259 CGPM.addPass(createCGSCCToFunctionPassAdaptor(CREATE_PASS(Params.get()))); \
2260 return Error::success(); \
2261 }
2262#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2263 if (Name == NAME) { \
2264 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
2265 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2266 return Error::success(); \
2267 }
2268#define LOOP_PASS(NAME, CREATE_PASS) \
2269 if (Name == NAME) { \
2270 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
2271 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2272 return Error::success(); \
2273 }
2274#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2275 if (checkParametrizedPassName(Name, NAME)) { \
2276 auto Params = parsePassParameters(PARSER, Name, NAME); \
2277 if (!Params) \
2278 return Params.takeError(); \
2279 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
2280 createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), false))); \
2281 return Error::success(); \
2282 }
2283#include "PassRegistry.def"
2284
2285 for (auto &C : CGSCCPipelineParsingCallbacks)
2286 if (C(Name, CGPM, InnerPipeline))
2287 return Error::success();
2288 return make_error<StringError>(formatv("unknown cgscc pass '{}'", Name).str(),
2290}
2291
2292Error PassBuilder::parseFunctionPass(FunctionPassManager &FPM,
2293 const PipelineElement &E) {
2294 auto &Name = E.Name;
2295 auto &InnerPipeline = E.InnerPipeline;
2296
2297 // First handle complex passes like the pass managers which carry pipelines.
2298 if (!InnerPipeline.empty()) {
2299 if (Name == "function") {
2300 FunctionPassManager NestedFPM;
2301 if (auto Err = parseFunctionPassPipeline(NestedFPM, InnerPipeline))
2302 return Err;
2303 // Add the nested pass manager with the appropriate adaptor.
2304 FPM.addPass(std::move(NestedFPM));
2305 return Error::success();
2306 }
2307 if (Name == "loop" || Name == "loop-mssa") {
2308 LoopPassManager LPM;
2309 if (auto Err = parseLoopPassPipeline(LPM, InnerPipeline))
2310 return Err;
2311 // Add the nested pass manager with the appropriate adaptor.
2312 bool UseMemorySSA = (Name == "loop-mssa");
2313 FPM.addPass(
2314 createFunctionToLoopPassAdaptor(std::move(LPM), UseMemorySSA));
2315 return Error::success();
2316 }
2317 if (Name == "machine-function") {
2319 if (auto Err = parseMachinePassPipeline(MFPM, InnerPipeline))
2320 return Err;
2322 return Error::success();
2323 }
2324
2325 for (auto &C : FunctionPipelineParsingCallbacks)
2326 if (C(Name, FPM, InnerPipeline))
2327 return Error::success();
2328
2329 // Normal passes can't have pipelines.
2331 formatv("invalid use of '{}' pass as function pipeline", Name).str(),
2333 }
2334
2335// Now expand the basic registered passes from the .inc file.
2336#define FUNCTION_PASS(NAME, CREATE_PASS) \
2337 if (Name == NAME) { \
2338 if constexpr (std::is_constructible_v< \
2339 std::remove_reference_t<decltype(CREATE_PASS)>, \
2340 const TargetMachine &>) { \
2341 if (!TM) \
2342 return make_error<StringError>( \
2343 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2344 inconvertibleErrorCode()); \
2345 } \
2346 FPM.addPass(CREATE_PASS); \
2347 return Error::success(); \
2348 }
2349#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2350 if (checkParametrizedPassName(Name, NAME)) { \
2351 auto Params = parsePassParameters(PARSER, Name, NAME); \
2352 if (!Params) \
2353 return Params.takeError(); \
2354 auto CreatePass = CREATE_PASS; \
2355 if constexpr (std::is_constructible_v< \
2356 std::remove_reference_t<decltype(CreatePass( \
2357 Params.get()))>, \
2358 const TargetMachine &, \
2359 std::remove_reference_t<decltype(Params.get())>>) { \
2360 if (!TM) { \
2361 return make_error<StringError>( \
2362 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2363 inconvertibleErrorCode()); \
2364 } \
2365 } \
2366 FPM.addPass(CREATE_PASS(Params.get())); \
2367 return Error::success(); \
2368 }
2369#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
2370 if (Name == "require<" NAME ">") { \
2371 if constexpr (std::is_constructible_v< \
2372 std::remove_reference_t<decltype(CREATE_PASS)>, \
2373 const TargetMachine &>) { \
2374 if (!TM) \
2375 return make_error<StringError>( \
2376 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2377 inconvertibleErrorCode()); \
2378 } \
2379 FPM.addPass( \
2380 RequireAnalysisPass<std::remove_reference_t<decltype(CREATE_PASS)>, \
2381 Function>()); \
2382 return Error::success(); \
2383 } \
2384 if (Name == "invalidate<" NAME ">") { \
2385 FPM.addPass(InvalidateAnalysisPass< \
2386 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2387 return Error::success(); \
2388 }
2389// FIXME: UseMemorySSA is set to false. Maybe we could do things like:
2390// bool UseMemorySSA = !("canon-freeze" || "loop-predication" ||
2391// "guard-widening");
2392// The risk is that it may become obsolete if we're not careful.
2393#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2394 if (Name == NAME) { \
2395 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS, false)); \
2396 return Error::success(); \
2397 }
2398#define LOOP_PASS(NAME, CREATE_PASS) \
2399 if (Name == NAME) { \
2400 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS, false)); \
2401 return Error::success(); \
2402 }
2403#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2404 if (checkParametrizedPassName(Name, NAME)) { \
2405 auto Params = parsePassParameters(PARSER, Name, NAME); \
2406 if (!Params) \
2407 return Params.takeError(); \
2408 FPM.addPass( \
2409 createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), false)); \
2410 return Error::success(); \
2411 }
2412#include "PassRegistry.def"
2413
2414 for (auto &C : FunctionPipelineParsingCallbacks)
2415 if (C(Name, FPM, InnerPipeline))
2416 return Error::success();
2418 formatv("unknown function pass '{}'", Name).str(),
2420}
2421
2422Error PassBuilder::parseLoopPass(LoopPassManager &LPM,
2423 const PipelineElement &E) {
2424 StringRef Name = E.Name;
2425 auto &InnerPipeline = E.InnerPipeline;
2426
2427 // First handle complex passes like the pass managers which carry pipelines.
2428 if (!InnerPipeline.empty()) {
2429 if (Name == "loop") {
2430 LoopPassManager NestedLPM;
2431 if (auto Err = parseLoopPassPipeline(NestedLPM, InnerPipeline))
2432 return Err;
2433 // Add the nested pass manager with the appropriate adaptor.
2434 LPM.addPass(std::move(NestedLPM));
2435 return Error::success();
2436 }
2437
2438 for (auto &C : LoopPipelineParsingCallbacks)
2439 if (C(Name, LPM, InnerPipeline))
2440 return Error::success();
2441
2442 // Normal passes can't have pipelines.
2444 formatv("invalid use of '{}' pass as loop pipeline", Name).str(),
2446 }
2447
2448// Now expand the basic registered passes from the .inc file.
2449#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2450 if (Name == NAME) { \
2451 LPM.addPass(CREATE_PASS); \
2452 return Error::success(); \
2453 }
2454#define LOOP_PASS(NAME, CREATE_PASS) \
2455 if (Name == NAME) { \
2456 LPM.addPass(CREATE_PASS); \
2457 return Error::success(); \
2458 }
2459#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2460 if (checkParametrizedPassName(Name, NAME)) { \
2461 auto Params = parsePassParameters(PARSER, Name, NAME); \
2462 if (!Params) \
2463 return Params.takeError(); \
2464 LPM.addPass(CREATE_PASS(Params.get())); \
2465 return Error::success(); \
2466 }
2467#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
2468 if (Name == "require<" NAME ">") { \
2469 LPM.addPass(RequireAnalysisPass< \
2470 std::remove_reference_t<decltype(CREATE_PASS)>, Loop, \
2471 LoopAnalysisManager, LoopStandardAnalysisResults &, \
2472 LPMUpdater &>()); \
2473 return Error::success(); \
2474 } \
2475 if (Name == "invalidate<" NAME ">") { \
2476 LPM.addPass(InvalidateAnalysisPass< \
2477 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2478 return Error::success(); \
2479 }
2480#include "PassRegistry.def"
2481
2482 for (auto &C : LoopPipelineParsingCallbacks)
2483 if (C(Name, LPM, InnerPipeline))
2484 return Error::success();
2485 return make_error<StringError>(formatv("unknown loop pass '{}'", Name).str(),
2487}
2488
2489Error PassBuilder::parseMachinePass(MachineFunctionPassManager &MFPM,
2490 const PipelineElement &E) {
2491 StringRef Name = E.Name;
2492 // Handle any nested pass managers.
2493 if (!E.InnerPipeline.empty()) {
2494 if (E.Name == "machine-function") {
2496 if (auto Err = parseMachinePassPipeline(NestedPM, E.InnerPipeline))
2497 return Err;
2498 MFPM.addPass(std::move(NestedPM));
2499 return Error::success();
2500 }
2501 return make_error<StringError>("invalid pipeline",
2503 }
2504
2505#define MACHINE_MODULE_PASS(NAME, CREATE_PASS) \
2506 if (Name == NAME) { \
2507 MFPM.addPass(CREATE_PASS); \
2508 return Error::success(); \
2509 }
2510#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
2511 if (Name == NAME) { \
2512 MFPM.addPass(CREATE_PASS); \
2513 return Error::success(); \
2514 }
2515#define MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, \
2516 PARAMS) \
2517 if (checkParametrizedPassName(Name, NAME)) { \
2518 auto Params = parsePassParameters(PARSER, Name, NAME); \
2519 if (!Params) \
2520 return Params.takeError(); \
2521 MFPM.addPass(CREATE_PASS(Params.get())); \
2522 return Error::success(); \
2523 }
2524#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
2525 if (Name == "require<" NAME ">") { \
2526 MFPM.addPass( \
2527 RequireAnalysisPass<std::remove_reference_t<decltype(CREATE_PASS)>, \
2528 MachineFunction>()); \
2529 return Error::success(); \
2530 } \
2531 if (Name == "invalidate<" NAME ">") { \
2532 MFPM.addPass(InvalidateAnalysisPass< \
2533 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2534 return Error::success(); \
2535 }
2536#include "llvm/Passes/MachinePassRegistry.def"
2537
2538 for (auto &C : MachineFunctionPipelineParsingCallbacks)
2539 if (C(Name, MFPM, E.InnerPipeline))
2540 return Error::success();
2542 formatv("unknown machine pass '{}'", Name).str(),
2544}
2545
2546bool PassBuilder::parseAAPassName(AAManager &AA, StringRef Name) {
2547#define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
2548 if (Name == NAME) { \
2549 AA.registerModuleAnalysis< \
2550 std::remove_reference_t<decltype(CREATE_PASS)>>(); \
2551 return true; \
2552 }
2553#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
2554 if (Name == NAME) { \
2555 AA.registerFunctionAnalysis< \
2556 std::remove_reference_t<decltype(CREATE_PASS)>>(); \
2557 return true; \
2558 }
2559#include "PassRegistry.def"
2560
2561 for (auto &C : AAParsingCallbacks)
2562 if (C(Name, AA))
2563 return true;
2564 return false;
2565}
2566
2567Error PassBuilder::parseMachinePassPipeline(
2569 for (const auto &Element : Pipeline) {
2570 if (auto Err = parseMachinePass(MFPM, Element))
2571 return Err;
2572 }
2573 return Error::success();
2574}
2575
2576Error PassBuilder::parseLoopPassPipeline(LoopPassManager &LPM,
2577 ArrayRef<PipelineElement> Pipeline) {
2578 for (const auto &Element : Pipeline) {
2579 if (auto Err = parseLoopPass(LPM, Element))
2580 return Err;
2581 }
2582 return Error::success();
2583}
2584
2585Error PassBuilder::parseFunctionPassPipeline(
2587 for (const auto &Element : Pipeline) {
2588 if (auto Err = parseFunctionPass(FPM, Element))
2589 return Err;
2590 }
2591 return Error::success();
2592}
2593
2594Error PassBuilder::parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
2595 ArrayRef<PipelineElement> Pipeline) {
2596 for (const auto &Element : Pipeline) {
2597 if (auto Err = parseCGSCCPass(CGPM, Element))
2598 return Err;
2599 }
2600 return Error::success();
2601}
2602
2608 MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });
2609 MAM.registerPass([&] { return CGSCCAnalysisManagerModuleProxy(CGAM); });
2610 CGAM.registerPass([&] { return ModuleAnalysisManagerCGSCCProxy(MAM); });
2611 FAM.registerPass([&] { return CGSCCAnalysisManagerFunctionProxy(CGAM); });
2612 FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); });
2613 FAM.registerPass([&] { return LoopAnalysisManagerFunctionProxy(LAM); });
2614 LAM.registerPass([&] { return FunctionAnalysisManagerLoopProxy(FAM); });
2615 if (MFAM) {
2616 MAM.registerPass(
2617 [&] { return MachineFunctionAnalysisManagerModuleProxy(*MFAM); });
2618 FAM.registerPass(
2619 [&] { return MachineFunctionAnalysisManagerFunctionProxy(*MFAM); });
2620 MFAM->registerPass(
2622 MFAM->registerPass(
2624 }
2625}
2626
2627Error PassBuilder::parseModulePassPipeline(ModulePassManager &MPM,
2628 ArrayRef<PipelineElement> Pipeline) {
2629 for (const auto &Element : Pipeline) {
2630 if (auto Err = parseModulePass(MPM, Element))
2631 return Err;
2632 }
2633 return Error::success();
2634}
2635
2636// Primary pass pipeline description parsing routine for a \c ModulePassManager
2637// FIXME: Should this routine accept a TargetMachine or require the caller to
2638// pre-populate the analysis managers with target-specific stuff?
2640 StringRef PipelineText) {
2641 auto Pipeline = parsePipelineText(PipelineText);
2642 if (!Pipeline || Pipeline->empty())
2644 formatv("invalid pipeline '{}'", PipelineText).str(),
2646
2647 // If the first name isn't at the module layer, wrap the pipeline up
2648 // automatically.
2649 StringRef FirstName = Pipeline->front().Name;
2650
2651 if (!isModulePassName(FirstName, ModulePipelineParsingCallbacks)) {
2652 bool UseMemorySSA;
2653 if (isCGSCCPassName(FirstName, CGSCCPipelineParsingCallbacks)) {
2654 Pipeline = {{"cgscc", std::move(*Pipeline)}};
2655 } else if (isFunctionPassName(FirstName,
2656 FunctionPipelineParsingCallbacks)) {
2657 Pipeline = {{"function", std::move(*Pipeline)}};
2658 } else if (isLoopNestPassName(FirstName, LoopPipelineParsingCallbacks,
2659 UseMemorySSA)) {
2660 Pipeline = {{"function", {{UseMemorySSA ? "loop-mssa" : "loop",
2661 std::move(*Pipeline)}}}};
2662 } else if (isLoopPassName(FirstName, LoopPipelineParsingCallbacks,
2663 UseMemorySSA)) {
2664 Pipeline = {{"function", {{UseMemorySSA ? "loop-mssa" : "loop",
2665 std::move(*Pipeline)}}}};
2666 } else if (isMachineFunctionPassName(
2667 FirstName, MachineFunctionPipelineParsingCallbacks)) {
2668 Pipeline = {{"function", {{"machine-function", std::move(*Pipeline)}}}};
2669 } else {
2670 for (auto &C : TopLevelPipelineParsingCallbacks)
2671 if (C(MPM, *Pipeline))
2672 return Error::success();
2673
2674 // Unknown pass or pipeline name!
2675 auto &InnerPipeline = Pipeline->front().InnerPipeline;
2677 formatv("unknown {} name '{}'",
2678 (InnerPipeline.empty() ? "pass" : "pipeline"), FirstName)
2679 .str(),
2681 }
2682 }
2683
2684 if (auto Err = parseModulePassPipeline(MPM, *Pipeline))
2685 return Err;
2686 return Error::success();
2687}
2688
2689// Primary pass pipeline description parsing routine for a \c CGSCCPassManager
2691 StringRef PipelineText) {
2692 auto Pipeline = parsePipelineText(PipelineText);
2693 if (!Pipeline || Pipeline->empty())
2695 formatv("invalid pipeline '{}'", PipelineText).str(),
2697
2698 StringRef FirstName = Pipeline->front().Name;
2699 if (!isCGSCCPassName(FirstName, CGSCCPipelineParsingCallbacks))
2701 formatv("unknown cgscc pass '{}' in pipeline '{}'", FirstName,
2702 PipelineText)
2703 .str(),
2705
2706 if (auto Err = parseCGSCCPassPipeline(CGPM, *Pipeline))
2707 return Err;
2708 return Error::success();
2709}
2710
2711// Primary pass pipeline description parsing routine for a \c
2712// FunctionPassManager
2714 StringRef PipelineText) {
2715 auto Pipeline = parsePipelineText(PipelineText);
2716 if (!Pipeline || Pipeline->empty())
2718 formatv("invalid pipeline '{}'", PipelineText).str(),
2720
2721 StringRef FirstName = Pipeline->front().Name;
2722 if (!isFunctionPassName(FirstName, FunctionPipelineParsingCallbacks))
2724 formatv("unknown function pass '{}' in pipeline '{}'", FirstName,
2725 PipelineText)
2726 .str(),
2728
2729 if (auto Err = parseFunctionPassPipeline(FPM, *Pipeline))
2730 return Err;
2731 return Error::success();
2732}
2733
2734// Primary pass pipeline description parsing routine for a \c LoopPassManager
2736 StringRef PipelineText) {
2737 auto Pipeline = parsePipelineText(PipelineText);
2738 if (!Pipeline || Pipeline->empty())
2740 formatv("invalid pipeline '{}'", PipelineText).str(),
2742
2743 if (auto Err = parseLoopPassPipeline(CGPM, *Pipeline))
2744 return Err;
2745
2746 return Error::success();
2747}
2748
2750 StringRef PipelineText) {
2751 auto Pipeline = parsePipelineText(PipelineText);
2752 if (!Pipeline || Pipeline->empty())
2754 formatv("invalid machine pass pipeline '{}'", PipelineText).str(),
2756
2757 if (auto Err = parseMachinePassPipeline(MFPM, *Pipeline))
2758 return Err;
2759
2760 return Error::success();
2761}
2762
2764 // If the pipeline just consists of the word 'default' just replace the AA
2765 // manager with our default one.
2766 if (PipelineText == "default") {
2768 return Error::success();
2769 }
2770
2771 while (!PipelineText.empty()) {
2772 StringRef Name;
2773 std::tie(Name, PipelineText) = PipelineText.split(',');
2774 if (!parseAAPassName(AA, Name))
2776 formatv("unknown alias analysis name '{}'", Name).str(),
2778 }
2779
2780 return Error::success();
2781}
2782
2783std::optional<RegAllocFilterFunc>
2785 if (FilterName == "all")
2786 return nullptr;
2787 for (auto &C : RegClassFilterParsingCallbacks)
2788 if (auto F = C(FilterName))
2789 return F;
2790 return std::nullopt;
2791}
2792
2794 OS << " " << PassName << "\n";
2795}
2797 raw_ostream &OS) {
2798 OS << " " << PassName << "<" << Params << ">\n";
2799}
2800
2802 // TODO: print pass descriptions when they are available
2803
2804 OS << "Module passes:\n";
2805#define MODULE_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2806#include "PassRegistry.def"
2807
2808 OS << "Module passes with params:\n";
2809#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2810 printPassName(NAME, PARAMS, OS);
2811#include "PassRegistry.def"
2812
2813 OS << "Module analyses:\n";
2814#define MODULE_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2815#include "PassRegistry.def"
2816
2817 OS << "Module alias analyses:\n";
2818#define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2819#include "PassRegistry.def"
2820
2821 OS << "CGSCC passes:\n";
2822#define CGSCC_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2823#include "PassRegistry.def"
2824
2825 OS << "CGSCC passes with params:\n";
2826#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2827 printPassName(NAME, PARAMS, OS);
2828#include "PassRegistry.def"
2829
2830 OS << "CGSCC analyses:\n";
2831#define CGSCC_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2832#include "PassRegistry.def"
2833
2834 OS << "Function passes:\n";
2835#define FUNCTION_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2836#include "PassRegistry.def"
2837
2838 OS << "Function passes with params:\n";
2839#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2840 printPassName(NAME, PARAMS, OS);
2841#include "PassRegistry.def"
2842
2843 OS << "Function analyses:\n";
2844#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2845#include "PassRegistry.def"
2846
2847 OS << "Function alias analyses:\n";
2848#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2849#include "PassRegistry.def"
2850
2851 OS << "LoopNest passes:\n";
2852#define LOOPNEST_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2853#include "PassRegistry.def"
2854
2855 OS << "Loop passes:\n";
2856#define LOOP_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2857#include "PassRegistry.def"
2858
2859 OS << "Loop passes with params:\n";
2860#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2861 printPassName(NAME, PARAMS, OS);
2862#include "PassRegistry.def"
2863
2864 OS << "Loop analyses:\n";
2865#define LOOP_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2866#include "PassRegistry.def"
2867
2868 OS << "Machine module passes (WIP):\n";
2869#define MACHINE_MODULE_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2870#include "llvm/Passes/MachinePassRegistry.def"
2871
2872 OS << "Machine function passes (WIP):\n";
2873#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2874#include "llvm/Passes/MachinePassRegistry.def"
2875
2876 OS << "Machine function analyses (WIP):\n";
2877#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2878#include "llvm/Passes/MachinePassRegistry.def"
2879}
2880
2882 const std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>)>
2883 &C) {
2884 TopLevelPipelineParsingCallbacks.push_back(C);
2885}
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 contains the declaration of the MachineKCFI class, which is a Machine Pass that implements ...
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...
This file provides the interface for LLVM's Scalar Replacement of Aggregates pass.
static const char * name
This file provides the interface for the pseudo probe implementation for AutoFDO.
This file provides the interface for the sampled PGO loader pass.
This is the interface for a SCEV-based alias analysis.
This pass converts vector operations into scalar operations (or, optionally, operations on smaller ve...
This is the interface for a metadata-based scoped no-alias analysis.
This file contains the declaration of the SelectOptimizePass class, its corresponding pass name is se...
This file provides the interface for the pass responsible for both simplifying and canonicalizing the...
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
This pass strips convergence intrinsics and operand bundles as those are only useful when modifying t...
Target-Independent Code Generator Pass Configuration Options pass.
This pass exposes codegen information to IR-level passes.
This is the interface for a metadata-based TBAA.
Defines an IR pass for type promotion.
LLVM IR instance of the generic uniformity analysis.
static const char PassName[]
A manager for alias analyses.
Class for arbitrary precision integers.
Definition APInt.h:78
uint64_t getZExtValue() const
Get zero extended value.
Definition APInt.h:1563
int64_t getSExtValue() const
Get sign extended value.
Definition APInt.h:1585
bool registerPass(PassBuilderT &&PassBuilder)
Register an analysis pass with the manager.
PassT::Result & getResult(IRUnitT &IR, ExtraArgTs... ExtraArgs)
Get the result of an analysis pass for a given IR unit.
Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; assumes that the block is well-formed.
Definition BasicBlock.h:237
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
Tagged union holding either a T or a Error.
Definition Error.h:485
static LLVM_ABI GlobalAlias * create(Type *Ty, unsigned AddressSpace, LinkageTypes Linkage, const Twine &Name, Constant *Aliasee, Module *Parent)
If a parent module is specified, the alias is automatically inserted into the end of the specified mo...
Definition Globals.cpp:621
A smart pointer to a reference-counted object that inherits from RefCountedBase or ThreadSafeRefCount...
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
This analysis create MachineFunction for given Function.
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const MachineFunctionProperties & getProperties() const
Get the function properties.
LLVM_ABI Register createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
static LLVM_ABI const OptimizationLevel O3
Optimize for fast execution as much as possible.
static LLVM_ABI const OptimizationLevel O0
Disable as many optimizations as possible.
static LLVM_ABI const OptimizationLevel O2
Optimize for fast execution as much as possible without triggering significant incremental compile ti...
static LLVM_ABI const OptimizationLevel O1
Optimize quickly without destroying debuggability.
This class provides access to building LLVM's passes.
LLVM_ABI void printPassNames(raw_ostream &OS)
Print pass names.
static bool checkParametrizedPassName(StringRef Name, StringRef PassName)
LLVM_ABI AAManager buildDefaultAAPipeline()
Build the default AAManager with the default alias analysis pipeline registered.
LLVM_ABI Error parseAAPipeline(AAManager &AA, StringRef PipelineText)
Parse a textual alias analysis pipeline into the provided AA manager.
LLVM_ABI void registerLoopAnalyses(LoopAnalysisManager &LAM)
Registers all available loop analysis passes.
LLVM_ABI std::optional< RegAllocFilterFunc > parseRegAllocFilter(StringRef RegAllocFilterName)
Parse RegAllocFilterName to get RegAllocFilterFunc.
LLVM_ABI void crossRegisterProxies(LoopAnalysisManager &LAM, FunctionAnalysisManager &FAM, CGSCCAnalysisManager &CGAM, ModuleAnalysisManager &MAM, MachineFunctionAnalysisManager *MFAM=nullptr)
Cross register the analysis managers through their proxies.
LLVM_ABI PassBuilder(TargetMachine *TM=nullptr, PipelineTuningOptions PTO=PipelineTuningOptions(), std::optional< PGOOptions > PGOOpt=std::nullopt, PassInstrumentationCallbacks *PIC=nullptr, IntrusiveRefCntPtr< vfs::FileSystem > FS=vfs::getRealFileSystem())
LLVM_ABI Error parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText)
Parse a textual pass pipeline description into a ModulePassManager.
void registerPipelineParsingCallback(const std::function< bool(StringRef Name, CGSCCPassManager &, ArrayRef< PipelineElement >)> &C)
{{@ Register pipeline parsing callbacks with this pass builder instance.
LLVM_ABI void registerModuleAnalyses(ModuleAnalysisManager &MAM)
Registers all available module analysis passes.
LLVM_ABI void registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM)
Registers all available CGSCC analysis passes.
static LLVM_ABI Expected< bool > parseSinglePassOption(StringRef Params, StringRef OptionName, StringRef PassName)
Handle passes only accept one bool-valued parameter.
LLVM_ABI void registerMachineFunctionAnalyses(MachineFunctionAnalysisManager &MFAM)
Registers all available machine function analysis passes.
LLVM_ABI void registerParseTopLevelPipelineCallback(const std::function< bool(ModulePassManager &, ArrayRef< PipelineElement >)> &C)
Register a callback for a top-level pipeline entry.
LLVM_ABI void registerFunctionAnalyses(FunctionAnalysisManager &FAM)
Registers all available function analysis passes.
This class manages callbacks registration, as well as provides a way for PassInstrumentation to pass ...
LLVM_ATTRIBUTE_MINSIZE std::enable_if_t<!std::is_same_v< PassT, PassManager > > addPass(PassT &&Pass)
Tunable parameters for passes in the default pipelines.
Definition PassBuilder.h:41
bool SLPVectorization
Tuning option to enable/disable slp loop vectorization, set based on opt level.
Definition PassBuilder.h:56
bool LoopVectorization
Tuning option to enable/disable loop vectorization, set based on opt level.
Definition PassBuilder.h:52
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition Analysis.h:115
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition StringRef.h:730
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
Definition StringRef.h:490
std::string str() const
Get the contents as an std::string.
Definition StringRef.h:222
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition StringRef.h:258
constexpr bool empty() const
Check if the string is empty.
Definition StringRef.h:141
char front() const
Get the first character in the string.
Definition StringRef.h:147
bool consume_front(char Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
Definition StringRef.h:655
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
Primary interface to the complete machine description for the target machine.
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
self_iterator getIterator()
Definition ilist_node.h:123
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
Interfaces for registering analysis passes, producing common pass manager configurations,...
Abstract Attribute helper functions.
Definition Attributor.h:165
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
std::optional< CodeGenOptLevel > getLevel(int OL)
Get the Level identified by the integer OL.
Definition CodeGen.h:93
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:81
DXILDebugInfoMap run(Module &M)
DropTestKind
Specifies how to drop type tests.
@ All
Drop only llvm.assumes using type test value.
NodeAddr< FuncNode * > Func
Definition RDFGraph.h:393
This is an optimization pass for GlobalISel generic memory operations.
OuterAnalysisManagerProxy< CGSCCAnalysisManager, Function > CGSCCAnalysisManagerFunctionProxy
A proxy from a CGSCCAnalysisManager to a Function.
OuterAnalysisManagerProxy< ModuleAnalysisManager, MachineFunction > ModuleAnalysisManagerMachineFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
ModuleToFunctionPassAdaptor createModuleToFunctionPassAdaptor(FunctionPassT &&Pass, bool EagerlyInvalidate=false)
A function to deduce a function pass type and wrap it in the templated adaptor.
DevirtSCCRepeatedPass createDevirtSCCRepeatedPass(CGSCCPassT &&Pass, int MaxIterations)
A function to deduce a function pass type and wrap it in the templated adaptor.
OuterAnalysisManagerProxy< ModuleAnalysisManager, Function > ModuleAnalysisManagerFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
LLVM_ABI std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
Definition Error.cpp:94
InnerAnalysisManagerProxy< FunctionAnalysisManager, Module > FunctionAnalysisManagerModuleProxy
Provide the FunctionAnalysisManager to Module proxy.
InnerAnalysisManagerProxy< LoopAnalysisManager, Function > LoopAnalysisManagerFunctionProxy
A proxy from a LoopAnalysisManager to a Function.
AnalysisManager< MachineFunction > MachineFunctionAnalysisManager
Error createStringError(std::error_code EC, char const *Fmt, const Ts &... Vals)
Create formatted StringError object.
Definition Error.h:1321
PassManager< LazyCallGraph::SCC, CGSCCAnalysisManager, LazyCallGraph &, CGSCCUpdateResult & > CGSCCPassManager
The CGSCC pass manager.
AnalysisManager< LazyCallGraph::SCC, LazyCallGraph & > CGSCCAnalysisManager
The CGSCC analysis manager.
AnalysisManager< Loop, LoopStandardAnalysisResults & > LoopAnalysisManager
The loop analysis manager.
PassManager< Loop, LoopAnalysisManager, LoopStandardAnalysisResults &, LPMUpdater & > LoopPassManager
The Loop pass manager.
ModuleToPostOrderCGSCCPassAdaptor createModuleToPostOrderCGSCCPassAdaptor(CGSCCPassT &&Pass)
A function to deduce a function pass type and wrap it in the templated adaptor.
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:1916
PassManager< MachineFunction > MachineFunctionPassManager
Convenience typedef for a pass manager over functions.
LLVM_ABI bool applyDebugifyMetadataToMachineFunction(DIBuilder &DIB, Function &F, llvm::function_ref< MachineFunction *(Function &)> GetMF)
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI std::optional< AllocTokenMode > getAllocTokenModeFromString(StringRef Name)
Returns the AllocTokenMode from its canonical string name; if an invalid name was provided returns nu...
@ Detailed
Hash with opcode only.
@ CallTargetIgnored
Hash with opcode and operands.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition MIRParser.h:39
@ Enable
Enable colors.
Definition WithColor.h:47
LLVM_ABI void reportFatalUsageError(Error Err)
Report a fatal error that does not indicate a bug in LLVM.
Definition Error.cpp:177
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:874
#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 for passes that can be skipped.