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"
143#include "llvm/CodeGen/PEI.h"
186#include "llvm/IR/DebugInfo.h"
187#include "llvm/IR/Dominators.h"
188#include "llvm/IR/PassManager.h"
190#include "llvm/IR/Verifier.h"
193#include "llvm/Support/CodeGen.h"
195#include "llvm/Support/Debug.h"
196#include "llvm/Support/Error.h"
199#include "llvm/Support/Regex.h"
391#include <optional>
392
393using namespace llvm;
394
396 "print-pipeline-passes",
397 cl::desc("Print a '-passes' compatible string describing the pipeline "
398 "(best-effort only)."));
399
400AnalysisKey NoOpModuleAnalysis::Key;
401AnalysisKey NoOpCGSCCAnalysis::Key;
402AnalysisKey NoOpFunctionAnalysis::Key;
403AnalysisKey NoOpLoopAnalysis::Key;
404
405namespace {
406
407// Passes for testing crashes.
408// DO NOT USE THIS EXCEPT FOR TESTING!
409class TriggerCrashModulePass : public PassInfoMixin<TriggerCrashModulePass> {
410public:
411 PreservedAnalyses run(Module &, ModuleAnalysisManager &) {
412 abort();
413 return PreservedAnalyses::all();
414 }
415 static StringRef name() { return "TriggerCrashModulePass"; }
416};
417
418class TriggerCrashFunctionPass
419 : public PassInfoMixin<TriggerCrashFunctionPass> {
420public:
421 PreservedAnalyses run(Function &, FunctionAnalysisManager &) {
422 abort();
423 return PreservedAnalyses::all();
424 }
425 static StringRef name() { return "TriggerCrashFunctionPass"; }
426};
427
428// A pass for testing message reporting of -verify-each failures.
429// DO NOT USE THIS EXCEPT FOR TESTING!
430class TriggerVerifierErrorPass
431 : public PassInfoMixin<TriggerVerifierErrorPass> {
432public:
433 PreservedAnalyses run(Module &M, ModuleAnalysisManager &) {
434 // Intentionally break the Module by creating an alias without setting the
435 // aliasee.
436 auto *PtrTy = PointerType::getUnqual(M.getContext());
437 GlobalAlias::create(PtrTy, PtrTy->getAddressSpace(),
438 GlobalValue::LinkageTypes::InternalLinkage,
439 "__bad_alias", nullptr, &M);
441 }
442
443 PreservedAnalyses run(Function &F, FunctionAnalysisManager &) {
444 // Intentionally break the Function by inserting a terminator
445 // instruction in the middle of a basic block.
446 BasicBlock &BB = F.getEntryBlock();
447 new UnreachableInst(F.getContext(), BB.getTerminator()->getIterator());
449 }
450
451 PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &) {
452 // Intentionally create a virtual register and set NoVRegs property.
453 auto &MRI = MF.getRegInfo();
455 MF.getProperties().setNoVRegs();
456 return PreservedAnalyses::all();
457 }
458
459 static StringRef name() { return "TriggerVerifierErrorPass"; }
460};
461
462// A pass requires all MachineFunctionProperties.
463// DO NOT USE THIS EXCEPT FOR TESTING!
464class RequireAllMachineFunctionPropertiesPass
465 : public PassInfoMixin<RequireAllMachineFunctionPropertiesPass> {
466public:
467 PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &) {
468 MFPropsModifier _(*this, MF);
470 }
471
472 static MachineFunctionProperties getRequiredProperties() {
473 return MachineFunctionProperties()
474 .setFailedISel()
475 .setFailsVerification()
476 .setIsSSA()
477 .setLegalized()
478 .setNoPHIs()
479 .setNoVRegs()
480 .setRegBankSelected()
481 .setSelected()
482 .setTiedOpsRewritten()
483 .setTracksDebugUserValues()
484 .setTracksLiveness();
485 }
486 static StringRef name() { return "RequireAllMachineFunctionPropertiesPass"; }
487};
488
489} // namespace
490
491static std::optional<OptimizationLevel> parseOptLevel(StringRef S) {
493 .Case("O0", OptimizationLevel::O0)
499 .Default(std::nullopt);
500}
501
503 std::optional<OptimizationLevel> OptLevel = parseOptLevel(S);
504 if (OptLevel)
505 return *OptLevel;
507 formatv("invalid optimization level '{}'", S).str(),
509}
510
512 std::optional<PGOOptions> PGOOpt,
515 : TM(TM), PTO(PTO), PGOOpt(PGOOpt), PIC(PIC), FS(std::move(FS)) {
516 if (TM)
517 TM->registerPassBuilderCallbacks(*this);
518 if (PIC) {
519 PIC->registerClassToPassNameCallback([this, PIC]() {
520 // MSVC requires this to be captured if it's used inside decltype.
521 // Other compilers consider it an unused lambda capture.
522 (void)this;
523#define MODULE_PASS(NAME, CREATE_PASS) \
524 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
525#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
526 PIC->addClassToPassName(CLASS, NAME);
527#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
528 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
529#define FUNCTION_PASS(NAME, CREATE_PASS) \
530 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
531#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
532 PIC->addClassToPassName(CLASS, NAME);
533#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
534 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
535#define LOOPNEST_PASS(NAME, CREATE_PASS) \
536 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
537#define LOOP_PASS(NAME, CREATE_PASS) \
538 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
539#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
540 PIC->addClassToPassName(CLASS, NAME);
541#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
542 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
543#define CGSCC_PASS(NAME, CREATE_PASS) \
544 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
545#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
546 PIC->addClassToPassName(CLASS, NAME);
547#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
548 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
549#include "PassRegistry.def"
550
551#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
552 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
553#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
554 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
555#define MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, \
556 PARAMS) \
557 PIC->addClassToPassName(CLASS, NAME);
558#include "llvm/Passes/MachinePassRegistry.def"
559 });
560 }
561
562 // Module-level callbacks without LTO phase
564 [this](StringRef Name, ModulePassManager &PM,
566#define MODULE_CALLBACK(NAME, INVOKE) \
567 if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
568 auto L = PassBuilder::parsePassParameters(parseOptLevelParam, Name, NAME); \
569 if (!L) { \
570 errs() << NAME ": " << toString(L.takeError()) << '\n'; \
571 return false; \
572 } \
573 INVOKE(PM, L.get()); \
574 return true; \
575 }
576#include "PassRegistry.def"
577 return false;
578 });
579
580 // Module-level callbacks with LTO phase (use Phase::None for string API)
582 [this](StringRef Name, ModulePassManager &PM,
584#define MODULE_LTO_CALLBACK(NAME, INVOKE) \
585 if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
586 auto L = PassBuilder::parsePassParameters(parseOptLevelParam, Name, NAME); \
587 if (!L) { \
588 errs() << NAME ": " << toString(L.takeError()) << '\n'; \
589 return false; \
590 } \
591 INVOKE(PM, L.get(), ThinOrFullLTOPhase::None); \
592 return true; \
593 }
594#include "PassRegistry.def"
595 return false;
596 });
597
598 // Function-level callbacks
600 [this](StringRef Name, FunctionPassManager &PM,
602#define FUNCTION_CALLBACK(NAME, INVOKE) \
603 if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
604 auto L = PassBuilder::parsePassParameters(parseOptLevelParam, Name, NAME); \
605 if (!L) { \
606 errs() << NAME ": " << toString(L.takeError()) << '\n'; \
607 return false; \
608 } \
609 INVOKE(PM, L.get()); \
610 return true; \
611 }
612#include "PassRegistry.def"
613 return false;
614 });
615
616 // CGSCC-level callbacks
618 [this](StringRef Name, CGSCCPassManager &PM,
620#define CGSCC_CALLBACK(NAME, INVOKE) \
621 if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
622 auto L = PassBuilder::parsePassParameters(parseOptLevelParam, Name, NAME); \
623 if (!L) { \
624 errs() << NAME ": " << toString(L.takeError()) << '\n'; \
625 return false; \
626 } \
627 INVOKE(PM, L.get()); \
628 return true; \
629 }
630#include "PassRegistry.def"
631 return false;
632 });
633
634 // Loop-level callbacks
636 [this](StringRef Name, LoopPassManager &PM,
638#define LOOP_CALLBACK(NAME, INVOKE) \
639 if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
640 auto L = PassBuilder::parsePassParameters(parseOptLevelParam, Name, NAME); \
641 if (!L) { \
642 errs() << NAME ": " << toString(L.takeError()) << '\n'; \
643 return false; \
644 } \
645 INVOKE(PM, L.get()); \
646 return true; \
647 }
648#include "PassRegistry.def"
649 return false;
650 });
651}
652
654#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
655 MAM.registerPass([&] { return CREATE_PASS; });
656#include "PassRegistry.def"
657
658 for (auto &C : ModuleAnalysisRegistrationCallbacks)
659 C(MAM);
660}
661
663#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
664 CGAM.registerPass([&] { return CREATE_PASS; });
665#include "PassRegistry.def"
666
667 for (auto &C : CGSCCAnalysisRegistrationCallbacks)
668 C(CGAM);
669}
670
672 // We almost always want the default alias analysis pipeline.
673 // If a user wants a different one, they can register their own before calling
674 // registerFunctionAnalyses().
675 FAM.registerPass([&] { return buildDefaultAAPipeline(); });
676
677#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
678 if constexpr (std::is_constructible_v< \
679 std::remove_reference_t<decltype(CREATE_PASS)>, \
680 const TargetMachine &>) { \
681 if (TM) \
682 FAM.registerPass([&] { return CREATE_PASS; }); \
683 } else { \
684 FAM.registerPass([&] { return CREATE_PASS; }); \
685 }
686#include "PassRegistry.def"
687
688 for (auto &C : FunctionAnalysisRegistrationCallbacks)
689 C(FAM);
690}
691
694
695#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
696 MFAM.registerPass([&] { return CREATE_PASS; });
697#include "llvm/Passes/MachinePassRegistry.def"
698
699 for (auto &C : MachineFunctionAnalysisRegistrationCallbacks)
700 C(MFAM);
701}
702
704#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
705 LAM.registerPass([&] { return CREATE_PASS; });
706#include "PassRegistry.def"
707
708 for (auto &C : LoopAnalysisRegistrationCallbacks)
709 C(LAM);
710}
711
712static std::optional<std::pair<bool, bool>>
714 std::pair<bool, bool> Params;
715 if (!Name.consume_front("function"))
716 return std::nullopt;
717 if (Name.empty())
718 return Params;
719 if (!Name.consume_front("<") || !Name.consume_back(">"))
720 return std::nullopt;
721 while (!Name.empty()) {
722 auto [Front, Back] = Name.split(';');
723 Name = Back;
724 if (Front == "eager-inv")
725 Params.first = true;
726 else if (Front == "no-rerun")
727 Params.second = true;
728 else
729 return std::nullopt;
730 }
731 return Params;
732}
733
734static std::optional<int> parseDevirtPassName(StringRef Name) {
735 if (!Name.consume_front("devirt<") || !Name.consume_back(">"))
736 return std::nullopt;
737 int Count;
738 if (Name.getAsInteger(0, Count) || Count < 0)
739 return std::nullopt;
740 return Count;
741}
742
744 StringRef OptionName,
746 bool Result = false;
747 while (!Params.empty()) {
748 StringRef ParamName;
749 std::tie(ParamName, Params) = Params.split(';');
750
751 if (ParamName == OptionName) {
752 Result = true;
753 } else {
755 formatv("invalid {} pass parameter '{}'", PassName, ParamName).str(),
757 }
758 }
759 return Result;
760}
761
762namespace {
763
764/// Parser of parameters for HardwareLoops pass.
765Expected<HardwareLoopOptions> parseHardwareLoopOptions(StringRef Params) {
766 HardwareLoopOptions HardwareLoopOpts;
767
768 while (!Params.empty()) {
769 StringRef ParamName;
770 std::tie(ParamName, Params) = Params.split(';');
771 if (ParamName.consume_front("hardware-loop-decrement=")) {
772 int Count;
773 if (ParamName.getAsInteger(0, Count))
775 formatv("invalid HardwareLoopPass parameter '{}'", ParamName).str(),
777 HardwareLoopOpts.setDecrement(Count);
778 continue;
779 }
780 if (ParamName.consume_front("hardware-loop-counter-bitwidth=")) {
781 int Count;
782 if (ParamName.getAsInteger(0, Count))
784 formatv("invalid HardwareLoopPass parameter '{}'", ParamName).str(),
786 HardwareLoopOpts.setCounterBitwidth(Count);
787 continue;
788 }
789 if (ParamName == "force-hardware-loops") {
790 HardwareLoopOpts.setForce(true);
791 } else if (ParamName == "force-hardware-loop-phi") {
792 HardwareLoopOpts.setForcePhi(true);
793 } else if (ParamName == "force-nested-hardware-loop") {
794 HardwareLoopOpts.setForceNested(true);
795 } else if (ParamName == "force-hardware-loop-guard") {
796 HardwareLoopOpts.setForceGuard(true);
797 } else {
799 formatv("invalid HardwarePass parameter '{}'", ParamName).str(),
801 }
802 }
803 return HardwareLoopOpts;
804}
805
806/// Parser of parameters for Lint pass.
807Expected<bool> parseLintOptions(StringRef Params) {
808 return PassBuilder::parseSinglePassOption(Params, "abort-on-error",
809 "LintPass");
810}
811
812/// Parser of parameters for FunctionPropertiesStatistics pass.
813Expected<bool> parseFunctionPropertiesStatisticsOptions(StringRef Params) {
814 return PassBuilder::parseSinglePassOption(Params, "pre-opt",
815 "FunctionPropertiesStatisticsPass");
816}
817
818/// Parser of parameters for InstCount pass.
819Expected<bool> parseInstCountOptions(StringRef Params) {
820 return PassBuilder::parseSinglePassOption(Params, "pre-opt", "InstCountPass");
821}
822
823/// Parser of parameters for LoopUnroll pass.
824Expected<LoopUnrollOptions> parseLoopUnrollOptions(StringRef Params) {
825 LoopUnrollOptions UnrollOpts;
826 while (!Params.empty()) {
827 StringRef ParamName;
828 std::tie(ParamName, Params) = Params.split(';');
829 std::optional<OptimizationLevel> OptLevel = parseOptLevel(ParamName);
830 // Don't accept -Os/-Oz.
831 if (OptLevel && !OptLevel->isOptimizingForSize()) {
832 UnrollOpts.setOptLevel(OptLevel->getSpeedupLevel());
833 continue;
834 }
835 if (ParamName.consume_front("full-unroll-max=")) {
836 int Count;
837 if (ParamName.getAsInteger(0, Count))
839 formatv("invalid LoopUnrollPass parameter '{}'", ParamName).str(),
841 UnrollOpts.setFullUnrollMaxCount(Count);
842 continue;
843 }
844
845 bool Enable = !ParamName.consume_front("no-");
846 if (ParamName == "partial") {
847 UnrollOpts.setPartial(Enable);
848 } else if (ParamName == "peeling") {
849 UnrollOpts.setPeeling(Enable);
850 } else if (ParamName == "profile-peeling") {
851 UnrollOpts.setProfileBasedPeeling(Enable);
852 } else if (ParamName == "runtime") {
853 UnrollOpts.setRuntime(Enable);
854 } else if (ParamName == "upperbound") {
855 UnrollOpts.setUpperBound(Enable);
856 } else {
858 formatv("invalid LoopUnrollPass parameter '{}'", ParamName).str(),
860 }
861 }
862 return UnrollOpts;
863}
864
865Expected<bool> parseGlobalDCEPassOptions(StringRef Params) {
867 Params, "vfe-linkage-unit-visibility", "GlobalDCE");
868}
869
870Expected<bool> parseCGProfilePassOptions(StringRef Params) {
871 return PassBuilder::parseSinglePassOption(Params, "in-lto-post-link",
872 "CGProfile");
873}
874
875Expected<bool> parseInlinerPassOptions(StringRef Params) {
876 return PassBuilder::parseSinglePassOption(Params, "only-mandatory",
877 "InlinerPass");
878}
879
880Expected<bool> parseCoroSplitPassOptions(StringRef Params) {
881 return PassBuilder::parseSinglePassOption(Params, "reuse-storage",
882 "CoroSplitPass");
883}
884
885Expected<bool> parsePostOrderFunctionAttrsPassOptions(StringRef Params) {
887 Params, "skip-non-recursive-function-attrs", "PostOrderFunctionAttrs");
888}
889
890Expected<bool> parseEarlyCSEPassOptions(StringRef Params) {
891 return PassBuilder::parseSinglePassOption(Params, "memssa", "EarlyCSE");
892}
893
894Expected<bool> parseEntryExitInstrumenterPassOptions(StringRef Params) {
895 return PassBuilder::parseSinglePassOption(Params, "post-inline",
896 "EntryExitInstrumenter");
897}
898
899Expected<bool> parseDropUnnecessaryAssumesPassOptions(StringRef Params) {
900 return PassBuilder::parseSinglePassOption(Params, "drop-deref",
901 "DropUnnecessaryAssumes");
902}
903
904Expected<bool> parseLoopExtractorPassOptions(StringRef Params) {
905 return PassBuilder::parseSinglePassOption(Params, "single", "LoopExtractor");
906}
907
908Expected<bool> parseLowerMatrixIntrinsicsPassOptions(StringRef Params) {
909 return PassBuilder::parseSinglePassOption(Params, "minimal",
910 "LowerMatrixIntrinsics");
911}
912
913Expected<IRNormalizerOptions> parseIRNormalizerPassOptions(StringRef Params) {
915 while (!Params.empty()) {
916 StringRef ParamName;
917 std::tie(ParamName, Params) = Params.split(';');
918
919 bool Enable = !ParamName.consume_front("no-");
920 if (ParamName == "preserve-order")
921 Result.PreserveOrder = Enable;
922 else if (ParamName == "rename-all")
923 Result.RenameAll = Enable;
924 else if (ParamName == "fold-all") // FIXME: Name mismatch
925 Result.FoldPreOutputs = Enable;
926 else if (ParamName == "reorder-operands")
927 Result.ReorderOperands = Enable;
928 else {
930 formatv("invalid normalize pass parameter '{}'", ParamName).str(),
932 }
933 }
934
935 return Result;
936}
937
938Expected<AddressSanitizerOptions> parseASanPassOptions(StringRef Params) {
940 while (!Params.empty()) {
941 StringRef ParamName;
942 std::tie(ParamName, Params) = Params.split(';');
943
944 if (ParamName == "kernel") {
945 Result.CompileKernel = true;
946 } else if (ParamName == "use-after-scope") {
947 Result.UseAfterScope = true;
948 } else {
950 formatv("invalid AddressSanitizer pass parameter '{}'", ParamName)
951 .str(),
953 }
954 }
955 return Result;
956}
957
958Expected<HWAddressSanitizerOptions> parseHWASanPassOptions(StringRef Params) {
960 while (!Params.empty()) {
961 StringRef ParamName;
962 std::tie(ParamName, Params) = Params.split(';');
963
964 if (ParamName == "recover") {
965 Result.Recover = true;
966 } else if (ParamName == "kernel") {
967 Result.CompileKernel = true;
968 } else {
970 formatv("invalid HWAddressSanitizer pass parameter '{}'", ParamName)
971 .str(),
973 }
974 }
975 return Result;
976}
977
979parseDropTypeTestsPassOptions(StringRef Params) {
981 while (!Params.empty()) {
982 StringRef ParamName;
983 std::tie(ParamName, Params) = Params.split(';');
984
985 if (ParamName == "all") {
987 } else if (ParamName == "assume") {
989 } else {
991 formatv("invalid DropTypeTestsPass parameter '{}'", ParamName).str(),
993 }
994 }
995 return Result;
996}
997
998Expected<EmbedBitcodeOptions> parseEmbedBitcodePassOptions(StringRef Params) {
1000 while (!Params.empty()) {
1001 StringRef ParamName;
1002 std::tie(ParamName, Params) = Params.split(';');
1003
1004 if (ParamName == "thinlto") {
1005 Result.IsThinLTO = true;
1006 } else if (ParamName == "emit-summary") {
1007 Result.EmitLTOSummary = true;
1008 } else {
1010 formatv("invalid EmbedBitcode pass parameter '{}'", ParamName).str(),
1012 }
1013 }
1014 return Result;
1015}
1016
1018parseLowerAllowCheckPassOptions(StringRef Params) {
1020 while (!Params.empty()) {
1021 StringRef ParamName;
1022 std::tie(ParamName, Params) = Params.split(';');
1023
1024 // Format is <cutoffs[1,2,3]=70000;cutoffs[5,6,8]=90000>
1025 //
1026 // Parsing allows duplicate indices (last one takes precedence).
1027 // It would technically be in spec to specify
1028 // cutoffs[0]=70000,cutoffs[1]=90000,cutoffs[0]=80000,...
1029 if (ParamName.starts_with("cutoffs[")) {
1030 StringRef IndicesStr;
1031 StringRef CutoffStr;
1032
1033 std::tie(IndicesStr, CutoffStr) = ParamName.split("]=");
1034 // cutoffs[1,2,3
1035 // 70000
1036
1037 int cutoff;
1038 if (CutoffStr.getAsInteger(0, cutoff))
1040 formatv("invalid LowerAllowCheck pass cutoffs parameter '{}' ({})",
1041 CutoffStr, Params)
1042 .str(),
1044
1045 if (!IndicesStr.consume_front("cutoffs[") || IndicesStr == "")
1047 formatv("invalid LowerAllowCheck pass index parameter '{}' ({})",
1048 IndicesStr, CutoffStr)
1049 .str(),
1051
1052 while (IndicesStr != "") {
1053 StringRef firstIndexStr;
1054 std::tie(firstIndexStr, IndicesStr) = IndicesStr.split('|');
1055
1056 unsigned int index;
1057 if (firstIndexStr.getAsInteger(0, index))
1059 formatv(
1060 "invalid LowerAllowCheck pass index parameter '{}' ({}) {}",
1061 firstIndexStr, IndicesStr)
1062 .str(),
1064
1065 // In the common case (sequentially increasing indices), we will issue
1066 // O(n) resize requests. We assume the underlying data structure has
1067 // O(1) runtime for each added element.
1068 if (index >= Result.cutoffs.size())
1069 Result.cutoffs.resize(index + 1, 0);
1070
1071 Result.cutoffs[index] = cutoff;
1072 }
1073 } else if (ParamName.starts_with("runtime_check")) {
1074 StringRef ValueString;
1075 std::tie(std::ignore, ValueString) = ParamName.split("=");
1076 int runtime_check;
1077 if (ValueString.getAsInteger(0, runtime_check)) {
1079 formatv("invalid LowerAllowCheck pass runtime_check parameter '{}' "
1080 "({})",
1081 ValueString, Params)
1082 .str(),
1084 }
1085 Result.runtime_check = runtime_check;
1086 } else {
1088 formatv("invalid LowerAllowCheck pass parameter '{}'", ParamName)
1089 .str(),
1091 }
1092 }
1093
1094 return Result;
1095}
1096
1097Expected<MemorySanitizerOptions> parseMSanPassOptions(StringRef Params) {
1099 while (!Params.empty()) {
1100 StringRef ParamName;
1101 std::tie(ParamName, Params) = Params.split(';');
1102
1103 if (ParamName == "recover") {
1104 Result.Recover = true;
1105 } else if (ParamName == "kernel") {
1106 Result.Kernel = true;
1107 } else if (ParamName.consume_front("track-origins=")) {
1108 if (ParamName.getAsInteger(0, Result.TrackOrigins))
1110 formatv("invalid argument to MemorySanitizer pass track-origins "
1111 "parameter: '{}'",
1112 ParamName)
1113 .str(),
1115 } else if (ParamName == "eager-checks") {
1116 Result.EagerChecks = true;
1117 } else {
1119 formatv("invalid MemorySanitizer pass parameter '{}'", ParamName)
1120 .str(),
1122 }
1123 }
1124 return Result;
1125}
1126
1127Expected<AllocTokenOptions> parseAllocTokenPassOptions(StringRef Params) {
1129 while (!Params.empty()) {
1130 StringRef ParamName;
1131 std::tie(ParamName, Params) = Params.split(';');
1132
1133 if (ParamName.consume_front("mode=")) {
1134 if (auto Mode = getAllocTokenModeFromString(ParamName))
1135 Result.Mode = *Mode;
1136 else
1138 formatv("invalid argument to AllocToken pass mode "
1139 "parameter: '{}'",
1140 ParamName)
1141 .str(),
1143 } else {
1145 formatv("invalid AllocToken pass parameter '{}'", ParamName).str(),
1147 }
1148 }
1149 return Result;
1150}
1151
1152/// Parser of parameters for SimplifyCFG pass.
1153Expected<SimplifyCFGOptions> parseSimplifyCFGOptions(StringRef Params) {
1155 while (!Params.empty()) {
1156 StringRef ParamName;
1157 std::tie(ParamName, Params) = Params.split(';');
1158
1159 bool Enable = !ParamName.consume_front("no-");
1160 if (ParamName == "speculate-blocks") {
1161 Result.speculateBlocks(Enable);
1162 } else if (ParamName == "simplify-cond-branch") {
1163 Result.setSimplifyCondBranch(Enable);
1164 } else if (ParamName == "forward-switch-cond") {
1165 Result.forwardSwitchCondToPhi(Enable);
1166 } else if (ParamName == "switch-range-to-icmp") {
1167 Result.convertSwitchRangeToICmp(Enable);
1168 } else if (ParamName == "switch-to-arithmetic") {
1169 Result.convertSwitchToArithmetic(Enable);
1170 } else if (ParamName == "switch-to-lookup") {
1171 Result.convertSwitchToLookupTable(Enable);
1172 } else if (ParamName == "keep-loops") {
1173 Result.needCanonicalLoops(Enable);
1174 } else if (ParamName == "hoist-common-insts") {
1175 Result.hoistCommonInsts(Enable);
1176 } else if (ParamName == "hoist-loads-stores-with-cond-faulting") {
1177 Result.hoistLoadsStoresWithCondFaulting(Enable);
1178 } else if (ParamName == "sink-common-insts") {
1179 Result.sinkCommonInsts(Enable);
1180 } else if (ParamName == "speculate-unpredictables") {
1181 Result.speculateUnpredictables(Enable);
1182 } else if (Enable && ParamName.consume_front("bonus-inst-threshold=")) {
1183 APInt BonusInstThreshold;
1184 if (ParamName.getAsInteger(0, BonusInstThreshold))
1186 formatv("invalid argument to SimplifyCFG pass bonus-threshold "
1187 "parameter: '{}'",
1188 ParamName)
1189 .str(),
1191 Result.bonusInstThreshold(BonusInstThreshold.getSExtValue());
1192 } else {
1194 formatv("invalid SimplifyCFG pass parameter '{}'", ParamName).str(),
1196 }
1197 }
1198 return Result;
1199}
1200
1201Expected<InstCombineOptions> parseInstCombineOptions(StringRef Params) {
1203 // When specifying "instcombine" in -passes enable fix-point verification by
1204 // default, as this is what most tests should use.
1205 Result.setVerifyFixpoint(true);
1206 while (!Params.empty()) {
1207 StringRef ParamName;
1208 std::tie(ParamName, Params) = Params.split(';');
1209
1210 bool Enable = !ParamName.consume_front("no-");
1211 if (ParamName == "verify-fixpoint") {
1212 Result.setVerifyFixpoint(Enable);
1213 } else if (Enable && ParamName.consume_front("max-iterations=")) {
1214 APInt MaxIterations;
1215 if (ParamName.getAsInteger(0, MaxIterations))
1217 formatv("invalid argument to InstCombine pass max-iterations "
1218 "parameter: '{}'",
1219 ParamName)
1220 .str(),
1222 Result.setMaxIterations((unsigned)MaxIterations.getZExtValue());
1223 } else {
1225 formatv("invalid InstCombine pass parameter '{}'", ParamName).str(),
1227 }
1228 }
1229 return Result;
1230}
1231
1232/// Parser of parameters for LoopVectorize pass.
1233Expected<LoopVectorizeOptions> parseLoopVectorizeOptions(StringRef Params) {
1235 while (!Params.empty()) {
1236 StringRef ParamName;
1237 std::tie(ParamName, Params) = Params.split(';');
1238
1239 bool Enable = !ParamName.consume_front("no-");
1240 if (ParamName == "interleave-forced-only") {
1242 } else if (ParamName == "vectorize-forced-only") {
1244 } else {
1246 formatv("invalid LoopVectorize parameter '{}'", ParamName).str(),
1248 }
1249 }
1250 return Opts;
1251}
1252
1253Expected<std::pair<bool, bool>> parseLoopUnswitchOptions(StringRef Params) {
1254 std::pair<bool, bool> Result = {false, true};
1255 while (!Params.empty()) {
1256 StringRef ParamName;
1257 std::tie(ParamName, Params) = Params.split(';');
1258
1259 bool Enable = !ParamName.consume_front("no-");
1260 if (ParamName == "nontrivial") {
1261 Result.first = Enable;
1262 } else if (ParamName == "trivial") {
1263 Result.second = Enable;
1264 } else {
1266 formatv("invalid LoopUnswitch pass parameter '{}'", ParamName).str(),
1268 }
1269 }
1270 return Result;
1271}
1272
1273Expected<LICMOptions> parseLICMOptions(StringRef Params) {
1275 while (!Params.empty()) {
1276 StringRef ParamName;
1277 std::tie(ParamName, Params) = Params.split(';');
1278
1279 bool Enable = !ParamName.consume_front("no-");
1280 if (ParamName == "allowspeculation") {
1281 Result.AllowSpeculation = Enable;
1282 } else {
1284 formatv("invalid LICM pass parameter '{}'", ParamName).str(),
1286 }
1287 }
1288 return Result;
1289}
1290
1291struct LoopRotateOptions {
1292 bool EnableHeaderDuplication = true;
1293 bool PrepareForLTO = false;
1294 bool CheckExitCount = false;
1295};
1296
1297Expected<LoopRotateOptions> parseLoopRotateOptions(StringRef Params) {
1298 LoopRotateOptions Result;
1299 while (!Params.empty()) {
1300 StringRef ParamName;
1301 std::tie(ParamName, Params) = Params.split(';');
1302
1303 bool Enable = !ParamName.consume_front("no-");
1304 if (ParamName == "header-duplication") {
1305 Result.EnableHeaderDuplication = Enable;
1306 } else if (ParamName == "prepare-for-lto") {
1307 Result.PrepareForLTO = Enable;
1308 } else if (ParamName == "check-exit-count") {
1309 Result.CheckExitCount = Enable;
1310 } else {
1312 formatv("invalid LoopRotate pass parameter '{}'", ParamName).str(),
1314 }
1315 }
1316 return Result;
1317}
1318
1319Expected<bool> parseMergedLoadStoreMotionOptions(StringRef Params) {
1320 bool Result = false;
1321 while (!Params.empty()) {
1322 StringRef ParamName;
1323 std::tie(ParamName, Params) = Params.split(';');
1324
1325 bool Enable = !ParamName.consume_front("no-");
1326 if (ParamName == "split-footer-bb") {
1327 Result = Enable;
1328 } else {
1330 formatv("invalid MergedLoadStoreMotion pass parameter '{}'",
1331 ParamName)
1332 .str(),
1334 }
1335 }
1336 return Result;
1337}
1338
1339Expected<GVNOptions> parseGVNOptions(StringRef Params) {
1341 while (!Params.empty()) {
1342 StringRef ParamName;
1343 std::tie(ParamName, Params) = Params.split(';');
1344
1345 bool Enable = !ParamName.consume_front("no-");
1346 if (ParamName == "pre") {
1347 Result.setPRE(Enable);
1348 } else if (ParamName == "load-pre") {
1349 Result.setLoadPRE(Enable);
1350 } else if (ParamName == "split-backedge-load-pre") {
1351 Result.setLoadPRESplitBackedge(Enable);
1352 } else if (ParamName == "memdep") {
1353 // MemDep and MemorySSA are mutually exclusive.
1354 Result.setMemDep(Enable);
1355 Result.setMemorySSA(!Enable);
1356 } else if (ParamName == "memoryssa") {
1357 // MemDep and MemorySSA are mutually exclusive.
1358 Result.setMemorySSA(Enable);
1359 Result.setMemDep(!Enable);
1360 } else {
1362 formatv("invalid GVN pass parameter '{}'", ParamName).str(),
1364 }
1365 }
1366 return Result;
1367}
1368
1369Expected<IPSCCPOptions> parseIPSCCPOptions(StringRef Params) {
1371 while (!Params.empty()) {
1372 StringRef ParamName;
1373 std::tie(ParamName, Params) = Params.split(';');
1374
1375 bool Enable = !ParamName.consume_front("no-");
1376 if (ParamName == "func-spec")
1377 Result.setFuncSpec(Enable);
1378 else
1380 formatv("invalid IPSCCP pass parameter '{}'", ParamName).str(),
1382 }
1383 return Result;
1384}
1385
1386Expected<ScalarizerPassOptions> parseScalarizerOptions(StringRef Params) {
1388 while (!Params.empty()) {
1389 StringRef ParamName;
1390 std::tie(ParamName, Params) = Params.split(';');
1391
1392 if (ParamName.consume_front("min-bits=")) {
1393 if (ParamName.getAsInteger(0, Result.ScalarizeMinBits)) {
1395 formatv("invalid argument to Scalarizer pass min-bits "
1396 "parameter: '{}'",
1397 ParamName)
1398 .str(),
1400 }
1401
1402 continue;
1403 }
1404
1405 bool Enable = !ParamName.consume_front("no-");
1406 if (ParamName == "load-store")
1407 Result.ScalarizeLoadStore = Enable;
1408 else if (ParamName == "variable-insert-extract")
1409 Result.ScalarizeVariableInsertExtract = Enable;
1410 else {
1412 formatv("invalid Scalarizer pass parameter '{}'", ParamName).str(),
1414 }
1415 }
1416
1417 return Result;
1418}
1419
1420Expected<SROAOptions> parseSROAOptions(StringRef Params) {
1421 if (Params.empty() || Params == "modify-cfg")
1423 if (Params == "preserve-cfg")
1426 formatv("invalid SROA pass parameter '{}' (either preserve-cfg or "
1427 "modify-cfg can be specified)",
1428 Params)
1429 .str(),
1431}
1432
1434parseStackLifetimeOptions(StringRef Params) {
1436 while (!Params.empty()) {
1437 StringRef ParamName;
1438 std::tie(ParamName, Params) = Params.split(';');
1439
1440 if (ParamName == "may") {
1442 } else if (ParamName == "must") {
1444 } else {
1446 formatv("invalid StackLifetime parameter '{}'", ParamName).str(),
1448 }
1449 }
1450 return Result;
1451}
1452
1453Expected<bool> parseDependenceAnalysisPrinterOptions(StringRef Params) {
1454 return PassBuilder::parseSinglePassOption(Params, "normalized-results",
1455 "DependenceAnalysisPrinter");
1456}
1457
1458Expected<bool> parseSeparateConstOffsetFromGEPPassOptions(StringRef Params) {
1459 return PassBuilder::parseSinglePassOption(Params, "lower-gep",
1460 "SeparateConstOffsetFromGEP");
1461}
1462
1463Expected<bool> parseStructurizeCFGPassOptions(StringRef Params) {
1464 return PassBuilder::parseSinglePassOption(Params, "skip-uniform-regions",
1465 "StructurizeCFG");
1466}
1467
1469parseFunctionSimplificationPipelineOptions(StringRef Params) {
1470 std::optional<OptimizationLevel> L = parseOptLevel(Params);
1471 if (!L || *L == OptimizationLevel::O0) {
1473 formatv("invalid function-simplification parameter '{}'", Params).str(),
1475 };
1476 return *L;
1477}
1478
1479Expected<bool> parseMemorySSAPrinterPassOptions(StringRef Params) {
1480 return PassBuilder::parseSinglePassOption(Params, "no-ensure-optimized-uses",
1481 "MemorySSAPrinterPass");
1482}
1483
1484Expected<bool> parseSpeculativeExecutionPassOptions(StringRef Params) {
1485 return PassBuilder::parseSinglePassOption(Params, "only-if-divergent-target",
1486 "SpeculativeExecutionPass");
1487}
1488
1489Expected<std::string> parseMemProfUsePassOptions(StringRef Params) {
1490 std::string Result;
1491 while (!Params.empty()) {
1492 StringRef ParamName;
1493 std::tie(ParamName, Params) = Params.split(';');
1494
1495 if (ParamName.consume_front("profile-filename=")) {
1496 Result = ParamName.str();
1497 } else {
1499 formatv("invalid MemProfUse pass parameter '{}'", ParamName).str(),
1501 }
1502 }
1503 return Result;
1504}
1505
1507parseStructuralHashPrinterPassOptions(StringRef Params) {
1508 if (Params.empty())
1510 if (Params == "detailed")
1512 if (Params == "call-target-ignored")
1515 formatv("invalid structural hash printer parameter '{}'", Params).str(),
1517}
1518
1519Expected<bool> parseWinEHPrepareOptions(StringRef Params) {
1520 return PassBuilder::parseSinglePassOption(Params, "demote-catchswitch-only",
1521 "WinEHPreparePass");
1522}
1523
1524Expected<GlobalMergeOptions> parseGlobalMergeOptions(StringRef Params) {
1526 while (!Params.empty()) {
1527 StringRef ParamName;
1528 std::tie(ParamName, Params) = Params.split(';');
1529
1530 bool Enable = !ParamName.consume_front("no-");
1531 if (ParamName == "group-by-use")
1532 Result.GroupByUse = Enable;
1533 else if (ParamName == "ignore-single-use")
1534 Result.IgnoreSingleUse = Enable;
1535 else if (ParamName == "merge-const")
1536 Result.MergeConstantGlobals = Enable;
1537 else if (ParamName == "merge-const-aggressive")
1538 Result.MergeConstAggressive = Enable;
1539 else if (ParamName == "merge-external")
1540 Result.MergeExternal = Enable;
1541 else if (ParamName.consume_front("max-offset=")) {
1542 if (ParamName.getAsInteger(0, Result.MaxOffset))
1544 formatv("invalid GlobalMergePass parameter '{}'", ParamName).str(),
1546 } else {
1548 formatv("invalid global-merge pass parameter '{}'", Params).str(),
1550 }
1551 }
1552 return Result;
1553}
1554
1555Expected<SmallVector<std::string, 0>> parseInternalizeGVs(StringRef Params) {
1556 SmallVector<std::string, 1> PreservedGVs;
1557 while (!Params.empty()) {
1558 StringRef ParamName;
1559 std::tie(ParamName, Params) = Params.split(';');
1560
1561 if (ParamName.consume_front("preserve-gv=")) {
1562 PreservedGVs.push_back(ParamName.str());
1563 } else {
1565 formatv("invalid Internalize pass parameter '{}'", ParamName).str(),
1567 }
1568 }
1569
1570 return Expected<SmallVector<std::string, 0>>(std::move(PreservedGVs));
1571}
1572
1574parseRegAllocFastPassOptions(PassBuilder &PB, StringRef Params) {
1576 while (!Params.empty()) {
1577 StringRef ParamName;
1578 std::tie(ParamName, Params) = Params.split(';');
1579
1580 if (ParamName.consume_front("filter=")) {
1581 std::optional<RegAllocFilterFunc> Filter =
1582 PB.parseRegAllocFilter(ParamName);
1583 if (!Filter) {
1585 formatv("invalid regallocfast register filter '{}'", ParamName)
1586 .str(),
1588 }
1589 Opts.Filter = *Filter;
1590 Opts.FilterName = ParamName;
1591 continue;
1592 }
1593
1594 if (ParamName == "no-clear-vregs") {
1595 Opts.ClearVRegs = false;
1596 continue;
1597 }
1598
1600 formatv("invalid regallocfast pass parameter '{}'", ParamName).str(),
1602 }
1603 return Opts;
1604}
1605
1607parseBoundsCheckingOptions(StringRef Params) {
1609 while (!Params.empty()) {
1610 StringRef ParamName;
1611 std::tie(ParamName, Params) = Params.split(';');
1612 if (ParamName == "trap") {
1613 Options.Rt = std::nullopt;
1614 } else if (ParamName == "rt") {
1615 Options.Rt = {
1616 /*MinRuntime=*/false,
1617 /*MayReturn=*/true,
1618 /*HandlerPreserveAllRegs=*/false,
1619 };
1620 } else if (ParamName == "rt-abort") {
1621 Options.Rt = {
1622 /*MinRuntime=*/false,
1623 /*MayReturn=*/false,
1624 /*HandlerPreserveAllRegs=*/false,
1625 };
1626 } else if (ParamName == "min-rt") {
1627 Options.Rt = {
1628 /*MinRuntime=*/true,
1629 /*MayReturn=*/true,
1630 /*HandlerPreserveAllRegs=*/false,
1631 };
1632 } else if (ParamName == "min-rt-abort") {
1633 Options.Rt = {
1634 /*MinRuntime=*/true,
1635 /*MayReturn=*/false,
1636 /*HandlerPreserveAllRegs=*/false,
1637 };
1638 } else if (ParamName == "merge") {
1639 Options.Merge = true;
1640 } else if (ParamName == "handler-preserve-all-regs") {
1641 if (Options.Rt)
1642 Options.Rt->HandlerPreserveAllRegs = true;
1643 } else {
1644 StringRef ParamEQ;
1645 StringRef Val;
1646 std::tie(ParamEQ, Val) = ParamName.split('=');
1647 int8_t Id;
1648 if (ParamEQ == "guard" && !Val.getAsInteger(0, Id)) {
1649 Options.GuardKind = Id;
1650 } else {
1652 formatv("invalid BoundsChecking pass parameter '{}'", ParamName)
1653 .str(),
1655 }
1656 }
1657 }
1658 return Options;
1659}
1660
1661Expected<CodeGenOptLevel> parseExpandIRInstsOptions(StringRef Param) {
1662 if (Param.empty())
1663 return CodeGenOptLevel::None;
1664
1665 // Parse a CodeGenOptLevel, e.g. "O1", "O2", "O3".
1666 auto [Prefix, Digit] = Param.split('O');
1667
1668 uint8_t N;
1669 if (!Prefix.empty() || Digit.getAsInteger(10, N))
1670 return createStringError("invalid expand-ir-insts pass parameter '%s'",
1671 Param.str().c_str());
1672
1673 std::optional<CodeGenOptLevel> Level = CodeGenOpt::getLevel(N);
1674 if (!Level.has_value())
1675 return createStringError(
1676 "invalid optimization level for expand-ir-insts pass: %s",
1677 Digit.str().c_str());
1678
1679 return *Level;
1680}
1681
1683parseRegAllocGreedyFilterFunc(PassBuilder &PB, StringRef Params) {
1684 if (Params.empty() || Params == "all")
1685 return RAGreedyPass::Options();
1686
1687 std::optional<RegAllocFilterFunc> Filter = PB.parseRegAllocFilter(Params);
1688 if (Filter)
1689 return RAGreedyPass::Options{*Filter, Params};
1690
1692 formatv("invalid regallocgreedy register filter '{}'", Params).str(),
1694}
1695
1696Expected<bool> parseMachineSinkingPassOptions(StringRef Params) {
1697 return PassBuilder::parseSinglePassOption(Params, "enable-sink-fold",
1698 "MachineSinkingPass");
1699}
1700
1701Expected<bool> parseMachineBlockPlacementPassOptions(StringRef Params) {
1702 bool AllowTailMerge = true;
1703 if (!Params.empty()) {
1704 AllowTailMerge = !Params.consume_front("no-");
1705 if (Params != "tail-merge")
1707 formatv("invalid MachineBlockPlacementPass parameter '{}'", Params)
1708 .str(),
1710 }
1711 return AllowTailMerge;
1712}
1713
1714Expected<bool> parseVirtRegRewriterPassOptions(StringRef Params) {
1715 bool ClearVirtRegs = true;
1716 if (!Params.empty()) {
1717 ClearVirtRegs = !Params.consume_front("no-");
1718 if (Params != "clear-vregs")
1720 formatv("invalid VirtRegRewriter pass parameter '{}'", Params).str(),
1722 }
1723 return ClearVirtRegs;
1724}
1725
1726struct FatLTOOptions {
1727 OptimizationLevel OptLevel;
1728 bool ThinLTO = false;
1729 bool EmitSummary = false;
1730};
1731
1732Expected<FatLTOOptions> parseFatLTOOptions(StringRef Params) {
1733 FatLTOOptions Result;
1734 bool HaveOptLevel = false;
1735 while (!Params.empty()) {
1736 StringRef ParamName;
1737 std::tie(ParamName, Params) = Params.split(';');
1738
1739 if (ParamName == "thinlto") {
1740 Result.ThinLTO = true;
1741 } else if (ParamName == "emit-summary") {
1742 Result.EmitSummary = true;
1743 } else if (std::optional<OptimizationLevel> OptLevel =
1744 parseOptLevel(ParamName)) {
1745 Result.OptLevel = *OptLevel;
1746 HaveOptLevel = true;
1747 } else {
1749 formatv("invalid fatlto-pre-link pass parameter '{}'", ParamName)
1750 .str(),
1752 }
1753 }
1754 if (!HaveOptLevel)
1756 "missing optimization level for fatlto-pre-link pipeline",
1758 return Result;
1759}
1760
1761} // namespace
1762
1763/// Tests whether registered callbacks will accept a given pass name.
1764///
1765/// When parsing a pipeline text, the type of the outermost pipeline may be
1766/// omitted, in which case the type is automatically determined from the first
1767/// pass name in the text. This may be a name that is handled through one of the
1768/// callbacks. We check this through the oridinary parsing callbacks by setting
1769/// up a dummy PassManager in order to not force the client to also handle this
1770/// type of query.
1771template <typename PassManagerT, typename CallbacksT>
1772static bool callbacksAcceptPassName(StringRef Name, CallbacksT &Callbacks) {
1773 if (!Callbacks.empty()) {
1774 PassManagerT DummyPM;
1775 for (auto &CB : Callbacks)
1776 if (CB(Name, DummyPM, {}))
1777 return true;
1778 }
1779 return false;
1780}
1781
1782template <typename CallbacksT>
1783static bool isModulePassName(StringRef Name, CallbacksT &Callbacks) {
1784 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1785
1786 // Explicitly handle pass manager names.
1787 if (Name == "module")
1788 return true;
1789 if (Name == "cgscc")
1790 return true;
1791 if (NameNoBracket == "function")
1792 return true;
1793 if (Name == "coro-cond")
1794 return true;
1795
1796#define MODULE_PASS(NAME, CREATE_PASS) \
1797 if (Name == NAME) \
1798 return true;
1799#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1800 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1801 return true;
1802#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
1803 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1804 return true;
1805#include "PassRegistry.def"
1806
1807 return callbacksAcceptPassName<ModulePassManager>(Name, Callbacks);
1808}
1809
1810template <typename CallbacksT>
1811static bool isCGSCCPassName(StringRef Name, CallbacksT &Callbacks) {
1812 // Explicitly handle pass manager names.
1813 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1814 if (Name == "cgscc")
1815 return true;
1816 if (NameNoBracket == "function")
1817 return true;
1818
1819 // Explicitly handle custom-parsed pass names.
1820 if (parseDevirtPassName(Name))
1821 return true;
1822
1823#define CGSCC_PASS(NAME, CREATE_PASS) \
1824 if (Name == NAME) \
1825 return true;
1826#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1827 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1828 return true;
1829#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
1830 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1831 return true;
1832#include "PassRegistry.def"
1833
1834 return callbacksAcceptPassName<CGSCCPassManager>(Name, Callbacks);
1835}
1836
1837template <typename CallbacksT>
1838static bool isFunctionPassName(StringRef Name, CallbacksT &Callbacks) {
1839 // Explicitly handle pass manager names.
1840 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1841 if (NameNoBracket == "function")
1842 return true;
1843 if (Name == "loop" || Name == "loop-mssa" || Name == "machine-function")
1844 return true;
1845
1846#define FUNCTION_PASS(NAME, CREATE_PASS) \
1847 if (Name == NAME) \
1848 return true;
1849#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1850 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1851 return true;
1852#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1853 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1854 return true;
1855#include "PassRegistry.def"
1856
1857 return callbacksAcceptPassName<FunctionPassManager>(Name, Callbacks);
1858}
1859
1860template <typename CallbacksT>
1861static bool isMachineFunctionPassName(StringRef Name, CallbacksT &Callbacks) {
1862 // Explicitly handle pass manager names.
1863 if (Name == "machine-function")
1864 return true;
1865
1866#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
1867 if (Name == NAME) \
1868 return true;
1869#define MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, \
1870 PARAMS) \
1871 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1872 return true;
1873
1874#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1875 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1876 return true;
1877
1878#include "llvm/Passes/MachinePassRegistry.def"
1879
1881}
1882
1883template <typename CallbacksT>
1884static bool isLoopNestPassName(StringRef Name, CallbacksT &Callbacks,
1885 bool &UseMemorySSA) {
1886 UseMemorySSA = false;
1887
1888 if (PassBuilder::checkParametrizedPassName(Name, "lnicm")) {
1889 UseMemorySSA = true;
1890 return true;
1891 }
1892
1893#define LOOPNEST_PASS(NAME, CREATE_PASS) \
1894 if (Name == NAME) \
1895 return true;
1896#include "PassRegistry.def"
1897
1898 return callbacksAcceptPassName<LoopPassManager>(Name, Callbacks);
1899}
1900
1901template <typename CallbacksT>
1902static bool isLoopPassName(StringRef Name, CallbacksT &Callbacks,
1903 bool &UseMemorySSA) {
1904 UseMemorySSA = false;
1905
1906 if (PassBuilder::checkParametrizedPassName(Name, "licm")) {
1907 UseMemorySSA = true;
1908 return true;
1909 }
1910
1911#define LOOP_PASS(NAME, CREATE_PASS) \
1912 if (Name == NAME) \
1913 return true;
1914#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1915 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1916 return true;
1917#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
1918 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1919 return true;
1920#include "PassRegistry.def"
1921
1922 return callbacksAcceptPassName<LoopPassManager>(Name, Callbacks);
1923}
1924
1925std::optional<std::vector<PassBuilder::PipelineElement>>
1926PassBuilder::parsePipelineText(StringRef Text) {
1927 std::vector<PipelineElement> ResultPipeline;
1928
1929 SmallVector<std::vector<PipelineElement> *, 4> PipelineStack = {
1930 &ResultPipeline};
1931 for (;;) {
1932 std::vector<PipelineElement> &Pipeline = *PipelineStack.back();
1933 size_t Pos = Text.find_first_of(",()");
1934 Pipeline.push_back({Text.substr(0, Pos), {}});
1935
1936 // If we have a single terminating name, we're done.
1937 if (Pos == Text.npos)
1938 break;
1939
1940 char Sep = Text[Pos];
1941 Text = Text.substr(Pos + 1);
1942 if (Sep == ',')
1943 // Just a name ending in a comma, continue.
1944 continue;
1945
1946 if (Sep == '(') {
1947 // Push the inner pipeline onto the stack to continue processing.
1948 PipelineStack.push_back(&Pipeline.back().InnerPipeline);
1949 continue;
1950 }
1951
1952 assert(Sep == ')' && "Bogus separator!");
1953 // When handling the close parenthesis, we greedily consume them to avoid
1954 // empty strings in the pipeline.
1955 do {
1956 // If we try to pop the outer pipeline we have unbalanced parentheses.
1957 if (PipelineStack.size() == 1)
1958 return std::nullopt;
1959
1960 PipelineStack.pop_back();
1961 } while (Text.consume_front(")"));
1962
1963 // Check if we've finished parsing.
1964 if (Text.empty())
1965 break;
1966
1967 // Otherwise, the end of an inner pipeline always has to be followed by
1968 // a comma, and then we can continue.
1969 if (!Text.consume_front(","))
1970 return std::nullopt;
1971 }
1972
1973 if (PipelineStack.size() > 1)
1974 // Unbalanced paretheses.
1975 return std::nullopt;
1976
1977 assert(PipelineStack.back() == &ResultPipeline &&
1978 "Wrong pipeline at the bottom of the stack!");
1979 return {std::move(ResultPipeline)};
1980}
1981
1984 PTO.LoopVectorization = L.getSpeedupLevel() > 1;
1985 PTO.SLPVectorization = L.getSpeedupLevel() > 1;
1986}
1987
1988Error PassBuilder::parseModulePass(ModulePassManager &MPM,
1989 const PipelineElement &E) {
1990 auto &Name = E.Name;
1991 auto &InnerPipeline = E.InnerPipeline;
1992
1993 // First handle complex passes like the pass managers which carry pipelines.
1994 if (!InnerPipeline.empty()) {
1995 if (Name == "module") {
1996 ModulePassManager NestedMPM;
1997 if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline))
1998 return Err;
1999 MPM.addPass(std::move(NestedMPM));
2000 return Error::success();
2001 }
2002 if (Name == "coro-cond") {
2003 ModulePassManager NestedMPM;
2004 if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline))
2005 return Err;
2006 MPM.addPass(CoroConditionalWrapper(std::move(NestedMPM)));
2007 return Error::success();
2008 }
2009 if (Name == "cgscc") {
2010 CGSCCPassManager CGPM;
2011 if (auto Err = parseCGSCCPassPipeline(CGPM, InnerPipeline))
2012 return Err;
2014 return Error::success();
2015 }
2016 if (auto Params = parseFunctionPipelineName(Name)) {
2017 if (Params->second)
2019 "cannot have a no-rerun module to function adaptor",
2022 if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline))
2023 return Err;
2024 MPM.addPass(
2025 createModuleToFunctionPassAdaptor(std::move(FPM), Params->first));
2026 return Error::success();
2027 }
2028
2029 for (auto &C : ModulePipelineParsingCallbacks)
2030 if (C(Name, MPM, InnerPipeline))
2031 return Error::success();
2032
2033 // Normal passes can't have pipelines.
2035 formatv("invalid use of '{}' pass as module pipeline", Name).str(),
2037 ;
2038 }
2039
2040 // Finally expand the basic registered passes from the .inc file.
2041#define MODULE_PASS(NAME, CREATE_PASS) \
2042 if (Name == NAME) { \
2043 MPM.addPass(CREATE_PASS); \
2044 return Error::success(); \
2045 }
2046#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2047 if (checkParametrizedPassName(Name, NAME)) { \
2048 auto Params = parsePassParameters(PARSER, Name, NAME); \
2049 if (!Params) \
2050 return Params.takeError(); \
2051 MPM.addPass(CREATE_PASS(Params.get())); \
2052 return Error::success(); \
2053 }
2054#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
2055 if (Name == "require<" NAME ">") { \
2056 MPM.addPass( \
2057 RequireAnalysisPass< \
2058 std::remove_reference_t<decltype(CREATE_PASS)>, Module>()); \
2059 return Error::success(); \
2060 } \
2061 if (Name == "invalidate<" NAME ">") { \
2062 MPM.addPass(InvalidateAnalysisPass< \
2063 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2064 return Error::success(); \
2065 }
2066#define CGSCC_PASS(NAME, CREATE_PASS) \
2067 if (Name == NAME) { \
2068 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(CREATE_PASS)); \
2069 return Error::success(); \
2070 }
2071#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2072 if (checkParametrizedPassName(Name, NAME)) { \
2073 auto Params = parsePassParameters(PARSER, Name, NAME); \
2074 if (!Params) \
2075 return Params.takeError(); \
2076 MPM.addPass( \
2077 createModuleToPostOrderCGSCCPassAdaptor(CREATE_PASS(Params.get()))); \
2078 return Error::success(); \
2079 }
2080#define FUNCTION_PASS(NAME, CREATE_PASS) \
2081 if (Name == NAME) { \
2082 if constexpr (std::is_constructible_v< \
2083 std::remove_reference_t<decltype(CREATE_PASS)>, \
2084 const TargetMachine &>) { \
2085 if (!TM) \
2086 return make_error<StringError>( \
2087 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2088 inconvertibleErrorCode()); \
2089 } \
2090 MPM.addPass(createModuleToFunctionPassAdaptor(CREATE_PASS)); \
2091 return Error::success(); \
2092 }
2093#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2094 if (checkParametrizedPassName(Name, NAME)) { \
2095 auto Params = parsePassParameters(PARSER, Name, NAME); \
2096 if (!Params) \
2097 return Params.takeError(); \
2098 auto CreatePass = CREATE_PASS; \
2099 if constexpr (std::is_constructible_v< \
2100 std::remove_reference_t<decltype(CreatePass( \
2101 Params.get()))>, \
2102 const TargetMachine &, \
2103 std::remove_reference_t<decltype(Params.get())>>) { \
2104 if (!TM) { \
2105 return make_error<StringError>( \
2106 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2107 inconvertibleErrorCode()); \
2108 } \
2109 } \
2110 MPM.addPass(createModuleToFunctionPassAdaptor(CREATE_PASS(Params.get()))); \
2111 return Error::success(); \
2112 }
2113#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2114 if (Name == NAME) { \
2115 MPM.addPass(createModuleToFunctionPassAdaptor( \
2116 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2117 return Error::success(); \
2118 }
2119#define LOOP_PASS(NAME, CREATE_PASS) \
2120 if (Name == NAME) { \
2121 MPM.addPass(createModuleToFunctionPassAdaptor( \
2122 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2123 return Error::success(); \
2124 }
2125#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2126 if (checkParametrizedPassName(Name, NAME)) { \
2127 auto Params = parsePassParameters(PARSER, Name, NAME); \
2128 if (!Params) \
2129 return Params.takeError(); \
2130 MPM.addPass(createModuleToFunctionPassAdaptor( \
2131 createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), false))); \
2132 return Error::success(); \
2133 }
2134#include "PassRegistry.def"
2135
2136 for (auto &C : ModulePipelineParsingCallbacks)
2137 if (C(Name, MPM, InnerPipeline))
2138 return Error::success();
2140 formatv("unknown module pass '{}'", Name).str(),
2142}
2143
2144Error PassBuilder::parseCGSCCPass(CGSCCPassManager &CGPM,
2145 const PipelineElement &E) {
2146 auto &Name = E.Name;
2147 auto &InnerPipeline = E.InnerPipeline;
2148
2149 // First handle complex passes like the pass managers which carry pipelines.
2150 if (!InnerPipeline.empty()) {
2151 if (Name == "cgscc") {
2152 CGSCCPassManager NestedCGPM;
2153 if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline))
2154 return Err;
2155 // Add the nested pass manager with the appropriate adaptor.
2156 CGPM.addPass(std::move(NestedCGPM));
2157 return Error::success();
2158 }
2159 if (auto Params = parseFunctionPipelineName(Name)) {
2161 if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline))
2162 return Err;
2163 // Add the nested pass manager with the appropriate adaptor.
2165 std::move(FPM), Params->first, Params->second));
2166 return Error::success();
2167 }
2168 if (auto MaxRepetitions = parseDevirtPassName(Name)) {
2169 CGSCCPassManager NestedCGPM;
2170 if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline))
2171 return Err;
2172 CGPM.addPass(
2173 createDevirtSCCRepeatedPass(std::move(NestedCGPM), *MaxRepetitions));
2174 return Error::success();
2175 }
2176
2177 for (auto &C : CGSCCPipelineParsingCallbacks)
2178 if (C(Name, CGPM, InnerPipeline))
2179 return Error::success();
2180
2181 // Normal passes can't have pipelines.
2183 formatv("invalid use of '{}' pass as cgscc pipeline", Name).str(),
2185 }
2186
2187// Now expand the basic registered passes from the .inc file.
2188#define CGSCC_PASS(NAME, CREATE_PASS) \
2189 if (Name == NAME) { \
2190 CGPM.addPass(CREATE_PASS); \
2191 return Error::success(); \
2192 }
2193#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2194 if (checkParametrizedPassName(Name, NAME)) { \
2195 auto Params = parsePassParameters(PARSER, Name, NAME); \
2196 if (!Params) \
2197 return Params.takeError(); \
2198 CGPM.addPass(CREATE_PASS(Params.get())); \
2199 return Error::success(); \
2200 }
2201#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
2202 if (Name == "require<" NAME ">") { \
2203 CGPM.addPass(RequireAnalysisPass< \
2204 std::remove_reference_t<decltype(CREATE_PASS)>, \
2205 LazyCallGraph::SCC, CGSCCAnalysisManager, LazyCallGraph &, \
2206 CGSCCUpdateResult &>()); \
2207 return Error::success(); \
2208 } \
2209 if (Name == "invalidate<" NAME ">") { \
2210 CGPM.addPass(InvalidateAnalysisPass< \
2211 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2212 return Error::success(); \
2213 }
2214#define FUNCTION_PASS(NAME, CREATE_PASS) \
2215 if (Name == NAME) { \
2216 if constexpr (std::is_constructible_v< \
2217 std::remove_reference_t<decltype(CREATE_PASS)>, \
2218 const TargetMachine &>) { \
2219 if (!TM) \
2220 return make_error<StringError>( \
2221 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2222 inconvertibleErrorCode()); \
2223 } \
2224 CGPM.addPass(createCGSCCToFunctionPassAdaptor(CREATE_PASS)); \
2225 return Error::success(); \
2226 }
2227#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2228 if (checkParametrizedPassName(Name, NAME)) { \
2229 auto Params = parsePassParameters(PARSER, Name, NAME); \
2230 if (!Params) \
2231 return Params.takeError(); \
2232 auto CreatePass = CREATE_PASS; \
2233 if constexpr (std::is_constructible_v< \
2234 std::remove_reference_t<decltype(CreatePass( \
2235 Params.get()))>, \
2236 const TargetMachine &, \
2237 std::remove_reference_t<decltype(Params.get())>>) { \
2238 if (!TM) { \
2239 return make_error<StringError>( \
2240 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2241 inconvertibleErrorCode()); \
2242 } \
2243 } \
2244 CGPM.addPass(createCGSCCToFunctionPassAdaptor(CREATE_PASS(Params.get()))); \
2245 return Error::success(); \
2246 }
2247#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2248 if (Name == NAME) { \
2249 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
2250 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2251 return Error::success(); \
2252 }
2253#define LOOP_PASS(NAME, CREATE_PASS) \
2254 if (Name == NAME) { \
2255 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
2256 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2257 return Error::success(); \
2258 }
2259#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2260 if (checkParametrizedPassName(Name, NAME)) { \
2261 auto Params = parsePassParameters(PARSER, Name, NAME); \
2262 if (!Params) \
2263 return Params.takeError(); \
2264 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
2265 createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), false))); \
2266 return Error::success(); \
2267 }
2268#include "PassRegistry.def"
2269
2270 for (auto &C : CGSCCPipelineParsingCallbacks)
2271 if (C(Name, CGPM, InnerPipeline))
2272 return Error::success();
2273 return make_error<StringError>(formatv("unknown cgscc pass '{}'", Name).str(),
2275}
2276
2277Error PassBuilder::parseFunctionPass(FunctionPassManager &FPM,
2278 const PipelineElement &E) {
2279 auto &Name = E.Name;
2280 auto &InnerPipeline = E.InnerPipeline;
2281
2282 // First handle complex passes like the pass managers which carry pipelines.
2283 if (!InnerPipeline.empty()) {
2284 if (Name == "function") {
2285 FunctionPassManager NestedFPM;
2286 if (auto Err = parseFunctionPassPipeline(NestedFPM, InnerPipeline))
2287 return Err;
2288 // Add the nested pass manager with the appropriate adaptor.
2289 FPM.addPass(std::move(NestedFPM));
2290 return Error::success();
2291 }
2292 if (Name == "loop" || Name == "loop-mssa") {
2293 LoopPassManager LPM;
2294 if (auto Err = parseLoopPassPipeline(LPM, InnerPipeline))
2295 return Err;
2296 // Add the nested pass manager with the appropriate adaptor.
2297 bool UseMemorySSA = (Name == "loop-mssa");
2298 FPM.addPass(
2299 createFunctionToLoopPassAdaptor(std::move(LPM), UseMemorySSA));
2300 return Error::success();
2301 }
2302 if (Name == "machine-function") {
2304 if (auto Err = parseMachinePassPipeline(MFPM, InnerPipeline))
2305 return Err;
2307 return Error::success();
2308 }
2309
2310 for (auto &C : FunctionPipelineParsingCallbacks)
2311 if (C(Name, FPM, InnerPipeline))
2312 return Error::success();
2313
2314 // Normal passes can't have pipelines.
2316 formatv("invalid use of '{}' pass as function pipeline", Name).str(),
2318 }
2319
2320// Now expand the basic registered passes from the .inc file.
2321#define FUNCTION_PASS(NAME, CREATE_PASS) \
2322 if (Name == NAME) { \
2323 if constexpr (std::is_constructible_v< \
2324 std::remove_reference_t<decltype(CREATE_PASS)>, \
2325 const TargetMachine &>) { \
2326 if (!TM) \
2327 return make_error<StringError>( \
2328 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2329 inconvertibleErrorCode()); \
2330 } \
2331 FPM.addPass(CREATE_PASS); \
2332 return Error::success(); \
2333 }
2334#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2335 if (checkParametrizedPassName(Name, NAME)) { \
2336 auto Params = parsePassParameters(PARSER, Name, NAME); \
2337 if (!Params) \
2338 return Params.takeError(); \
2339 auto CreatePass = CREATE_PASS; \
2340 if constexpr (std::is_constructible_v< \
2341 std::remove_reference_t<decltype(CreatePass( \
2342 Params.get()))>, \
2343 const TargetMachine &, \
2344 std::remove_reference_t<decltype(Params.get())>>) { \
2345 if (!TM) { \
2346 return make_error<StringError>( \
2347 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2348 inconvertibleErrorCode()); \
2349 } \
2350 } \
2351 FPM.addPass(CREATE_PASS(Params.get())); \
2352 return Error::success(); \
2353 }
2354#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
2355 if (Name == "require<" NAME ">") { \
2356 if constexpr (std::is_constructible_v< \
2357 std::remove_reference_t<decltype(CREATE_PASS)>, \
2358 const TargetMachine &>) { \
2359 if (!TM) \
2360 return make_error<StringError>( \
2361 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2362 inconvertibleErrorCode()); \
2363 } \
2364 FPM.addPass( \
2365 RequireAnalysisPass<std::remove_reference_t<decltype(CREATE_PASS)>, \
2366 Function>()); \
2367 return Error::success(); \
2368 } \
2369 if (Name == "invalidate<" NAME ">") { \
2370 FPM.addPass(InvalidateAnalysisPass< \
2371 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2372 return Error::success(); \
2373 }
2374// FIXME: UseMemorySSA is set to false. Maybe we could do things like:
2375// bool UseMemorySSA = !("canon-freeze" || "loop-predication" ||
2376// "guard-widening");
2377// The risk is that it may become obsolete if we're not careful.
2378#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2379 if (Name == NAME) { \
2380 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS, false)); \
2381 return Error::success(); \
2382 }
2383#define LOOP_PASS(NAME, CREATE_PASS) \
2384 if (Name == NAME) { \
2385 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS, false)); \
2386 return Error::success(); \
2387 }
2388#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2389 if (checkParametrizedPassName(Name, NAME)) { \
2390 auto Params = parsePassParameters(PARSER, Name, NAME); \
2391 if (!Params) \
2392 return Params.takeError(); \
2393 FPM.addPass( \
2394 createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), false)); \
2395 return Error::success(); \
2396 }
2397#include "PassRegistry.def"
2398
2399 for (auto &C : FunctionPipelineParsingCallbacks)
2400 if (C(Name, FPM, InnerPipeline))
2401 return Error::success();
2403 formatv("unknown function pass '{}'", Name).str(),
2405}
2406
2407Error PassBuilder::parseLoopPass(LoopPassManager &LPM,
2408 const PipelineElement &E) {
2409 StringRef Name = E.Name;
2410 auto &InnerPipeline = E.InnerPipeline;
2411
2412 // First handle complex passes like the pass managers which carry pipelines.
2413 if (!InnerPipeline.empty()) {
2414 if (Name == "loop") {
2415 LoopPassManager NestedLPM;
2416 if (auto Err = parseLoopPassPipeline(NestedLPM, InnerPipeline))
2417 return Err;
2418 // Add the nested pass manager with the appropriate adaptor.
2419 LPM.addPass(std::move(NestedLPM));
2420 return Error::success();
2421 }
2422
2423 for (auto &C : LoopPipelineParsingCallbacks)
2424 if (C(Name, LPM, InnerPipeline))
2425 return Error::success();
2426
2427 // Normal passes can't have pipelines.
2429 formatv("invalid use of '{}' pass as loop pipeline", Name).str(),
2431 }
2432
2433// Now expand the basic registered passes from the .inc file.
2434#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2435 if (Name == NAME) { \
2436 LPM.addPass(CREATE_PASS); \
2437 return Error::success(); \
2438 }
2439#define LOOP_PASS(NAME, CREATE_PASS) \
2440 if (Name == NAME) { \
2441 LPM.addPass(CREATE_PASS); \
2442 return Error::success(); \
2443 }
2444#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2445 if (checkParametrizedPassName(Name, NAME)) { \
2446 auto Params = parsePassParameters(PARSER, Name, NAME); \
2447 if (!Params) \
2448 return Params.takeError(); \
2449 LPM.addPass(CREATE_PASS(Params.get())); \
2450 return Error::success(); \
2451 }
2452#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
2453 if (Name == "require<" NAME ">") { \
2454 LPM.addPass(RequireAnalysisPass< \
2455 std::remove_reference_t<decltype(CREATE_PASS)>, Loop, \
2456 LoopAnalysisManager, LoopStandardAnalysisResults &, \
2457 LPMUpdater &>()); \
2458 return Error::success(); \
2459 } \
2460 if (Name == "invalidate<" NAME ">") { \
2461 LPM.addPass(InvalidateAnalysisPass< \
2462 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2463 return Error::success(); \
2464 }
2465#include "PassRegistry.def"
2466
2467 for (auto &C : LoopPipelineParsingCallbacks)
2468 if (C(Name, LPM, InnerPipeline))
2469 return Error::success();
2470 return make_error<StringError>(formatv("unknown loop pass '{}'", Name).str(),
2472}
2473
2474Error PassBuilder::parseMachinePass(MachineFunctionPassManager &MFPM,
2475 const PipelineElement &E) {
2476 StringRef Name = E.Name;
2477 // Handle any nested pass managers.
2478 if (!E.InnerPipeline.empty()) {
2479 if (E.Name == "machine-function") {
2481 if (auto Err = parseMachinePassPipeline(NestedPM, E.InnerPipeline))
2482 return Err;
2483 MFPM.addPass(std::move(NestedPM));
2484 return Error::success();
2485 }
2486 return make_error<StringError>("invalid pipeline",
2488 }
2489
2490#define MACHINE_MODULE_PASS(NAME, CREATE_PASS) \
2491 if (Name == NAME) { \
2492 MFPM.addPass(CREATE_PASS); \
2493 return Error::success(); \
2494 }
2495#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
2496 if (Name == NAME) { \
2497 MFPM.addPass(CREATE_PASS); \
2498 return Error::success(); \
2499 }
2500#define MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, \
2501 PARAMS) \
2502 if (checkParametrizedPassName(Name, NAME)) { \
2503 auto Params = parsePassParameters(PARSER, Name, NAME); \
2504 if (!Params) \
2505 return Params.takeError(); \
2506 MFPM.addPass(CREATE_PASS(Params.get())); \
2507 return Error::success(); \
2508 }
2509#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
2510 if (Name == "require<" NAME ">") { \
2511 MFPM.addPass( \
2512 RequireAnalysisPass<std::remove_reference_t<decltype(CREATE_PASS)>, \
2513 MachineFunction>()); \
2514 return Error::success(); \
2515 } \
2516 if (Name == "invalidate<" NAME ">") { \
2517 MFPM.addPass(InvalidateAnalysisPass< \
2518 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2519 return Error::success(); \
2520 }
2521#include "llvm/Passes/MachinePassRegistry.def"
2522
2523 for (auto &C : MachineFunctionPipelineParsingCallbacks)
2524 if (C(Name, MFPM, E.InnerPipeline))
2525 return Error::success();
2527 formatv("unknown machine pass '{}'", Name).str(),
2529}
2530
2531bool PassBuilder::parseAAPassName(AAManager &AA, StringRef Name) {
2532#define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
2533 if (Name == NAME) { \
2534 AA.registerModuleAnalysis< \
2535 std::remove_reference_t<decltype(CREATE_PASS)>>(); \
2536 return true; \
2537 }
2538#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
2539 if (Name == NAME) { \
2540 AA.registerFunctionAnalysis< \
2541 std::remove_reference_t<decltype(CREATE_PASS)>>(); \
2542 return true; \
2543 }
2544#include "PassRegistry.def"
2545
2546 for (auto &C : AAParsingCallbacks)
2547 if (C(Name, AA))
2548 return true;
2549 return false;
2550}
2551
2552Error PassBuilder::parseMachinePassPipeline(
2554 for (const auto &Element : Pipeline) {
2555 if (auto Err = parseMachinePass(MFPM, Element))
2556 return Err;
2557 }
2558 return Error::success();
2559}
2560
2561Error PassBuilder::parseLoopPassPipeline(LoopPassManager &LPM,
2562 ArrayRef<PipelineElement> Pipeline) {
2563 for (const auto &Element : Pipeline) {
2564 if (auto Err = parseLoopPass(LPM, Element))
2565 return Err;
2566 }
2567 return Error::success();
2568}
2569
2570Error PassBuilder::parseFunctionPassPipeline(
2572 for (const auto &Element : Pipeline) {
2573 if (auto Err = parseFunctionPass(FPM, Element))
2574 return Err;
2575 }
2576 return Error::success();
2577}
2578
2579Error PassBuilder::parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
2580 ArrayRef<PipelineElement> Pipeline) {
2581 for (const auto &Element : Pipeline) {
2582 if (auto Err = parseCGSCCPass(CGPM, Element))
2583 return Err;
2584 }
2585 return Error::success();
2586}
2587
2593 MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });
2594 MAM.registerPass([&] { return CGSCCAnalysisManagerModuleProxy(CGAM); });
2595 CGAM.registerPass([&] { return ModuleAnalysisManagerCGSCCProxy(MAM); });
2596 FAM.registerPass([&] { return CGSCCAnalysisManagerFunctionProxy(CGAM); });
2597 FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); });
2598 FAM.registerPass([&] { return LoopAnalysisManagerFunctionProxy(LAM); });
2599 LAM.registerPass([&] { return FunctionAnalysisManagerLoopProxy(FAM); });
2600 if (MFAM) {
2601 MAM.registerPass(
2602 [&] { return MachineFunctionAnalysisManagerModuleProxy(*MFAM); });
2603 FAM.registerPass(
2604 [&] { return MachineFunctionAnalysisManagerFunctionProxy(*MFAM); });
2605 MFAM->registerPass(
2607 MFAM->registerPass(
2609 }
2610}
2611
2612Error PassBuilder::parseModulePassPipeline(ModulePassManager &MPM,
2613 ArrayRef<PipelineElement> Pipeline) {
2614 for (const auto &Element : Pipeline) {
2615 if (auto Err = parseModulePass(MPM, Element))
2616 return Err;
2617 }
2618 return Error::success();
2619}
2620
2621// Primary pass pipeline description parsing routine for a \c ModulePassManager
2622// FIXME: Should this routine accept a TargetMachine or require the caller to
2623// pre-populate the analysis managers with target-specific stuff?
2625 StringRef PipelineText) {
2626 auto Pipeline = parsePipelineText(PipelineText);
2627 if (!Pipeline || Pipeline->empty())
2629 formatv("invalid pipeline '{}'", PipelineText).str(),
2631
2632 // If the first name isn't at the module layer, wrap the pipeline up
2633 // automatically.
2634 StringRef FirstName = Pipeline->front().Name;
2635
2636 if (!isModulePassName(FirstName, ModulePipelineParsingCallbacks)) {
2637 bool UseMemorySSA;
2638 if (isCGSCCPassName(FirstName, CGSCCPipelineParsingCallbacks)) {
2639 Pipeline = {{"cgscc", std::move(*Pipeline)}};
2640 } else if (isFunctionPassName(FirstName,
2641 FunctionPipelineParsingCallbacks)) {
2642 Pipeline = {{"function", std::move(*Pipeline)}};
2643 } else if (isLoopNestPassName(FirstName, LoopPipelineParsingCallbacks,
2644 UseMemorySSA)) {
2645 Pipeline = {{"function", {{UseMemorySSA ? "loop-mssa" : "loop",
2646 std::move(*Pipeline)}}}};
2647 } else if (isLoopPassName(FirstName, LoopPipelineParsingCallbacks,
2648 UseMemorySSA)) {
2649 Pipeline = {{"function", {{UseMemorySSA ? "loop-mssa" : "loop",
2650 std::move(*Pipeline)}}}};
2651 } else if (isMachineFunctionPassName(
2652 FirstName, MachineFunctionPipelineParsingCallbacks)) {
2653 Pipeline = {{"function", {{"machine-function", std::move(*Pipeline)}}}};
2654 } else {
2655 for (auto &C : TopLevelPipelineParsingCallbacks)
2656 if (C(MPM, *Pipeline))
2657 return Error::success();
2658
2659 // Unknown pass or pipeline name!
2660 auto &InnerPipeline = Pipeline->front().InnerPipeline;
2662 formatv("unknown {} name '{}'",
2663 (InnerPipeline.empty() ? "pass" : "pipeline"), FirstName)
2664 .str(),
2666 }
2667 }
2668
2669 if (auto Err = parseModulePassPipeline(MPM, *Pipeline))
2670 return Err;
2671 return Error::success();
2672}
2673
2674// Primary pass pipeline description parsing routine for a \c CGSCCPassManager
2676 StringRef PipelineText) {
2677 auto Pipeline = parsePipelineText(PipelineText);
2678 if (!Pipeline || Pipeline->empty())
2680 formatv("invalid pipeline '{}'", PipelineText).str(),
2682
2683 StringRef FirstName = Pipeline->front().Name;
2684 if (!isCGSCCPassName(FirstName, CGSCCPipelineParsingCallbacks))
2686 formatv("unknown cgscc pass '{}' in pipeline '{}'", FirstName,
2687 PipelineText)
2688 .str(),
2690
2691 if (auto Err = parseCGSCCPassPipeline(CGPM, *Pipeline))
2692 return Err;
2693 return Error::success();
2694}
2695
2696// Primary pass pipeline description parsing routine for a \c
2697// FunctionPassManager
2699 StringRef PipelineText) {
2700 auto Pipeline = parsePipelineText(PipelineText);
2701 if (!Pipeline || Pipeline->empty())
2703 formatv("invalid pipeline '{}'", PipelineText).str(),
2705
2706 StringRef FirstName = Pipeline->front().Name;
2707 if (!isFunctionPassName(FirstName, FunctionPipelineParsingCallbacks))
2709 formatv("unknown function pass '{}' in pipeline '{}'", FirstName,
2710 PipelineText)
2711 .str(),
2713
2714 if (auto Err = parseFunctionPassPipeline(FPM, *Pipeline))
2715 return Err;
2716 return Error::success();
2717}
2718
2719// Primary pass pipeline description parsing routine for a \c LoopPassManager
2721 StringRef PipelineText) {
2722 auto Pipeline = parsePipelineText(PipelineText);
2723 if (!Pipeline || Pipeline->empty())
2725 formatv("invalid pipeline '{}'", PipelineText).str(),
2727
2728 if (auto Err = parseLoopPassPipeline(CGPM, *Pipeline))
2729 return Err;
2730
2731 return Error::success();
2732}
2733
2735 StringRef PipelineText) {
2736 auto Pipeline = parsePipelineText(PipelineText);
2737 if (!Pipeline || Pipeline->empty())
2739 formatv("invalid machine pass pipeline '{}'", PipelineText).str(),
2741
2742 if (auto Err = parseMachinePassPipeline(MFPM, *Pipeline))
2743 return Err;
2744
2745 return Error::success();
2746}
2747
2749 // If the pipeline just consists of the word 'default' just replace the AA
2750 // manager with our default one.
2751 if (PipelineText == "default") {
2753 return Error::success();
2754 }
2755
2756 while (!PipelineText.empty()) {
2757 StringRef Name;
2758 std::tie(Name, PipelineText) = PipelineText.split(',');
2759 if (!parseAAPassName(AA, Name))
2761 formatv("unknown alias analysis name '{}'", Name).str(),
2763 }
2764
2765 return Error::success();
2766}
2767
2768std::optional<RegAllocFilterFunc>
2770 if (FilterName == "all")
2771 return nullptr;
2772 for (auto &C : RegClassFilterParsingCallbacks)
2773 if (auto F = C(FilterName))
2774 return F;
2775 return std::nullopt;
2776}
2777
2779 OS << " " << PassName << "\n";
2780}
2782 raw_ostream &OS) {
2783 OS << " " << PassName << "<" << Params << ">\n";
2784}
2785
2787 // TODO: print pass descriptions when they are available
2788
2789 OS << "Module passes:\n";
2790#define MODULE_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2791#include "PassRegistry.def"
2792
2793 OS << "Module passes with params:\n";
2794#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2795 printPassName(NAME, PARAMS, OS);
2796#include "PassRegistry.def"
2797
2798 OS << "Module analyses:\n";
2799#define MODULE_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2800#include "PassRegistry.def"
2801
2802 OS << "Module alias analyses:\n";
2803#define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2804#include "PassRegistry.def"
2805
2806 OS << "CGSCC passes:\n";
2807#define CGSCC_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2808#include "PassRegistry.def"
2809
2810 OS << "CGSCC passes with params:\n";
2811#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2812 printPassName(NAME, PARAMS, OS);
2813#include "PassRegistry.def"
2814
2815 OS << "CGSCC analyses:\n";
2816#define CGSCC_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2817#include "PassRegistry.def"
2818
2819 OS << "Function passes:\n";
2820#define FUNCTION_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2821#include "PassRegistry.def"
2822
2823 OS << "Function passes with params:\n";
2824#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2825 printPassName(NAME, PARAMS, OS);
2826#include "PassRegistry.def"
2827
2828 OS << "Function analyses:\n";
2829#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2830#include "PassRegistry.def"
2831
2832 OS << "Function alias analyses:\n";
2833#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2834#include "PassRegistry.def"
2835
2836 OS << "LoopNest passes:\n";
2837#define LOOPNEST_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2838#include "PassRegistry.def"
2839
2840 OS << "Loop passes:\n";
2841#define LOOP_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2842#include "PassRegistry.def"
2843
2844 OS << "Loop passes with params:\n";
2845#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2846 printPassName(NAME, PARAMS, OS);
2847#include "PassRegistry.def"
2848
2849 OS << "Loop analyses:\n";
2850#define LOOP_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2851#include "PassRegistry.def"
2852
2853 OS << "Machine module passes (WIP):\n";
2854#define MACHINE_MODULE_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2855#include "llvm/Passes/MachinePassRegistry.def"
2856
2857 OS << "Machine function passes (WIP):\n";
2858#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2859#include "llvm/Passes/MachinePassRegistry.def"
2860
2861 OS << "Machine function analyses (WIP):\n";
2862#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2863#include "llvm/Passes/MachinePassRegistry.def"
2864}
2865
2867 const std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>)>
2868 &C) {
2869 TopLevelPipelineParsingCallbacks.push_back(C);
2870}
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
AggressiveInstCombiner - Combine expression patterns to form expressions with fewer,...
This file implements a simple N^2 alias analysis accuracy evaluator.
Provides passes to inlining "always_inline" functions.
This is the interface for LLVM's primary stateless and local alias analysis.
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
This file provides the interface for LLVM's Call Graph Profile pass.
This header provides classes for managing passes over SCCs of the call graph.
Provides analysis for continuously CSEing during GISel passes.
This file provides interfaces used to build and manipulate a call graph, which is a very useful tool ...
Defines an IR pass for CodeGen Prepare.
This file declares an analysis pass that computes CycleInfo for LLVM IR, specialized from GenericCycl...
Analysis that tracks defined/used subregister lanes across COPY instructions and instructions that ge...
This file provides the interface for a simple, fast CSE pass.
This file provides a pass which clones the current module and runs the provided pass pipeline on the ...
Super simple passes to force specific function attrs from the commandline into the IR for debugging p...
Provides passes for computing function attributes based on interprocedural analyses.
This file provides the interface for the GCOV style profiler pass.
Provides analysis for querying information about KnownBits during GISel passes.
This file provides the interface for LLVM's Global Value Numbering pass which eliminates fully redund...
This is the interface for a simple mod/ref and alias analysis over globals.
Defines an IR pass for the creation of hardware loops.
#define _
AcceleratorCodeSelection - Identify all functions reachable from a kernel, removing those that are un...
This file defines the IR2Vec vocabulary analysis(IR2VecVocabAnalysis), the core ir2vec::Embedder inte...
This file defines passes to print out IR in various granularities.
This header defines various interfaces for pass management in LLVM.
Interfaces for passes which infer implicit function attributes from the name and signature of functio...
This file provides the primary interface to the instcombine pass.
Defines passes for running instruction simplification across chunks of IR.
This file provides the interface for LLVM's PGO Instrumentation lowering pass.
This file contains the declaration of the InterleavedAccessPass class, its corresponding pass name is...
See the comments on JumpThreadingPass.
static LVOptions Options
Definition LVOptions.cpp:25
Implements a lazy call graph analysis and related passes for the new pass manager.
This file defines the interface for the loop cache analysis.
This file provides the interface for LLVM's Loop Data Prefetching Pass.
This file implements the Loop Fusion pass.
This header defines the LoopLoadEliminationPass object.
This file defines the interface for the loop nest analysis.
This header provides classes for managing a pipeline of passes over loops in LLVM IR.
This file provides the interface for the pass responsible for removing expensive ubsan checks.
The header file for the LowerConstantIntrinsics pass as used by the new pass manager.
The header file for the LowerExpectIntrinsic pass as used by the new pass manager.
#define F(x, y, z)
Definition MD5.cpp:54
Machine Check Debug Module
Machine IR instance of the generic uniformity analysis.
This file exposes an interface to building/using memory SSA to walk memory instructions using a use/d...
This pass performs merges of loads and stores on both sides of a.
This is the interface to build a ModuleSummaryIndex for a module.
Contains a collection of routines for determining if a given instruction is guaranteed to execute if ...
This file provides the interface for LLVM's Global Value Numbering pass.
This file declares a simple ARC-aware AliasAnalysis using special knowledge of Objective C to enhance...
This header enumerates the LLVM-provided high-level optimization levels.
This file provides the interface for IR based instrumentation passes ( (profile-gen,...
CGSCCAnalysisManager CGAM
LoopAnalysisManager LAM
FunctionAnalysisManager FAM
ModuleAnalysisManager MAM
if(PassOpts->AAPipeline)
PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC)
static bool isModulePassName(StringRef Name, CallbacksT &Callbacks)
static bool callbacksAcceptPassName(StringRef Name, CallbacksT &Callbacks)
Tests whether registered callbacks will accept a given pass name.
static std::optional< int > parseDevirtPassName(StringRef Name)
static bool isLoopNestPassName(StringRef Name, CallbacksT &Callbacks, bool &UseMemorySSA)
static bool isMachineFunctionPassName(StringRef Name, CallbacksT &Callbacks)
static Expected< OptimizationLevel > parseOptLevelParam(StringRef S)
static std::optional< OptimizationLevel > parseOptLevel(StringRef S)
static bool isLoopPassName(StringRef Name, CallbacksT &Callbacks, bool &UseMemorySSA)
static std::optional< std::pair< bool, bool > > parseFunctionPipelineName(StringRef Name)
static bool isCGSCCPassName(StringRef Name, CallbacksT &Callbacks)
static void printPassName(StringRef PassName, raw_ostream &OS)
static bool isFunctionPassName(StringRef Name, CallbacksT &Callbacks)
static void setupOptionsForPipelineAlias(PipelineTuningOptions &PTO, OptimizationLevel L)
This file implements the PredicateInfo analysis, which creates an Extended SSA form for operations us...
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
This pass is required to take advantage of the interprocedural register allocation infrastructure.
This file implements relative lookup table converter that converts lookup tables to relative lookup t...
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.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction; 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".
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const MachineFunctionProperties & getProperties() const
Get the function properties.
LLVM_ABI Register createGenericVirtualRegister(LLT Ty, StringRef Name="")
Create and return a new generic virtual register with low-level type Ty.
static LLVM_ABI const OptimizationLevel O3
Optimize for fast execution as much as possible.
static LLVM_ABI const OptimizationLevel Oz
A very specialized mode that will optimize for code size at any and all costs.
static LLVM_ABI const OptimizationLevel O0
Disable as many optimizations as possible.
static LLVM_ABI const OptimizationLevel Os
Similar to O2 but tries to optimize for small code size instead of fast execution without triggering ...
static LLVM_ABI const OptimizationLevel O2
Optimize for fast execution as much as possible without triggering significant incremental compile ti...
static LLVM_ABI const OptimizationLevel O1
Optimize quickly without destroying debuggability.
This class provides access to building LLVM's passes.
LLVM_ABI void printPassNames(raw_ostream &OS)
Print pass names.
static bool checkParametrizedPassName(StringRef Name, StringRef PassName)
LLVM_ABI AAManager buildDefaultAAPipeline()
Build the default AAManager with the default alias analysis pipeline registered.
LLVM_ABI Error parseAAPipeline(AAManager &AA, StringRef PipelineText)
Parse a textual alias analysis pipeline into the provided AA manager.
LLVM_ABI void registerLoopAnalyses(LoopAnalysisManager &LAM)
Registers all available loop analysis passes.
LLVM_ABI std::optional< RegAllocFilterFunc > parseRegAllocFilter(StringRef RegAllocFilterName)
Parse RegAllocFilterName to get RegAllocFilterFunc.
LLVM_ABI void crossRegisterProxies(LoopAnalysisManager &LAM, FunctionAnalysisManager &FAM, CGSCCAnalysisManager &CGAM, ModuleAnalysisManager &MAM, MachineFunctionAnalysisManager *MFAM=nullptr)
Cross register the analysis managers through their proxies.
LLVM_ABI PassBuilder(TargetMachine *TM=nullptr, PipelineTuningOptions PTO=PipelineTuningOptions(), std::optional< PGOOptions > PGOOpt=std::nullopt, PassInstrumentationCallbacks *PIC=nullptr, IntrusiveRefCntPtr< vfs::FileSystem > FS=vfs::getRealFileSystem())
LLVM_ABI Error parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText)
Parse a textual pass pipeline description into a ModulePassManager.
void registerPipelineParsingCallback(const std::function< bool(StringRef Name, CGSCCPassManager &, ArrayRef< PipelineElement >)> &C)
{{@ Register pipeline parsing callbacks with this pass builder instance.
LLVM_ABI void registerModuleAnalyses(ModuleAnalysisManager &MAM)
Registers all available module analysis passes.
LLVM_ABI void registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM)
Registers all available CGSCC analysis passes.
static LLVM_ABI Expected< bool > parseSinglePassOption(StringRef Params, StringRef OptionName, StringRef PassName)
Handle passes only accept one bool-valued parameter.
LLVM_ABI void registerMachineFunctionAnalyses(MachineFunctionAnalysisManager &MFAM)
Registers all available machine function analysis passes.
LLVM_ABI void registerParseTopLevelPipelineCallback(const std::function< bool(ModulePassManager &, ArrayRef< PipelineElement >)> &C)
Register a callback for a top-level pipeline entry.
LLVM_ABI void registerFunctionAnalyses(FunctionAnalysisManager &FAM)
Registers all available function analysis passes.
This class manages callbacks registration, as well as provides a way for PassInstrumentation to pass ...
LLVM_ATTRIBUTE_MINSIZE std::enable_if_t<!std::is_same_v< PassT, PassManager > > addPass(PassT &&Pass)
Tunable parameters for passes in the default pipelines.
Definition PassBuilder.h:41
bool SLPVectorization
Tuning option to enable/disable slp loop vectorization, set based on opt level.
Definition PassBuilder.h:56
bool LoopVectorization
Tuning option to enable/disable loop vectorization, set based on opt level.
Definition PassBuilder.h:52
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition Analysis.h:115
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition StringRef.h:730
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
Definition StringRef.h:490
std::string str() const
str - Get the contents as an std::string.
Definition StringRef.h:222
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition StringRef.h:258
constexpr bool empty() const
empty - Check if the string is empty.
Definition StringRef.h:140
char front() const
front - Get the first character in the string.
Definition StringRef.h:146
bool consume_front(char Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
Definition StringRef.h:655
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
Primary interface to the complete machine description for the target machine.
self_iterator getIterator()
Definition ilist_node.h:123
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
Interfaces for registering analysis passes, producing common pass manager configurations,...
Abstract Attribute helper functions.
Definition Attributor.h:165
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
std::optional< CodeGenOptLevel > getLevel(int OL)
Get the Level identified by the integer OL.
Definition CodeGen.h:93
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:81
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
DropTestKind
Specifies how to drop type tests.
@ All
Drop only llvm.assumes using type test value.
This is an optimization pass for GlobalISel generic memory operations.
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:1917
PassManager< MachineFunction > MachineFunctionPassManager
Convenience typedef for a pass manager over functions.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI std::optional< AllocTokenMode > getAllocTokenModeFromString(StringRef Name)
Returns the AllocTokenMode from its canonical string name; if an invalid name was provided returns nu...
@ Detailed
Hash with opcode only.
@ CallTargetIgnored
Hash with opcode and operands.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition MIRParser.h:39
@ Enable
Enable colors.
Definition WithColor.h:47
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:870
#define N
A special type used by analysis passes to provide an address that identifies that particular analysis...
Definition Analysis.h:29
A set of parameters to control various transforms performed by GVN pass.
Definition GVN.h:78
HardwareLoopOptions & setForceNested(bool Force)
HardwareLoopOptions & setDecrement(unsigned Count)
HardwareLoopOptions & setForceGuard(bool Force)
HardwareLoopOptions & setForce(bool Force)
HardwareLoopOptions & setCounterBitwidth(unsigned Width)
HardwareLoopOptions & setForcePhi(bool Force)
A set of parameters to control various transforms performed by IPSCCP pass.
Definition SCCP.h:35
A set of parameters used to control various transforms performed by the LoopUnroll pass.
LoopUnrollOptions & setPeeling(bool Peeling)
Enables or disables loop peeling.
LoopUnrollOptions & setOptLevel(int O)
LoopUnrollOptions & setPartial(bool Partial)
Enables or disables partial unrolling.
LoopUnrollOptions & setFullUnrollMaxCount(unsigned O)
LoopUnrollOptions & setUpperBound(bool UpperBound)
Enables or disables the use of trip count upper bound in loop unrolling.
LoopUnrollOptions & setRuntime(bool Runtime)
Enables or disables unrolling of loops with runtime trip count.
LoopUnrollOptions & setProfileBasedPeeling(int O)
LoopVectorizeOptions & setVectorizeOnlyWhenForced(bool Value)
LoopVectorizeOptions & setInterleaveOnlyWhenForced(bool Value)
A CRTP mix-in to automatically provide informational APIs needed for passes.
Definition PassManager.h:70