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"
19#include "llvm/CodeGen/KCFI.h"
25#include "llvm/MC/MCStreamer.h"
32
33using namespace llvm;
34
35namespace {
36
37class RISCVCodeGenPassBuilder : public CodeGenPassBuilder {
38 using Base = CodeGenPassBuilder;
39
40 RISCVTargetMachine &getTM() const {
41 return static_cast<RISCVTargetMachine &>(TM);
42 }
43
44public:
45 explicit RISCVCodeGenPassBuilder(RISCVTargetMachine &TM,
46 const CGPassBuilderOption &Opts,
47 PassInstrumentationCallbacks *PIC)
48 : CodeGenPassBuilder(TM, Opts, PIC) {
49 // TODO: See the FIXME on RISCVPassConfig::setEnableSinkAndFold in the
50 // legacy pass manager pipeline. There is currently no way to plumb
51 // -riscv-enable-sink-fold through to CGPassBuilderOption::EnableSinkAndFold
52 // from a target-local CodeGenPassBuilder, so this NewPM pipeline always
53 // uses the base class default (disabled).
54 }
55
56 void addIRPasses(PassManagerWrapper &PMW) override;
57 void addCodeGenPrepare(PassManagerWrapper &PMW) override;
58 Error addInstSelector(PassManagerWrapper &PMW) override;
59 void addMachineSSAOptimization(PassManagerWrapper &PMW) override;
60 void addPreRegAlloc(PassManagerWrapper &PMW) override;
61 void addPostRegAlloc(PassManagerWrapper &PMW) override;
62 void addPreSched2(PassManagerWrapper &PMW) override;
63 void addPreEmitPass(PassManagerWrapper &PMW) override;
64 void addPreEmitPass2(PassManagerWrapper &PMW) override;
65 void addAsmPrinterBegin(PassManagerWrapper &PMW) override;
66 void addAsmPrinter(PassManagerWrapper &PMW) override;
67 void addAsmPrinterEnd(PassManagerWrapper &PMW) override;
68};
69
70void RISCVCodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) {
71 addFunctionPass(AtomicExpandPass(TM), PMW);
72 addFunctionPass(RISCVZacasABIFixPass(&getTM()), PMW);
73
74 if (getOptLevel() != CodeGenOptLevel::None) {
75 addFunctionPass(LoopDataPrefetchPass(), PMW);
76
77 addFunctionPass(RISCVGatherScatterLoweringPass(&getTM()), PMW);
78 addFunctionPass(InterleavedAccessPass(TM), PMW);
79 addFunctionPass(RISCVCodeGenPreparePass(&getTM()), PMW);
80 }
81
82 Base::addIRPasses(PMW);
83
84 // TODO: SelectOptimizePass is already added by the base class when
85 // !Opt.DisableSelectOptimize. The legacy pipeline additionally gates this
86 // on -riscv-select-opt and only runs it at -O3; that extra gating is not
87 // yet replicated here.
88}
89
90void RISCVCodeGenPassBuilder::addCodeGenPrepare(PassManagerWrapper &PMW) {
91 if (getOptLevel() != CodeGenOptLevel::None)
92 addFunctionPass(TypePromotionPass(TM), PMW);
93 Base::addCodeGenPrepare(PMW);
94}
95
96Error RISCVCodeGenPassBuilder::addInstSelector(PassManagerWrapper &PMW) {
97 addMachineFunctionPass(RISCVISelDAGToDAGPass(getTM(), getOptLevel()), PMW);
98 return Error::success();
99}
100
101void RISCVCodeGenPassBuilder::addMachineSSAOptimization(
102 PassManagerWrapper &PMW) {
103 // It's beneficial to reduce the VL to enable more
104 // Machine SSA optimizations.
105 if (getOptLevel() != CodeGenOptLevel::None) {
106 // RISCVVLOptimizer can make loop invariant instructions like vmv.v.i
107 // loop variant by propagating a VL defined inside the loop. Run LICM and
108 // hoist them early. Don't do this at -O0 to avoid the compile-time
109 // overhead. Not reducing the VL of loop invariant pseudos results in more
110 // vsetvli toggles, and still requires the MachineLoopInfo analysis to be
111 // run.
112 addMachineFunctionPass(EarlyMachineLICMPass(), PMW);
113 addMachineFunctionPass(RISCVVLOptimizerPass(), PMW);
114 }
115
116 addMachineFunctionPass(RISCVVectorPeepholePass(), PMW);
117 addMachineFunctionPass(RISCVFoldMemOffsetPass(), PMW);
118
119 Base::addMachineSSAOptimization(PMW);
120
121 if (TM.getTargetTriple().isRISCV64())
122 addMachineFunctionPass(RISCVOptWInstrsPass(), PMW);
123}
124
125void RISCVCodeGenPassBuilder::addPreRegAlloc(PassManagerWrapper &PMW) {
126 addMachineFunctionPass(RISCVPreRAExpandPseudoPass(), PMW);
127 if (getOptLevel() != CodeGenOptLevel::None) {
128 // TODO: RISCVMergeBaseOffsetOptPass
129 // TODO: RISCVPreAllocZilsdOptPass
130 }
131
132 // TODO: RISCVInsertReadWriteCSRPass
133 // TODO: RISCVInsertWriteVXRMPass
134 // TODO: RISCVLandingPadSetupPass
135
136 // TODO: MachinePipelinerPass (no new pass manager port exists yet)
137
138 // TODO: RISCVVMV0EliminationPass
139}
140
141void RISCVCodeGenPassBuilder::addPostRegAlloc(PassManagerWrapper &PMW) {
142 if (getOptLevel() != CodeGenOptLevel::None) {
143 // TODO: RISCVRedundantCopyEliminationPass
144 }
145}
146
147void RISCVCodeGenPassBuilder::addPreSched2(PassManagerWrapper &PMW) {
148 addMachineFunctionPass(RISCVPostRAExpandPseudoPass(), PMW);
149
150 addMachineFunctionPass(MachineKCFIPass(), PMW);
151 if (getOptLevel() != CodeGenOptLevel::None) {
152 // TODO: RISCVLoadStoreOptPass
153 }
154}
155
156void RISCVCodeGenPassBuilder::addPreEmitPass(PassManagerWrapper &PMW) {
157 // TODO: It would potentially be better to schedule copy propagation after
158 // expanding pseudos (in addPreEmitPass2). However, performing copy
159 // propagation after the machine outliner (which runs after addPreEmitPass)
160 // currently leads to incorrect code-gen, where copies to registers within
161 // outlined functions are removed erroneously.
162 if (getOptLevel() >= CodeGenOptLevel::Default) {
163 addMachineFunctionPass(MachineCopyPropagationPass(true), PMW);
164 // TODO: RISCVLateBranchOptPass
165 }
166 // The IndirectBranchTrackingPass inserts lpad and could have changed the
167 // basic block alignment. It must be done before Branch Relaxation to
168 // prevent the adjusted offset exceeding the branch range.
169 // TODO: RISCVIndirectBranchTrackingPass
170 addMachineFunctionPass(BranchRelaxationPass(), PMW);
171 // TODO: RISCVMakeCompressibleOptPass
172}
173
174void RISCVCodeGenPassBuilder::addPreEmitPass2(PassManagerWrapper &PMW) {
175 if (getOptLevel() != CodeGenOptLevel::None) {
176 // TODO: RISCVMoveMergePass
177 // TODO: RISCVPushPopOptimizationPass
178 }
179 addMachineFunctionPass(RISCVExpandPseudoPass(), PMW);
180
181 // Add QC Relaxation Markers as late as possible, and only for RV32
182 if (getOptLevel() != CodeGenOptLevel::None &&
183 TM.getTargetTriple().isRISCV32()) {
184 // TODO: RISCVQCRelaxMarkingPass
185 }
186
187 addMachineFunctionPass(RISCVExpandAtomicPseudoPass(), PMW);
188
189 // KCFI indirect call checks are lowered to a bundle.
190 addMachineFunctionPass(
191 UnpackMachineBundlesPass([&](const MachineFunction &MF) {
192 return MF.getFunction().getParent()->getModuleFlag("kcfi");
193 }),
194 PMW);
195
196 // RISCVTargetMachine's constructor sets Options.EnableCFIFixup to the
197 // inverse of -riscv-enable-cfi-instr-inserter (a flag private to
198 // RISCVTargetMachine.cpp), so checking it here is equivalent to checking
199 // that flag directly -- the two passes solve overlapping problems and
200 // this target picks exactly one.
201 if (!TM.Options.EnableCFIFixup)
202 addMachineFunctionPass(CFIInstrInserterPass(), PMW);
203}
204
205void RISCVCodeGenPassBuilder::addAsmPrinterBegin(PassManagerWrapper &PMW) {
206 addModulePass(RISCVAsmPrinterBeginPass(), PMW, /*Force=*/true);
207}
208
209void RISCVCodeGenPassBuilder::addAsmPrinter(PassManagerWrapper &PMW) {
210 addMachineFunctionPass(RISCVAsmPrinterPass(), PMW);
211}
212
213void RISCVCodeGenPassBuilder::addAsmPrinterEnd(PassManagerWrapper &PMW) {
214 addModulePass(RISCVAsmPrinterEndPass(), PMW, /*Force=*/true);
215}
216
217} // namespace
218
220#define GET_PASS_REGISTRY "RISCVPassRegistry.def"
222
223 PB.registerLateLoopOptimizationsEPCallback([=](LoopPassManager &LPM,
224 OptimizationLevel Level) {
225 if (Level != OptimizationLevel::O0)
227 });
228}
229
232 raw_pwrite_stream *DwoOut, CodeGenFileType FileType,
233 const CGPassBuilderOption &Opt, MCContext &Ctx,
235 auto CGPB = RISCVCodeGenPassBuilder(*this, Opt, PIC);
236 return CGPB.buildPipeline(MPM, MAM, Out, DwoOut, FileType, Ctx);
237}
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 ...
const GCNTargetMachine & getTM(const GCNSubtarget *STI)
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