LLVM 24.0.0git
SPIRVCodeGenPassBuilder.cpp
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
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
10#include "SPIRV.h"
11#include "SPIRVAsmPrinter.h"
12#include "SPIRVModuleAnalysis.h"
13#include "SPIRVTargetMachine.h"
39
40using namespace llvm;
41
42namespace {
43
44class SPIRVCodeGenPassBuilder : public CodeGenPassBuilder {
45 using Base = CodeGenPassBuilder;
46
47 SPIRVTargetMachine &getTM() const {
48 return static_cast<SPIRVTargetMachine &>(TM);
49 }
50
51public:
52 explicit SPIRVCodeGenPassBuilder(SPIRVTargetMachine &TM,
53 const CGPassBuilderOption &Opts,
54 PassInstrumentationCallbacks *PIC)
55 : CodeGenPassBuilder(TM, Opts, PIC) {
56 // Disable passes that break from assuming no virtual registers exist.
57 disablePass<MachineCopyPropagationPass, PostRAMachineSinkingPass,
58 PostRASchedulerPass, FuncletLayoutPass, StackMapLivenessPass,
59 PatchableFunctionPass, ShrinkWrapPass, LiveDebugValuesPass,
60 MachineLateInstrsCleanupPass, RemoveLoadsIntoFakeUsesPass,
61 BranchFolderPass, MachineBlockPlacementPass>();
62 }
63
64 void addIRPasses(PassManagerWrapper &PMW) override;
65 void addISelPrepare(PassManagerWrapper &PMW) override;
66 Error addIRTranslator(PassManagerWrapper &PMW) override;
67 void addPreLegalizeMachineIR(PassManagerWrapper &PMW) override;
68 Error addLegalizeMachineIR(PassManagerWrapper &PMW) override;
69 Error addRegBankSelect(PassManagerWrapper &PMW) override;
70 Error addGlobalInstructionSelect(PassManagerWrapper &PMW) override;
71
72 Error addFastRegAlloc(PassManagerWrapper &PMW) override;
73
74 Error addOptimizedRegAlloc(PassManagerWrapper &PMW) override;
75
76 void addPreEmitPass2(PassManagerWrapper &PMW) override;
77
78 void addAsmPrinterBegin(PassManagerWrapper &PMW) override;
79 void addAsmPrinter(PassManagerWrapper &PMW) override;
80 void addAsmPrinterEnd(PassManagerWrapper &PMW) override;
81};
82
83void SPIRVCodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) {
84 addFunctionPass(AtomicExpandPass(TM), PMW);
85
86 Base::addIRPasses(PMW);
87
88 flushFPMsToMPM(PMW);
89
90 if (getTM().getSubtargetImpl()->isShader()) {
91 if (getOptLevel() != CodeGenOptLevel::None) {
92 addModulePass(SPIRVFinalizeShaderLinkagePass(getTM()), PMW);
93 }
94 } else {
95 // Variadic function calls aren't supported in shader code.
96 // This needs to come before SPIRVPrepareFunctions because this
97 // may introduce intrinsic calls.
98 addModulePass(ExpandVariadicsPass(ExpandVariadicsMode::Lowering), PMW);
99 }
100
101 addFunctionPass(SPIRVRegularizerPass(), PMW);
102 flushFPMsToMPM(PMW);
103 addModulePass(SPIRVCtorDtorLoweringPass(), PMW);
104 addModulePass(SPIRVPrepareFunctionsPass(getTM()), PMW);
105 addModulePass(SPIRVPrepareGlobalsPass(), PMW);
106}
107
108void SPIRVCodeGenPassBuilder::addISelPrepare(PassManagerWrapper &PMW) {
109 SPIRVTargetMachine &TM = getTM();
110 if (getTM().getSubtargetImpl()->isShader()) {
111 // Vulkan does not allow address space casts. This pass is run to remove
112 // address space casts that can be removed.
113 // If an address space cast is not removed while targeting Vulkan, lowering
114 // will fail during MIR lowering.
115 addFunctionPass(InferAddressSpacesPass(), PMW);
116
117 // 1. Simplify loop for subsequent transformations. After this steps, loops
118 // have the following properties:
119 // - loops have a single entry edge (pre-header to loop header).
120 // - all loop exits are dominated by the loop pre-header.
121 // - loops have a single back-edge.
122 addFunctionPass(LoopSimplifyPass(), PMW);
123
124 // 2. Removes registers whose lifetime spans across basic blocks. Also
125 // removes phi nodes. This will greatly simplify the next steps.
126 addFunctionPass(RegToMemPass(), PMW);
127
128 // 3. Merge the convergence region exit nodes into one. After this step,
129 // regions are single-entry, single-exit. This will help determine the
130 // correct merge block.
131 addFunctionPass(SPIRVMergeRegionExitTargetsPass(), PMW);
132
133 // 4. Structurize.
134 addFunctionPass(SPIRVStructurizerPass(), PMW);
135
136 // 5. Reduce the amount of variables required by pushing some operations
137 // back to virtual registers.
138 addFunctionPass(PromotePass(), PMW);
139 } else {
140 // Canonicalize loops so they have a single latch and preheader.
141 // This enables OpLoopMerge emission for non-shader targets.
142 addFunctionPass(LoopSimplifyPass(), PMW);
143 }
144 addFunctionPass(StripConvergenceIntrinsicsPass(), PMW);
145 flushFPMsToMPM(PMW);
146 addModulePass(SPIRVLegalizeResourceBindingPass(), PMW);
147 addModulePass(SPIRVLegalizeZeroSizeArraysPass(getTM()), PMW);
148 addModulePass(SPIRVCBufferAccessPass(), PMW);
149 addModulePass(SPIRVPushConstantAccessPass(getTM()), PMW);
150 addModulePass(SPIRVEmitIntrinsicsPass(getTM()), PMW);
152 addFunctionPass(SPIRVLegalizePointerCastPass(getTM()), PMW);
153 Base::addISelPrepare(PMW);
154}
155
156Error SPIRVCodeGenPassBuilder::addIRTranslator(PassManagerWrapper &PMW) {
157 addMachineFunctionPass(IRTranslatorPass(getOptLevel()), PMW);
158 return Error::success();
159}
160
161void SPIRVCodeGenPassBuilder::addPreLegalizeMachineIR(PassManagerWrapper &PMW) {
162 addMachineFunctionPass(SPIRVPreLegalizerCombinerPass(), PMW);
163 addMachineFunctionPass(SPIRVPreLegalizerPass(), PMW);
164}
165
166Error SPIRVCodeGenPassBuilder::addLegalizeMachineIR(PassManagerWrapper &PMW) {
167 addMachineFunctionPass(LegalizerPass(), PMW);
168 addMachineFunctionPass(SPIRVPostLegalizerPass(), PMW);
169 return Error::success();
170}
171
172Error SPIRVCodeGenPassBuilder::addRegBankSelect(PassManagerWrapper &PMW) {
173 // We do not add RegBankSelectPass as we only ever need virtual registers.
174 return Error::success();
175}
176
177Error SPIRVCodeGenPassBuilder::addGlobalInstructionSelect(
178 PassManagerWrapper &PMW) {
179 addMachineFunctionPass(
180 InstructionSelectPass(getOptLevel(), /*RequireRegBankSelection=*/false),
181 PMW);
182 return Error::success();
183}
184
185// We do nothing in register allocation as we keep virtual registers.
186Error SPIRVCodeGenPassBuilder::addFastRegAlloc(PassManagerWrapper &PMW) {
187 return Error::success();
188}
189
190Error SPIRVCodeGenPassBuilder::addOptimizedRegAlloc(PassManagerWrapper &PMW) {
191 return Error::success();
192}
193
194void SPIRVCodeGenPassBuilder::addPreEmitPass2(PassManagerWrapper &PMW) {
195 addMachineFunctionPass(SPIRVPrepareModuleAnalysisPass(), PMW);
196}
197
198void SPIRVCodeGenPassBuilder::addAsmPrinterBegin(PassManagerWrapper &PMW) {
199 addModulePass(SPIRVAsmPrinterBeginPass(), PMW);
200}
201
202void SPIRVCodeGenPassBuilder::addAsmPrinter(PassManagerWrapper &PMW) {
203 // SPIRVModuleAnalysis needs every MachineFunction before printing starts.
205 flushFPMsToMPM(PMW);
206 addModulePass(RequireAnalysisPass<SPIRVModuleAnalysis, Module>(), PMW,
207 /*Force=*/true);
208 }
209 addMachineFunctionPass(SPIRVAsmPrinterPass(), PMW);
210}
211
212void SPIRVCodeGenPassBuilder::addAsmPrinterEnd(PassManagerWrapper &PMW) {
213 addModulePass(SPIRVAsmPrinterEndPass(), PMW);
214}
215
216} // namespace
217
219#define GET_PASS_REGISTRY "SPIRVPassRegistry.def"
221}
222
225 raw_pwrite_stream *DwoOut, CodeGenFileType FileType,
226 const CGPassBuilderOption &Opt, MCContext &Ctx,
228 auto CGPB = SPIRVCodeGenPassBuilder(*this, Opt, PIC);
229 return CGPB.buildPipeline(MPM, MAM, Out, DwoOut, FileType, Ctx);
230}
Interfaces for producing common pass manager configurations.
This file declares the IRTranslator pass.
ModuleAnalysisManager MAM
PassInstrumentationCallbacks PIC
PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC)
This file defines the Pass Instrumentation classes that provide instrumentation points into the pass ...
const GCNTargetMachine & getTM(const GCNSubtarget *STI)
This pass strips convergence intrinsics and operand bundles as those are only useful when modifying t...
This class provides access to building LLVM's passes.
Lightweight error class with error context and mandatory checking.
Definition Error.h:159
static ErrorSuccess success()
Create a success value.
Definition Error.h:336
Context object for machine code objects.
Definition MCContext.h:83
This class provides access to building LLVM's passes.
This class manages callbacks registration, as well as provides a way for PassInstrumentation to pass ...
bool isLogicalSPIRV() const
void registerPassBuilderCallbacks(PassBuilder &PB) override
Allow the target to modify the pass pipeline.
const SPIRVSubtarget * getSubtargetImpl() const
Error buildCodeGenPipeline(ModulePassManager &MPM, ModuleAnalysisManager &MAM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut, CodeGenFileType FileType, const CGPassBuilderOption &Opt, MCContext &Ctx, PassInstrumentationCallbacks *PIC) override
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.
Interfaces for registering analysis passes, producing common pass manager configurations,...
LLVM_READNONE constexpr bool isShader(CallingConv::ID CC)
This is an optimization pass for GlobalISel generic memory operations.
CodeGenFileType
These enums are meant to be passed into addPassesToEmitFile to indicate what type of file to emit,...
Definition CodeGen.h:256
PassManager< Module > ModulePassManager
Convenience typedef for a pass manager over modules.
AnalysisManager< Module > ModuleAnalysisManager
Convenience typedef for the Module analysis manager.
Definition MIRParser.h:39