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