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 "SPIRVTargetMachine.h"
38
39using namespace llvm;
40
41namespace {
42
43class SPIRVCodeGenPassBuilder : public CodeGenPassBuilder {
44 using Base = CodeGenPassBuilder;
45
46 SPIRVTargetMachine &getTM() const {
47 return static_cast<SPIRVTargetMachine &>(TM);
48 }
49
50public:
51 explicit SPIRVCodeGenPassBuilder(SPIRVTargetMachine &TM,
52 const CGPassBuilderOption &Opts,
53 PassInstrumentationCallbacks *PIC)
54 : CodeGenPassBuilder(TM, Opts, PIC) {
55 // Disable passes that break from assuming no virtual registers exist.
56 disablePass<MachineCopyPropagationPass, PostRAMachineSinkingPass,
57 PostRASchedulerPass, FuncletLayoutPass, StackMapLivenessPass,
58 PatchableFunctionPass, ShrinkWrapPass, LiveDebugValuesPass,
59 MachineLateInstrsCleanupPass, RemoveLoadsIntoFakeUsesPass,
60 BranchFolderPass, MachineBlockPlacementPass>();
61 }
62
63 void addIRPasses(PassManagerWrapper &PMW) override;
64 void addISelPrepare(PassManagerWrapper &PMW) override;
65 Error addIRTranslator(PassManagerWrapper &PMW) override;
66 void addPreLegalizeMachineIR(PassManagerWrapper &PMW) override;
67 Error addLegalizeMachineIR(PassManagerWrapper &PMW) override;
68 Error addRegBankSelect(PassManagerWrapper &PMW) override;
69 Error addGlobalInstructionSelect(PassManagerWrapper &PMW) override;
70
71 Error addFastRegAlloc(PassManagerWrapper &PMW) override;
72
73 Error addOptimizedRegAlloc(PassManagerWrapper &PMW) override;
74
75 void addAsmPrinterBegin(PassManagerWrapper &PMW) override;
76 void addAsmPrinter(PassManagerWrapper &PMW) override;
77 void addAsmPrinterEnd(PassManagerWrapper &PMW) override;
78};
79
80void SPIRVCodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) {
81 addFunctionPass(AtomicExpandPass(TM), PMW);
82
83 Base::addIRPasses(PMW);
84
85 flushFPMsToMPM(PMW);
86
87 if (getTM().getSubtargetImpl()->isShader()) {
88 if (getOptLevel() != CodeGenOptLevel::None) {
89 addModulePass(SPIRVFinalizeShaderLinkagePass(getTM()), PMW);
90 }
91 } else {
92 // Variadic function calls aren't supported in shader code.
93 // This needs to come before SPIRVPrepareFunctions because this
94 // may introduce intrinsic calls.
95 addModulePass(ExpandVariadicsPass(ExpandVariadicsMode::Lowering), PMW);
96 }
97
98 addFunctionPass(SPIRVRegularizerPass(), PMW);
99 flushFPMsToMPM(PMW);
100 addModulePass(SPIRVCtorDtorLoweringPass(), PMW);
101 addModulePass(SPIRVPrepareFunctionsPass(getTM()), PMW);
102 addModulePass(SPIRVPrepareGlobalsPass(), PMW);
103}
104
105void SPIRVCodeGenPassBuilder::addISelPrepare(PassManagerWrapper &PMW) {
106 SPIRVTargetMachine &TM = getTM();
107 if (getTM().getSubtargetImpl()->isShader()) {
108 // Vulkan does not allow address space casts. This pass is run to remove
109 // address space casts that can be removed.
110 // If an address space cast is not removed while targeting Vulkan, lowering
111 // will fail during MIR lowering.
112 addFunctionPass(InferAddressSpacesPass(), PMW);
113
114 // 1. Simplify loop for subsequent transformations. After this steps, loops
115 // have the following properties:
116 // - loops have a single entry edge (pre-header to loop header).
117 // - all loop exits are dominated by the loop pre-header.
118 // - loops have a single back-edge.
119 addFunctionPass(LoopSimplifyPass(), PMW);
120
121 // 2. Removes registers whose lifetime spans across basic blocks. Also
122 // removes phi nodes. This will greatly simplify the next steps.
123 addFunctionPass(RegToMemPass(), PMW);
124
125 // 3. Merge the convergence region exit nodes into one. After this step,
126 // regions are single-entry, single-exit. This will help determine the
127 // correct merge block.
128 addFunctionPass(SPIRVMergeRegionExitTargetsPass(), PMW);
129
130 // 4. Structurize.
131 addFunctionPass(SPIRVStructurizerPass(), PMW);
132
133 // 5. Reduce the amount of variables required by pushing some operations
134 // back to virtual registers.
135 addFunctionPass(PromotePass(), PMW);
136 } else {
137 // Canonicalize loops so they have a single latch and preheader.
138 // This enables OpLoopMerge emission for non-shader targets.
139 addFunctionPass(LoopSimplifyPass(), PMW);
140 }
141 addFunctionPass(StripConvergenceIntrinsicsPass(), PMW);
142 flushFPMsToMPM(PMW);
143 addModulePass(SPIRVLegalizeImplicitBindingPass(), PMW);
144 addModulePass(SPIRVLegalizeZeroSizeArraysPass(getTM()), PMW);
145 addModulePass(SPIRVCBufferAccessPass(), PMW);
146 addModulePass(SPIRVPushConstantAccessPass(getTM()), PMW);
147 addModulePass(SPIRVEmitIntrinsicsPass(getTM()), PMW);
149 addFunctionPass(SPIRVLegalizePointerCastPass(getTM()), PMW);
150 Base::addISelPrepare(PMW);
151}
152
153Error SPIRVCodeGenPassBuilder::addIRTranslator(PassManagerWrapper &PMW) {
154 addMachineFunctionPass(IRTranslatorPass(getOptLevel()), PMW);
155 return Error::success();
156}
157
158void SPIRVCodeGenPassBuilder::addPreLegalizeMachineIR(PassManagerWrapper &PMW) {
159 addMachineFunctionPass(SPIRVPreLegalizerCombinerPass(), PMW);
160 addMachineFunctionPass(SPIRVPreLegalizerPass(), PMW);
161}
162
163Error SPIRVCodeGenPassBuilder::addLegalizeMachineIR(PassManagerWrapper &PMW) {
164 addMachineFunctionPass(LegalizerPass(), PMW);
165 addMachineFunctionPass(SPIRVPostLegalizerPass(), PMW);
166 return Error::success();
167}
168
169Error SPIRVCodeGenPassBuilder::addRegBankSelect(PassManagerWrapper &PMW) {
170 // We do not add RegBankSelectPass as we only ever need virtual registers.
171 return Error::success();
172}
173
174Error SPIRVCodeGenPassBuilder::addGlobalInstructionSelect(
175 PassManagerWrapper &PMW) {
176 addMachineFunctionPass(InstructionSelectPass(getOptLevel()), PMW);
177 return Error::success();
178}
179
180// We do nothing in register allocation as we keep virtual registers.
181Error SPIRVCodeGenPassBuilder::addFastRegAlloc(PassManagerWrapper &PMW) {
182 return Error::success();
183}
184
185Error SPIRVCodeGenPassBuilder::addOptimizedRegAlloc(PassManagerWrapper &PMW) {
186 return Error::success();
187}
188
189void SPIRVCodeGenPassBuilder::addAsmPrinterBegin(PassManagerWrapper &PMW) {
190 addModulePass(SPIRVAsmPrinterBeginPass(), PMW);
191}
192
193void SPIRVCodeGenPassBuilder::addAsmPrinter(PassManagerWrapper &PMW) {
194 addMachineFunctionPass(SPIRVAsmPrinterPass(), PMW);
195}
196
197void SPIRVCodeGenPassBuilder::addAsmPrinterEnd(PassManagerWrapper &PMW) {
198 addModulePass(SPIRVAsmPrinterEndPass(), PMW);
199}
200
201} // namespace
202
204#define GET_PASS_REGISTRY "SPIRVPassRegistry.def"
206}
207
210 raw_pwrite_stream *DwoOut, CodeGenFileType FileType,
211 const CGPassBuilderOption &Opt, MCContext &Ctx,
213 auto CGPB = SPIRVCodeGenPassBuilder(*this, Opt, PIC);
214 return CGPB.buildPipeline(MPM, MAM, Out, DwoOut, FileType, Ctx);
215}
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
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:178
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