LLVM 22.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"
14#include "SPIRV.h"
15#include "SPIRVCBufferAccess.h"
16#include "SPIRVGlobalRegistry.h"
17#include "SPIRVLegalizerInfo.h"
27#include "llvm/CodeGen/Passes.h"
31#include "llvm/Pass.h"
37#include <optional>
38
39using namespace llvm;
40
67
68static Reloc::Model getEffectiveRelocModel(std::optional<Reloc::Model> RM) {
69 if (!RM)
70 return Reloc::PIC_;
71 return *RM;
72}
73
74// Pin SPIRVTargetObjectFile's vtables to this file.
76
78 StringRef CPU, StringRef FS,
80 std::optional<Reloc::Model> RM,
81 std::optional<CodeModel::Model> CM,
82 CodeGenOptLevel OL, bool JIT)
83 : CodeGenTargetMachineImpl(T, TT.computeDataLayout(), TT, CPU, FS, Options,
85 getEffectiveCodeModel(CM, CodeModel::Small), OL),
86 TLOF(std::make_unique<SPIRVTargetObjectFile>()),
87 Subtarget(TT, CPU.str(), FS.str(), *this) {
89 setGlobalISel(true);
90 setFastISel(false);
91 setO0WantsFastISel(false);
93}
94
96#define GET_PASS_REGISTRY "SPIRVPassRegistry.def"
98}
99
100namespace {
101// SPIR-V Code Generator Pass Configuration Options.
102class SPIRVPassConfig : public TargetPassConfig {
103public:
104 SPIRVPassConfig(SPIRVTargetMachine &TM, PassManagerBase &PM)
105 : TargetPassConfig(TM, PM), TM(TM) {}
106
107 SPIRVTargetMachine &getSPIRVTargetMachine() const {
109 }
110 void addMachineSSAOptimization() override;
111 void addIRPasses() override;
112 void addISelPrepare() override;
113
114 bool addIRTranslator() override;
115 void addPreLegalizeMachineIR() override;
116 bool addLegalizeMachineIR() override;
117 bool addRegBankSelect() override;
118 bool addGlobalInstructionSelect() override;
119
120 FunctionPass *createTargetRegisterAllocator(bool) override;
121 void addFastRegAlloc() override {}
122 void addOptimizedRegAlloc() override {}
123
124 void addPostRegAlloc() override;
125 void addPreEmitPass() override;
126
127private:
128 const SPIRVTargetMachine &TM;
129};
130} // namespace
131
132// We do not use physical registers, and maintain virtual registers throughout
133// the entire pipeline, so return nullptr to disable register allocation.
134FunctionPass *SPIRVPassConfig::createTargetRegisterAllocator(bool) {
135 return nullptr;
136}
137
138// A place to disable passes that may break CFG.
139void SPIRVPassConfig::addMachineSSAOptimization() {
141}
142
143// Disable passes that break from assuming no virtual registers exist.
144void SPIRVPassConfig::addPostRegAlloc() {
145 // Do not work with vregs instead of physical regs.
146 disablePass(&MachineCopyPropagationID);
147 disablePass(&PostRAMachineSinkingID);
148 disablePass(&PostRASchedulerID);
149 disablePass(&FuncletLayoutID);
150 disablePass(&StackMapLivenessID);
151 disablePass(&PatchableFunctionID);
152 disablePass(&ShrinkWrapID);
153 disablePass(&LiveDebugValuesID);
154 disablePass(&MachineLateInstrsCleanupID);
155 disablePass(&RemoveLoadsIntoFakeUsesID);
156
157 // Do not work with OpPhi.
158 disablePass(&BranchFolderPassID);
159 disablePass(&MachineBlockPlacementID);
160
162}
163
166 return TargetTransformInfo(std::make_unique<SPIRVTTIImpl>(this, F));
167}
168
170 return new SPIRVPassConfig(*this, PM);
171}
172
173void SPIRVPassConfig::addIRPasses() {
175
179}
180
181void SPIRVPassConfig::addISelPrepare() {
182 if (TM.getSubtargetImpl()->isShader()) {
183 // Vulkan does not allow address space casts. This pass is run to remove
184 // address space casts that can be removed.
185 // If an address space cast is not removed while targeting Vulkan, lowering
186 // will fail during MIR lowering.
188
189 // 1. Simplify loop for subsequent transformations. After this steps, loops
190 // have the following properties:
191 // - loops have a single entry edge (pre-header to loop header).
192 // - all loop exits are dominated by the loop pre-header.
193 // - loops have a single back-edge.
194 addPass(createLoopSimplifyPass());
195
196 // 2. Removes registers whose lifetime spans across basic blocks. Also
197 // removes phi nodes. This will greatly simplify the next steps.
198 addPass(createRegToMemWrapperPass());
199
200 // 3. Merge the convergence region exit nodes into one. After this step,
201 // regions are single-entry, single-exit. This will help determine the
202 // correct merge block.
204
205 // 4. Structurize.
207
208 // 5. Reduce the amount of variables required by pushing some operations
209 // back to virtual registers.
211 }
212
216 addPass(
219 if (TM.getSubtargetImpl()->isLogicalSPIRV())
222}
223
224bool SPIRVPassConfig::addIRTranslator() {
225 addPass(new IRTranslator(getOptLevel()));
226 return false;
227}
228
229void SPIRVPassConfig::addPreLegalizeMachineIR() {
232}
233
234// Use the default legalizer.
235bool SPIRVPassConfig::addLegalizeMachineIR() {
236 addPass(new Legalizer());
238 return false;
239}
240
241// Do not add the RegBankSelect pass, as we only ever need virtual registers.
242bool SPIRVPassConfig::addRegBankSelect() {
243 disablePass(&RegBankSelect::ID);
244 return false;
245}
246
248 "spv-emit-nonsemantic-debug-info",
249 cl::desc("Emit SPIR-V NonSemantic.Shader.DebugInfo.100 instructions"),
250 cl::Optional, cl::init(false));
251
252void SPIRVPassConfig::addPreEmitPass() {
254 getSPIRVTargetMachine().getTargetTriple().getVendor() == Triple::AMD) {
256 }
257}
258
259namespace {
260// A custom subclass of InstructionSelect, which is mostly the same except from
261// not requiring RegBankSelect to occur previously.
262class SPIRVInstructionSelect : public InstructionSelect {
263 // We don't use register banks, so unset the requirement for them
264 MachineFunctionProperties getRequiredProperties() const override {
265 return InstructionSelect::getRequiredProperties().resetRegBankSelected();
266 }
267};
268} // namespace
269
270// Add the custom SPIRVInstructionSelect from above.
271bool SPIRVPassConfig::addGlobalInstructionSelect() {
272 addPass(new SPIRVInstructionSelect());
273 return false;
274}
static Reloc::Model getEffectiveRelocModel()
#define LLVM_ABI
Definition Compiler.h:213
#define LLVM_EXTERNAL_VISIBILITY
Definition Compiler.h:132
DXIL Legalizer
This file declares the IRTranslator pass.
#define F(x, y, z)
Definition MD5.cpp:54
#define T
PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC)
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("Emit SPIR-V NonSemantic.Shader.DebugInfo.100 instructions"), cl::Optional, cl::init(false))
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
Target-Independent Code Generator Pass Configuration Options pass.
CodeGenTargetMachineImpl(const Target &T, StringRef DataLayoutString, 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:314
This pass is responsible for selecting generic machine instructions to target-specific instructions.
MachineFunctionProperties getRequiredProperties() const override
This class provides access to building LLVM's passes.
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...
void registerPassBuilderCallbacks(PassBuilder &PB) override
Allow the target to modify the pass pipeline.
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)
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 ...
StringRef - Represent a constant reference to a string, i.e.
Definition StringRef.h:55
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:47
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)
void initializeSPIRVEmitIntrinsicsPass(PassRegistry &)
FunctionPass * createSPIRVStructurizerPass()
LLVM_ABI FunctionPass * createPromoteMemoryToRegisterPass()
Definition Mem2Reg.cpp:114
MachineFunctionPass * createSPIRVEmitNonSemanticDIPass(SPIRVTargetMachine *TM)
Target & getTheSPIRV32Target()
ModulePass * createSPIRVEmitIntrinsicsPass(SPIRVTargetMachine *TM)
void initializeSPIRVPrepareFunctionsPass(PassRegistry &)
LLVM_ABI FunctionPass * createRegToMemWrapperPass()
Definition Reg2Mem.cpp:146
FunctionPass * createSPIRVPreLegalizerPass()
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 initializeSPIRVMergeRegionExitTargetsPass(PassRegistry &)
FunctionPass * createSPIRVStripConvergenceIntrinsicsPass()
void initializeSPIRVPreLegalizerCombinerPass(PassRegistry &)
LLVM_ABI char & LiveDebugValuesID
LiveDebugValues pass.
void initializeSPIRVLegalizePointerCastPass(PassRegistry &)
FunctionPass * createSPIRVPreLegalizerCombiner()
void initializeSPIRVModuleAnalysisPass(PassRegistry &)
static Reloc::Model getEffectiveRelocModel(std::optional< Reloc::Model > RM)
FunctionPass * createSPIRVPostLegalizerPass()
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 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...
ModulePass * createSPIRVPrepareGlobalsPass()
void initializeSPIRVRegularizerPass(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.
CodeGenOptLevel
Code generation optimization level.
Definition CodeGen.h:82
Target & getTheSPIRV64Target()
void initializeSPIRVPostLegalizerPass(PassRegistry &)
void initializeSPIRVCBufferAccessLegacyPass(PassRegistry &)
ModulePass * createSPIRVCBufferAccessLegacyPass()
LLVM_ABI void initializeGlobalISel(PassRegistry &)
Initialize all passes linked into the GlobalISel library.
Target & getTheSPIRVLogicalTarget()
void initializeSPIRVAsmPrinterPass(PassRegistry &)
FunctionPass * createSPIRVRegularizerPass()
void initializeSPIRVStructurizerPass(PassRegistry &)
void initializeSPIRVEmitNonSemanticDIPass(PassRegistry &)
FunctionPass * createSPIRVMergeRegionExitTargetsPass()
LLVM_ABI FunctionPass * createInferAddressSpacesPass(unsigned AddressSpace=~0u)
void initializeSPIRVPreLegalizerPass(PassRegistry &)
void initializeSPIRVConvergenceRegionAnalysisWrapperPassPass(PassRegistry &)
LLVM_ABI char & MachineBlockPlacementID
MachineBlockPlacement - This pass places basic blocks based on branch probabilities.
LLVM_ABI char & BranchFolderPassID
BranchFolding - This pass performs machine code CFG based optimizations to delete branches to branche...
ModulePass * createSPIRVPrepareFunctionsPass(const SPIRVTargetMachine &TM)
void initializeSPIRVPrepareGlobalsPass(PassRegistry &)
FunctionPass * createSPIRVLegalizePointerCastPass(SPIRVTargetMachine *TM)
LLVM_ABI Pass * createLoopSimplifyPass()
LLVM_ABI char & MachineCopyPropagationID
MachineCopyPropagation - This pass performs copy propagation on machine instructions.
void initializeSPIRVStripConvergentIntrinsicsPass(PassRegistry &)
ModulePass * createSPIRVLegalizeImplicitBindingPass()
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:870
RegisterTargetMachine - Helper template for registering a target machine implementation,...