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 addMachineSSAOptimization(PassManagerWrapper &PMW) override;
72 void addILPOpts(PassManagerWrapper &PMW) override;
73 void addPreRegAlloc(PassManagerWrapper &PMW) override;
74 Error addRegAssignAndRewriteFast(PassManagerWrapper &PMW) override;
75 Expected<bool>
76 addRegAssignAndRewriteOptimized(PassManagerWrapper &PMW) override;
77 void addPostRegAlloc(PassManagerWrapper &PMW) override;
78 void addPreSched2(PassManagerWrapper &PMW) override;
79 void addPreEmitPass(PassManagerWrapper &PMW) override;
80 void addPreEmitPass2(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 addFunctionPass(X86FenceNonTemporalStoresPass(&getTM()), PMW);
117}
118
119void X86CodeGenPassBuilder::addPreISel(PassManagerWrapper &PMW) {
120 // Only add this pass for 32-bit x86 Windows.
121 const Triple &TT = TM.getTargetTriple();
122 if (TT.isOSWindows() && TT.isX86_32()) {
123 flushFPMsToMPM(PMW);
124 addModulePass(X86WinEHStatePass(), PMW);
125 }
126}
127
128Error X86CodeGenPassBuilder::addInstSelector(PassManagerWrapper &PMW) {
129 addMachineFunctionPass(X86ISelDAGToDAGPass(getTM()), PMW);
130
131 // For ELF, cleanup any local-dynamic TLS accesses
132 if (TM.getTargetTriple().isOSBinFormatELF() &&
133 getOptLevel() != CodeGenOptLevel::None) {
134 addMachineFunctionPass(X86CleanupLocalDynamicTLSPass(), PMW);
135 }
136
137 addMachineFunctionPass(X86GlobalBaseRegPass(), PMW);
138 addMachineFunctionPass(X86ArgumentStackSlotPass(), PMW);
139 return Error::success();
140}
141
142Error X86CodeGenPassBuilder::addIRTranslator(PassManagerWrapper &PMW) {
143 addMachineFunctionPass(IRTranslatorPass(getOptLevel()), PMW);
144 return Error::success();
145}
146
147void X86CodeGenPassBuilder::addPreLegalizeMachineIR(PassManagerWrapper &PMW) {
148 if (getOptLevel() != CodeGenOptLevel::None)
149 addMachineFunctionPass(X86PreLegalizerCombinerPass(), PMW);
150}
151
152Error X86CodeGenPassBuilder::addLegalizeMachineIR(PassManagerWrapper &PMW) {
153 addMachineFunctionPass(LegalizerPass(), PMW);
154 return Error::success();
155}
156
157void X86CodeGenPassBuilder::addPreRegBankSelect(PassManagerWrapper &PMW) {
158 if (getOptLevel() != CodeGenOptLevel::None)
159 addMachineFunctionPass(X86PostLegalizerCombinerPass(), PMW);
160}
161
162Error X86CodeGenPassBuilder::addRegBankSelect(PassManagerWrapper &PMW) {
163 addMachineFunctionPass(RegBankSelectPass(), PMW);
164 return Error::success();
165}
166
167Error X86CodeGenPassBuilder::addGlobalInstructionSelect(
168 PassManagerWrapper &PMW) {
169 addMachineFunctionPass(InstructionSelectPass(getOptLevel()), PMW);
170 // Add GlobalBaseReg in case there is no SelectionDAG passes afterwards
171 if (isGlobalISelAbortEnabled())
172 addMachineFunctionPass(X86GlobalBaseRegPass(), PMW);
173 return Error::success();
174}
175
176void X86CodeGenPassBuilder::addMachineSSAOptimization(PassManagerWrapper &PMW) {
177 addMachineFunctionPass(X86DomainReassignmentPass(), PMW);
178 Base::addMachineSSAOptimization(PMW);
179}
180
181void X86CodeGenPassBuilder::addILPOpts(PassManagerWrapper &PMW) {
182 addMachineFunctionPass(EarlyIfConverterPass(), PMW);
183 if (getTM().getCLOpts().machine_combiner)
184 addMachineFunctionPass(MachineCombinerPass(), PMW);
185 addMachineFunctionPass(X86CmovConversionPass(), PMW);
186}
187
188void X86CodeGenPassBuilder::addPreRegAlloc(PassManagerWrapper &PMW) {
189 if (getOptLevel() != CodeGenOptLevel::None) {
190 addMachineFunctionPass(LiveRangeShrinkPass(), PMW);
191 addMachineFunctionPass(X86FixupSetCCPass(), PMW);
192 addMachineFunctionPass(X86OptimizeLEAsPass(), PMW);
193 addMachineFunctionPass(X86CallFrameOptimizationPass(), PMW);
194 addMachineFunctionPass(X86AvoidStoreForwardingBlocksPass(), PMW);
195 }
196
197 addMachineFunctionPass(X86SuppressAPXForRelocationPass(), PMW);
198 addMachineFunctionPass(X86SpeculativeLoadHardeningPass(), PMW);
199 addMachineFunctionPass(X86FlagsCopyLoweringPass(), PMW);
200 addMachineFunctionPass(X86DynAllocaExpanderPass(), PMW);
201
202 if (getOptLevel() != CodeGenOptLevel::None)
203 addMachineFunctionPass(X86PreTileConfigPass(), PMW);
204 else
205 addMachineFunctionPass(X86FastPreTileConfigPass(), PMW);
206}
207
208static bool onlyAllocateTileRegisters(const TargetRegisterInfo &TRI,
209 const MachineRegisterInfo &MRI,
210 const Register Reg) {
212 return static_cast<const X86RegisterInfo &>(TRI).isTileRegisterClass(RC);
213}
214
215Error X86CodeGenPassBuilder::addRegAssignAndRewriteFast(
216 PassManagerWrapper &PMW) {
217 Error PossibleError = Base::addRegAssignAndRewriteFast(PMW);
218 addMachineFunctionPass(X86FastTileConfigPass(), PMW);
219 return PossibleError;
220}
221
222Expected<bool> X86CodeGenPassBuilder::addRegAssignAndRewriteOptimized(
223 PassManagerWrapper &PMW) {
224 // Don't support tile RA when RA is specified by command line "-regalloc".
225 if (Opt.RegAlloc == RegAllocType::Default && getTM().getCLOpts().tile_ra) {
226 // Allocate tile register first.
227 addMachineFunctionPass(
228 RAGreedyPass({RAGreedyPass::Options(onlyAllocateTileRegisters)}), PMW);
229 addMachineFunctionPass(X86TileConfigPass(), PMW);
230 }
231 return Base::addRegAssignAndRewriteOptimized(PMW);
232}
233
234void X86CodeGenPassBuilder::addPostRegAlloc(PassManagerWrapper &PMW) {
235 addMachineFunctionPass(X86LowerTileCopyPass(), PMW);
236 addMachineFunctionPass(X86FPStackifierPass(), PMW);
237 // When -O0 is enabled, the Load Value Injection Hardening pass will fall back
238 // to using the Speculative Execution Side Effect Suppression pass for
239 // mitigation. This is to prevent slow downs due to
240 // analyses needed by the LVIHardening pass when compiling at -O0.
241 if (getOptLevel() != CodeGenOptLevel::None) {
242 addMachineFunctionPass(X86LoadValueInjectionLoadHardeningPass(), PMW);
243 }
244}
245
246void X86CodeGenPassBuilder::addPreSched2(PassManagerWrapper &PMW) {
247 addMachineFunctionPass(X86ExpandPseudoPass(), PMW);
248 addMachineFunctionPass(MachineKCFIPass(), PMW);
249}
250
251void X86CodeGenPassBuilder::addPreEmitPass(PassManagerWrapper &PMW) {
252 if (getOptLevel() != CodeGenOptLevel::None) {
253 // TODO(boomanaiden154): Add X86ExecutionDomainFixPass here once it has
254 // been ported.
255 addMachineFunctionPass(BreakFalseDepsPass(), PMW);
256 }
257
258 addMachineFunctionPass(X86IndirectBranchTrackingPass(), PMW);
259 addMachineFunctionPass(X86InsertVZeroUpperPass(), PMW);
260
261 if (getOptLevel() != CodeGenOptLevel::None) {
262 addMachineFunctionPass(X86FixupBWInstsPass(), PMW);
263 addMachineFunctionPass(X86PadShortFunctionsPass(), PMW);
264 addMachineFunctionPass(X86FixupLEAsPass(), PMW);
265 addMachineFunctionPass(X86FixupInstTuningPass(), PMW);
266 addMachineFunctionPass(X86FixupVectorConstantsPass(), PMW);
267 }
268 addMachineFunctionPass(X86CompressEVEXPass(), PMW);
269 addMachineFunctionPass(X86InsertX87WaitPass(), PMW);
270
271 if (TM.getTargetTriple().isLFI())
272 addMachineFunctionPass(X86LFIRewritePass(), PMW);
273}
274
275void X86CodeGenPassBuilder::addPreEmitPass2(PassManagerWrapper &PMW) {
276 const Triple &TT = TM.getTargetTriple();
277
278 // The X86 Speculative Execution Pass must run after all control
279 // flow graph modifying passes. As a result it was listed to run right before
280 // the X86 Retpoline Thunks pass. The reason it must run after control flow
281 // graph modifications is that the model of LFENCE in LLVM has to be updated
282 // (FIXME: https://bugs.llvm.org/show_bug.cgi?id=45167). Currently the
283 // placement of this pass was hand checked to ensure that the subsequent
284 // passes don't move the code around the LFENCEs in a way that will hurt the
285 // correctness of this pass. This placement has been shown to work based on
286 // hand inspection of the codegen output.
287 addMachineFunctionPass(X86SpeculativeExecutionSideEffectSuppressionPass(),
288 PMW);
289 // TODO(boomanaiden154): Add X86IndirectThunksPass here
290 // once it has been ported.
291 addMachineFunctionPass(X86ReturnThunksPass(), PMW);
292
293 // Insert extra int3 instructions after trailing call instructions to avoid
294 // issues in the unwinder.
295 if (TT.isOSWindows() && TT.isX86_64())
296 addMachineFunctionPass(X86AvoidTrailingCallPass(), PMW);
297
298 // Verify basic block incoming and outgoing cfa offset and register values and
299 // correct CFA calculation rule where needed by inserting appropriate CFI
300 // instructions. CFIInstrInserter self-skips targets that do not use DWARF
301 // CFI.
302 if (!TT.isOSDarwin())
303 addMachineFunctionPass(CFIInstrInserterPass(), PMW);
304
305 if (TT.isOSWindows()) {
306 // Identify valid longjmp targets for Windows Control Flow Guard.
307 addMachineFunctionPass(CFGuardLongjmpPass(), PMW);
308 // Identify valid eh continuation targets for Windows EHCont Guard.
309 addMachineFunctionPass(EHContGuardTargetsPass(), PMW);
310 }
311
312 addMachineFunctionPass(X86LoadValueInjectionRetHardeningPass(), PMW);
313
314 // Insert pseudo probe annotation for callsite profiling
315 addMachineFunctionPass(PseudoProbeInserterPass(), PMW);
316
317 // KCFI indirect call checks are lowered to a bundle, and on Darwin platforms,
318 // also CALL_RVMARKER.
319 addMachineFunctionPass(
320 UnpackMachineBundlesPass([&TT](const MachineFunction &MF) {
321 // Only run bundle expansion if the module uses kcfi, or there are
322 // relevant ObjC runtime functions present in the module.
323 const Function &F = MF.getFunction();
324 const Module *M = F.getParent();
325 return M->getModuleFlag("kcfi") ||
326 (TT.isOSDarwin() &&
327 (M->getFunction("objc_retainAutoreleasedReturnValue") ||
328 M->getFunction("objc_unsafeClaimAutoreleasedReturnValue")));
329 }),
330 PMW);
331
332 // Analyzes and emits pseudos to support Win x64 Unwind V2. This pass must run
333 // after all real instructions have been added to the epilog.
334 if (TT.isOSWindows() && TT.isX86_64()) {
335 addMachineFunctionPass(X86WinEHUnwindV2Pass(), PMW);
336 }
337}
338
339void X86CodeGenPassBuilder::addAsmPrinterBegin(PassManagerWrapper &PMW) {
340 addModulePass(X86AsmPrinterBeginPass(), PMW, /*Force=*/true);
341}
342
343void X86CodeGenPassBuilder::addAsmPrinter(PassManagerWrapper &PMW) {
344 addMachineFunctionPass(X86AsmPrinterPass(), PMW);
345}
346
347void X86CodeGenPassBuilder::addAsmPrinterEnd(PassManagerWrapper &PMW) {
348 addModulePass(X86AsmPrinterEndPass(), PMW, /*Force=*/true);
349}
350
351} // namespace
352
354#define GET_PASS_REGISTRY "X86PassRegistry.def"
356}
357
360 raw_pwrite_stream *DwoOut, CodeGenFileType FileType,
361 const CGPassBuilderOption &Opt, MCContext &Ctx,
363 auto CGPB = X86CodeGenPassBuilder(*this, Opt, PIC);
364 return CGPB.buildPipeline(MPM, MAM, Out, DwoOut, FileType, Ctx);
365}
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
MachineRegisterInfo & MRI
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:309
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