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