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