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