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
33#include "llvm/Analysis/DDG.h"
54#include "llvm/Analysis/Lint.h"
115#include "llvm/CodeGen/KCFI.h"
150#include "llvm/CodeGen/PEI.h"
193#include "llvm/IR/DebugInfo.h"
194#include "llvm/IR/Dominators.h"
195#include "llvm/IR/PassManager.h"
197#include "llvm/IR/Verifier.h"
200#include "llvm/Support/CodeGen.h"
202#include "llvm/Support/Debug.h"
203#include "llvm/Support/Error.h"
207#include "llvm/Support/Regex.h"
401#include <optional>
402
403using namespace llvm;
404
408 "print-pipeline-passes", cl::ValueOptional,
409 cl::desc(
410 "Print string describing the pipeline (best-effort only).\n"
411 " - =text\tPrint a '-passes' compatible string describing the "
412 "pipeline.\n"
413 " - =tree\tPrint a tree-like structure describing the pipeline."));
414
416 cl::Option &O, StringRef ArgName, StringRef Arg,
417 std::optional<PrintPipelinePassesFormat> &Val) {
418 std::optional<PrintPipelinePassesFormat> Format =
423 .Default(std::nullopt);
424
425 if (!Format)
426 return O.error(formatv(
427 "'{0}' value invalid for print-pipeline-passes argument!", Arg));
428
429 Val = Format;
430 return false;
431}
432
435 switch (Format) {
437 OS << Pipeline;
438 break;
440 int IndentLevel = 0;
441 for (char C : Pipeline) {
442 switch (C) {
443 case '(':
444 ++IndentLevel;
445 OS << formatv("\n{0}", fmt_repeat(" ", IndentLevel));
446 break;
447 case ')':
448 --IndentLevel;
449 assert(IndentLevel >= 0 && "Invalid pipeline string!");
450 break;
451 case ',':
452 OS << formatv("\n{0}", fmt_repeat(" ", IndentLevel));
453 break;
454 default:
455 OS << C;
456 }
457 }
458 break;
459 }
460 }
461}
462
463AnalysisKey NoOpModuleAnalysis::Key;
464AnalysisKey NoOpCGSCCAnalysis::Key;
465AnalysisKey NoOpFunctionAnalysis::Key;
466AnalysisKey NoOpLoopAnalysis::Key;
467
468namespace {
469
470bool applyMIRDebugify(DIBuilder &DIB, Function &F, ModuleAnalysisManager &AM) {
473 .getManager();
474
476 DIB, F, [&](Function &Func) -> MachineFunction * {
478 FAM.getCachedResult<MachineFunctionAnalysis>(Func);
479 return MFA ? &MFA->getMF() : nullptr;
480 });
481}
482
483// A pass for testing message reporting of -verify-each failures.
484// DO NOT USE THIS EXCEPT FOR TESTING!
485class TriggerVerifierErrorPass
486 : public OptionalPassInfoMixin<TriggerVerifierErrorPass> {
487public:
488 PreservedAnalyses run(Module &M, ModuleAnalysisManager &) {
489 // Intentionally break the Module by creating an alias without setting the
490 // aliasee.
491 auto *PtrTy = PointerType::getUnqual(M.getContext());
492 GlobalAlias::create(PtrTy, PtrTy->getAddressSpace(),
493 GlobalValue::LinkageTypes::InternalLinkage,
494 "__bad_alias", nullptr, &M);
496 }
497
498 PreservedAnalyses run(Function &F, FunctionAnalysisManager &) {
499 // Intentionally break the Function by inserting a terminator
500 // instruction in the middle of a basic block.
501 BasicBlock &BB = F.getEntryBlock();
502 new UnreachableInst(F.getContext(), BB.getTerminator()->getIterator());
504 }
505
506 PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &) {
507 // Intentionally create a virtual register and set NoVRegs property.
508 auto &MRI = MF.getRegInfo();
510 MF.getProperties().setNoVRegs();
511 return PreservedAnalyses::all();
512 }
513
514 static StringRef name() { return "TriggerVerifierErrorPass"; }
515};
516
517// A pass requires all MachineFunctionProperties.
518// DO NOT USE THIS EXCEPT FOR TESTING!
519class RequireAllMachineFunctionPropertiesPass
520 : public OptionalPassInfoMixin<RequireAllMachineFunctionPropertiesPass> {
521public:
522 PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &) {
523 MFPropsModifier _(*this, MF);
525 }
526
527 static MachineFunctionProperties getRequiredProperties() {
528 return MachineFunctionProperties()
529 .setFailedISel()
530 .setFailsVerification()
531 .setIsSSA()
532 .setLegalized()
533 .setNoPHIs()
534 .setNoVRegs()
535 .setRegBankSelected()
536 .setSelected()
537 .setTiedOpsRewritten()
538 .setTracksDebugUserValues()
539 .setTracksLiveness();
540 }
541 static StringRef name() { return "RequireAllMachineFunctionPropertiesPass"; }
542};
543
544} // namespace
545
546static std::optional<OptimizationLevel> parseOptLevel(StringRef S) {
547 if (S == "Os" || S == "Oz")
549 Twine("The optimization level \"") + S +
550 "\" is no longer supported. Use O2 in conjunction with the " +
551 (S == "Os" ? "optsize" : "minsize") + " attribute instead.");
552
554 .Case("O0", OptimizationLevel::O0)
558 .Default(std::nullopt);
559}
560
562 std::optional<OptimizationLevel> OptLevel = parseOptLevel(S);
563 if (OptLevel)
564 return *OptLevel;
566 formatv("invalid optimization level '{}'", S).str(),
568}
569
571 std::optional<PGOOptions> PGOOpt,
574 : TM(TM), PTO(PTO), PGOOpt(PGOOpt), PIC(PIC), FS(std::move(FS)) {
575 if (TM)
576 TM->registerPassBuilderCallbacks(*this);
577 if (PIC) {
578 PIC->registerClassToPassNameCallback([this, PIC]() {
579 // MSVC requires this to be captured if it's used inside decltype.
580 // Other compilers consider it an unused lambda capture.
581 (void)this;
582#define MODULE_PASS(NAME, CREATE_PASS) \
583 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
584#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
585 PIC->addClassToPassName(CLASS, NAME);
586#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
587 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
588#define FUNCTION_PASS(NAME, CREATE_PASS) \
589 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
590#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
591 PIC->addClassToPassName(CLASS, NAME);
592#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
593 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
594#define LOOPNEST_PASS(NAME, CREATE_PASS) \
595 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
596#define LOOP_PASS(NAME, CREATE_PASS) \
597 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
598#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
599 PIC->addClassToPassName(CLASS, NAME);
600#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
601 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
602#define CGSCC_PASS(NAME, CREATE_PASS) \
603 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
604#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
605 PIC->addClassToPassName(CLASS, NAME);
606#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
607 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
608#include "PassRegistry.def"
609
610#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
611 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
612#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
613 PIC->addClassToPassName(decltype(CREATE_PASS)::name(), NAME);
614#define MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, \
615 PARAMS) \
616 PIC->addClassToPassName(CLASS, NAME);
617#include "llvm/Passes/MachinePassRegistry.def"
618 });
619 }
620
621 // Module-level callbacks without LTO phase
623 [this](StringRef Name, ModulePassManager &PM,
625#define MODULE_CALLBACK(NAME, INVOKE) \
626 if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
627 auto L = PassBuilder::parsePassParameters(parseOptLevelParam, Name, NAME); \
628 if (!L) { \
629 errs() << NAME ": " << toString(L.takeError()) << '\n'; \
630 return false; \
631 } \
632 INVOKE(PM, L.get()); \
633 return true; \
634 }
635#include "PassRegistry.def"
636 return false;
637 });
638
639 // Module-level callbacks with LTO phase (use Phase::None for string API)
641 [this](StringRef Name, ModulePassManager &PM,
643#define MODULE_LTO_CALLBACK(NAME, INVOKE) \
644 if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
645 auto L = PassBuilder::parsePassParameters(parseOptLevelParam, Name, NAME); \
646 if (!L) { \
647 errs() << NAME ": " << toString(L.takeError()) << '\n'; \
648 return false; \
649 } \
650 INVOKE(PM, L.get(), ThinOrFullLTOPhase::None); \
651 return true; \
652 }
653#include "PassRegistry.def"
654 return false;
655 });
656
657 // Function-level callbacks
659 [this](StringRef Name, FunctionPassManager &PM,
661#define FUNCTION_CALLBACK(NAME, INVOKE) \
662 if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
663 auto L = PassBuilder::parsePassParameters(parseOptLevelParam, Name, NAME); \
664 if (!L) { \
665 errs() << NAME ": " << toString(L.takeError()) << '\n'; \
666 return false; \
667 } \
668 INVOKE(PM, L.get()); \
669 return true; \
670 }
671#include "PassRegistry.def"
672 return false;
673 });
674
675 // CGSCC-level callbacks
677 [this](StringRef Name, CGSCCPassManager &PM,
679#define CGSCC_CALLBACK(NAME, INVOKE) \
680 if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
681 auto L = PassBuilder::parsePassParameters(parseOptLevelParam, Name, NAME); \
682 if (!L) { \
683 errs() << NAME ": " << toString(L.takeError()) << '\n'; \
684 return false; \
685 } \
686 INVOKE(PM, L.get()); \
687 return true; \
688 }
689#include "PassRegistry.def"
690 return false;
691 });
692
693 // Loop-level callbacks
695 [this](StringRef Name, LoopPassManager &PM,
697#define LOOP_CALLBACK(NAME, INVOKE) \
698 if (PassBuilder::checkParametrizedPassName(Name, NAME)) { \
699 auto L = PassBuilder::parsePassParameters(parseOptLevelParam, Name, NAME); \
700 if (!L) { \
701 errs() << NAME ": " << toString(L.takeError()) << '\n'; \
702 return false; \
703 } \
704 INVOKE(PM, L.get()); \
705 return true; \
706 }
707#include "PassRegistry.def"
708 return false;
709 });
710}
711
713#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
714 MAM.registerPass([&] { return CREATE_PASS; });
715#include "PassRegistry.def"
716
717 for (auto &C : ModuleAnalysisRegistrationCallbacks)
718 C(MAM);
719}
720
722#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
723 CGAM.registerPass([&] { return CREATE_PASS; });
724#include "PassRegistry.def"
725
726 for (auto &C : CGSCCAnalysisRegistrationCallbacks)
727 C(CGAM);
728}
729
731 // We almost always want the default alias analysis pipeline.
732 // If a user wants a different one, they can register their own before calling
733 // registerFunctionAnalyses().
734 FAM.registerPass([&] { return buildDefaultAAPipeline(); });
735
736#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
737 if constexpr (std::is_constructible_v< \
738 std::remove_reference_t<decltype(CREATE_PASS)>, \
739 const TargetMachine &>) { \
740 if (TM) \
741 FAM.registerPass([&] { return CREATE_PASS; }); \
742 } else { \
743 FAM.registerPass([&] { return CREATE_PASS; }); \
744 }
745#include "PassRegistry.def"
746
747 for (auto &C : FunctionAnalysisRegistrationCallbacks)
748 C(FAM);
749}
750
753
754#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
755 MFAM.registerPass([&] { return CREATE_PASS; });
756#include "llvm/Passes/MachinePassRegistry.def"
757
758 for (auto &C : MachineFunctionAnalysisRegistrationCallbacks)
759 C(MFAM);
760}
761
763#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
764 LAM.registerPass([&] { return CREATE_PASS; });
765#include "PassRegistry.def"
766
767 for (auto &C : LoopAnalysisRegistrationCallbacks)
768 C(LAM);
769}
770
771static std::optional<std::pair<bool, bool>>
773 std::pair<bool, bool> Params;
774 if (!Name.consume_front("function"))
775 return std::nullopt;
776 if (Name.empty())
777 return Params;
778 if (!Name.consume_front("<") || !Name.consume_back(">"))
779 return std::nullopt;
780 while (!Name.empty()) {
781 auto [Front, Back] = Name.split(';');
782 Name = Back;
783 if (Front == "eager-inv")
784 Params.first = true;
785 else if (Front == "no-rerun")
786 Params.second = true;
787 else
788 return std::nullopt;
789 }
790 return Params;
791}
792
793static std::optional<int> parseDevirtPassName(StringRef Name) {
794 if (!Name.consume_front("devirt<") || !Name.consume_back(">"))
795 return std::nullopt;
796 int Count;
797 if (Name.getAsInteger(0, Count) || Count < 0)
798 return std::nullopt;
799 return Count;
800}
801
803 StringRef OptionName,
805 bool Result = false;
806 while (!Params.empty()) {
807 StringRef ParamName;
808 std::tie(ParamName, Params) = Params.split(';');
809
810 if (ParamName == OptionName) {
811 Result = true;
812 } else {
814 formatv("invalid {} pass parameter '{}'", PassName, ParamName).str(),
816 }
817 }
818 return Result;
819}
820
821namespace {
822
823/// Parser of parameters for HardwareLoops pass.
824Expected<HardwareLoopOptions> parseHardwareLoopOptions(StringRef Params) {
825 HardwareLoopOptions HardwareLoopOpts;
826
827 while (!Params.empty()) {
828 StringRef ParamName;
829 std::tie(ParamName, Params) = Params.split(';');
830 if (ParamName.consume_front("hardware-loop-decrement=")) {
831 int Count;
832 if (ParamName.getAsInteger(0, Count))
834 formatv("invalid HardwareLoopPass parameter '{}'", ParamName).str(),
836 HardwareLoopOpts.setDecrement(Count);
837 continue;
838 }
839 if (ParamName.consume_front("hardware-loop-counter-bitwidth=")) {
840 int Count;
841 if (ParamName.getAsInteger(0, Count))
843 formatv("invalid HardwareLoopPass parameter '{}'", ParamName).str(),
845 HardwareLoopOpts.setCounterBitwidth(Count);
846 continue;
847 }
848 if (ParamName == "force-hardware-loops") {
849 HardwareLoopOpts.setForce(true);
850 } else if (ParamName == "force-hardware-loop-phi") {
851 HardwareLoopOpts.setForcePhi(true);
852 } else if (ParamName == "force-nested-hardware-loop") {
853 HardwareLoopOpts.setForceNested(true);
854 } else if (ParamName == "force-hardware-loop-guard") {
855 HardwareLoopOpts.setForceGuard(true);
856 } else {
858 formatv("invalid HardwarePass parameter '{}'", ParamName).str(),
860 }
861 }
862 return HardwareLoopOpts;
863}
864
865/// Parser of parameters for Lint pass.
866Expected<bool> parseLintOptions(StringRef Params) {
867 return PassBuilder::parseSinglePassOption(Params, "abort-on-error",
868 "LintPass");
869}
870
871/// Parser of parameters for FunctionPropertiesStatistics pass.
872Expected<bool> parseFunctionPropertiesStatisticsOptions(StringRef Params) {
873 return PassBuilder::parseSinglePassOption(Params, "pre-opt",
874 "FunctionPropertiesStatisticsPass");
875}
876
877/// Parser of parameters for InstCount pass.
878Expected<bool> parseInstCountOptions(StringRef Params) {
879 return PassBuilder::parseSinglePassOption(Params, "pre-opt", "InstCountPass");
880}
881
882/// Parser of parameters for LoopUnroll pass.
883Expected<LoopUnrollOptions> parseLoopUnrollOptions(StringRef Params) {
884 LoopUnrollOptions UnrollOpts;
885 while (!Params.empty()) {
886 StringRef ParamName;
887 std::tie(ParamName, Params) = Params.split(';');
888 std::optional<OptimizationLevel> OptLevel = parseOptLevel(ParamName);
889 if (OptLevel) {
890 UnrollOpts.setOptLevel(OptLevel->getSpeedupLevel());
891 continue;
892 }
893 if (ParamName.consume_front("full-unroll-max=")) {
894 int Count;
895 if (ParamName.getAsInteger(0, Count))
897 formatv("invalid LoopUnrollPass parameter '{}'", ParamName).str(),
899 UnrollOpts.setFullUnrollMaxCount(Count);
900 continue;
901 }
902
903 bool Enable = !ParamName.consume_front("no-");
904 if (ParamName == "partial") {
905 UnrollOpts.setPartial(Enable);
906 } else if (ParamName == "peeling") {
907 UnrollOpts.setPeeling(Enable);
908 } else if (ParamName == "profile-peeling") {
909 UnrollOpts.setProfileBasedPeeling(Enable);
910 } else if (ParamName == "runtime") {
911 UnrollOpts.setRuntime(Enable);
912 } else if (ParamName == "upperbound") {
913 UnrollOpts.setUpperBound(Enable);
914 } else {
916 formatv("invalid LoopUnrollPass parameter '{}'", ParamName).str(),
918 }
919 }
920 return UnrollOpts;
921}
922
923Expected<bool> parseGlobalDCEPassOptions(StringRef Params) {
925 Params, "vfe-linkage-unit-visibility", "GlobalDCE");
926}
927
928Expected<bool> parseCGProfilePassOptions(StringRef Params) {
929 return PassBuilder::parseSinglePassOption(Params, "in-lto-post-link",
930 "CGProfile");
931}
932
933Expected<bool> parseInlinerPassOptions(StringRef Params) {
934 return PassBuilder::parseSinglePassOption(Params, "only-mandatory",
935 "InlinerPass");
936}
937
938Expected<bool> parseCoroSplitPassOptions(StringRef Params) {
939 return PassBuilder::parseSinglePassOption(Params, "reuse-storage",
940 "CoroSplitPass");
941}
942
943Expected<bool> parsePostOrderFunctionAttrsPassOptions(StringRef Params) {
945 Params, "skip-non-recursive-function-attrs", "PostOrderFunctionAttrs");
946}
947
948Expected<bool> parseEarlyCSEPassOptions(StringRef Params) {
949 return PassBuilder::parseSinglePassOption(Params, "memssa", "EarlyCSE");
950}
951
952Expected<bool> parseEntryExitInstrumenterPassOptions(StringRef Params) {
953 return PassBuilder::parseSinglePassOption(Params, "post-inline",
954 "EntryExitInstrumenter");
955}
956
957Expected<bool> parseDropUnnecessaryAssumesPassOptions(StringRef Params) {
958 return PassBuilder::parseSinglePassOption(Params, "drop-deref",
959 "DropUnnecessaryAssumes");
960}
961
962Expected<bool> parseLoopExtractorPassOptions(StringRef Params) {
963 return PassBuilder::parseSinglePassOption(Params, "single", "LoopExtractor");
964}
965
966Expected<bool> parseLowerMatrixIntrinsicsPassOptions(StringRef Params) {
967 return PassBuilder::parseSinglePassOption(Params, "minimal",
968 "LowerMatrixIntrinsics");
969}
970
971Expected<IRNormalizerOptions> parseIRNormalizerPassOptions(StringRef Params) {
973 while (!Params.empty()) {
974 StringRef ParamName;
975 std::tie(ParamName, Params) = Params.split(';');
976
977 bool Enable = !ParamName.consume_front("no-");
978 if (ParamName == "preserve-order")
979 Result.PreserveOrder = Enable;
980 else if (ParamName == "rename-all")
981 Result.RenameAll = Enable;
982 else if (ParamName == "fold-all") // FIXME: Name mismatch
983 Result.FoldPreOutputs = Enable;
984 else if (ParamName == "reorder-operands")
985 Result.ReorderOperands = Enable;
986 else {
988 formatv("invalid normalize pass parameter '{}'", ParamName).str(),
990 }
991 }
992
993 return Result;
994}
995
996Expected<AddressSanitizerOptions> parseASanPassOptions(StringRef Params) {
998 while (!Params.empty()) {
999 StringRef ParamName;
1000 std::tie(ParamName, Params) = Params.split(';');
1001
1002 if (ParamName == "kernel") {
1003 Result.CompileKernel = true;
1004 } else if (ParamName == "use-after-scope") {
1005 Result.UseAfterScope = true;
1006 } else {
1008 formatv("invalid AddressSanitizer pass parameter '{}'", ParamName)
1009 .str(),
1011 }
1012 }
1013 return Result;
1014}
1015
1016Expected<HWAddressSanitizerOptions> parseHWASanPassOptions(StringRef Params) {
1018 while (!Params.empty()) {
1019 StringRef ParamName;
1020 std::tie(ParamName, Params) = Params.split(';');
1021
1022 if (ParamName == "recover") {
1023 Result.Recover = true;
1024 } else if (ParamName == "kernel") {
1025 Result.CompileKernel = true;
1026 } else {
1028 formatv("invalid HWAddressSanitizer pass parameter '{}'", ParamName)
1029 .str(),
1031 }
1032 }
1033 return Result;
1034}
1035
1037parseDropTypeTestsPassOptions(StringRef Params) {
1039 while (!Params.empty()) {
1040 StringRef ParamName;
1041 std::tie(ParamName, Params) = Params.split(';');
1042
1043 if (ParamName == "all") {
1045 } else if (ParamName == "assume") {
1047 } else {
1049 formatv("invalid DropTypeTestsPass parameter '{}'", ParamName).str(),
1051 }
1052 }
1053 return Result;
1054}
1055
1056Expected<EmbedBitcodeOptions> parseEmbedBitcodePassOptions(StringRef Params) {
1058 while (!Params.empty()) {
1059 StringRef ParamName;
1060 std::tie(ParamName, Params) = Params.split(';');
1061
1062 if (ParamName == "thinlto") {
1063 Result.IsThinLTO = true;
1064 } else if (ParamName == "emit-summary") {
1065 Result.EmitLTOSummary = true;
1066 } else {
1068 formatv("invalid EmbedBitcode pass parameter '{}'", ParamName).str(),
1070 }
1071 }
1072 return Result;
1073}
1074
1076parseLowerAllowCheckPassOptions(StringRef Params) {
1078 while (!Params.empty()) {
1079 StringRef ParamName;
1080 std::tie(ParamName, Params) = Params.split(';');
1081
1082 // Format is <cutoffs[1,2,3]=70000;cutoffs[5,6,8]=90000>
1083 //
1084 // Parsing allows duplicate indices (last one takes precedence).
1085 // It would technically be in spec to specify
1086 // cutoffs[0]=70000,cutoffs[1]=90000,cutoffs[0]=80000,...
1087 if (ParamName.starts_with("cutoffs[")) {
1088 StringRef IndicesStr;
1089 StringRef CutoffStr;
1090
1091 std::tie(IndicesStr, CutoffStr) = ParamName.split("]=");
1092 // cutoffs[1,2,3
1093 // 70000
1094
1095 int cutoff;
1096 if (CutoffStr.getAsInteger(0, cutoff))
1098 formatv("invalid LowerAllowCheck pass cutoffs parameter '{}' ({})",
1099 CutoffStr, Params)
1100 .str(),
1102
1103 if (!IndicesStr.consume_front("cutoffs[") || IndicesStr == "")
1105 formatv("invalid LowerAllowCheck pass index parameter '{}' ({})",
1106 IndicesStr, CutoffStr)
1107 .str(),
1109
1110 while (IndicesStr != "") {
1111 StringRef firstIndexStr;
1112 std::tie(firstIndexStr, IndicesStr) = IndicesStr.split('|');
1113
1114 unsigned int index;
1115 if (firstIndexStr.getAsInteger(0, index))
1117 formatv(
1118 "invalid LowerAllowCheck pass index parameter '{}' ({}) {}",
1119 firstIndexStr, IndicesStr)
1120 .str(),
1122
1123 // In the common case (sequentially increasing indices), we will issue
1124 // O(n) resize requests. We assume the underlying data structure has
1125 // O(1) runtime for each added element.
1126 if (index >= Result.cutoffs.size())
1127 Result.cutoffs.resize(index + 1, 0);
1128
1129 Result.cutoffs[index] = cutoff;
1130 }
1131 } else if (ParamName.starts_with("runtime_check")) {
1132 StringRef ValueString;
1133 std::tie(std::ignore, ValueString) = ParamName.split("=");
1134 int runtime_check;
1135 if (ValueString.getAsInteger(0, runtime_check)) {
1137 formatv("invalid LowerAllowCheck pass runtime_check parameter '{}' "
1138 "({})",
1139 ValueString, Params)
1140 .str(),
1142 }
1143 Result.runtime_check = runtime_check;
1144 } else {
1146 formatv("invalid LowerAllowCheck pass parameter '{}'", ParamName)
1147 .str(),
1149 }
1150 }
1151
1152 return Result;
1153}
1154
1155Expected<MemorySanitizerOptions> parseMSanPassOptions(StringRef Params) {
1157 while (!Params.empty()) {
1158 StringRef ParamName;
1159 std::tie(ParamName, Params) = Params.split(';');
1160
1161 if (ParamName == "recover") {
1162 Result.Recover = true;
1163 } else if (ParamName == "kernel") {
1164 Result.Kernel = true;
1165 } else if (ParamName.consume_front("track-origins=")) {
1166 if (ParamName.getAsInteger(0, Result.TrackOrigins))
1168 formatv("invalid argument to MemorySanitizer pass track-origins "
1169 "parameter: '{}'",
1170 ParamName)
1171 .str(),
1173 } else if (ParamName == "eager-checks") {
1174 Result.EagerChecks = true;
1175 } else {
1177 formatv("invalid MemorySanitizer pass parameter '{}'", ParamName)
1178 .str(),
1180 }
1181 }
1182 return Result;
1183}
1184
1185Expected<AllocTokenOptions> parseAllocTokenPassOptions(StringRef Params) {
1187 while (!Params.empty()) {
1188 StringRef ParamName;
1189 std::tie(ParamName, Params) = Params.split(';');
1190
1191 if (ParamName.consume_front("mode=")) {
1192 if (auto Mode = getAllocTokenModeFromString(ParamName))
1193 Result.Mode = *Mode;
1194 else
1196 formatv("invalid argument to AllocToken pass mode "
1197 "parameter: '{}'",
1198 ParamName)
1199 .str(),
1201 } else {
1203 formatv("invalid AllocToken pass parameter '{}'", ParamName).str(),
1205 }
1206 }
1207 return Result;
1208}
1209
1210/// Parser of parameters for SimplifyCFG pass.
1211Expected<SimplifyCFGOptions> parseSimplifyCFGOptions(StringRef Params) {
1213 while (!Params.empty()) {
1214 StringRef ParamName;
1215 std::tie(ParamName, Params) = Params.split(';');
1216
1217 bool Enable = !ParamName.consume_front("no-");
1218 if (ParamName == "speculate-blocks") {
1219 Result.speculateBlocks(Enable);
1220 } else if (ParamName == "simplify-cond-branch") {
1221 Result.setSimplifyCondBranch(Enable);
1222 } else if (ParamName == "forward-switch-cond") {
1223 Result.forwardSwitchCondToPhi(Enable);
1224 } else if (ParamName == "switch-range-to-icmp") {
1225 Result.convertSwitchRangeToICmp(Enable);
1226 } else if (ParamName == "switch-to-arithmetic") {
1227 Result.convertSwitchToArithmetic(Enable);
1228 } else if (ParamName == "switch-to-lookup") {
1229 Result.convertSwitchToLookupTable(Enable);
1230 } else if (ParamName == "keep-loops") {
1231 Result.needCanonicalLoops(Enable);
1232 } else if (ParamName == "hoist-common-insts") {
1233 Result.hoistCommonInsts(Enable);
1234 } else if (ParamName == "hoist-loads-stores-with-cond-faulting") {
1235 Result.hoistLoadsStoresWithCondFaulting(Enable);
1236 } else if (ParamName == "sink-common-insts") {
1237 Result.sinkCommonInsts(Enable);
1238 } else if (ParamName == "speculate-unpredictables") {
1239 Result.speculateUnpredictables(Enable);
1240 } else if (Enable && ParamName.consume_front("bonus-inst-threshold=")) {
1241 APInt BonusInstThreshold;
1242 if (ParamName.getAsInteger(0, BonusInstThreshold))
1244 formatv("invalid argument to SimplifyCFG pass bonus-threshold "
1245 "parameter: '{}'",
1246 ParamName)
1247 .str(),
1249 Result.bonusInstThreshold(BonusInstThreshold.getSExtValue());
1250 } else {
1252 formatv("invalid SimplifyCFG pass parameter '{}'", ParamName).str(),
1254 }
1255 }
1256 return Result;
1257}
1258
1259Expected<InstCombineOptions> parseInstCombineOptions(StringRef Params) {
1261 // When specifying "instcombine" in -passes enable fix-point verification by
1262 // default, as this is what most tests should use.
1263 Result.setVerifyFixpoint(true);
1264 while (!Params.empty()) {
1265 StringRef ParamName;
1266 std::tie(ParamName, Params) = Params.split(';');
1267
1268 bool Enable = !ParamName.consume_front("no-");
1269 if (ParamName == "verify-fixpoint") {
1270 Result.setVerifyFixpoint(Enable);
1271 } else if (Enable && ParamName.consume_front("max-iterations=")) {
1272 APInt MaxIterations;
1273 if (ParamName.getAsInteger(0, MaxIterations))
1275 formatv("invalid argument to InstCombine pass max-iterations "
1276 "parameter: '{}'",
1277 ParamName)
1278 .str(),
1280 Result.setMaxIterations((unsigned)MaxIterations.getZExtValue());
1281 } else {
1283 formatv("invalid InstCombine pass parameter '{}'", ParamName).str(),
1285 }
1286 }
1287 return Result;
1288}
1289
1290/// Parser of parameters for LoopVectorize pass.
1291Expected<LoopVectorizeOptions> parseLoopVectorizeOptions(StringRef Params) {
1293 while (!Params.empty()) {
1294 StringRef ParamName;
1295 std::tie(ParamName, Params) = Params.split(';');
1296
1297 bool Enable = !ParamName.consume_front("no-");
1298 if (ParamName == "interleave-forced-only") {
1300 } else if (ParamName == "vectorize-forced-only") {
1302 } else {
1304 formatv("invalid LoopVectorize parameter '{}'", ParamName).str(),
1306 }
1307 }
1308 return Opts;
1309}
1310
1311Expected<std::pair<bool, bool>> parseLoopUnswitchOptions(StringRef Params) {
1312 std::pair<bool, bool> Result = {false, true};
1313 while (!Params.empty()) {
1314 StringRef ParamName;
1315 std::tie(ParamName, Params) = Params.split(';');
1316
1317 bool Enable = !ParamName.consume_front("no-");
1318 if (ParamName == "nontrivial") {
1319 Result.first = Enable;
1320 } else if (ParamName == "trivial") {
1321 Result.second = Enable;
1322 } else {
1324 formatv("invalid LoopUnswitch pass parameter '{}'", ParamName).str(),
1326 }
1327 }
1328 return Result;
1329}
1330
1331Expected<LICMOptions> parseLICMOptions(StringRef Params) {
1333 while (!Params.empty()) {
1334 StringRef ParamName;
1335 std::tie(ParamName, Params) = Params.split(';');
1336
1337 bool Enable = !ParamName.consume_front("no-");
1338 if (ParamName == "allowspeculation") {
1339 Result.AllowSpeculation = Enable;
1340 } else {
1342 formatv("invalid LICM pass parameter '{}'", ParamName).str(),
1344 }
1345 }
1346 return Result;
1347}
1348
1349struct LoopRotateOptions {
1350 bool EnableHeaderDuplication = true;
1351 bool PrepareForLTO = false;
1352 bool CheckExitCount = false;
1353};
1354
1355Expected<LoopRotateOptions> parseLoopRotateOptions(StringRef Params) {
1356 LoopRotateOptions Result;
1357 while (!Params.empty()) {
1358 StringRef ParamName;
1359 std::tie(ParamName, Params) = Params.split(';');
1360
1361 bool Enable = !ParamName.consume_front("no-");
1362 if (ParamName == "header-duplication") {
1363 Result.EnableHeaderDuplication = Enable;
1364 } else if (ParamName == "prepare-for-lto") {
1365 Result.PrepareForLTO = Enable;
1366 } else if (ParamName == "check-exit-count") {
1367 Result.CheckExitCount = Enable;
1368 } else {
1370 formatv("invalid LoopRotate pass parameter '{}'", ParamName).str(),
1372 }
1373 }
1374 return Result;
1375}
1376
1377Expected<bool> parseMergedLoadStoreMotionOptions(StringRef Params) {
1378 bool Result = false;
1379 while (!Params.empty()) {
1380 StringRef ParamName;
1381 std::tie(ParamName, Params) = Params.split(';');
1382
1383 bool Enable = !ParamName.consume_front("no-");
1384 if (ParamName == "split-footer-bb") {
1385 Result = Enable;
1386 } else {
1388 formatv("invalid MergedLoadStoreMotion pass parameter '{}'",
1389 ParamName)
1390 .str(),
1392 }
1393 }
1394 return Result;
1395}
1396
1397Expected<GVNOptions> parseGVNOptions(StringRef Params) {
1399 while (!Params.empty()) {
1400 StringRef ParamName;
1401 std::tie(ParamName, Params) = Params.split(';');
1402
1403 bool Enable = !ParamName.consume_front("no-");
1404 if (ParamName == "scalar-pre") {
1405 Result.setScalarPRE(Enable);
1406 } else if (ParamName == "load-pre") {
1407 Result.setLoadPRE(Enable);
1408 } else if (ParamName == "split-backedge-load-pre") {
1409 Result.setLoadPRESplitBackedge(Enable);
1410 } else if (ParamName == "memdep") {
1411 // MemDep and MemorySSA are mutually exclusive.
1412 Result.setMemDep(Enable);
1413 Result.setMemorySSA(!Enable);
1414 } else if (ParamName == "memoryssa") {
1415 // MemDep and MemorySSA are mutually exclusive.
1416 Result.setMemorySSA(Enable);
1417 Result.setMemDep(!Enable);
1418 } else {
1420 formatv("invalid GVN pass parameter '{}'", ParamName).str(),
1422 }
1423 }
1424 return Result;
1425}
1426
1427Expected<IPSCCPOptions> parseIPSCCPOptions(StringRef Params) {
1429 while (!Params.empty()) {
1430 StringRef ParamName;
1431 std::tie(ParamName, Params) = Params.split(';');
1432
1433 bool Enable = !ParamName.consume_front("no-");
1434 if (ParamName == "func-spec")
1435 Result.setFuncSpec(Enable);
1436 else
1438 formatv("invalid IPSCCP pass parameter '{}'", ParamName).str(),
1440 }
1441 return Result;
1442}
1443
1444Expected<ScalarizerPassOptions> parseScalarizerOptions(StringRef Params) {
1446 while (!Params.empty()) {
1447 StringRef ParamName;
1448 std::tie(ParamName, Params) = Params.split(';');
1449
1450 if (ParamName.consume_front("min-bits=")) {
1451 if (ParamName.getAsInteger(0, Result.ScalarizeMinBits)) {
1453 formatv("invalid argument to Scalarizer pass min-bits "
1454 "parameter: '{}'",
1455 ParamName)
1456 .str(),
1458 }
1459
1460 continue;
1461 }
1462
1463 bool Enable = !ParamName.consume_front("no-");
1464 if (ParamName == "load-store")
1465 Result.ScalarizeLoadStore = Enable;
1466 else if (ParamName == "variable-insert-extract")
1467 Result.ScalarizeVariableInsertExtract = Enable;
1468 else {
1470 formatv("invalid Scalarizer pass parameter '{}'", ParamName).str(),
1472 }
1473 }
1474
1475 return Result;
1476}
1477
1478Expected<SROAOptions> parseSROAOptions(StringRef Params) {
1480 bool SawCFGOption = false;
1481 while (!Params.empty()) {
1482 StringRef ParamName;
1483 std::tie(ParamName, Params) = Params.split(';');
1484
1485 if (ParamName == "modify-cfg") {
1486 if (SawCFGOption)
1487 return make_error<StringError>("multiple SROA CFG options specified",
1490 SawCFGOption = true;
1491 } else if (ParamName == "preserve-cfg") {
1492 if (SawCFGOption)
1493 return make_error<StringError>("multiple SROA CFG options specified",
1496 SawCFGOption = true;
1497 } else if (ParamName == "aggregate-to-vector") {
1498 Result.AggregateToVector = true;
1499 } else {
1501 formatv("invalid SROA pass parameter '{}' (expected preserve-cfg, "
1502 "modify-cfg, or aggregate-to-vector)",
1503 ParamName)
1504 .str(),
1506 }
1507 }
1508 return Result;
1509}
1510
1512parseStackLifetimeOptions(StringRef Params) {
1514 while (!Params.empty()) {
1515 StringRef ParamName;
1516 std::tie(ParamName, Params) = Params.split(';');
1517
1518 if (ParamName == "may") {
1520 } else if (ParamName == "must") {
1522 } else {
1524 formatv("invalid StackLifetime parameter '{}'", ParamName).str(),
1526 }
1527 }
1528 return Result;
1529}
1530
1531Expected<bool> parseDependenceAnalysisPrinterOptions(StringRef Params) {
1532 return PassBuilder::parseSinglePassOption(Params, "normalized-results",
1533 "DependenceAnalysisPrinter");
1534}
1535
1536Expected<bool> parseSeparateConstOffsetFromGEPPassOptions(StringRef Params) {
1537 return PassBuilder::parseSinglePassOption(Params, "lower-gep",
1538 "SeparateConstOffsetFromGEP");
1539}
1540
1541Expected<bool> parseStructurizeCFGPassOptions(StringRef Params) {
1542 return PassBuilder::parseSinglePassOption(Params, "skip-uniform-regions",
1543 "StructurizeCFG");
1544}
1545
1547parseFunctionSimplificationPipelineOptions(StringRef Params) {
1548 std::optional<OptimizationLevel> L = parseOptLevel(Params);
1549 if (!L || *L == OptimizationLevel::O0) {
1551 formatv("invalid function-simplification parameter '{}'", Params).str(),
1553 };
1554 return *L;
1555}
1556
1557Expected<bool> parseMemorySSAPrinterPassOptions(StringRef Params) {
1558 return PassBuilder::parseSinglePassOption(Params, "no-ensure-optimized-uses",
1559 "MemorySSAPrinterPass");
1560}
1561
1562Expected<bool> parseSpeculativeExecutionPassOptions(StringRef Params) {
1563 return PassBuilder::parseSinglePassOption(Params, "only-if-divergent-target",
1564 "SpeculativeExecutionPass");
1565}
1566
1567Expected<std::string> parseMemProfUsePassOptions(StringRef Params) {
1568 std::string Result;
1569 while (!Params.empty()) {
1570 StringRef ParamName;
1571 std::tie(ParamName, Params) = Params.split(';');
1572
1573 if (ParamName.consume_front("profile-filename=")) {
1574 Result = ParamName.str();
1575 } else {
1577 formatv("invalid MemProfUse pass parameter '{}'", ParamName).str(),
1579 }
1580 }
1581 return Result;
1582}
1583
1585parseStructuralHashPrinterPassOptions(StringRef Params) {
1586 if (Params.empty())
1588 if (Params == "detailed")
1590 if (Params == "call-target-ignored")
1593 formatv("invalid structural hash printer parameter '{}'", Params).str(),
1595}
1596
1597Expected<bool> parseWinEHPrepareOptions(StringRef Params) {
1598 return PassBuilder::parseSinglePassOption(Params, "demote-catchswitch-only",
1599 "WinEHPreparePass");
1600}
1601
1602Expected<GlobalMergeOptions> parseGlobalMergeOptions(StringRef Params) {
1604 while (!Params.empty()) {
1605 StringRef ParamName;
1606 std::tie(ParamName, Params) = Params.split(';');
1607
1608 bool Enable = !ParamName.consume_front("no-");
1609 if (ParamName == "group-by-use")
1610 Result.GroupByUse = Enable;
1611 else if (ParamName == "ignore-single-use")
1612 Result.IgnoreSingleUse = Enable;
1613 else if (ParamName == "merge-const")
1614 Result.MergeConstantGlobals = Enable;
1615 else if (ParamName == "merge-const-aggressive")
1616 Result.MergeConstAggressive = Enable;
1617 else if (ParamName == "merge-external")
1618 Result.MergeExternal = Enable;
1619 else if (ParamName.consume_front("max-offset=")) {
1620 if (ParamName.getAsInteger(0, Result.MaxOffset))
1622 formatv("invalid GlobalMergePass parameter '{}'", ParamName).str(),
1624 } else {
1626 formatv("invalid global-merge pass parameter '{}'", Params).str(),
1628 }
1629 }
1630 return Result;
1631}
1632
1633Expected<SmallVector<std::string, 0>> parseInternalizeGVs(StringRef Params) {
1634 SmallVector<std::string, 1> PreservedGVs;
1635 while (!Params.empty()) {
1636 StringRef ParamName;
1637 std::tie(ParamName, Params) = Params.split(';');
1638
1639 if (ParamName.consume_front("preserve-gv=")) {
1640 PreservedGVs.push_back(ParamName.str());
1641 } else {
1643 formatv("invalid Internalize pass parameter '{}'", ParamName).str(),
1645 }
1646 }
1647
1648 return Expected<SmallVector<std::string, 0>>(std::move(PreservedGVs));
1649}
1650
1652parseRegAllocFastPassOptions(PassBuilder &PB, StringRef Params) {
1654 while (!Params.empty()) {
1655 StringRef ParamName;
1656 std::tie(ParamName, Params) = Params.split(';');
1657
1658 if (ParamName.consume_front("filter=")) {
1659 std::optional<RegAllocFilterFunc> Filter =
1660 PB.parseRegAllocFilter(ParamName);
1661 if (!Filter) {
1663 formatv("invalid regallocfast register filter '{}'", ParamName)
1664 .str(),
1666 }
1667 Opts.Filter = *Filter;
1668 Opts.FilterName = ParamName;
1669 continue;
1670 }
1671
1672 if (ParamName == "no-clear-vregs") {
1673 Opts.ClearVRegs = false;
1674 continue;
1675 }
1676
1678 formatv("invalid regallocfast pass parameter '{}'", ParamName).str(),
1680 }
1681 return Opts;
1682}
1683
1685parseBoundsCheckingOptions(StringRef Params) {
1687 while (!Params.empty()) {
1688 StringRef ParamName;
1689 std::tie(ParamName, Params) = Params.split(';');
1690 if (ParamName == "trap") {
1691 Options.Rt = std::nullopt;
1692 } else if (ParamName == "rt") {
1693 Options.Rt = {
1694 /*MinRuntime=*/false,
1695 /*MayReturn=*/true,
1696 /*HandlerPreserveAllRegs=*/false,
1697 };
1698 } else if (ParamName == "rt-abort") {
1699 Options.Rt = {
1700 /*MinRuntime=*/false,
1701 /*MayReturn=*/false,
1702 /*HandlerPreserveAllRegs=*/false,
1703 };
1704 } else if (ParamName == "min-rt") {
1705 Options.Rt = {
1706 /*MinRuntime=*/true,
1707 /*MayReturn=*/true,
1708 /*HandlerPreserveAllRegs=*/false,
1709 };
1710 } else if (ParamName == "min-rt-abort") {
1711 Options.Rt = {
1712 /*MinRuntime=*/true,
1713 /*MayReturn=*/false,
1714 /*HandlerPreserveAllRegs=*/false,
1715 };
1716 } else if (ParamName == "merge") {
1717 Options.Merge = true;
1718 } else if (ParamName == "handler-preserve-all-regs") {
1719 if (Options.Rt)
1720 Options.Rt->HandlerPreserveAllRegs = true;
1721 } else {
1722 StringRef ParamEQ;
1723 StringRef Val;
1724 std::tie(ParamEQ, Val) = ParamName.split('=');
1725 int8_t Id;
1726 if (ParamEQ == "guard" && !Val.getAsInteger(0, Id)) {
1727 Options.GuardKind = Id;
1728 } else {
1730 formatv("invalid BoundsChecking pass parameter '{}'", ParamName)
1731 .str(),
1733 }
1734 }
1735 }
1736 return Options;
1737}
1738
1739Expected<CodeGenOptLevel> parseExpandIRInstsOptions(StringRef Param) {
1740 if (Param.empty())
1741 return CodeGenOptLevel::None;
1742
1743 // Parse a CodeGenOptLevel, e.g. "O1", "O2", "O3".
1744 auto [Prefix, Digit] = Param.split('O');
1745
1746 uint8_t N;
1747 if (!Prefix.empty() || Digit.getAsInteger(10, N))
1748 return createStringError("invalid expand-ir-insts pass parameter '%s'",
1749 Param.str().c_str());
1750
1751 std::optional<CodeGenOptLevel> Level = CodeGenOpt::getLevel(N);
1752 if (!Level.has_value())
1753 return createStringError(
1754 "invalid optimization level for expand-ir-insts pass: %s",
1755 Digit.str().c_str());
1756
1757 return *Level;
1758}
1759
1761parseRegAllocGreedyFilterFunc(PassBuilder &PB, StringRef Params) {
1762 if (Params.empty() || Params == "all")
1763 return RAGreedyPass::Options();
1764
1765 std::optional<RegAllocFilterFunc> Filter = PB.parseRegAllocFilter(Params);
1766 if (Filter)
1767 return RAGreedyPass::Options{*Filter, Params};
1768
1770 formatv("invalid regallocgreedy register filter '{}'", Params).str(),
1772}
1773
1774Expected<bool> parseMachineSinkingPassOptions(StringRef Params) {
1775 return PassBuilder::parseSinglePassOption(Params, "enable-sink-fold",
1776 "MachineSinkingPass");
1777}
1778
1779Expected<bool> parseMachineBlockPlacementPassOptions(StringRef Params) {
1780 bool AllowTailMerge = true;
1781 if (!Params.empty()) {
1782 AllowTailMerge = !Params.consume_front("no-");
1783 if (Params != "tail-merge")
1785 formatv("invalid MachineBlockPlacementPass parameter '{}'", Params)
1786 .str(),
1788 }
1789 return AllowTailMerge;
1790}
1791
1792Expected<bool> parseVirtRegRewriterPassOptions(StringRef Params) {
1793 bool ClearVirtRegs = true;
1794 if (!Params.empty()) {
1795 ClearVirtRegs = !Params.consume_front("no-");
1796 if (Params != "clear-vregs")
1798 formatv("invalid VirtRegRewriter pass parameter '{}'", Params).str(),
1800 }
1801 return ClearVirtRegs;
1802}
1803
1804struct FatLTOOptions {
1805 OptimizationLevel OptLevel;
1806 bool ThinLTO = false;
1807 bool EmitSummary = false;
1808};
1809
1810Expected<FatLTOOptions> parseFatLTOOptions(StringRef Params) {
1811 FatLTOOptions Result;
1812 bool HaveOptLevel = false;
1813 while (!Params.empty()) {
1814 StringRef ParamName;
1815 std::tie(ParamName, Params) = Params.split(';');
1816
1817 if (ParamName == "thinlto") {
1818 Result.ThinLTO = true;
1819 } else if (ParamName == "emit-summary") {
1820 Result.EmitSummary = true;
1821 } else if (std::optional<OptimizationLevel> OptLevel =
1822 parseOptLevel(ParamName)) {
1823 Result.OptLevel = *OptLevel;
1824 HaveOptLevel = true;
1825 } else {
1827 formatv("invalid fatlto-pre-link pass parameter '{}'", ParamName)
1828 .str(),
1830 }
1831 }
1832 if (!HaveOptLevel)
1834 "missing optimization level for fatlto-pre-link pipeline",
1836 return Result;
1837}
1838
1839} // namespace
1840
1841/// Tests whether registered callbacks will accept a given pass name.
1842///
1843/// When parsing a pipeline text, the type of the outermost pipeline may be
1844/// omitted, in which case the type is automatically determined from the first
1845/// pass name in the text. This may be a name that is handled through one of the
1846/// callbacks. We check this through the oridinary parsing callbacks by setting
1847/// up a dummy PassManager in order to not force the client to also handle this
1848/// type of query.
1849template <typename PassManagerT, typename CallbacksT>
1850static bool callbacksAcceptPassName(StringRef Name, CallbacksT &Callbacks) {
1851 if (!Callbacks.empty()) {
1852 PassManagerT DummyPM;
1853 for (auto &CB : Callbacks)
1854 if (CB(Name, DummyPM, {}))
1855 return true;
1856 }
1857 return false;
1858}
1859
1860template <typename CallbacksT>
1861static bool isModulePassName(StringRef Name, CallbacksT &Callbacks) {
1862 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1863
1864 // Explicitly handle pass manager names.
1865 if (Name == "module")
1866 return true;
1867 if (Name == "cgscc")
1868 return true;
1869 if (NameNoBracket == "function")
1870 return true;
1871 if (Name == "coro-cond")
1872 return true;
1873
1874#define MODULE_PASS(NAME, CREATE_PASS) \
1875 if (Name == NAME) \
1876 return true;
1877#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1878 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1879 return true;
1880#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
1881 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1882 return true;
1883#include "PassRegistry.def"
1884
1885 return callbacksAcceptPassName<ModulePassManager>(Name, Callbacks);
1886}
1887
1888template <typename CallbacksT>
1889static bool isCGSCCPassName(StringRef Name, CallbacksT &Callbacks) {
1890 // Explicitly handle pass manager names.
1891 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1892 if (Name == "cgscc")
1893 return true;
1894 if (NameNoBracket == "function")
1895 return true;
1896
1897 // Explicitly handle custom-parsed pass names.
1898 if (parseDevirtPassName(Name))
1899 return true;
1900
1901#define CGSCC_PASS(NAME, CREATE_PASS) \
1902 if (Name == NAME) \
1903 return true;
1904#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1905 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1906 return true;
1907#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
1908 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1909 return true;
1910#include "PassRegistry.def"
1911
1912 return callbacksAcceptPassName<CGSCCPassManager>(Name, Callbacks);
1913}
1914
1915template <typename CallbacksT>
1916static bool isFunctionPassName(StringRef Name, CallbacksT &Callbacks) {
1917 // Explicitly handle pass manager names.
1918 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1919 if (NameNoBracket == "function")
1920 return true;
1921 if (Name == "loop" || Name == "loop-mssa" || Name == "machine-function")
1922 return true;
1923
1924#define FUNCTION_PASS(NAME, CREATE_PASS) \
1925 if (Name == NAME) \
1926 return true;
1927#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1928 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1929 return true;
1930#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1931 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1932 return true;
1933#include "PassRegistry.def"
1934
1935 return callbacksAcceptPassName<FunctionPassManager>(Name, Callbacks);
1936}
1937
1938template <typename CallbacksT>
1939static bool isMachineFunctionPassName(StringRef Name, CallbacksT &Callbacks) {
1940 // Explicitly handle pass manager names.
1941 if (Name == "machine-function")
1942 return true;
1943
1944#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
1945 if (Name == NAME) \
1946 return true;
1947#define MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, \
1948 PARAMS) \
1949 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1950 return true;
1951
1952#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1953 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1954 return true;
1955
1956#include "llvm/Passes/MachinePassRegistry.def"
1957
1959}
1960
1961template <typename CallbacksT>
1962static bool isLoopNestPassName(StringRef Name, CallbacksT &Callbacks,
1963 bool &UseMemorySSA) {
1964 UseMemorySSA = false;
1965
1966 if (PassBuilder::checkParametrizedPassName(Name, "lnicm")) {
1967 UseMemorySSA = true;
1968 return true;
1969 }
1970
1971#define LOOPNEST_PASS(NAME, CREATE_PASS) \
1972 if (Name == NAME) \
1973 return true;
1974#include "PassRegistry.def"
1975
1976 return callbacksAcceptPassName<LoopPassManager>(Name, Callbacks);
1977}
1978
1979template <typename CallbacksT>
1980static bool isLoopPassName(StringRef Name, CallbacksT &Callbacks,
1981 bool &UseMemorySSA) {
1982 UseMemorySSA = false;
1983
1984 if (PassBuilder::checkParametrizedPassName(Name, "licm")) {
1985 UseMemorySSA = true;
1986 return true;
1987 }
1988
1989#define LOOP_PASS(NAME, CREATE_PASS) \
1990 if (Name == NAME) \
1991 return true;
1992#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1993 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1994 return true;
1995#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
1996 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1997 return true;
1998#include "PassRegistry.def"
1999
2000 return callbacksAcceptPassName<LoopPassManager>(Name, Callbacks);
2001}
2002
2003std::optional<std::vector<PassBuilder::PipelineElement>>
2004PassBuilder::parsePipelineText(StringRef Text) {
2005 std::vector<PipelineElement> ResultPipeline;
2006
2007 SmallVector<std::vector<PipelineElement> *, 4> PipelineStack = {
2008 &ResultPipeline};
2009 for (;;) {
2010 std::vector<PipelineElement> &Pipeline = *PipelineStack.back();
2011 size_t Pos = Text.find_first_of(",()");
2012 Pipeline.push_back({Text.substr(0, Pos), {}});
2013
2014 // If we have a single terminating name, we're done.
2015 if (Pos == Text.npos)
2016 break;
2017
2018 char Sep = Text[Pos];
2019 Text = Text.substr(Pos + 1);
2020 if (Sep == ',')
2021 // Just a name ending in a comma, continue.
2022 continue;
2023
2024 if (Sep == '(') {
2025 // Push the inner pipeline onto the stack to continue processing.
2026 PipelineStack.push_back(&Pipeline.back().InnerPipeline);
2027 continue;
2028 }
2029
2030 assert(Sep == ')' && "Bogus separator!");
2031 // When handling the close parenthesis, we greedily consume them to avoid
2032 // empty strings in the pipeline.
2033 do {
2034 // If we try to pop the outer pipeline we have unbalanced parentheses.
2035 if (PipelineStack.size() == 1)
2036 return std::nullopt;
2037
2038 PipelineStack.pop_back();
2039 } while (Text.consume_front(")"));
2040
2041 // Check if we've finished parsing.
2042 if (Text.empty())
2043 break;
2044
2045 // Otherwise, the end of an inner pipeline always has to be followed by
2046 // a comma, and then we can continue.
2047 if (!Text.consume_front(","))
2048 return std::nullopt;
2049 }
2050
2051 if (PipelineStack.size() > 1)
2052 // Unbalanced paretheses.
2053 return std::nullopt;
2054
2055 assert(PipelineStack.back() == &ResultPipeline &&
2056 "Wrong pipeline at the bottom of the stack!");
2057 return {std::move(ResultPipeline)};
2058}
2059
2062 PTO.LoopVectorization = L.getSpeedupLevel() > 1;
2063 PTO.SLPVectorization = L.getSpeedupLevel() > 1;
2064}
2065
2066Error PassBuilder::parseModulePass(ModulePassManager &MPM,
2067 const PipelineElement &E) {
2068 auto &Name = E.Name;
2069 auto &InnerPipeline = E.InnerPipeline;
2070
2071 // First handle complex passes like the pass managers which carry pipelines.
2072 if (!InnerPipeline.empty()) {
2073 if (Name == "module") {
2074 ModulePassManager NestedMPM;
2075 if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline))
2076 return Err;
2077 MPM.addPass(std::move(NestedMPM));
2078 return Error::success();
2079 }
2080 if (Name == "coro-cond") {
2081 ModulePassManager NestedMPM;
2082 if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline))
2083 return Err;
2084 MPM.addPass(CoroConditionalWrapper(std::move(NestedMPM)));
2085 return Error::success();
2086 }
2087 if (Name == "cgscc") {
2088 CGSCCPassManager CGPM;
2089 if (auto Err = parseCGSCCPassPipeline(CGPM, InnerPipeline))
2090 return Err;
2092 return Error::success();
2093 }
2094 if (auto Params = parseFunctionPipelineName(Name)) {
2095 if (Params->second)
2097 "cannot have a no-rerun module to function adaptor",
2100 if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline))
2101 return Err;
2102 MPM.addPass(
2103 createModuleToFunctionPassAdaptor(std::move(FPM), Params->first));
2104 return Error::success();
2105 }
2106
2107 for (auto &C : ModulePipelineParsingCallbacks)
2108 if (C(Name, MPM, InnerPipeline))
2109 return Error::success();
2110
2111 // Normal passes can't have pipelines.
2113 formatv("invalid use of '{}' pass as module pipeline", Name).str(),
2115 ;
2116 }
2117
2118 // Finally expand the basic registered passes from the .inc file.
2119#define MODULE_PASS(NAME, CREATE_PASS) \
2120 if (Name == NAME) { \
2121 MPM.addPass(CREATE_PASS); \
2122 return Error::success(); \
2123 }
2124#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2125 if (checkParametrizedPassName(Name, NAME)) { \
2126 auto Params = parsePassParameters(PARSER, Name, NAME); \
2127 if (!Params) \
2128 return Params.takeError(); \
2129 MPM.addPass(CREATE_PASS(Params.get())); \
2130 return Error::success(); \
2131 }
2132#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
2133 if (Name == "require<" NAME ">") { \
2134 MPM.addPass( \
2135 RequireAnalysisPass< \
2136 std::remove_reference_t<decltype(CREATE_PASS)>, Module>()); \
2137 return Error::success(); \
2138 } \
2139 if (Name == "invalidate<" NAME ">") { \
2140 MPM.addPass(InvalidateAnalysisPass< \
2141 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2142 return Error::success(); \
2143 }
2144#define CGSCC_PASS(NAME, CREATE_PASS) \
2145 if (Name == NAME) { \
2146 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(CREATE_PASS)); \
2147 return Error::success(); \
2148 }
2149#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2150 if (checkParametrizedPassName(Name, NAME)) { \
2151 auto Params = parsePassParameters(PARSER, Name, NAME); \
2152 if (!Params) \
2153 return Params.takeError(); \
2154 MPM.addPass( \
2155 createModuleToPostOrderCGSCCPassAdaptor(CREATE_PASS(Params.get()))); \
2156 return Error::success(); \
2157 }
2158#define FUNCTION_PASS(NAME, CREATE_PASS) \
2159 if (Name == NAME) { \
2160 if constexpr (std::is_constructible_v< \
2161 std::remove_reference_t<decltype(CREATE_PASS)>, \
2162 const TargetMachine &>) { \
2163 if (!TM) \
2164 return make_error<StringError>( \
2165 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2166 inconvertibleErrorCode()); \
2167 } \
2168 MPM.addPass(createModuleToFunctionPassAdaptor(CREATE_PASS)); \
2169 return Error::success(); \
2170 }
2171#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2172 if (checkParametrizedPassName(Name, NAME)) { \
2173 auto Params = parsePassParameters(PARSER, Name, NAME); \
2174 if (!Params) \
2175 return Params.takeError(); \
2176 auto CreatePass = CREATE_PASS; \
2177 if constexpr (std::is_constructible_v< \
2178 std::remove_reference_t<decltype(CreatePass( \
2179 Params.get()))>, \
2180 const TargetMachine &, \
2181 std::remove_reference_t<decltype(Params.get())>>) { \
2182 if (!TM) { \
2183 return make_error<StringError>( \
2184 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2185 inconvertibleErrorCode()); \
2186 } \
2187 } \
2188 MPM.addPass(createModuleToFunctionPassAdaptor(CREATE_PASS(Params.get()))); \
2189 return Error::success(); \
2190 }
2191#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2192 if (Name == NAME) { \
2193 MPM.addPass(createModuleToFunctionPassAdaptor( \
2194 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2195 return Error::success(); \
2196 }
2197#define LOOP_PASS(NAME, CREATE_PASS) \
2198 if (Name == NAME) { \
2199 MPM.addPass(createModuleToFunctionPassAdaptor( \
2200 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2201 return Error::success(); \
2202 }
2203#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2204 if (checkParametrizedPassName(Name, NAME)) { \
2205 auto Params = parsePassParameters(PARSER, Name, NAME); \
2206 if (!Params) \
2207 return Params.takeError(); \
2208 MPM.addPass(createModuleToFunctionPassAdaptor( \
2209 createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), false))); \
2210 return Error::success(); \
2211 }
2212#include "PassRegistry.def"
2213
2214 for (auto &C : ModulePipelineParsingCallbacks)
2215 if (C(Name, MPM, InnerPipeline))
2216 return Error::success();
2218 formatv("unknown module pass '{}'", Name).str(),
2220}
2221
2222Error PassBuilder::parseCGSCCPass(CGSCCPassManager &CGPM,
2223 const PipelineElement &E) {
2224 auto &Name = E.Name;
2225 auto &InnerPipeline = E.InnerPipeline;
2226
2227 // First handle complex passes like the pass managers which carry pipelines.
2228 if (!InnerPipeline.empty()) {
2229 if (Name == "cgscc") {
2230 CGSCCPassManager NestedCGPM;
2231 if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline))
2232 return Err;
2233 // Add the nested pass manager with the appropriate adaptor.
2234 CGPM.addPass(std::move(NestedCGPM));
2235 return Error::success();
2236 }
2237 if (auto Params = parseFunctionPipelineName(Name)) {
2239 if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline))
2240 return Err;
2241 // Add the nested pass manager with the appropriate adaptor.
2243 std::move(FPM), Params->first, Params->second));
2244 return Error::success();
2245 }
2246 if (auto MaxRepetitions = parseDevirtPassName(Name)) {
2247 CGSCCPassManager NestedCGPM;
2248 if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline))
2249 return Err;
2250 CGPM.addPass(
2251 createDevirtSCCRepeatedPass(std::move(NestedCGPM), *MaxRepetitions));
2252 return Error::success();
2253 }
2254
2255 for (auto &C : CGSCCPipelineParsingCallbacks)
2256 if (C(Name, CGPM, InnerPipeline))
2257 return Error::success();
2258
2259 // Normal passes can't have pipelines.
2261 formatv("invalid use of '{}' pass as cgscc pipeline", Name).str(),
2263 }
2264
2265// Now expand the basic registered passes from the .inc file.
2266#define CGSCC_PASS(NAME, CREATE_PASS) \
2267 if (Name == NAME) { \
2268 CGPM.addPass(CREATE_PASS); \
2269 return Error::success(); \
2270 }
2271#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2272 if (checkParametrizedPassName(Name, NAME)) { \
2273 auto Params = parsePassParameters(PARSER, Name, NAME); \
2274 if (!Params) \
2275 return Params.takeError(); \
2276 CGPM.addPass(CREATE_PASS(Params.get())); \
2277 return Error::success(); \
2278 }
2279#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
2280 if (Name == "require<" NAME ">") { \
2281 CGPM.addPass(RequireAnalysisPass< \
2282 std::remove_reference_t<decltype(CREATE_PASS)>, \
2283 LazyCallGraph::SCC, CGSCCAnalysisManager, LazyCallGraph &, \
2284 CGSCCUpdateResult &>()); \
2285 return Error::success(); \
2286 } \
2287 if (Name == "invalidate<" NAME ">") { \
2288 CGPM.addPass(InvalidateAnalysisPass< \
2289 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2290 return Error::success(); \
2291 }
2292#define FUNCTION_PASS(NAME, CREATE_PASS) \
2293 if (Name == NAME) { \
2294 if constexpr (std::is_constructible_v< \
2295 std::remove_reference_t<decltype(CREATE_PASS)>, \
2296 const TargetMachine &>) { \
2297 if (!TM) \
2298 return make_error<StringError>( \
2299 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2300 inconvertibleErrorCode()); \
2301 } \
2302 CGPM.addPass(createCGSCCToFunctionPassAdaptor(CREATE_PASS)); \
2303 return Error::success(); \
2304 }
2305#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2306 if (checkParametrizedPassName(Name, NAME)) { \
2307 auto Params = parsePassParameters(PARSER, Name, NAME); \
2308 if (!Params) \
2309 return Params.takeError(); \
2310 auto CreatePass = CREATE_PASS; \
2311 if constexpr (std::is_constructible_v< \
2312 std::remove_reference_t<decltype(CreatePass( \
2313 Params.get()))>, \
2314 const TargetMachine &, \
2315 std::remove_reference_t<decltype(Params.get())>>) { \
2316 if (!TM) { \
2317 return make_error<StringError>( \
2318 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2319 inconvertibleErrorCode()); \
2320 } \
2321 } \
2322 CGPM.addPass(createCGSCCToFunctionPassAdaptor(CREATE_PASS(Params.get()))); \
2323 return Error::success(); \
2324 }
2325#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2326 if (Name == NAME) { \
2327 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
2328 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2329 return Error::success(); \
2330 }
2331#define LOOP_PASS(NAME, CREATE_PASS) \
2332 if (Name == NAME) { \
2333 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
2334 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2335 return Error::success(); \
2336 }
2337#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2338 if (checkParametrizedPassName(Name, NAME)) { \
2339 auto Params = parsePassParameters(PARSER, Name, NAME); \
2340 if (!Params) \
2341 return Params.takeError(); \
2342 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
2343 createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), false))); \
2344 return Error::success(); \
2345 }
2346#include "PassRegistry.def"
2347
2348 for (auto &C : CGSCCPipelineParsingCallbacks)
2349 if (C(Name, CGPM, InnerPipeline))
2350 return Error::success();
2351 return make_error<StringError>(formatv("unknown cgscc pass '{}'", Name).str(),
2353}
2354
2355Error PassBuilder::parseFunctionPass(FunctionPassManager &FPM,
2356 const PipelineElement &E) {
2357 auto &Name = E.Name;
2358 auto &InnerPipeline = E.InnerPipeline;
2359
2360 // First handle complex passes like the pass managers which carry pipelines.
2361 if (!InnerPipeline.empty()) {
2362 if (Name == "function") {
2363 FunctionPassManager NestedFPM;
2364 if (auto Err = parseFunctionPassPipeline(NestedFPM, InnerPipeline))
2365 return Err;
2366 // Add the nested pass manager with the appropriate adaptor.
2367 FPM.addPass(std::move(NestedFPM));
2368 return Error::success();
2369 }
2370 if (Name == "loop" || Name == "loop-mssa") {
2371 LoopPassManager LPM;
2372 if (auto Err = parseLoopPassPipeline(LPM, InnerPipeline))
2373 return Err;
2374 // Add the nested pass manager with the appropriate adaptor.
2375 bool UseMemorySSA = (Name == "loop-mssa");
2376 FPM.addPass(
2377 createFunctionToLoopPassAdaptor(std::move(LPM), UseMemorySSA));
2378 return Error::success();
2379 }
2380 if (Name == "machine-function") {
2382 if (auto Err = parseMachinePassPipeline(MFPM, InnerPipeline))
2383 return Err;
2385 return Error::success();
2386 }
2387
2388 for (auto &C : FunctionPipelineParsingCallbacks)
2389 if (C(Name, FPM, InnerPipeline))
2390 return Error::success();
2391
2392 // Normal passes can't have pipelines.
2394 formatv("invalid use of '{}' pass as function pipeline", Name).str(),
2396 }
2397
2398// Now expand the basic registered passes from the .inc file.
2399#define FUNCTION_PASS(NAME, CREATE_PASS) \
2400 if (Name == NAME) { \
2401 if constexpr (std::is_constructible_v< \
2402 std::remove_reference_t<decltype(CREATE_PASS)>, \
2403 const TargetMachine &>) { \
2404 if (!TM) \
2405 return make_error<StringError>( \
2406 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2407 inconvertibleErrorCode()); \
2408 } \
2409 FPM.addPass(CREATE_PASS); \
2410 return Error::success(); \
2411 }
2412#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2413 if (checkParametrizedPassName(Name, NAME)) { \
2414 auto Params = parsePassParameters(PARSER, Name, NAME); \
2415 if (!Params) \
2416 return Params.takeError(); \
2417 auto CreatePass = CREATE_PASS; \
2418 if constexpr (std::is_constructible_v< \
2419 std::remove_reference_t<decltype(CreatePass( \
2420 Params.get()))>, \
2421 const TargetMachine &, \
2422 std::remove_reference_t<decltype(Params.get())>>) { \
2423 if (!TM) { \
2424 return make_error<StringError>( \
2425 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2426 inconvertibleErrorCode()); \
2427 } \
2428 } \
2429 FPM.addPass(CREATE_PASS(Params.get())); \
2430 return Error::success(); \
2431 }
2432#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
2433 if (Name == "require<" NAME ">") { \
2434 if constexpr (std::is_constructible_v< \
2435 std::remove_reference_t<decltype(CREATE_PASS)>, \
2436 const TargetMachine &>) { \
2437 if (!TM) \
2438 return make_error<StringError>( \
2439 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2440 inconvertibleErrorCode()); \
2441 } \
2442 FPM.addPass( \
2443 RequireAnalysisPass<std::remove_reference_t<decltype(CREATE_PASS)>, \
2444 Function>()); \
2445 return Error::success(); \
2446 } \
2447 if (Name == "invalidate<" NAME ">") { \
2448 FPM.addPass(InvalidateAnalysisPass< \
2449 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2450 return Error::success(); \
2451 }
2452// FIXME: UseMemorySSA is set to false. Maybe we could do things like:
2453// bool UseMemorySSA = !("canon-freeze" || "loop-predication" ||
2454// "guard-widening");
2455// The risk is that it may become obsolete if we're not careful.
2456#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2457 if (Name == NAME) { \
2458 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS, false)); \
2459 return Error::success(); \
2460 }
2461#define LOOP_PASS(NAME, CREATE_PASS) \
2462 if (Name == NAME) { \
2463 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS, false)); \
2464 return Error::success(); \
2465 }
2466#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2467 if (checkParametrizedPassName(Name, NAME)) { \
2468 auto Params = parsePassParameters(PARSER, Name, NAME); \
2469 if (!Params) \
2470 return Params.takeError(); \
2471 FPM.addPass( \
2472 createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), false)); \
2473 return Error::success(); \
2474 }
2475#include "PassRegistry.def"
2476
2477 for (auto &C : FunctionPipelineParsingCallbacks)
2478 if (C(Name, FPM, InnerPipeline))
2479 return Error::success();
2481 formatv("unknown function pass '{}'", Name).str(),
2483}
2484
2485Error PassBuilder::parseLoopPass(LoopPassManager &LPM,
2486 const PipelineElement &E) {
2487 StringRef Name = E.Name;
2488 auto &InnerPipeline = E.InnerPipeline;
2489
2490 // First handle complex passes like the pass managers which carry pipelines.
2491 if (!InnerPipeline.empty()) {
2492 if (Name == "loop") {
2493 LoopPassManager NestedLPM;
2494 if (auto Err = parseLoopPassPipeline(NestedLPM, InnerPipeline))
2495 return Err;
2496 // Add the nested pass manager with the appropriate adaptor.
2497 LPM.addPass(std::move(NestedLPM));
2498 return Error::success();
2499 }
2500
2501 for (auto &C : LoopPipelineParsingCallbacks)
2502 if (C(Name, LPM, InnerPipeline))
2503 return Error::success();
2504
2505 // Normal passes can't have pipelines.
2507 formatv("invalid use of '{}' pass as loop pipeline", Name).str(),
2509 }
2510
2511// Now expand the basic registered passes from the .inc file.
2512#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2513 if (Name == NAME) { \
2514 LPM.addPass(CREATE_PASS); \
2515 return Error::success(); \
2516 }
2517#define LOOP_PASS(NAME, CREATE_PASS) \
2518 if (Name == NAME) { \
2519 LPM.addPass(CREATE_PASS); \
2520 return Error::success(); \
2521 }
2522#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2523 if (checkParametrizedPassName(Name, NAME)) { \
2524 auto Params = parsePassParameters(PARSER, Name, NAME); \
2525 if (!Params) \
2526 return Params.takeError(); \
2527 LPM.addPass(CREATE_PASS(Params.get())); \
2528 return Error::success(); \
2529 }
2530#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
2531 if (Name == "require<" NAME ">") { \
2532 LPM.addPass(RequireAnalysisPass< \
2533 std::remove_reference_t<decltype(CREATE_PASS)>, Loop, \
2534 LoopAnalysisManager, LoopStandardAnalysisResults &, \
2535 LPMUpdater &>()); \
2536 return Error::success(); \
2537 } \
2538 if (Name == "invalidate<" NAME ">") { \
2539 LPM.addPass(InvalidateAnalysisPass< \
2540 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2541 return Error::success(); \
2542 }
2543#include "PassRegistry.def"
2544
2545 for (auto &C : LoopPipelineParsingCallbacks)
2546 if (C(Name, LPM, InnerPipeline))
2547 return Error::success();
2548 return make_error<StringError>(formatv("unknown loop pass '{}'", Name).str(),
2550}
2551
2552Error PassBuilder::parseMachinePass(MachineFunctionPassManager &MFPM,
2553 const PipelineElement &E) {
2554 StringRef Name = E.Name;
2555 // Handle any nested pass managers.
2556 if (!E.InnerPipeline.empty()) {
2557 if (E.Name == "machine-function") {
2559 if (auto Err = parseMachinePassPipeline(NestedPM, E.InnerPipeline))
2560 return Err;
2561 MFPM.addPass(std::move(NestedPM));
2562 return Error::success();
2563 }
2564 return make_error<StringError>("invalid pipeline",
2566 }
2567
2568#define MACHINE_MODULE_PASS(NAME, CREATE_PASS) \
2569 if (Name == NAME) { \
2570 MFPM.addPass(CREATE_PASS); \
2571 return Error::success(); \
2572 }
2573#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
2574 if (Name == NAME) { \
2575 MFPM.addPass(CREATE_PASS); \
2576 return Error::success(); \
2577 }
2578#define MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, \
2579 PARAMS) \
2580 if (checkParametrizedPassName(Name, NAME)) { \
2581 auto Params = parsePassParameters(PARSER, Name, NAME); \
2582 if (!Params) \
2583 return Params.takeError(); \
2584 MFPM.addPass(CREATE_PASS(Params.get())); \
2585 return Error::success(); \
2586 }
2587#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
2588 if (Name == "require<" NAME ">") { \
2589 MFPM.addPass( \
2590 RequireAnalysisPass<std::remove_reference_t<decltype(CREATE_PASS)>, \
2591 MachineFunction>()); \
2592 return Error::success(); \
2593 } \
2594 if (Name == "invalidate<" NAME ">") { \
2595 MFPM.addPass(InvalidateAnalysisPass< \
2596 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2597 return Error::success(); \
2598 }
2599#include "llvm/Passes/MachinePassRegistry.def"
2600
2601 for (auto &C : MachineFunctionPipelineParsingCallbacks)
2602 if (C(Name, MFPM, E.InnerPipeline))
2603 return Error::success();
2605 formatv("unknown machine pass '{}'", Name).str(),
2607}
2608
2609bool PassBuilder::parseAAPassName(AAManager &AA, StringRef Name) {
2610#define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
2611 if (Name == NAME) { \
2612 AA.registerModuleAnalysis< \
2613 std::remove_reference_t<decltype(CREATE_PASS)>>(); \
2614 return true; \
2615 }
2616#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
2617 if (Name == NAME) { \
2618 AA.registerFunctionAnalysis< \
2619 std::remove_reference_t<decltype(CREATE_PASS)>>(); \
2620 return true; \
2621 }
2622#include "PassRegistry.def"
2623
2624 for (auto &C : AAParsingCallbacks)
2625 if (C(Name, AA))
2626 return true;
2627 return false;
2628}
2629
2630Error PassBuilder::parseMachinePassPipeline(
2632 for (const auto &Element : Pipeline) {
2633 if (auto Err = parseMachinePass(MFPM, Element))
2634 return Err;
2635 }
2636 return Error::success();
2637}
2638
2639Error PassBuilder::parseLoopPassPipeline(LoopPassManager &LPM,
2640 ArrayRef<PipelineElement> Pipeline) {
2641 for (const auto &Element : Pipeline) {
2642 if (auto Err = parseLoopPass(LPM, Element))
2643 return Err;
2644 }
2645 return Error::success();
2646}
2647
2648Error PassBuilder::parseFunctionPassPipeline(
2650 for (const auto &Element : Pipeline) {
2651 if (auto Err = parseFunctionPass(FPM, Element))
2652 return Err;
2653 }
2654 return Error::success();
2655}
2656
2657Error PassBuilder::parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
2658 ArrayRef<PipelineElement> Pipeline) {
2659 for (const auto &Element : Pipeline) {
2660 if (auto Err = parseCGSCCPass(CGPM, Element))
2661 return Err;
2662 }
2663 return Error::success();
2664}
2665
2671 MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });
2672 MAM.registerPass([&] { return CGSCCAnalysisManagerModuleProxy(CGAM); });
2673 CGAM.registerPass([&] { return ModuleAnalysisManagerCGSCCProxy(MAM); });
2674 FAM.registerPass([&] { return CGSCCAnalysisManagerFunctionProxy(CGAM); });
2675 FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); });
2676 FAM.registerPass([&] { return LoopAnalysisManagerFunctionProxy(LAM); });
2677 LAM.registerPass([&] { return FunctionAnalysisManagerLoopProxy(FAM); });
2678 if (MFAM) {
2679 MAM.registerPass(
2680 [&] { return MachineFunctionAnalysisManagerModuleProxy(*MFAM); });
2681 FAM.registerPass(
2682 [&] { return MachineFunctionAnalysisManagerFunctionProxy(*MFAM); });
2683 MFAM->registerPass(
2685 MFAM->registerPass(
2687 }
2688}
2689
2690Error PassBuilder::parseModulePassPipeline(ModulePassManager &MPM,
2691 ArrayRef<PipelineElement> Pipeline) {
2692 for (const auto &Element : Pipeline) {
2693 if (auto Err = parseModulePass(MPM, Element))
2694 return Err;
2695 }
2696 return Error::success();
2697}
2698
2699// Primary pass pipeline description parsing routine for a \c ModulePassManager
2700// FIXME: Should this routine accept a TargetMachine or require the caller to
2701// pre-populate the analysis managers with target-specific stuff?
2703 StringRef PipelineText) {
2704 auto Pipeline = parsePipelineText(PipelineText);
2705 if (!Pipeline || Pipeline->empty())
2707 formatv("invalid pipeline '{}'", PipelineText).str(),
2709
2710 // If the first name isn't at the module layer, wrap the pipeline up
2711 // automatically.
2712 StringRef FirstName = Pipeline->front().Name;
2713
2714 if (!isModulePassName(FirstName, ModulePipelineParsingCallbacks)) {
2715 bool UseMemorySSA;
2716 if (isCGSCCPassName(FirstName, CGSCCPipelineParsingCallbacks)) {
2717 Pipeline = {{"cgscc", std::move(*Pipeline)}};
2718 } else if (isFunctionPassName(FirstName,
2719 FunctionPipelineParsingCallbacks)) {
2720 Pipeline = {{"function", std::move(*Pipeline)}};
2721 } else if (isLoopNestPassName(FirstName, LoopPipelineParsingCallbacks,
2722 UseMemorySSA)) {
2723 Pipeline = {{"function", {{UseMemorySSA ? "loop-mssa" : "loop",
2724 std::move(*Pipeline)}}}};
2725 } else if (isLoopPassName(FirstName, LoopPipelineParsingCallbacks,
2726 UseMemorySSA)) {
2727 Pipeline = {{"function", {{UseMemorySSA ? "loop-mssa" : "loop",
2728 std::move(*Pipeline)}}}};
2729 } else if (isMachineFunctionPassName(
2730 FirstName, MachineFunctionPipelineParsingCallbacks)) {
2731 Pipeline = {{"function", {{"machine-function", std::move(*Pipeline)}}}};
2732 } else {
2733 for (auto &C : TopLevelPipelineParsingCallbacks)
2734 if (C(MPM, *Pipeline))
2735 return Error::success();
2736
2737 // Unknown pass or pipeline name!
2738 auto &InnerPipeline = Pipeline->front().InnerPipeline;
2740 formatv("unknown {} name '{}'",
2741 (InnerPipeline.empty() ? "pass" : "pipeline"), FirstName)
2742 .str(),
2744 }
2745 }
2746
2747 if (auto Err = parseModulePassPipeline(MPM, *Pipeline))
2748 return Err;
2749 return Error::success();
2750}
2751
2752// Primary pass pipeline description parsing routine for a \c CGSCCPassManager
2754 StringRef PipelineText) {
2755 auto Pipeline = parsePipelineText(PipelineText);
2756 if (!Pipeline || Pipeline->empty())
2758 formatv("invalid pipeline '{}'", PipelineText).str(),
2760
2761 StringRef FirstName = Pipeline->front().Name;
2762 if (!isCGSCCPassName(FirstName, CGSCCPipelineParsingCallbacks))
2764 formatv("unknown cgscc pass '{}' in pipeline '{}'", FirstName,
2765 PipelineText)
2766 .str(),
2768
2769 if (auto Err = parseCGSCCPassPipeline(CGPM, *Pipeline))
2770 return Err;
2771 return Error::success();
2772}
2773
2774// Primary pass pipeline description parsing routine for a \c
2775// FunctionPassManager
2777 StringRef PipelineText) {
2778 auto Pipeline = parsePipelineText(PipelineText);
2779 if (!Pipeline || Pipeline->empty())
2781 formatv("invalid pipeline '{}'", PipelineText).str(),
2783
2784 StringRef FirstName = Pipeline->front().Name;
2785 if (!isFunctionPassName(FirstName, FunctionPipelineParsingCallbacks))
2787 formatv("unknown function pass '{}' in pipeline '{}'", FirstName,
2788 PipelineText)
2789 .str(),
2791
2792 if (auto Err = parseFunctionPassPipeline(FPM, *Pipeline))
2793 return Err;
2794 return Error::success();
2795}
2796
2797// Primary pass pipeline description parsing routine for a \c LoopPassManager
2799 StringRef PipelineText) {
2800 auto Pipeline = parsePipelineText(PipelineText);
2801 if (!Pipeline || Pipeline->empty())
2803 formatv("invalid pipeline '{}'", PipelineText).str(),
2805
2806 if (auto Err = parseLoopPassPipeline(CGPM, *Pipeline))
2807 return Err;
2808
2809 return Error::success();
2810}
2811
2813 StringRef PipelineText) {
2814 auto Pipeline = parsePipelineText(PipelineText);
2815 if (!Pipeline || Pipeline->empty())
2817 formatv("invalid machine pass pipeline '{}'", PipelineText).str(),
2819
2820 if (auto Err = parseMachinePassPipeline(MFPM, *Pipeline))
2821 return Err;
2822
2823 return Error::success();
2824}
2825
2827 // If the pipeline just consists of the word 'default' just replace the AA
2828 // manager with our default one.
2829 if (PipelineText == "default") {
2831 return Error::success();
2832 }
2833
2834 while (!PipelineText.empty()) {
2835 StringRef Name;
2836 std::tie(Name, PipelineText) = PipelineText.split(',');
2837 if (!parseAAPassName(AA, Name))
2839 formatv("unknown alias analysis name '{}'", Name).str(),
2841 }
2842
2843 return Error::success();
2844}
2845
2846std::optional<RegAllocFilterFunc>
2848 if (FilterName == "all")
2849 return nullptr;
2850 for (auto &C : RegClassFilterParsingCallbacks)
2851 if (auto F = C(FilterName))
2852 return F;
2853 return std::nullopt;
2854}
2855
2857 raw_ostream &OS) {
2858 for (StringRef PassName : drop_begin(PassNames))
2859 OS << " " << PassName << '\n';
2860}
2861
2862LLVM_ATTRIBUTE_NOINLINE static void
2864 auto I = PassNames.begin();
2865 auto End = PassNames.end();
2866 ++I;
2867 while (I != End) {
2868 StringRef Name = *I;
2869 ++I;
2870 assert(I != End);
2871 StringRef Params = *I;
2872 ++I;
2873 OS << " " << Name << '<' << Params << ">\n";
2874 }
2875}
2876
2878 // TODO: print pass descriptions when they are available
2879
2880 OS << "Module passes:\n";
2881 static constexpr char ModulePassNames[] = {"\0"
2882#define MODULE_PASS(NAME, CREATE_PASS) NAME "\0"
2883#include "PassRegistry.def"
2884 };
2885 printPassNameList(StringTable(ModulePassNames), OS);
2886
2887 OS << "Module passes with params:\n";
2888 static constexpr char ModulePassNamesWithParams[] = {"\0"
2889#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2890 NAME "\0" PARAMS "\0"
2891#include "PassRegistry.def"
2892 };
2893 printPassNameListWithParams(StringTable(ModulePassNamesWithParams), OS);
2894
2895 OS << "Module analyses:\n";
2896 static constexpr char ModuleAnalysisNames[] = {"\0"
2897#define MODULE_ANALYSIS(NAME, CREATE_PASS) NAME "\0"
2898#include "PassRegistry.def"
2899 };
2900 printPassNameList(StringTable(ModuleAnalysisNames), OS);
2901
2902 OS << "Module alias analyses:\n";
2903 static constexpr char ModuleAliasAnalysisNames[] = {"\0"
2904#define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) NAME "\0"
2905#include "PassRegistry.def"
2906 };
2907 printPassNameList(StringTable(ModuleAliasAnalysisNames), OS);
2908
2909 OS << "CGSCC passes:\n";
2910 static constexpr char CGSCCPassNames[] = {"\0"
2911#define CGSCC_PASS(NAME, CREATE_PASS) NAME "\0"
2912#include "PassRegistry.def"
2913 };
2914 printPassNameList(StringTable(CGSCCPassNames), OS);
2915
2916 OS << "CGSCC passes with params:\n";
2917 static constexpr char CGSCCPassNamesWithParams[] = {"\0"
2918#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2919 NAME "\0" PARAMS "\0"
2920#include "PassRegistry.def"
2921 };
2922 printPassNameListWithParams(StringTable(CGSCCPassNamesWithParams), OS);
2923
2924 OS << "CGSCC analyses:\n";
2925 static constexpr char CGSCCAnalysisNames[] = {"\0"
2926#define CGSCC_ANALYSIS(NAME, CREATE_PASS) NAME "\0"
2927#include "PassRegistry.def"
2928 };
2929 printPassNameList(StringTable(CGSCCAnalysisNames), OS);
2930
2931 OS << "Function passes:\n";
2932 static constexpr char FunctionPassNames[] = {"\0"
2933#define FUNCTION_PASS(NAME, CREATE_PASS) NAME "\0"
2934#include "PassRegistry.def"
2935 };
2936 printPassNameList(StringTable(FunctionPassNames), OS);
2937
2938 OS << "Function passes with params:\n";
2939 static constexpr char FunctionPassNamesWithParams[] = {"\0"
2940#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2941 NAME "\0" PARAMS "\0"
2942#include "PassRegistry.def"
2943 };
2944 printPassNameListWithParams(StringTable(FunctionPassNamesWithParams), OS);
2945
2946 OS << "Function analyses:\n";
2947 static constexpr char FunctionAnalysisNames[] = {"\0"
2948#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) NAME "\0"
2949#include "PassRegistry.def"
2950 };
2951 printPassNameList(StringTable(FunctionAnalysisNames), OS);
2952
2953 OS << "Function alias analyses:\n";
2954 static constexpr char FunctionAliasAnalysisNames[] = {"\0"
2955#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) NAME "\0"
2956#include "PassRegistry.def"
2957 };
2958 printPassNameList(StringTable(FunctionAliasAnalysisNames), OS);
2959
2960 OS << "LoopNest passes:\n";
2961 static constexpr char LoopNestPassNames[] = {"\0"
2962#define LOOPNEST_PASS(NAME, CREATE_PASS) NAME "\0"
2963#include "PassRegistry.def"
2964 };
2965 printPassNameList(StringTable(LoopNestPassNames), OS);
2966
2967 OS << "Loop passes:\n";
2968 static constexpr char LoopPassNames[] = {"\0"
2969#define LOOP_PASS(NAME, CREATE_PASS) NAME "\0"
2970#include "PassRegistry.def"
2971 };
2972 printPassNameList(StringTable(LoopPassNames), OS);
2973
2974 OS << "Loop passes with params:\n";
2975 static constexpr char LoopPassNamesWithParams[] = {"\0"
2976#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2977 NAME "\0" PARAMS "\0"
2978#include "PassRegistry.def"
2979 };
2980 printPassNameListWithParams(StringTable(LoopPassNamesWithParams), OS);
2981
2982 OS << "Loop analyses:\n";
2983 static constexpr char LoopAnalysisNames[] = {"\0"
2984#define LOOP_ANALYSIS(NAME, CREATE_PASS) NAME "\0"
2985#include "PassRegistry.def"
2986 };
2987 printPassNameList(StringTable(LoopAnalysisNames), OS);
2988
2989 OS << "Machine module passes (WIP):\n";
2990 static constexpr char MachineModulePassNames[] = {"\0"
2991#define MACHINE_MODULE_PASS(NAME, CREATE_PASS) NAME "\0"
2992#include "llvm/Passes/MachinePassRegistry.def"
2993 };
2994 printPassNameList(StringTable(MachineModulePassNames), OS);
2995
2996 OS << "Machine function passes (WIP):\n";
2997 static constexpr char MachineFunctionPassNames[] = {"\0"
2998#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) NAME "\0"
2999#include "llvm/Passes/MachinePassRegistry.def"
3000 };
3001 printPassNameList(StringTable(MachineFunctionPassNames), OS);
3002
3003 OS << "Machine function analyses (WIP):\n";
3004 static constexpr char MachineFunctionAnalysisNames[] = {"\0"
3005#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) NAME "\0"
3006#include "llvm/Passes/MachinePassRegistry.def"
3007 };
3008 printPassNameList(StringTable(MachineFunctionAnalysisNames), OS);
3009}
3010
3012 const std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>)>
3013 &C) {
3014 TopLevelPipelineParsingCallbacks.push_back(C);
3015}
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")
Contains definition of the base CFIFixup pass.
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 ...
#define LLVM_ATTRIBUTE_NOINLINE
LLVM_ATTRIBUTE_NOINLINE - On compilers where we have a directive to do so, mark a method "not for inl...
Definition Compiler.h:348
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
#define I(x, y, z)
Definition MD5.cpp:57
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 LLVM_ATTRIBUTE_NOINLINE void printPassNameList(StringTable PassNames, raw_ostream &OS)
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 LLVM_ATTRIBUTE_NOINLINE void printPassNameListWithParams(StringTable PassNames, 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:630
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:736
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:661
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
A table of densely packed, null-terminated strings indexed by offset.
Definition StringTable.h:34
constexpr Iterator begin() const
constexpr Iterator end() const
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.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
Definition STLExtras.h:315
OuterAnalysisManagerProxy< CGSCCAnalysisManager, Function > CGSCCAnalysisManagerFunctionProxy
A proxy from a CGSCCAnalysisManager to a Function.
OuterAnalysisManagerProxy< ModuleAnalysisManager, MachineFunction > ModuleAnalysisManagerMachineFunctionProxy
Provide the ModuleAnalysisManager to Function proxy.
LLVM_ABI cl::opt< std::optional< PrintPipelinePassesFormat >, false, PrintPipelinePassesFormatParser > PrintPipelinePasses
Common option used by multiple tools to print pipeline passes.
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.
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
support::detail::RepeatAdapter< T > fmt_repeat(T &&Item, size_t Count)
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 >
LLVM_ABI void printFormattedPipelinePasses(raw_ostream &OS, StringRef Pipeline, PrintPipelinePassesFormat Format=PrintPipelinePassesFormat::Text)
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1917
PassManager< MachineFunction > MachineFunctionPassManager
Convenience typedef for a pass manager over functions.
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...
PrintPipelinePassesFormat
@ 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:860
#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.
LLVM_ABI bool parse(cl::Option &O, StringRef ArgName, StringRef ArgValue, std::optional< PrintPipelinePassesFormat > &Val)