[llvm] [CodeGen] Let `CodeGenPassBuilder` know concrete target machine (PR #88614)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Apr 13 04:12:52 PDT 2024
https://github.com/paperchalice created https://github.com/llvm/llvm-project/pull/88614
Many backends passes accept only `<Target>TargetMachine`, this can avoid cast to derived type.
>From 451cf4e0ae4bf36db6f971d1e45841b990c1fa41 Mon Sep 17 00:00:00 2001
From: PaperChalice <liujunchang97 at outlook.com>
Date: Sat, 13 Apr 2024 19:09:06 +0800
Subject: [PATCH] [CodeGen] Let `CodeGenPassBuilder` know concrete target
machine Many backends passes accept only `<Target>TargetMachine`, this can
prevent cast to derived type.
---
llvm/include/llvm/Passes/CodeGenPassBuilder.h | 107 +++++++++---------
llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp | 5 +-
2 files changed, 59 insertions(+), 53 deletions(-)
diff --git a/llvm/include/llvm/Passes/CodeGenPassBuilder.h b/llvm/include/llvm/Passes/CodeGenPassBuilder.h
index ed5d8affa79380..2e94a19502131a 100644
--- a/llvm/include/llvm/Passes/CodeGenPassBuilder.h
+++ b/llvm/include/llvm/Passes/CodeGenPassBuilder.h
@@ -109,9 +109,9 @@ namespace llvm {
/// construction. The \c MachinePassRegistry.def file specifies how to construct
/// all of the built-in passes, and those may reference these members during
/// construction.
-template <typename DerivedT> class CodeGenPassBuilder {
+template <typename DerivedT, typename TargetMachineT> class CodeGenPassBuilder {
public:
- explicit CodeGenPassBuilder(LLVMTargetMachine &TM,
+ explicit CodeGenPassBuilder(TargetMachineT &TM,
const CGPassBuilderOption &Opts,
PassInstrumentationCallbacks *PIC)
: TM(TM), Opt(Opts), PIC(PIC) {
@@ -237,7 +237,7 @@ template <typename DerivedT> class CodeGenPassBuilder {
const DerivedT &PB;
};
- LLVMTargetMachine &TM;
+ TargetMachineT &TM;
CGPassBuilderOption Opt;
PassInstrumentationCallbacks *PIC;
@@ -498,8 +498,8 @@ template <typename DerivedT> class CodeGenPassBuilder {
mutable bool Stopped = true;
};
-template <typename Derived>
-Error CodeGenPassBuilder<Derived>::buildPipeline(
+template <typename Derived, typename TargetMachineT>
+Error CodeGenPassBuilder<Derived, TargetMachineT>::buildPipeline(
ModulePassManager &MPM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut,
CodeGenFileType FileType) const {
auto StartStopInfo = TargetPassConfig::getStartStopInfo(*PIC);
@@ -542,8 +542,8 @@ Error CodeGenPassBuilder<Derived>::buildPipeline(
return verifyStartStop(*StartStopInfo);
}
-template <typename Derived>
-void CodeGenPassBuilder<Derived>::setStartStopPasses(
+template <typename Derived, typename TargetMachineT>
+void CodeGenPassBuilder<Derived, TargetMachineT>::setStartStopPasses(
const TargetPassConfig::StartStopInfo &Info) const {
if (!Info.StartPass.empty()) {
Started = false;
@@ -585,8 +585,8 @@ void CodeGenPassBuilder<Derived>::setStartStopPasses(
}
}
-template <typename Derived>
-Error CodeGenPassBuilder<Derived>::verifyStartStop(
+template <typename Derived, typename TargetMachineT>
+Error CodeGenPassBuilder<Derived, TargetMachineT>::verifyStartStop(
const TargetPassConfig::StartStopInfo &Info) const {
if (Started && Stopped)
return Error::success();
@@ -604,8 +604,9 @@ Error CodeGenPassBuilder<Derived>::verifyStartStop(
return Error::success();
}
-template <typename Derived>
-void CodeGenPassBuilder<Derived>::addISelPasses(AddIRPass &addPass) const {
+template <typename Derived, typename TargetMachineT>
+void CodeGenPassBuilder<Derived, TargetMachineT>::addISelPasses(
+ AddIRPass &addPass) const {
derived().addGlobalMergePass(addPass);
if (TM.useEmulatedTLS())
addPass(LowerEmuTLSPass());
@@ -620,8 +621,9 @@ void CodeGenPassBuilder<Derived>::addISelPasses(AddIRPass &addPass) const {
/// Add common target configurable passes that perform LLVM IR to IR transforms
/// following machine independent optimization.
-template <typename Derived>
-void CodeGenPassBuilder<Derived>::addIRPasses(AddIRPass &addPass) const {
+template <typename Derived, typename TargetMachineT>
+void CodeGenPassBuilder<Derived, TargetMachineT>::addIRPasses(
+ AddIRPass &addPass) const {
// Before running any passes, run the verifier to determine if the input
// coming from the front-end and/or optimizer is valid.
if (!Opt.DisableVerify)
@@ -686,8 +688,8 @@ void CodeGenPassBuilder<Derived>::addIRPasses(AddIRPass &addPass) const {
/// Turn exception handling constructs into something the code generators can
/// handle.
-template <typename Derived>
-void CodeGenPassBuilder<Derived>::addPassesToHandleExceptions(
+template <typename Derived, typename TargetMachineT>
+void CodeGenPassBuilder<Derived, TargetMachineT>::addPassesToHandleExceptions(
AddIRPass &addPass) const {
const MCAsmInfo *MCAI = TM.getMCAsmInfo();
assert(MCAI && "No MCAsmInfo");
@@ -733,8 +735,9 @@ void CodeGenPassBuilder<Derived>::addPassesToHandleExceptions(
/// Add pass to prepare the LLVM IR for code generation. This should be done
/// before exception handling preparation passes.
-template <typename Derived>
-void CodeGenPassBuilder<Derived>::addCodeGenPrepare(AddIRPass &addPass) const {
+template <typename Derived, typename TargetMachineT>
+void CodeGenPassBuilder<Derived, TargetMachineT>::addCodeGenPrepare(
+ AddIRPass &addPass) const {
if (getOptLevel() != CodeGenOptLevel::None && !Opt.DisableCGP)
addPass(CodeGenPreparePass(&TM));
// TODO: Default ctor'd RewriteSymbolPass is no-op.
@@ -743,8 +746,9 @@ void CodeGenPassBuilder<Derived>::addCodeGenPrepare(AddIRPass &addPass) const {
/// Add common passes that perform LLVM IR to IR transforms in preparation for
/// instruction selection.
-template <typename Derived>
-void CodeGenPassBuilder<Derived>::addISelPrepare(AddIRPass &addPass) const {
+template <typename Derived, typename TargetMachineT>
+void CodeGenPassBuilder<Derived, TargetMachineT>::addISelPrepare(
+ AddIRPass &addPass) const {
derived().addPreISel(addPass);
addPass(CallBrPreparePass());
@@ -763,8 +767,8 @@ void CodeGenPassBuilder<Derived>::addISelPrepare(AddIRPass &addPass) const {
addPass(VerifierPass());
}
-template <typename Derived>
-Error CodeGenPassBuilder<Derived>::addCoreISelPasses(
+template <typename Derived, typename TargetMachineT>
+Error CodeGenPassBuilder<Derived, TargetMachineT>::addCoreISelPasses(
AddMachinePass &addPass) const {
// Enable FastISel with -fast-isel, but allow that to be overridden.
TM.setO0WantsFastISel(Opt.EnableFastISelOption.value_or(true));
@@ -846,17 +850,18 @@ Error CodeGenPassBuilder<Derived>::addCoreISelPasses(
/// with nontrivial configuration or multiple passes are broken out below in
/// add%Stage routines.
///
-/// Any CodeGenPassBuilder<Derived>::addXX routine may be overriden by the
-/// Target. The addPre/Post methods with empty header implementations allow
-/// injecting target-specific fixups just before or after major stages.
-/// Additionally, targets have the flexibility to change pass order within a
-/// stage by overriding default implementation of add%Stage routines below. Each
-/// technique has maintainability tradeoffs because alternate pass orders are
-/// not well supported. addPre/Post works better if the target pass is easily
-/// tied to a common pass. But if it has subtle dependencies on multiple passes,
-/// the target should override the stage instead.
-template <typename Derived>
-Error CodeGenPassBuilder<Derived>::addMachinePasses(
+/// Any CodeGenPassBuilder<Derived, TargetMachine>::addXX routine may be
+/// overriden by the Target. The addPre/Post methods with empty header
+/// implementations allow injecting target-specific fixups just before or after
+/// major stages. Additionally, targets have the flexibility to change pass
+/// order within a stage by overriding default implementation of add%Stage
+/// routines below. Each technique has maintainability tradeoffs because
+/// alternate pass orders are not well supported. addPre/Post works better if
+/// the target pass is easily tied to a common pass. But if it has subtle
+/// dependencies on multiple passes, the target should override the stage
+/// instead.
+template <typename Derived, typename TargetMachineT>
+Error CodeGenPassBuilder<Derived, TargetMachineT>::addMachinePasses(
AddMachinePass &addPass) const {
// Add passes that optimize machine instructions in SSA form.
if (getOptLevel() != CodeGenOptLevel::None) {
@@ -962,8 +967,8 @@ Error CodeGenPassBuilder<Derived>::addMachinePasses(
}
/// Add passes that optimize machine instructions in SSA form.
-template <typename Derived>
-void CodeGenPassBuilder<Derived>::addMachineSSAOptimization(
+template <typename Derived, typename TargetMachineT>
+void CodeGenPassBuilder<Derived, TargetMachineT>::addMachineSSAOptimization(
AddMachinePass &addPass) const {
// Pre-ra tail duplication.
addPass(EarlyTailDuplicatePass());
@@ -1014,8 +1019,8 @@ void CodeGenPassBuilder<Derived>::addMachineSSAOptimization(
/// A target that uses the standard regalloc pass order for fast or optimized
/// allocation may still override this for per-target regalloc
/// selection. But -regalloc=... always takes precedence.
-template <typename Derived>
-void CodeGenPassBuilder<Derived>::addTargetRegisterAllocator(
+template <typename Derived, typename TargetMachineT>
+void CodeGenPassBuilder<Derived, TargetMachineT>::addTargetRegisterAllocator(
AddMachinePass &addPass, bool Optimized) const {
if (Optimized)
addPass(RAGreedyPass());
@@ -1026,22 +1031,22 @@ void CodeGenPassBuilder<Derived>::addTargetRegisterAllocator(
/// Find and instantiate the register allocation pass requested by this target
/// at the current optimization level. Different register allocators are
/// defined as separate passes because they may require different analysis.
-template <typename Derived>
-void CodeGenPassBuilder<Derived>::addRegAllocPass(AddMachinePass &addPass,
- bool Optimized) const {
+template <typename Derived, typename TargetMachineT>
+void CodeGenPassBuilder<Derived, TargetMachineT>::addRegAllocPass(
+ AddMachinePass &addPass, bool Optimized) const {
// TODO: Parse Opt.RegAlloc to add register allocator.
}
-template <typename Derived>
-Error CodeGenPassBuilder<Derived>::addRegAssignmentFast(
+template <typename Derived, typename TargetMachineT>
+Error CodeGenPassBuilder<Derived, TargetMachineT>::addRegAssignmentFast(
AddMachinePass &addPass) const {
// TODO: Ensure allocator is default or fast.
addRegAllocPass(addPass, false);
return Error::success();
}
-template <typename Derived>
-Error CodeGenPassBuilder<Derived>::addRegAssignmentOptimized(
+template <typename Derived, typename TargetMachineT>
+Error CodeGenPassBuilder<Derived, TargetMachineT>::addRegAssignmentOptimized(
AddMachinePass &addPass) const {
// Add the selected register allocation pass.
addRegAllocPass(addPass, true);
@@ -1062,8 +1067,8 @@ Error CodeGenPassBuilder<Derived>::addRegAssignmentOptimized(
/// Add the minimum set of target-independent passes that are required for
/// register allocation. No coalescing or scheduling.
-template <typename Derived>
-Error CodeGenPassBuilder<Derived>::addFastRegAlloc(
+template <typename Derived, typename TargetMachineT>
+Error CodeGenPassBuilder<Derived, TargetMachineT>::addFastRegAlloc(
AddMachinePass &addPass) const {
addPass(PHIEliminationPass());
addPass(TwoAddressInstructionPass());
@@ -1073,8 +1078,8 @@ Error CodeGenPassBuilder<Derived>::addFastRegAlloc(
/// Add standard target-independent passes that are tightly coupled with
/// optimized register allocation, including coalescing, machine instruction
/// scheduling, and register allocation itself.
-template <typename Derived>
-void CodeGenPassBuilder<Derived>::addOptimizedRegAlloc(
+template <typename Derived, typename TargetMachineT>
+void CodeGenPassBuilder<Derived, TargetMachineT>::addOptimizedRegAlloc(
AddMachinePass &addPass) const {
addPass(DetectDeadLanesPass());
@@ -1121,8 +1126,8 @@ void CodeGenPassBuilder<Derived>::addOptimizedRegAlloc(
//===---------------------------------------------------------------------===//
/// Add passes that optimize machine instructions after register allocation.
-template <typename Derived>
-void CodeGenPassBuilder<Derived>::addMachineLateOptimization(
+template <typename Derived, typename TargetMachineT>
+void CodeGenPassBuilder<Derived, TargetMachineT>::addMachineLateOptimization(
AddMachinePass &addPass) const {
// Branch folding must be run after regalloc and prolog/epilog insertion.
addPass(BranchFolderPass());
@@ -1142,8 +1147,8 @@ void CodeGenPassBuilder<Derived>::addMachineLateOptimization(
}
/// Add standard basic block placement passes.
-template <typename Derived>
-void CodeGenPassBuilder<Derived>::addBlockPlacement(
+template <typename Derived, typename TargetMachineT>
+void CodeGenPassBuilder<Derived, TargetMachineT>::addBlockPlacement(
AddMachinePass &addPass) const {
addPass(MachineBlockPlacementPass());
// Run a separate pass to collect block placement statistics.
diff --git a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
index 453754381034e3..7c1fb0b99f4136 100644
--- a/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
+++ b/llvm/lib/Target/X86/X86CodeGenPassBuilder.cpp
@@ -19,9 +19,10 @@ using namespace llvm;
namespace {
-class X86CodeGenPassBuilder : public CodeGenPassBuilder<X86CodeGenPassBuilder> {
+class X86CodeGenPassBuilder
+ : public CodeGenPassBuilder<X86CodeGenPassBuilder, X86TargetMachine> {
public:
- explicit X86CodeGenPassBuilder(LLVMTargetMachine &TM,
+ explicit X86CodeGenPassBuilder(X86TargetMachine &TM,
const CGPassBuilderOption &Opts,
PassInstrumentationCallbacks *PIC)
: CodeGenPassBuilder(TM, Opts, PIC) {}
More information about the llvm-commits
mailing list