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