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