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-arithmetic") {
1115 Result.convertSwitchToArithmetic(Enable);
1116 } else if (ParamName == "switch-to-lookup") {
1117 Result.convertSwitchToLookupTable(Enable);
1118 } else if (ParamName == "keep-loops") {
1119 Result.needCanonicalLoops(Enable);
1120 } else if (ParamName == "hoist-common-insts") {
1121 Result.hoistCommonInsts(Enable);
1122 } else if (ParamName == "hoist-loads-stores-with-cond-faulting") {
1123 Result.hoistLoadsStoresWithCondFaulting(Enable);
1124 } else if (ParamName == "sink-common-insts") {
1125 Result.sinkCommonInsts(Enable);
1126 } else if (ParamName == "speculate-unpredictables") {
1127 Result.speculateUnpredictables(Enable);
1128 } else if (Enable && ParamName.consume_front("bonus-inst-threshold=")) {
1129 APInt BonusInstThreshold;
1130 if (ParamName.getAsInteger(0, BonusInstThreshold))
1132 formatv("invalid argument to SimplifyCFG pass bonus-threshold "
1133 "parameter: '{}'",
1134 ParamName)
1135 .str(),
1137 Result.bonusInstThreshold(BonusInstThreshold.getSExtValue());
1138 } else {
1140 formatv("invalid SimplifyCFG pass parameter '{}'", ParamName).str(),
1142 }
1143 }
1144 return Result;
1145}
1146
1147Expected<InstCombineOptions> parseInstCombineOptions(StringRef Params) {
1149 // When specifying "instcombine" in -passes enable fix-point verification by
1150 // default, as this is what most tests should use.
1151 Result.setVerifyFixpoint(true);
1152 while (!Params.empty()) {
1153 StringRef ParamName;
1154 std::tie(ParamName, Params) = Params.split(';');
1155
1156 bool Enable = !ParamName.consume_front("no-");
1157 if (ParamName == "verify-fixpoint") {
1158 Result.setVerifyFixpoint(Enable);
1159 } else if (Enable && ParamName.consume_front("max-iterations=")) {
1160 APInt MaxIterations;
1161 if (ParamName.getAsInteger(0, MaxIterations))
1163 formatv("invalid argument to InstCombine pass max-iterations "
1164 "parameter: '{}'",
1165 ParamName)
1166 .str(),
1168 Result.setMaxIterations((unsigned)MaxIterations.getZExtValue());
1169 } else {
1171 formatv("invalid InstCombine pass parameter '{}'", ParamName).str(),
1173 }
1174 }
1175 return Result;
1176}
1177
1178/// Parser of parameters for LoopVectorize pass.
1179Expected<LoopVectorizeOptions> parseLoopVectorizeOptions(StringRef Params) {
1181 while (!Params.empty()) {
1182 StringRef ParamName;
1183 std::tie(ParamName, Params) = Params.split(';');
1184
1185 bool Enable = !ParamName.consume_front("no-");
1186 if (ParamName == "interleave-forced-only") {
1188 } else if (ParamName == "vectorize-forced-only") {
1190 } else {
1192 formatv("invalid LoopVectorize parameter '{}'", ParamName).str(),
1194 }
1195 }
1196 return Opts;
1197}
1198
1199Expected<std::pair<bool, bool>> parseLoopUnswitchOptions(StringRef Params) {
1200 std::pair<bool, bool> Result = {false, true};
1201 while (!Params.empty()) {
1202 StringRef ParamName;
1203 std::tie(ParamName, Params) = Params.split(';');
1204
1205 bool Enable = !ParamName.consume_front("no-");
1206 if (ParamName == "nontrivial") {
1207 Result.first = Enable;
1208 } else if (ParamName == "trivial") {
1209 Result.second = Enable;
1210 } else {
1212 formatv("invalid LoopUnswitch pass parameter '{}'", ParamName).str(),
1214 }
1215 }
1216 return Result;
1217}
1218
1219Expected<LICMOptions> parseLICMOptions(StringRef Params) {
1221 while (!Params.empty()) {
1222 StringRef ParamName;
1223 std::tie(ParamName, Params) = Params.split(';');
1224
1225 bool Enable = !ParamName.consume_front("no-");
1226 if (ParamName == "allowspeculation") {
1227 Result.AllowSpeculation = Enable;
1228 } else {
1230 formatv("invalid LICM pass parameter '{}'", ParamName).str(),
1232 }
1233 }
1234 return Result;
1235}
1236
1237Expected<std::pair<bool, bool>> parseLoopRotateOptions(StringRef Params) {
1238 std::pair<bool, bool> Result = {true, false};
1239 while (!Params.empty()) {
1240 StringRef ParamName;
1241 std::tie(ParamName, Params) = Params.split(';');
1242
1243 bool Enable = !ParamName.consume_front("no-");
1244 if (ParamName == "header-duplication") {
1245 Result.first = Enable;
1246 } else if (ParamName == "prepare-for-lto") {
1247 Result.second = Enable;
1248 } else {
1250 formatv("invalid LoopRotate pass parameter '{}'", ParamName).str(),
1252 }
1253 }
1254 return Result;
1255}
1256
1257Expected<bool> parseMergedLoadStoreMotionOptions(StringRef Params) {
1258 bool Result = false;
1259 while (!Params.empty()) {
1260 StringRef ParamName;
1261 std::tie(ParamName, Params) = Params.split(';');
1262
1263 bool Enable = !ParamName.consume_front("no-");
1264 if (ParamName == "split-footer-bb") {
1265 Result = Enable;
1266 } else {
1268 formatv("invalid MergedLoadStoreMotion pass parameter '{}'",
1269 ParamName)
1270 .str(),
1272 }
1273 }
1274 return Result;
1275}
1276
1277Expected<GVNOptions> parseGVNOptions(StringRef Params) {
1279 while (!Params.empty()) {
1280 StringRef ParamName;
1281 std::tie(ParamName, Params) = Params.split(';');
1282
1283 bool Enable = !ParamName.consume_front("no-");
1284 if (ParamName == "pre") {
1285 Result.setPRE(Enable);
1286 } else if (ParamName == "load-pre") {
1287 Result.setLoadPRE(Enable);
1288 } else if (ParamName == "split-backedge-load-pre") {
1289 Result.setLoadPRESplitBackedge(Enable);
1290 } else if (ParamName == "memdep") {
1291 // MemDep and MemorySSA are mutually exclusive.
1292 Result.setMemDep(Enable);
1293 Result.setMemorySSA(!Enable);
1294 } else if (ParamName == "memoryssa") {
1295 // MemDep and MemorySSA are mutually exclusive.
1296 Result.setMemorySSA(Enable);
1297 Result.setMemDep(!Enable);
1298 } else {
1300 formatv("invalid GVN pass parameter '{}'", ParamName).str(),
1302 }
1303 }
1304 return Result;
1305}
1306
1307Expected<IPSCCPOptions> parseIPSCCPOptions(StringRef Params) {
1309 while (!Params.empty()) {
1310 StringRef ParamName;
1311 std::tie(ParamName, Params) = Params.split(';');
1312
1313 bool Enable = !ParamName.consume_front("no-");
1314 if (ParamName == "func-spec")
1315 Result.setFuncSpec(Enable);
1316 else
1318 formatv("invalid IPSCCP pass parameter '{}'", ParamName).str(),
1320 }
1321 return Result;
1322}
1323
1324Expected<ScalarizerPassOptions> parseScalarizerOptions(StringRef Params) {
1326 while (!Params.empty()) {
1327 StringRef ParamName;
1328 std::tie(ParamName, Params) = Params.split(';');
1329
1330 if (ParamName.consume_front("min-bits=")) {
1331 if (ParamName.getAsInteger(0, Result.ScalarizeMinBits)) {
1333 formatv("invalid argument to Scalarizer pass min-bits "
1334 "parameter: '{}'",
1335 ParamName)
1336 .str(),
1338 }
1339
1340 continue;
1341 }
1342
1343 bool Enable = !ParamName.consume_front("no-");
1344 if (ParamName == "load-store")
1345 Result.ScalarizeLoadStore = Enable;
1346 else if (ParamName == "variable-insert-extract")
1347 Result.ScalarizeVariableInsertExtract = Enable;
1348 else {
1350 formatv("invalid Scalarizer pass parameter '{}'", ParamName).str(),
1352 }
1353 }
1354
1355 return Result;
1356}
1357
1358Expected<SROAOptions> parseSROAOptions(StringRef Params) {
1359 if (Params.empty() || Params == "modify-cfg")
1361 if (Params == "preserve-cfg")
1364 formatv("invalid SROA pass parameter '{}' (either preserve-cfg or "
1365 "modify-cfg can be specified)",
1366 Params)
1367 .str(),
1369}
1370
1372parseStackLifetimeOptions(StringRef Params) {
1374 while (!Params.empty()) {
1375 StringRef ParamName;
1376 std::tie(ParamName, Params) = Params.split(';');
1377
1378 if (ParamName == "may") {
1380 } else if (ParamName == "must") {
1382 } else {
1384 formatv("invalid StackLifetime parameter '{}'", ParamName).str(),
1386 }
1387 }
1388 return Result;
1389}
1390
1391Expected<bool> parseDependenceAnalysisPrinterOptions(StringRef Params) {
1392 return PassBuilder::parseSinglePassOption(Params, "normalized-results",
1393 "DependenceAnalysisPrinter");
1394}
1395
1396Expected<bool> parseSeparateConstOffsetFromGEPPassOptions(StringRef Params) {
1397 return PassBuilder::parseSinglePassOption(Params, "lower-gep",
1398 "SeparateConstOffsetFromGEP");
1399}
1400
1401Expected<bool> parseStructurizeCFGPassOptions(StringRef Params) {
1402 return PassBuilder::parseSinglePassOption(Params, "skip-uniform-regions",
1403 "StructurizeCFG");
1404}
1405
1407parseFunctionSimplificationPipelineOptions(StringRef Params) {
1408 std::optional<OptimizationLevel> L = parseOptLevel(Params);
1409 if (!L || *L == OptimizationLevel::O0) {
1411 formatv("invalid function-simplification parameter '{}'", Params).str(),
1413 };
1414 return *L;
1415}
1416
1417Expected<bool> parseMemorySSAPrinterPassOptions(StringRef Params) {
1418 return PassBuilder::parseSinglePassOption(Params, "no-ensure-optimized-uses",
1419 "MemorySSAPrinterPass");
1420}
1421
1422Expected<bool> parseSpeculativeExecutionPassOptions(StringRef Params) {
1423 return PassBuilder::parseSinglePassOption(Params, "only-if-divergent-target",
1424 "SpeculativeExecutionPass");
1425}
1426
1427Expected<std::string> parseMemProfUsePassOptions(StringRef Params) {
1428 std::string Result;
1429 while (!Params.empty()) {
1430 StringRef ParamName;
1431 std::tie(ParamName, Params) = Params.split(';');
1432
1433 if (ParamName.consume_front("profile-filename=")) {
1434 Result = ParamName.str();
1435 } else {
1437 formatv("invalid MemProfUse pass parameter '{}'", ParamName).str(),
1439 }
1440 }
1441 return Result;
1442}
1443
1445parseStructuralHashPrinterPassOptions(StringRef Params) {
1446 if (Params.empty())
1448 if (Params == "detailed")
1450 if (Params == "call-target-ignored")
1453 formatv("invalid structural hash printer parameter '{}'", Params).str(),
1455}
1456
1457Expected<bool> parseWinEHPrepareOptions(StringRef Params) {
1458 return PassBuilder::parseSinglePassOption(Params, "demote-catchswitch-only",
1459 "WinEHPreparePass");
1460}
1461
1462Expected<GlobalMergeOptions> parseGlobalMergeOptions(StringRef Params) {
1464 while (!Params.empty()) {
1465 StringRef ParamName;
1466 std::tie(ParamName, Params) = Params.split(';');
1467
1468 bool Enable = !ParamName.consume_front("no-");
1469 if (ParamName == "group-by-use")
1470 Result.GroupByUse = Enable;
1471 else if (ParamName == "ignore-single-use")
1472 Result.IgnoreSingleUse = Enable;
1473 else if (ParamName == "merge-const")
1474 Result.MergeConstantGlobals = Enable;
1475 else if (ParamName == "merge-const-aggressive")
1476 Result.MergeConstAggressive = Enable;
1477 else if (ParamName == "merge-external")
1478 Result.MergeExternal = Enable;
1479 else if (ParamName.consume_front("max-offset=")) {
1480 if (ParamName.getAsInteger(0, Result.MaxOffset))
1482 formatv("invalid GlobalMergePass parameter '{}'", ParamName).str(),
1484 } else {
1486 formatv("invalid global-merge pass parameter '{}'", Params).str(),
1488 }
1489 }
1490 return Result;
1491}
1492
1493Expected<SmallVector<std::string, 0>> parseInternalizeGVs(StringRef Params) {
1494 SmallVector<std::string, 1> PreservedGVs;
1495 while (!Params.empty()) {
1496 StringRef ParamName;
1497 std::tie(ParamName, Params) = Params.split(';');
1498
1499 if (ParamName.consume_front("preserve-gv=")) {
1500 PreservedGVs.push_back(ParamName.str());
1501 } else {
1503 formatv("invalid Internalize pass parameter '{}'", ParamName).str(),
1505 }
1506 }
1507
1508 return Expected<SmallVector<std::string, 0>>(std::move(PreservedGVs));
1509}
1510
1512parseRegAllocFastPassOptions(PassBuilder &PB, StringRef Params) {
1514 while (!Params.empty()) {
1515 StringRef ParamName;
1516 std::tie(ParamName, Params) = Params.split(';');
1517
1518 if (ParamName.consume_front("filter=")) {
1519 std::optional<RegAllocFilterFunc> Filter =
1520 PB.parseRegAllocFilter(ParamName);
1521 if (!Filter) {
1523 formatv("invalid regallocfast register filter '{}'", ParamName)
1524 .str(),
1526 }
1527 Opts.Filter = *Filter;
1528 Opts.FilterName = ParamName;
1529 continue;
1530 }
1531
1532 if (ParamName == "no-clear-vregs") {
1533 Opts.ClearVRegs = false;
1534 continue;
1535 }
1536
1538 formatv("invalid regallocfast pass parameter '{}'", ParamName).str(),
1540 }
1541 return Opts;
1542}
1543
1545parseBoundsCheckingOptions(StringRef Params) {
1547 while (!Params.empty()) {
1548 StringRef ParamName;
1549 std::tie(ParamName, Params) = Params.split(';');
1550 if (ParamName == "trap") {
1551 Options.Rt = std::nullopt;
1552 } else if (ParamName == "rt") {
1553 Options.Rt = {
1554 /*MinRuntime=*/false,
1555 /*MayReturn=*/true,
1556 };
1557 } else if (ParamName == "rt-abort") {
1558 Options.Rt = {
1559 /*MinRuntime=*/false,
1560 /*MayReturn=*/false,
1561 };
1562 } else if (ParamName == "min-rt") {
1563 Options.Rt = {
1564 /*MinRuntime=*/true,
1565 /*MayReturn=*/true,
1566 };
1567 } else if (ParamName == "min-rt-abort") {
1568 Options.Rt = {
1569 /*MinRuntime=*/true,
1570 /*MayReturn=*/false,
1571 };
1572 } else if (ParamName == "merge") {
1573 Options.Merge = true;
1574 } else {
1575 StringRef ParamEQ;
1576 StringRef Val;
1577 std::tie(ParamEQ, Val) = ParamName.split('=');
1578 int8_t Id;
1579 if (ParamEQ == "guard" && !Val.getAsInteger(0, Id)) {
1580 Options.GuardKind = Id;
1581 } else {
1583 formatv("invalid BoundsChecking pass parameter '{}'", ParamName)
1584 .str(),
1586 }
1587 }
1588 }
1589 return Options;
1590}
1591
1592Expected<CodeGenOptLevel> parseExpandFpOptions(StringRef Param) {
1593 if (Param.empty())
1594 return CodeGenOptLevel::None;
1595
1596 // Parse a CodeGenOptLevel, e.g. "O1", "O2", "O3".
1597 auto [Prefix, Digit] = Param.split('O');
1598
1599 uint8_t N;
1600 if (!Prefix.empty() || Digit.getAsInteger(10, N))
1601 return createStringError("invalid expand-fp pass parameter '%s'",
1602 Param.str().c_str());
1603
1604 std::optional<CodeGenOptLevel> Level = CodeGenOpt::getLevel(N);
1605 if (!Level.has_value())
1606 return createStringError(
1607 "invalid optimization level for expand-fp pass: %s",
1608 Digit.str().c_str());
1609
1610 return *Level;
1611}
1612
1614parseRegAllocGreedyFilterFunc(PassBuilder &PB, StringRef Params) {
1615 if (Params.empty() || Params == "all")
1616 return RAGreedyPass::Options();
1617
1618 std::optional<RegAllocFilterFunc> Filter = PB.parseRegAllocFilter(Params);
1619 if (Filter)
1620 return RAGreedyPass::Options{*Filter, Params};
1621
1623 formatv("invalid regallocgreedy register filter '{}'", Params).str(),
1625}
1626
1627Expected<bool> parseMachineSinkingPassOptions(StringRef Params) {
1628 return PassBuilder::parseSinglePassOption(Params, "enable-sink-fold",
1629 "MachineSinkingPass");
1630}
1631
1632Expected<bool> parseMachineBlockPlacementPassOptions(StringRef Params) {
1633 bool AllowTailMerge = true;
1634 if (!Params.empty()) {
1635 AllowTailMerge = !Params.consume_front("no-");
1636 if (Params != "tail-merge")
1638 formatv("invalid MachineBlockPlacementPass parameter '{}'", Params)
1639 .str(),
1641 }
1642 return AllowTailMerge;
1643}
1644
1645Expected<bool> parseVirtRegRewriterPassOptions(StringRef Params) {
1646 bool ClearVirtRegs = true;
1647 if (!Params.empty()) {
1648 ClearVirtRegs = !Params.consume_front("no-");
1649 if (Params != "clear-vregs")
1651 formatv("invalid VirtRegRewriter pass parameter '{}'", Params).str(),
1653 }
1654 return ClearVirtRegs;
1655}
1656
1657struct FatLTOOptions {
1658 OptimizationLevel OptLevel;
1659 bool ThinLTO = false;
1660 bool EmitSummary = false;
1661};
1662
1663Expected<FatLTOOptions> parseFatLTOOptions(StringRef Params) {
1664 FatLTOOptions Result;
1665 bool HaveOptLevel = false;
1666 while (!Params.empty()) {
1667 StringRef ParamName;
1668 std::tie(ParamName, Params) = Params.split(';');
1669
1670 if (ParamName == "thinlto") {
1671 Result.ThinLTO = true;
1672 } else if (ParamName == "emit-summary") {
1673 Result.EmitSummary = true;
1674 } else if (std::optional<OptimizationLevel> OptLevel =
1675 parseOptLevel(ParamName)) {
1676 Result.OptLevel = *OptLevel;
1677 HaveOptLevel = true;
1678 } else {
1680 formatv("invalid fatlto-pre-link pass parameter '{}'", ParamName)
1681 .str(),
1683 }
1684 }
1685 if (!HaveOptLevel)
1687 "missing optimization level for fatlto-pre-link pipeline",
1689 return Result;
1690}
1691
1692} // namespace
1693
1694/// Tests whether registered callbacks will accept a given pass name.
1695///
1696/// When parsing a pipeline text, the type of the outermost pipeline may be
1697/// omitted, in which case the type is automatically determined from the first
1698/// pass name in the text. This may be a name that is handled through one of the
1699/// callbacks. We check this through the oridinary parsing callbacks by setting
1700/// up a dummy PassManager in order to not force the client to also handle this
1701/// type of query.
1702template <typename PassManagerT, typename CallbacksT>
1703static bool callbacksAcceptPassName(StringRef Name, CallbacksT &Callbacks) {
1704 if (!Callbacks.empty()) {
1705 PassManagerT DummyPM;
1706 for (auto &CB : Callbacks)
1707 if (CB(Name, DummyPM, {}))
1708 return true;
1709 }
1710 return false;
1711}
1712
1713template <typename CallbacksT>
1714static bool isModulePassName(StringRef Name, CallbacksT &Callbacks) {
1715 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1716
1717 // Explicitly handle pass manager names.
1718 if (Name == "module")
1719 return true;
1720 if (Name == "cgscc")
1721 return true;
1722 if (NameNoBracket == "function")
1723 return true;
1724 if (Name == "coro-cond")
1725 return true;
1726
1727#define MODULE_PASS(NAME, CREATE_PASS) \
1728 if (Name == NAME) \
1729 return true;
1730#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1731 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1732 return true;
1733#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
1734 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1735 return true;
1736#include "PassRegistry.def"
1737
1738 return callbacksAcceptPassName<ModulePassManager>(Name, Callbacks);
1739}
1740
1741template <typename CallbacksT>
1742static bool isCGSCCPassName(StringRef Name, CallbacksT &Callbacks) {
1743 // Explicitly handle pass manager names.
1744 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1745 if (Name == "cgscc")
1746 return true;
1747 if (NameNoBracket == "function")
1748 return true;
1749
1750 // Explicitly handle custom-parsed pass names.
1751 if (parseDevirtPassName(Name))
1752 return true;
1753
1754#define CGSCC_PASS(NAME, CREATE_PASS) \
1755 if (Name == NAME) \
1756 return true;
1757#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1758 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1759 return true;
1760#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
1761 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1762 return true;
1763#include "PassRegistry.def"
1764
1765 return callbacksAcceptPassName<CGSCCPassManager>(Name, Callbacks);
1766}
1767
1768template <typename CallbacksT>
1769static bool isFunctionPassName(StringRef Name, CallbacksT &Callbacks) {
1770 // Explicitly handle pass manager names.
1771 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1772 if (NameNoBracket == "function")
1773 return true;
1774 if (Name == "loop" || Name == "loop-mssa" || Name == "machine-function")
1775 return true;
1776
1777#define FUNCTION_PASS(NAME, CREATE_PASS) \
1778 if (Name == NAME) \
1779 return true;
1780#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1781 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1782 return true;
1783#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1784 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1785 return true;
1786#include "PassRegistry.def"
1787
1788 return callbacksAcceptPassName<FunctionPassManager>(Name, Callbacks);
1789}
1790
1791template <typename CallbacksT>
1792static bool isMachineFunctionPassName(StringRef Name, CallbacksT &Callbacks) {
1793 // Explicitly handle pass manager names.
1794 if (Name == "machine-function")
1795 return true;
1796
1797#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
1798 if (Name == NAME) \
1799 return true;
1800#define MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, \
1801 PARAMS) \
1802 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1803 return true;
1804
1805#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1806 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1807 return true;
1808
1809#include "llvm/Passes/MachinePassRegistry.def"
1810
1812}
1813
1814template <typename CallbacksT>
1815static bool isLoopNestPassName(StringRef Name, CallbacksT &Callbacks,
1816 bool &UseMemorySSA) {
1817 UseMemorySSA = false;
1818
1819 if (PassBuilder::checkParametrizedPassName(Name, "lnicm")) {
1820 UseMemorySSA = true;
1821 return true;
1822 }
1823
1824#define LOOPNEST_PASS(NAME, CREATE_PASS) \
1825 if (Name == NAME) \
1826 return true;
1827#include "PassRegistry.def"
1828
1829 return callbacksAcceptPassName<LoopPassManager>(Name, Callbacks);
1830}
1831
1832template <typename CallbacksT>
1833static bool isLoopPassName(StringRef Name, CallbacksT &Callbacks,
1834 bool &UseMemorySSA) {
1835 UseMemorySSA = false;
1836
1837 if (PassBuilder::checkParametrizedPassName(Name, "licm")) {
1838 UseMemorySSA = true;
1839 return true;
1840 }
1841
1842#define LOOP_PASS(NAME, CREATE_PASS) \
1843 if (Name == NAME) \
1844 return true;
1845#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1846 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1847 return true;
1848#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
1849 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1850 return true;
1851#include "PassRegistry.def"
1852
1853 return callbacksAcceptPassName<LoopPassManager>(Name, Callbacks);
1854}
1855
1856std::optional<std::vector<PassBuilder::PipelineElement>>
1857PassBuilder::parsePipelineText(StringRef Text) {
1858 std::vector<PipelineElement> ResultPipeline;
1859
1860 SmallVector<std::vector<PipelineElement> *, 4> PipelineStack = {
1861 &ResultPipeline};
1862 for (;;) {
1863 std::vector<PipelineElement> &Pipeline = *PipelineStack.back();
1864 size_t Pos = Text.find_first_of(",()");
1865 Pipeline.push_back({Text.substr(0, Pos), {}});
1866
1867 // If we have a single terminating name, we're done.
1868 if (Pos == Text.npos)
1869 break;
1870
1871 char Sep = Text[Pos];
1872 Text = Text.substr(Pos + 1);
1873 if (Sep == ',')
1874 // Just a name ending in a comma, continue.
1875 continue;
1876
1877 if (Sep == '(') {
1878 // Push the inner pipeline onto the stack to continue processing.
1879 PipelineStack.push_back(&Pipeline.back().InnerPipeline);
1880 continue;
1881 }
1882
1883 assert(Sep == ')' && "Bogus separator!");
1884 // When handling the close parenthesis, we greedily consume them to avoid
1885 // empty strings in the pipeline.
1886 do {
1887 // If we try to pop the outer pipeline we have unbalanced parentheses.
1888 if (PipelineStack.size() == 1)
1889 return std::nullopt;
1890
1891 PipelineStack.pop_back();
1892 } while (Text.consume_front(")"));
1893
1894 // Check if we've finished parsing.
1895 if (Text.empty())
1896 break;
1897
1898 // Otherwise, the end of an inner pipeline always has to be followed by
1899 // a comma, and then we can continue.
1900 if (!Text.consume_front(","))
1901 return std::nullopt;
1902 }
1903
1904 if (PipelineStack.size() > 1)
1905 // Unbalanced paretheses.
1906 return std::nullopt;
1907
1908 assert(PipelineStack.back() == &ResultPipeline &&
1909 "Wrong pipeline at the bottom of the stack!");
1910 return {std::move(ResultPipeline)};
1911}
1912
1915 // This is consistent with old pass manager invoked via opt, but
1916 // inconsistent with clang. Clang doesn't enable loop vectorization
1917 // but does enable slp vectorization at Oz.
1918 PTO.LoopVectorization = L.getSpeedupLevel() > 1 && L != OptimizationLevel::Oz;
1919 PTO.SLPVectorization = L.getSpeedupLevel() > 1 && L != OptimizationLevel::Oz;
1920}
1921
1922Error PassBuilder::parseModulePass(ModulePassManager &MPM,
1923 const PipelineElement &E) {
1924 auto &Name = E.Name;
1925 auto &InnerPipeline = E.InnerPipeline;
1926
1927 // First handle complex passes like the pass managers which carry pipelines.
1928 if (!InnerPipeline.empty()) {
1929 if (Name == "module") {
1930 ModulePassManager NestedMPM;
1931 if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline))
1932 return Err;
1933 MPM.addPass(std::move(NestedMPM));
1934 return Error::success();
1935 }
1936 if (Name == "coro-cond") {
1937 ModulePassManager NestedMPM;
1938 if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline))
1939 return Err;
1940 MPM.addPass(CoroConditionalWrapper(std::move(NestedMPM)));
1941 return Error::success();
1942 }
1943 if (Name == "cgscc") {
1944 CGSCCPassManager CGPM;
1945 if (auto Err = parseCGSCCPassPipeline(CGPM, InnerPipeline))
1946 return Err;
1948 return Error::success();
1949 }
1950 if (auto Params = parseFunctionPipelineName(Name)) {
1951 if (Params->second)
1953 "cannot have a no-rerun module to function adaptor",
1956 if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline))
1957 return Err;
1958 MPM.addPass(
1959 createModuleToFunctionPassAdaptor(std::move(FPM), Params->first));
1960 return Error::success();
1961 }
1962
1963 for (auto &C : ModulePipelineParsingCallbacks)
1964 if (C(Name, MPM, InnerPipeline))
1965 return Error::success();
1966
1967 // Normal passes can't have pipelines.
1969 formatv("invalid use of '{}' pass as module pipeline", Name).str(),
1971 ;
1972 }
1973
1974 // Finally expand the basic registered passes from the .inc file.
1975#define MODULE_PASS(NAME, CREATE_PASS) \
1976 if (Name == NAME) { \
1977 MPM.addPass(CREATE_PASS); \
1978 return Error::success(); \
1979 }
1980#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1981 if (checkParametrizedPassName(Name, NAME)) { \
1982 auto Params = parsePassParameters(PARSER, Name, NAME); \
1983 if (!Params) \
1984 return Params.takeError(); \
1985 MPM.addPass(CREATE_PASS(Params.get())); \
1986 return Error::success(); \
1987 }
1988#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
1989 if (Name == "require<" NAME ">") { \
1990 MPM.addPass( \
1991 RequireAnalysisPass< \
1992 std::remove_reference_t<decltype(CREATE_PASS)>, Module>()); \
1993 return Error::success(); \
1994 } \
1995 if (Name == "invalidate<" NAME ">") { \
1996 MPM.addPass(InvalidateAnalysisPass< \
1997 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
1998 return Error::success(); \
1999 }
2000#define CGSCC_PASS(NAME, CREATE_PASS) \
2001 if (Name == NAME) { \
2002 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(CREATE_PASS)); \
2003 return Error::success(); \
2004 }
2005#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2006 if (checkParametrizedPassName(Name, NAME)) { \
2007 auto Params = parsePassParameters(PARSER, Name, NAME); \
2008 if (!Params) \
2009 return Params.takeError(); \
2010 MPM.addPass( \
2011 createModuleToPostOrderCGSCCPassAdaptor(CREATE_PASS(Params.get()))); \
2012 return Error::success(); \
2013 }
2014#define FUNCTION_PASS(NAME, CREATE_PASS) \
2015 if (Name == NAME) { \
2016 MPM.addPass(createModuleToFunctionPassAdaptor(CREATE_PASS)); \
2017 return Error::success(); \
2018 }
2019#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2020 if (checkParametrizedPassName(Name, NAME)) { \
2021 auto Params = parsePassParameters(PARSER, Name, NAME); \
2022 if (!Params) \
2023 return Params.takeError(); \
2024 MPM.addPass(createModuleToFunctionPassAdaptor(CREATE_PASS(Params.get()))); \
2025 return Error::success(); \
2026 }
2027#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2028 if (Name == NAME) { \
2029 MPM.addPass(createModuleToFunctionPassAdaptor( \
2030 createFunctionToLoopPassAdaptor(CREATE_PASS, false, false))); \
2031 return Error::success(); \
2032 }
2033#define LOOP_PASS(NAME, CREATE_PASS) \
2034 if (Name == NAME) { \
2035 MPM.addPass(createModuleToFunctionPassAdaptor( \
2036 createFunctionToLoopPassAdaptor(CREATE_PASS, false, false))); \
2037 return Error::success(); \
2038 }
2039#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2040 if (checkParametrizedPassName(Name, NAME)) { \
2041 auto Params = parsePassParameters(PARSER, Name, NAME); \
2042 if (!Params) \
2043 return Params.takeError(); \
2044 MPM.addPass( \
2045 createModuleToFunctionPassAdaptor(createFunctionToLoopPassAdaptor( \
2046 CREATE_PASS(Params.get()), false, false))); \
2047 return Error::success(); \
2048 }
2049#include "PassRegistry.def"
2050
2051 for (auto &C : ModulePipelineParsingCallbacks)
2052 if (C(Name, MPM, InnerPipeline))
2053 return Error::success();
2055 formatv("unknown module pass '{}'", Name).str(),
2057}
2058
2059Error PassBuilder::parseCGSCCPass(CGSCCPassManager &CGPM,
2060 const PipelineElement &E) {
2061 auto &Name = E.Name;
2062 auto &InnerPipeline = E.InnerPipeline;
2063
2064 // First handle complex passes like the pass managers which carry pipelines.
2065 if (!InnerPipeline.empty()) {
2066 if (Name == "cgscc") {
2067 CGSCCPassManager NestedCGPM;
2068 if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline))
2069 return Err;
2070 // Add the nested pass manager with the appropriate adaptor.
2071 CGPM.addPass(std::move(NestedCGPM));
2072 return Error::success();
2073 }
2074 if (auto Params = parseFunctionPipelineName(Name)) {
2076 if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline))
2077 return Err;
2078 // Add the nested pass manager with the appropriate adaptor.
2080 std::move(FPM), Params->first, Params->second));
2081 return Error::success();
2082 }
2083 if (auto MaxRepetitions = parseDevirtPassName(Name)) {
2084 CGSCCPassManager NestedCGPM;
2085 if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline))
2086 return Err;
2087 CGPM.addPass(
2088 createDevirtSCCRepeatedPass(std::move(NestedCGPM), *MaxRepetitions));
2089 return Error::success();
2090 }
2091
2092 for (auto &C : CGSCCPipelineParsingCallbacks)
2093 if (C(Name, CGPM, InnerPipeline))
2094 return Error::success();
2095
2096 // Normal passes can't have pipelines.
2098 formatv("invalid use of '{}' pass as cgscc pipeline", Name).str(),
2100 }
2101
2102// Now expand the basic registered passes from the .inc file.
2103#define CGSCC_PASS(NAME, CREATE_PASS) \
2104 if (Name == NAME) { \
2105 CGPM.addPass(CREATE_PASS); \
2106 return Error::success(); \
2107 }
2108#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2109 if (checkParametrizedPassName(Name, NAME)) { \
2110 auto Params = parsePassParameters(PARSER, Name, NAME); \
2111 if (!Params) \
2112 return Params.takeError(); \
2113 CGPM.addPass(CREATE_PASS(Params.get())); \
2114 return Error::success(); \
2115 }
2116#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
2117 if (Name == "require<" NAME ">") { \
2118 CGPM.addPass(RequireAnalysisPass< \
2119 std::remove_reference_t<decltype(CREATE_PASS)>, \
2120 LazyCallGraph::SCC, CGSCCAnalysisManager, LazyCallGraph &, \
2121 CGSCCUpdateResult &>()); \
2122 return Error::success(); \
2123 } \
2124 if (Name == "invalidate<" NAME ">") { \
2125 CGPM.addPass(InvalidateAnalysisPass< \
2126 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2127 return Error::success(); \
2128 }
2129#define FUNCTION_PASS(NAME, CREATE_PASS) \
2130 if (Name == NAME) { \
2131 CGPM.addPass(createCGSCCToFunctionPassAdaptor(CREATE_PASS)); \
2132 return Error::success(); \
2133 }
2134#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2135 if (checkParametrizedPassName(Name, NAME)) { \
2136 auto Params = parsePassParameters(PARSER, Name, NAME); \
2137 if (!Params) \
2138 return Params.takeError(); \
2139 CGPM.addPass(createCGSCCToFunctionPassAdaptor(CREATE_PASS(Params.get()))); \
2140 return Error::success(); \
2141 }
2142#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2143 if (Name == NAME) { \
2144 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
2145 createFunctionToLoopPassAdaptor(CREATE_PASS, false, false))); \
2146 return Error::success(); \
2147 }
2148#define LOOP_PASS(NAME, CREATE_PASS) \
2149 if (Name == NAME) { \
2150 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
2151 createFunctionToLoopPassAdaptor(CREATE_PASS, false, false))); \
2152 return Error::success(); \
2153 }
2154#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2155 if (checkParametrizedPassName(Name, NAME)) { \
2156 auto Params = parsePassParameters(PARSER, Name, NAME); \
2157 if (!Params) \
2158 return Params.takeError(); \
2159 CGPM.addPass( \
2160 createCGSCCToFunctionPassAdaptor(createFunctionToLoopPassAdaptor( \
2161 CREATE_PASS(Params.get()), false, false))); \
2162 return Error::success(); \
2163 }
2164#include "PassRegistry.def"
2165
2166 for (auto &C : CGSCCPipelineParsingCallbacks)
2167 if (C(Name, CGPM, InnerPipeline))
2168 return Error::success();
2169 return make_error<StringError>(formatv("unknown cgscc pass '{}'", Name).str(),
2171}
2172
2173Error PassBuilder::parseFunctionPass(FunctionPassManager &FPM,
2174 const PipelineElement &E) {
2175 auto &Name = E.Name;
2176 auto &InnerPipeline = E.InnerPipeline;
2177
2178 // First handle complex passes like the pass managers which carry pipelines.
2179 if (!InnerPipeline.empty()) {
2180 if (Name == "function") {
2181 FunctionPassManager NestedFPM;
2182 if (auto Err = parseFunctionPassPipeline(NestedFPM, InnerPipeline))
2183 return Err;
2184 // Add the nested pass manager with the appropriate adaptor.
2185 FPM.addPass(std::move(NestedFPM));
2186 return Error::success();
2187 }
2188 if (Name == "loop" || Name == "loop-mssa") {
2189 LoopPassManager LPM;
2190 if (auto Err = parseLoopPassPipeline(LPM, InnerPipeline))
2191 return Err;
2192 // Add the nested pass manager with the appropriate adaptor.
2193 bool UseMemorySSA = (Name == "loop-mssa");
2194 bool UseBFI = llvm::any_of(InnerPipeline, [](auto Pipeline) {
2195 return Pipeline.Name.contains("simple-loop-unswitch");
2196 });
2197 FPM.addPass(createFunctionToLoopPassAdaptor(std::move(LPM), UseMemorySSA,
2198 UseBFI));
2199 return Error::success();
2200 }
2201 if (Name == "machine-function") {
2203 if (auto Err = parseMachinePassPipeline(MFPM, InnerPipeline))
2204 return Err;
2206 return Error::success();
2207 }
2208
2209 for (auto &C : FunctionPipelineParsingCallbacks)
2210 if (C(Name, FPM, InnerPipeline))
2211 return Error::success();
2212
2213 // Normal passes can't have pipelines.
2215 formatv("invalid use of '{}' pass as function pipeline", Name).str(),
2217 }
2218
2219// Now expand the basic registered passes from the .inc file.
2220#define FUNCTION_PASS(NAME, CREATE_PASS) \
2221 if (Name == NAME) { \
2222 FPM.addPass(CREATE_PASS); \
2223 return Error::success(); \
2224 }
2225#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2226 if (checkParametrizedPassName(Name, NAME)) { \
2227 auto Params = parsePassParameters(PARSER, Name, NAME); \
2228 if (!Params) \
2229 return Params.takeError(); \
2230 FPM.addPass(CREATE_PASS(Params.get())); \
2231 return Error::success(); \
2232 }
2233#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
2234 if (Name == "require<" NAME ">") { \
2235 FPM.addPass( \
2236 RequireAnalysisPass< \
2237 std::remove_reference_t<decltype(CREATE_PASS)>, Function>()); \
2238 return Error::success(); \
2239 } \
2240 if (Name == "invalidate<" NAME ">") { \
2241 FPM.addPass(InvalidateAnalysisPass< \
2242 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2243 return Error::success(); \
2244 }
2245// FIXME: UseMemorySSA is set to false. Maybe we could do things like:
2246// bool UseMemorySSA = !("canon-freeze" || "loop-predication" ||
2247// "guard-widening");
2248// The risk is that it may become obsolete if we're not careful.
2249#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2250 if (Name == NAME) { \
2251 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS, false, false)); \
2252 return Error::success(); \
2253 }
2254#define LOOP_PASS(NAME, CREATE_PASS) \
2255 if (Name == NAME) { \
2256 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS, false, false)); \
2257 return Error::success(); \
2258 }
2259#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2260 if (checkParametrizedPassName(Name, NAME)) { \
2261 auto Params = parsePassParameters(PARSER, Name, NAME); \
2262 if (!Params) \
2263 return Params.takeError(); \
2264 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), \
2265 false, false)); \
2266 return Error::success(); \
2267 }
2268#include "PassRegistry.def"
2269
2270 for (auto &C : FunctionPipelineParsingCallbacks)
2271 if (C(Name, FPM, InnerPipeline))
2272 return Error::success();
2274 formatv("unknown function pass '{}'", Name).str(),
2276}
2277
2278Error PassBuilder::parseLoopPass(LoopPassManager &LPM,
2279 const PipelineElement &E) {
2280 StringRef Name = E.Name;
2281 auto &InnerPipeline = E.InnerPipeline;
2282
2283 // First handle complex passes like the pass managers which carry pipelines.
2284 if (!InnerPipeline.empty()) {
2285 if (Name == "loop") {
2286 LoopPassManager NestedLPM;
2287 if (auto Err = parseLoopPassPipeline(NestedLPM, InnerPipeline))
2288 return Err;
2289 // Add the nested pass manager with the appropriate adaptor.
2290 LPM.addPass(std::move(NestedLPM));
2291 return Error::success();
2292 }
2293
2294 for (auto &C : LoopPipelineParsingCallbacks)
2295 if (C(Name, LPM, InnerPipeline))
2296 return Error::success();
2297
2298 // Normal passes can't have pipelines.
2300 formatv("invalid use of '{}' pass as loop pipeline", Name).str(),
2302 }
2303
2304// Now expand the basic registered passes from the .inc file.
2305#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2306 if (Name == NAME) { \
2307 LPM.addPass(CREATE_PASS); \
2308 return Error::success(); \
2309 }
2310#define LOOP_PASS(NAME, CREATE_PASS) \
2311 if (Name == NAME) { \
2312 LPM.addPass(CREATE_PASS); \
2313 return Error::success(); \
2314 }
2315#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2316 if (checkParametrizedPassName(Name, NAME)) { \
2317 auto Params = parsePassParameters(PARSER, Name, NAME); \
2318 if (!Params) \
2319 return Params.takeError(); \
2320 LPM.addPass(CREATE_PASS(Params.get())); \
2321 return Error::success(); \
2322 }
2323#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
2324 if (Name == "require<" NAME ">") { \
2325 LPM.addPass(RequireAnalysisPass< \
2326 std::remove_reference_t<decltype(CREATE_PASS)>, Loop, \
2327 LoopAnalysisManager, LoopStandardAnalysisResults &, \
2328 LPMUpdater &>()); \
2329 return Error::success(); \
2330 } \
2331 if (Name == "invalidate<" NAME ">") { \
2332 LPM.addPass(InvalidateAnalysisPass< \
2333 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2334 return Error::success(); \
2335 }
2336#include "PassRegistry.def"
2337
2338 for (auto &C : LoopPipelineParsingCallbacks)
2339 if (C(Name, LPM, InnerPipeline))
2340 return Error::success();
2341 return make_error<StringError>(formatv("unknown loop pass '{}'", Name).str(),
2343}
2344
2345Error PassBuilder::parseMachinePass(MachineFunctionPassManager &MFPM,
2346 const PipelineElement &E) {
2347 StringRef Name = E.Name;
2348 // Handle any nested pass managers.
2349 if (!E.InnerPipeline.empty()) {
2350 if (E.Name == "machine-function") {
2352 if (auto Err = parseMachinePassPipeline(NestedPM, E.InnerPipeline))
2353 return Err;
2354 MFPM.addPass(std::move(NestedPM));
2355 return Error::success();
2356 }
2357 return make_error<StringError>("invalid pipeline",
2359 }
2360
2361#define MACHINE_MODULE_PASS(NAME, CREATE_PASS) \
2362 if (Name == NAME) { \
2363 MFPM.addPass(CREATE_PASS); \
2364 return Error::success(); \
2365 }
2366#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
2367 if (Name == NAME) { \
2368 MFPM.addPass(CREATE_PASS); \
2369 return Error::success(); \
2370 }
2371#define MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, \
2372 PARAMS) \
2373 if (checkParametrizedPassName(Name, NAME)) { \
2374 auto Params = parsePassParameters(PARSER, Name, NAME); \
2375 if (!Params) \
2376 return Params.takeError(); \
2377 MFPM.addPass(CREATE_PASS(Params.get())); \
2378 return Error::success(); \
2379 }
2380#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
2381 if (Name == "require<" NAME ">") { \
2382 MFPM.addPass( \
2383 RequireAnalysisPass<std::remove_reference_t<decltype(CREATE_PASS)>, \
2384 MachineFunction>()); \
2385 return Error::success(); \
2386 } \
2387 if (Name == "invalidate<" NAME ">") { \
2388 MFPM.addPass(InvalidateAnalysisPass< \
2389 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2390 return Error::success(); \
2391 }
2392#include "llvm/Passes/MachinePassRegistry.def"
2393
2394 for (auto &C : MachineFunctionPipelineParsingCallbacks)
2395 if (C(Name, MFPM, E.InnerPipeline))
2396 return Error::success();
2398 formatv("unknown machine pass '{}'", Name).str(),
2400}
2401
2402bool PassBuilder::parseAAPassName(AAManager &AA, StringRef Name) {
2403#define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
2404 if (Name == NAME) { \
2405 AA.registerModuleAnalysis< \
2406 std::remove_reference_t<decltype(CREATE_PASS)>>(); \
2407 return true; \
2408 }
2409#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
2410 if (Name == NAME) { \
2411 AA.registerFunctionAnalysis< \
2412 std::remove_reference_t<decltype(CREATE_PASS)>>(); \
2413 return true; \
2414 }
2415#include "PassRegistry.def"
2416
2417 for (auto &C : AAParsingCallbacks)
2418 if (C(Name, AA))
2419 return true;
2420 return false;
2421}
2422
2423Error PassBuilder::parseMachinePassPipeline(
2425 for (const auto &Element : Pipeline) {
2426 if (auto Err = parseMachinePass(MFPM, Element))
2427 return Err;
2428 }
2429 return Error::success();
2430}
2431
2432Error PassBuilder::parseLoopPassPipeline(LoopPassManager &LPM,
2433 ArrayRef<PipelineElement> Pipeline) {
2434 for (const auto &Element : Pipeline) {
2435 if (auto Err = parseLoopPass(LPM, Element))
2436 return Err;
2437 }
2438 return Error::success();
2439}
2440
2441Error PassBuilder::parseFunctionPassPipeline(
2443 for (const auto &Element : Pipeline) {
2444 if (auto Err = parseFunctionPass(FPM, Element))
2445 return Err;
2446 }
2447 return Error::success();
2448}
2449
2450Error PassBuilder::parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
2451 ArrayRef<PipelineElement> Pipeline) {
2452 for (const auto &Element : Pipeline) {
2453 if (auto Err = parseCGSCCPass(CGPM, Element))
2454 return Err;
2455 }
2456 return Error::success();
2457}
2458
2464 MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });
2465 MAM.registerPass([&] { return CGSCCAnalysisManagerModuleProxy(CGAM); });
2466 CGAM.registerPass([&] { return ModuleAnalysisManagerCGSCCProxy(MAM); });
2467 FAM.registerPass([&] { return CGSCCAnalysisManagerFunctionProxy(CGAM); });
2468 FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); });
2469 FAM.registerPass([&] { return LoopAnalysisManagerFunctionProxy(LAM); });
2470 LAM.registerPass([&] { return FunctionAnalysisManagerLoopProxy(FAM); });
2471 if (MFAM) {
2472 MAM.registerPass(
2473 [&] { return MachineFunctionAnalysisManagerModuleProxy(*MFAM); });
2474 FAM.registerPass(
2475 [&] { return MachineFunctionAnalysisManagerFunctionProxy(*MFAM); });
2476 MFAM->registerPass(
2478 MFAM->registerPass(
2480 }
2481}
2482
2483Error PassBuilder::parseModulePassPipeline(ModulePassManager &MPM,
2484 ArrayRef<PipelineElement> Pipeline) {
2485 for (const auto &Element : Pipeline) {
2486 if (auto Err = parseModulePass(MPM, Element))
2487 return Err;
2488 }
2489 return Error::success();
2490}
2491
2492// Primary pass pipeline description parsing routine for a \c ModulePassManager
2493// FIXME: Should this routine accept a TargetMachine or require the caller to
2494// pre-populate the analysis managers with target-specific stuff?
2496 StringRef PipelineText) {
2497 auto Pipeline = parsePipelineText(PipelineText);
2498 if (!Pipeline || Pipeline->empty())
2500 formatv("invalid pipeline '{}'", PipelineText).str(),
2502
2503 // If the first name isn't at the module layer, wrap the pipeline up
2504 // automatically.
2505 StringRef FirstName = Pipeline->front().Name;
2506
2507 if (!isModulePassName(FirstName, ModulePipelineParsingCallbacks)) {
2508 bool UseMemorySSA;
2509 if (isCGSCCPassName(FirstName, CGSCCPipelineParsingCallbacks)) {
2510 Pipeline = {{"cgscc", std::move(*Pipeline)}};
2511 } else if (isFunctionPassName(FirstName,
2512 FunctionPipelineParsingCallbacks)) {
2513 Pipeline = {{"function", std::move(*Pipeline)}};
2514 } else if (isLoopNestPassName(FirstName, LoopPipelineParsingCallbacks,
2515 UseMemorySSA)) {
2516 Pipeline = {{"function", {{UseMemorySSA ? "loop-mssa" : "loop",
2517 std::move(*Pipeline)}}}};
2518 } else if (isLoopPassName(FirstName, LoopPipelineParsingCallbacks,
2519 UseMemorySSA)) {
2520 Pipeline = {{"function", {{UseMemorySSA ? "loop-mssa" : "loop",
2521 std::move(*Pipeline)}}}};
2522 } else if (isMachineFunctionPassName(
2523 FirstName, MachineFunctionPipelineParsingCallbacks)) {
2524 Pipeline = {{"function", {{"machine-function", std::move(*Pipeline)}}}};
2525 } else {
2526 for (auto &C : TopLevelPipelineParsingCallbacks)
2527 if (C(MPM, *Pipeline))
2528 return Error::success();
2529
2530 // Unknown pass or pipeline name!
2531 auto &InnerPipeline = Pipeline->front().InnerPipeline;
2533 formatv("unknown {} name '{}'",
2534 (InnerPipeline.empty() ? "pass" : "pipeline"), FirstName)
2535 .str(),
2537 }
2538 }
2539
2540 if (auto Err = parseModulePassPipeline(MPM, *Pipeline))
2541 return Err;
2542 return Error::success();
2543}
2544
2545// Primary pass pipeline description parsing routine for a \c CGSCCPassManager
2547 StringRef PipelineText) {
2548 auto Pipeline = parsePipelineText(PipelineText);
2549 if (!Pipeline || Pipeline->empty())
2551 formatv("invalid pipeline '{}'", PipelineText).str(),
2553
2554 StringRef FirstName = Pipeline->front().Name;
2555 if (!isCGSCCPassName(FirstName, CGSCCPipelineParsingCallbacks))
2557 formatv("unknown cgscc pass '{}' in pipeline '{}'", FirstName,
2558 PipelineText)
2559 .str(),
2561
2562 if (auto Err = parseCGSCCPassPipeline(CGPM, *Pipeline))
2563 return Err;
2564 return Error::success();
2565}
2566
2567// Primary pass pipeline description parsing routine for a \c
2568// FunctionPassManager
2570 StringRef PipelineText) {
2571 auto Pipeline = parsePipelineText(PipelineText);
2572 if (!Pipeline || Pipeline->empty())
2574 formatv("invalid pipeline '{}'", PipelineText).str(),
2576
2577 StringRef FirstName = Pipeline->front().Name;
2578 if (!isFunctionPassName(FirstName, FunctionPipelineParsingCallbacks))
2580 formatv("unknown function pass '{}' in pipeline '{}'", FirstName,
2581 PipelineText)
2582 .str(),
2584
2585 if (auto Err = parseFunctionPassPipeline(FPM, *Pipeline))
2586 return Err;
2587 return Error::success();
2588}
2589
2590// Primary pass pipeline description parsing routine for a \c LoopPassManager
2592 StringRef PipelineText) {
2593 auto Pipeline = parsePipelineText(PipelineText);
2594 if (!Pipeline || Pipeline->empty())
2596 formatv("invalid pipeline '{}'", PipelineText).str(),
2598
2599 if (auto Err = parseLoopPassPipeline(CGPM, *Pipeline))
2600 return Err;
2601
2602 return Error::success();
2603}
2604
2606 StringRef PipelineText) {
2607 auto Pipeline = parsePipelineText(PipelineText);
2608 if (!Pipeline || Pipeline->empty())
2610 formatv("invalid machine pass pipeline '{}'", PipelineText).str(),
2612
2613 if (auto Err = parseMachinePassPipeline(MFPM, *Pipeline))
2614 return Err;
2615
2616 return Error::success();
2617}
2618
2620 // If the pipeline just consists of the word 'default' just replace the AA
2621 // manager with our default one.
2622 if (PipelineText == "default") {
2624 return Error::success();
2625 }
2626
2627 while (!PipelineText.empty()) {
2628 StringRef Name;
2629 std::tie(Name, PipelineText) = PipelineText.split(',');
2630 if (!parseAAPassName(AA, Name))
2632 formatv("unknown alias analysis name '{}'", Name).str(),
2634 }
2635
2636 return Error::success();
2637}
2638
2639std::optional<RegAllocFilterFunc>
2641 if (FilterName == "all")
2642 return nullptr;
2643 for (auto &C : RegClassFilterParsingCallbacks)
2644 if (auto F = C(FilterName))
2645 return F;
2646 return std::nullopt;
2647}
2648
2650 OS << " " << PassName << "\n";
2651}
2653 raw_ostream &OS) {
2654 OS << " " << PassName << "<" << Params << ">\n";
2655}
2656
2658 // TODO: print pass descriptions when they are available
2659
2660 OS << "Module passes:\n";
2661#define MODULE_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2662#include "PassRegistry.def"
2663
2664 OS << "Module passes with params:\n";
2665#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2666 printPassName(NAME, PARAMS, OS);
2667#include "PassRegistry.def"
2668
2669 OS << "Module analyses:\n";
2670#define MODULE_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2671#include "PassRegistry.def"
2672
2673 OS << "Module alias analyses:\n";
2674#define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2675#include "PassRegistry.def"
2676
2677 OS << "CGSCC passes:\n";
2678#define CGSCC_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2679#include "PassRegistry.def"
2680
2681 OS << "CGSCC passes with params:\n";
2682#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2683 printPassName(NAME, PARAMS, OS);
2684#include "PassRegistry.def"
2685
2686 OS << "CGSCC analyses:\n";
2687#define CGSCC_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2688#include "PassRegistry.def"
2689
2690 OS << "Function passes:\n";
2691#define FUNCTION_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2692#include "PassRegistry.def"
2693
2694 OS << "Function passes with params:\n";
2695#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2696 printPassName(NAME, PARAMS, OS);
2697#include "PassRegistry.def"
2698
2699 OS << "Function analyses:\n";
2700#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2701#include "PassRegistry.def"
2702
2703 OS << "Function alias analyses:\n";
2704#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2705#include "PassRegistry.def"
2706
2707 OS << "LoopNest passes:\n";
2708#define LOOPNEST_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2709#include "PassRegistry.def"
2710
2711 OS << "Loop passes:\n";
2712#define LOOP_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2713#include "PassRegistry.def"
2714
2715 OS << "Loop passes with params:\n";
2716#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2717 printPassName(NAME, PARAMS, OS);
2718#include "PassRegistry.def"
2719
2720 OS << "Loop analyses:\n";
2721#define LOOP_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2722#include "PassRegistry.def"
2723
2724 OS << "Machine module passes (WIP):\n";
2725#define MACHINE_MODULE_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2726#include "llvm/Passes/MachinePassRegistry.def"
2727
2728 OS << "Machine function passes (WIP):\n";
2729#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2730#include "llvm/Passes/MachinePassRegistry.def"
2731
2732 OS << "Machine function analyses (WIP):\n";
2733#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2734#include "llvm/Passes/MachinePassRegistry.def"
2735}
2736
2738 const std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>)>
2739 &C) {
2740 TopLevelPipelineParsingCallbacks.push_back(C);
2741}
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