14#ifndef LLVM_PASSES_CODEGENPASSBUILDER_H
15#define LLVM_PASSES_CODEGENPASSBUILDER_H
82#define DUMMY_FUNCTION_PASS(NAME, PASS_NAME) \
83 struct PASS_NAME : public PassInfoMixin<PASS_NAME> { \
84 template <typename... Ts> PASS_NAME(Ts &&...) {} \
85 PreservedAnalyses run(Function &, FunctionAnalysisManager &) { \
86 return PreservedAnalyses::all(); \
89#define DUMMY_MACHINE_MODULE_PASS(NAME, PASS_NAME) \
90 struct PASS_NAME : public PassInfoMixin<PASS_NAME> { \
91 template <typename... Ts> PASS_NAME(Ts &&...) {} \
92 PreservedAnalyses run(Module &, ModuleAnalysisManager &) { \
93 return PreservedAnalyses::all(); \
96#define DUMMY_MACHINE_FUNCTION_PASS(NAME, PASS_NAME) \
97 struct PASS_NAME : public PassInfoMixin<PASS_NAME> { \
98 template <typename... Ts> PASS_NAME(Ts &&...) {} \
99 PreservedAnalyses run(MachineFunction &, \
100 MachineFunctionAnalysisManager &) { \
101 return PreservedAnalyses::all(); \
104#include "llvm/Passes/MachinePassRegistry.def"
142 template <
typename PassT>
144 std::declval<Module &>(), std::declval<ModuleAnalysisManager &>()));
146 template <
typename PassT>
148 std::declval<Function &>(), std::declval<FunctionAnalysisManager &>()));
150 template <
typename PassT>
152 std::declval<MachineFunction &>(),
153 std::declval<MachineFunctionAnalysisManager &>()));
167 template <
typename PassT>
171 "Only module pass and function pass are supported.");
173 if (!PB.runBeforeAdding(
Name))
206 template <
typename PassT>
211 "Only module pass and function pass are supported.");
213 if (!Force && !PB.runBeforeAdding(
Name))
230 for (
auto &
C : PB.AfterCallbacks)
244 template <
typename TMC> TMC &
getTM()
const {
return static_cast<TMC &
>(
TM); }
264 return make_error<StringError>(
"addInstSelector is not overridden",
332 return make_error<StringError>(
"addIRTranslator is not overridden",
343 return make_error<StringError>(
"addLegalizeMachineIR is not overridden",
355 return make_error<StringError>(
"addRegBankSelect is not overridden",
368 return make_error<StringError>(
369 "addGlobalInstructionSelect is not overridden",
434 std::function<Expected<std::unique_ptr<MCStreamer>>(
MCContext &)>;
458 BeforeCallbacks.emplace_back(
464 template <
typename TargetPassT,
typename InsertedPassT>
466 AfterCallbacks.emplace_back(
468 if (
Name == TargetPassT::name())
474 DerivedT &derived() {
return static_cast<DerivedT &
>(*this); }
475 const DerivedT &derived()
const {
476 return static_cast<const DerivedT &
>(*this);
479 bool runBeforeAdding(StringRef
Name)
const {
480 bool ShouldAdd =
true;
481 for (
auto &
C : BeforeCallbacks)
482 ShouldAdd &=
C(
Name);
486 void setStartStopPasses(
const TargetPassConfig::StartStopInfo &
Info)
const;
488 Error verifyStartStop(
const TargetPassConfig::StartStopInfo &
Info)
const;
497 mutable bool Started =
true;
498 mutable bool Stopped =
true;
501template <
typename Derived,
typename TargetMachineT>
507 return StartStopInfo.takeError();
508 setStartStopPasses(*StartStopInfo);
517 addISelPasses(addIRPass);
525 if (
auto Err = addCoreISelPasses(addPass))
526 return std::move(Err);
528 if (
auto Err = derived().addMachinePasses(addPass))
529 return std::move(Err);
532 derived().addAsmPrinter(
533 addPass, [
this, &Out, DwoOut, FileType](
MCContext &Ctx) {
534 return this->TM.createMCStreamer(Out, DwoOut, FileType, Ctx);
542 return verifyStartStop(*StartStopInfo);
545template <
typename Derived,
typename TargetMachineT>
548 if (!
Info.StartPass.empty()) {
550 BeforeCallbacks.emplace_back([
this, &
Info, AfterFlag =
Info.StartAfter,
551 Count = 0u](
StringRef ClassName)
mutable {
552 if (Count == Info.StartInstanceNum) {
562 Started = !
Info.StartAfter;
568 if (!
Info.StopPass.empty()) {
570 BeforeCallbacks.emplace_back([
this, &
Info, AfterFlag =
Info.StopAfter,
571 Count = 0u](StringRef ClassName)
mutable {
572 if (Count == Info.StopInstanceNum) {
582 Stopped = !
Info.StopAfter;
588template <
typename Derived,
typename TargetMachineT>
589Error CodeGenPassBuilder<Derived, TargetMachineT>::verifyStartStop(
590 const TargetPassConfig::StartStopInfo &
Info)
const {
591 if (Started && Stopped)
592 return Error::success();
595 return make_error<StringError>(
596 "Can't find start pass \"" +
597 PIC->getPassNameForClassName(
Info.StartPass) +
"\".",
598 std::make_error_code(std::errc::invalid_argument));
600 return make_error<StringError>(
601 "Can't find stop pass \"" +
602 PIC->getPassNameForClassName(
Info.StopPass) +
"\".",
603 std::make_error_code(std::errc::invalid_argument));
604 return Error::success();
607template <
typename Derived,
typename TargetMachineT>
611 if (
TM.useEmulatedTLS())
616 derived().addIRPasses(addPass);
617 derived().addCodeGenPrepare(addPass);
618 addPassesToHandleExceptions(addPass);
619 derived().addISelPrepare(addPass);
624template <
typename Derived,
typename TargetMachineT>
633 if (getOptLevel() != CodeGenOptLevel::None && !Opt.
DisableLSR) {
641 if (getOptLevel() != CodeGenOptLevel::None) {
666 if (getOptLevel() != CodeGenOptLevel::None)
669 if (getOptLevel() != CodeGenOptLevel::None &&
691template <
typename Derived,
typename TargetMachineT>
695 assert(MCAI &&
"No MCAsmInfo");
697 case ExceptionHandling::SjLj:
706 case ExceptionHandling::DwarfCFI:
707 case ExceptionHandling::ARM:
708 case ExceptionHandling::AIX:
709 case ExceptionHandling::ZOS:
712 case ExceptionHandling::WinEH:
719 case ExceptionHandling::Wasm:
727 case ExceptionHandling::None:
738template <
typename Derived,
typename TargetMachineT>
741 if (getOptLevel() != CodeGenOptLevel::None && !Opt.
DisableCGP)
749template <
typename Derived,
typename TargetMachineT>
762 "\n\n*** Final LLVM Code input to ISel ***\n"));
770template <
typename Derived,
typename TargetMachineT>
778 SelectorType Selector;
781 Selector = SelectorType::FastISel;
784 (
TM.Options.EnableGlobalISel &&
787 Selector = SelectorType::GlobalISel;
788 else if (
TM.getOptLevel() == CodeGenOptLevel::None &&
TM.getO0WantsFastISel())
789 Selector = SelectorType::FastISel;
791 Selector = SelectorType::SelectionDAG;
794 if (Selector == SelectorType::FastISel) {
795 TM.setFastISel(
true);
796 TM.setGlobalISel(
false);
797 }
else if (Selector == SelectorType::GlobalISel) {
798 TM.setFastISel(
false);
799 TM.setGlobalISel(
true);
803 if (Selector == SelectorType::GlobalISel) {
804 if (
auto Err = derived().addIRTranslator(addPass))
805 return std::move(Err);
807 derived().addPreLegalizeMachineIR(addPass);
809 if (
auto Err = derived().addLegalizeMachineIR(addPass))
810 return std::move(Err);
814 derived().addPreRegBankSelect(addPass);
816 if (
auto Err = derived().addRegBankSelect(addPass))
817 return std::move(Err);
819 derived().addPreGlobalInstructionSelect(addPass);
821 if (
auto Err = derived().addGlobalInstructionSelect(addPass))
822 return std::move(Err);
825 addPass(ResetMachineFunctionPass(reportDiagnosticWhenGlobalISelFallback(),
826 isGlobalISelAbortEnabled()));
830 if (!isGlobalISelAbortEnabled())
831 if (
auto Err = derived().addInstSelector(addPass))
832 return std::move(Err);
834 }
else if (
auto Err = derived().addInstSelector(addPass))
835 return std::move(Err);
839 addPass(FinalizeISelPass());
844 return Error::success();
863template <
typename Derived,
typename TargetMachineT>
867 if (getOptLevel() != CodeGenOptLevel::None) {
872 addPass(LocalStackSlotPass());
875 if (
TM.Options.EnableIPRA)
876 addPass(RegUsageInfoPropagationPass());
879 derived().addPreRegAlloc(addPass);
884 derived().addOptimizedRegAlloc(addPass);
886 if (
auto Err = derived().addFastRegAlloc(addPass))
891 derived().addPostRegAlloc(addPass);
893 addPass(RemoveRedundantDebugValuesPass());
896 if (getOptLevel() != CodeGenOptLevel::None) {
897 addPass(PostRAMachineSinkingPass());
898 addPass(ShrinkWrapPass());
901 addPass(PrologEpilogInserterPass());
904 if (getOptLevel() != CodeGenOptLevel::None)
905 derived().addMachineLateOptimization(addPass);
908 addPass(ExpandPostRAPseudosPass());
911 derived().addPreSched2(addPass);
914 addPass(ImplicitNullChecksPass());
919 if (getOptLevel() != CodeGenOptLevel::None &&
920 !
TM.targetSchedulesPostRAScheduling()) {
922 addPass(PostMachineSchedulerPass());
924 addPass(PostRASchedulerPass());
928 derived().addGCPasses(addPass);
931 if (getOptLevel() != CodeGenOptLevel::None)
932 derived().addBlockPlacement(addPass);
935 addPass(FEntryInserterPass());
937 addPass(XRayInstrumentationPass());
938 addPass(PatchableFunctionPass());
940 derived().addPreEmitPass(addPass);
942 if (
TM.Options.EnableIPRA)
945 addPass(RegUsageInfoCollectorPass());
947 addPass(FuncletLayoutPass());
949 addPass(StackMapLivenessPass());
950 addPass(LiveDebugValuesPass());
951 addPass(MachineSanitizerBinaryMetadata());
953 if (
TM.Options.EnableMachineOutliner &&
954 getOptLevel() != CodeGenOptLevel::None &&
956 bool RunOnAllFunctions =
958 bool AddOutliner = RunOnAllFunctions ||
TM.Options.SupportsDefaultOutlining;
960 addPass(MachineOutlinerPass(RunOnAllFunctions));
964 derived().addPreEmitPass2(addPass);
966 return Error::success();
970template <
typename Derived,
typename TargetMachineT>
974 addPass(EarlyTailDuplicatePass());
978 addPass(OptimizePHIsPass());
982 addPass(StackColoringPass());
986 addPass(LocalStackSlotPass());
997 derived().addILPOpts(addPass);
999 addPass(EarlyMachineLICMPass());
1000 addPass(MachineCSEPass());
1002 addPass(MachineSinkingPass());
1004 addPass(PeepholeOptimizerPass());
1022template <
typename Derived,
typename TargetMachineT>
1026 addPass(RAGreedyPass());
1028 addPass(RAFastPass());
1034template <
typename Derived,
typename TargetMachineT>
1040template <
typename Derived,
typename TargetMachineT>
1044 addRegAllocPass(addPass,
false);
1045 return Error::success();
1048template <
typename Derived,
typename TargetMachineT>
1052 addRegAllocPass(addPass,
true);
1055 derived().addPreRewrite(addPass);
1058 addPass(VirtRegRewriterPass());
1063 addPass(StackSlotColoringPass());
1065 return Error::success();
1070template <
typename Derived,
typename TargetMachineT>
1073 addPass(PHIEliminationPass());
1074 addPass(TwoAddressInstructionPass());
1075 return derived().addRegAssignmentFast(addPass);
1081template <
typename Derived,
typename TargetMachineT>
1084 addPass(DetectDeadLanesPass());
1086 addPass(InitUndefPass());
1088 addPass(ProcessImplicitDefsPass());
1091 addPass(PHIEliminationPass());
1095 addPass(LiveIntervalsPass());
1097 addPass(TwoAddressInstructionPass());
1098 addPass(RegisterCoalescerPass());
1103 addPass(RenameIndependentSubregsPass());
1106 addPass(MachineSchedulerPass());
1108 if (derived().addRegAssignmentOptimized(addPass)) {
1111 derived().addPostRewrite(addPass);
1115 addPass(MachineCopyPropagationPass());
1120 addPass(MachineLICMPass());
1129template <
typename Derived,
typename TargetMachineT>
1133 addPass(BranchFolderPass());
1139 if (!
TM.requiresStructuredCFG())
1140 addPass(TailDuplicatePass());
1143 addPass(MachineLateInstrsCleanupPass());
1146 addPass(MachineCopyPropagationPass());
1150template <
typename Derived,
typename TargetMachineT>
1153 addPass(MachineBlockPlacementPass());
1156 addPass(MachineBlockPlacementStatsPass());
This is the interface for LLVM's primary stateless and local alias analysis.
Analysis containing CSE Info
Defines an IR pass for CodeGen Prepare.
This file defines passes to print out IR in various granularities.
This file contains the declaration of the InterleavedAccessPass class, its corresponding pass name is...
This header provides classes for managing a pipeline of passes over loops in LLVM IR.
The header file for the LowerConstantIntrinsics pass as used by the new pass manager.
const char LLVMTargetMachineRef TM
PassInstrumentationCallbacks PIC
PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC)
This header defines various interfaces for pass management in LLVM.
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
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 defines the SmallVector class.
Target-Independent Code Generator Pass Configuration Options pass.
This is the interface for a metadata-based TBAA.
static const char PassName[]
AddIRPass(ModulePassManager &MPM, const DerivedT &PB)
void operator()(PassT &&Pass, StringRef Name=PassT::name())
AddMachinePass(ModulePassManager &MPM, const DerivedT &PB)
void operator()(PassT &&Pass, bool Force=false, StringRef Name=PassT::name())
This class provides access to building LLVM's passes.
void addPreRewrite(AddMachinePass &) const
addPreRewrite - Add passes to the optimized register allocation pipeline after register allocation is...
void addPostRegAlloc(AddMachinePass &) const
This method may be implemented by targets that want to run passes after register allocation pass pipe...
void insertPass(InsertedPassT &&Pass)
Insert InsertedPass pass after TargetPass pass.
void addPreGlobalInstructionSelect(AddMachinePass &) const
This method may be implemented by targets that want to run passes immediately before the (global) ins...
Error addRegAssignmentFast(AddMachinePass &) const
Add core register alloator passes which do the actual register assignment and rewriting.
Error addFastRegAlloc(AddMachinePass &) const
addFastRegAlloc - Add the minimum set of target-independent passes that are required for fast registe...
Error addIRTranslator(AddMachinePass &) const
This method should install an IR translator pass, which converts from LLVM code to machine instructio...
void addILPOpts(AddMachinePass &) const
Add passes that optimize instruction level parallelism for out-of-order targets.
void addRegAllocPass(AddMachinePass &, bool Optimized) const
addMachinePasses helper to create the target-selected or overriden regalloc pass.
void addPreSched2(AddMachinePass &) const
This method may be implemented by targets that want to run passes after prolog-epilog insertion and b...
std::function< Expected< std::unique_ptr< MCStreamer > >(MCContext &)> CreateMCStreamer
Error addRegBankSelect(AddMachinePass &) const
This method should install a register bank selector pass, which assigns register banks to virtual reg...
bool isGlobalISelAbortEnabled() const
Check whether or not GlobalISel should abort on error.
void addPreRegAlloc(AddMachinePass &) const
This method may be implemented by targets that want to run passes immediately before register allocat...
void addGCPasses(AddMachinePass &) const
addGCPasses - Add late codegen passes that analyze code for garbage collection.
Error buildPipeline(ModulePassManager &MPM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut, CodeGenFileType FileType) const
void addGlobalMergePass(AddIRPass &) const
Target can override this to add GlobalMergePass before all IR passes.
Error addLegalizeMachineIR(AddMachinePass &) const
This method should install a legalize pass, which converts the instruction sequence into one that can...
Error addCoreISelPasses(AddMachinePass &) const
Add the actual instruction selection passes.
void addOptimizedRegAlloc(AddMachinePass &) const
addOptimizedRegAlloc - Add passes related to register allocation.
void addISelPasses(AddIRPass &) const
High level function that adds all passes necessary to go from llvm IR representation to the MI repres...
PassInstrumentationCallbacks * PIC
void addMachineSSAOptimization(AddMachinePass &) const
Methods with trivial inline returns are convenient points in the common codegen pass pipeline where t...
decltype(std::declval< PassT & >().run(std::declval< Module & >(), std::declval< ModuleAnalysisManager & >())) is_module_pass_t
CodeGenPassBuilder(TargetMachineT &TM, const CGPassBuilderOption &Opts, PassInstrumentationCallbacks *PIC)
Error addRegAssignmentOptimized(AddMachinePass &) const
void addCodeGenPrepare(AddIRPass &) const
Add pass to prepare the LLVM IR for code generation.
Error addMachinePasses(AddMachinePass &) const
Add the complete, standard set of LLVM CodeGen passes.
void addISelPrepare(AddIRPass &) const
Add common passes that perform LLVM IR to IR transforms in preparation for instruction selection.
void disablePass()
Allow the target to disable a specific pass by default.
void addBlockPlacement(AddMachinePass &) const
Add standard basic block placement passes.
Error addInstSelector(AddMachinePass &) const
addInstSelector - This method should install an instruction selector pass, which converts from LLVM c...
void addTargetRegisterAllocator(AddMachinePass &, bool Optimized) const
Utilities for targets to add passes to the pass manager.
void addPreEmitPass2(AddMachinePass &) const
Targets may add passes immediately before machine code is emitted in this callback.
void addPostRewrite(AddMachinePass &) const
Add passes to be run immediately after virtual registers are rewritten to physical registers.
void addPreRegBankSelect(AddMachinePass &) const
This method may be implemented by targets that want to run passes immediately before the register ban...
void addPreEmitPass(AddMachinePass &) const
This pass may be implemented by targets that want to run passes immediately before machine code is em...
Error addGlobalInstructionSelect(AddMachinePass &) const
This method should install a (global) instruction selector pass, which converts possibly generic inst...
void addMachineLateOptimization(AddMachinePass &) const
Add passes that optimize machine instructions after register allocation.
void addIRPasses(AddIRPass &) const
Add common target configurable passes that perform LLVM IR to IR transforms following machine indepen...
decltype(std::declval< PassT & >().run(std::declval< Function & >(), std::declval< FunctionAnalysisManager & >())) is_function_pass_t
decltype(std::declval< PassT & >().run(std::declval< MachineFunction & >(), std::declval< MachineFunctionAnalysisManager & >())) is_machine_function_pass_t
void addPreLegalizeMachineIR(AddMachinePass &) const
This method may be implemented by targets that want to run passes immediately before legalization.
CodeGenOptLevel getOptLevel() const
void addPassesToHandleExceptions(AddIRPass &) const
Add passes to lower exception handling for the code generator.
PassInstrumentationCallbacks * getPassInstrumentationCallbacks() const
bool reportDiagnosticWhenGlobalISelFallback() const
Check whether or not a diagnostic should be emitted when GlobalISel uses the fallback path.
void addPreISel(AddIRPass &) const
{{@ For GlobalISel
void addAsmPrinter(AddMachinePass &, CreateMCStreamer) const
Lightweight error class with error context and mandatory checking.
This is a fast-path instruction selection class that generates poor code and doesn't support illegal ...
LowerIntrinsics - This pass rewrites calls to the llvm.gcread or llvm.gcwrite intrinsics,...
Performs Loop Strength Reduce Pass.
This class is intended to be used as a base class for asm properties and features specific to the tar...
ExceptionHandling getExceptionHandlingType() const
Context object for machine code objects.
This class manages callbacks registration, as well as provides a way for PassInstrumentation to pass ...
StringRef getPassNameForClassName(StringRef ClassName)
Get the pass name for a given pass class name.
LLVM_ATTRIBUTE_MINSIZE void addPass(PassT &&Pass)
bool isEmpty() const
Returns if the pass manager contains any passes.
Pass interface - Implemented by all 'passes'.
Pass (for the new pass manager) for printing a Function as LLVM's text IR assembly.
This is used to represent a portion of an LLVM function in a low-level Data Dependence DAG representa...
StringRef - Represent a constant reference to a string, i.e.
static Expected< StartStopInfo > getStartStopInfo(PassInstrumentationCallbacks &PIC)
Returns pass name in -stop-before or -stop-after NOTE: New pass manager migration only.
static bool willCompleteCodeGenPipeline()
Returns true if none of the -stop-before and -stop-after options is set.
An abstract base class for streams implementations that also support a pwrite operation.
unique_function is a type-erasing functor similar to std::function.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
@ C
The default llvm calling convention, compatible with C.
This is an optimization pass for GlobalISel generic memory operations.
PassManager< Function > FunctionPassManager
Convenience typedef for a pass manager over functions.
ModuleToFunctionPassAdaptor createModuleToFunctionPassAdaptor(FunctionPassT &&Pass, bool EagerlyInvalidate=false)
A function to deduce a function pass type and wrap it in the templated adaptor.
std::error_code inconvertibleErrorCode()
The value returned by this function can be returned from convertToErrorCode for Error values where no...
PassManager< MachineFunction > MachineFunctionPassManager
Convenience typedef for a pass manager over functions.
typename detail::detector< void, Op, Args... >::value_t is_detected
Detects if a given trait holds for some set of arguments 'Args'.
CodeGenFileType
These enums are meant to be passed into addPassesToEmitFile to indicate what type of file to emit,...
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
ModuleToMachineFunctionPassAdaptor createModuleToMachineFunctionPassAdaptor(MachineFunctionPassT &&Pass)
CodeGenOptLevel
Code generation optimization level.
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
std::enable_if_t< is_detected< HasRunOnLoopT, LoopPassT >::value, FunctionToLoopPassAdaptor > createFunctionToLoopPassAdaptor(LoopPassT &&Pass, bool UseMemorySSA=false, bool UseBlockFrequencyInfo=false, bool UseBranchProbabilityInfo=false)
A function to deduce a loop pass type and wrap it in the templated adaptor.
bool DisablePartialLibcallInlining
std::optional< bool > EnableGlobalISelOption
std::optional< bool > EnableIPRA
bool DisableConstantHoisting
std::optional< bool > OptimizeRegAlloc
RunOutliner EnableMachineOutliner
std::optional< bool > EnableFastISelOption
std::optional< GlobalISelAbortMode > EnableGlobalISelAbort
bool EnableImplicitNullChecks
bool EnableBlockPlacementStats
bool DisableSelectOptimize
A utility pass template to force an analysis result to be available.