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