LLVM 23.0.0git
X86CodeGenPassBuilder.cpp
Go to the documentation of this file.
1//===-- X86CodeGenPassBuilder.cpp ---------------------------------*- C++ -*-=//
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 X86 CodeGen pipeline builder.
10/// TODO: Port CodeGen passes to new pass manager.
11//===----------------------------------------------------------------------===//
12
13#include "X86.h"
14#include "X86AsmPrinter.h"
15#include "X86ISelDAGToDAG.h"
16#include "X86TargetMachine.h"
17
23#include "llvm/MC/MCStreamer.h"
28
29using namespace llvm;
30
32
33namespace {
34
35class X86CodeGenPassBuilder
36 : public CodeGenPassBuilder<X86CodeGenPassBuilder, X86TargetMachine> {
37 using Base = CodeGenPassBuilder<X86CodeGenPassBuilder, X86TargetMachine>;
38
39public:
40 explicit X86CodeGenPassBuilder(X86TargetMachine &TM,
41 const CGPassBuilderOption &Opts,
42 PassInstrumentationCallbacks *PIC)
43 : CodeGenPassBuilder(TM, Opts, PIC) {}
44
45 void addIRPasses(PassManagerWrapper &PMW) const;
46 void addPreISel(PassManagerWrapper &PMW) const;
47 Error addInstSelector(PassManagerWrapper &PMW) const;
48 void addILPOpts(PassManagerWrapper &PMW) const;
49 void addPreRegBankSelect(PassManagerWrapper &PMW) const;
50 void addMachineSSAOptimization(PassManagerWrapper &PMW) const;
51 void addPreRegAlloc(PassManagerWrapper &PMW) const;
52 // TODO(boomanaiden154): We need to add addPostFastRegAllocRewrite here once
53 // it is available to support AMX.
54 void addPostRegAlloc(PassManagerWrapper &PMW) const;
55 void addPreSched2(PassManagerWrapper &PMW) const;
56 void addPreEmitPass(PassManagerWrapper &PMW) const;
57 void addPreEmitPass2(PassManagerWrapper &PMW) const;
58 // TODO(boomanaiden154): We need to add addRegAssignAndRewriteOptimized here
59 // once it is available to support AMX.
60 void addAsmPrinterBegin(PassManagerWrapper &PMW) const;
61 void addAsmPrinter(PassManagerWrapper &PMW) const;
62 void addAsmPrinterEnd(PassManagerWrapper &PMW) const;
63};
64
65void X86CodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) const {
66 addFunctionPass(AtomicExpandPass(TM), PMW);
67
68 // We add both pass anyway and when these two passes run, one will be a
69 // no-op based on the optimization level/attributes.
70 addFunctionPass(X86LowerAMXIntrinsicsPass(&TM), PMW);
71 addFunctionPass(X86LowerAMXTypePass(&TM), PMW);
72
73 Base::addIRPasses(PMW);
74
75 if (getOptLevel() != CodeGenOptLevel::None) {
76 addFunctionPass(InterleavedAccessPass(TM), PMW);
77 addFunctionPass(X86PartialReductionPass(&TM), PMW);
78 }
79
80 // Add passes that handle indirect branch removal and insertion of a retpoline
81 // thunk. These will be a no-op unless a function subtarget has the retpoline
82 // feature enabled.
83 addFunctionPass(IndirectBrExpandPass(TM), PMW);
84
85 // Add Control Flow Guard checks.
86 const Triple &TT = TM.getTargetTriple();
87 if (TT.isOSWindows())
88 addFunctionPass(CFGuardPass(), PMW);
89
90 if (TM.Options.JMCInstrument) {
91 flushFPMsToMPM(PMW);
92 addModulePass(JMCInstrumenterPass(), PMW);
93 }
94}
95
96void X86CodeGenPassBuilder::addPreISel(PassManagerWrapper &PMW) const {
97 // Only add this pass for 32-bit x86 Windows.
98 const Triple &TT = TM.getTargetTriple();
99 if (TT.isOSWindows() && TT.isX86_32()) {
100 flushFPMsToMPM(PMW);
101 addModulePass(X86WinEHStatePass(), PMW);
102 }
103}
104
105Error X86CodeGenPassBuilder::addInstSelector(PassManagerWrapper &PMW) const {
106 addMachineFunctionPass(X86ISelDAGToDAGPass(TM), PMW);
107
108 // For ELF, cleanup any local-dynamic TLS accesses
109 if (TM.getTargetTriple().isOSBinFormatELF() &&
110 getOptLevel() != CodeGenOptLevel::None) {
111 addMachineFunctionPass(X86CleanupLocalDynamicTLSPass(), PMW);
112 }
113
114 addMachineFunctionPass(X86GlobalBaseRegPass(), PMW);
115 addMachineFunctionPass(X86ArgumentStackSlotPass(), PMW);
116 return Error::success();
117}
118
119void X86CodeGenPassBuilder::addILPOpts(PassManagerWrapper &PMW) const {
120 addMachineFunctionPass(EarlyIfConverterPass(), PMW);
122 // TODO(boomanaiden154): Add the MachineCombinerPass here once it has been
123 // ported to the new pass manager.
124 }
125 addMachineFunctionPass(X86CmovConversionPass(), PMW);
126}
127
128void X86CodeGenPassBuilder::addPreRegBankSelect(PassManagerWrapper &PMW) const {
129 addMachineFunctionPass(X86PostLegalizerCombinerPass(), PMW);
130}
131
132void X86CodeGenPassBuilder::addMachineSSAOptimization(
133 PassManagerWrapper &PMW) const {
134 addMachineFunctionPass(X86DomainReassignmentPass(), PMW);
135 Base::addMachineSSAOptimization(PMW);
136}
137
138void X86CodeGenPassBuilder::addPreRegAlloc(PassManagerWrapper &PMW) const {
139 if (getOptLevel() != CodeGenOptLevel::None) {
140 addMachineFunctionPass(LiveRangeShrinkPass(), PMW);
141 addMachineFunctionPass(X86FixupSetCCPass(), PMW);
142 addMachineFunctionPass(X86CallFrameOptimizationPass(), PMW);
143 addMachineFunctionPass(X86AvoidStoreForwardingBlocksPass(), PMW);
144 }
145
146 addMachineFunctionPass(X86SuppressAPXForRelocationPass(), PMW);
147 addMachineFunctionPass(X86SpeculativeLoadHardeningPass(), PMW);
148 addMachineFunctionPass(X86FlagsCopyLoweringPass(), PMW);
149 addMachineFunctionPass(X86DynAllocaExpanderPass(), PMW);
150
151 if (getOptLevel() != CodeGenOptLevel::None)
152 addMachineFunctionPass(X86PreTileConfigPass(), PMW);
153 else
154 addMachineFunctionPass(X86FastPreTileConfigPass(), PMW);
155}
156
157void X86CodeGenPassBuilder::addPostRegAlloc(PassManagerWrapper &PMW) const {
158 addMachineFunctionPass(X86LowerTileCopyPass(), PMW);
159 addMachineFunctionPass(X86FPStackifierPass(), PMW);
160 // When -O0 is enabled, the Load Value Injection Hardening pass will fall back
161 // to using the Speculative Execution Side Effect Suppression pass for
162 // mitigation. This is to prevent slow downs due to
163 // analyses needed by the LVIHardening pass when compiling at -O0.
164 if (getOptLevel() != CodeGenOptLevel::None) {
165 addMachineFunctionPass(X86LoadValueInjectionLoadHardeningPass(), PMW);
166 }
167}
168
169void X86CodeGenPassBuilder::addPreSched2(PassManagerWrapper &PMW) const {
170 addMachineFunctionPass(X86ExpandPseudoPass(), PMW);
171 // TODO(boomanaiden154): Add KCFGPass here once it has been ported.
172}
173
174void X86CodeGenPassBuilder::addPreEmitPass(PassManagerWrapper &PMW) const {
175 if (getOptLevel() != CodeGenOptLevel::None) {
176 // TODO(boomanaiden154): Add X86ExecutionDomainFixPass here once it has
177 // been ported.
178 addMachineFunctionPass(BreakFalseDepsPass(), PMW);
179 }
180
181 addMachineFunctionPass(X86IndirectBranchTrackingPass(), PMW);
182 addMachineFunctionPass(X86InsertVZeroUpperPass(), PMW);
183
184 if (getOptLevel() != CodeGenOptLevel::None) {
185 addMachineFunctionPass(X86FixupBWInstsPass(), PMW);
186 // TODO(boomanaiden154): Add X86PadShortFunctionsPass here once it has been
187 // ported.
188 addMachineFunctionPass(X86FixupLEAsPass(), PMW);
189 addMachineFunctionPass(X86FixupInstTuningPass(), PMW);
190 addMachineFunctionPass(X86FixupVectorConstantsPass(), PMW);
191 }
192 addMachineFunctionPass(X86CompressEVEXPass(), PMW);
193 addMachineFunctionPass(X86InsertX87WaitPass(), PMW);
194}
195
196void X86CodeGenPassBuilder::addPreEmitPass2(PassManagerWrapper &PMW) const {
197 const Triple &TT = TM.getTargetTriple();
198 const MCAsmInfo *MAI = TM.getMCAsmInfo();
199
200 // The X86 Speculative Execution Pass must run after all control
201 // flow graph modifying passes. As a result it was listed to run right before
202 // the X86 Retpoline Thunks pass. The reason it must run after control flow
203 // graph modifications is that the model of LFENCE in LLVM has to be updated
204 // (FIXME: https://bugs.llvm.org/show_bug.cgi?id=45167). Currently the
205 // placement of this pass was hand checked to ensure that the subsequent
206 // passes don't move the code around the LFENCEs in a way that will hurt the
207 // correctness of this pass. This placement has been shown to work based on
208 // hand inspection of the codegen output.
209 addMachineFunctionPass(X86SpeculativeExecutionSideEffectSuppressionPass(),
210 PMW);
211 // TODO(boomanaiden154): Add X86IndirectThunksPass here
212 // once it has been ported.
213 addMachineFunctionPass(X86ReturnThunksPass(), PMW);
214
215 // Insert extra int3 instructions after trailing call instructions to avoid
216 // issues in the unwinder.
217 if (TT.isOSWindows() && TT.isX86_64())
218 addMachineFunctionPass(X86AvoidTrailingCallPass(), PMW);
219
220 // Verify basic block incoming and outgoing cfa offset and register values and
221 // correct CFA calculation rule where needed by inserting appropriate CFI
222 // instructions.
223 if (!TT.isOSDarwin() &&
224 (!TT.isOSWindows() ||
225 MAI->getExceptionHandlingType() == ExceptionHandling::DwarfCFI)) {
226 // TODO(boomanaiden154): Add CFInstrInserterPass here when it has been
227 // ported.
228 }
229
230 if (TT.isOSWindows()) {
231 // Identify valid longjmp targets for Windows Control Flow Guard.
232 // TODO(boomanaiden154): Add CFGuardLongjmpPass here when it has been
233 // ported.
234 // Identify valid eh continuation targets for Windows EHCont Guard.
235 // TODO(boomanaiden154): Add EHContGuardTargetsPass when it has been
236 // ported.
237 }
238
239 addMachineFunctionPass(X86LoadValueInjectionRetHardeningPass(), PMW);
240
241 // Insert pseudo probe annotation for callsite profiling
242 // TODO(boomanaiden154): Add PseudoProberInserterPass here once it has been
243 // ported.
244
245 // KCFI indirect call checks are lowered to a bundle, and on Darwin platforms,
246 // also CALL_RVMARKER.
247 // TODO(boomanaiden154): Add UnpackMachineBundlesPass here once it has been
248 // ported.
249
250 // Analyzes and emits pseudos to support Win x64 Unwind V2. This pass must run
251 // after all real instructions have been added to the epilog.
252 if (TT.isOSWindows() && TT.isX86_64()) {
253 addMachineFunctionPass(X86WinEHUnwindV2Pass(), PMW);
254 }
255}
256
257void X86CodeGenPassBuilder::addAsmPrinterBegin(PassManagerWrapper &PMW) const {
258 addModulePass(X86AsmPrinterBeginPass(), PMW, /*Force=*/true);
259}
260
261void X86CodeGenPassBuilder::addAsmPrinter(PassManagerWrapper &PMW) const {
262 addMachineFunctionPass(X86AsmPrinterPass(), PMW);
263}
264
265void X86CodeGenPassBuilder::addAsmPrinterEnd(PassManagerWrapper &PMW) const {
266 addModulePass(X86AsmPrinterEndPass(), PMW, /*Force=*/true);
267}
268
269} // namespace
270
272#define GET_PASS_REGISTRY "X86PassRegistry.def"
274 // TODO(boomanaiden154): Move this into the base CodeGenPassBuilder once all
275 // targets that currently implement it have a ported asm-printer pass.
276 if (PIC) {
277 PIC->addClassToPassName(X86AsmPrinterBeginPass::name(),
278 "x86-asm-printer-begin");
279 PIC->addClassToPassName(X86AsmPrinterPass::name(), "x86-asm-printer");
280 PIC->addClassToPassName(X86AsmPrinterEndPass::name(),
281 "x86-asm-printer-end");
282 }
283}
284
287 raw_pwrite_stream *DwoOut, CodeGenFileType FileType,
288 const CGPassBuilderOption &Opt, MCContext &Ctx,
290 auto CGPB = X86CodeGenPassBuilder(*this, Opt, PIC);
291 return CGPB.buildPipeline(MPM, MAM, Out, DwoOut, FileType, Ctx);
292}
Interfaces for producing common pass manager configurations.
This file contains the declaration of the InterleavedAccessPass class, its corresponding pass name is...
ModuleAnalysisManager MAM
PassInstrumentationCallbacks PIC
PassBuilder PB(Machine, PassOpts->PTO, std::nullopt, &PIC)
cl::opt< bool > X86EnableMachineCombinerPass
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
ExceptionHandling getExceptionHandlingType() const
Definition MCAsmInfo.h:646
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 ...
void registerPassBuilderCallbacks(PassBuilder &PB) override
Allow the target to modify the pass pipeline.
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,...
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:111
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