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