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"
53#include "llvm/Analysis/Lint.h"
138#include "llvm/CodeGen/PEI.h"
181#include "llvm/IR/DebugInfo.h"
182#include "llvm/IR/Dominators.h"
183#include "llvm/IR/PassManager.h"
185#include "llvm/IR/Verifier.h"
188#include "llvm/Support/CodeGen.h"
190#include "llvm/Support/Debug.h"
191#include "llvm/Support/Error.h"
194#include "llvm/Support/Regex.h"
384#include <optional>
385
386using namespace llvm;
387
389 "print-pipeline-passes",
390 cl::desc("Print a '-passes' compatible string describing the pipeline "
391 "(best-effort only)."));
392
393AnalysisKey NoOpModuleAnalysis::Key;
394AnalysisKey NoOpCGSCCAnalysis::Key;
395AnalysisKey NoOpFunctionAnalysis::Key;
396AnalysisKey NoOpLoopAnalysis::Key;
397
398namespace {
399
400// Passes for testing crashes.
401// DO NOT USE THIS EXCEPT FOR TESTING!
402class TriggerCrashModulePass : public PassInfoMixin<TriggerCrashModulePass> {
403public:
404 PreservedAnalyses run(Module &, ModuleAnalysisManager &) {
405 abort();
406 return PreservedAnalyses::all();
407 }
408 static StringRef name() { return "TriggerCrashModulePass"; }
409};
410
411class TriggerCrashFunctionPass
412 : public PassInfoMixin<TriggerCrashFunctionPass> {
413public:
414 PreservedAnalyses run(Function &, FunctionAnalysisManager &) {
415 abort();
416 return PreservedAnalyses::all();
417 }
418 static StringRef name() { return "TriggerCrashFunctionPass"; }
419};
420
421// A pass for testing message reporting of -verify-each failures.
422// DO NOT USE THIS EXCEPT FOR TESTING!
423class TriggerVerifierErrorPass
424 : public PassInfoMixin<TriggerVerifierErrorPass> {
425public:
426 PreservedAnalyses run(Module &M, ModuleAnalysisManager &) {
427 // Intentionally break the Module by creating an alias without setting the
428 // aliasee.
429 auto *PtrTy = PointerType::getUnqual(M.getContext());
430 GlobalAlias::create(PtrTy, PtrTy->getAddressSpace(),
431 GlobalValue::LinkageTypes::InternalLinkage,
432 "__bad_alias", nullptr, &M);
434 }
435
436 PreservedAnalyses run(Function &F, FunctionAnalysisManager &) {
437 // Intentionally break the Function by inserting a terminator
438 // instruction in the middle of a basic block.
439 BasicBlock &BB = F.getEntryBlock();
440 new UnreachableInst(F.getContext(), BB.getTerminator()->getIterator());
442 }
443
444 PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &) {
445 // Intentionally create a virtual register and set NoVRegs property.
446 auto &MRI = MF.getRegInfo();
447 MRI.createGenericVirtualRegister(LLT::scalar(8));
448 MF.getProperties().setNoVRegs();
449 return PreservedAnalyses::all();
450 }
451
452 static StringRef name() { return "TriggerVerifierErrorPass"; }
453};
454
455// A pass requires all MachineFunctionProperties.
456// DO NOT USE THIS EXCEPT FOR TESTING!
457class RequireAllMachineFunctionPropertiesPass
458 : public PassInfoMixin<RequireAllMachineFunctionPropertiesPass> {
459public:
460 PreservedAnalyses run(MachineFunction &MF, MachineFunctionAnalysisManager &) {
461 MFPropsModifier _(*this, MF);
463 }
464
465 static MachineFunctionProperties getRequiredProperties() {
466 return MachineFunctionProperties()
467 .setFailedISel()
468 .setFailsVerification()
469 .setIsSSA()
470 .setLegalized()
471 .setNoPHIs()
472 .setNoVRegs()
473 .setRegBankSelected()
474 .setSelected()
475 .setTiedOpsRewritten()
476 .setTracksDebugUserValues()
477 .setTracksLiveness();
478 }
479 static StringRef name() { return "RequireAllMachineFunctionPropertiesPass"; }
480};
481
482} // namespace
483
484static std::optional<OptimizationLevel> parseOptLevel(StringRef S) {
486 .Case("O0", OptimizationLevel::O0)
492 .Default(std::nullopt);
493}
494
496 std::optional<OptimizationLevel> OptLevel = parseOptLevel(S);
497 if (OptLevel)
498 return *OptLevel;
500 formatv("invalid optimization level '{}'", S).str(),
502}
503
505 std::optional<PGOOptions> PGOOpt,
508 : TM(TM), PTO(PTO), PGOOpt(PGOOpt), PIC(PIC), FS(std::move(FS)) {
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 if constexpr (std::is_constructible_v< \
672 std::remove_reference_t<decltype(CREATE_PASS)>, \
673 const TargetMachine &>) { \
674 if (TM) \
675 FAM.registerPass([&] { return CREATE_PASS; }); \
676 } else { \
677 FAM.registerPass([&] { return CREATE_PASS; }); \
678 }
679#include "PassRegistry.def"
680
681 for (auto &C : FunctionAnalysisRegistrationCallbacks)
682 C(FAM);
683}
684
687
688#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
689 MFAM.registerPass([&] { return CREATE_PASS; });
690#include "llvm/Passes/MachinePassRegistry.def"
691
692 for (auto &C : MachineFunctionAnalysisRegistrationCallbacks)
693 C(MFAM);
694}
695
697#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
698 LAM.registerPass([&] { return CREATE_PASS; });
699#include "PassRegistry.def"
700
701 for (auto &C : LoopAnalysisRegistrationCallbacks)
702 C(LAM);
703}
704
705static std::optional<std::pair<bool, bool>>
707 std::pair<bool, bool> Params;
708 if (!Name.consume_front("function"))
709 return std::nullopt;
710 if (Name.empty())
711 return Params;
712 if (!Name.consume_front("<") || !Name.consume_back(">"))
713 return std::nullopt;
714 while (!Name.empty()) {
715 auto [Front, Back] = Name.split(';');
716 Name = Back;
717 if (Front == "eager-inv")
718 Params.first = true;
719 else if (Front == "no-rerun")
720 Params.second = true;
721 else
722 return std::nullopt;
723 }
724 return Params;
725}
726
727static std::optional<int> parseDevirtPassName(StringRef Name) {
728 if (!Name.consume_front("devirt<") || !Name.consume_back(">"))
729 return std::nullopt;
730 int Count;
731 if (Name.getAsInteger(0, Count) || Count < 0)
732 return std::nullopt;
733 return Count;
734}
735
737 StringRef OptionName,
739 bool Result = false;
740 while (!Params.empty()) {
741 StringRef ParamName;
742 std::tie(ParamName, Params) = Params.split(';');
743
744 if (ParamName == OptionName) {
745 Result = true;
746 } else {
748 formatv("invalid {} pass parameter '{}'", PassName, ParamName).str(),
750 }
751 }
752 return Result;
753}
754
755namespace {
756
757/// Parser of parameters for HardwareLoops pass.
758Expected<HardwareLoopOptions> parseHardwareLoopOptions(StringRef Params) {
759 HardwareLoopOptions HardwareLoopOpts;
760
761 while (!Params.empty()) {
762 StringRef ParamName;
763 std::tie(ParamName, Params) = Params.split(';');
764 if (ParamName.consume_front("hardware-loop-decrement=")) {
765 int Count;
766 if (ParamName.getAsInteger(0, Count))
768 formatv("invalid HardwareLoopPass parameter '{}'", ParamName).str(),
770 HardwareLoopOpts.setDecrement(Count);
771 continue;
772 }
773 if (ParamName.consume_front("hardware-loop-counter-bitwidth=")) {
774 int Count;
775 if (ParamName.getAsInteger(0, Count))
777 formatv("invalid HardwareLoopPass parameter '{}'", ParamName).str(),
779 HardwareLoopOpts.setCounterBitwidth(Count);
780 continue;
781 }
782 if (ParamName == "force-hardware-loops") {
783 HardwareLoopOpts.setForce(true);
784 } else if (ParamName == "force-hardware-loop-phi") {
785 HardwareLoopOpts.setForcePhi(true);
786 } else if (ParamName == "force-nested-hardware-loop") {
787 HardwareLoopOpts.setForceNested(true);
788 } else if (ParamName == "force-hardware-loop-guard") {
789 HardwareLoopOpts.setForceGuard(true);
790 } else {
792 formatv("invalid HardwarePass parameter '{}'", ParamName).str(),
794 }
795 }
796 return HardwareLoopOpts;
797}
798
799/// Parser of parameters for Lint pass.
800Expected<bool> parseLintOptions(StringRef Params) {
801 return PassBuilder::parseSinglePassOption(Params, "abort-on-error",
802 "LintPass");
803}
804
805/// Parser of parameters for LoopUnroll pass.
806Expected<LoopUnrollOptions> parseLoopUnrollOptions(StringRef Params) {
807 LoopUnrollOptions UnrollOpts;
808 while (!Params.empty()) {
809 StringRef ParamName;
810 std::tie(ParamName, Params) = Params.split(';');
811 std::optional<OptimizationLevel> OptLevel = parseOptLevel(ParamName);
812 // Don't accept -Os/-Oz.
813 if (OptLevel && !OptLevel->isOptimizingForSize()) {
814 UnrollOpts.setOptLevel(OptLevel->getSpeedupLevel());
815 continue;
816 }
817 if (ParamName.consume_front("full-unroll-max=")) {
818 int Count;
819 if (ParamName.getAsInteger(0, Count))
821 formatv("invalid LoopUnrollPass parameter '{}'", ParamName).str(),
823 UnrollOpts.setFullUnrollMaxCount(Count);
824 continue;
825 }
826
827 bool Enable = !ParamName.consume_front("no-");
828 if (ParamName == "partial") {
829 UnrollOpts.setPartial(Enable);
830 } else if (ParamName == "peeling") {
831 UnrollOpts.setPeeling(Enable);
832 } else if (ParamName == "profile-peeling") {
833 UnrollOpts.setProfileBasedPeeling(Enable);
834 } else if (ParamName == "runtime") {
835 UnrollOpts.setRuntime(Enable);
836 } else if (ParamName == "upperbound") {
837 UnrollOpts.setUpperBound(Enable);
838 } else {
840 formatv("invalid LoopUnrollPass parameter '{}'", ParamName).str(),
842 }
843 }
844 return UnrollOpts;
845}
846
847Expected<bool> parseGlobalDCEPassOptions(StringRef Params) {
849 Params, "vfe-linkage-unit-visibility", "GlobalDCE");
850}
851
852Expected<bool> parseCGProfilePassOptions(StringRef Params) {
853 return PassBuilder::parseSinglePassOption(Params, "in-lto-post-link",
854 "CGProfile");
855}
856
857Expected<bool> parseInlinerPassOptions(StringRef Params) {
858 return PassBuilder::parseSinglePassOption(Params, "only-mandatory",
859 "InlinerPass");
860}
861
862Expected<bool> parseCoroSplitPassOptions(StringRef Params) {
863 return PassBuilder::parseSinglePassOption(Params, "reuse-storage",
864 "CoroSplitPass");
865}
866
867Expected<bool> parsePostOrderFunctionAttrsPassOptions(StringRef Params) {
869 Params, "skip-non-recursive-function-attrs", "PostOrderFunctionAttrs");
870}
871
872Expected<CFGuardPass::Mechanism> parseCFGuardPassOptions(StringRef Params) {
873 if (Params.empty())
875
876 auto [Param, RHS] = Params.split(';');
877 if (!RHS.empty())
879 formatv("too many CFGuardPass parameters '{}'", Params).str(),
881
882 if (Param == "check")
884 if (Param == "dispatch")
886
888 formatv("invalid CFGuardPass mechanism: '{}'", Param).str(),
890}
891
892Expected<bool> parseEarlyCSEPassOptions(StringRef Params) {
893 return PassBuilder::parseSinglePassOption(Params, "memssa", "EarlyCSE");
894}
895
896Expected<bool> parseEntryExitInstrumenterPassOptions(StringRef Params) {
897 return PassBuilder::parseSinglePassOption(Params, "post-inline",
898 "EntryExitInstrumenter");
899}
900
901Expected<bool> parseDropUnnecessaryAssumesPassOptions(StringRef Params) {
902 return PassBuilder::parseSinglePassOption(Params, "drop-deref",
903 "DropUnnecessaryAssumes");
904}
905
906Expected<bool> parseLoopExtractorPassOptions(StringRef Params) {
907 return PassBuilder::parseSinglePassOption(Params, "single", "LoopExtractor");
908}
909
910Expected<bool> parseLowerMatrixIntrinsicsPassOptions(StringRef Params) {
911 return PassBuilder::parseSinglePassOption(Params, "minimal",
912 "LowerMatrixIntrinsics");
913}
914
915Expected<IRNormalizerOptions> parseIRNormalizerPassOptions(StringRef Params) {
917 while (!Params.empty()) {
918 StringRef ParamName;
919 std::tie(ParamName, Params) = Params.split(';');
920
921 bool Enable = !ParamName.consume_front("no-");
922 if (ParamName == "preserve-order")
923 Result.PreserveOrder = Enable;
924 else if (ParamName == "rename-all")
925 Result.RenameAll = Enable;
926 else if (ParamName == "fold-all") // FIXME: Name mismatch
927 Result.FoldPreOutputs = Enable;
928 else if (ParamName == "reorder-operands")
929 Result.ReorderOperands = Enable;
930 else {
932 formatv("invalid normalize pass parameter '{}'", ParamName).str(),
934 }
935 }
936
937 return Result;
938}
939
940Expected<AddressSanitizerOptions> parseASanPassOptions(StringRef Params) {
942 while (!Params.empty()) {
943 StringRef ParamName;
944 std::tie(ParamName, Params) = Params.split(';');
945
946 if (ParamName == "kernel") {
947 Result.CompileKernel = true;
948 } else if (ParamName == "use-after-scope") {
949 Result.UseAfterScope = true;
950 } else {
952 formatv("invalid AddressSanitizer pass parameter '{}'", ParamName)
953 .str(),
955 }
956 }
957 return Result;
958}
959
960Expected<HWAddressSanitizerOptions> parseHWASanPassOptions(StringRef Params) {
962 while (!Params.empty()) {
963 StringRef ParamName;
964 std::tie(ParamName, Params) = Params.split(';');
965
966 if (ParamName == "recover") {
967 Result.Recover = true;
968 } else if (ParamName == "kernel") {
969 Result.CompileKernel = true;
970 } else {
972 formatv("invalid HWAddressSanitizer pass parameter '{}'", ParamName)
973 .str(),
975 }
976 }
977 return Result;
978}
979
980Expected<EmbedBitcodeOptions> parseEmbedBitcodePassOptions(StringRef Params) {
982 while (!Params.empty()) {
983 StringRef ParamName;
984 std::tie(ParamName, Params) = Params.split(';');
985
986 if (ParamName == "thinlto") {
987 Result.IsThinLTO = true;
988 } else if (ParamName == "emit-summary") {
989 Result.EmitLTOSummary = true;
990 } else {
992 formatv("invalid EmbedBitcode pass parameter '{}'", ParamName).str(),
994 }
995 }
996 return Result;
997}
998
1000parseLowerAllowCheckPassOptions(StringRef Params) {
1002 while (!Params.empty()) {
1003 StringRef ParamName;
1004 std::tie(ParamName, Params) = Params.split(';');
1005
1006 // Format is <cutoffs[1,2,3]=70000;cutoffs[5,6,8]=90000>
1007 //
1008 // Parsing allows duplicate indices (last one takes precedence).
1009 // It would technically be in spec to specify
1010 // cutoffs[0]=70000,cutoffs[1]=90000,cutoffs[0]=80000,...
1011 if (ParamName.starts_with("cutoffs[")) {
1012 StringRef IndicesStr;
1013 StringRef CutoffStr;
1014
1015 std::tie(IndicesStr, CutoffStr) = ParamName.split("]=");
1016 // cutoffs[1,2,3
1017 // 70000
1018
1019 int cutoff;
1020 if (CutoffStr.getAsInteger(0, cutoff))
1022 formatv("invalid LowerAllowCheck pass cutoffs parameter '{}' ({})",
1023 CutoffStr, Params)
1024 .str(),
1026
1027 if (!IndicesStr.consume_front("cutoffs[") || IndicesStr == "")
1029 formatv("invalid LowerAllowCheck pass index parameter '{}' ({})",
1030 IndicesStr, CutoffStr)
1031 .str(),
1033
1034 while (IndicesStr != "") {
1035 StringRef firstIndexStr;
1036 std::tie(firstIndexStr, IndicesStr) = IndicesStr.split('|');
1037
1038 unsigned int index;
1039 if (firstIndexStr.getAsInteger(0, index))
1041 formatv(
1042 "invalid LowerAllowCheck pass index parameter '{}' ({}) {}",
1043 firstIndexStr, IndicesStr)
1044 .str(),
1046
1047 // In the common case (sequentially increasing indices), we will issue
1048 // O(n) resize requests. We assume the underlying data structure has
1049 // O(1) runtime for each added element.
1050 if (index >= Result.cutoffs.size())
1051 Result.cutoffs.resize(index + 1, 0);
1052
1053 Result.cutoffs[index] = cutoff;
1054 }
1055 } else if (ParamName.starts_with("runtime_check")) {
1056 StringRef ValueString;
1057 std::tie(std::ignore, ValueString) = ParamName.split("=");
1058 int runtime_check;
1059 if (ValueString.getAsInteger(0, runtime_check)) {
1061 formatv("invalid LowerAllowCheck pass runtime_check parameter '{}' "
1062 "({})",
1063 ValueString, Params)
1064 .str(),
1066 }
1067 Result.runtime_check = runtime_check;
1068 } else {
1070 formatv("invalid LowerAllowCheck pass parameter '{}'", ParamName)
1071 .str(),
1073 }
1074 }
1075
1076 return Result;
1077}
1078
1079Expected<MemorySanitizerOptions> parseMSanPassOptions(StringRef Params) {
1081 while (!Params.empty()) {
1082 StringRef ParamName;
1083 std::tie(ParamName, Params) = Params.split(';');
1084
1085 if (ParamName == "recover") {
1086 Result.Recover = true;
1087 } else if (ParamName == "kernel") {
1088 Result.Kernel = true;
1089 } else if (ParamName.consume_front("track-origins=")) {
1090 if (ParamName.getAsInteger(0, Result.TrackOrigins))
1092 formatv("invalid argument to MemorySanitizer pass track-origins "
1093 "parameter: '{}'",
1094 ParamName)
1095 .str(),
1097 } else if (ParamName == "eager-checks") {
1098 Result.EagerChecks = true;
1099 } else {
1101 formatv("invalid MemorySanitizer pass parameter '{}'", ParamName)
1102 .str(),
1104 }
1105 }
1106 return Result;
1107}
1108
1109Expected<AllocTokenOptions> parseAllocTokenPassOptions(StringRef Params) {
1111 while (!Params.empty()) {
1112 StringRef ParamName;
1113 std::tie(ParamName, Params) = Params.split(';');
1114
1115 if (ParamName.consume_front("mode=")) {
1116 if (auto Mode = getAllocTokenModeFromString(ParamName))
1117 Result.Mode = *Mode;
1118 else
1120 formatv("invalid argument to AllocToken pass mode "
1121 "parameter: '{}'",
1122 ParamName)
1123 .str(),
1125 } else {
1127 formatv("invalid AllocToken pass parameter '{}'", ParamName).str(),
1129 }
1130 }
1131 return Result;
1132}
1133
1134/// Parser of parameters for SimplifyCFG pass.
1135Expected<SimplifyCFGOptions> parseSimplifyCFGOptions(StringRef Params) {
1137 while (!Params.empty()) {
1138 StringRef ParamName;
1139 std::tie(ParamName, Params) = Params.split(';');
1140
1141 bool Enable = !ParamName.consume_front("no-");
1142 if (ParamName == "speculate-blocks") {
1143 Result.speculateBlocks(Enable);
1144 } else if (ParamName == "simplify-cond-branch") {
1145 Result.setSimplifyCondBranch(Enable);
1146 } else if (ParamName == "forward-switch-cond") {
1147 Result.forwardSwitchCondToPhi(Enable);
1148 } else if (ParamName == "switch-range-to-icmp") {
1149 Result.convertSwitchRangeToICmp(Enable);
1150 } else if (ParamName == "switch-to-arithmetic") {
1151 Result.convertSwitchToArithmetic(Enable);
1152 } else if (ParamName == "switch-to-lookup") {
1153 Result.convertSwitchToLookupTable(Enable);
1154 } else if (ParamName == "keep-loops") {
1155 Result.needCanonicalLoops(Enable);
1156 } else if (ParamName == "hoist-common-insts") {
1157 Result.hoistCommonInsts(Enable);
1158 } else if (ParamName == "hoist-loads-stores-with-cond-faulting") {
1159 Result.hoistLoadsStoresWithCondFaulting(Enable);
1160 } else if (ParamName == "sink-common-insts") {
1161 Result.sinkCommonInsts(Enable);
1162 } else if (ParamName == "speculate-unpredictables") {
1163 Result.speculateUnpredictables(Enable);
1164 } else if (Enable && ParamName.consume_front("bonus-inst-threshold=")) {
1165 APInt BonusInstThreshold;
1166 if (ParamName.getAsInteger(0, BonusInstThreshold))
1168 formatv("invalid argument to SimplifyCFG pass bonus-threshold "
1169 "parameter: '{}'",
1170 ParamName)
1171 .str(),
1173 Result.bonusInstThreshold(BonusInstThreshold.getSExtValue());
1174 } else {
1176 formatv("invalid SimplifyCFG pass parameter '{}'", ParamName).str(),
1178 }
1179 }
1180 return Result;
1181}
1182
1183Expected<InstCombineOptions> parseInstCombineOptions(StringRef Params) {
1185 // When specifying "instcombine" in -passes enable fix-point verification by
1186 // default, as this is what most tests should use.
1187 Result.setVerifyFixpoint(true);
1188 while (!Params.empty()) {
1189 StringRef ParamName;
1190 std::tie(ParamName, Params) = Params.split(';');
1191
1192 bool Enable = !ParamName.consume_front("no-");
1193 if (ParamName == "verify-fixpoint") {
1194 Result.setVerifyFixpoint(Enable);
1195 } else if (Enable && ParamName.consume_front("max-iterations=")) {
1196 APInt MaxIterations;
1197 if (ParamName.getAsInteger(0, MaxIterations))
1199 formatv("invalid argument to InstCombine pass max-iterations "
1200 "parameter: '{}'",
1201 ParamName)
1202 .str(),
1204 Result.setMaxIterations((unsigned)MaxIterations.getZExtValue());
1205 } else {
1207 formatv("invalid InstCombine pass parameter '{}'", ParamName).str(),
1209 }
1210 }
1211 return Result;
1212}
1213
1214/// Parser of parameters for LoopVectorize pass.
1215Expected<LoopVectorizeOptions> parseLoopVectorizeOptions(StringRef Params) {
1217 while (!Params.empty()) {
1218 StringRef ParamName;
1219 std::tie(ParamName, Params) = Params.split(';');
1220
1221 bool Enable = !ParamName.consume_front("no-");
1222 if (ParamName == "interleave-forced-only") {
1224 } else if (ParamName == "vectorize-forced-only") {
1226 } else {
1228 formatv("invalid LoopVectorize parameter '{}'", ParamName).str(),
1230 }
1231 }
1232 return Opts;
1233}
1234
1235Expected<std::pair<bool, bool>> parseLoopUnswitchOptions(StringRef Params) {
1236 std::pair<bool, bool> Result = {false, true};
1237 while (!Params.empty()) {
1238 StringRef ParamName;
1239 std::tie(ParamName, Params) = Params.split(';');
1240
1241 bool Enable = !ParamName.consume_front("no-");
1242 if (ParamName == "nontrivial") {
1243 Result.first = Enable;
1244 } else if (ParamName == "trivial") {
1245 Result.second = Enable;
1246 } else {
1248 formatv("invalid LoopUnswitch pass parameter '{}'", ParamName).str(),
1250 }
1251 }
1252 return Result;
1253}
1254
1255Expected<LICMOptions> parseLICMOptions(StringRef Params) {
1257 while (!Params.empty()) {
1258 StringRef ParamName;
1259 std::tie(ParamName, Params) = Params.split(';');
1260
1261 bool Enable = !ParamName.consume_front("no-");
1262 if (ParamName == "allowspeculation") {
1263 Result.AllowSpeculation = Enable;
1264 } else {
1266 formatv("invalid LICM pass parameter '{}'", ParamName).str(),
1268 }
1269 }
1270 return Result;
1271}
1272
1273Expected<std::pair<bool, bool>> parseLoopRotateOptions(StringRef Params) {
1274 std::pair<bool, bool> Result = {true, false};
1275 while (!Params.empty()) {
1276 StringRef ParamName;
1277 std::tie(ParamName, Params) = Params.split(';');
1278
1279 bool Enable = !ParamName.consume_front("no-");
1280 if (ParamName == "header-duplication") {
1281 Result.first = Enable;
1282 } else if (ParamName == "prepare-for-lto") {
1283 Result.second = Enable;
1284 } else {
1286 formatv("invalid LoopRotate pass parameter '{}'", ParamName).str(),
1288 }
1289 }
1290 return Result;
1291}
1292
1293Expected<bool> parseMergedLoadStoreMotionOptions(StringRef Params) {
1294 bool Result = false;
1295 while (!Params.empty()) {
1296 StringRef ParamName;
1297 std::tie(ParamName, Params) = Params.split(';');
1298
1299 bool Enable = !ParamName.consume_front("no-");
1300 if (ParamName == "split-footer-bb") {
1301 Result = Enable;
1302 } else {
1304 formatv("invalid MergedLoadStoreMotion pass parameter '{}'",
1305 ParamName)
1306 .str(),
1308 }
1309 }
1310 return Result;
1311}
1312
1313Expected<GVNOptions> parseGVNOptions(StringRef Params) {
1315 while (!Params.empty()) {
1316 StringRef ParamName;
1317 std::tie(ParamName, Params) = Params.split(';');
1318
1319 bool Enable = !ParamName.consume_front("no-");
1320 if (ParamName == "pre") {
1321 Result.setPRE(Enable);
1322 } else if (ParamName == "load-pre") {
1323 Result.setLoadPRE(Enable);
1324 } else if (ParamName == "split-backedge-load-pre") {
1325 Result.setLoadPRESplitBackedge(Enable);
1326 } else if (ParamName == "memdep") {
1327 // MemDep and MemorySSA are mutually exclusive.
1328 Result.setMemDep(Enable);
1329 Result.setMemorySSA(!Enable);
1330 } else if (ParamName == "memoryssa") {
1331 // MemDep and MemorySSA are mutually exclusive.
1332 Result.setMemorySSA(Enable);
1333 Result.setMemDep(!Enable);
1334 } else {
1336 formatv("invalid GVN pass parameter '{}'", ParamName).str(),
1338 }
1339 }
1340 return Result;
1341}
1342
1343Expected<IPSCCPOptions> parseIPSCCPOptions(StringRef Params) {
1345 while (!Params.empty()) {
1346 StringRef ParamName;
1347 std::tie(ParamName, Params) = Params.split(';');
1348
1349 bool Enable = !ParamName.consume_front("no-");
1350 if (ParamName == "func-spec")
1351 Result.setFuncSpec(Enable);
1352 else
1354 formatv("invalid IPSCCP pass parameter '{}'", ParamName).str(),
1356 }
1357 return Result;
1358}
1359
1360Expected<ScalarizerPassOptions> parseScalarizerOptions(StringRef Params) {
1362 while (!Params.empty()) {
1363 StringRef ParamName;
1364 std::tie(ParamName, Params) = Params.split(';');
1365
1366 if (ParamName.consume_front("min-bits=")) {
1367 if (ParamName.getAsInteger(0, Result.ScalarizeMinBits)) {
1369 formatv("invalid argument to Scalarizer pass min-bits "
1370 "parameter: '{}'",
1371 ParamName)
1372 .str(),
1374 }
1375
1376 continue;
1377 }
1378
1379 bool Enable = !ParamName.consume_front("no-");
1380 if (ParamName == "load-store")
1381 Result.ScalarizeLoadStore = Enable;
1382 else if (ParamName == "variable-insert-extract")
1383 Result.ScalarizeVariableInsertExtract = Enable;
1384 else {
1386 formatv("invalid Scalarizer pass parameter '{}'", ParamName).str(),
1388 }
1389 }
1390
1391 return Result;
1392}
1393
1394Expected<SROAOptions> parseSROAOptions(StringRef Params) {
1395 if (Params.empty() || Params == "modify-cfg")
1397 if (Params == "preserve-cfg")
1400 formatv("invalid SROA pass parameter '{}' (either preserve-cfg or "
1401 "modify-cfg can be specified)",
1402 Params)
1403 .str(),
1405}
1406
1408parseStackLifetimeOptions(StringRef Params) {
1410 while (!Params.empty()) {
1411 StringRef ParamName;
1412 std::tie(ParamName, Params) = Params.split(';');
1413
1414 if (ParamName == "may") {
1416 } else if (ParamName == "must") {
1418 } else {
1420 formatv("invalid StackLifetime parameter '{}'", ParamName).str(),
1422 }
1423 }
1424 return Result;
1425}
1426
1427Expected<bool> parseDependenceAnalysisPrinterOptions(StringRef Params) {
1428 return PassBuilder::parseSinglePassOption(Params, "normalized-results",
1429 "DependenceAnalysisPrinter");
1430}
1431
1432Expected<bool> parseSeparateConstOffsetFromGEPPassOptions(StringRef Params) {
1433 return PassBuilder::parseSinglePassOption(Params, "lower-gep",
1434 "SeparateConstOffsetFromGEP");
1435}
1436
1437Expected<bool> parseStructurizeCFGPassOptions(StringRef Params) {
1438 return PassBuilder::parseSinglePassOption(Params, "skip-uniform-regions",
1439 "StructurizeCFG");
1440}
1441
1443parseFunctionSimplificationPipelineOptions(StringRef Params) {
1444 std::optional<OptimizationLevel> L = parseOptLevel(Params);
1445 if (!L || *L == OptimizationLevel::O0) {
1447 formatv("invalid function-simplification parameter '{}'", Params).str(),
1449 };
1450 return *L;
1451}
1452
1453Expected<bool> parseMemorySSAPrinterPassOptions(StringRef Params) {
1454 return PassBuilder::parseSinglePassOption(Params, "no-ensure-optimized-uses",
1455 "MemorySSAPrinterPass");
1456}
1457
1458Expected<bool> parseSpeculativeExecutionPassOptions(StringRef Params) {
1459 return PassBuilder::parseSinglePassOption(Params, "only-if-divergent-target",
1460 "SpeculativeExecutionPass");
1461}
1462
1463Expected<std::string> parseMemProfUsePassOptions(StringRef Params) {
1464 std::string Result;
1465 while (!Params.empty()) {
1466 StringRef ParamName;
1467 std::tie(ParamName, Params) = Params.split(';');
1468
1469 if (ParamName.consume_front("profile-filename=")) {
1470 Result = ParamName.str();
1471 } else {
1473 formatv("invalid MemProfUse pass parameter '{}'", ParamName).str(),
1475 }
1476 }
1477 return Result;
1478}
1479
1481parseStructuralHashPrinterPassOptions(StringRef Params) {
1482 if (Params.empty())
1484 if (Params == "detailed")
1486 if (Params == "call-target-ignored")
1489 formatv("invalid structural hash printer parameter '{}'", Params).str(),
1491}
1492
1493Expected<bool> parseWinEHPrepareOptions(StringRef Params) {
1494 return PassBuilder::parseSinglePassOption(Params, "demote-catchswitch-only",
1495 "WinEHPreparePass");
1496}
1497
1498Expected<GlobalMergeOptions> parseGlobalMergeOptions(StringRef Params) {
1500 while (!Params.empty()) {
1501 StringRef ParamName;
1502 std::tie(ParamName, Params) = Params.split(';');
1503
1504 bool Enable = !ParamName.consume_front("no-");
1505 if (ParamName == "group-by-use")
1506 Result.GroupByUse = Enable;
1507 else if (ParamName == "ignore-single-use")
1508 Result.IgnoreSingleUse = Enable;
1509 else if (ParamName == "merge-const")
1510 Result.MergeConstantGlobals = Enable;
1511 else if (ParamName == "merge-const-aggressive")
1512 Result.MergeConstAggressive = Enable;
1513 else if (ParamName == "merge-external")
1514 Result.MergeExternal = Enable;
1515 else if (ParamName.consume_front("max-offset=")) {
1516 if (ParamName.getAsInteger(0, Result.MaxOffset))
1518 formatv("invalid GlobalMergePass parameter '{}'", ParamName).str(),
1520 } else {
1522 formatv("invalid global-merge pass parameter '{}'", Params).str(),
1524 }
1525 }
1526 return Result;
1527}
1528
1529Expected<SmallVector<std::string, 0>> parseInternalizeGVs(StringRef Params) {
1530 SmallVector<std::string, 1> PreservedGVs;
1531 while (!Params.empty()) {
1532 StringRef ParamName;
1533 std::tie(ParamName, Params) = Params.split(';');
1534
1535 if (ParamName.consume_front("preserve-gv=")) {
1536 PreservedGVs.push_back(ParamName.str());
1537 } else {
1539 formatv("invalid Internalize pass parameter '{}'", ParamName).str(),
1541 }
1542 }
1543
1544 return Expected<SmallVector<std::string, 0>>(std::move(PreservedGVs));
1545}
1546
1548parseRegAllocFastPassOptions(PassBuilder &PB, StringRef Params) {
1550 while (!Params.empty()) {
1551 StringRef ParamName;
1552 std::tie(ParamName, Params) = Params.split(';');
1553
1554 if (ParamName.consume_front("filter=")) {
1555 std::optional<RegAllocFilterFunc> Filter =
1556 PB.parseRegAllocFilter(ParamName);
1557 if (!Filter) {
1559 formatv("invalid regallocfast register filter '{}'", ParamName)
1560 .str(),
1562 }
1563 Opts.Filter = *Filter;
1564 Opts.FilterName = ParamName;
1565 continue;
1566 }
1567
1568 if (ParamName == "no-clear-vregs") {
1569 Opts.ClearVRegs = false;
1570 continue;
1571 }
1572
1574 formatv("invalid regallocfast pass parameter '{}'", ParamName).str(),
1576 }
1577 return Opts;
1578}
1579
1581parseBoundsCheckingOptions(StringRef Params) {
1583 while (!Params.empty()) {
1584 StringRef ParamName;
1585 std::tie(ParamName, Params) = Params.split(';');
1586 if (ParamName == "trap") {
1587 Options.Rt = std::nullopt;
1588 } else if (ParamName == "rt") {
1589 Options.Rt = {
1590 /*MinRuntime=*/false,
1591 /*MayReturn=*/true,
1592 /*HandlerPreserveAllRegs=*/false,
1593 };
1594 } else if (ParamName == "rt-abort") {
1595 Options.Rt = {
1596 /*MinRuntime=*/false,
1597 /*MayReturn=*/false,
1598 /*HandlerPreserveAllRegs=*/false,
1599 };
1600 } else if (ParamName == "min-rt") {
1601 Options.Rt = {
1602 /*MinRuntime=*/true,
1603 /*MayReturn=*/true,
1604 /*HandlerPreserveAllRegs=*/false,
1605 };
1606 } else if (ParamName == "min-rt-abort") {
1607 Options.Rt = {
1608 /*MinRuntime=*/true,
1609 /*MayReturn=*/false,
1610 /*HandlerPreserveAllRegs=*/false,
1611 };
1612 } else if (ParamName == "merge") {
1613 Options.Merge = true;
1614 } else if (ParamName == "handler-preserve-all-regs") {
1615 if (Options.Rt)
1616 Options.Rt->HandlerPreserveAllRegs = true;
1617 } else {
1618 StringRef ParamEQ;
1619 StringRef Val;
1620 std::tie(ParamEQ, Val) = ParamName.split('=');
1621 int8_t Id;
1622 if (ParamEQ == "guard" && !Val.getAsInteger(0, Id)) {
1623 Options.GuardKind = Id;
1624 } else {
1626 formatv("invalid BoundsChecking pass parameter '{}'", ParamName)
1627 .str(),
1629 }
1630 }
1631 }
1632 return Options;
1633}
1634
1635Expected<CodeGenOptLevel> parseExpandFpOptions(StringRef Param) {
1636 if (Param.empty())
1637 return CodeGenOptLevel::None;
1638
1639 // Parse a CodeGenOptLevel, e.g. "O1", "O2", "O3".
1640 auto [Prefix, Digit] = Param.split('O');
1641
1642 uint8_t N;
1643 if (!Prefix.empty() || Digit.getAsInteger(10, N))
1644 return createStringError("invalid expand-fp pass parameter '%s'",
1645 Param.str().c_str());
1646
1647 std::optional<CodeGenOptLevel> Level = CodeGenOpt::getLevel(N);
1648 if (!Level.has_value())
1649 return createStringError(
1650 "invalid optimization level for expand-fp pass: %s",
1651 Digit.str().c_str());
1652
1653 return *Level;
1654}
1655
1657parseRegAllocGreedyFilterFunc(PassBuilder &PB, StringRef Params) {
1658 if (Params.empty() || Params == "all")
1659 return RAGreedyPass::Options();
1660
1661 std::optional<RegAllocFilterFunc> Filter = PB.parseRegAllocFilter(Params);
1662 if (Filter)
1663 return RAGreedyPass::Options{*Filter, Params};
1664
1666 formatv("invalid regallocgreedy register filter '{}'", Params).str(),
1668}
1669
1670Expected<bool> parseMachineSinkingPassOptions(StringRef Params) {
1671 return PassBuilder::parseSinglePassOption(Params, "enable-sink-fold",
1672 "MachineSinkingPass");
1673}
1674
1675Expected<bool> parseMachineBlockPlacementPassOptions(StringRef Params) {
1676 bool AllowTailMerge = true;
1677 if (!Params.empty()) {
1678 AllowTailMerge = !Params.consume_front("no-");
1679 if (Params != "tail-merge")
1681 formatv("invalid MachineBlockPlacementPass parameter '{}'", Params)
1682 .str(),
1684 }
1685 return AllowTailMerge;
1686}
1687
1688Expected<bool> parseVirtRegRewriterPassOptions(StringRef Params) {
1689 bool ClearVirtRegs = true;
1690 if (!Params.empty()) {
1691 ClearVirtRegs = !Params.consume_front("no-");
1692 if (Params != "clear-vregs")
1694 formatv("invalid VirtRegRewriter pass parameter '{}'", Params).str(),
1696 }
1697 return ClearVirtRegs;
1698}
1699
1700struct FatLTOOptions {
1701 OptimizationLevel OptLevel;
1702 bool ThinLTO = false;
1703 bool EmitSummary = false;
1704};
1705
1706Expected<FatLTOOptions> parseFatLTOOptions(StringRef Params) {
1707 FatLTOOptions Result;
1708 bool HaveOptLevel = false;
1709 while (!Params.empty()) {
1710 StringRef ParamName;
1711 std::tie(ParamName, Params) = Params.split(';');
1712
1713 if (ParamName == "thinlto") {
1714 Result.ThinLTO = true;
1715 } else if (ParamName == "emit-summary") {
1716 Result.EmitSummary = true;
1717 } else if (std::optional<OptimizationLevel> OptLevel =
1718 parseOptLevel(ParamName)) {
1719 Result.OptLevel = *OptLevel;
1720 HaveOptLevel = true;
1721 } else {
1723 formatv("invalid fatlto-pre-link pass parameter '{}'", ParamName)
1724 .str(),
1726 }
1727 }
1728 if (!HaveOptLevel)
1730 "missing optimization level for fatlto-pre-link pipeline",
1732 return Result;
1733}
1734
1735} // namespace
1736
1737/// Tests whether registered callbacks will accept a given pass name.
1738///
1739/// When parsing a pipeline text, the type of the outermost pipeline may be
1740/// omitted, in which case the type is automatically determined from the first
1741/// pass name in the text. This may be a name that is handled through one of the
1742/// callbacks. We check this through the oridinary parsing callbacks by setting
1743/// up a dummy PassManager in order to not force the client to also handle this
1744/// type of query.
1745template <typename PassManagerT, typename CallbacksT>
1746static bool callbacksAcceptPassName(StringRef Name, CallbacksT &Callbacks) {
1747 if (!Callbacks.empty()) {
1748 PassManagerT DummyPM;
1749 for (auto &CB : Callbacks)
1750 if (CB(Name, DummyPM, {}))
1751 return true;
1752 }
1753 return false;
1754}
1755
1756template <typename CallbacksT>
1757static bool isModulePassName(StringRef Name, CallbacksT &Callbacks) {
1758 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1759
1760 // Explicitly handle pass manager names.
1761 if (Name == "module")
1762 return true;
1763 if (Name == "cgscc")
1764 return true;
1765 if (NameNoBracket == "function")
1766 return true;
1767 if (Name == "coro-cond")
1768 return true;
1769
1770#define MODULE_PASS(NAME, CREATE_PASS) \
1771 if (Name == NAME) \
1772 return true;
1773#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1774 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1775 return true;
1776#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
1777 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1778 return true;
1779#include "PassRegistry.def"
1780
1781 return callbacksAcceptPassName<ModulePassManager>(Name, Callbacks);
1782}
1783
1784template <typename CallbacksT>
1785static bool isCGSCCPassName(StringRef Name, CallbacksT &Callbacks) {
1786 // Explicitly handle pass manager names.
1787 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1788 if (Name == "cgscc")
1789 return true;
1790 if (NameNoBracket == "function")
1791 return true;
1792
1793 // Explicitly handle custom-parsed pass names.
1794 if (parseDevirtPassName(Name))
1795 return true;
1796
1797#define CGSCC_PASS(NAME, CREATE_PASS) \
1798 if (Name == NAME) \
1799 return true;
1800#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1801 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1802 return true;
1803#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
1804 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1805 return true;
1806#include "PassRegistry.def"
1807
1808 return callbacksAcceptPassName<CGSCCPassManager>(Name, Callbacks);
1809}
1810
1811template <typename CallbacksT>
1812static bool isFunctionPassName(StringRef Name, CallbacksT &Callbacks) {
1813 // Explicitly handle pass manager names.
1814 StringRef NameNoBracket = Name.take_until([](char C) { return C == '<'; });
1815 if (NameNoBracket == "function")
1816 return true;
1817 if (Name == "loop" || Name == "loop-mssa" || Name == "machine-function")
1818 return true;
1819
1820#define FUNCTION_PASS(NAME, CREATE_PASS) \
1821 if (Name == NAME) \
1822 return true;
1823#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1824 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1825 return true;
1826#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1827 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1828 return true;
1829#include "PassRegistry.def"
1830
1831 return callbacksAcceptPassName<FunctionPassManager>(Name, Callbacks);
1832}
1833
1834template <typename CallbacksT>
1835static bool isMachineFunctionPassName(StringRef Name, CallbacksT &Callbacks) {
1836 // Explicitly handle pass manager names.
1837 if (Name == "machine-function")
1838 return true;
1839
1840#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
1841 if (Name == NAME) \
1842 return true;
1843#define MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, \
1844 PARAMS) \
1845 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1846 return true;
1847
1848#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
1849 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1850 return true;
1851
1852#include "llvm/Passes/MachinePassRegistry.def"
1853
1855}
1856
1857template <typename CallbacksT>
1858static bool isLoopNestPassName(StringRef Name, CallbacksT &Callbacks,
1859 bool &UseMemorySSA) {
1860 UseMemorySSA = false;
1861
1862 if (PassBuilder::checkParametrizedPassName(Name, "lnicm")) {
1863 UseMemorySSA = true;
1864 return true;
1865 }
1866
1867#define LOOPNEST_PASS(NAME, CREATE_PASS) \
1868 if (Name == NAME) \
1869 return true;
1870#include "PassRegistry.def"
1871
1872 return callbacksAcceptPassName<LoopPassManager>(Name, Callbacks);
1873}
1874
1875template <typename CallbacksT>
1876static bool isLoopPassName(StringRef Name, CallbacksT &Callbacks,
1877 bool &UseMemorySSA) {
1878 UseMemorySSA = false;
1879
1880 if (PassBuilder::checkParametrizedPassName(Name, "licm")) {
1881 UseMemorySSA = true;
1882 return true;
1883 }
1884
1885#define LOOP_PASS(NAME, CREATE_PASS) \
1886 if (Name == NAME) \
1887 return true;
1888#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
1889 if (PassBuilder::checkParametrizedPassName(Name, NAME)) \
1890 return true;
1891#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
1892 if (Name == "require<" NAME ">" || Name == "invalidate<" NAME ">") \
1893 return true;
1894#include "PassRegistry.def"
1895
1896 return callbacksAcceptPassName<LoopPassManager>(Name, Callbacks);
1897}
1898
1899std::optional<std::vector<PassBuilder::PipelineElement>>
1900PassBuilder::parsePipelineText(StringRef Text) {
1901 std::vector<PipelineElement> ResultPipeline;
1902
1903 SmallVector<std::vector<PipelineElement> *, 4> PipelineStack = {
1904 &ResultPipeline};
1905 for (;;) {
1906 std::vector<PipelineElement> &Pipeline = *PipelineStack.back();
1907 size_t Pos = Text.find_first_of(",()");
1908 Pipeline.push_back({Text.substr(0, Pos), {}});
1909
1910 // If we have a single terminating name, we're done.
1911 if (Pos == Text.npos)
1912 break;
1913
1914 char Sep = Text[Pos];
1915 Text = Text.substr(Pos + 1);
1916 if (Sep == ',')
1917 // Just a name ending in a comma, continue.
1918 continue;
1919
1920 if (Sep == '(') {
1921 // Push the inner pipeline onto the stack to continue processing.
1922 PipelineStack.push_back(&Pipeline.back().InnerPipeline);
1923 continue;
1924 }
1925
1926 assert(Sep == ')' && "Bogus separator!");
1927 // When handling the close parenthesis, we greedily consume them to avoid
1928 // empty strings in the pipeline.
1929 do {
1930 // If we try to pop the outer pipeline we have unbalanced parentheses.
1931 if (PipelineStack.size() == 1)
1932 return std::nullopt;
1933
1934 PipelineStack.pop_back();
1935 } while (Text.consume_front(")"));
1936
1937 // Check if we've finished parsing.
1938 if (Text.empty())
1939 break;
1940
1941 // Otherwise, the end of an inner pipeline always has to be followed by
1942 // a comma, and then we can continue.
1943 if (!Text.consume_front(","))
1944 return std::nullopt;
1945 }
1946
1947 if (PipelineStack.size() > 1)
1948 // Unbalanced paretheses.
1949 return std::nullopt;
1950
1951 assert(PipelineStack.back() == &ResultPipeline &&
1952 "Wrong pipeline at the bottom of the stack!");
1953 return {std::move(ResultPipeline)};
1954}
1955
1958 // This is consistent with old pass manager invoked via opt, but
1959 // inconsistent with clang. Clang doesn't enable loop vectorization
1960 // but does enable slp vectorization at Oz.
1961 PTO.LoopVectorization = L.getSpeedupLevel() > 1 && L != OptimizationLevel::Oz;
1962 PTO.SLPVectorization = L.getSpeedupLevel() > 1 && L != OptimizationLevel::Oz;
1963}
1964
1965Error PassBuilder::parseModulePass(ModulePassManager &MPM,
1966 const PipelineElement &E) {
1967 auto &Name = E.Name;
1968 auto &InnerPipeline = E.InnerPipeline;
1969
1970 // First handle complex passes like the pass managers which carry pipelines.
1971 if (!InnerPipeline.empty()) {
1972 if (Name == "module") {
1973 ModulePassManager NestedMPM;
1974 if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline))
1975 return Err;
1976 MPM.addPass(std::move(NestedMPM));
1977 return Error::success();
1978 }
1979 if (Name == "coro-cond") {
1980 ModulePassManager NestedMPM;
1981 if (auto Err = parseModulePassPipeline(NestedMPM, InnerPipeline))
1982 return Err;
1983 MPM.addPass(CoroConditionalWrapper(std::move(NestedMPM)));
1984 return Error::success();
1985 }
1986 if (Name == "cgscc") {
1987 CGSCCPassManager CGPM;
1988 if (auto Err = parseCGSCCPassPipeline(CGPM, InnerPipeline))
1989 return Err;
1991 return Error::success();
1992 }
1993 if (auto Params = parseFunctionPipelineName(Name)) {
1994 if (Params->second)
1996 "cannot have a no-rerun module to function adaptor",
1999 if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline))
2000 return Err;
2001 MPM.addPass(
2002 createModuleToFunctionPassAdaptor(std::move(FPM), Params->first));
2003 return Error::success();
2004 }
2005
2006 for (auto &C : ModulePipelineParsingCallbacks)
2007 if (C(Name, MPM, InnerPipeline))
2008 return Error::success();
2009
2010 // Normal passes can't have pipelines.
2012 formatv("invalid use of '{}' pass as module pipeline", Name).str(),
2014 ;
2015 }
2016
2017 // Finally expand the basic registered passes from the .inc file.
2018#define MODULE_PASS(NAME, CREATE_PASS) \
2019 if (Name == NAME) { \
2020 MPM.addPass(CREATE_PASS); \
2021 return Error::success(); \
2022 }
2023#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2024 if (checkParametrizedPassName(Name, NAME)) { \
2025 auto Params = parsePassParameters(PARSER, Name, NAME); \
2026 if (!Params) \
2027 return Params.takeError(); \
2028 MPM.addPass(CREATE_PASS(Params.get())); \
2029 return Error::success(); \
2030 }
2031#define MODULE_ANALYSIS(NAME, CREATE_PASS) \
2032 if (Name == "require<" NAME ">") { \
2033 MPM.addPass( \
2034 RequireAnalysisPass< \
2035 std::remove_reference_t<decltype(CREATE_PASS)>, Module>()); \
2036 return Error::success(); \
2037 } \
2038 if (Name == "invalidate<" NAME ">") { \
2039 MPM.addPass(InvalidateAnalysisPass< \
2040 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2041 return Error::success(); \
2042 }
2043#define CGSCC_PASS(NAME, CREATE_PASS) \
2044 if (Name == NAME) { \
2045 MPM.addPass(createModuleToPostOrderCGSCCPassAdaptor(CREATE_PASS)); \
2046 return Error::success(); \
2047 }
2048#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2049 if (checkParametrizedPassName(Name, NAME)) { \
2050 auto Params = parsePassParameters(PARSER, Name, NAME); \
2051 if (!Params) \
2052 return Params.takeError(); \
2053 MPM.addPass( \
2054 createModuleToPostOrderCGSCCPassAdaptor(CREATE_PASS(Params.get()))); \
2055 return Error::success(); \
2056 }
2057#define FUNCTION_PASS(NAME, CREATE_PASS) \
2058 if (Name == NAME) { \
2059 if constexpr (std::is_constructible_v< \
2060 std::remove_reference_t<decltype(CREATE_PASS)>, \
2061 const TargetMachine &>) { \
2062 if (!TM) \
2063 return make_error<StringError>( \
2064 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2065 inconvertibleErrorCode()); \
2066 } \
2067 MPM.addPass(createModuleToFunctionPassAdaptor(CREATE_PASS)); \
2068 return Error::success(); \
2069 }
2070#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2071 if (checkParametrizedPassName(Name, NAME)) { \
2072 auto Params = parsePassParameters(PARSER, Name, NAME); \
2073 if (!Params) \
2074 return Params.takeError(); \
2075 auto CreatePass = CREATE_PASS; \
2076 if constexpr (std::is_constructible_v< \
2077 std::remove_reference_t<decltype(CreatePass( \
2078 Params.get()))>, \
2079 const TargetMachine &, \
2080 std::remove_reference_t<decltype(Params.get())>>) { \
2081 if (!TM) { \
2082 return make_error<StringError>( \
2083 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2084 inconvertibleErrorCode()); \
2085 } \
2086 } \
2087 MPM.addPass(createModuleToFunctionPassAdaptor(CREATE_PASS(Params.get()))); \
2088 return Error::success(); \
2089 }
2090#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2091 if (Name == NAME) { \
2092 MPM.addPass(createModuleToFunctionPassAdaptor( \
2093 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2094 return Error::success(); \
2095 }
2096#define LOOP_PASS(NAME, CREATE_PASS) \
2097 if (Name == NAME) { \
2098 MPM.addPass(createModuleToFunctionPassAdaptor( \
2099 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2100 return Error::success(); \
2101 }
2102#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2103 if (checkParametrizedPassName(Name, NAME)) { \
2104 auto Params = parsePassParameters(PARSER, Name, NAME); \
2105 if (!Params) \
2106 return Params.takeError(); \
2107 MPM.addPass(createModuleToFunctionPassAdaptor( \
2108 createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), false))); \
2109 return Error::success(); \
2110 }
2111#include "PassRegistry.def"
2112
2113 for (auto &C : ModulePipelineParsingCallbacks)
2114 if (C(Name, MPM, InnerPipeline))
2115 return Error::success();
2117 formatv("unknown module pass '{}'", Name).str(),
2119}
2120
2121Error PassBuilder::parseCGSCCPass(CGSCCPassManager &CGPM,
2122 const PipelineElement &E) {
2123 auto &Name = E.Name;
2124 auto &InnerPipeline = E.InnerPipeline;
2125
2126 // First handle complex passes like the pass managers which carry pipelines.
2127 if (!InnerPipeline.empty()) {
2128 if (Name == "cgscc") {
2129 CGSCCPassManager NestedCGPM;
2130 if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline))
2131 return Err;
2132 // Add the nested pass manager with the appropriate adaptor.
2133 CGPM.addPass(std::move(NestedCGPM));
2134 return Error::success();
2135 }
2136 if (auto Params = parseFunctionPipelineName(Name)) {
2138 if (auto Err = parseFunctionPassPipeline(FPM, InnerPipeline))
2139 return Err;
2140 // Add the nested pass manager with the appropriate adaptor.
2142 std::move(FPM), Params->first, Params->second));
2143 return Error::success();
2144 }
2145 if (auto MaxRepetitions = parseDevirtPassName(Name)) {
2146 CGSCCPassManager NestedCGPM;
2147 if (auto Err = parseCGSCCPassPipeline(NestedCGPM, InnerPipeline))
2148 return Err;
2149 CGPM.addPass(
2150 createDevirtSCCRepeatedPass(std::move(NestedCGPM), *MaxRepetitions));
2151 return Error::success();
2152 }
2153
2154 for (auto &C : CGSCCPipelineParsingCallbacks)
2155 if (C(Name, CGPM, InnerPipeline))
2156 return Error::success();
2157
2158 // Normal passes can't have pipelines.
2160 formatv("invalid use of '{}' pass as cgscc pipeline", Name).str(),
2162 }
2163
2164// Now expand the basic registered passes from the .inc file.
2165#define CGSCC_PASS(NAME, CREATE_PASS) \
2166 if (Name == NAME) { \
2167 CGPM.addPass(CREATE_PASS); \
2168 return Error::success(); \
2169 }
2170#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2171 if (checkParametrizedPassName(Name, NAME)) { \
2172 auto Params = parsePassParameters(PARSER, Name, NAME); \
2173 if (!Params) \
2174 return Params.takeError(); \
2175 CGPM.addPass(CREATE_PASS(Params.get())); \
2176 return Error::success(); \
2177 }
2178#define CGSCC_ANALYSIS(NAME, CREATE_PASS) \
2179 if (Name == "require<" NAME ">") { \
2180 CGPM.addPass(RequireAnalysisPass< \
2181 std::remove_reference_t<decltype(CREATE_PASS)>, \
2182 LazyCallGraph::SCC, CGSCCAnalysisManager, LazyCallGraph &, \
2183 CGSCCUpdateResult &>()); \
2184 return Error::success(); \
2185 } \
2186 if (Name == "invalidate<" NAME ">") { \
2187 CGPM.addPass(InvalidateAnalysisPass< \
2188 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2189 return Error::success(); \
2190 }
2191#define FUNCTION_PASS(NAME, CREATE_PASS) \
2192 if (Name == NAME) { \
2193 if constexpr (std::is_constructible_v< \
2194 std::remove_reference_t<decltype(CREATE_PASS)>, \
2195 const TargetMachine &>) { \
2196 if (!TM) \
2197 return make_error<StringError>( \
2198 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2199 inconvertibleErrorCode()); \
2200 } \
2201 CGPM.addPass(createCGSCCToFunctionPassAdaptor(CREATE_PASS)); \
2202 return Error::success(); \
2203 }
2204#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2205 if (checkParametrizedPassName(Name, NAME)) { \
2206 auto Params = parsePassParameters(PARSER, Name, NAME); \
2207 if (!Params) \
2208 return Params.takeError(); \
2209 auto CreatePass = CREATE_PASS; \
2210 if constexpr (std::is_constructible_v< \
2211 std::remove_reference_t<decltype(CreatePass( \
2212 Params.get()))>, \
2213 const TargetMachine &, \
2214 std::remove_reference_t<decltype(Params.get())>>) { \
2215 if (!TM) { \
2216 return make_error<StringError>( \
2217 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2218 inconvertibleErrorCode()); \
2219 } \
2220 } \
2221 CGPM.addPass(createCGSCCToFunctionPassAdaptor(CREATE_PASS(Params.get()))); \
2222 return Error::success(); \
2223 }
2224#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2225 if (Name == NAME) { \
2226 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
2227 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2228 return Error::success(); \
2229 }
2230#define LOOP_PASS(NAME, CREATE_PASS) \
2231 if (Name == NAME) { \
2232 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
2233 createFunctionToLoopPassAdaptor(CREATE_PASS, false))); \
2234 return Error::success(); \
2235 }
2236#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2237 if (checkParametrizedPassName(Name, NAME)) { \
2238 auto Params = parsePassParameters(PARSER, Name, NAME); \
2239 if (!Params) \
2240 return Params.takeError(); \
2241 CGPM.addPass(createCGSCCToFunctionPassAdaptor( \
2242 createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), false))); \
2243 return Error::success(); \
2244 }
2245#include "PassRegistry.def"
2246
2247 for (auto &C : CGSCCPipelineParsingCallbacks)
2248 if (C(Name, CGPM, InnerPipeline))
2249 return Error::success();
2250 return make_error<StringError>(formatv("unknown cgscc pass '{}'", Name).str(),
2252}
2253
2254Error PassBuilder::parseFunctionPass(FunctionPassManager &FPM,
2255 const PipelineElement &E) {
2256 auto &Name = E.Name;
2257 auto &InnerPipeline = E.InnerPipeline;
2258
2259 // First handle complex passes like the pass managers which carry pipelines.
2260 if (!InnerPipeline.empty()) {
2261 if (Name == "function") {
2262 FunctionPassManager NestedFPM;
2263 if (auto Err = parseFunctionPassPipeline(NestedFPM, InnerPipeline))
2264 return Err;
2265 // Add the nested pass manager with the appropriate adaptor.
2266 FPM.addPass(std::move(NestedFPM));
2267 return Error::success();
2268 }
2269 if (Name == "loop" || Name == "loop-mssa") {
2270 LoopPassManager LPM;
2271 if (auto Err = parseLoopPassPipeline(LPM, InnerPipeline))
2272 return Err;
2273 // Add the nested pass manager with the appropriate adaptor.
2274 bool UseMemorySSA = (Name == "loop-mssa");
2275 FPM.addPass(
2276 createFunctionToLoopPassAdaptor(std::move(LPM), UseMemorySSA));
2277 return Error::success();
2278 }
2279 if (Name == "machine-function") {
2281 if (auto Err = parseMachinePassPipeline(MFPM, InnerPipeline))
2282 return Err;
2284 return Error::success();
2285 }
2286
2287 for (auto &C : FunctionPipelineParsingCallbacks)
2288 if (C(Name, FPM, InnerPipeline))
2289 return Error::success();
2290
2291 // Normal passes can't have pipelines.
2293 formatv("invalid use of '{}' pass as function pipeline", Name).str(),
2295 }
2296
2297// Now expand the basic registered passes from the .inc file.
2298#define FUNCTION_PASS(NAME, CREATE_PASS) \
2299 if (Name == NAME) { \
2300 if constexpr (std::is_constructible_v< \
2301 std::remove_reference_t<decltype(CREATE_PASS)>, \
2302 const TargetMachine &>) { \
2303 if (!TM) \
2304 return make_error<StringError>( \
2305 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2306 inconvertibleErrorCode()); \
2307 } \
2308 FPM.addPass(CREATE_PASS); \
2309 return Error::success(); \
2310 }
2311#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2312 if (checkParametrizedPassName(Name, NAME)) { \
2313 auto Params = parsePassParameters(PARSER, Name, NAME); \
2314 if (!Params) \
2315 return Params.takeError(); \
2316 auto CreatePass = CREATE_PASS; \
2317 if constexpr (std::is_constructible_v< \
2318 std::remove_reference_t<decltype(CreatePass( \
2319 Params.get()))>, \
2320 const TargetMachine &, \
2321 std::remove_reference_t<decltype(Params.get())>>) { \
2322 if (!TM) { \
2323 return make_error<StringError>( \
2324 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2325 inconvertibleErrorCode()); \
2326 } \
2327 } \
2328 FPM.addPass(CREATE_PASS(Params.get())); \
2329 return Error::success(); \
2330 }
2331#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
2332 if (Name == "require<" NAME ">") { \
2333 if constexpr (std::is_constructible_v< \
2334 std::remove_reference_t<decltype(CREATE_PASS)>, \
2335 const TargetMachine &>) { \
2336 if (!TM) \
2337 return make_error<StringError>( \
2338 formatv("pass '{0}' requires TargetMachine", Name).str(), \
2339 inconvertibleErrorCode()); \
2340 } \
2341 FPM.addPass( \
2342 RequireAnalysisPass<std::remove_reference_t<decltype(CREATE_PASS)>, \
2343 Function>()); \
2344 return Error::success(); \
2345 } \
2346 if (Name == "invalidate<" NAME ">") { \
2347 FPM.addPass(InvalidateAnalysisPass< \
2348 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2349 return Error::success(); \
2350 }
2351// FIXME: UseMemorySSA is set to false. Maybe we could do things like:
2352// bool UseMemorySSA = !("canon-freeze" || "loop-predication" ||
2353// "guard-widening");
2354// The risk is that it may become obsolete if we're not careful.
2355#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2356 if (Name == NAME) { \
2357 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS, false)); \
2358 return Error::success(); \
2359 }
2360#define LOOP_PASS(NAME, CREATE_PASS) \
2361 if (Name == NAME) { \
2362 FPM.addPass(createFunctionToLoopPassAdaptor(CREATE_PASS, false)); \
2363 return Error::success(); \
2364 }
2365#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2366 if (checkParametrizedPassName(Name, NAME)) { \
2367 auto Params = parsePassParameters(PARSER, Name, NAME); \
2368 if (!Params) \
2369 return Params.takeError(); \
2370 FPM.addPass( \
2371 createFunctionToLoopPassAdaptor(CREATE_PASS(Params.get()), false)); \
2372 return Error::success(); \
2373 }
2374#include "PassRegistry.def"
2375
2376 for (auto &C : FunctionPipelineParsingCallbacks)
2377 if (C(Name, FPM, InnerPipeline))
2378 return Error::success();
2380 formatv("unknown function pass '{}'", Name).str(),
2382}
2383
2384Error PassBuilder::parseLoopPass(LoopPassManager &LPM,
2385 const PipelineElement &E) {
2386 StringRef Name = E.Name;
2387 auto &InnerPipeline = E.InnerPipeline;
2388
2389 // First handle complex passes like the pass managers which carry pipelines.
2390 if (!InnerPipeline.empty()) {
2391 if (Name == "loop") {
2392 LoopPassManager NestedLPM;
2393 if (auto Err = parseLoopPassPipeline(NestedLPM, InnerPipeline))
2394 return Err;
2395 // Add the nested pass manager with the appropriate adaptor.
2396 LPM.addPass(std::move(NestedLPM));
2397 return Error::success();
2398 }
2399
2400 for (auto &C : LoopPipelineParsingCallbacks)
2401 if (C(Name, LPM, InnerPipeline))
2402 return Error::success();
2403
2404 // Normal passes can't have pipelines.
2406 formatv("invalid use of '{}' pass as loop pipeline", Name).str(),
2408 }
2409
2410// Now expand the basic registered passes from the .inc file.
2411#define LOOPNEST_PASS(NAME, CREATE_PASS) \
2412 if (Name == NAME) { \
2413 LPM.addPass(CREATE_PASS); \
2414 return Error::success(); \
2415 }
2416#define LOOP_PASS(NAME, CREATE_PASS) \
2417 if (Name == NAME) { \
2418 LPM.addPass(CREATE_PASS); \
2419 return Error::success(); \
2420 }
2421#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2422 if (checkParametrizedPassName(Name, NAME)) { \
2423 auto Params = parsePassParameters(PARSER, Name, NAME); \
2424 if (!Params) \
2425 return Params.takeError(); \
2426 LPM.addPass(CREATE_PASS(Params.get())); \
2427 return Error::success(); \
2428 }
2429#define LOOP_ANALYSIS(NAME, CREATE_PASS) \
2430 if (Name == "require<" NAME ">") { \
2431 LPM.addPass(RequireAnalysisPass< \
2432 std::remove_reference_t<decltype(CREATE_PASS)>, Loop, \
2433 LoopAnalysisManager, LoopStandardAnalysisResults &, \
2434 LPMUpdater &>()); \
2435 return Error::success(); \
2436 } \
2437 if (Name == "invalidate<" NAME ">") { \
2438 LPM.addPass(InvalidateAnalysisPass< \
2439 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2440 return Error::success(); \
2441 }
2442#include "PassRegistry.def"
2443
2444 for (auto &C : LoopPipelineParsingCallbacks)
2445 if (C(Name, LPM, InnerPipeline))
2446 return Error::success();
2447 return make_error<StringError>(formatv("unknown loop pass '{}'", Name).str(),
2449}
2450
2451Error PassBuilder::parseMachinePass(MachineFunctionPassManager &MFPM,
2452 const PipelineElement &E) {
2453 StringRef Name = E.Name;
2454 // Handle any nested pass managers.
2455 if (!E.InnerPipeline.empty()) {
2456 if (E.Name == "machine-function") {
2458 if (auto Err = parseMachinePassPipeline(NestedPM, E.InnerPipeline))
2459 return Err;
2460 MFPM.addPass(std::move(NestedPM));
2461 return Error::success();
2462 }
2463 return make_error<StringError>("invalid pipeline",
2465 }
2466
2467#define MACHINE_MODULE_PASS(NAME, CREATE_PASS) \
2468 if (Name == NAME) { \
2469 MFPM.addPass(CREATE_PASS); \
2470 return Error::success(); \
2471 }
2472#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) \
2473 if (Name == NAME) { \
2474 MFPM.addPass(CREATE_PASS); \
2475 return Error::success(); \
2476 }
2477#define MACHINE_FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, \
2478 PARAMS) \
2479 if (checkParametrizedPassName(Name, NAME)) { \
2480 auto Params = parsePassParameters(PARSER, Name, NAME); \
2481 if (!Params) \
2482 return Params.takeError(); \
2483 MFPM.addPass(CREATE_PASS(Params.get())); \
2484 return Error::success(); \
2485 }
2486#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) \
2487 if (Name == "require<" NAME ">") { \
2488 MFPM.addPass( \
2489 RequireAnalysisPass<std::remove_reference_t<decltype(CREATE_PASS)>, \
2490 MachineFunction>()); \
2491 return Error::success(); \
2492 } \
2493 if (Name == "invalidate<" NAME ">") { \
2494 MFPM.addPass(InvalidateAnalysisPass< \
2495 std::remove_reference_t<decltype(CREATE_PASS)>>()); \
2496 return Error::success(); \
2497 }
2498#include "llvm/Passes/MachinePassRegistry.def"
2499
2500 for (auto &C : MachineFunctionPipelineParsingCallbacks)
2501 if (C(Name, MFPM, E.InnerPipeline))
2502 return Error::success();
2504 formatv("unknown machine pass '{}'", Name).str(),
2506}
2507
2508bool PassBuilder::parseAAPassName(AAManager &AA, StringRef Name) {
2509#define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
2510 if (Name == NAME) { \
2511 AA.registerModuleAnalysis< \
2512 std::remove_reference_t<decltype(CREATE_PASS)>>(); \
2513 return true; \
2514 }
2515#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) \
2516 if (Name == NAME) { \
2517 AA.registerFunctionAnalysis< \
2518 std::remove_reference_t<decltype(CREATE_PASS)>>(); \
2519 return true; \
2520 }
2521#include "PassRegistry.def"
2522
2523 for (auto &C : AAParsingCallbacks)
2524 if (C(Name, AA))
2525 return true;
2526 return false;
2527}
2528
2529Error PassBuilder::parseMachinePassPipeline(
2531 for (const auto &Element : Pipeline) {
2532 if (auto Err = parseMachinePass(MFPM, Element))
2533 return Err;
2534 }
2535 return Error::success();
2536}
2537
2538Error PassBuilder::parseLoopPassPipeline(LoopPassManager &LPM,
2539 ArrayRef<PipelineElement> Pipeline) {
2540 for (const auto &Element : Pipeline) {
2541 if (auto Err = parseLoopPass(LPM, Element))
2542 return Err;
2543 }
2544 return Error::success();
2545}
2546
2547Error PassBuilder::parseFunctionPassPipeline(
2549 for (const auto &Element : Pipeline) {
2550 if (auto Err = parseFunctionPass(FPM, Element))
2551 return Err;
2552 }
2553 return Error::success();
2554}
2555
2556Error PassBuilder::parseCGSCCPassPipeline(CGSCCPassManager &CGPM,
2557 ArrayRef<PipelineElement> Pipeline) {
2558 for (const auto &Element : Pipeline) {
2559 if (auto Err = parseCGSCCPass(CGPM, Element))
2560 return Err;
2561 }
2562 return Error::success();
2563}
2564
2570 MAM.registerPass([&] { return FunctionAnalysisManagerModuleProxy(FAM); });
2571 MAM.registerPass([&] { return CGSCCAnalysisManagerModuleProxy(CGAM); });
2572 CGAM.registerPass([&] { return ModuleAnalysisManagerCGSCCProxy(MAM); });
2573 FAM.registerPass([&] { return CGSCCAnalysisManagerFunctionProxy(CGAM); });
2574 FAM.registerPass([&] { return ModuleAnalysisManagerFunctionProxy(MAM); });
2575 FAM.registerPass([&] { return LoopAnalysisManagerFunctionProxy(LAM); });
2576 LAM.registerPass([&] { return FunctionAnalysisManagerLoopProxy(FAM); });
2577 if (MFAM) {
2578 MAM.registerPass(
2579 [&] { return MachineFunctionAnalysisManagerModuleProxy(*MFAM); });
2580 FAM.registerPass(
2581 [&] { return MachineFunctionAnalysisManagerFunctionProxy(*MFAM); });
2582 MFAM->registerPass(
2584 MFAM->registerPass(
2586 }
2587}
2588
2589Error PassBuilder::parseModulePassPipeline(ModulePassManager &MPM,
2590 ArrayRef<PipelineElement> Pipeline) {
2591 for (const auto &Element : Pipeline) {
2592 if (auto Err = parseModulePass(MPM, Element))
2593 return Err;
2594 }
2595 return Error::success();
2596}
2597
2598// Primary pass pipeline description parsing routine for a \c ModulePassManager
2599// FIXME: Should this routine accept a TargetMachine or require the caller to
2600// pre-populate the analysis managers with target-specific stuff?
2602 StringRef PipelineText) {
2603 auto Pipeline = parsePipelineText(PipelineText);
2604 if (!Pipeline || Pipeline->empty())
2606 formatv("invalid pipeline '{}'", PipelineText).str(),
2608
2609 // If the first name isn't at the module layer, wrap the pipeline up
2610 // automatically.
2611 StringRef FirstName = Pipeline->front().Name;
2612
2613 if (!isModulePassName(FirstName, ModulePipelineParsingCallbacks)) {
2614 bool UseMemorySSA;
2615 if (isCGSCCPassName(FirstName, CGSCCPipelineParsingCallbacks)) {
2616 Pipeline = {{"cgscc", std::move(*Pipeline)}};
2617 } else if (isFunctionPassName(FirstName,
2618 FunctionPipelineParsingCallbacks)) {
2619 Pipeline = {{"function", std::move(*Pipeline)}};
2620 } else if (isLoopNestPassName(FirstName, LoopPipelineParsingCallbacks,
2621 UseMemorySSA)) {
2622 Pipeline = {{"function", {{UseMemorySSA ? "loop-mssa" : "loop",
2623 std::move(*Pipeline)}}}};
2624 } else if (isLoopPassName(FirstName, LoopPipelineParsingCallbacks,
2625 UseMemorySSA)) {
2626 Pipeline = {{"function", {{UseMemorySSA ? "loop-mssa" : "loop",
2627 std::move(*Pipeline)}}}};
2628 } else if (isMachineFunctionPassName(
2629 FirstName, MachineFunctionPipelineParsingCallbacks)) {
2630 Pipeline = {{"function", {{"machine-function", std::move(*Pipeline)}}}};
2631 } else {
2632 for (auto &C : TopLevelPipelineParsingCallbacks)
2633 if (C(MPM, *Pipeline))
2634 return Error::success();
2635
2636 // Unknown pass or pipeline name!
2637 auto &InnerPipeline = Pipeline->front().InnerPipeline;
2639 formatv("unknown {} name '{}'",
2640 (InnerPipeline.empty() ? "pass" : "pipeline"), FirstName)
2641 .str(),
2643 }
2644 }
2645
2646 if (auto Err = parseModulePassPipeline(MPM, *Pipeline))
2647 return Err;
2648 return Error::success();
2649}
2650
2651// Primary pass pipeline description parsing routine for a \c CGSCCPassManager
2653 StringRef PipelineText) {
2654 auto Pipeline = parsePipelineText(PipelineText);
2655 if (!Pipeline || Pipeline->empty())
2657 formatv("invalid pipeline '{}'", PipelineText).str(),
2659
2660 StringRef FirstName = Pipeline->front().Name;
2661 if (!isCGSCCPassName(FirstName, CGSCCPipelineParsingCallbacks))
2663 formatv("unknown cgscc pass '{}' in pipeline '{}'", FirstName,
2664 PipelineText)
2665 .str(),
2667
2668 if (auto Err = parseCGSCCPassPipeline(CGPM, *Pipeline))
2669 return Err;
2670 return Error::success();
2671}
2672
2673// Primary pass pipeline description parsing routine for a \c
2674// FunctionPassManager
2676 StringRef PipelineText) {
2677 auto Pipeline = parsePipelineText(PipelineText);
2678 if (!Pipeline || Pipeline->empty())
2680 formatv("invalid pipeline '{}'", PipelineText).str(),
2682
2683 StringRef FirstName = Pipeline->front().Name;
2684 if (!isFunctionPassName(FirstName, FunctionPipelineParsingCallbacks))
2686 formatv("unknown function pass '{}' in pipeline '{}'", FirstName,
2687 PipelineText)
2688 .str(),
2690
2691 if (auto Err = parseFunctionPassPipeline(FPM, *Pipeline))
2692 return Err;
2693 return Error::success();
2694}
2695
2696// Primary pass pipeline description parsing routine for a \c LoopPassManager
2698 StringRef PipelineText) {
2699 auto Pipeline = parsePipelineText(PipelineText);
2700 if (!Pipeline || Pipeline->empty())
2702 formatv("invalid pipeline '{}'", PipelineText).str(),
2704
2705 if (auto Err = parseLoopPassPipeline(CGPM, *Pipeline))
2706 return Err;
2707
2708 return Error::success();
2709}
2710
2712 StringRef PipelineText) {
2713 auto Pipeline = parsePipelineText(PipelineText);
2714 if (!Pipeline || Pipeline->empty())
2716 formatv("invalid machine pass pipeline '{}'", PipelineText).str(),
2718
2719 if (auto Err = parseMachinePassPipeline(MFPM, *Pipeline))
2720 return Err;
2721
2722 return Error::success();
2723}
2724
2726 // If the pipeline just consists of the word 'default' just replace the AA
2727 // manager with our default one.
2728 if (PipelineText == "default") {
2730 return Error::success();
2731 }
2732
2733 while (!PipelineText.empty()) {
2734 StringRef Name;
2735 std::tie(Name, PipelineText) = PipelineText.split(',');
2736 if (!parseAAPassName(AA, Name))
2738 formatv("unknown alias analysis name '{}'", Name).str(),
2740 }
2741
2742 return Error::success();
2743}
2744
2745std::optional<RegAllocFilterFunc>
2747 if (FilterName == "all")
2748 return nullptr;
2749 for (auto &C : RegClassFilterParsingCallbacks)
2750 if (auto F = C(FilterName))
2751 return F;
2752 return std::nullopt;
2753}
2754
2756 OS << " " << PassName << "\n";
2757}
2759 raw_ostream &OS) {
2760 OS << " " << PassName << "<" << Params << ">\n";
2761}
2762
2764 // TODO: print pass descriptions when they are available
2765
2766 OS << "Module passes:\n";
2767#define MODULE_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2768#include "PassRegistry.def"
2769
2770 OS << "Module passes with params:\n";
2771#define MODULE_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2772 printPassName(NAME, PARAMS, OS);
2773#include "PassRegistry.def"
2774
2775 OS << "Module analyses:\n";
2776#define MODULE_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2777#include "PassRegistry.def"
2778
2779 OS << "Module alias analyses:\n";
2780#define MODULE_ALIAS_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2781#include "PassRegistry.def"
2782
2783 OS << "CGSCC passes:\n";
2784#define CGSCC_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2785#include "PassRegistry.def"
2786
2787 OS << "CGSCC passes with params:\n";
2788#define CGSCC_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2789 printPassName(NAME, PARAMS, OS);
2790#include "PassRegistry.def"
2791
2792 OS << "CGSCC analyses:\n";
2793#define CGSCC_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2794#include "PassRegistry.def"
2795
2796 OS << "Function passes:\n";
2797#define FUNCTION_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2798#include "PassRegistry.def"
2799
2800 OS << "Function passes with params:\n";
2801#define FUNCTION_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2802 printPassName(NAME, PARAMS, OS);
2803#include "PassRegistry.def"
2804
2805 OS << "Function analyses:\n";
2806#define FUNCTION_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2807#include "PassRegistry.def"
2808
2809 OS << "Function alias analyses:\n";
2810#define FUNCTION_ALIAS_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2811#include "PassRegistry.def"
2812
2813 OS << "LoopNest passes:\n";
2814#define LOOPNEST_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2815#include "PassRegistry.def"
2816
2817 OS << "Loop passes:\n";
2818#define LOOP_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2819#include "PassRegistry.def"
2820
2821 OS << "Loop passes with params:\n";
2822#define LOOP_PASS_WITH_PARAMS(NAME, CLASS, CREATE_PASS, PARSER, PARAMS) \
2823 printPassName(NAME, PARAMS, OS);
2824#include "PassRegistry.def"
2825
2826 OS << "Loop analyses:\n";
2827#define LOOP_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2828#include "PassRegistry.def"
2829
2830 OS << "Machine module passes (WIP):\n";
2831#define MACHINE_MODULE_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2832#include "llvm/Passes/MachinePassRegistry.def"
2833
2834 OS << "Machine function passes (WIP):\n";
2835#define MACHINE_FUNCTION_PASS(NAME, CREATE_PASS) printPassName(NAME, OS);
2836#include "llvm/Passes/MachinePassRegistry.def"
2837
2838 OS << "Machine function analyses (WIP):\n";
2839#define MACHINE_FUNCTION_ANALYSIS(NAME, CREATE_PASS) printPassName(NAME, OS);
2840#include "llvm/Passes/MachinePassRegistry.def"
2841}
2842
2844 const std::function<bool(ModulePassManager &, ArrayRef<PipelineElement>)>
2845 &C) {
2846 TopLevelPipelineParsingCallbacks.push_back(C);
2847}
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:54
Machine Check Debug Module
Machine IR instance of the generic uniformity analysis.
This file exposes an interface to building/using memory SSA to walk memory instructions using a use/d...
This pass performs merges of loads and stores on both sides of a.
This is the interface to build a ModuleSummaryIndex for a module.
Contains a collection of routines for determining if a given instruction is guaranteed to execute if ...
This file provides the interface for LLVM's Global Value Numbering pass.
This file declares a simple ARC-aware AliasAnalysis using special knowledge of Objective C to enhance...
This header enumerates the LLVM-provided high-level optimization levels.
This file provides the interface for IR based instrumentation passes ( (profile-gen,...
CGSCCAnalysisManager CGAM
LoopAnalysisManager LAM
FunctionAnalysisManager FAM
ModuleAnalysisManager MAM
if(PassOpts->AAPipeline)
PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC)
static bool isModulePassName(StringRef Name, CallbacksT &Callbacks)
static bool callbacksAcceptPassName(StringRef Name, CallbacksT &Callbacks)
Tests whether registered callbacks will accept a given pass name.
static std::optional< int > parseDevirtPassName(StringRef Name)
static bool isLoopNestPassName(StringRef Name, CallbacksT &Callbacks, bool &UseMemorySSA)
static bool isMachineFunctionPassName(StringRef Name, CallbacksT &Callbacks)
static Expected< OptimizationLevel > parseOptLevelParam(StringRef S)
static std::optional< OptimizationLevel > parseOptLevel(StringRef S)
static bool isLoopPassName(StringRef Name, CallbacksT &Callbacks, bool &UseMemorySSA)
static std::optional< std::pair< bool, bool > > parseFunctionPipelineName(StringRef Name)
static bool isCGSCCPassName(StringRef Name, CallbacksT &Callbacks)
static void printPassName(StringRef PassName, raw_ostream &OS)
static bool isFunctionPassName(StringRef Name, CallbacksT &Callbacks)
static void setupOptionsForPipelineAlias(PipelineTuningOptions &PTO, OptimizationLevel L)
This file implements the PredicateInfo analysis, which creates an Extended SSA form for operations us...
static cl::opt< RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode > Mode("regalloc-enable-advisor", cl::Hidden, cl::init(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default), cl::desc("Enable regalloc advisor mode"), cl::values(clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Default, "default", "Default"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Release, "release", "precompiled"), clEnumValN(RegAllocEvictionAdvisorAnalysisLegacy::AdvisorMode::Development, "development", "for training")))
This pass is required to take advantage of the interprocedural register allocation infrastructure.
This file implements relative lookup table converter that converts lookup tables to relative lookup t...
static const char * name
This file provides the interface for LLVM's Scalar Replacement of Aggregates pass.
This file provides the interface for the pseudo probe implementation for AutoFDO.
This file provides the interface for the sampled PGO loader pass.
This is the interface for a SCEV-based alias analysis.
This pass converts vector operations into scalar operations (or, optionally, operations on smaller ve...
This is the interface for a metadata-based scoped no-alias analysis.
This file contains the declaration of the SelectOptimizePass class, its corresponding pass name is se...
This file provides the interface for the pass responsible for both simplifying and canonicalizing the...
This file implements the StringSwitch template, which mimics a switch() statement whose cases are str...
Target-Independent Code Generator Pass Configuration Options pass.
This pass exposes codegen information to IR-level passes.
This is the interface for a metadata-based TBAA.
Defines an IR pass for type promotion.
LLVM IR instance of the generic uniformity analysis.
static const char PassName[]
Value * RHS
A manager for alias analyses.
Class for arbitrary precision integers.
Definition APInt.h:78
uint64_t getZExtValue() const
Get zero extended value.
Definition APInt.h:1541
int64_t getSExtValue() const
Get sign extended value.
Definition APInt.h:1563
bool registerPass(PassBuilderT &&PassBuilder)
Register an analysis pass with the manager.
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition ArrayRef.h:40
const Instruction * getTerminator() const LLVM_READONLY
Returns the terminator instruction if the block is well formed or null if the block is not well forme...
Definition BasicBlock.h:233
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
Tagged union holding either a T or a Error.
Definition Error.h:485
static LLVM_ABI GlobalAlias * create(Type *Ty, unsigned AddressSpace, LinkageTypes Linkage, const Twine &Name, Constant *Aliasee, Module *Parent)
If a parent module is specified, the alias is automatically inserted into the end of the specified mo...
Definition Globals.cpp:598
A smart pointer to a reference-counted object that inherits from RefCountedBase or ThreadSafeRefCount...
static constexpr LLT scalar(unsigned SizeInBits)
Get a low-level scalar or aggregate "bag of bits".
MachineRegisterInfo & getRegInfo()
getRegInfo - Return information about the registers currently in use.
const MachineFunctionProperties & getProperties() const
Get the function properties.
static LLVM_ABI const OptimizationLevel O3
Optimize for fast execution as much as possible.
static LLVM_ABI const OptimizationLevel Oz
A very specialized mode that will optimize for code size at any and all costs.
static LLVM_ABI const OptimizationLevel O0
Disable as many optimizations as possible.
static LLVM_ABI const OptimizationLevel Os
Similar to O2 but tries to optimize for small code size instead of fast execution without triggering ...
static LLVM_ABI const OptimizationLevel O2
Optimize for fast execution as much as possible without triggering significant incremental compile ti...
static LLVM_ABI const OptimizationLevel O1
Optimize quickly without destroying debuggability.
This class provides access to building LLVM's passes.
LLVM_ABI void printPassNames(raw_ostream &OS)
Print pass names.
static bool checkParametrizedPassName(StringRef Name, StringRef PassName)
LLVM_ABI AAManager buildDefaultAAPipeline()
Build the default AAManager with the default alias analysis pipeline registered.
LLVM_ABI Error parseAAPipeline(AAManager &AA, StringRef PipelineText)
Parse a textual alias analysis pipeline into the provided AA manager.
LLVM_ABI void registerLoopAnalyses(LoopAnalysisManager &LAM)
Registers all available loop analysis passes.
LLVM_ABI std::optional< RegAllocFilterFunc > parseRegAllocFilter(StringRef RegAllocFilterName)
Parse RegAllocFilterName to get RegAllocFilterFunc.
LLVM_ABI void crossRegisterProxies(LoopAnalysisManager &LAM, FunctionAnalysisManager &FAM, CGSCCAnalysisManager &CGAM, ModuleAnalysisManager &MAM, MachineFunctionAnalysisManager *MFAM=nullptr)
Cross register the analysis managers through their proxies.
LLVM_ABI PassBuilder(TargetMachine *TM=nullptr, PipelineTuningOptions PTO=PipelineTuningOptions(), std::optional< PGOOptions > PGOOpt=std::nullopt, PassInstrumentationCallbacks *PIC=nullptr, IntrusiveRefCntPtr< vfs::FileSystem > FS=vfs::getRealFileSystem())
LLVM_ABI Error parsePassPipeline(ModulePassManager &MPM, StringRef PipelineText)
Parse a textual pass pipeline description into a ModulePassManager.
void registerPipelineParsingCallback(const std::function< bool(StringRef Name, CGSCCPassManager &, ArrayRef< PipelineElement >)> &C)
{{@ Register pipeline parsing callbacks with this pass builder instance.
LLVM_ABI void registerModuleAnalyses(ModuleAnalysisManager &MAM)
Registers all available module analysis passes.
LLVM_ABI void registerCGSCCAnalyses(CGSCCAnalysisManager &CGAM)
Registers all available CGSCC analysis passes.
static LLVM_ABI Expected< bool > parseSinglePassOption(StringRef Params, StringRef OptionName, StringRef PassName)
Handle passes only accept one bool-valued parameter.
LLVM_ABI void registerMachineFunctionAnalyses(MachineFunctionAnalysisManager &MFAM)
Registers all available machine function analysis passes.
LLVM_ABI void registerParseTopLevelPipelineCallback(const std::function< bool(ModulePassManager &, ArrayRef< PipelineElement >)> &C)
Register a callback for a top-level pipeline entry.
LLVM_ABI void registerFunctionAnalyses(FunctionAnalysisManager &FAM)
Registers all available function analysis passes.
This class manages callbacks registration, as well as provides a way for PassInstrumentation to pass ...
LLVM_ATTRIBUTE_MINSIZE std::enable_if_t<!std::is_same_v< PassT, PassManager > > addPass(PassT &&Pass)
Tunable parameters for passes in the default pipelines.
Definition PassBuilder.h:41
bool SLPVectorization
Tuning option to enable/disable slp loop vectorization, set based on opt level.
Definition PassBuilder.h:56
bool LoopVectorization
Tuning option to enable/disable loop vectorization, set based on opt level.
Definition PassBuilder.h:52
static PreservedAnalyses none()
Convenience factory function for the empty preserved set.
Definition Analysis.h:115
static PreservedAnalyses all()
Construct a special preserved set that preserves all passes.
Definition Analysis.h:118
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
std::pair< StringRef, StringRef > split(char Separator) const
Split into two substrings around the first occurrence of a separator character.
Definition StringRef.h:702
bool getAsInteger(unsigned Radix, T &Result) const
Parse the current string as an integer of the specified radix.
Definition StringRef.h:472
std::string str() const
str - Get the contents as an std::string.
Definition StringRef.h:225
bool starts_with(StringRef Prefix) const
Check if this string starts with the given Prefix.
Definition StringRef.h:261
constexpr bool empty() const
empty - Check if the string is empty.
Definition StringRef.h:143
char front() const
front - Get the first character in the string.
Definition StringRef.h:149
bool consume_front(StringRef Prefix)
Returns true if this StringRef has the given prefix and removes that prefix.
Definition StringRef.h:637
A switch()-like statement whose cases are string literals.
StringSwitch & Case(StringLiteral S, T Value)
Primary interface to the complete machine description for the target machine.
self_iterator getIterator()
Definition ilist_node.h:123
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
Interfaces for registering analysis passes, producing common pass manager configurations,...
Abstract Attribute helper functions.
Definition Attributor.h:165
@ C
The default llvm calling convention, compatible with C.
Definition CallingConv.h:34
std::optional< CodeGenOptLevel > getLevel(int OL)
Get the Level identified by the integer OL.
Definition CodeGen.h:93
@ BasicBlock
Various leaf nodes.
Definition ISDOpcodes.h:81
PointerTypeMap run(const Module &M)
Compute the PointerTypeMap for the module M.
This is an optimization pass for GlobalISel generic memory operations.
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.
ModuleToPostOrderCGSCCPassAdaptor createModuleToPostOrderCGSCCPassAdaptor(CGSCCPassT &&Pass)
A function to deduce a function pass type and wrap it in the templated adaptor.
LLVM_ABI cl::opt< bool > PrintPipelinePasses
Common option used by multiple tools to print pipeline passes.
auto formatv(bool Validate, const char *Fmt, Ts &&...Vals)
FunctionToLoopPassAdaptor createFunctionToLoopPassAdaptor(LoopPassT &&Pass, bool UseMemorySSA=false)
A function to deduce a loop pass type and wrap it in the templated adaptor.
CGSCCToFunctionPassAdaptor createCGSCCToFunctionPassAdaptor(FunctionPassT &&Pass, bool EagerlyInvalidate=false, bool NoRerun=false)
A function to deduce a function pass type and wrap it in the templated adaptor.
FunctionToMachineFunctionPassAdaptor createFunctionToMachineFunctionPassAdaptor(MachineFunctionPassT &&Pass)
PassManager< Module > ModulePassManager
Convenience typedef for a pass manager over modules.
FunctionAddr VTableAddr Count
Definition InstrProf.h:139
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
InnerAnalysisManagerProxy< MachineFunctionAnalysisManager, Function > MachineFunctionAnalysisManagerFunctionProxy
OuterAnalysisManagerProxy< FunctionAnalysisManager, Loop, LoopStandardAnalysisResults & > FunctionAnalysisManagerLoopProxy
A proxy from a FunctionAnalysisManager to a Loop.
Error make_error(ArgTs &&... Args)
Make a Error instance representing failure using the given error info type.
Definition Error.h:340
OuterAnalysisManagerProxy< ModuleAnalysisManager, LazyCallGraph::SCC, LazyCallGraph & > ModuleAnalysisManagerCGSCCProxy
A proxy from a ModuleAnalysisManager to an SCC.
InnerAnalysisManagerProxy< MachineFunctionAnalysisManager, Module > MachineFunctionAnalysisManagerModuleProxy
InnerAnalysisManagerProxy< CGSCCAnalysisManager, Module > CGSCCAnalysisManagerModuleProxy
A proxy from a CGSCCAnalysisManager to a Module.
PassManager< Function > FunctionPassManager
Convenience typedef for a pass manager over functions.
MFPropsModifier(PassT &P, MachineFunction &MF) -> MFPropsModifier< PassT >
OutputIt move(R &&Range, OutputIt Out)
Provide wrappers to std::move which take ranges instead of having to pass begin/end explicitly.
Definition STLExtras.h:1888
PassManager< MachineFunction > MachineFunctionPassManager
Convenience typedef for a pass manager over functions.
AnalysisManager< Function > FunctionAnalysisManager
Convenience typedef for the Function analysis manager.
LLVM_ABI std::optional< AllocTokenMode > getAllocTokenModeFromString(StringRef Name)
Returns the AllocTokenMode from its canonical string name; if an invalid name was provided returns nu...
@ Detailed
Hash with opcode only.
@ CallTargetIgnored
Hash with opcode and operands.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition MIRParser.h:39
@ Enable
Enable colors.
Definition WithColor.h:47
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:870
#define N
A special type used by analysis passes to provide an address that identifies that particular analysis...
Definition Analysis.h:29
A set of parameters to control various transforms performed by GVN pass.
Definition GVN.h:78
HardwareLoopOptions & setForceNested(bool Force)
HardwareLoopOptions & setDecrement(unsigned Count)
HardwareLoopOptions & setForceGuard(bool Force)
HardwareLoopOptions & setForce(bool Force)
HardwareLoopOptions & setCounterBitwidth(unsigned Width)
HardwareLoopOptions & setForcePhi(bool Force)
A set of parameters to control various transforms performed by IPSCCP pass.
Definition SCCP.h:35
A set of parameters used to control various transforms performed by the LoopUnroll pass.
LoopUnrollOptions & setPeeling(bool Peeling)
Enables or disables loop peeling.
LoopUnrollOptions & setOptLevel(int O)
LoopUnrollOptions & setPartial(bool Partial)
Enables or disables partial unrolling.
LoopUnrollOptions & setFullUnrollMaxCount(unsigned O)
LoopUnrollOptions & setUpperBound(bool UpperBound)
Enables or disables the use of trip count upper bound in loop unrolling.
LoopUnrollOptions & setRuntime(bool Runtime)
Enables or disables unrolling of loops with runtime trip count.
LoopUnrollOptions & setProfileBasedPeeling(int O)
LoopVectorizeOptions & setVectorizeOnlyWhenForced(bool Value)
LoopVectorizeOptions & setInterleaveOnlyWhenForced(bool Value)
A CRTP mix-in to automatically provide informational APIs needed for passes.
Definition PassManager.h:69