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