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
30#include "llvm/CodeGen/KCFI.h"
34#include "llvm/MC/MCAsmInfo.h"
35#include "llvm/MC/MCStreamer.h"
36#include "llvm/Pass.h"
42
43using namespace llvm;
44
45namespace {
46
47class X86CodeGenPassBuilder : public CodeGenPassBuilder {
48 using Base = CodeGenPassBuilder;
49
50 X86TargetMachine &getTM() const {
51 return static_cast<X86TargetMachine &>(TM);
52 }
53
54public:
55 explicit X86CodeGenPassBuilder(X86TargetMachine &TM,
56 const CGPassBuilderOption &Opts,
57 PassInstrumentationCallbacks *PIC)
58 : CodeGenPassBuilder(TM, Opts, PIC) {}
59
60 void addIRPasses(PassManagerWrapper &PMW) override;
61 void addPreISel(PassManagerWrapper &PMW) override;
62 Error addInstSelector(PassManagerWrapper &PMW) override;
63
64 Error addIRTranslator(PassManagerWrapper &PMW) override;
65 void addPreLegalizeMachineIR(PassManagerWrapper &PMW) override;
66 Error addLegalizeMachineIR(PassManagerWrapper &PMW) override;
67 void addPreRegBankSelect(PassManagerWrapper &PMW) override;
68 Error addRegBankSelect(PassManagerWrapper &PMW) override;
69 Error addGlobalInstructionSelect(PassManagerWrapper &PMW) override;
70
71 void addILPOpts(PassManagerWrapper &PMW) override;
72 void addMachineSSAOptimization(PassManagerWrapper &PMW) override;
73 void addPreRegAlloc(PassManagerWrapper &PMW) override;
74 void addPostRegAlloc(PassManagerWrapper &PMW) override;
75 void addPreSched2(PassManagerWrapper &PMW) override;
76 void addPreEmitPass(PassManagerWrapper &PMW) override;
77 void addPreEmitPass2(PassManagerWrapper &PMW) override;
78 Error addRegAssignAndRewriteFast(PassManagerWrapper &PMW) override;
79 Expected<bool>
80 addRegAssignAndRewriteOptimized(PassManagerWrapper &PMW) override;
81 void addAsmPrinterBegin(PassManagerWrapper &PMW) override;
82 void addAsmPrinter(PassManagerWrapper &PMW) override;
83 void addAsmPrinterEnd(PassManagerWrapper &PMW) override;
84};
85
86void X86CodeGenPassBuilder::addIRPasses(PassManagerWrapper &PMW) {
87 addFunctionPass(AtomicExpandPass(TM), PMW);
88
89 // We add both pass anyway and when these two passes run, one will be a
90 // no-op based on the optimization level/attributes.
91 addFunctionPass(X86LowerAMXIntrinsicsPass(&TM), PMW);
92 addFunctionPass(X86LowerAMXTypePass(&TM), PMW);
93
94 Base::addIRPasses(PMW);
95
96 if (getOptLevel() != CodeGenOptLevel::None) {
97 addFunctionPass(InterleavedAccessPass(TM), PMW);
98 addFunctionPass(X86PartialReductionPass(&getTM()), PMW);
99 }
100
101 // Add passes that handle indirect branch removal and insertion of a retpoline
102 // thunk. These will be a no-op unless a function subtarget has the retpoline
103 // feature enabled.
104 addFunctionPass(IndirectBrExpandPass(TM), PMW);
105
106 // Add Control Flow Guard checks.
107 const Triple &TT = TM.getTargetTriple();
108 if (TT.isOSWindows())
109 addFunctionPass(CFGuardPass(), PMW);
110
111 if (TM.Options.JMCInstrument) {
112 flushFPMsToMPM(PMW);
113 addModulePass(JMCInstrumenterPass(), PMW);
114 }
115}
116
117void X86CodeGenPassBuilder::addPreISel(PassManagerWrapper &PMW) {
118 // Only add this pass for 32-bit x86 Windows.
119 const Triple &TT = TM.getTargetTriple();
120 if (TT.isOSWindows() && TT.isX86_32()) {
121 flushFPMsToMPM(PMW);
122 addModulePass(X86WinEHStatePass(), PMW);
123 }
124}
125
126Error X86CodeGenPassBuilder::addInstSelector(PassManagerWrapper &PMW) {
127 addMachineFunctionPass(X86ISelDAGToDAGPass(getTM()), PMW);
128
129 // For ELF, cleanup any local-dynamic TLS accesses
130 if (TM.getTargetTriple().isOSBinFormatELF() &&
131 getOptLevel() != CodeGenOptLevel::None) {
132 addMachineFunctionPass(X86CleanupLocalDynamicTLSPass(), PMW);
133 }
134
135 addMachineFunctionPass(X86GlobalBaseRegPass(), PMW);
136 addMachineFunctionPass(X86ArgumentStackSlotPass(), PMW);
137 return Error::success();
138}
139
140Error X86CodeGenPassBuilder::addIRTranslator(PassManagerWrapper &PMW) {
141 addMachineFunctionPass(IRTranslatorPass(getOptLevel()), PMW);
142 return Error::success();
143}
144
145void X86CodeGenPassBuilder::addPreLegalizeMachineIR(PassManagerWrapper &PMW) {
146 if (getOptLevel() != CodeGenOptLevel::None)
147 addMachineFunctionPass(X86PreLegalizerCombinerPass(), PMW);
148}
149
150Error X86CodeGenPassBuilder::addLegalizeMachineIR(PassManagerWrapper &PMW) {
151 addMachineFunctionPass(LegalizerPass(), PMW);
152 return Error::success();
153}
154
155void X86CodeGenPassBuilder::addPreRegBankSelect(PassManagerWrapper &PMW) {
156 if (getOptLevel() != CodeGenOptLevel::None)
157 addMachineFunctionPass(X86PostLegalizerCombinerPass(), PMW);
158}
159
160Error X86CodeGenPassBuilder::addRegBankSelect(PassManagerWrapper &PMW) {
161 addMachineFunctionPass(RegBankSelectPass(), PMW);
162 return Error::success();
163}
164
165Error X86CodeGenPassBuilder::addGlobalInstructionSelect(
166 PassManagerWrapper &PMW) {
167 addMachineFunctionPass(InstructionSelectPass(getOptLevel()), PMW);
168 // Add GlobalBaseReg in case there is no SelectionDAG passes afterwards
169 if (isGlobalISelAbortEnabled())
170 addMachineFunctionPass(X86GlobalBaseRegPass(), PMW);
171 return Error::success();
172}
173
174void X86CodeGenPassBuilder::addILPOpts(PassManagerWrapper &PMW) {
175 addMachineFunctionPass(EarlyIfConverterPass(), PMW);
176 if (getTM().getCLOpts().machine_combiner)
177 addMachineFunctionPass(MachineCombinerPass(), PMW);
178 addMachineFunctionPass(X86CmovConversionPass(), PMW);
179}
180
181void X86CodeGenPassBuilder::addMachineSSAOptimization(PassManagerWrapper &PMW) {
182 addMachineFunctionPass(X86DomainReassignmentPass(), PMW);
183 Base::addMachineSSAOptimization(PMW);
184}
185
186void X86CodeGenPassBuilder::addPreRegAlloc(PassManagerWrapper &PMW) {
187 if (getOptLevel() != CodeGenOptLevel::None) {
188 addMachineFunctionPass(LiveRangeShrinkPass(), PMW);
189 addMachineFunctionPass(X86FixupSetCCPass(), PMW);
190 addMachineFunctionPass(X86OptimizeLEAsPass(), PMW);
191 addMachineFunctionPass(X86CallFrameOptimizationPass(), PMW);
192 addMachineFunctionPass(X86AvoidStoreForwardingBlocksPass(), PMW);
193 }
194
195 addMachineFunctionPass(X86SuppressAPXForRelocationPass(), PMW);
196 addMachineFunctionPass(X86SpeculativeLoadHardeningPass(), PMW);
197 addMachineFunctionPass(X86FlagsCopyLoweringPass(), PMW);
198 addMachineFunctionPass(X86DynAllocaExpanderPass(), PMW);
199
200 if (getOptLevel() != CodeGenOptLevel::None)
201 addMachineFunctionPass(X86PreTileConfigPass(), PMW);
202 else
203 addMachineFunctionPass(X86FastPreTileConfigPass(), PMW);
204}
205
206void X86CodeGenPassBuilder::addPostRegAlloc(PassManagerWrapper &PMW) {
207 addMachineFunctionPass(X86LowerTileCopyPass(), PMW);
208 addMachineFunctionPass(X86FPStackifierPass(), PMW);
209 // When -O0 is enabled, the Load Value Injection Hardening pass will fall back
210 // to using the Speculative Execution Side Effect Suppression pass for
211 // mitigation. This is to prevent slow downs due to
212 // analyses needed by the LVIHardening pass when compiling at -O0.
213 if (getOptLevel() != CodeGenOptLevel::None) {
214 addMachineFunctionPass(X86LoadValueInjectionLoadHardeningPass(), PMW);
215 }
216}
217
218void X86CodeGenPassBuilder::addPreSched2(PassManagerWrapper &PMW) {
219 addMachineFunctionPass(X86ExpandPseudoPass(), PMW);
220 addMachineFunctionPass(MachineKCFIPass(), PMW);
221}
222
223void X86CodeGenPassBuilder::addPreEmitPass(PassManagerWrapper &PMW) {
224 if (getOptLevel() != CodeGenOptLevel::None) {
225 // TODO(boomanaiden154): Add X86ExecutionDomainFixPass here once it has
226 // been ported.
227 addMachineFunctionPass(BreakFalseDepsPass(), PMW);
228 }
229
230 addMachineFunctionPass(X86IndirectBranchTrackingPass(), PMW);
231 addMachineFunctionPass(X86InsertVZeroUpperPass(), PMW);
232
233 if (getOptLevel() != CodeGenOptLevel::None) {
234 addMachineFunctionPass(X86FixupBWInstsPass(), PMW);
235 addMachineFunctionPass(X86PadShortFunctionsPass(), PMW);
236 addMachineFunctionPass(X86FixupLEAsPass(), PMW);
237 addMachineFunctionPass(X86FixupInstTuningPass(), PMW);
238 addMachineFunctionPass(X86FixupVectorConstantsPass(), PMW);
239 }
240 addMachineFunctionPass(X86CompressEVEXPass(), PMW);
241 addMachineFunctionPass(X86InsertX87WaitPass(), PMW);
242
243 if (TM.getTargetTriple().isLFI())
244 addMachineFunctionPass(X86LFIRewritePass(), PMW);
245}
246
247void X86CodeGenPassBuilder::addPreEmitPass2(PassManagerWrapper &PMW) {
248 const Triple &TT = TM.getTargetTriple();
249
250 // The X86 Speculative Execution Pass must run after all control
251 // flow graph modifying passes. As a result it was listed to run right before
252 // the X86 Retpoline Thunks pass. The reason it must run after control flow
253 // graph modifications is that the model of LFENCE in LLVM has to be updated
254 // (FIXME: https://bugs.llvm.org/show_bug.cgi?id=45167). Currently the
255 // placement of this pass was hand checked to ensure that the subsequent
256 // passes don't move the code around the LFENCEs in a way that will hurt the
257 // correctness of this pass. This placement has been shown to work based on
258 // hand inspection of the codegen output.
259 addMachineFunctionPass(X86SpeculativeExecutionSideEffectSuppressionPass(),
260 PMW);
261 // TODO(boomanaiden154): Add X86IndirectThunksPass here
262 // once it has been ported.
263 addMachineFunctionPass(X86ReturnThunksPass(), PMW);
264
265 // Insert extra int3 instructions after trailing call instructions to avoid
266 // issues in the unwinder.
267 if (TT.isOSWindows() && TT.isX86_64())
268 addMachineFunctionPass(X86AvoidTrailingCallPass(), PMW);
269
270 // Verify basic block incoming and outgoing cfa offset and register values and
271 // correct CFA calculation rule where needed by inserting appropriate CFI
272 // instructions. CFIInstrInserter self-skips targets that do not use DWARF
273 // CFI.
274 if (!TT.isOSDarwin())
275 addMachineFunctionPass(CFIInstrInserterPass(), PMW);
276
277 if (TT.isOSWindows()) {
278 // Identify valid longjmp targets for Windows Control Flow Guard.
279 addMachineFunctionPass(CFGuardLongjmpPass(), PMW);
280 // Identify valid eh continuation targets for Windows EHCont Guard.
281 addMachineFunctionPass(EHContGuardTargetsPass(), PMW);
282 }
283
284 addMachineFunctionPass(X86LoadValueInjectionRetHardeningPass(), PMW);
285
286 // Insert pseudo probe annotation for callsite profiling
287 addMachineFunctionPass(PseudoProbeInserterPass(), PMW);
288
289 // KCFI indirect call checks are lowered to a bundle, and on Darwin platforms,
290 // also CALL_RVMARKER.
291 addMachineFunctionPass(
292 UnpackMachineBundlesPass([&TT](const MachineFunction &MF) {
293 // Only run bundle expansion if the module uses kcfi, or there are
294 // relevant ObjC runtime functions present in the module.
295 const Function &F = MF.getFunction();
296 const Module *M = F.getParent();
297 return M->getModuleFlag("kcfi") ||
298 (TT.isOSDarwin() &&
299 (M->getFunction("objc_retainAutoreleasedReturnValue") ||
300 M->getFunction("objc_unsafeClaimAutoreleasedReturnValue")));
301 }),
302 PMW);
303
304 // Analyzes and emits pseudos to support Win x64 Unwind V2. This pass must run
305 // after all real instructions have been added to the epilog.
306 if (TT.isOSWindows() && TT.isX86_64()) {
307 addMachineFunctionPass(X86WinEHUnwindV2Pass(), PMW);
308 }
309}
310
311static bool onlyAllocateTileRegisters(const TargetRegisterInfo &TRI,
312 const MachineRegisterInfo &MRI,
313 const Register Reg) {
314 const TargetRegisterClass *RC = MRI.getRegClass(Reg);
315 return static_cast<const X86RegisterInfo &>(TRI).isTileRegisterClass(RC);
316}
317
318Error X86CodeGenPassBuilder::addRegAssignAndRewriteFast(
319 PassManagerWrapper &PMW) {
320 Error PossibleError = Base::addRegAssignAndRewriteFast(PMW);
321 addMachineFunctionPass(X86FastTileConfigPass(), PMW);
322 return PossibleError;
323}
324
325Expected<bool> X86CodeGenPassBuilder::addRegAssignAndRewriteOptimized(
326 PassManagerWrapper &PMW) {
327 // Don't support tile RA when RA is specified by command line "-regalloc".
328 if (Opt.RegAlloc == RegAllocType::Default && getTM().getCLOpts().tile_ra) {
329 // Allocate tile register first.
330 addMachineFunctionPass(
331 RAGreedyPass({RAGreedyPass::Options(onlyAllocateTileRegisters)}), PMW);
332 addMachineFunctionPass(X86TileConfigPass(), PMW);
333 }
334 return Base::addRegAssignAndRewriteOptimized(PMW);
335}
336
337void X86CodeGenPassBuilder::addAsmPrinterBegin(PassManagerWrapper &PMW) {
338 addModulePass(X86AsmPrinterBeginPass(), PMW, /*Force=*/true);
339}
340
341void X86CodeGenPassBuilder::addAsmPrinter(PassManagerWrapper &PMW) {
342 addMachineFunctionPass(X86AsmPrinterPass(), PMW);
343}
344
345void X86CodeGenPassBuilder::addAsmPrinterEnd(PassManagerWrapper &PMW) {
346 addModulePass(X86AsmPrinterEndPass(), PMW, /*Force=*/true);
347}
348
349} // namespace
350
352#define GET_PASS_REGISTRY "X86PassRegistry.def"
354}
355
358 raw_pwrite_stream *DwoOut, CodeGenFileType FileType,
359 const CGPassBuilderOption &Opt, MCContext &Ctx,
361 auto CGPB = X86CodeGenPassBuilder(*this, Opt, PIC);
362 return CGPB.buildPipeline(MPM, MAM, Out, DwoOut, FileType, Ctx);
363}
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 declares the IRTranslator pass.
This file contains the declaration of the InterleavedAccessPass class, its corresponding pass name is...
#define F(x, y, z)
Definition MD5.cpp:54
Machine Check Debug Module
Register Reg
Register const TargetRegisterInfo * TRI
Promote Memory to Register
Definition Mem2Reg.cpp:110
ModuleAnalysisManager MAM
PassBuilder PB(Mod->getContext(), Machine, PassOpts->PTO, std::nullopt, &PIC)
PassInstrumentationCallbacks PIC
This file describes the interface of the MachineFunctionPass responsible for assigning the generic vi...
const GCNTargetMachine & getTM(const GCNSubtarget *STI)
static bool onlyAllocateTileRegisters(const TargetRegisterInfo &TRI, const MachineRegisterInfo &MRI, const Register Reg)
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
Context object for machine code objects.
Definition MCContext.h:83
Function & getFunction()
Return the LLVM function that this machine code represents.
const TargetRegisterClass * getRegClass(Register Reg) const
Return the register class of the specified virtual register.
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,...
const AArch64MCOptions & getCLOpts(const MCTargetOptions &Options)
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:256
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
MCRegisterClass TargetRegisterClass
Definition FastISel.h:58