LLVM 24.0.0git
RISCVCodeGenPassBuilder.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/// \file
9/// This file contains the RISC-V CodeGen pipeline builder.
10//===----------------------------------------------------------------------===//
11
12#include "RISCV.h"
13#include "RISCVAsmPrinter.h"
14#include "RISCVTargetMachine.h"
18#include "llvm/CodeGen/KCFI.h"
24#include "llvm/MC/MCStreamer.h"
31
32using namespace llvm;
33
34namespace {
35
36class RISCVCodeGenPassBuilder
37 : public CodeGenPassBuilder<RISCVCodeGenPassBuilder, RISCVTargetMachine> {
38 using Base = CodeGenPassBuilder<RISCVCodeGenPassBuilder, RISCVTargetMachine>;
39
40public:
41 explicit RISCVCodeGenPassBuilder(RISCVTargetMachine &TM,
42 const CGPassBuilderOption &Opts,
43 PassInstrumentationCallbacks *PIC)
44 : CodeGenPassBuilder(TM, Opts, PIC) {
45 // TODO: See the FIXME on RISCVPassConfig::setEnableSinkAndFold in the
46 // legacy pass manager pipeline. There is currently no way to plumb
47 // -riscv-enable-sink-fold through to CGPassBuilderOption::EnableSinkAndFold
48 // from a target-local CodeGenPassBuilder, so this NewPM pipeline always
49 // uses the base class default (disabled).
50 }
51
52 void addIRPasses(PassManagerWrapper &PMW) const;
53 void addCodeGenPrepare(PassManagerWrapper &PMW) const;
54 Error addInstSelector(PassManagerWrapper &PMW) const;
55 void addMachineSSAOptimization(PassManagerWrapper &PMW) const;
56 void addPreRegAlloc(PassManagerWrapper &PMW) const;
57 void addPostRegAlloc(PassManagerWrapper &PMW) const;
58 void addPreSched2(PassManagerWrapper &PMW) const;
59 void addPreEmitPass(PassManagerWrapper &PMW) const;
60 void addPreEmitPass2(PassManagerWrapper &PMW) const;
61 void addAsmPrinterBegin(PassManagerWrapper &PMW) const;
62 void addAsmPrinter(PassManagerWrapper &PMW) const;
63 void addAsmPrinterEnd(PassManagerWrapper &PMW) const;
64};
65
66void RISCVCodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) const {
67 addFunctionPass(AtomicExpandPass(TM), PMW);
68 // TODO: RISCVZacasABIFixPass
69
70 if (getOptLevel() != CodeGenOptLevel::None) {
71 addFunctionPass(LoopDataPrefetchPass(), PMW);
72
73 // TODO: RISCVGatherScatterLoweringPass
74 addFunctionPass(InterleavedAccessPass(TM), PMW);
75 addFunctionPass(RISCVCodeGenPreparePass(&TM), PMW);
76 }
77
78 Base::addIRPasses(PMW);
79
80 // TODO: SelectOptimizePass is already added by the base class when
81 // !Opt.DisableSelectOptimize. The legacy pipeline additionally gates this
82 // on -riscv-select-opt and only runs it at -O3; that extra gating is not
83 // yet replicated here.
84}
85
86void RISCVCodeGenPassBuilder::addCodeGenPrepare(PassManagerWrapper &PMW) const {
87 if (getOptLevel() != CodeGenOptLevel::None)
88 addFunctionPass(TypePromotionPass(TM), PMW);
89 Base::addCodeGenPrepare(PMW);
90}
91
92Error RISCVCodeGenPassBuilder::addInstSelector(PassManagerWrapper &PMW) const {
93 addMachineFunctionPass(RISCVISelDAGToDAGPass(TM, getOptLevel()), PMW);
94 return Error::success();
95}
96
97void RISCVCodeGenPassBuilder::addMachineSSAOptimization(
98 PassManagerWrapper &PMW) const {
99 // It's beneficial to reduce the VL to enable more
100 // Machine SSA optimizations.
101 if (getOptLevel() != CodeGenOptLevel::None) {
102 // RISCVVLOptimizer can make loop invariant instructions like vmv.v.i
103 // loop variant by propagating a VL defined inside the loop. Run LICM and
104 // hoist them early. Don't do this at -O0 to avoid the compile-time
105 // overhead. Not reducing the VL of loop invariant pseudos results in more
106 // vsetvli toggles, and still requires the MachineLoopInfo analysis to be
107 // run.
108 addMachineFunctionPass(EarlyMachineLICMPass(), PMW);
109 // TODO: RISCVVLOptimizerPass
110 }
111
112 // TODO: RISCVVectorPeepholePass
113 // TODO: RISCVFoldMemOffsetPass
114
115 Base::addMachineSSAOptimization(PMW);
116
117 if (TM.getTargetTriple().isRISCV64()) {
118 // TODO: RISCVOptWInstrsPass
119 }
120}
121
122void RISCVCodeGenPassBuilder::addPreRegAlloc(PassManagerWrapper &PMW) const {
123 // TODO: RISCVPreRAExpandPseudoPass
124 if (getOptLevel() != CodeGenOptLevel::None) {
125 // TODO: RISCVMergeBaseOffsetOptPass
126 // TODO: RISCVPreAllocZilsdOptPass
127 }
128
129 // TODO: RISCVInsertReadWriteCSRPass
130 // TODO: RISCVInsertWriteVXRMPass
131 // TODO: RISCVLandingPadSetupPass
132
133 // TODO: MachinePipelinerPass (no new pass manager port exists yet)
134
135 // TODO: RISCVVMV0EliminationPass
136}
137
138void RISCVCodeGenPassBuilder::addPostRegAlloc(PassManagerWrapper &PMW) const {
139 if (getOptLevel() != CodeGenOptLevel::None) {
140 // TODO: RISCVRedundantCopyEliminationPass
141 }
142}
143
144void RISCVCodeGenPassBuilder::addPreSched2(PassManagerWrapper &PMW) const {
145 // TODO: RISCVPostRAExpandPseudoPass
146
147 addMachineFunctionPass(MachineKCFIPass(), PMW);
148 if (getOptLevel() != CodeGenOptLevel::None) {
149 // TODO: RISCVLoadStoreOptPass
150 }
151}
152
153void RISCVCodeGenPassBuilder::addPreEmitPass(PassManagerWrapper &PMW) const {
154 // TODO: It would potentially be better to schedule copy propagation after
155 // expanding pseudos (in addPreEmitPass2). However, performing copy
156 // propagation after the machine outliner (which runs after addPreEmitPass)
157 // currently leads to incorrect code-gen, where copies to registers within
158 // outlined functions are removed erroneously.
159 if (getOptLevel() >= CodeGenOptLevel::Default) {
160 addMachineFunctionPass(MachineCopyPropagationPass(true), PMW);
161 // TODO: RISCVLateBranchOptPass
162 }
163 // The IndirectBranchTrackingPass inserts lpad and could have changed the
164 // basic block alignment. It must be done before Branch Relaxation to
165 // prevent the adjusted offset exceeding the branch range.
166 // TODO: RISCVIndirectBranchTrackingPass
167 addMachineFunctionPass(BranchRelaxationPass(), PMW);
168 // TODO: RISCVMakeCompressibleOptPass
169}
170
171void RISCVCodeGenPassBuilder::addPreEmitPass2(PassManagerWrapper &PMW) const {
172 if (getOptLevel() != CodeGenOptLevel::None) {
173 // TODO: RISCVMoveMergePass
174 // TODO: RISCVPushPopOptimizationPass
175 }
176 // TODO: RISCVExpandPseudoPass
177
178 // Add QC Relaxation Markers as late as possible, and only for RV32
179 if (getOptLevel() != CodeGenOptLevel::None &&
180 TM.getTargetTriple().isRISCV32()) {
181 // TODO: RISCVQCRelaxMarkingPass
182 }
183
184 // TODO: RISCVExpandAtomicPseudoPass
185
186 // KCFI indirect call checks are lowered to a bundle.
187 addMachineFunctionPass(
188 UnpackMachineBundlesPass([&](const MachineFunction &MF) {
189 return MF.getFunction().getParent()->getModuleFlag("kcfi");
190 }),
191 PMW);
192
193 // TODO: CFIInstrInserterPass
194}
195
196void RISCVCodeGenPassBuilder::addAsmPrinterBegin(
197 PassManagerWrapper &PMW) const {
198 addModulePass(RISCVAsmPrinterBeginPass(), PMW, /*Force=*/true);
199}
200
201void RISCVCodeGenPassBuilder::addAsmPrinter(PassManagerWrapper &PMW) const {
202 addMachineFunctionPass(RISCVAsmPrinterPass(), PMW);
203}
204
205void RISCVCodeGenPassBuilder::addAsmPrinterEnd(PassManagerWrapper &PMW) const {
206 addModulePass(RISCVAsmPrinterEndPass(), PMW, /*Force=*/true);
207}
208
209} // namespace
210
212#define GET_PASS_REGISTRY "RISCVPassRegistry.def"
214
215 PB.registerLateLoopOptimizationsEPCallback([=](LoopPassManager &LPM,
216 OptimizationLevel Level) {
217 if (Level != OptimizationLevel::O0)
219 });
220
221 // TODO: Move this into the base CodeGenPassBuilder once all targets that
222 // currently implement it have a ported asm-printer pass.
223 if (PIC) {
224 PIC->addClassToPassName(RISCVAsmPrinterBeginPass::name(),
225 "riscv-asm-printer-begin");
226 PIC->addClassToPassName(RISCVAsmPrinterPass::name(), "riscv-asm-printer");
227 PIC->addClassToPassName(RISCVAsmPrinterEndPass::name(),
228 "riscv-asm-printer-end");
229 }
230}
231
234 raw_pwrite_stream *DwoOut, CodeGenFileType FileType,
235 const CGPassBuilderOption &Opt, MCContext &Ctx,
237 auto CGPB = RISCVCodeGenPassBuilder(*this, Opt, PIC);
238 return CGPB.buildPipeline(MPM, MAM, Out, DwoOut, FileType, Ctx);
239}
Interfaces for producing common pass manager configurations.
This file contains the declaration of the MachineKCFI class, which is a Machine Pass that implements ...
This file contains the declaration of the InterleavedAccessPass class, its corresponding pass name is...
This file provides the interface for LLVM's Loop Data Prefetching 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 ...
Defines an IR pass for type promotion.
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
Module * getParent()
Get the module that this global value is contained inside of...
Context object for machine code objects.
Definition MCContext.h:83
Function & getFunction()
Return the LLVM function that this machine code represents.
Metadata * getModuleFlag(StringRef Key) const
Return the corresponding value if Key appears in module flags, otherwise return null.
Definition Module.cpp:358
This class provides access to building LLVM's passes.
This class manages callbacks registration, as well as provides a way for PassInstrumentation to pass ...
Error buildCodeGenPipeline(ModulePassManager &MPM, ModuleAnalysisManager &MAM, raw_pwrite_stream &Out, raw_pwrite_stream *DwoOut, CodeGenFileType FileType, const CGPassBuilderOption &Opt, MCContext &Ctx, PassInstrumentationCallbacks *PIC) override
void registerPassBuilderCallbacks(PassBuilder &PB) override
Allow the target to modify the pass pipeline.
An abstract base class for streams implementations that also support a pwrite operation.
Interfaces for registering analysis passes, producing common pass manager configurations,...
This is an optimization pass for GlobalISel generic memory operations.
@ O0
Disable as many optimizations as possible.
PassManager< Loop, LoopAnalysisManager, LoopStandardAnalysisResults &, LPMUpdater & > LoopPassManager
The Loop pass manager.
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