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