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