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