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(TT.isX86_64() ? CFGuardPass::Mechanism::Dispatch
89 : CFGuardPass::Mechanism::Check),
90 PMW);
91
92 if (TM.Options.JMCInstrument) {
93 flushFPMsToMPM(PMW);
94 addModulePass(JMCInstrumenterPass(), PMW);
95 }
96}
97
98void X86CodeGenPassBuilder::addPreISel(PassManagerWrapper &PMW) const {
99 // Only add this pass for 32-bit x86 Windows.
100 const Triple &TT = TM.getTargetTriple();
101 if (TT.isOSWindows() && TT.isX86_32()) {
102 flushFPMsToMPM(PMW);
103 addModulePass(X86WinEHStatePass(), PMW);
104 }
105}
106
107Error X86CodeGenPassBuilder::addInstSelector(PassManagerWrapper &PMW) const {
108 addMachineFunctionPass(X86ISelDAGToDAGPass(TM), PMW);
109
110 // For ELF, cleanup any local-dynamic TLS accesses
111 if (TM.getTargetTriple().isOSBinFormatELF() &&
112 getOptLevel() != CodeGenOptLevel::None) {
113 addMachineFunctionPass(X86CleanupLocalDynamicTLSPass(), PMW);
114 }
115
116 addMachineFunctionPass(X86GlobalBaseRegPass(), PMW);
117 addMachineFunctionPass(X86ArgumentStackSlotPass(), PMW);
118 return Error::success();
119}
120
121void X86CodeGenPassBuilder::addILPOpts(PassManagerWrapper &PMW) const {
122 addMachineFunctionPass(EarlyIfConverterPass(), PMW);
124 // TODO(boomanaiden154): Add the MachineCombinerPass here once it has been
125 // ported to the new pass manager.
126 }
127 addMachineFunctionPass(X86CmovConversionPass(), PMW);
128}
129
130void X86CodeGenPassBuilder::addPreRegBankSelect(PassManagerWrapper &PMW) const {
131 addMachineFunctionPass(X86PostLegalizerCombinerPass(), PMW);
132}
133
134void X86CodeGenPassBuilder::addMachineSSAOptimization(
135 PassManagerWrapper &PMW) const {
136 addMachineFunctionPass(X86DomainReassignmentPass(), PMW);
137 Base::addMachineSSAOptimization(PMW);
138}
139
140void X86CodeGenPassBuilder::addPreRegAlloc(PassManagerWrapper &PMW) const {
141 if (getOptLevel() != CodeGenOptLevel::None) {
142 addMachineFunctionPass(LiveRangeShrinkPass(), PMW);
143 addMachineFunctionPass(X86FixupSetCCPass(), PMW);
144 addMachineFunctionPass(X86CallFrameOptimizationPass(), PMW);
145 addMachineFunctionPass(X86AvoidStoreForwardingBlocksPass(), PMW);
146 }
147
148 addMachineFunctionPass(X86SuppressAPXForRelocationPass(), PMW);
149 addMachineFunctionPass(X86SpeculativeLoadHardeningPass(), PMW);
150 addMachineFunctionPass(X86FlagsCopyLoweringPass(), PMW);
151 addMachineFunctionPass(X86DynAllocaExpanderPass(), PMW);
152
153 if (getOptLevel() != CodeGenOptLevel::None)
154 addMachineFunctionPass(X86PreTileConfigPass(), PMW);
155 else
156 addMachineFunctionPass(X86FastPreTileConfigPass(), PMW);
157}
158
159void X86CodeGenPassBuilder::addPostRegAlloc(PassManagerWrapper &PMW) const {
160 addMachineFunctionPass(X86LowerTileCopyPass(), PMW);
161 addMachineFunctionPass(X86FPStackifierPass(), PMW);
162 // When -O0 is enabled, the Load Value Injection Hardening pass will fall back
163 // to using the Speculative Execution Side Effect Suppression pass for
164 // mitigation. This is to prevent slow downs due to
165 // analyses needed by the LVIHardening pass when compiling at -O0.
166 if (getOptLevel() != CodeGenOptLevel::None) {
167 addMachineFunctionPass(X86LoadValueInjectionLoadHardeningPass(), PMW);
168 }
169}
170
171void X86CodeGenPassBuilder::addPreSched2(PassManagerWrapper &PMW) const {
172 addMachineFunctionPass(X86ExpandPseudoPass(), PMW);
173 // TODO(boomanaiden154): Add KCFGPass here once it has been ported.
174}
175
176void X86CodeGenPassBuilder::addPreEmitPass(PassManagerWrapper &PMW) const {
177 if (getOptLevel() != CodeGenOptLevel::None) {
178 // TODO(boomanaiden154): Add X86ExecutionDomainFixPass here once it has
179 // been ported.
180 addMachineFunctionPass(BreakFalseDepsPass(), PMW);
181 }
182
183 addMachineFunctionPass(X86IndirectBranchTrackingPass(), PMW);
184 // TODO(boomanaiden154): Add X86IssueVZeroUpperPass here once it has been
185 // ported.
186
187 if (getOptLevel() != CodeGenOptLevel::None) {
188 addMachineFunctionPass(X86FixupBWInstsPass(), PMW);
189 // TODO(boomanaiden154): Add X86PadShortFunctionsPass here once it has been
190 // ported.
191 addMachineFunctionPass(X86FixupLEAsPass(), PMW);
192 addMachineFunctionPass(X86FixupInstTuningPass(), PMW);
193 addMachineFunctionPass(X86FixupVectorConstantsPass(), PMW);
194 }
195 addMachineFunctionPass(X86CompressEVEXPass(), PMW);
196 addMachineFunctionPass(X86InsertX87WaitPass(), PMW);
197}
198
199void X86CodeGenPassBuilder::addPreEmitPass2(PassManagerWrapper &PMW) const {
200 const Triple &TT = TM.getTargetTriple();
201 const MCAsmInfo *MAI = TM.getMCAsmInfo();
202
203 // The X86 Speculative Execution Pass must run after all control
204 // flow graph modifying passes. As a result it was listed to run right before
205 // the X86 Retpoline Thunks pass. The reason it must run after control flow
206 // graph modifications is that the model of LFENCE in LLVM has to be updated
207 // (FIXME: https://bugs.llvm.org/show_bug.cgi?id=45167). Currently the
208 // placement of this pass was hand checked to ensure that the subsequent
209 // passes don't move the code around the LFENCEs in a way that will hurt the
210 // correctness of this pass. This placement has been shown to work based on
211 // hand inspection of the codegen output.
212 addMachineFunctionPass(X86SpeculativeExecutionSideEffectSuppressionPass(),
213 PMW);
214 // TODO(boomanaiden154): Add X86IndirectThunksPass here
215 // once it has been ported.
216 addMachineFunctionPass(X86ReturnThunksPass(), PMW);
217
218 // Insert extra int3 instructions after trailing call instructions to avoid
219 // issues in the unwinder.
220 if (TT.isOSWindows() && TT.isX86_64())
221 addMachineFunctionPass(X86AvoidTrailingCallPass(), PMW);
222
223 // Verify basic block incoming and outgoing cfa offset and register values and
224 // correct CFA calculation rule where needed by inserting appropriate CFI
225 // instructions.
226 if (!TT.isOSDarwin() &&
227 (!TT.isOSWindows() ||
228 MAI->getExceptionHandlingType() == ExceptionHandling::DwarfCFI)) {
229 // TODO(boomanaiden154): Add CFInstrInserterPass here when it has been
230 // ported.
231 }
232
233 if (TT.isOSWindows()) {
234 // Identify valid longjmp targets for Windows Control Flow Guard.
235 // TODO(boomanaiden154): Add CFGuardLongjmpPass here when it has been
236 // ported.
237 // Identify valid eh continuation targets for Windows EHCont Guard.
238 // TODO(boomanaiden154): Add EHContGuardTargetsPass when it has been
239 // ported.
240 }
241
242 addMachineFunctionPass(X86LoadValueInjectionRetHardeningPass(), PMW);
243
244 // Insert pseudo probe annotation for callsite profiling
245 // TODO(boomanaiden154): Add PseudoProberInserterPass here once it has been
246 // ported.
247
248 // KCFI indirect call checks are lowered to a bundle, and on Darwin platforms,
249 // also CALL_RVMARKER.
250 // TODO(boomanaiden154): Add UnpackMachineBundlesPass here once it has been
251 // ported.
252
253 // Analyzes and emits pseudos to support Win x64 Unwind V2. This pass must run
254 // after all real instructions have been added to the epilog.
255 if (TT.isOSWindows() && TT.isX86_64()) {
256 addMachineFunctionPass(X86WinEHUnwindV2Pass(), PMW);
257 }
258}
259
260void X86CodeGenPassBuilder::addAsmPrinterBegin(PassManagerWrapper &PMW) const {
261 addModulePass(X86AsmPrinterBeginPass(), PMW, /*Force=*/true);
262}
263
264void X86CodeGenPassBuilder::addAsmPrinter(PassManagerWrapper &PMW) const {
265 addMachineFunctionPass(X86AsmPrinterPass(), PMW);
266}
267
268void X86CodeGenPassBuilder::addAsmPrinterEnd(PassManagerWrapper &PMW) const {
269 addModulePass(X86AsmPrinterEndPass(), PMW, /*Force=*/true);
270}
271
272} // namespace
273
275#define GET_PASS_REGISTRY "X86PassRegistry.def"
277 // TODO(boomanaiden154): Move this into the base CodeGenPassBuilder once all
278 // targets that currently implement it have a ported asm-printer pass.
279 if (PIC) {
280 PIC->addClassToPassName(X86AsmPrinterBeginPass::name(),
281 "x86-asm-printer-begin");
282 PIC->addClassToPassName(X86AsmPrinterPass::name(), "x86-asm-printer");
283 PIC->addClassToPassName(X86AsmPrinterEndPass::name(),
284 "x86-asm-printer-end");
285 }
286}
287
290 raw_pwrite_stream *DwoOut, CodeGenFileType FileType,
291 const CGPassBuilderOption &Opt, MCContext &Ctx,
293 auto CGPB = X86CodeGenPassBuilder(*this, Opt, PIC);
294 return CGPB.buildPipeline(MPM, MAM, Out, DwoOut, FileType, Ctx);
295}
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