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 LoopUnroll pass.
835Expected<LoopUnrollOptions> parseLoopUnrollOptions(StringRef Params) {
836 LoopUnrollOptions UnrollOpts;
837 while (!Params.empty()) {
838 StringRef ParamName;
839 std::tie(ParamName, Params) = Params.split(';');
840 std::optional<OptimizationLevel> OptLevel = parseOptLevel(ParamName);
841 if (OptLevel) {
842 UnrollOpts.setOptLevel(OptLevel->getSpeedupLevel());
843 continue;
844 }
845 if (ParamName.consume_front("full-unroll-max=")) {
846 int Count;
847 if (ParamName.getAsInteger(0, Count))
849 formatv("invalid LoopUnrollPass parameter '{}'", ParamName).str(),
851 UnrollOpts.setFullUnrollMaxCount(Count);
852 continue;
853 }
854
855 bool Enable = !ParamName.consume_front("no-");
856 if (ParamName == "partial") {
857 UnrollOpts.setPartial(Enable);
858 } else if (ParamName == "peeling") {
859 UnrollOpts.setPeeling(Enable);
860 } else if (ParamName == "profile-peeling") {
861 UnrollOpts.setProfileBasedPeeling(Enable);
862 } else if (ParamName == "runtime") {
863 UnrollOpts.setRuntime(Enable);
864 } else if (ParamName == "upperbound") {
865 UnrollOpts.setUpperBound(Enable);
866 } else {
868 formatv("invalid LoopUnrollPass parameter '{}'", ParamName).str(),
870 }
871 }
872 return UnrollOpts;
873}
874
875Expected<bool> parseGlobalDCEPassOptions(StringRef Params) {
877 Params, "vfe-linkage-unit-visibility", "GlobalDCE");
878}
879
880Expected<bool> parseCGProfilePassOptions(StringRef Params) {
881 return PassBuilder::parseSinglePassOption(Params, "in-lto-post-link",
882 "CGProfile");
883}
884
885Expected<bool> parseInlinerPassOptions(StringRef Params) {
886 return PassBuilder::parseSinglePassOption(Params, "only-mandatory",
887 "InlinerPass");
888}
889
890Expected<bool> parseCoroSplitPassOptions(StringRef Params) {
891 return PassBuilder::parseSinglePassOption(Params, "reuse-storage",
892 "CoroSplitPass");
893}
894
895Expected<bool> parsePostOrderFunctionAttrsPassOptions(StringRef Params) {
897 Params, "skip-non-recursive-function-attrs", "PostOrderFunctionAttrs");
898}
899
900Expected<bool> parseEarlyCSEPassOptions(StringRef Params) {
901 return PassBuilder::parseSinglePassOption(Params, "memssa", "EarlyCSE");
902}
903
904Expected<bool> parseEntryExitInstrumenterPassOptions(StringRef Params) {
905 return PassBuilder::parseSinglePassOption(Params, "post-inline",
906 "EntryExitInstrumenter");
907}
908
909Expected<bool> parseDropUnnecessaryAssumesPassOptions(StringRef Params) {
910 return PassBuilder::parseSinglePassOption(Params, "drop-deref",
911 "DropUnnecessaryAssumes");
912}
913
914Expected<bool> parseLoopExtractorPassOptions(StringRef Params) {
915 return PassBuilder::parseSinglePassOption(Params, "single", "LoopExtractor");
916}
917
918Expected<bool> parseLowerMatrixIntrinsicsPassOptions(StringRef Params) {
919 return PassBuilder::parseSinglePassOption(Params, "minimal",
920 "LowerMatrixIntrinsics");
921}
922
923Expected<IRNormalizerOptions> parseIRNormalizerPassOptions(StringRef Params) {
925 while (!Params.empty()) {
926 StringRef ParamName;
927 std::tie(ParamName, Params) = Params.split(';');
928
929 bool Enable = !ParamName.consume_front("no-");
930 if (ParamName == "preserve-order")
931 Result.PreserveOrder = Enable;
932 else if (ParamName == "rename-all")
933 Result.RenameAll = Enable;
934 else if (ParamName == "fold-all") // FIXME: Name mismatch
935 Result.FoldPreOutputs = Enable;
936 else if (ParamName == "reorder-operands")
937 Result.ReorderOperands = Enable;
938 else {
940 formatv("invalid normalize pass parameter '{}'", ParamName).str(),
942 }
943 }
944
945 return Result;
946}
947
948Expected<AddressSanitizerOptions> parseASanPassOptions(StringRef Params) {
950 while (!Params.empty()) {
951 StringRef ParamName;
952 std::tie(ParamName, Params) = Params.split(';');
953
954 if (ParamName == "kernel") {
955 Result.CompileKernel = true;
956 } else if (ParamName == "use-after-scope") {
957 Result.UseAfterScope = true;
958 } else {
960 formatv("invalid AddressSanitizer pass parameter '{}'", ParamName)
961 .str(),
963 }
964 }
965 return Result;
966}
967
968Expected<HWAddressSanitizerOptions> parseHWASanPassOptions(StringRef Params) {
970 while (!Params.empty()) {
971 StringRef ParamName;
972 std::tie(ParamName, Params) = Params.split(';');
973
974 if (ParamName == "recover") {
975 Result.Recover = true;
976 } else if (ParamName == "kernel") {
977 Result.CompileKernel = true;
978 } else {
980 formatv("invalid HWAddressSanitizer pass parameter '{}'", ParamName)
981 .str(),
983 }
984 }
985 return Result;
986}
987
989parseDropTypeTestsPassOptions(StringRef Params) {
991 while (!Params.empty()) {
992 StringRef ParamName;
993 std::tie(ParamName, Params) = Params.split(';');
994
995 if (ParamName == "all") {
997 } else if (ParamName == "assume") {
999 } else {
1001 formatv("invalid DropTypeTestsPass parameter '{}'", ParamName).str(),
1003 }
1004 }
1005 return Result;
1006}
1007
1008Expected<EmbedBitcodeOptions> parseEmbedBitcodePassOptions(StringRef Params) {
1010 while (!Params.empty()) {
1011 StringRef ParamName;
1012 std::tie(ParamName, Params) = Params.split(';');
1013
1014 if (ParamName == "thinlto") {
1015 Result.IsThinLTO = true;
1016 } else if (ParamName == "emit-summary") {
1017 Result.EmitLTOSummary = true;
1018 } else {
1020 formatv("invalid EmbedBitcode pass parameter '{}'", ParamName).str(),
1022 }
1023 }
1024 return Result;
1025}
1026
1028parseLowerAllowCheckPassOptions(StringRef Params) {
1030 while (!Params.empty()) {
1031 StringRef ParamName;
1032 std::tie(ParamName, Params) = Params.split(';');
1033
1034 // Format is <cutoffs[1,2,3]=70000;cutoffs[5,6,8]=90000>
1035 //
1036 // Parsing allows duplicate indices (last one takes precedence).
1037 // It would technically be in spec to specify
1038 // cutoffs[0]=70000,cutoffs[1]=90000,cutoffs[0]=80000,...
1039 if (ParamName.starts_with("cutoffs[")) {
1040 StringRef IndicesStr;
1041 StringRef CutoffStr;
1042
1043 std::tie(IndicesStr, CutoffStr) = ParamName.split("]=");
1044 // cutoffs[1,2,3
1045 // 70000
1046
1047 int cutoff;
1048 if (CutoffStr.getAsInteger(0, cutoff))
1050 formatv("invalid LowerAllowCheck pass cutoffs parameter '{}' ({})",
1051 CutoffStr, Params)
1052 .str(),
1054
1055 if (!IndicesStr.consume_front("cutoffs[") || IndicesStr == "")
1057 formatv("invalid LowerAllowCheck pass index parameter '{}' ({})",
1058 IndicesStr, CutoffStr)
1059 .str(),
1061
1062 while (IndicesStr != "") {
1063 StringRef firstIndexStr;
1064 std::tie(firstIndexStr, IndicesStr) = IndicesStr.split('|');
1065
1066 unsigned int index;
1067 if (firstIndexStr.getAsInteger(0, index))
1069 formatv(
1070 "invalid LowerAllowCheck pass index parameter '{}' ({}) {}",
1071 firstIndexStr, IndicesStr)
1072 .str(),
1074
1075 // In the common case (sequentially increasing indices), we will issue
1076 // O(n) resize requests. We assume the underlying data structure has
1077 // O(1) runtime for each added element.
1078 if (index >= Result.cutoffs.size())
1079 Result.cutoffs.resize(index + 1, 0);
1080
1081 Result.cutoffs[index] = cutoff;
1082 }
1083 } else if (ParamName.starts_with("runtime_check")) {
1084 StringRef ValueString;
1085 std::tie(std::ignore, ValueString) = ParamName.split("=");
1086 int runtime_check;
1087 if (ValueString.getAsInteger(0, runtime_check)) {
1089 formatv("invalid LowerAllowCheck pass runtime_check parameter '{}' "
1090 "({})",
1091 ValueString, Params)
1092 .str(),
1094 }
1095 Result.runtime_check = runtime_check;
1096 } else {
1098 formatv("invalid LowerAllowCheck pass parameter '{}'", ParamName)
1099 .str(),
1101 }
1102 }
1103
1104 return Result;
1105}
1106
1107Expected<MemorySanitizerOptions> parseMSanPassOptions(StringRef Params) {
1109 while (!Params.empty()) {
1110 StringRef ParamName;
1111 std::tie(ParamName, Params) = Params.split(';');
1112
1113 if (ParamName == "recover") {
1114 Result.Recover = true;
1115 } else if (ParamName == "kernel") {
1116 Result.Kernel = true;
1117 } else if (ParamName.consume_front("track-origins=")) {
1118 if (ParamName.getAsInteger(0, Result.TrackOrigins))
1120 formatv("invalid argument to MemorySanitizer pass track-origins "
1121 "parameter: '{}'",
1122 ParamName)
1123 .str(),
1125 } else if (ParamName == "eager-checks") {
1126 Result.EagerChecks = true;
1127 } else {
1129 formatv("invalid MemorySanitizer pass parameter '{}'", ParamName)
1130 .str(),
1132 }
1133 }
1134 return Result;
1135}
1136
1137Expected<AllocTokenOptions> parseAllocTokenPassOptions(StringRef Params) {
1139 while (!Params.empty()) {
1140 StringRef ParamName;
1141 std::tie(ParamName, Params) = Params.split(';');
1142
1143 if (ParamName.consume_front("mode=")) {
1144 if (auto Mode = getAllocTokenModeFromString(ParamName))
1145 Result.Mode = *Mode;
1146 else
1148 formatv("invalid argument to AllocToken pass mode "
1149 "parameter: '{}'",
1150 ParamName)
1151 .str(),
1153 } else {
1155 formatv("invalid AllocToken pass parameter '{}'", ParamName).str(),
1157 }
1158 }
1159 return Result;
1160}
1161
1162/// Parser of parameters for SimplifyCFG pass.
1163Expected<SimplifyCFGOptions> parseSimplifyCFGOptions(StringRef Params) {
1165 while (!Params.empty()) {
1166 StringRef ParamName;
1167 std::tie(ParamName, Params) = Params.split(';');
1168
1169 bool Enable = !ParamName.consume_front("no-");
1170 if (ParamName == "speculate-blocks") {
1171 Result.speculateBlocks(Enable);
1172 } else if (ParamName == "simplify-cond-branch") {
1173 Result.setSimplifyCondBranch(Enable);
1174 } else if (ParamName == "forward-switch-cond") {
1175 Result.forwardSwitchCondToPhi(Enable);
1176 } else if (ParamName == "switch-range-to-icmp") {
1177 Result.convertSwitchRangeToICmp(Enable);
1178 } else if (ParamName == "switch-to-arithmetic") {
1179 Result.convertSwitchToArithmetic(Enable);
1180 } else if (ParamName == "switch-to-lookup") {
1181 Result.convertSwitchToLookupTable(Enable);
1182 } else if (ParamName == "keep-loops") {
1183 Result.needCanonicalLoops(Enable);
1184 } else if (ParamName == "hoist-common-insts") {
1185 Result.hoistCommonInsts(Enable);
1186 } else if (ParamName == "hoist-loads-stores-with-cond-faulting") {
1187 Result.hoistLoadsStoresWithCondFaulting(Enable);
1188 } else if (ParamName == "sink-common-insts") {
1189 Result.sinkCommonInsts(Enable);
1190 } else if (ParamName == "speculate-unpredictables") {
1191 Result.speculateUnpredictables(Enable);
1192 } else if (Enable && ParamName.consume_front("bonus-inst-threshold=")) {
1193 APInt BonusInstThreshold;
1194 if (ParamName.getAsInteger(0, BonusInstThreshold))
1196 formatv("invalid argument to SimplifyCFG pass bonus-threshold "
1197 "parameter: '{}'",
1198 ParamName)
1199 .str(),
1201 Result.bonusInstThreshold(BonusInstThreshold.getSExtValue());
1202 } else {
1204 formatv("invalid SimplifyCFG pass parameter '{}'", ParamName).str(),
1206 }
1207 }
1208 return Result;
1209}
1210
1211Expected<InstCombineOptions> parseInstCombineOptions(StringRef Params) {
1213 // When specifying "instcombine" in -passes enable fix-point verification by
1214 // default, as this is what most tests should use.
1215 Result.setVerifyFixpoint(true);
1216 while (!Params.empty()) {
1217 StringRef ParamName;
1218 std::tie(ParamName, Params) = Params.split(';');
1219
1220 bool Enable = !ParamName.consume_front("no-");
1221 if (ParamName == "verify-fixpoint") {
1222 Result.setVerifyFixpoint(Enable);
1223 } else if (Enable && ParamName.consume_front("max-iterations=")) {
1224 APInt MaxIterations;
1225 if (ParamName.getAsInteger(0, MaxIterations))
1227 formatv("invalid argument to InstCombine pass max-iterations "
1228 "parameter: '{}'",
1229 ParamName)
1230 .str(),
1232 Result.setMaxIterations((unsigned)MaxIterations.getZExtValue());
1233 } else {
1235 formatv("invalid InstCombine pass parameter '{}'", ParamName).str(),
1237 }
1238 }
1239 return Result;
1240}
1241
1242/// Parser of parameters for LoopVectorize pass.
1243Expected<LoopVectorizeOptions> parseLoopVectorizeOptions(StringRef Params) {
1245 while (!Params.empty()) {
1246 StringRef ParamName;
1247 std::tie(ParamName, Params) = Params.split(';');
1248
1249 bool Enable = !ParamName.consume_front("no-");
1250 if (ParamName == "interleave-forced-only") {
1252 } else if (ParamName == "vectorize-forced-only") {
1254 } else {
1256 formatv("invalid LoopVectorize parameter '{}'", ParamName).str(),
1258 }
1259 }
1260 return Opts;
1261}
1262
1263Expected<std::pair<bool, bool>> parseLoopUnswitchOptions(StringRef Params) {
1264 std::pair<bool, bool> Result = {false, true};
1265 while (!Params.empty()) {
1266 StringRef ParamName;
1267 std::tie(ParamName, Params) = Params.split(';');
1268
1269 bool Enable = !ParamName.consume_front("no-");
1270 if (ParamName == "nontrivial") {
1271 Result.first = Enable;
1272 } else if (ParamName == "trivial") {
1273 Result.second = Enable;
1274 } else {
1276 formatv("invalid LoopUnswitch pass parameter '{}'", ParamName).str(),
1278 }
1279 }
1280 return Result;
1281}
1282
1283Expected<LICMOptions> parseLICMOptions(StringRef Params) {
1285 while (!Params.empty()) {
1286 StringRef ParamName;
1287 std::tie(ParamName, Params) = Params.split(';');
1288
1289 bool Enable = !ParamName.consume_front("no-");
1290 if (ParamName == "allowspeculation") {
1291 Result.AllowSpeculation = Enable;
1292 } else {
1294 formatv("invalid LICM pass parameter '{}'", ParamName).str(),
1296 }
1297 }
1298 return Result;
1299}
1300
1301struct LoopRotateOptions {
1302 bool EnableHeaderDuplication = true;
1303 bool PrepareForLTO = false;
1304 bool CheckExitCount = false;
1305};
1306
1307Expected<LoopRotateOptions> parseLoopRotateOptions(StringRef Params) {
1308 LoopRotateOptions Result;
1309 while (!Params.empty()) {
1310 StringRef ParamName;
1311 std::tie(ParamName, Params) = Params.split(';');
1312
1313 bool Enable = !ParamName.consume_front("no-");
1314 if (ParamName == "header-duplication") {
1315 Result.EnableHeaderDuplication = Enable;
1316 } else if (ParamName == "prepare-for-lto") {
1317 Result.PrepareForLTO = Enable;
1318 } else if (ParamName == "check-exit-count") {
1319 Result.CheckExitCount = Enable;
1320 } else {
1322 formatv("invalid LoopRotate pass parameter '{}'", ParamName).str(),
1324 }
1325 }
1326 return Result;
1327}
1328
1329Expected<bool> parseMergedLoadStoreMotionOptions(StringRef Params) {
1330 bool Result = false;
1331 while (!Params.empty()) {
1332 StringRef ParamName;
1333 std::tie(ParamName, Params) = Params.split(';');
1334
1335 bool Enable = !ParamName.consume_front("no-");
1336 if (ParamName == "split-footer-bb") {
1337 Result = Enable;
1338 } else {
1340 formatv("invalid MergedLoadStoreMotion pass parameter '{}'",
1341 ParamName)
1342 .str(),
1344 }
1345 }
1346 return Result;
1347}
1348
1349Expected<GVNOptions> parseGVNOptions(StringRef Params) {
1351 while (!Params.empty()) {
1352 StringRef ParamName;
1353 std::tie(ParamName, Params) = Params.split(';');
1354
1355 bool Enable = !ParamName.consume_front("no-");
1356 if (ParamName == "scalar-pre") {
1357 Result.setScalarPRE(Enable);
1358 } else if (ParamName == "load-pre") {
1359 Result.setLoadPRE(Enable);
1360 } else if (ParamName == "split-backedge-load-pre") {
1361 Result.setLoadPRESplitBackedge(Enable);
1362 } else if (ParamName == "memdep") {
1363 // MemDep and MemorySSA are mutually exclusive.
1364 Result.setMemDep(Enable);
1365 Result.setMemorySSA(!Enable);
1366 } else if (ParamName == "memoryssa") {
1367 // MemDep and MemorySSA are mutually exclusive.
1368 Result.setMemorySSA(Enable);
1369 Result.setMemDep(!Enable);
1370 } else {
1372 formatv("invalid GVN pass parameter '{}'", ParamName).str(),
1374 }
1375 }
1376 return Result;
1377}
1378
1379Expected<IPSCCPOptions> parseIPSCCPOptions(StringRef Params) {
1381 while (!Params.empty()) {
1382 StringRef ParamName;
1383 std::tie(ParamName, Params) = Params.split(';');
1384
1385 bool Enable = !ParamName.consume_front("no-");
1386 if (ParamName == "func-spec")
1387 Result.setFuncSpec(Enable);
1388 else
1390 formatv("invalid IPSCCP pass parameter '{}'", ParamName).str(),
1392 }
1393 return Result;
1394}
1395
1396Expected<ScalarizerPassOptions> parseScalarizerOptions(StringRef Params) {
1398 while (!Params.empty()) {
1399 StringRef ParamName;
1400 std::tie(ParamName, Params) = Params.split(';');
1401
1402 if (ParamName.consume_front("min-bits=")) {
1403 if (ParamName.getAsInteger(0, Result.ScalarizeMinBits)) {
1405 formatv("invalid argument to Scalarizer pass min-bits "
1406 "parameter: '{}'",
1407 ParamName)
1408 .str(),
1410 }
1411
1412 continue;
1413 }
1414
1415 bool Enable = !ParamName.consume_front("no-");
1416 if (ParamName == "load-store")
1417 Result.ScalarizeLoadStore = Enable;
1418 else if (ParamName == "variable-insert-extract")
1419 Result.ScalarizeVariableInsertExtract = Enable;
1420 else {
1422 formatv("invalid Scalarizer pass parameter '{}'", ParamName).str(),
1424 }
1425 }
1426
1427 return Result;
1428}
1429
1430Expected<SROAOptions> parseSROAOptions(StringRef Params) {
1431 if (Params.empty() || Params == "modify-cfg")
1433 if (Params == "preserve-cfg")
1436 formatv("invalid SROA pass parameter '{}' (either preserve-cfg or "
1437 "modify-cfg can be specified)",
1438 Params)
1439 .str(),
1441}
1442
1444parseStackLifetimeOptions(StringRef Params) {
1446 while (!Params.empty()) {
1447 StringRef ParamName;
1448 std::tie(ParamName, Params) = Params.split(';');
1449
1450 if (ParamName == "may") {
1452 } else if (ParamName == "must") {
1454 } else {
1456 formatv("invalid StackLifetime parameter '{}'", ParamName).str(),
1458 }
1459 }
1460 return Result;
1461}
1462
1463Expected<bool> parseDependenceAnalysisPrinterOptions(StringRef Params) {
1464 return PassBuilder::parseSinglePassOption(Params, "normalized-results",
1465 "DependenceAnalysisPrinter");
1466}
1467
1468Expected<bool> parseSeparateConstOffsetFromGEPPassOptions(StringRef Params) {
1469 return PassBuilder::parseSinglePassOption(Params, "lower-gep",
1470 "SeparateConstOffsetFromGEP");
1471}
1472
1473Expected<bool> parseStructurizeCFGPassOptions(StringRef Params) {
1474 return PassBuilder::parseSinglePassOption(Params, "skip-uniform-regions",
1475 "StructurizeCFG");
1476}
1477
1479parseFunctionSimplificationPipelineOptions(StringRef Params) {
1480 std::optional<OptimizationLevel> L = parseOptLevel(Params);
1481 if (!L || *L == OptimizationLevel::O0) {
1483 formatv("invalid function-simplification parameter '{}'", Params).str(),
1485 };
1486 return *L;
1487}
1488
1489Expected<bool> parseMemorySSAPrinterPassOptions(StringRef Params) {
1490 return PassBuilder::parseSinglePassOption(Params, "no-ensure-optimized-uses",
1491 "MemorySSAPrinterPass");
1492}
1493
1494Expected<bool> parseSpeculativeExecutionPassOptions(StringRef Params) {
1495 return PassBuilder::parseSinglePassOption(Params, "only-if-divergent-target",
1496 "SpeculativeExecutionPass");
1497}
1498
1499Expected<std::string> parseMemProfUsePassOptions(StringRef Params) {
1500 std::string Result;
1501 while (!Params.empty()) {
1502 StringRef ParamName;
1503 std::tie(ParamName, Params) = Params.split(';');
1504
1505 if (ParamName.consume_front("profile-filename=")) {
1506 Result = ParamName.str();
1507 } else {
1509 formatv("invalid MemProfUse pass parameter '{}'", ParamName).str(),
1511 }
1512 }
1513 return Result;
1514}
1515
1517parseStructuralHashPrinterPassOptions(StringRef Params) {
1518 if (Params.empty())
1520 if (Params == "detailed")
1522 if (Params == "call-target-ignored")
1525 formatv("invalid structural hash printer parameter '{}'", Params).str(),
1527}
1528
1529Expected<bool> parseWinEHPrepareOptions(StringRef Params) {
1530 return PassBuilder::parseSinglePassOption(Params, "demote-catchswitch-only",
1531 "WinEHPreparePass");
1532}
1533
1534Expected<GlobalMergeOptions> parseGlobalMergeOptions(StringRef Params) {
1536 while (!Params.empty()) {
1537 StringRef ParamName;
1538 std::tie(ParamName, Params) = Params.split(';');
1539
1540 bool Enable = !ParamName.consume_front("no-");
1541 if (ParamName == "group-by-use")
1542 Result.GroupByUse = Enable;
1543 else if (ParamName == "ignore-single-use")
1544 Result.IgnoreSingleUse = Enable;
1545 else if (ParamName == "merge-const")
1546 Result.MergeConstantGlobals = Enable;
1547 else if (ParamName == "merge-const-aggressive")
1548 Result.MergeConstAggressive = Enable;
1549 else if (ParamName == "merge-external")
1550 Result.MergeExternal = Enable;
1551 else if (ParamName.consume_front("max-offset=")) {
1552 if (ParamName.getAsInteger(0, Result.MaxOffset))
1554 formatv("invalid GlobalMergePass parameter '{}'", ParamName).str(),
1556 } else {
1558 formatv("invalid global-merge pass parameter '{}'", Params).str(),
1560 }
1561 }
1562 return Result;
1563}
1564
1565Expected<SmallVector<std::string, 0>> parseInternalizeGVs(StringRef Params) {
1566 SmallVector<std::string, 1> PreservedGVs;
1567 while (!Params.empty()) {
1568 StringRef ParamName;
1569 std::tie(ParamName, Params) = Params.split(';');
1570
1571 if (ParamName.consume_front("preserve-gv=")) {
1572 PreservedGVs.push_back(ParamName.str());
1573 } else {
1575 formatv("invalid Internalize pass parameter '{}'", ParamName).str(),
1577 }
1578 }
1579
1580 return Expected<SmallVector<std::string, 0>>(std::move(PreservedGVs));
1581}
1582
1584parseRegAllocFastPassOptions(PassBuilder &PB, StringRef Params) {
1586 while (!Params.empty()) {
1587 StringRef ParamName;
1588 std::tie(ParamName, Params) = Params.split(';');
1589
1590 if (ParamName.consume_front("filter=")) {
1591 std::optional<RegAllocFilterFunc> Filter =
1592 PB.parseRegAllocFilter(ParamName);
1593 if (!Filter) {
1595 formatv("invalid regallocfast register filter '{}'", ParamName)
1596 .str(),
1598 }
1599 Opts.Filter = *Filter;
1600 Opts.FilterName = ParamName;
1601 continue;
1602 }
1603
1604 if (ParamName == "no-clear-vregs") {
1605 Opts.ClearVRegs = false;
1606 continue;
1607 }
1608
1610 formatv("invalid regallocfast pass parameter '{}'", ParamName).str(),
1612 }
1613 return Opts;
1614}
1615
1617parseBoundsCheckingOptions(StringRef Params) {
1619 while (!Params.empty()) {
1620 StringRef ParamName;
1621 std::tie(ParamName, Params) = Params.split(';');
1622 if (ParamName == "trap") {
1623 Options.Rt = std::nullopt;
1624 } else if (ParamName == "rt") {
1625 Options.Rt = {
1626 /*MinRuntime=*/false,
1627 /*MayReturn=*/true,
1628 /*HandlerPreserveAllRegs=*/false,
1629 };
1630 } else if (ParamName == "rt-abort") {
1631 Options.Rt = {
1632 /*MinRuntime=*/false,
1633 /*MayReturn=*/false,
1634 /*HandlerPreserveAllRegs=*/false,
1635 };
1636 } else if (ParamName == "min-rt") {
1637 Options.Rt = {
1638 /*MinRuntime=*/true,
1639 /*MayReturn=*/true,
1640 /*HandlerPreserveAllRegs=*/false,
1641 };
1642 } else if (ParamName == "min-rt-abort") {
1643 Options.Rt = {
1644 /*MinRuntime=*/true,
1645 /*MayReturn=*/false,
1646 /*HandlerPreserveAllRegs=*/false,
1647 };
1648 } else if (ParamName == "merge") {
1649 Options.Merge = true;
1650 } else if (ParamName == "handler-preserve-all-regs") {
1651 if (Options.Rt)
1652 Options.Rt->HandlerPreserveAllRegs = true;
1653 } else {
1654 StringRef ParamEQ;
1655 StringRef Val;
1656 std::tie(ParamEQ, Val) = ParamName.split('=');
1657 int8_t Id;
1658 if (ParamEQ == "guard" && !Val.getAsInteger(0, Id)) {
1659 Options.GuardKind = Id;
1660 } else {
1662 formatv("invalid BoundsChecking pass parameter '{}'", ParamName)
1663 .str(),
1665 }
1666 }
1667 }
1668 return Options;
1669}
1670
1671Expected<CodeGenOptLevel> parseExpandIRInstsOptions(StringRef Param) {
1672 if (Param.empty())
1673 return CodeGenOptLevel::None;
1674
1675 // Parse a CodeGenOptLevel, e.g. "O1", "O2", "O3".
1676 auto [Prefix, Digit] = Param.split('O');
1677
1678 uint8_t N;
1679 if (!Prefix.empty() || Digit.getAsInteger(10, N))
1680 return createStringError("invalid expand-ir-insts pass parameter '%s'",
1681 Param.str().c_str());
1682
1683 std::optional<CodeGenOptLevel> Level = CodeGenOpt::getLevel(N);
1684 if (!Level.has_value())
1685 return createStringError(
1686 "invalid optimization level for expand-ir-insts pass: %s",
1687 Digit.str().c_str());
1688
1689 return *Level;
1690}
1691
1693parseRegAllocGreedyFilterFunc(PassBuilder &PB, StringRef Params) {
1694 if (Params.empty() || Params == "all")
1695 return RAGreedyPass::Options();
1696
1697 std::optional<RegAllocFilterFunc> Filter = PB.parseRegAllocFilter(Params);
1698 if (Filter)
1699 return RAGreedyPass::Options{*Filter, Params};
1700
1702 formatv("invalid regallocgreedy register filter '{}'", Params).str(),
1704}
1705
1706Expected<bool> parseMachineSinkingPassOptions(StringRef Params) {
1707 return PassBuilder::parseSinglePassOption(Params, "enable-sink-fold",
1708 "MachineSinkingPass");
1709}
1710
1711Expected<bool> parseMachineBlockPlacementPassOptions(StringRef Params) {
1712 bool AllowTailMerge = true;
1713 if (!Params.empty()) {
1714 AllowTailMerge = !Params.consume_front("no-");
1715 if (Params != "tail-merge")
1717 formatv("invalid MachineBlockPlacementPass parameter '{}'", Params)
1718 .str(),
1720 }
1721 return AllowTailMerge;
1722}
1723
1724Expected<bool> parseVirtRegRewriterPassOptions(StringRef Params) {
1725 bool ClearVirtRegs = true;
1726 if (!Params.empty()) {
1727 ClearVirtRegs = !Params.consume_front("no-");
1728 if (Params != "clear-vregs")
1730 formatv("invalid VirtRegRewriter pass parameter '{}'", Params).str(),
1732 }
1733 return ClearVirtRegs;
1734}
1735
1736struct FatLTOOptions {
1737 OptimizationLevel OptLevel;
1738 bool ThinLTO = false;
1739 bool EmitSummary = false;
1740};
1741
1742Expected<FatLTOOptions> parseFatLTOOptions(StringRef Params) {
1743 FatLTOOptions Result;
1744 bool HaveOptLevel = false;
1745 while (!Params.empty()) {
1746 StringRef ParamName;
1747 std::tie(ParamName, Params) = Params.split(';');
1748
1749 if (ParamName == "thinlto") {
1750 Result.ThinLTO = true;
1751 } else if (ParamName == "emit-summary") {
1752 Result.EmitSummary = true;
1753 } else if (std::optional<OptimizationLevel> OptLevel =
1754 parseOptLevel(ParamName)) {
1755 Result.OptLevel = *OptLevel;
1756 HaveOptLevel = true;
1757 } else {
1759 formatv("invalid fatlto-pre-link pass parameter '{}'", ParamName)
1760 .str(),
1762 }
1763 }
1764 if (!HaveOptLevel)
1766 "missing optimization level for fatlto-pre-link pipeline",
1768 return Result;
1769}
1770
1771} // namespace
1772
1773/// Tests whether registered callbacks will accept a given pass name.
1774///
1775/// When parsing a pipeline text, the type of the outermost pipeline may be
1776/// omitted, in which case the type is automatically determined from the first
1777/// pass name in the text. This may be a name that is handled through one of the
1778/// callbacks. We check this through the oridinary parsing callbacks by setting
1779/// up a dummy PassManager in order to not force the client to also handle this
1780/// type of query.
1781template <typename PassManagerT, typename CallbacksT>
1782static bool callbacksAcceptPassName(StringRef Name, CallbacksT &Callbacks) {
1783 if (!Callbacks.empty()) {
1784 PassManagerT DummyPM;
1785 for (auto &CB : Callbacks)
1786 if (CB(Name, DummyPM, {}))
1787 return true;
1788 }
1789 return false;
1790}
1791
1792template <typename CallbacksT>
1793static bool isModulePassName(StringRef Name, CallbacksT &Callbacks) {
1794 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1795
1796 // Explicitly handle pass manager names.
1797 if (Name == "module")
1798 return true;
1799 if (Name == "cgscc")
1800 return true;
1801 if (NameNoBracket == "function")
1802 return true;
1803 if (Name == "coro-cond")
1804 return true;
1805
1806#define MODULE_PASS(NAME, CREATE_PASS) \
1807 if (Name == NAME) \
1808 return true;
1809#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1810 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1811 return true;
1812#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
1813 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1814 return true;
1815#include "PassRegistry.def"
1816
1817 return callbacksAcceptPassName<ModulePassManager>(Name, Callbacks);
1818}
1819
1820template <typename CallbacksT>
1821static bool isCGSCCPassName(StringRef Name, CallbacksT &Callbacks) {
1822 // Explicitly handle pass manager names.
1823 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1824 if (Name == "cgscc")
1825 return true;
1826 if (NameNoBracket == "function")
1827 return true;
1828
1829 // Explicitly handle custom-parsed pass names.
1830 if (parseDevirtPassName(Name))
1831 return true;
1832
1833#define CGSCC_PASS(NAME, CREATE_PASS) \
1834 if (Name == NAME) \
1835 return true;
1836#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1837 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1838 return true;
1839#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
1840 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1841 return true;
1842#include "PassRegistry.def"
1843
1844 return callbacksAcceptPassName<CGSCCPassManager>(Name, Callbacks);
1845}
1846
1847template <typename CallbacksT>
1848static bool isFunctionPassName(StringRef Name, CallbacksT &Callbacks) {
1849 // Explicitly handle pass manager names.
1850 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1851 if (NameNoBracket == "function")
1852 return true;
1853 if (Name == "loop" || Name == "loop-mssa" || Name == "machine-function")
1854 return true;
1855
1856#define FUNCTION_PASS(NAME, CREATE_PASS) \
1857 if (Name == NAME) \
1858 return true;
1859#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1860 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1861 return true;
1862#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1863 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1864 return true;
1865#include "PassRegistry.def"
1866
1867 return callbacksAcceptPassName<FunctionPassManager>(Name, Callbacks);
1868}
1869
1870template <typename CallbacksT>
1871static bool isMachineFunctionPassName(StringRef Name, CallbacksT &Callbacks) {
1872 // Explicitly handle pass manager names.
1873 if (Name == "machine-function")
1874 return true;
1875
1876#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
1877 if (Name == NAME) \
1878 return true;
1879#define MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, \
1880 PARAMS) \
1881 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1882 return true;
1883
1884#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1885 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1886 return true;
1887
1888#include "llvm/Passes/MachinePassRegistry.def"
1889
1891}
1892
1893template <typename CallbacksT>
1894static bool isLoopNestPassName(StringRef Name, CallbacksT &Callbacks,
1895 bool &UseMemorySSA) {
1896 UseMemorySSA = false;
1897
1898 if (PassBuilder::checkParametrizedPassName(Name, "lnicm")) {
1899 UseMemorySSA = true;
1900 return true;
1901 }
1902
1903#define LOOPNEST_PASS(NAME, CREATE_PASS) \
1904 if (Name == NAME) \
1905 return true;
1906#include "PassRegistry.def"
1907
1908 return callbacksAcceptPassName<LoopPassManager>(Name, Callbacks);
1909}
1910
1911template <typename CallbacksT>
1912static bool isLoopPassName(StringRef Name, CallbacksT &Callbacks,
1913 bool &UseMemorySSA) {
1914 UseMemorySSA = false;
1915
1916 if (PassBuilder::checkParametrizedPassName(Name, "licm")) {
1917 UseMemorySSA = true;
1918 return true;
1919 }
1920
1921#define LOOP_PASS(NAME, CREATE_PASS) \
1922 if (Name == NAME) \
1923 return true;
1924#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1925 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1926 return true;
1927#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
1928 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1929 return true;
1930#include "PassRegistry.def"
1931
1932 return callbacksAcceptPassName<LoopPassManager>(Name, Callbacks);
1933}
1934
1935std::optional<std::vector<PassBuilder::PipelineElement>>
1936PassBuilder::parsePipelineText(StringRef Text) {
1937 std::vector<PipelineElement> ResultPipeline;
1938
1939 SmallVector<std::vector<PipelineElement> *, 4> PipelineStack = {
1940 &ResultPipeline};
1941 for (;;) {
1942 std::vector<PipelineElement> &Pipeline = *PipelineStack.back();
1943 size_t Pos = Text.find_first_of(",()");
1944 Pipeline.push_back({Text.substr(0, Pos), {}});
1945
1946 // If we have a single terminating name, we're done.
1947 if (Pos == Text.npos)
1948 break;
1949
1950 char Sep = Text[Pos];
1951 Text = Text.substr(Pos + 1);
1952 if (Sep == ',')
1953 // Just a name ending in a comma, continue.
1954 continue;
1955
1956 if (Sep == '(') {
1957 // Push the inner pipeline onto the stack to continue processing.
1958 PipelineStack.push_back(&Pipeline.back().InnerPipeline);
1959 continue;
1960 }
1961
1962 assert(Sep == ')' && "Bogus separator!");
1963 // When handling the close parenthesis, we greedily consume them to avoid
1964 // empty strings in the pipeline.
1965 do {
1966 // If we try to pop the outer pipeline we have unbalanced parentheses.
1967 if (PipelineStack.size() == 1)
1968 return std::nullopt;
1969
1970 PipelineStack.pop_back();
1971 } while (Text.consume_front(")"));
1972
1973 // Check if we've finished parsing.
1974 if (Text.empty())
1975 break;
1976
1977 // Otherwise, the end of an inner pipeline always has to be followed by
1978 // a comma, and then we can continue.
1979 if (!Text.consume_front(","))
1980 return std::nullopt;
1981 }
1982
1983 if (PipelineStack.size() > 1)
1984 // Unbalanced paretheses.
1985 return std::nullopt;
1986
1987 assert(PipelineStack.back() == &ResultPipeline &&
1988 "Wrong pipeline at the bottom of the stack!");
1989 return {std::move(ResultPipeline)};
1990}
1991
1994 PTO.LoopVectorization = L.getSpeedupLevel() > 1;
1995 PTO.SLPVectorization = L.getSpeedupLevel() > 1;
1996}
1997
1998Error PassBuilder::parseModulePass(ModulePassManager &MPM,
1999 const PipelineElement &E) {
2000 auto &Name = E.Name;
2001 auto &InnerPipeline = E.InnerPipeline;
2002
2003 // First handle complex passes like the pass managers which carry pipelines.
2004 if (!InnerPipeline.empty()) {
2005 if (Name == "module") {
2006 ModulePassManager NestedMPM;
2007 if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline))
2008 return Err;
2009 MPM.addPass(std::move(NestedMPM));
2010 return Error::success();
2011 }
2012 if (Name == "coro-cond") {
2013 ModulePassManager NestedMPM;
2014 if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline))
2015 return Err;
2016 MPM.addPass(CoroConditionalWrapper(std::move(NestedMPM)));
2017 return Error::success();
2018 }
2019 if (Name == "cgscc") {
2020 CGSCCPassManager CGPM;
2021 if (auto Err = parseCGSCCPassPipeline(CGPM, InnerPipeline))
2022 return Err;
2024 return Error::success();
2025 }
2026 if (auto Params = parseFunctionPipelineName(Name)) {
2027 if (Params->second)
2029 "cannot have a no-rerun module to function adaptor",
2032 if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline))
2033 return Err;
2034 MPM.addPass(
2035 createModuleToFunctionPassAdaptor(std::move(FPM), Params->first));
2036 return Error::success();
2037 }
2038
2039 for (auto &C : ModulePipelineParsingCallbacks)
2040 if (C(Name, MPM, InnerPipeline))
2041 return Error::success();
2042
2043 // Normal passes can't have pipelines.
2045 formatv("invalid use of '{}' pass as module pipeline", Name).str(),
2047 ;
2048 }
2049
2050 // Finally expand the basic registered passes from the .inc file.
2051#define MODULE_PASS(NAME, CREATE_PASS) \
2052 if (Name == NAME) { \
2053 MPM.addPass(CREATE_PASS); \
2054 return Error::success(); \
2055 }
2056#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2057 if (checkParametrizedPassName(Name, NAME)) { \
2058 auto Params = parsePassParameters(PARSER, Name, NAME); \
2059 if (!Params) \
2060 return Params.takeError(); \
2061 MPM.addPass(CREATE_PASS(Params.get())); \
2062 return Error::success(); \
2063 }
2064#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
2065 if (Name == "require<" NAME ">") { \
2066 MPM.addPass( \
2067 RequireAnalysisPass< \
2068 std::remove_reference_t<decltype(CREATE_PASS)>, Module>()); \
2069 return Error::success(); \
2070 } \
2071 if (Name == "invalidate<" NAME ">") { \
2072 MPM.addPass(InvalidateAnalysisPass< \
2073 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2074 return Error::success(); \
2075 }
2076#define CGSCC_PASS(NAME, CREATE_PASS) \
2077 if (Name == NAME) { \
2078 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(CREATE_PASS)); \
2079 return Error::success(); \
2080 }
2081#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2082 if (checkParametrizedPassName(Name, NAME)) { \
2083 auto Params = parsePassParameters(PARSER, Name, NAME); \
2084 if (!Params) \
2085 return Params.takeError(); \
2086 MPM.addPass( \
2087 createModuleToPostOrderCGSCCPassAdaptor(CREATE_PASS(Params.get()))); \
2088 return Error::success(); \
2089 }
2090#define FUNCTION_PASS(NAME, CREATE_PASS) \
2091 if (Name == NAME) { \
2092 if constexpr (std::is_constructible_v< \
2093 std::remove_reference_t<decltype(CREATE_PASS)>, \
2094 const TargetMachine &>) { \
2095 if (!TM) \
2096 return make_error<StringError>( \
2097 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2098 inconvertibleErrorCode()); \
2099 } \
2100 MPM.addPass(createModuleToFunctionPassAdaptor(CREATE_PASS)); \
2101 return Error::success(); \
2102 }
2103#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2104 if (checkParametrizedPassName(Name, NAME)) { \
2105 auto Params = parsePassParameters(PARSER, Name, NAME); \
2106 if (!Params) \
2107 return Params.takeError(); \
2108 auto CreatePass = CREATE_PASS; \
2109 if constexpr (std::is_constructible_v< \
2110 std::remove_reference_t<decltype(CreatePass( \
2111 Params.get()))>, \
2112 const TargetMachine &, \
2113 std::remove_reference_t<decltype(Params.get())>>) { \
2114 if (!TM) { \
2115 return make_error<StringError>( \
2116 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2117 inconvertibleErrorCode()); \
2118 } \
2119 } \
2120 MPM.addPass(createModuleToFunctionPassAdaptor(CREATE_PASS(Params.get()))); \
2121 return Error::success(); \
2122 }
2123#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2124 if (Name == NAME) { \
2125 MPM.addPass(createModuleToFunctionPassAdaptor( \
2126 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2127 return Error::success(); \
2128 }
2129#define LOOP_PASS(NAME, CREATE_PASS) \
2130 if (Name == NAME) { \
2131 MPM.addPass(createModuleToFunctionPassAdaptor( \
2132 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2133 return Error::success(); \
2134 }
2135#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2136 if (checkParametrizedPassName(Name, NAME)) { \
2137 auto Params = parsePassParameters(PARSER, Name, NAME); \
2138 if (!Params) \
2139 return Params.takeError(); \
2140 MPM.addPass(createModuleToFunctionPassAdaptor( \
2141 createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), false))); \
2142 return Error::success(); \
2143 }
2144#include "PassRegistry.def"
2145
2146 for (auto &C : ModulePipelineParsingCallbacks)
2147 if (C(Name, MPM, InnerPipeline))
2148 return Error::success();
2150 formatv("unknown module pass '{}'", Name).str(),
2152}
2153
2154Error PassBuilder::parseCGSCCPass(CGSCCPassManager &CGPM,
2155 const PipelineElement &E) {
2156 auto &Name = E.Name;
2157 auto &InnerPipeline = E.InnerPipeline;
2158
2159 // First handle complex passes like the pass managers which carry pipelines.
2160 if (!InnerPipeline.empty()) {
2161 if (Name == "cgscc") {
2162 CGSCCPassManager NestedCGPM;
2163 if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline))
2164 return Err;
2165 // Add the nested pass manager with the appropriate adaptor.
2166 CGPM.addPass(std::move(NestedCGPM));
2167 return Error::success();
2168 }
2169 if (auto Params = parseFunctionPipelineName(Name)) {
2171 if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline))
2172 return Err;
2173 // Add the nested pass manager with the appropriate adaptor.
2175 std::move(FPM), Params->first, Params->second));
2176 return Error::success();
2177 }
2178 if (auto MaxRepetitions = parseDevirtPassName(Name)) {
2179 CGSCCPassManager NestedCGPM;
2180 if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline))
2181 return Err;
2182 CGPM.addPass(
2183 createDevirtSCCRepeatedPass(std::move(NestedCGPM), *MaxRepetitions));
2184 return Error::success();
2185 }
2186
2187 for (auto &C : CGSCCPipelineParsingCallbacks)
2188 if (C(Name, CGPM, InnerPipeline))
2189 return Error::success();
2190
2191 // Normal passes can't have pipelines.
2193 formatv("invalid use of '{}' pass as cgscc pipeline", Name).str(),
2195 }
2196
2197// Now expand the basic registered passes from the .inc file.
2198#define CGSCC_PASS(NAME, CREATE_PASS) \
2199 if (Name == NAME) { \
2200 CGPM.addPass(CREATE_PASS); \
2201 return Error::success(); \
2202 }
2203#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2204 if (checkParametrizedPassName(Name, NAME)) { \
2205 auto Params = parsePassParameters(PARSER, Name, NAME); \
2206 if (!Params) \
2207 return Params.takeError(); \
2208 CGPM.addPass(CREATE_PASS(Params.get())); \
2209 return Error::success(); \
2210 }
2211#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
2212 if (Name == "require<" NAME ">") { \
2213 CGPM.addPass(RequireAnalysisPass< \
2214 std::remove_reference_t<decltype(CREATE_PASS)>, \
2215 LazyCallGraph::SCC, CGSCCAnalysisManager, LazyCallGraph &, \
2216 CGSCCUpdateResult &>()); \
2217 return Error::success(); \
2218 } \
2219 if (Name == "invalidate<" NAME ">") { \
2220 CGPM.addPass(InvalidateAnalysisPass< \
2221 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2222 return Error::success(); \
2223 }
2224#define FUNCTION_PASS(NAME, CREATE_PASS) \
2225 if (Name == NAME) { \
2226 if constexpr (std::is_constructible_v< \
2227 std::remove_reference_t<decltype(CREATE_PASS)>, \
2228 const TargetMachine &>) { \
2229 if (!TM) \
2230 return make_error<StringError>( \
2231 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2232 inconvertibleErrorCode()); \
2233 } \
2234 CGPM.addPass(createCGSCCToFunctionPassAdaptor(CREATE_PASS)); \
2235 return Error::success(); \
2236 }
2237#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2238 if (checkParametrizedPassName(Name, NAME)) { \
2239 auto Params = parsePassParameters(PARSER, Name, NAME); \
2240 if (!Params) \
2241 return Params.takeError(); \
2242 auto CreatePass = CREATE_PASS; \
2243 if constexpr (std::is_constructible_v< \
2244 std::remove_reference_t<decltype(CreatePass( \
2245 Params.get()))>, \
2246 const TargetMachine &, \
2247 std::remove_reference_t<decltype(Params.get())>>) { \
2248 if (!TM) { \
2249 return make_error<StringError>( \
2250 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2251 inconvertibleErrorCode()); \
2252 } \
2253 } \
2254 CGPM.addPass(createCGSCCToFunctionPassAdaptor(CREATE_PASS(Params.get()))); \
2255 return Error::success(); \
2256 }
2257#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2258 if (Name == NAME) { \
2259 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
2260 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2261 return Error::success(); \
2262 }
2263#define LOOP_PASS(NAME, CREATE_PASS) \
2264 if (Name == NAME) { \
2265 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
2266 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2267 return Error::success(); \
2268 }
2269#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2270 if (checkParametrizedPassName(Name, NAME)) { \
2271 auto Params = parsePassParameters(PARSER, Name, NAME); \
2272 if (!Params) \
2273 return Params.takeError(); \
2274 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
2275 createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), false))); \
2276 return Error::success(); \
2277 }
2278#include "PassRegistry.def"
2279
2280 for (auto &C : CGSCCPipelineParsingCallbacks)
2281 if (C(Name, CGPM, InnerPipeline))
2282 return Error::success();
2283 return make_error<StringError>(formatv("unknown cgscc pass '{}'", Name).str(),
2285}
2286
2287Error PassBuilder::parseFunctionPass(FunctionPassManager &FPM,
2288 const PipelineElement &E) {
2289 auto &Name = E.Name;
2290 auto &InnerPipeline = E.InnerPipeline;
2291
2292 // First handle complex passes like the pass managers which carry pipelines.
2293 if (!InnerPipeline.empty()) {
2294 if (Name == "function") {
2295 FunctionPassManager NestedFPM;
2296 if (auto Err = parseFunctionPassPipeline(NestedFPM, InnerPipeline))
2297 return Err;
2298 // Add the nested pass manager with the appropriate adaptor.
2299 FPM.addPass(std::move(NestedFPM));
2300 return Error::success();
2301 }
2302 if (Name == "loop" || Name == "loop-mssa") {
2303 LoopPassManager LPM;
2304 if (auto Err = parseLoopPassPipeline(LPM, InnerPipeline))
2305 return Err;
2306 // Add the nested pass manager with the appropriate adaptor.
2307 bool UseMemorySSA = (Name == "loop-mssa");
2308 FPM.addPass(
2309 createFunctionToLoopPassAdaptor(std::move(LPM), UseMemorySSA));
2310 return Error::success();
2311 }
2312 if (Name == "machine-function") {
2314 if (auto Err = parseMachinePassPipeline(MFPM, InnerPipeline))
2315 return Err;
2317 return Error::success();
2318 }
2319
2320 for (auto &C : FunctionPipelineParsingCallbacks)
2321 if (C(Name, FPM, InnerPipeline))
2322 return Error::success();
2323
2324 // Normal passes can't have pipelines.
2326 formatv("invalid use of '{}' pass as function pipeline", Name).str(),
2328 }
2329
2330// Now expand the basic registered passes from the .inc file.
2331#define FUNCTION_PASS(NAME, CREATE_PASS) \
2332 if (Name == NAME) { \
2333 if constexpr (std::is_constructible_v< \
2334 std::remove_reference_t<decltype(CREATE_PASS)>, \
2335 const TargetMachine &>) { \
2336 if (!TM) \
2337 return make_error<StringError>( \
2338 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2339 inconvertibleErrorCode()); \
2340 } \
2341 FPM.addPass(CREATE_PASS); \
2342 return Error::success(); \
2343 }
2344#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2345 if (checkParametrizedPassName(Name, NAME)) { \
2346 auto Params = parsePassParameters(PARSER, Name, NAME); \
2347 if (!Params) \
2348 return Params.takeError(); \
2349 auto CreatePass = CREATE_PASS; \
2350 if constexpr (std::is_constructible_v< \
2351 std::remove_reference_t<decltype(CreatePass( \
2352 Params.get()))>, \
2353 const TargetMachine &, \
2354 std::remove_reference_t<decltype(Params.get())>>) { \
2355 if (!TM) { \
2356 return make_error<StringError>( \
2357 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2358 inconvertibleErrorCode()); \
2359 } \
2360 } \
2361 FPM.addPass(CREATE_PASS(Params.get())); \
2362 return Error::success(); \
2363 }
2364#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
2365 if (Name == "require<" NAME ">") { \
2366 if constexpr (std::is_constructible_v< \
2367 std::remove_reference_t<decltype(CREATE_PASS)>, \
2368 const TargetMachine &>) { \
2369 if (!TM) \
2370 return make_error<StringError>( \
2371 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2372 inconvertibleErrorCode()); \
2373 } \
2374 FPM.addPass( \
2375 RequireAnalysisPass<std::remove_reference_t<decltype(CREATE_PASS)>, \
2376 Function>()); \
2377 return Error::success(); \
2378 } \
2379 if (Name == "invalidate<" NAME ">") { \
2380 FPM.addPass(InvalidateAnalysisPass< \
2381 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2382 return Error::success(); \
2383 }
2384// FIXME: UseMemorySSA is set to false. Maybe we could do things like:
2385// bool UseMemorySSA = !("canon-freeze" || "loop-predication" ||
2386// "guard-widening");
2387// The risk is that it may become obsolete if we're not careful.
2388#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2389 if (Name == NAME) { \
2390 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS, false)); \
2391 return Error::success(); \
2392 }
2393#define LOOP_PASS(NAME, CREATE_PASS) \
2394 if (Name == NAME) { \
2395 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS, false)); \
2396 return Error::success(); \
2397 }
2398#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2399 if (checkParametrizedPassName(Name, NAME)) { \
2400 auto Params = parsePassParameters(PARSER, Name, NAME); \
2401 if (!Params) \
2402 return Params.takeError(); \
2403 FPM.addPass( \
2404 createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), false)); \
2405 return Error::success(); \
2406 }
2407#include "PassRegistry.def"
2408
2409 for (auto &C : FunctionPipelineParsingCallbacks)
2410 if (C(Name, FPM, InnerPipeline))
2411 return Error::success();
2413 formatv("unknown function pass '{}'", Name).str(),
2415}
2416
2417Error PassBuilder::parseLoopPass(LoopPassManager &LPM,
2418 const PipelineElement &E) {
2419 StringRef Name = E.Name;
2420 auto &InnerPipeline = E.InnerPipeline;
2421
2422 // First handle complex passes like the pass managers which carry pipelines.
2423 if (!InnerPipeline.empty()) {
2424 if (Name == "loop") {
2425 LoopPassManager NestedLPM;
2426 if (auto Err = parseLoopPassPipeline(NestedLPM, InnerPipeline))
2427 return Err;
2428 // Add the nested pass manager with the appropriate adaptor.
2429 LPM.addPass(std::move(NestedLPM));
2430 return Error::success();
2431 }
2432
2433 for (auto &C : LoopPipelineParsingCallbacks)
2434 if (C(Name, LPM, InnerPipeline))
2435 return Error::success();
2436
2437 // Normal passes can't have pipelines.
2439 formatv("invalid use of '{}' pass as loop pipeline", Name).str(),
2441 }
2442
2443// Now expand the basic registered passes from the .inc file.
2444#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2445 if (Name == NAME) { \
2446 LPM.addPass(CREATE_PASS); \
2447 return Error::success(); \
2448 }
2449#define LOOP_PASS(NAME, CREATE_PASS) \
2450 if (Name == NAME) { \
2451 LPM.addPass(CREATE_PASS); \
2452 return Error::success(); \
2453 }
2454#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2455 if (checkParametrizedPassName(Name, NAME)) { \
2456 auto Params = parsePassParameters(PARSER, Name, NAME); \
2457 if (!Params) \
2458 return Params.takeError(); \
2459 LPM.addPass(CREATE_PASS(Params.get())); \
2460 return Error::success(); \
2461 }
2462#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
2463 if (Name == "require<" NAME ">") { \
2464 LPM.addPass(RequireAnalysisPass< \
2465 std::remove_reference_t<decltype(CREATE_PASS)>, Loop, \
2466 LoopAnalysisManager, LoopStandardAnalysisResults &, \
2467 LPMUpdater &>()); \
2468 return Error::success(); \
2469 } \
2470 if (Name == "invalidate<" NAME ">") { \
2471 LPM.addPass(InvalidateAnalysisPass< \
2472 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2473 return Error::success(); \
2474 }
2475#include "PassRegistry.def"
2476
2477 for (auto &C : LoopPipelineParsingCallbacks)
2478 if (C(Name, LPM, InnerPipeline))
2479 return Error::success();
2480 return make_error<StringError>(formatv("unknown loop pass '{}'", Name).str(),
2482}
2483
2484Error PassBuilder::parseMachinePass(MachineFunctionPassManager &MFPM,
2485 const PipelineElement &E) {
2486 StringRef Name = E.Name;
2487 // Handle any nested pass managers.
2488 if (!E.InnerPipeline.empty()) {
2489 if (E.Name == "machine-function") {
2491 if (auto Err = parseMachinePassPipeline(NestedPM, E.InnerPipeline))
2492 return Err;
2493 MFPM.addPass(std::move(NestedPM));
2494 return Error::success();
2495 }
2496 return make_error<StringError>("invalid pipeline",
2498 }
2499
2500#define MACHINE_MODULE_PASS(NAME, CREATE_PASS) \
2501 if (Name == NAME) { \
2502 MFPM.addPass(CREATE_PASS); \
2503 return Error::success(); \
2504 }
2505#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
2506 if (Name == NAME) { \
2507 MFPM.addPass(CREATE_PASS); \
2508 return Error::success(); \
2509 }
2510#define MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, \
2511 PARAMS) \
2512 if (checkParametrizedPassName(Name, NAME)) { \
2513 auto Params = parsePassParameters(PARSER, Name, NAME); \
2514 if (!Params) \
2515 return Params.takeError(); \
2516 MFPM.addPass(CREATE_PASS(Params.get())); \
2517 return Error::success(); \
2518 }
2519#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
2520 if (Name == "require<" NAME ">") { \
2521 MFPM.addPass( \
2522 RequireAnalysisPass<std::remove_reference_t<decltype(CREATE_PASS)>, \
2523 MachineFunction>()); \
2524 return Error::success(); \
2525 } \
2526 if (Name == "invalidate<" NAME ">") { \
2527 MFPM.addPass(InvalidateAnalysisPass< \
2528 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2529 return Error::success(); \
2530 }
2531#include "llvm/Passes/MachinePassRegistry.def"
2532
2533 for (auto &C : MachineFunctionPipelineParsingCallbacks)
2534 if (C(Name, MFPM, E.InnerPipeline))
2535 return Error::success();
2537 formatv("unknown machine pass '{}'", Name).str(),
2539}
2540
2541bool PassBuilder::parseAAPassName(AAManager &AA, StringRef Name) {
2542#define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
2543 if (Name == NAME) { \
2544 AA.registerModuleAnalysis< \
2545 std::remove_reference_t<decltype(CREATE_PASS)>>(); \
2546 return true; \
2547 }
2548#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
2549 if (Name == NAME) { \
2550 AA.registerFunctionAnalysis< \
2551 std::remove_reference_t<decltype(CREATE_PASS)>>(); \
2552 return true; \
2553 }
2554#include "PassRegistry.def"
2555
2556 for (auto &C : AAParsingCallbacks)
2557 if (C(Name, AA))
2558 return true;
2559 return false;
2560}
2561
2562Error PassBuilder::parseMachinePassPipeline(
2564 for (const auto &Element : Pipeline) {
2565 if (auto Err = parseMachinePass(MFPM, Element))
2566 return Err;
2567 }
2568 return Error::success();
2569}
2570
2571Error PassBuilder::parseLoopPassPipeline(LoopPassManager &LPM,
2572 ArrayRef<PipelineElement> Pipeline) {
2573 for (const auto &Element : Pipeline) {
2574 if (auto Err = parseLoopPass(LPM, Element))
2575 return Err;
2576 }
2577 return Error::success();
2578}
2579
2580Error PassBuilder::parseFunctionPassPipeline(
2582 for (const auto &Element : Pipeline) {
2583 if (auto Err = parseFunctionPass(FPM, Element))
2584 return Err;
2585 }
2586 return Error::success();
2587}
2588
2589Error PassBuilder::parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
2590 ArrayRef<PipelineElement> Pipeline) {
2591 for (const auto &Element : Pipeline) {
2592 if (auto Err = parseCGSCCPass(CGPM, Element))
2593 return Err;
2594 }
2595 return Error::success();
2596}
2597
2603 MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });
2604 MAM.registerPass([&] { return CGSCCAnalysisManagerModuleProxy(CGAM); });
2605 CGAM.registerPass([&] { return ModuleAnalysisManagerCGSCCProxy(MAM); });
2606 FAM.registerPass([&] { return CGSCCAnalysisManagerFunctionProxy(CGAM); });
2607 FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); });
2608 FAM.registerPass([&] { return LoopAnalysisManagerFunctionProxy(LAM); });
2609 LAM.registerPass([&] { return FunctionAnalysisManagerLoopProxy(FAM); });
2610 if (MFAM) {
2611 MAM.registerPass(
2612 [&] { return MachineFunctionAnalysisManagerModuleProxy(*MFAM); });
2613 FAM.registerPass(
2614 [&] { return MachineFunctionAnalysisManagerFunctionProxy(*MFAM); });
2615 MFAM->registerPass(
2617 MFAM->registerPass(
2619 }
2620}
2621
2622Error PassBuilder::parseModulePassPipeline(ModulePassManager &MPM,
2623 ArrayRef<PipelineElement> Pipeline) {
2624 for (const auto &Element : Pipeline) {
2625 if (auto Err = parseModulePass(MPM, Element))
2626 return Err;
2627 }
2628 return Error::success();
2629}
2630
2631// Primary pass pipeline description parsing routine for a \c ModulePassManager
2632// FIXME: Should this routine accept a TargetMachine or require the caller to
2633// pre-populate the analysis managers with target-specific stuff?
2635 StringRef PipelineText) {
2636 auto Pipeline = parsePipelineText(PipelineText);
2637 if (!Pipeline || Pipeline->empty())
2639 formatv("invalid pipeline '{}'", PipelineText).str(),
2641
2642 // If the first name isn't at the module layer, wrap the pipeline up
2643 // automatically.
2644 StringRef FirstName = Pipeline->front().Name;
2645
2646 if (!isModulePassName(FirstName, ModulePipelineParsingCallbacks)) {
2647 bool UseMemorySSA;
2648 if (isCGSCCPassName(FirstName, CGSCCPipelineParsingCallbacks)) {
2649 Pipeline = {{"cgscc", std::move(*Pipeline)}};
2650 } else if (isFunctionPassName(FirstName,
2651 FunctionPipelineParsingCallbacks)) {
2652 Pipeline = {{"function", std::move(*Pipeline)}};
2653 } else if (isLoopNestPassName(FirstName, LoopPipelineParsingCallbacks,
2654 UseMemorySSA)) {
2655 Pipeline = {{"function", {{UseMemorySSA ? "loop-mssa" : "loop",
2656 std::move(*Pipeline)}}}};
2657 } else if (isLoopPassName(FirstName, LoopPipelineParsingCallbacks,
2658 UseMemorySSA)) {
2659 Pipeline = {{"function", {{UseMemorySSA ? "loop-mssa" : "loop",
2660 std::move(*Pipeline)}}}};
2661 } else if (isMachineFunctionPassName(
2662 FirstName, MachineFunctionPipelineParsingCallbacks)) {
2663 Pipeline = {{"function", {{"machine-function", std::move(*Pipeline)}}}};
2664 } else {
2665 for (auto &C : TopLevelPipelineParsingCallbacks)
2666 if (C(MPM, *Pipeline))
2667 return Error::success();
2668
2669 // Unknown pass or pipeline name!
2670 auto &InnerPipeline = Pipeline->front().InnerPipeline;
2672 formatv("unknown {} name '{}'",
2673 (InnerPipeline.empty() ? "pass" : "pipeline"), FirstName)
2674 .str(),
2676 }
2677 }
2678
2679 if (auto Err = parseModulePassPipeline(MPM, *Pipeline))
2680 return Err;
2681 return Error::success();
2682}
2683
2684// Primary pass pipeline description parsing routine for a \c CGSCCPassManager
2686 StringRef PipelineText) {
2687 auto Pipeline = parsePipelineText(PipelineText);
2688 if (!Pipeline || Pipeline->empty())
2690 formatv("invalid pipeline '{}'", PipelineText).str(),
2692
2693 StringRef FirstName = Pipeline->front().Name;
2694 if (!isCGSCCPassName(FirstName, CGSCCPipelineParsingCallbacks))
2696 formatv("unknown cgscc pass '{}' in pipeline '{}'", FirstName,
2697 PipelineText)
2698 .str(),
2700
2701 if (auto Err = parseCGSCCPassPipeline(CGPM, *Pipeline))
2702 return Err;
2703 return Error::success();
2704}
2705
2706// Primary pass pipeline description parsing routine for a \c
2707// FunctionPassManager
2709 StringRef PipelineText) {
2710 auto Pipeline = parsePipelineText(PipelineText);
2711 if (!Pipeline || Pipeline->empty())
2713 formatv("invalid pipeline '{}'", PipelineText).str(),
2715
2716 StringRef FirstName = Pipeline->front().Name;
2717 if (!isFunctionPassName(FirstName, FunctionPipelineParsingCallbacks))
2719 formatv("unknown function pass '{}' in pipeline '{}'", FirstName,
2720 PipelineText)
2721 .str(),
2723
2724 if (auto Err = parseFunctionPassPipeline(FPM, *Pipeline))
2725 return Err;
2726 return Error::success();
2727}
2728
2729// Primary pass pipeline description parsing routine for a \c LoopPassManager
2731 StringRef PipelineText) {
2732 auto Pipeline = parsePipelineText(PipelineText);
2733 if (!Pipeline || Pipeline->empty())
2735 formatv("invalid pipeline '{}'", PipelineText).str(),
2737
2738 if (auto Err = parseLoopPassPipeline(CGPM, *Pipeline))
2739 return Err;
2740
2741 return Error::success();
2742}
2743
2745 StringRef PipelineText) {
2746 auto Pipeline = parsePipelineText(PipelineText);
2747 if (!Pipeline || Pipeline->empty())
2749 formatv("invalid machine pass pipeline '{}'", PipelineText).str(),
2751
2752 if (auto Err = parseMachinePassPipeline(MFPM, *Pipeline))
2753 return Err;
2754
2755 return Error::success();
2756}
2757
2759 // If the pipeline just consists of the word 'default' just replace the AA
2760 // manager with our default one.
2761 if (PipelineText == "default") {
2763 return Error::success();
2764 }
2765
2766 while (!PipelineText.empty()) {
2767 StringRef Name;
2768 std::tie(Name, PipelineText) = PipelineText.split(',');
2769 if (!parseAAPassName(AA, Name))
2771 formatv("unknown alias analysis name '{}'", Name).str(),
2773 }
2774
2775 return Error::success();
2776}
2777
2778std::optional<RegAllocFilterFunc>
2780 if (FilterName == "all")
2781 return nullptr;
2782 for (auto &C : RegClassFilterParsingCallbacks)
2783 if (auto F = C(FilterName))
2784 return F;
2785 return std::nullopt;
2786}
2787
2789 OS << " " << PassName << "\n";
2790}
2792 raw_ostream &OS) {
2793 OS << " " << PassName << "<" << Params << ">\n";
2794}
2795
2797 // TODO: print pass descriptions when they are available
2798
2799 OS << "Module passes:\n";
2800#define MODULE_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2801#include "PassRegistry.def"
2802
2803 OS << "Module passes with params:\n";
2804#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2805 printPassName(NAME, PARAMS, OS);
2806#include "PassRegistry.def"
2807
2808 OS << "Module analyses:\n";
2809#define MODULE_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2810#include "PassRegistry.def"
2811
2812 OS << "Module alias analyses:\n";
2813#define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2814#include "PassRegistry.def"
2815
2816 OS << "CGSCC passes:\n";
2817#define CGSCC_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2818#include "PassRegistry.def"
2819
2820 OS << "CGSCC passes with params:\n";
2821#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2822 printPassName(NAME, PARAMS, OS);
2823#include "PassRegistry.def"
2824
2825 OS << "CGSCC analyses:\n";
2826#define CGSCC_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2827#include "PassRegistry.def"
2828
2829 OS << "Function passes:\n";
2830#define FUNCTION_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2831#include "PassRegistry.def"
2832
2833 OS << "Function passes with params:\n";
2834#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2835 printPassName(NAME, PARAMS, OS);
2836#include "PassRegistry.def"
2837
2838 OS << "Function analyses:\n";
2839#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2840#include "PassRegistry.def"
2841
2842 OS << "Function alias analyses:\n";
2843#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2844#include "PassRegistry.def"
2845
2846 OS << "LoopNest passes:\n";
2847#define LOOPNEST_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2848#include "PassRegistry.def"
2849
2850 OS << "Loop passes:\n";
2851#define LOOP_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2852#include "PassRegistry.def"
2853
2854 OS << "Loop passes with params:\n";
2855#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2856 printPassName(NAME, PARAMS, OS);
2857#include "PassRegistry.def"
2858
2859 OS << "Loop analyses:\n";
2860#define LOOP_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2861#include "PassRegistry.def"
2862
2863 OS << "Machine module passes (WIP):\n";
2864#define MACHINE_MODULE_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2865#include "llvm/Passes/MachinePassRegistry.def"
2866
2867 OS << "Machine function passes (WIP):\n";
2868#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2869#include "llvm/Passes/MachinePassRegistry.def"
2870
2871 OS << "Machine function analyses (WIP):\n";
2872#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2873#include "llvm/Passes/MachinePassRegistry.def"
2874}
2875
2877 const std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>)>
2878 &C) {
2879 TopLevelPipelineParsingCallbacks.push_back(C);
2880}
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.