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