LLVM 24.0.0git
SPIRVTargetMachine.cpp
Go to the documentation of this file.
1//===- SPIRVTargetMachine.cpp - Define TargetMachine for SPIR-V -*- C++ -*-===//
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//
9// Implements the info about SPIR-V target spec.
10//
11//===----------------------------------------------------------------------===//
12
13#include "SPIRVTargetMachine.h"
15#include "SPIRV.h"
16#include "SPIRVGlobalRegistry.h"
17#include "SPIRVLegalizerInfo.h"
26#include "llvm/CodeGen/Passes.h"
30#include "llvm/Pass.h"
38#include <optional>
39
40using namespace llvm;
41
71
72static Reloc::Model getEffectiveRelocModel(std::optional<Reloc::Model> RM) {
73 if (!RM)
74 return Reloc::PIC_;
75 return *RM;
76}
77
78// Pin SPIRVTargetObjectFile's vtables to this file.
80
82 StringRef CPU, StringRef FS,
84 std::optional<Reloc::Model> RM,
85 std::optional<CodeModel::Model> CM,
86 CodeGenOptLevel OL, bool JIT)
87 : CodeGenTargetMachineImpl(T, TT, CPU, FS, Options,
89 getEffectiveCodeModel(CM, CodeModel::Small), OL),
90 TLOF(std::make_unique<SPIRVTargetObjectFile>()),
91 Subtarget(TT, CPU.str(), FS.str(), *this) {
93 setGlobalISel(true);
94 setFastISel(false);
95 setO0WantsFastISel(false);
97}
98
99namespace {
100// SPIR-V Code Generator Pass Configuration Options.
101class SPIRVPassConfig : public TargetPassConfig {
102public:
103 SPIRVPassConfig(SPIRVTargetMachine &TM, PassManagerBase &PM)
104 : TargetPassConfig(TM, PM), TM(TM) {}
105
106 void addMachineSSAOptimization() override;
107 void addIRPasses() override;
108 void addISelPrepare() override;
109
110 bool addIRTranslator() override;
111 void addPreLegalizeMachineIR() override;
112 bool addLegalizeMachineIR() override;
113 bool addRegBankSelect() override;
114 bool addGlobalInstructionSelect() override;
115
116 FunctionPass *createTargetRegisterAllocator(bool) override;
117 void addFastRegAlloc() override {}
118 void addOptimizedRegAlloc() override {}
119
120 void addPostRegAlloc() override;
121 void addPreEmitPass2() override;
122
123private:
124 const SPIRVTargetMachine &TM;
125};
126} // namespace
127
128// We do not use physical registers, and maintain virtual registers throughout
129// the entire pipeline, so return nullptr to disable register allocation.
130FunctionPass *SPIRVPassConfig::createTargetRegisterAllocator(bool) {
131 return nullptr;
132}
133
134// A place to disable passes that may break CFG.
135void SPIRVPassConfig::addMachineSSAOptimization() {
137}
138
139// Disable passes that break from assuming no virtual registers exist.
140void SPIRVPassConfig::addPostRegAlloc() {
141 // Do not work with vregs instead of physical regs.
142 disablePass(&MachineCopyPropagationID);
143 disablePass(&PostRAMachineSinkingID);
144 disablePass(&PostRASchedulerID);
145 disablePass(&FuncletLayoutID);
146 disablePass(&StackMapLivenessID);
147 disablePass(&PatchableFunctionID);
148 disablePass(&ShrinkWrapID);
149 disablePass(&LiveDebugValuesID);
150 disablePass(&MachineLateInstrsCleanupID);
151 disablePass(&RemoveLoadsIntoFakeUsesID);
152
153 // Do not work with OpPhi.
154 disablePass(&BranchFolderPassID);
155 disablePass(&MachineBlockPlacementID);
156
158}
159
160void SPIRVPassConfig::addPreEmitPass2() {
162}
163
166 return TargetTransformInfo(std::make_unique<SPIRVTTIImpl>(this, F));
167}
168
170 return new SPIRVPassConfig(*this, PM);
171}
172
173// CSE can merge same-LLT values with different SPIR-V types.
177
178void SPIRVPassConfig::addIRPasses() {
180
182
183 if (TM.getSubtargetImpl()->isShader()) {
184 if (getOptLevel() != CodeGenOptLevel::None)
186 } else {
187 // Variadic function calls aren't supported in shader code.
188 // This needs to come before SPIRVPrepareFunctions because this
189 // may introduce intrinsic calls.
191 }
192
197}
198
199void SPIRVPassConfig::addISelPrepare() {
200 if (TM.getSubtargetImpl()->isShader()) {
201 // Vulkan does not allow address space casts. This pass is run to remove
202 // address space casts that can be removed.
203 // If an address space cast is not removed while targeting Vulkan, lowering
204 // will fail during MIR lowering.
206
207 // 1. Simplify loop for subsequent transformations. After this steps, loops
208 // have the following properties:
209 // - loops have a single entry edge (pre-header to loop header).
210 // - all loop exits are dominated by the loop pre-header.
211 // - loops have a single back-edge.
212 addPass(createLoopSimplifyPass());
213
214 // 2. Removes registers whose lifetime spans across basic blocks. Also
215 // removes phi nodes. This will greatly simplify the next steps.
216 addPass(createRegToMemWrapperPass());
217
218 // 3. Merge the convergence region exit nodes into one. After this step,
219 // regions are single-entry, single-exit. This will help determine the
220 // correct merge block.
222
223 // 4. Structurize.
225
226 // 5. Reduce the amount of variables required by pushing some operations
227 // back to virtual registers.
229 } else {
230 // Canonicalize loops so they have a single latch and preheader.
231 // This enables OpLoopMerge emission for non-shader targets.
232 addPass(createLoopSimplifyPass());
233 }
244}
245
246bool SPIRVPassConfig::addIRTranslator() {
247 addPass(new IRTranslatorLegacy(getOptLevel()));
248 return false;
249}
250
251void SPIRVPassConfig::addPreLegalizeMachineIR() {
254}
255
256// Use the default legalizer.
257bool SPIRVPassConfig::addLegalizeMachineIR() {
258 addPass(new LegalizerLegacy());
260 return false;
261}
262
263// Do not add the RegBankSelect pass, as we only ever need virtual registers.
264bool SPIRVPassConfig::addRegBankSelect() {
265 disablePass(&RegBankSelectLegacy::ID);
266 return false;
267}
268
269// Deprecated flag kept for backward compatibility. NSDI emission is now handled
270// by SPIRVNonSemanticDebugHandler, registered in SPIRVAsmPrinter::
271// doInitialization() when the module contains debug info (llvm.dbg.cu).
272// TODO: Remove this option after a deprecation period. Callers that used
273// -spv-emit-nonsemantic-debug-info should switch to -g.
275 "spv-emit-nonsemantic-debug-info",
276 cl::desc("Deprecated. Use -g to emit SPIR-V NonSemantic.Shader.DebugInfo "
277 "instructions"),
278 cl::init(false));
279
280// Add the custom SPIRVInstructionSelect from above.
281bool SPIRVPassConfig::addGlobalInstructionSelect() {
282 addPass(new InstructionSelectLegacy(getOptLevel(),
283 /*RequireRegBankSelection=*/false));
284 return false;
285}
static Reloc::Model getEffectiveRelocModel()
#define X(NUM, ENUM, NAME)
Definition ELF.h:665
#define LLVM_ABI
Definition Compiler.h:211
#define LLVM_EXTERNAL_VISIBILITY
Definition Compiler.h:132
This file declares the IRTranslator pass.
#define F(x, y, z)
Definition MD5.cpp:54
#define T
This file describes the interface of the MachineFunctionPass responsible for assigning the generic vi...
const GCNTargetMachine & getTM(const GCNSubtarget *STI)
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeSPIRVTarget()
static cl::opt< bool > SPVEnableNonSemanticDI("spv-emit-nonsemantic-debug-info", cl::desc("Deprecated. Use -g to emit SPIR-V NonSemantic.Shader.DebugInfo " "instructions"), cl::init(false))
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
Target-Independent Code Generator Pass Configuration Options pass.
CodeGenTargetMachineImpl(const Target &T, const Triple &TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, CodeGenOptLevel OL)
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:312
This pass is responsible for selecting generic machine instructions to target-specific instructions.
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
bool isLogicalSPIRV() const
SPIRVTargetMachine(const Target &T, const Triple &TT, StringRef CPU, StringRef FS, const TargetOptions &Options, std::optional< Reloc::Model > RM, std::optional< CodeModel::Model > CM, CodeGenOptLevel OL, bool JIT)
const SPIRVSubtarget * getSubtargetImpl() const
TargetTransformInfo getTargetTransformInfo(const Function &F) const override
Get a TargetTransformInfo implementation for the target.
TargetPassConfig * createPassConfig(PassManagerBase &PM) override
Create a pass configuration object to be used by addPassToEmitX methods for generating a pipeline of ...
CSEConfigBase * createCSEConfig() const override
GlobalISel CSEConfig for the new PM. Return NULL for the standard one.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
void setFastISel(bool Enable)
void setRequiresStructuredCFG(bool Value)
void setGlobalISel(bool Enable)
TargetOptions Options
void setO0WantsFastISel(bool Enable)
Target-Independent Code Generator Pass Configuration Options.
virtual void addPostRegAlloc()
This method may be implemented by targets that want to run passes after register allocation pass pipe...
virtual void addIRPasses()
Add common target configurable passes that perform LLVM IR to IR transforms following machine indepen...
virtual void addMachineSSAOptimization()
addMachineSSAOptimization - Add standard passes that optimize machine instructions in SSA form.
virtual void addISelPrepare()
Add common passes that perform LLVM IR to IR transforms in preparation for instruction selection.
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
Target - Wrapper for Target specific information.
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
PassManagerBase - An abstract interface to allow code to add passes to a pass manager without having ...
Interfaces for registering analysis passes, producing common pass manager configurations,...
initializer< Ty > init(const Ty &Val)
This is an optimization pass for GlobalISel generic memory operations.
ModulePass * createSPIRVPushConstantAccessLegacyPass(SPIRVTargetMachine *TM)
ModulePass * createSPIRVCtorDtorLoweringLegacyPass()
FunctionPass * createSPIRVStructurizerPass()
ModulePass * createSPIRVEmitIntrinsicsPass(const SPIRVTargetMachine &TM)
LLVM_ABI FunctionPass * createPromoteMemoryToRegisterPass()
Definition Mem2Reg.cpp:114
Target & getTheSPIRV32Target()
LLVM_ABI FunctionPass * createRegToMemWrapperPass()
Definition Reg2Mem.cpp:141
void initializeSPIRVPushConstantAccessLegacyPass(PassRegistry &)
LLVM_ABI char & PatchableFunctionID
This pass implements the "patchable-function" attribute.
LLVM_ABI char & PostRASchedulerID
PostRAScheduler - This pass performs post register allocation scheduling.
LLVM_ABI char & RemoveLoadsIntoFakeUsesID
RemoveLoadsIntoFakeUses pass.
void initializeSPIRVLegalizePointerCastLegacyPass(PassRegistry &)
void initializeSPIRVPrepareFunctionsLegacyPass(PassRegistry &)
LLVM_ABI char & LiveDebugValuesID
LiveDebugValues pass.
static Reloc::Model getEffectiveRelocModel(std::optional< Reloc::Model > RM)
FunctionPass * createSPIRVPreLegalizerCombinerLegacyPass()
CodeModel::Model getEffectiveCodeModel(std::optional< CodeModel::Model > CM, CodeModel::Model Default)
Helper method for getting the code model, returning Default if CM does not have a value.
LLVM_ABI ModulePass * createExpandVariadicsPass(ExpandVariadicsMode)
FunctionPass * createSPIRVPostLegalizerLegacyPass()
LLVM_ABI char & ShrinkWrapID
ShrinkWrap pass. Look for the best place to insert save and restore.
LLVM_ABI char & MachineLateInstrsCleanupID
MachineLateInstrsCleanup - This pass removes redundant identical instructions after register allocati...
void initializeSPIRVLegalizeZeroSizeArraysLegacyPass(PassRegistry &)
ModulePass * createSPIRVFinalizeShaderLinkagePass(const SPIRVTargetMachine &TM)
ModulePass * createSPIRVPrepareGlobalsPass()
void initializeSPIRVEmitIntrinsicsLegacyPass(PassRegistry &)
LLVM_ABI char & StackMapLivenessID
StackMapLiveness - This pass analyses the register live-out set of stackmap/patchpoint intrinsics and...
LLVM_ABI char & FuncletLayoutID
This pass lays out funclets contiguously.
LLVM_ABI char & PostRAMachineSinkingID
This pass perform post-ra machine sink for COPY instructions.
FunctionPass * createSPIRVPrepareModuleAnalysisLegacyPass()
CodeGenOptLevel
Code generation optimization level.
Definition CodeGen.h:280
Target & getTheSPIRV64Target()
void initializeSPIRVPrepareModuleAnalysisLegacyPass(PassRegistry &)
ModulePass * createSPIRVLegalizeZeroSizeArraysPass(const SPIRVTargetMachine &TM)
LLVM_ABI FunctionPass * createStripConvergenceIntrinsicsPass()
void initializeSPIRVCBufferAccessLegacyPass(PassRegistry &)
ModulePass * createSPIRVCBufferAccessLegacyPass()
LLVM_ABI void initializeGlobalISel(PassRegistry &)
Initialize all passes linked into the GlobalISel library.
void initializeSPIRVPostLegalizerLegacyPass(PassRegistry &)
void initializeSPIRVModuleAnalysisWrapperPassPass(PassRegistry &)
void initializeSPIRVPrepareGlobalsLegacyPass(PassRegistry &)
Target & getTheSPIRVLogicalTarget()
void initializeSPIRVAsmPrinterPass(PassRegistry &)
void initializeSPIRVRegularizerLegacyPass(PassRegistry &)
FunctionPass * createSPIRVRegularizerPass()
void initializeSPIRVStructurizerPass(PassRegistry &)
FunctionPass * createSPIRVMergeRegionExitTargetsPass()
LLVM_ABI FunctionPass * createInferAddressSpacesPass(unsigned AddressSpace=~0u)
void initializeSPIRVPreLegalizerCombinerLegacyPass(PassRegistry &)
void initializeSPIRVPreLegalizerLegacyPass(PassRegistry &)
FunctionPass * createSPIRVPreLegalizerLegacyPass()
void initializeSPIRVConvergenceRegionAnalysisWrapperPassPass(PassRegistry &)
LLVM_ABI char & MachineBlockPlacementID
MachineBlockPlacement - This pass places basic blocks based on branch probabilities.
LLVM_ABI FunctionPass * createAtomicExpandLegacyPass()
AtomicExpandPass - At IR level this pass replace atomic instructions with __atomic_* library calls,...
LLVM_ABI char & BranchFolderPassID
BranchFolding - This pass performs machine code CFG based optimizations to delete branches to branche...
ModulePass * createSPIRVPrepareFunctionsPass(const SPIRVTargetMachine &TM)
FunctionPass * createSPIRVLegalizePointerCastPass(SPIRVTargetMachine *TM)
LLVM_ABI Pass * createLoopSimplifyPass()
ModulePass * createSPIRVLegalizeResourceBindingPass()
void initializeSPIRVCtorDtorLoweringLegacyPass(PassRegistry &)
LLVM_ABI char & MachineCopyPropagationID
MachineCopyPropagation - This pass performs copy propagation on machine instructions.
void initializeSPIRVMergeRegionExitTargetsLegacyPass(PassRegistry &)
void initializeSPIRVLegalizeResourceBindingLegacyPass(PassRegistry &)
void initializeSPIRVFinalizeShaderLinkageLegacyPass(PassRegistry &)
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:878
RegisterTargetMachine - Helper template for registering a target machine implementation,...