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 FAM.registerPass([&] { return CREATE_PASS; });
673#include "PassRegistry.def"
674
675 for (auto &C : FunctionAnalysisRegistrationCallbacks)
676 C(FAM);
677}
678
681
682#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
683 MFAM.registerPass([&] { return CREATE_PASS; });
684#include "llvm/Passes/MachinePassRegistry.def"
685
686 for (auto &C : MachineFunctionAnalysisRegistrationCallbacks)
687 C(MFAM);
688}
689
691#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
692 LAM.registerPass([&] { return CREATE_PASS; });
693#include "PassRegistry.def"
694
695 for (auto &C : LoopAnalysisRegistrationCallbacks)
696 C(LAM);
697}
698
699static std::optional<std::pair<bool, bool>>
701 std::pair<bool, bool> Params;
702 if (!Name.consume_front("function"))
703 return std::nullopt;
704 if (Name.empty())
705 return Params;
706 if (!Name.consume_front("<") || !Name.consume_back(">"))
707 return std::nullopt;
708 while (!Name.empty()) {
709 auto [Front, Back] = Name.split(';');
710 Name = Back;
711 if (Front == "eager-inv")
712 Params.first = true;
713 else if (Front == "no-rerun")
714 Params.second = true;
715 else
716 return std::nullopt;
717 }
718 return Params;
719}
720
721static std::optional<int> parseDevirtPassName(StringRef Name) {
722 if (!Name.consume_front("devirt<") || !Name.consume_back(">"))
723 return std::nullopt;
724 int Count;
725 if (Name.getAsInteger(0, Count) || Count < 0)
726 return std::nullopt;
727 return Count;
728}
729
731 StringRef OptionName,
733 bool Result = false;
734 while (!Params.empty()) {
735 StringRef ParamName;
736 std::tie(ParamName, Params) = Params.split(';');
737
738 if (ParamName == OptionName) {
739 Result = true;
740 } else {
742 formatv("invalid {} pass parameter '{}'", PassName, ParamName).str(),
744 }
745 }
746 return Result;
747}
748
749namespace {
750
751/// Parser of parameters for HardwareLoops pass.
752Expected<HardwareLoopOptions> parseHardwareLoopOptions(StringRef Params) {
753 HardwareLoopOptions HardwareLoopOpts;
754
755 while (!Params.empty()) {
756 StringRef ParamName;
757 std::tie(ParamName, Params) = Params.split(';');
758 if (ParamName.consume_front("hardware-loop-decrement=")) {
759 int Count;
760 if (ParamName.getAsInteger(0, Count))
762 formatv("invalid HardwareLoopPass parameter '{}'", ParamName).str(),
764 HardwareLoopOpts.setDecrement(Count);
765 continue;
766 }
767 if (ParamName.consume_front("hardware-loop-counter-bitwidth=")) {
768 int Count;
769 if (ParamName.getAsInteger(0, Count))
771 formatv("invalid HardwareLoopPass parameter '{}'", ParamName).str(),
773 HardwareLoopOpts.setCounterBitwidth(Count);
774 continue;
775 }
776 if (ParamName == "force-hardware-loops") {
777 HardwareLoopOpts.setForce(true);
778 } else if (ParamName == "force-hardware-loop-phi") {
779 HardwareLoopOpts.setForcePhi(true);
780 } else if (ParamName == "force-nested-hardware-loop") {
781 HardwareLoopOpts.setForceNested(true);
782 } else if (ParamName == "force-hardware-loop-guard") {
783 HardwareLoopOpts.setForceGuard(true);
784 } else {
786 formatv("invalid HardwarePass parameter '{}'", ParamName).str(),
788 }
789 }
790 return HardwareLoopOpts;
791}
792
793/// Parser of parameters for Lint pass.
794Expected<bool> parseLintOptions(StringRef Params) {
795 return PassBuilder::parseSinglePassOption(Params, "abort-on-error",
796 "LintPass");
797}
798
799/// Parser of parameters for LoopUnroll pass.
800Expected<LoopUnrollOptions> parseLoopUnrollOptions(StringRef Params) {
801 LoopUnrollOptions UnrollOpts;
802 while (!Params.empty()) {
803 StringRef ParamName;
804 std::tie(ParamName, Params) = Params.split(';');
805 std::optional<OptimizationLevel> OptLevel = parseOptLevel(ParamName);
806 // Don't accept -Os/-Oz.
807 if (OptLevel && !OptLevel->isOptimizingForSize()) {
808 UnrollOpts.setOptLevel(OptLevel->getSpeedupLevel());
809 continue;
810 }
811 if (ParamName.consume_front("full-unroll-max=")) {
812 int Count;
813 if (ParamName.getAsInteger(0, Count))
815 formatv("invalid LoopUnrollPass parameter '{}'", ParamName).str(),
817 UnrollOpts.setFullUnrollMaxCount(Count);
818 continue;
819 }
820
821 bool Enable = !ParamName.consume_front("no-");
822 if (ParamName == "partial") {
823 UnrollOpts.setPartial(Enable);
824 } else if (ParamName == "peeling") {
825 UnrollOpts.setPeeling(Enable);
826 } else if (ParamName == "profile-peeling") {
827 UnrollOpts.setProfileBasedPeeling(Enable);
828 } else if (ParamName == "runtime") {
829 UnrollOpts.setRuntime(Enable);
830 } else if (ParamName == "upperbound") {
831 UnrollOpts.setUpperBound(Enable);
832 } else {
834 formatv("invalid LoopUnrollPass parameter '{}'", ParamName).str(),
836 }
837 }
838 return UnrollOpts;
839}
840
841Expected<bool> parseGlobalDCEPassOptions(StringRef Params) {
843 Params, "vfe-linkage-unit-visibility", "GlobalDCE");
844}
845
846Expected<bool> parseCGProfilePassOptions(StringRef Params) {
847 return PassBuilder::parseSinglePassOption(Params, "in-lto-post-link",
848 "CGProfile");
849}
850
851Expected<bool> parseInlinerPassOptions(StringRef Params) {
852 return PassBuilder::parseSinglePassOption(Params, "only-mandatory",
853 "InlinerPass");
854}
855
856Expected<bool> parseCoroSplitPassOptions(StringRef Params) {
857 return PassBuilder::parseSinglePassOption(Params, "reuse-storage",
858 "CoroSplitPass");
859}
860
861Expected<bool> parsePostOrderFunctionAttrsPassOptions(StringRef Params) {
863 Params, "skip-non-recursive-function-attrs", "PostOrderFunctionAttrs");
864}
865
866Expected<CFGuardPass::Mechanism> parseCFGuardPassOptions(StringRef Params) {
867 if (Params.empty())
869
870 auto [Param, RHS] = Params.split(';');
871 if (!RHS.empty())
873 formatv("too many CFGuardPass parameters '{}'", Params).str(),
875
876 if (Param == "check")
878 if (Param == "dispatch")
880
882 formatv("invalid CFGuardPass mechanism: '{}'", Param).str(),
884}
885
886Expected<bool> parseEarlyCSEPassOptions(StringRef Params) {
887 return PassBuilder::parseSinglePassOption(Params, "memssa", "EarlyCSE");
888}
889
890Expected<bool> parseEntryExitInstrumenterPassOptions(StringRef Params) {
891 return PassBuilder::parseSinglePassOption(Params, "post-inline",
892 "EntryExitInstrumenter");
893}
894
895Expected<bool> parseLoopExtractorPassOptions(StringRef Params) {
896 return PassBuilder::parseSinglePassOption(Params, "single", "LoopExtractor");
897}
898
899Expected<bool> parseLowerMatrixIntrinsicsPassOptions(StringRef Params) {
900 return PassBuilder::parseSinglePassOption(Params, "minimal",
901 "LowerMatrixIntrinsics");
902}
903
904Expected<IRNormalizerOptions> parseIRNormalizerPassOptions(StringRef Params) {
906 while (!Params.empty()) {
907 StringRef ParamName;
908 std::tie(ParamName, Params) = Params.split(';');
909
910 bool Enable = !ParamName.consume_front("no-");
911 if (ParamName == "preserve-order")
912 Result.PreserveOrder = Enable;
913 else if (ParamName == "rename-all")
914 Result.RenameAll = Enable;
915 else if (ParamName == "fold-all") // FIXME: Name mismatch
916 Result.FoldPreOutputs = Enable;
917 else if (ParamName == "reorder-operands")
918 Result.ReorderOperands = Enable;
919 else {
921 formatv("invalid normalize pass parameter '{}'", ParamName).str(),
923 }
924 }
925
926 return Result;
927}
928
929Expected<AddressSanitizerOptions> parseASanPassOptions(StringRef Params) {
931 while (!Params.empty()) {
932 StringRef ParamName;
933 std::tie(ParamName, Params) = Params.split(';');
934
935 if (ParamName == "kernel") {
936 Result.CompileKernel = true;
937 } else if (ParamName == "use-after-scope") {
938 Result.UseAfterScope = true;
939 } else {
941 formatv("invalid AddressSanitizer pass parameter '{}'", ParamName)
942 .str(),
944 }
945 }
946 return Result;
947}
948
949Expected<HWAddressSanitizerOptions> parseHWASanPassOptions(StringRef Params) {
951 while (!Params.empty()) {
952 StringRef ParamName;
953 std::tie(ParamName, Params) = Params.split(';');
954
955 if (ParamName == "recover") {
956 Result.Recover = true;
957 } else if (ParamName == "kernel") {
958 Result.CompileKernel = true;
959 } else {
961 formatv("invalid HWAddressSanitizer pass parameter '{}'", ParamName)
962 .str(),
964 }
965 }
966 return Result;
967}
968
969Expected<EmbedBitcodeOptions> parseEmbedBitcodePassOptions(StringRef Params) {
971 while (!Params.empty()) {
972 StringRef ParamName;
973 std::tie(ParamName, Params) = Params.split(';');
974
975 if (ParamName == "thinlto") {
976 Result.IsThinLTO = true;
977 } else if (ParamName == "emit-summary") {
978 Result.EmitLTOSummary = true;
979 } else {
981 formatv("invalid EmbedBitcode pass parameter '{}'", ParamName).str(),
983 }
984 }
985 return Result;
986}
987
989parseLowerAllowCheckPassOptions(StringRef Params) {
991 while (!Params.empty()) {
992 StringRef ParamName;
993 std::tie(ParamName, Params) = Params.split(';');
994
995 // Format is <cutoffs[1,2,3]=70000;cutoffs[5,6,8]=90000>
996 //
997 // Parsing allows duplicate indices (last one takes precedence).
998 // It would technically be in spec to specify
999 // cutoffs[0]=70000,cutoffs[1]=90000,cutoffs[0]=80000,...
1000 if (ParamName.starts_with("cutoffs[")) {
1001 StringRef IndicesStr;
1002 StringRef CutoffStr;
1003
1004 std::tie(IndicesStr, CutoffStr) = ParamName.split("]=");
1005 // cutoffs[1,2,3
1006 // 70000
1007
1008 int cutoff;
1009 if (CutoffStr.getAsInteger(0, cutoff))
1011 formatv("invalid LowerAllowCheck pass cutoffs parameter '{}' ({})",
1012 CutoffStr, Params)
1013 .str(),
1015
1016 if (!IndicesStr.consume_front("cutoffs[") || IndicesStr == "")
1018 formatv("invalid LowerAllowCheck pass index parameter '{}' ({})",
1019 IndicesStr, CutoffStr)
1020 .str(),
1022
1023 while (IndicesStr != "") {
1024 StringRef firstIndexStr;
1025 std::tie(firstIndexStr, IndicesStr) = IndicesStr.split('|');
1026
1027 unsigned int index;
1028 if (firstIndexStr.getAsInteger(0, index))
1030 formatv(
1031 "invalid LowerAllowCheck pass index parameter '{}' ({}) {}",
1032 firstIndexStr, IndicesStr)
1033 .str(),
1035
1036 // In the common case (sequentially increasing indices), we will issue
1037 // O(n) resize requests. We assume the underlying data structure has
1038 // O(1) runtime for each added element.
1039 if (index >= Result.cutoffs.size())
1040 Result.cutoffs.resize(index + 1, 0);
1041
1042 Result.cutoffs[index] = cutoff;
1043 }
1044 } else if (ParamName.starts_with("runtime_check")) {
1045 StringRef ValueString;
1046 std::tie(std::ignore, ValueString) = ParamName.split("=");
1047 int runtime_check;
1048 if (ValueString.getAsInteger(0, runtime_check)) {
1050 formatv("invalid LowerAllowCheck pass runtime_check parameter '{}' "
1051 "({})",
1052 ValueString, Params)
1053 .str(),
1055 }
1056 Result.runtime_check = runtime_check;
1057 } else {
1059 formatv("invalid LowerAllowCheck pass parameter '{}'", ParamName)
1060 .str(),
1062 }
1063 }
1064
1065 return Result;
1066}
1067
1068Expected<MemorySanitizerOptions> parseMSanPassOptions(StringRef Params) {
1070 while (!Params.empty()) {
1071 StringRef ParamName;
1072 std::tie(ParamName, Params) = Params.split(';');
1073
1074 if (ParamName == "recover") {
1075 Result.Recover = true;
1076 } else if (ParamName == "kernel") {
1077 Result.Kernel = true;
1078 } else if (ParamName.consume_front("track-origins=")) {
1079 if (ParamName.getAsInteger(0, Result.TrackOrigins))
1081 formatv("invalid argument to MemorySanitizer pass track-origins "
1082 "parameter: '{}'",
1083 ParamName)
1084 .str(),
1086 } else if (ParamName == "eager-checks") {
1087 Result.EagerChecks = true;
1088 } else {
1090 formatv("invalid MemorySanitizer pass parameter '{}'", ParamName)
1091 .str(),
1093 }
1094 }
1095 return Result;
1096}
1097
1098/// Parser of parameters for SimplifyCFG pass.
1099Expected<SimplifyCFGOptions> parseSimplifyCFGOptions(StringRef Params) {
1101 while (!Params.empty()) {
1102 StringRef ParamName;
1103 std::tie(ParamName, Params) = Params.split(';');
1104
1105 bool Enable = !ParamName.consume_front("no-");
1106 if (ParamName == "speculate-blocks") {
1107 Result.speculateBlocks(Enable);
1108 } else if (ParamName == "simplify-cond-branch") {
1109 Result.setSimplifyCondBranch(Enable);
1110 } else if (ParamName == "forward-switch-cond") {
1111 Result.forwardSwitchCondToPhi(Enable);
1112 } else if (ParamName == "switch-range-to-icmp") {
1113 Result.convertSwitchRangeToICmp(Enable);
1114 } else if (ParamName == "switch-to-lookup") {
1115 Result.convertSwitchToLookupTable(Enable);
1116 } else if (ParamName == "keep-loops") {
1117 Result.needCanonicalLoops(Enable);
1118 } else if (ParamName == "hoist-common-insts") {
1119 Result.hoistCommonInsts(Enable);
1120 } else if (ParamName == "hoist-loads-stores-with-cond-faulting") {
1121 Result.hoistLoadsStoresWithCondFaulting(Enable);
1122 } else if (ParamName == "sink-common-insts") {
1123 Result.sinkCommonInsts(Enable);
1124 } else if (ParamName == "speculate-unpredictables") {
1125 Result.speculateUnpredictables(Enable);
1126 } else if (Enable && ParamName.consume_front("bonus-inst-threshold=")) {
1127 APInt BonusInstThreshold;
1128 if (ParamName.getAsInteger(0, BonusInstThreshold))
1130 formatv("invalid argument to SimplifyCFG pass bonus-threshold "
1131 "parameter: '{}'",
1132 ParamName)
1133 .str(),
1135 Result.bonusInstThreshold(BonusInstThreshold.getSExtValue());
1136 } else {
1138 formatv("invalid SimplifyCFG pass parameter '{}'", ParamName).str(),
1140 }
1141 }
1142 return Result;
1143}
1144
1145Expected<InstCombineOptions> parseInstCombineOptions(StringRef Params) {
1147 // When specifying "instcombine" in -passes enable fix-point verification by
1148 // default, as this is what most tests should use.
1149 Result.setVerifyFixpoint(true);
1150 while (!Params.empty()) {
1151 StringRef ParamName;
1152 std::tie(ParamName, Params) = Params.split(';');
1153
1154 bool Enable = !ParamName.consume_front("no-");
1155 if (ParamName == "verify-fixpoint") {
1156 Result.setVerifyFixpoint(Enable);
1157 } else if (Enable && ParamName.consume_front("max-iterations=")) {
1158 APInt MaxIterations;
1159 if (ParamName.getAsInteger(0, MaxIterations))
1161 formatv("invalid argument to InstCombine pass max-iterations "
1162 "parameter: '{}'",
1163 ParamName)
1164 .str(),
1166 Result.setMaxIterations((unsigned)MaxIterations.getZExtValue());
1167 } else {
1169 formatv("invalid InstCombine pass parameter '{}'", ParamName).str(),
1171 }
1172 }
1173 return Result;
1174}
1175
1176/// Parser of parameters for LoopVectorize pass.
1177Expected<LoopVectorizeOptions> parseLoopVectorizeOptions(StringRef Params) {
1179 while (!Params.empty()) {
1180 StringRef ParamName;
1181 std::tie(ParamName, Params) = Params.split(';');
1182
1183 bool Enable = !ParamName.consume_front("no-");
1184 if (ParamName == "interleave-forced-only") {
1186 } else if (ParamName == "vectorize-forced-only") {
1188 } else {
1190 formatv("invalid LoopVectorize parameter '{}'", ParamName).str(),
1192 }
1193 }
1194 return Opts;
1195}
1196
1197Expected<std::pair<bool, bool>> parseLoopUnswitchOptions(StringRef Params) {
1198 std::pair<bool, bool> Result = {false, true};
1199 while (!Params.empty()) {
1200 StringRef ParamName;
1201 std::tie(ParamName, Params) = Params.split(';');
1202
1203 bool Enable = !ParamName.consume_front("no-");
1204 if (ParamName == "nontrivial") {
1205 Result.first = Enable;
1206 } else if (ParamName == "trivial") {
1207 Result.second = Enable;
1208 } else {
1210 formatv("invalid LoopUnswitch pass parameter '{}'", ParamName).str(),
1212 }
1213 }
1214 return Result;
1215}
1216
1217Expected<LICMOptions> parseLICMOptions(StringRef Params) {
1219 while (!Params.empty()) {
1220 StringRef ParamName;
1221 std::tie(ParamName, Params) = Params.split(';');
1222
1223 bool Enable = !ParamName.consume_front("no-");
1224 if (ParamName == "allowspeculation") {
1225 Result.AllowSpeculation = Enable;
1226 } else {
1228 formatv("invalid LICM pass parameter '{}'", ParamName).str(),
1230 }
1231 }
1232 return Result;
1233}
1234
1235Expected<std::pair<bool, bool>> parseLoopRotateOptions(StringRef Params) {
1236 std::pair<bool, bool> Result = {true, false};
1237 while (!Params.empty()) {
1238 StringRef ParamName;
1239 std::tie(ParamName, Params) = Params.split(';');
1240
1241 bool Enable = !ParamName.consume_front("no-");
1242 if (ParamName == "header-duplication") {
1243 Result.first = Enable;
1244 } else if (ParamName == "prepare-for-lto") {
1245 Result.second = Enable;
1246 } else {
1248 formatv("invalid LoopRotate pass parameter '{}'", ParamName).str(),
1250 }
1251 }
1252 return Result;
1253}
1254
1255Expected<bool> parseMergedLoadStoreMotionOptions(StringRef Params) {
1256 bool Result = false;
1257 while (!Params.empty()) {
1258 StringRef ParamName;
1259 std::tie(ParamName, Params) = Params.split(';');
1260
1261 bool Enable = !ParamName.consume_front("no-");
1262 if (ParamName == "split-footer-bb") {
1263 Result = Enable;
1264 } else {
1266 formatv("invalid MergedLoadStoreMotion pass parameter '{}'",
1267 ParamName)
1268 .str(),
1270 }
1271 }
1272 return Result;
1273}
1274
1275Expected<GVNOptions> parseGVNOptions(StringRef Params) {
1277 while (!Params.empty()) {
1278 StringRef ParamName;
1279 std::tie(ParamName, Params) = Params.split(';');
1280
1281 bool Enable = !ParamName.consume_front("no-");
1282 if (ParamName == "pre") {
1283 Result.setPRE(Enable);
1284 } else if (ParamName == "load-pre") {
1285 Result.setLoadPRE(Enable);
1286 } else if (ParamName == "split-backedge-load-pre") {
1287 Result.setLoadPRESplitBackedge(Enable);
1288 } else if (ParamName == "memdep") {
1289 // MemDep and MemorySSA are mutually exclusive.
1290 Result.setMemDep(Enable);
1291 Result.setMemorySSA(!Enable);
1292 } else if (ParamName == "memoryssa") {
1293 // MemDep and MemorySSA are mutually exclusive.
1294 Result.setMemorySSA(Enable);
1295 Result.setMemDep(!Enable);
1296 } else {
1298 formatv("invalid GVN pass parameter '{}'", ParamName).str(),
1300 }
1301 }
1302 return Result;
1303}
1304
1305Expected<IPSCCPOptions> parseIPSCCPOptions(StringRef Params) {
1307 while (!Params.empty()) {
1308 StringRef ParamName;
1309 std::tie(ParamName, Params) = Params.split(';');
1310
1311 bool Enable = !ParamName.consume_front("no-");
1312 if (ParamName == "func-spec")
1313 Result.setFuncSpec(Enable);
1314 else
1316 formatv("invalid IPSCCP pass parameter '{}'", ParamName).str(),
1318 }
1319 return Result;
1320}
1321
1322Expected<ScalarizerPassOptions> parseScalarizerOptions(StringRef Params) {
1324 while (!Params.empty()) {
1325 StringRef ParamName;
1326 std::tie(ParamName, Params) = Params.split(';');
1327
1328 if (ParamName.consume_front("min-bits=")) {
1329 if (ParamName.getAsInteger(0, Result.ScalarizeMinBits)) {
1331 formatv("invalid argument to Scalarizer pass min-bits "
1332 "parameter: '{}'",
1333 ParamName)
1334 .str(),
1336 }
1337
1338 continue;
1339 }
1340
1341 bool Enable = !ParamName.consume_front("no-");
1342 if (ParamName == "load-store")
1343 Result.ScalarizeLoadStore = Enable;
1344 else if (ParamName == "variable-insert-extract")
1345 Result.ScalarizeVariableInsertExtract = Enable;
1346 else {
1348 formatv("invalid Scalarizer pass parameter '{}'", ParamName).str(),
1350 }
1351 }
1352
1353 return Result;
1354}
1355
1356Expected<SROAOptions> parseSROAOptions(StringRef Params) {
1357 if (Params.empty() || Params == "modify-cfg")
1359 if (Params == "preserve-cfg")
1362 formatv("invalid SROA pass parameter '{}' (either preserve-cfg or "
1363 "modify-cfg can be specified)",
1364 Params)
1365 .str(),
1367}
1368
1370parseStackLifetimeOptions(StringRef Params) {
1372 while (!Params.empty()) {
1373 StringRef ParamName;
1374 std::tie(ParamName, Params) = Params.split(';');
1375
1376 if (ParamName == "may") {
1378 } else if (ParamName == "must") {
1380 } else {
1382 formatv("invalid StackLifetime parameter '{}'", ParamName).str(),
1384 }
1385 }
1386 return Result;
1387}
1388
1389Expected<bool> parseDependenceAnalysisPrinterOptions(StringRef Params) {
1390 return PassBuilder::parseSinglePassOption(Params, "normalized-results",
1391 "DependenceAnalysisPrinter");
1392}
1393
1394Expected<bool> parseSeparateConstOffsetFromGEPPassOptions(StringRef Params) {
1395 return PassBuilder::parseSinglePassOption(Params, "lower-gep",
1396 "SeparateConstOffsetFromGEP");
1397}
1398
1399Expected<bool> parseStructurizeCFGPassOptions(StringRef Params) {
1400 return PassBuilder::parseSinglePassOption(Params, "skip-uniform-regions",
1401 "StructurizeCFG");
1402}
1403
1405parseFunctionSimplificationPipelineOptions(StringRef Params) {
1406 std::optional<OptimizationLevel> L = parseOptLevel(Params);
1407 if (!L || *L == OptimizationLevel::O0) {
1409 formatv("invalid function-simplification parameter '{}'", Params).str(),
1411 };
1412 return *L;
1413}
1414
1415Expected<bool> parseMemorySSAPrinterPassOptions(StringRef Params) {
1416 return PassBuilder::parseSinglePassOption(Params, "no-ensure-optimized-uses",
1417 "MemorySSAPrinterPass");
1418}
1419
1420Expected<bool> parseSpeculativeExecutionPassOptions(StringRef Params) {
1421 return PassBuilder::parseSinglePassOption(Params, "only-if-divergent-target",
1422 "SpeculativeExecutionPass");
1423}
1424
1425Expected<std::string> parseMemProfUsePassOptions(StringRef Params) {
1426 std::string Result;
1427 while (!Params.empty()) {
1428 StringRef ParamName;
1429 std::tie(ParamName, Params) = Params.split(';');
1430
1431 if (ParamName.consume_front("profile-filename=")) {
1432 Result = ParamName.str();
1433 } else {
1435 formatv("invalid MemProfUse pass parameter '{}'", ParamName).str(),
1437 }
1438 }
1439 return Result;
1440}
1441
1443parseStructuralHashPrinterPassOptions(StringRef Params) {
1444 if (Params.empty())
1446 if (Params == "detailed")
1448 if (Params == "call-target-ignored")
1451 formatv("invalid structural hash printer parameter '{}'", Params).str(),
1453}
1454
1455Expected<bool> parseWinEHPrepareOptions(StringRef Params) {
1456 return PassBuilder::parseSinglePassOption(Params, "demote-catchswitch-only",
1457 "WinEHPreparePass");
1458}
1459
1460Expected<GlobalMergeOptions> parseGlobalMergeOptions(StringRef Params) {
1462 while (!Params.empty()) {
1463 StringRef ParamName;
1464 std::tie(ParamName, Params) = Params.split(';');
1465
1466 bool Enable = !ParamName.consume_front("no-");
1467 if (ParamName == "group-by-use")
1468 Result.GroupByUse = Enable;
1469 else if (ParamName == "ignore-single-use")
1470 Result.IgnoreSingleUse = Enable;
1471 else if (ParamName == "merge-const")
1472 Result.MergeConstantGlobals = Enable;
1473 else if (ParamName == "merge-const-aggressive")
1474 Result.MergeConstAggressive = Enable;
1475 else if (ParamName == "merge-external")
1476 Result.MergeExternal = Enable;
1477 else if (ParamName.consume_front("max-offset=")) {
1478 if (ParamName.getAsInteger(0, Result.MaxOffset))
1480 formatv("invalid GlobalMergePass parameter '{}'", ParamName).str(),
1482 } else {
1484 formatv("invalid global-merge pass parameter '{}'", Params).str(),
1486 }
1487 }
1488 return Result;
1489}
1490
1491Expected<SmallVector<std::string, 0>> parseInternalizeGVs(StringRef Params) {
1492 SmallVector<std::string, 1> PreservedGVs;
1493 while (!Params.empty()) {
1494 StringRef ParamName;
1495 std::tie(ParamName, Params) = Params.split(';');
1496
1497 if (ParamName.consume_front("preserve-gv=")) {
1498 PreservedGVs.push_back(ParamName.str());
1499 } else {
1501 formatv("invalid Internalize pass parameter '{}'", ParamName).str(),
1503 }
1504 }
1505
1506 return Expected<SmallVector<std::string, 0>>(std::move(PreservedGVs));
1507}
1508
1510parseRegAllocFastPassOptions(PassBuilder &PB, StringRef Params) {
1512 while (!Params.empty()) {
1513 StringRef ParamName;
1514 std::tie(ParamName, Params) = Params.split(';');
1515
1516 if (ParamName.consume_front("filter=")) {
1517 std::optional<RegAllocFilterFunc> Filter =
1518 PB.parseRegAllocFilter(ParamName);
1519 if (!Filter) {
1521 formatv("invalid regallocfast register filter '{}'", ParamName)
1522 .str(),
1524 }
1525 Opts.Filter = *Filter;
1526 Opts.FilterName = ParamName;
1527 continue;
1528 }
1529
1530 if (ParamName == "no-clear-vregs") {
1531 Opts.ClearVRegs = false;
1532 continue;
1533 }
1534
1536 formatv("invalid regallocfast pass parameter '{}'", ParamName).str(),
1538 }
1539 return Opts;
1540}
1541
1543parseBoundsCheckingOptions(StringRef Params) {
1545 while (!Params.empty()) {
1546 StringRef ParamName;
1547 std::tie(ParamName, Params) = Params.split(';');
1548 if (ParamName == "trap") {
1549 Options.Rt = std::nullopt;
1550 } else if (ParamName == "rt") {
1551 Options.Rt = {
1552 /*MinRuntime=*/false,
1553 /*MayReturn=*/true,
1554 };
1555 } else if (ParamName == "rt-abort") {
1556 Options.Rt = {
1557 /*MinRuntime=*/false,
1558 /*MayReturn=*/false,
1559 };
1560 } else if (ParamName == "min-rt") {
1561 Options.Rt = {
1562 /*MinRuntime=*/true,
1563 /*MayReturn=*/true,
1564 };
1565 } else if (ParamName == "min-rt-abort") {
1566 Options.Rt = {
1567 /*MinRuntime=*/true,
1568 /*MayReturn=*/false,
1569 };
1570 } else if (ParamName == "merge") {
1571 Options.Merge = true;
1572 } else {
1573 StringRef ParamEQ;
1574 StringRef Val;
1575 std::tie(ParamEQ, Val) = ParamName.split('=');
1576 int8_t Id;
1577 if (ParamEQ == "guard" && !Val.getAsInteger(0, Id)) {
1578 Options.GuardKind = Id;
1579 } else {
1581 formatv("invalid BoundsChecking pass parameter '{}'", ParamName)
1582 .str(),
1584 }
1585 }
1586 }
1587 return Options;
1588}
1589
1590Expected<CodeGenOptLevel> parseExpandFpOptions(StringRef Param) {
1591 if (Param.empty())
1592 return CodeGenOptLevel::None;
1593
1594 // Parse a CodeGenOptLevel, e.g. "O1", "O2", "O3".
1595 auto [Prefix, Digit] = Param.split('O');
1596
1597 uint8_t N;
1598 if (!Prefix.empty() || Digit.getAsInteger(10, N))
1599 return createStringError("invalid expand-fp pass parameter '%s'",
1600 Param.str().c_str());
1601
1602 std::optional<CodeGenOptLevel> Level = CodeGenOpt::getLevel(N);
1603 if (!Level.has_value())
1604 return createStringError(
1605 "invalid optimization level for expand-fp pass: %s",
1606 Digit.str().c_str());
1607
1608 return *Level;
1609}
1610
1612parseRegAllocGreedyFilterFunc(PassBuilder &PB, StringRef Params) {
1613 if (Params.empty() || Params == "all")
1614 return RAGreedyPass::Options();
1615
1616 std::optional<RegAllocFilterFunc> Filter = PB.parseRegAllocFilter(Params);
1617 if (Filter)
1618 return RAGreedyPass::Options{*Filter, Params};
1619
1621 formatv("invalid regallocgreedy register filter '{}'", Params).str(),
1623}
1624
1625Expected<bool> parseMachineSinkingPassOptions(StringRef Params) {
1626 return PassBuilder::parseSinglePassOption(Params, "enable-sink-fold",
1627 "MachineSinkingPass");
1628}
1629
1630Expected<bool> parseMachineBlockPlacementPassOptions(StringRef Params) {
1631 bool AllowTailMerge = true;
1632 if (!Params.empty()) {
1633 AllowTailMerge = !Params.consume_front("no-");
1634 if (Params != "tail-merge")
1636 formatv("invalid MachineBlockPlacementPass parameter '{}'", Params)
1637 .str(),
1639 }
1640 return AllowTailMerge;
1641}
1642
1643Expected<bool> parseVirtRegRewriterPassOptions(StringRef Params) {
1644 bool ClearVirtRegs = true;
1645 if (!Params.empty()) {
1646 ClearVirtRegs = !Params.consume_front("no-");
1647 if (Params != "clear-vregs")
1649 formatv("invalid VirtRegRewriter pass parameter '{}'", Params).str(),
1651 }
1652 return ClearVirtRegs;
1653}
1654
1655struct FatLTOOptions {
1656 OptimizationLevel OptLevel;
1657 bool ThinLTO = false;
1658 bool EmitSummary = false;
1659};
1660
1661Expected<FatLTOOptions> parseFatLTOOptions(StringRef Params) {
1662 FatLTOOptions Result;
1663 bool HaveOptLevel = false;
1664 while (!Params.empty()) {
1665 StringRef ParamName;
1666 std::tie(ParamName, Params) = Params.split(';');
1667
1668 if (ParamName == "thinlto") {
1669 Result.ThinLTO = true;
1670 } else if (ParamName == "emit-summary") {
1671 Result.EmitSummary = true;
1672 } else if (std::optional<OptimizationLevel> OptLevel =
1673 parseOptLevel(ParamName)) {
1674 Result.OptLevel = *OptLevel;
1675 HaveOptLevel = true;
1676 } else {
1678 formatv("invalid fatlto-pre-link pass parameter '{}'", ParamName)
1679 .str(),
1681 }
1682 }
1683 if (!HaveOptLevel)
1685 "missing optimization level for fatlto-pre-link pipeline",
1687 return Result;
1688}
1689
1690} // namespace
1691
1692/// Tests whether registered callbacks will accept a given pass name.
1693///
1694/// When parsing a pipeline text, the type of the outermost pipeline may be
1695/// omitted, in which case the type is automatically determined from the first
1696/// pass name in the text. This may be a name that is handled through one of the
1697/// callbacks. We check this through the oridinary parsing callbacks by setting
1698/// up a dummy PassManager in order to not force the client to also handle this
1699/// type of query.
1700template <typename PassManagerT, typename CallbacksT>
1701static bool callbacksAcceptPassName(StringRef Name, CallbacksT &Callbacks) {
1702 if (!Callbacks.empty()) {
1703 PassManagerT DummyPM;
1704 for (auto &CB : Callbacks)
1705 if (CB(Name, DummyPM, {}))
1706 return true;
1707 }
1708 return false;
1709}
1710
1711template <typename CallbacksT>
1712static bool isModulePassName(StringRef Name, CallbacksT &Callbacks) {
1713 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1714
1715 // Explicitly handle pass manager names.
1716 if (Name == "module")
1717 return true;
1718 if (Name == "cgscc")
1719 return true;
1720 if (NameNoBracket == "function")
1721 return true;
1722 if (Name == "coro-cond")
1723 return true;
1724
1725#define MODULE_PASS(NAME, CREATE_PASS) \
1726 if (Name == NAME) \
1727 return true;
1728#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1729 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1730 return true;
1731#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
1732 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1733 return true;
1734#include "PassRegistry.def"
1735
1736 return callbacksAcceptPassName<ModulePassManager>(Name, Callbacks);
1737}
1738
1739template <typename CallbacksT>
1740static bool isCGSCCPassName(StringRef Name, CallbacksT &Callbacks) {
1741 // Explicitly handle pass manager names.
1742 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1743 if (Name == "cgscc")
1744 return true;
1745 if (NameNoBracket == "function")
1746 return true;
1747
1748 // Explicitly handle custom-parsed pass names.
1749 if (parseDevirtPassName(Name))
1750 return true;
1751
1752#define CGSCC_PASS(NAME, CREATE_PASS) \
1753 if (Name == NAME) \
1754 return true;
1755#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1756 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1757 return true;
1758#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
1759 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1760 return true;
1761#include "PassRegistry.def"
1762
1763 return callbacksAcceptPassName<CGSCCPassManager>(Name, Callbacks);
1764}
1765
1766template <typename CallbacksT>
1767static bool isFunctionPassName(StringRef Name, CallbacksT &Callbacks) {
1768 // Explicitly handle pass manager names.
1769 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1770 if (NameNoBracket == "function")
1771 return true;
1772 if (Name == "loop" || Name == "loop-mssa" || Name == "machine-function")
1773 return true;
1774
1775#define FUNCTION_PASS(NAME, CREATE_PASS) \
1776 if (Name == NAME) \
1777 return true;
1778#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1779 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1780 return true;
1781#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1782 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1783 return true;
1784#include "PassRegistry.def"
1785
1786 return callbacksAcceptPassName<FunctionPassManager>(Name, Callbacks);
1787}
1788
1789template <typename CallbacksT>
1790static bool isMachineFunctionPassName(StringRef Name, CallbacksT &Callbacks) {
1791 // Explicitly handle pass manager names.
1792 if (Name == "machine-function")
1793 return true;
1794
1795#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
1796 if (Name == NAME) \
1797 return true;
1798#define MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, \
1799 PARAMS) \
1800 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1801 return true;
1802
1803#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1804 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1805 return true;
1806
1807#include "llvm/Passes/MachinePassRegistry.def"
1808
1810}
1811
1812template <typename CallbacksT>
1813static bool isLoopNestPassName(StringRef Name, CallbacksT &Callbacks,
1814 bool &UseMemorySSA) {
1815 UseMemorySSA = false;
1816
1817 if (PassBuilder::checkParametrizedPassName(Name, "lnicm")) {
1818 UseMemorySSA = true;
1819 return true;
1820 }
1821
1822#define LOOPNEST_PASS(NAME, CREATE_PASS) \
1823 if (Name == NAME) \
1824 return true;
1825#include "PassRegistry.def"
1826
1827 return callbacksAcceptPassName<LoopPassManager>(Name, Callbacks);
1828}
1829
1830template <typename CallbacksT>
1831static bool isLoopPassName(StringRef Name, CallbacksT &Callbacks,
1832 bool &UseMemorySSA) {
1833 UseMemorySSA = false;
1834
1835 if (PassBuilder::checkParametrizedPassName(Name, "licm")) {
1836 UseMemorySSA = true;
1837 return true;
1838 }
1839
1840#define LOOP_PASS(NAME, CREATE_PASS) \
1841 if (Name == NAME) \
1842 return true;
1843#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1844 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1845 return true;
1846#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
1847 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1848 return true;
1849#include "PassRegistry.def"
1850
1851 return callbacksAcceptPassName<LoopPassManager>(Name, Callbacks);
1852}
1853
1854std::optional<std::vector<PassBuilder::PipelineElement>>
1855PassBuilder::parsePipelineText(StringRef Text) {
1856 std::vector<PipelineElement> ResultPipeline;
1857
1858 SmallVector<std::vector<PipelineElement> *, 4> PipelineStack = {
1859 &ResultPipeline};
1860 for (;;) {
1861 std::vector<PipelineElement> &Pipeline = *PipelineStack.back();
1862 size_t Pos = Text.find_first_of(",()");
1863 Pipeline.push_back({Text.substr(0, Pos), {}});
1864
1865 // If we have a single terminating name, we're done.
1866 if (Pos == Text.npos)
1867 break;
1868
1869 char Sep = Text[Pos];
1870 Text = Text.substr(Pos + 1);
1871 if (Sep == ',')
1872 // Just a name ending in a comma, continue.
1873 continue;
1874
1875 if (Sep == '(') {
1876 // Push the inner pipeline onto the stack to continue processing.
1877 PipelineStack.push_back(&Pipeline.back().InnerPipeline);
1878 continue;
1879 }
1880
1881 assert(Sep == ')' && "Bogus separator!");
1882 // When handling the close parenthesis, we greedily consume them to avoid
1883 // empty strings in the pipeline.
1884 do {
1885 // If we try to pop the outer pipeline we have unbalanced parentheses.
1886 if (PipelineStack.size() == 1)
1887 return std::nullopt;
1888
1889 PipelineStack.pop_back();
1890 } while (Text.consume_front(")"));
1891
1892 // Check if we've finished parsing.
1893 if (Text.empty())
1894 break;
1895
1896 // Otherwise, the end of an inner pipeline always has to be followed by
1897 // a comma, and then we can continue.
1898 if (!Text.consume_front(","))
1899 return std::nullopt;
1900 }
1901
1902 if (PipelineStack.size() > 1)
1903 // Unbalanced paretheses.
1904 return std::nullopt;
1905
1906 assert(PipelineStack.back() == &ResultPipeline &&
1907 "Wrong pipeline at the bottom of the stack!");
1908 return {std::move(ResultPipeline)};
1909}
1910
1913 // This is consistent with old pass manager invoked via opt, but
1914 // inconsistent with clang. Clang doesn't enable loop vectorization
1915 // but does enable slp vectorization at Oz.
1916 PTO.LoopVectorization = L.getSpeedupLevel() > 1 && L != OptimizationLevel::Oz;
1917 PTO.SLPVectorization = L.getSpeedupLevel() > 1 && L != OptimizationLevel::Oz;
1918}
1919
1920Error PassBuilder::parseModulePass(ModulePassManager &MPM,
1921 const PipelineElement &E) {
1922 auto &Name = E.Name;
1923 auto &InnerPipeline = E.InnerPipeline;
1924
1925 // First handle complex passes like the pass managers which carry pipelines.
1926 if (!InnerPipeline.empty()) {
1927 if (Name == "module") {
1928 ModulePassManager NestedMPM;
1929 if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline))
1930 return Err;
1931 MPM.addPass(std::move(NestedMPM));
1932 return Error::success();
1933 }
1934 if (Name == "coro-cond") {
1935 ModulePassManager NestedMPM;
1936 if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline))
1937 return Err;
1938 MPM.addPass(CoroConditionalWrapper(std::move(NestedMPM)));
1939 return Error::success();
1940 }
1941 if (Name == "cgscc") {
1942 CGSCCPassManager CGPM;
1943 if (auto Err = parseCGSCCPassPipeline(CGPM, InnerPipeline))
1944 return Err;
1946 return Error::success();
1947 }
1948 if (auto Params = parseFunctionPipelineName(Name)) {
1949 if (Params->second)
1951 "cannot have a no-rerun module to function adaptor",
1954 if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline))
1955 return Err;
1956 MPM.addPass(
1957 createModuleToFunctionPassAdaptor(std::move(FPM), Params->first));
1958 return Error::success();
1959 }
1960
1961 for (auto &C : ModulePipelineParsingCallbacks)
1962 if (C(Name, MPM, InnerPipeline))
1963 return Error::success();
1964
1965 // Normal passes can't have pipelines.
1967 formatv("invalid use of '{}' pass as module pipeline", Name).str(),
1969 ;
1970 }
1971
1972 // Finally expand the basic registered passes from the .inc file.
1973#define MODULE_PASS(NAME, CREATE_PASS) \
1974 if (Name == NAME) { \
1975 MPM.addPass(CREATE_PASS); \
1976 return Error::success(); \
1977 }
1978#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1979 if (checkParametrizedPassName(Name, NAME)) { \
1980 auto Params = parsePassParameters(PARSER, Name, NAME); \
1981 if (!Params) \
1982 return Params.takeError(); \
1983 MPM.addPass(CREATE_PASS(Params.get())); \
1984 return Error::success(); \
1985 }
1986#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
1987 if (Name == "require<" NAME ">") { \
1988 MPM.addPass( \
1989 RequireAnalysisPass< \
1990 std::remove_reference_t<decltype(CREATE_PASS)>, Module>()); \
1991 return Error::success(); \
1992 } \
1993 if (Name == "invalidate<" NAME ">") { \
1994 MPM.addPass(InvalidateAnalysisPass< \
1995 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
1996 return Error::success(); \
1997 }
1998#define CGSCC_PASS(NAME, CREATE_PASS) \
1999 if (Name == NAME) { \
2000 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(CREATE_PASS)); \
2001 return Error::success(); \
2002 }
2003#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2004 if (checkParametrizedPassName(Name, NAME)) { \
2005 auto Params = parsePassParameters(PARSER, Name, NAME); \
2006 if (!Params) \
2007 return Params.takeError(); \
2008 MPM.addPass( \
2009 createModuleToPostOrderCGSCCPassAdaptor(CREATE_PASS(Params.get()))); \
2010 return Error::success(); \
2011 }
2012#define FUNCTION_PASS(NAME, CREATE_PASS) \
2013 if (Name == NAME) { \
2014 MPM.addPass(createModuleToFunctionPassAdaptor(CREATE_PASS)); \
2015 return Error::success(); \
2016 }
2017#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2018 if (checkParametrizedPassName(Name, NAME)) { \
2019 auto Params = parsePassParameters(PARSER, Name, NAME); \
2020 if (!Params) \
2021 return Params.takeError(); \
2022 MPM.addPass(createModuleToFunctionPassAdaptor(CREATE_PASS(Params.get()))); \
2023 return Error::success(); \
2024 }
2025#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2026 if (Name == NAME) { \
2027 MPM.addPass(createModuleToFunctionPassAdaptor( \
2028 createFunctionToLoopPassAdaptor(CREATE_PASS, false, false))); \
2029 return Error::success(); \
2030 }
2031#define LOOP_PASS(NAME, CREATE_PASS) \
2032 if (Name == NAME) { \
2033 MPM.addPass(createModuleToFunctionPassAdaptor( \
2034 createFunctionToLoopPassAdaptor(CREATE_PASS, false, false))); \
2035 return Error::success(); \
2036 }
2037#define LOOP_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 createModuleToFunctionPassAdaptor(createFunctionToLoopPassAdaptor( \
2044 CREATE_PASS(Params.get()), false, false))); \
2045 return Error::success(); \
2046 }
2047#include "PassRegistry.def"
2048
2049 for (auto &C : ModulePipelineParsingCallbacks)
2050 if (C(Name, MPM, InnerPipeline))
2051 return Error::success();
2053 formatv("unknown module pass '{}'", Name).str(),
2055}
2056
2057Error PassBuilder::parseCGSCCPass(CGSCCPassManager &CGPM,
2058 const PipelineElement &E) {
2059 auto &Name = E.Name;
2060 auto &InnerPipeline = E.InnerPipeline;
2061
2062 // First handle complex passes like the pass managers which carry pipelines.
2063 if (!InnerPipeline.empty()) {
2064 if (Name == "cgscc") {
2065 CGSCCPassManager NestedCGPM;
2066 if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline))
2067 return Err;
2068 // Add the nested pass manager with the appropriate adaptor.
2069 CGPM.addPass(std::move(NestedCGPM));
2070 return Error::success();
2071 }
2072 if (auto Params = parseFunctionPipelineName(Name)) {
2074 if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline))
2075 return Err;
2076 // Add the nested pass manager with the appropriate adaptor.
2078 std::move(FPM), Params->first, Params->second));
2079 return Error::success();
2080 }
2081 if (auto MaxRepetitions = parseDevirtPassName(Name)) {
2082 CGSCCPassManager NestedCGPM;
2083 if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline))
2084 return Err;
2085 CGPM.addPass(
2086 createDevirtSCCRepeatedPass(std::move(NestedCGPM), *MaxRepetitions));
2087 return Error::success();
2088 }
2089
2090 for (auto &C : CGSCCPipelineParsingCallbacks)
2091 if (C(Name, CGPM, InnerPipeline))
2092 return Error::success();
2093
2094 // Normal passes can't have pipelines.
2096 formatv("invalid use of '{}' pass as cgscc pipeline", Name).str(),
2098 }
2099
2100// Now expand the basic registered passes from the .inc file.
2101#define CGSCC_PASS(NAME, CREATE_PASS) \
2102 if (Name == NAME) { \
2103 CGPM.addPass(CREATE_PASS); \
2104 return Error::success(); \
2105 }
2106#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2107 if (checkParametrizedPassName(Name, NAME)) { \
2108 auto Params = parsePassParameters(PARSER, Name, NAME); \
2109 if (!Params) \
2110 return Params.takeError(); \
2111 CGPM.addPass(CREATE_PASS(Params.get())); \
2112 return Error::success(); \
2113 }
2114#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
2115 if (Name == "require<" NAME ">") { \
2116 CGPM.addPass(RequireAnalysisPass< \
2117 std::remove_reference_t<decltype(CREATE_PASS)>, \
2118 LazyCallGraph::SCC, CGSCCAnalysisManager, LazyCallGraph &, \
2119 CGSCCUpdateResult &>()); \
2120 return Error::success(); \
2121 } \
2122 if (Name == "invalidate<" NAME ">") { \
2123 CGPM.addPass(InvalidateAnalysisPass< \
2124 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2125 return Error::success(); \
2126 }
2127#define FUNCTION_PASS(NAME, CREATE_PASS) \
2128 if (Name == NAME) { \
2129 CGPM.addPass(createCGSCCToFunctionPassAdaptor(CREATE_PASS)); \
2130 return Error::success(); \
2131 }
2132#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2133 if (checkParametrizedPassName(Name, NAME)) { \
2134 auto Params = parsePassParameters(PARSER, Name, NAME); \
2135 if (!Params) \
2136 return Params.takeError(); \
2137 CGPM.addPass(createCGSCCToFunctionPassAdaptor(CREATE_PASS(Params.get()))); \
2138 return Error::success(); \
2139 }
2140#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2141 if (Name == NAME) { \
2142 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
2143 createFunctionToLoopPassAdaptor(CREATE_PASS, false, false))); \
2144 return Error::success(); \
2145 }
2146#define LOOP_PASS(NAME, CREATE_PASS) \
2147 if (Name == NAME) { \
2148 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
2149 createFunctionToLoopPassAdaptor(CREATE_PASS, false, false))); \
2150 return Error::success(); \
2151 }
2152#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2153 if (checkParametrizedPassName(Name, NAME)) { \
2154 auto Params = parsePassParameters(PARSER, Name, NAME); \
2155 if (!Params) \
2156 return Params.takeError(); \
2157 CGPM.addPass( \
2158 createCGSCCToFunctionPassAdaptor(createFunctionToLoopPassAdaptor( \
2159 CREATE_PASS(Params.get()), false, false))); \
2160 return Error::success(); \
2161 }
2162#include "PassRegistry.def"
2163
2164 for (auto &C : CGSCCPipelineParsingCallbacks)
2165 if (C(Name, CGPM, InnerPipeline))
2166 return Error::success();
2167 return make_error<StringError>(formatv("unknown cgscc pass '{}'", Name).str(),
2169}
2170
2171Error PassBuilder::parseFunctionPass(FunctionPassManager &FPM,
2172 const PipelineElement &E) {
2173 auto &Name = E.Name;
2174 auto &InnerPipeline = E.InnerPipeline;
2175
2176 // First handle complex passes like the pass managers which carry pipelines.
2177 if (!InnerPipeline.empty()) {
2178 if (Name == "function") {
2179 FunctionPassManager NestedFPM;
2180 if (auto Err = parseFunctionPassPipeline(NestedFPM, InnerPipeline))
2181 return Err;
2182 // Add the nested pass manager with the appropriate adaptor.
2183 FPM.addPass(std::move(NestedFPM));
2184 return Error::success();
2185 }
2186 if (Name == "loop" || Name == "loop-mssa") {
2187 LoopPassManager LPM;
2188 if (auto Err = parseLoopPassPipeline(LPM, InnerPipeline))
2189 return Err;
2190 // Add the nested pass manager with the appropriate adaptor.
2191 bool UseMemorySSA = (Name == "loop-mssa");
2192 bool UseBFI = llvm::any_of(InnerPipeline, [](auto Pipeline) {
2193 return Pipeline.Name.contains("simple-loop-unswitch");
2194 });
2195 FPM.addPass(createFunctionToLoopPassAdaptor(std::move(LPM), UseMemorySSA,
2196 UseBFI));
2197 return Error::success();
2198 }
2199 if (Name == "machine-function") {
2201 if (auto Err = parseMachinePassPipeline(MFPM, InnerPipeline))
2202 return Err;
2204 return Error::success();
2205 }
2206
2207 for (auto &C : FunctionPipelineParsingCallbacks)
2208 if (C(Name, FPM, InnerPipeline))
2209 return Error::success();
2210
2211 // Normal passes can't have pipelines.
2213 formatv("invalid use of '{}' pass as function pipeline", Name).str(),
2215 }
2216
2217// Now expand the basic registered passes from the .inc file.
2218#define FUNCTION_PASS(NAME, CREATE_PASS) \
2219 if (Name == NAME) { \
2220 FPM.addPass(CREATE_PASS); \
2221 return Error::success(); \
2222 }
2223#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2224 if (checkParametrizedPassName(Name, NAME)) { \
2225 auto Params = parsePassParameters(PARSER, Name, NAME); \
2226 if (!Params) \
2227 return Params.takeError(); \
2228 FPM.addPass(CREATE_PASS(Params.get())); \
2229 return Error::success(); \
2230 }
2231#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
2232 if (Name == "require<" NAME ">") { \
2233 FPM.addPass( \
2234 RequireAnalysisPass< \
2235 std::remove_reference_t<decltype(CREATE_PASS)>, Function>()); \
2236 return Error::success(); \
2237 } \
2238 if (Name == "invalidate<" NAME ">") { \
2239 FPM.addPass(InvalidateAnalysisPass< \
2240 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2241 return Error::success(); \
2242 }
2243// FIXME: UseMemorySSA is set to false. Maybe we could do things like:
2244// bool UseMemorySSA = !("canon-freeze" || "loop-predication" ||
2245// "guard-widening");
2246// The risk is that it may become obsolete if we're not careful.
2247#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2248 if (Name == NAME) { \
2249 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS, false, false)); \
2250 return Error::success(); \
2251 }
2252#define LOOP_PASS(NAME, CREATE_PASS) \
2253 if (Name == NAME) { \
2254 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS, false, false)); \
2255 return Error::success(); \
2256 }
2257#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2258 if (checkParametrizedPassName(Name, NAME)) { \
2259 auto Params = parsePassParameters(PARSER, Name, NAME); \
2260 if (!Params) \
2261 return Params.takeError(); \
2262 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), \
2263 false, false)); \
2264 return Error::success(); \
2265 }
2266#include "PassRegistry.def"
2267
2268 for (auto &C : FunctionPipelineParsingCallbacks)
2269 if (C(Name, FPM, InnerPipeline))
2270 return Error::success();
2272 formatv("unknown function pass '{}'", Name).str(),
2274}
2275
2276Error PassBuilder::parseLoopPass(LoopPassManager &LPM,
2277 const PipelineElement &E) {
2278 StringRef Name = E.Name;
2279 auto &InnerPipeline = E.InnerPipeline;
2280
2281 // First handle complex passes like the pass managers which carry pipelines.
2282 if (!InnerPipeline.empty()) {
2283 if (Name == "loop") {
2284 LoopPassManager NestedLPM;
2285 if (auto Err = parseLoopPassPipeline(NestedLPM, InnerPipeline))
2286 return Err;
2287 // Add the nested pass manager with the appropriate adaptor.
2288 LPM.addPass(std::move(NestedLPM));
2289 return Error::success();
2290 }
2291
2292 for (auto &C : LoopPipelineParsingCallbacks)
2293 if (C(Name, LPM, InnerPipeline))
2294 return Error::success();
2295
2296 // Normal passes can't have pipelines.
2298 formatv("invalid use of '{}' pass as loop pipeline", Name).str(),
2300 }
2301
2302// Now expand the basic registered passes from the .inc file.
2303#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2304 if (Name == NAME) { \
2305 LPM.addPass(CREATE_PASS); \
2306 return Error::success(); \
2307 }
2308#define LOOP_PASS(NAME, CREATE_PASS) \
2309 if (Name == NAME) { \
2310 LPM.addPass(CREATE_PASS); \
2311 return Error::success(); \
2312 }
2313#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2314 if (checkParametrizedPassName(Name, NAME)) { \
2315 auto Params = parsePassParameters(PARSER, Name, NAME); \
2316 if (!Params) \
2317 return Params.takeError(); \
2318 LPM.addPass(CREATE_PASS(Params.get())); \
2319 return Error::success(); \
2320 }
2321#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
2322 if (Name == "require<" NAME ">") { \
2323 LPM.addPass(RequireAnalysisPass< \
2324 std::remove_reference_t<decltype(CREATE_PASS)>, Loop, \
2325 LoopAnalysisManager, LoopStandardAnalysisResults &, \
2326 LPMUpdater &>()); \
2327 return Error::success(); \
2328 } \
2329 if (Name == "invalidate<" NAME ">") { \
2330 LPM.addPass(InvalidateAnalysisPass< \
2331 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2332 return Error::success(); \
2333 }
2334#include "PassRegistry.def"
2335
2336 for (auto &C : LoopPipelineParsingCallbacks)
2337 if (C(Name, LPM, InnerPipeline))
2338 return Error::success();
2339 return make_error<StringError>(formatv("unknown loop pass '{}'", Name).str(),
2341}
2342
2343Error PassBuilder::parseMachinePass(MachineFunctionPassManager &MFPM,
2344 const PipelineElement &E) {
2345 StringRef Name = E.Name;
2346 // Handle any nested pass managers.
2347 if (!E.InnerPipeline.empty()) {
2348 if (E.Name == "machine-function") {
2350 if (auto Err = parseMachinePassPipeline(NestedPM, E.InnerPipeline))
2351 return Err;
2352 MFPM.addPass(std::move(NestedPM));
2353 return Error::success();
2354 }
2355 return make_error<StringError>("invalid pipeline",
2357 }
2358
2359#define MACHINE_MODULE_PASS(NAME, CREATE_PASS) \
2360 if (Name == NAME) { \
2361 MFPM.addPass(CREATE_PASS); \
2362 return Error::success(); \
2363 }
2364#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
2365 if (Name == NAME) { \
2366 MFPM.addPass(CREATE_PASS); \
2367 return Error::success(); \
2368 }
2369#define MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, \
2370 PARAMS) \
2371 if (checkParametrizedPassName(Name, NAME)) { \
2372 auto Params = parsePassParameters(PARSER, Name, NAME); \
2373 if (!Params) \
2374 return Params.takeError(); \
2375 MFPM.addPass(CREATE_PASS(Params.get())); \
2376 return Error::success(); \
2377 }
2378#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
2379 if (Name == "require<" NAME ">") { \
2380 MFPM.addPass( \
2381 RequireAnalysisPass<std::remove_reference_t<decltype(CREATE_PASS)>, \
2382 MachineFunction>()); \
2383 return Error::success(); \
2384 } \
2385 if (Name == "invalidate<" NAME ">") { \
2386 MFPM.addPass(InvalidateAnalysisPass< \
2387 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2388 return Error::success(); \
2389 }
2390#include "llvm/Passes/MachinePassRegistry.def"
2391
2392 for (auto &C : MachineFunctionPipelineParsingCallbacks)
2393 if (C(Name, MFPM, E.InnerPipeline))
2394 return Error::success();
2396 formatv("unknown machine pass '{}'", Name).str(),
2398}
2399
2400bool PassBuilder::parseAAPassName(AAManager &AA, StringRef Name) {
2401#define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
2402 if (Name == NAME) { \
2403 AA.registerModuleAnalysis< \
2404 std::remove_reference_t<decltype(CREATE_PASS)>>(); \
2405 return true; \
2406 }
2407#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
2408 if (Name == NAME) { \
2409 AA.registerFunctionAnalysis< \
2410 std::remove_reference_t<decltype(CREATE_PASS)>>(); \
2411 return true; \
2412 }
2413#include "PassRegistry.def"
2414
2415 for (auto &C : AAParsingCallbacks)
2416 if (C(Name, AA))
2417 return true;
2418 return false;
2419}
2420
2421Error PassBuilder::parseMachinePassPipeline(
2423 for (const auto &Element : Pipeline) {
2424 if (auto Err = parseMachinePass(MFPM, Element))
2425 return Err;
2426 }
2427 return Error::success();
2428}
2429
2430Error PassBuilder::parseLoopPassPipeline(LoopPassManager &LPM,
2431 ArrayRef<PipelineElement> Pipeline) {
2432 for (const auto &Element : Pipeline) {
2433 if (auto Err = parseLoopPass(LPM, Element))
2434 return Err;
2435 }
2436 return Error::success();
2437}
2438
2439Error PassBuilder::parseFunctionPassPipeline(
2441 for (const auto &Element : Pipeline) {
2442 if (auto Err = parseFunctionPass(FPM, Element))
2443 return Err;
2444 }
2445 return Error::success();
2446}
2447
2448Error PassBuilder::parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
2449 ArrayRef<PipelineElement> Pipeline) {
2450 for (const auto &Element : Pipeline) {
2451 if (auto Err = parseCGSCCPass(CGPM, Element))
2452 return Err;
2453 }
2454 return Error::success();
2455}
2456
2462 MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });
2463 MAM.registerPass([&] { return CGSCCAnalysisManagerModuleProxy(CGAM); });
2464 CGAM.registerPass([&] { return ModuleAnalysisManagerCGSCCProxy(MAM); });
2465 FAM.registerPass([&] { return CGSCCAnalysisManagerFunctionProxy(CGAM); });
2466 FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); });
2467 FAM.registerPass([&] { return LoopAnalysisManagerFunctionProxy(LAM); });
2468 LAM.registerPass([&] { return FunctionAnalysisManagerLoopProxy(FAM); });
2469 if (MFAM) {
2470 MAM.registerPass(
2471 [&] { return MachineFunctionAnalysisManagerModuleProxy(*MFAM); });
2472 FAM.registerPass(
2473 [&] { return MachineFunctionAnalysisManagerFunctionProxy(*MFAM); });
2474 MFAM->registerPass(
2476 MFAM->registerPass(
2478 }
2479}
2480
2481Error PassBuilder::parseModulePassPipeline(ModulePassManager &MPM,
2482 ArrayRef<PipelineElement> Pipeline) {
2483 for (const auto &Element : Pipeline) {
2484 if (auto Err = parseModulePass(MPM, Element))
2485 return Err;
2486 }
2487 return Error::success();
2488}
2489
2490// Primary pass pipeline description parsing routine for a \c ModulePassManager
2491// FIXME: Should this routine accept a TargetMachine or require the caller to
2492// pre-populate the analysis managers with target-specific stuff?
2494 StringRef PipelineText) {
2495 auto Pipeline = parsePipelineText(PipelineText);
2496 if (!Pipeline || Pipeline->empty())
2498 formatv("invalid pipeline '{}'", PipelineText).str(),
2500
2501 // If the first name isn't at the module layer, wrap the pipeline up
2502 // automatically.
2503 StringRef FirstName = Pipeline->front().Name;
2504
2505 if (!isModulePassName(FirstName, ModulePipelineParsingCallbacks)) {
2506 bool UseMemorySSA;
2507 if (isCGSCCPassName(FirstName, CGSCCPipelineParsingCallbacks)) {
2508 Pipeline = {{"cgscc", std::move(*Pipeline)}};
2509 } else if (isFunctionPassName(FirstName,
2510 FunctionPipelineParsingCallbacks)) {
2511 Pipeline = {{"function", std::move(*Pipeline)}};
2512 } else if (isLoopNestPassName(FirstName, LoopPipelineParsingCallbacks,
2513 UseMemorySSA)) {
2514 Pipeline = {{"function", {{UseMemorySSA ? "loop-mssa" : "loop",
2515 std::move(*Pipeline)}}}};
2516 } else if (isLoopPassName(FirstName, LoopPipelineParsingCallbacks,
2517 UseMemorySSA)) {
2518 Pipeline = {{"function", {{UseMemorySSA ? "loop-mssa" : "loop",
2519 std::move(*Pipeline)}}}};
2520 } else if (isMachineFunctionPassName(
2521 FirstName, MachineFunctionPipelineParsingCallbacks)) {
2522 Pipeline = {{"function", {{"machine-function", std::move(*Pipeline)}}}};
2523 } else {
2524 for (auto &C : TopLevelPipelineParsingCallbacks)
2525 if (C(MPM, *Pipeline))
2526 return Error::success();
2527
2528 // Unknown pass or pipeline name!
2529 auto &InnerPipeline = Pipeline->front().InnerPipeline;
2531 formatv("unknown {} name '{}'",
2532 (InnerPipeline.empty() ? "pass" : "pipeline"), FirstName)
2533 .str(),
2535 }
2536 }
2537
2538 if (auto Err = parseModulePassPipeline(MPM, *Pipeline))
2539 return Err;
2540 return Error::success();
2541}
2542
2543// Primary pass pipeline description parsing routine for a \c CGSCCPassManager
2545 StringRef PipelineText) {
2546 auto Pipeline = parsePipelineText(PipelineText);
2547 if (!Pipeline || Pipeline->empty())
2549 formatv("invalid pipeline '{}'", PipelineText).str(),
2551
2552 StringRef FirstName = Pipeline->front().Name;
2553 if (!isCGSCCPassName(FirstName, CGSCCPipelineParsingCallbacks))
2555 formatv("unknown cgscc pass '{}' in pipeline '{}'", FirstName,
2556 PipelineText)
2557 .str(),
2559
2560 if (auto Err = parseCGSCCPassPipeline(CGPM, *Pipeline))
2561 return Err;
2562 return Error::success();
2563}
2564
2565// Primary pass pipeline description parsing routine for a \c
2566// FunctionPassManager
2568 StringRef PipelineText) {
2569 auto Pipeline = parsePipelineText(PipelineText);
2570 if (!Pipeline || Pipeline->empty())
2572 formatv("invalid pipeline '{}'", PipelineText).str(),
2574
2575 StringRef FirstName = Pipeline->front().Name;
2576 if (!isFunctionPassName(FirstName, FunctionPipelineParsingCallbacks))
2578 formatv("unknown function pass '{}' in pipeline '{}'", FirstName,
2579 PipelineText)
2580 .str(),
2582
2583 if (auto Err = parseFunctionPassPipeline(FPM, *Pipeline))
2584 return Err;
2585 return Error::success();
2586}
2587
2588// Primary pass pipeline description parsing routine for a \c LoopPassManager
2590 StringRef PipelineText) {
2591 auto Pipeline = parsePipelineText(PipelineText);
2592 if (!Pipeline || Pipeline->empty())
2594 formatv("invalid pipeline '{}'", PipelineText).str(),
2596
2597 if (auto Err = parseLoopPassPipeline(CGPM, *Pipeline))
2598 return Err;
2599
2600 return Error::success();
2601}
2602
2604 StringRef PipelineText) {
2605 auto Pipeline = parsePipelineText(PipelineText);
2606 if (!Pipeline || Pipeline->empty())
2608 formatv("invalid machine pass pipeline '{}'", PipelineText).str(),
2610
2611 if (auto Err = parseMachinePassPipeline(MFPM, *Pipeline))
2612 return Err;
2613
2614 return Error::success();
2615}
2616
2618 // If the pipeline just consists of the word 'default' just replace the AA
2619 // manager with our default one.
2620 if (PipelineText == "default") {
2622 return Error::success();
2623 }
2624
2625 while (!PipelineText.empty()) {
2626 StringRef Name;
2627 std::tie(Name, PipelineText) = PipelineText.split(',');
2628 if (!parseAAPassName(AA, Name))
2630 formatv("unknown alias analysis name '{}'", Name).str(),
2632 }
2633
2634 return Error::success();
2635}
2636
2637std::optional<RegAllocFilterFunc>
2639 if (FilterName == "all")
2640 return nullptr;
2641 for (auto &C : RegClassFilterParsingCallbacks)
2642 if (auto F = C(FilterName))
2643 return F;
2644 return std::nullopt;
2645}
2646
2648 OS << " " << PassName << "\n";
2649}
2651 raw_ostream &OS) {
2652 OS << " " << PassName << "<" << Params << ">\n";
2653}
2654
2656 // TODO: print pass descriptions when they are available
2657
2658 OS << "Module passes:\n";
2659#define MODULE_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2660#include "PassRegistry.def"
2661
2662 OS << "Module passes with params:\n";
2663#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2664 printPassName(NAME, PARAMS, OS);
2665#include "PassRegistry.def"
2666
2667 OS << "Module analyses:\n";
2668#define MODULE_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2669#include "PassRegistry.def"
2670
2671 OS << "Module alias analyses:\n";
2672#define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2673#include "PassRegistry.def"
2674
2675 OS << "CGSCC passes:\n";
2676#define CGSCC_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2677#include "PassRegistry.def"
2678
2679 OS << "CGSCC passes with params:\n";
2680#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2681 printPassName(NAME, PARAMS, OS);
2682#include "PassRegistry.def"
2683
2684 OS << "CGSCC analyses:\n";
2685#define CGSCC_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2686#include "PassRegistry.def"
2687
2688 OS << "Function passes:\n";
2689#define FUNCTION_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2690#include "PassRegistry.def"
2691
2692 OS << "Function passes with params:\n";
2693#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2694 printPassName(NAME, PARAMS, OS);
2695#include "PassRegistry.def"
2696
2697 OS << "Function analyses:\n";
2698#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2699#include "PassRegistry.def"
2700
2701 OS << "Function alias analyses:\n";
2702#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2703#include "PassRegistry.def"
2704
2705 OS << "LoopNest passes:\n";
2706#define LOOPNEST_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2707#include "PassRegistry.def"
2708
2709 OS << "Loop passes:\n";
2710#define LOOP_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2711#include "PassRegistry.def"
2712
2713 OS << "Loop passes with params:\n";
2714#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2715 printPassName(NAME, PARAMS, OS);
2716#include "PassRegistry.def"
2717
2718 OS << "Loop analyses:\n";
2719#define LOOP_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2720#include "PassRegistry.def"
2721
2722 OS << "Machine module passes (WIP):\n";
2723#define MACHINE_MODULE_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2724#include "llvm/Passes/MachinePassRegistry.def"
2725
2726 OS << "Machine function passes (WIP):\n";
2727#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2728#include "llvm/Passes/MachinePassRegistry.def"
2729
2730 OS << "Machine function analyses (WIP):\n";
2731#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2732#include "llvm/Passes/MachinePassRegistry.def"
2733}
2734
2736 const std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>)>
2737 &C) {
2738 TopLevelPipelineParsingCallbacks.push_back(C);
2739}
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
UseBFI
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...
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.
bool any_of(R &&range, UnaryPredicate P)
Provide wrappers to std::any_of which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1734
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, bool UseBlockFrequencyInfo=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:1869
PassManager< MachineFunction > MachineFunctionPassManager
Convenience typedef for a pass manager over functions.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
@ 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:77
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