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