LLVM 24.0.0git
NVPTXTargetMachine.cpp
Go to the documentation of this file.
1//===-- NVPTXTargetMachine.cpp - Define TargetMachine for NVPTX -----------===//
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//
9// Top-level implementation for the NVPTX target.
10//
11//===----------------------------------------------------------------------===//
12
13#include "NVPTXTargetMachine.h"
14#include "NVPTX.h"
15#include "NVPTXAliasAnalysis.h"
21#include "llvm/CodeGen/Passes.h"
23#include "llvm/IR/IntrinsicsNVPTX.h"
26#include "llvm/Pass.h"
35#include <cassert>
36#include <optional>
37#include <string>
38
39using namespace llvm;
40
42 // Register the target.
46
48 // FIXME: This pass is really intended to be invoked during IR optimization,
49 // but it's very NVPTX-specific.
75}
76
78 StringRef CPU, StringRef FS,
80 std::optional<Reloc::Model> RM,
81 std::optional<CodeModel::Model> CM,
82 CodeGenOptLevel OL, bool JIT)
83 // The pic relocation model is used regardless of what the client has
84 // specified, as it is the only relocation model currently supported.
85 : CodeGenTargetMachineImpl(T, TT, CPU, FS, Options, Reloc::PIC_,
86 getEffectiveCodeModel(CM, CodeModel::Small), OL),
87 CLOpts(cl::LibraryOptionsContext::get<NVPTXOptions>(
88 Options.MCOptions.LibraryOptions)),
89 TLOF(std::make_unique<NVPTXTargetObjectFile>()),
90 Subtarget(TT, CPU, FS, *this) {
91 if (!CLOpts.disable_nvptx_require_structured_cfg)
93 // NVPTX does not produce verifier-clean MIR yet; see isMachineVerifierClean()
94 // for the legacy pass manager equivalent.
97}
98
100
101namespace {
102
103/// NVPTXPassConfig mirrors the NewPM implementation in NVPTXCodeGenPassBuilder
104/// in NVPTXCodeGenPassBuilder.cpp; the two must be kept in sync until this path
105/// is removed.
106class NVPTXPassConfig : public TargetPassConfig {
107 const NVPTXOptions &CLOpts;
108
109public:
110 NVPTXPassConfig(NVPTXTargetMachine &TM, PassManagerBase &PM)
111 : TargetPassConfig(TM, PM), CLOpts(TM.getCLOpts()) {}
112
113 NVPTXTargetMachine &getNVPTXTargetMachine() const {
115 }
116
117 void addIRPasses() override;
118 bool addInstSelector() override;
119 void addPreRegAlloc() override;
120 void addPostRegAlloc() override;
121
122 FunctionPass *createTargetRegisterAllocator(bool) override;
123 void addFastRegAlloc() override;
124 void addOptimizedRegAlloc() override;
125
126 bool addRegAssignAndRewriteFast() override {
127 llvm_unreachable("should not be used");
128 }
129
130 bool addRegAssignAndRewriteOptimized() override {
131 llvm_unreachable("should not be used");
132 }
133
134private:
135 // If the opt level is aggressive, add GVN; otherwise, add EarlyCSE. This
136 // function is only called in opt mode.
137 void addEarlyCSEOrGVNPass();
138
139 // Add passes that propagate special memory spaces.
140 void addAddressSpaceInferencePasses();
141
142 // Add passes that perform straight-line scalar optimizations.
143 void addStraightLineScalarOptimizationPasses();
144};
145
146} // end anonymous namespace
147
149 return new NVPTXPassConfig(*this, PM);
150}
151
158
162
165 return TargetTransformInfo(std::make_unique<NVPTXTTIImpl>(this, F));
166}
167
168std::pair<const Value *, unsigned>
170 if (auto *II = dyn_cast<IntrinsicInst>(V)) {
171 switch (II->getIntrinsicID()) {
172 case Intrinsic::nvvm_isspacep_const:
173 return std::make_pair(II->getArgOperand(0), llvm::ADDRESS_SPACE_CONST);
174 case Intrinsic::nvvm_isspacep_global:
175 return std::make_pair(II->getArgOperand(0), llvm::ADDRESS_SPACE_GLOBAL);
176 case Intrinsic::nvvm_isspacep_local:
177 return std::make_pair(II->getArgOperand(0), llvm::ADDRESS_SPACE_LOCAL);
178 case Intrinsic::nvvm_isspacep_shared:
179 return std::make_pair(II->getArgOperand(0), llvm::ADDRESS_SPACE_SHARED);
180 case Intrinsic::nvvm_isspacep_shared_cluster:
181 return std::make_pair(II->getArgOperand(0),
183 default:
184 break;
185 }
186 }
187 return std::make_pair(nullptr, -1);
188}
189
190void NVPTXPassConfig::addEarlyCSEOrGVNPass() {
191 if (getOptLevel() == CodeGenOptLevel::Aggressive)
192 // Disable scalar PRE due to Register Pressure increase
193 addPass(createGVNPass(/*ScalarPRE=*/false));
194 else
195 addPass(createEarlyCSEPass());
196}
197
198void NVPTXPassConfig::addAddressSpaceInferencePasses() {
199 // NVPTXLowerArgs emits alloca for byval parameters which can often
200 // be eliminated by SROA.
201 addPass(createSROAPass(/*PreserveCFG=*/true,
202 /*AggregateToVector=*/true));
204 // TODO: Consider running InferAddressSpaces during opt, earlier in the
205 // compilation flow.
208}
209
210void NVPTXPassConfig::addStraightLineScalarOptimizationPasses() {
213 // ReassociateGEPs exposes more opportunites for SLSR. See
214 // the example in reassociate-geps-and-slsr.ll.
216 // SeparateConstOffsetFromGEP and SLSR creates common expressions which GVN or
217 // EarlyCSE can reuse. GVN generates significantly better code than EarlyCSE
218 // for some of our benchmarks.
219 addEarlyCSEOrGVNPass();
220 // Run NaryReassociate after EarlyCSE/GVN to be more effective.
221 addPass(createNaryReassociatePass());
222 // NaryReassociate on GEPs creates redundant common expressions, so run
223 // EarlyCSE after it.
224 addPass(createEarlyCSEPass());
225}
226
227void NVPTXPassConfig::addIRPasses() {
228 // The following passes are known to not play well with virtual regs hanging
229 // around after register allocation (which in our case, is *all* registers).
230 // We explicitly disable them here. We do, however, need some functionality
231 // of the PrologEpilogCodeInserter pass, so we emulate that behavior in the
232 // NVPTXPrologEpilog pass (see NVPTXPrologEpilogPass.cpp).
233 disablePass(&PrologEpilogCodeInserterID);
234 disablePass(&MachineLateInstrsCleanupID);
235 disablePass(&MachineCopyPropagationID);
236 disablePass(&TailDuplicateLegacyID);
237 disablePass(&StackMapLivenessID);
238 disablePass(&PostRAMachineSinkingID);
239 disablePass(&PostRASchedulerID);
240 disablePass(&FuncletLayoutID);
241 disablePass(&PatchableFunctionID);
242 disablePass(&ShrinkWrapID);
243 disablePass(&RemoveLoadsIntoFakeUsesID);
244
245 // Leave block placement to ptxas. Its CFG transformations can invalidate
246 // layout decisions made at the PTX level, and block placement here can
247 // interfere with ptxas analyses.
248 disablePass(&MachineBlockPlacementID);
249
250 addPass(createNVPTXAAWrapperPass());
252
253 // NVVMReflectPass is added in addEarlyAsPossiblePasses, so hopefully running
254 // it here does nothing. But since we need it for correctness when lowering
255 // to NVPTX, run it here too, in case whoever built our pass pipeline didn't
256 // call addEarlyAsPossiblePasses.
258 addPass(createNVVMReflectPass(ST.getSmVersion()));
260
261 if (getOptLevel() != CodeGenOptLevel::None)
265
266 // Lower variadic calls before address space inference.
268
269 // NVPTXLowerArgs is required for correctness and should be run right
270 // before the address space inference passes.
271 if (getNVPTXTargetMachine().getDrvInterface() == NVPTX::CUDA)
274 addPass(createNVPTXLowerArgsPass());
275 if (getOptLevel() != CodeGenOptLevel::None) {
276 addAddressSpaceInferencePasses();
277 addStraightLineScalarOptimizationPasses();
278 } else {
279 // Required for correct stack lowering
281 }
282
285
286 // === LSR and other generic IR passes ===
288 // EarlyCSE is not always strong enough to clean up what LSR produces. For
289 // example, GVN can combine
290 //
291 // %0 = add %a, %b
292 // %1 = add %b, %a
293 //
294 // and
295 //
296 // %0 = shl nsw %a, 2
297 // %1 = shl %a, 2
298 //
299 // but EarlyCSE can do neither of them.
300 if (getOptLevel() != CodeGenOptLevel::None) {
301 addEarlyCSEOrGVNPass();
302 if (!CLOpts.disable_nvptx_load_store_vectorizer)
304 addPass(createSROAPass(/*PreserveCFG=*/true,
305 /*AggregateToVector=*/true));
307 if (!CLOpts.disable_nvptx_ir_peephole)
308 addPass(createNVPTXIRPeepholePass());
309 }
310
311 if (ST.hasPTXASUnreachableBug()) {
312 // Run LowerUnreachable to WAR a ptxas bug. See the commit description of
313 // 1ee4d880e8760256c606fe55b7af85a4f70d006d for more details.
314 const auto &Options = getNVPTXTargetMachine().Options;
315 addPass(createNVPTXLowerUnreachableLegacyPass(Options.TrapUnreachable,
316 Options.NoTrapAfterNoreturn));
317 }
318}
319
320bool NVPTXPassConfig::addInstSelector() {
323 addPass(createNVPTXISelDag(getNVPTXTargetMachine(), getOptLevel()));
325
326 return false;
327}
328
329void NVPTXPassConfig::addPreRegAlloc() {
331 if (getOptLevel() != CodeGenOptLevel::None)
333 // Remove Proxy Register pseudo instructions used to keep `callseq_end` alive.
335}
336
337void NVPTXPassConfig::addPostRegAlloc() {
339 if (getOptLevel() != CodeGenOptLevel::None) {
340 // NVPTXPrologEpilogPass calculates frame object offset and replace frame
341 // index with VRFrame register. NVPTXPeephole need to be run after that and
342 // will replace VRFrame with VRFrameLocal when possible.
344 }
345}
346
347FunctionPass *NVPTXPassConfig::createTargetRegisterAllocator(bool) {
348 return nullptr; // No reg alloc
349}
350
351void NVPTXPassConfig::addFastRegAlloc() {
352 addPass(&PHIEliminationID);
354}
355
356void NVPTXPassConfig::addOptimizedRegAlloc() {
357 addPass(&ProcessImplicitDefsID);
358 addPass(&MachineLoopInfoID);
359 addPass(&PHIEliminationID);
360
362 addPass(&RegisterCoalescerID);
363
364 // PreRA instruction scheduling.
365 if (addPass(&MachineSchedulerID))
366 printAndVerify("After Machine Scheduling");
367
368 addPass(&StackSlotColoringID);
369
370 // FIXME: Needs physical registers
371 // addPass(&MachineLICMID);
372
373 printAndVerify("After StackSlotColoring");
374}
#define X(NUM, ENUM, NAME)
Definition ELF.h:665
#define LLVM_ABI
Definition Compiler.h:211
#define LLVM_EXTERNAL_VISIBILITY
Definition Compiler.h:132
This file provides the interface for LLVM's Global Value Numbering pass which eliminates fully redund...
static LVOptions Options
Definition LVOptions.cpp:25
#define F(x, y, z)
Definition MD5.cpp:54
#define T
This is the NVPTX address space based alias analysis pass.
LLVM_ABI LLVM_EXTERNAL_VISIBILITY void LLVMInitializeNVPTXTarget()
This file a TargetTransformInfoImplBase conforming object specific to the NVPTX target machine.
uint64_t IntrinsicInst * II
const GCNTargetMachine & getTM(const GCNSubtarget *STI)
static TableGen::Emitter::Opt Y("gen-skeleton-entry", EmitSkeleton, "Generate example skeleton entry")
Target-Independent Code Generator Pass Configuration Options pass.
This pass exposes codegen information to IR-level passes.
A manager for alias analyses.
void registerFunctionAnalysis()
Register a specific AA result.
CodeGenTargetMachineImpl(const Target &T, const Triple &TT, StringRef CPU, StringRef FS, const TargetOptions &Options, Reloc::Model RM, CodeModel::Model CM, CodeGenOptLevel OL)
FunctionPass class - This class is used to implement most global optimizations.
Definition Pass.h:312
const TargetSubtargetInfo * getSubtargetImpl(const Function &) const override
Virtual method implemented by subclasses that returns a reference to that target's TargetSubtargetInf...
Analysis pass providing a never-invalidated alias analysis result.
NVPTXTargetMachine(const Target &T, const Triple &TT, StringRef CPU, StringRef FS, const TargetOptions &Options, std::optional< Reloc::Model > RM, std::optional< CodeModel::Model > CM, CodeGenOptLevel OL, bool JIT)
TargetTransformInfo getTargetTransformInfo(const Function &F) const override
Get a TargetTransformInfo implementation for the target.
std::pair< const Value *, unsigned > getPredicatedAddrSpace(const Value *V) const override
If the specified predicate checks whether a generic pointer falls within a specified address space,...
void registerEarlyDefaultAliasAnalyses(AAManager &AAM) override
Allow the target to register early alias analyses (AA before BasicAA) with the AAManager for use with...
~NVPTXTargetMachine() override
MachineFunctionInfo * createMachineFunctionInfo(BumpPtrAllocator &Allocator, const Function &F, const TargetSubtargetInfo *STI) const override
Create the target's instance of MachineFunctionInfo.
TargetPassConfig * createPassConfig(PassManagerBase &PM) override
Create a pass configuration object to be used by addPassToEmitX methods for generating a pipeline of ...
PassRegistry - This class manages the registration and intitialization of the pass subsystem as appli...
static LLVM_ABI PassRegistry * getPassRegistry()
getPassRegistry - Access the global registry object, which is automatically initialized at applicatio...
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
void setRequiresStructuredCFG(bool Value)
std::unique_ptr< const MCSubtargetInfo > STI
TargetOptions Options
void setEnableDefaultMachineVerifier(bool Enable)
Target-Independent Code Generator Pass Configuration Options.
virtual void addIRPasses()
Add common target configurable passes that perform LLVM IR to IR transforms following machine indepen...
TargetSubtargetInfo - Generic base class for all target subtargets.
This pass provides access to the codegen interfaces that are needed for IR-level transformations.
Target - Wrapper for Target specific information.
Triple - Helper class for working with autoconf configuration names.
Definition Triple.h:48
LLVM Value Representation.
Definition Value.h:75
PassManagerBase - An abstract interface to allow code to add passes to a pass manager without having ...
Registers T::Global with cl::ParseCommandLineOptions.
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
This namespace contains all of the command line option processing machinery.
This is an optimization pass for GlobalISel generic memory operations.
FunctionPass * createNVPTXLowerUnreachableLegacyPass(bool TrapUnreachable, bool NoTrapAfterNoreturn)
FunctionPass * createNVPTXIRPeepholePass()
FunctionPass * createNVPTXAtomicLowerLegacyPass()
FunctionPass * createNVPTXImageOptimizerLegacyPass()
void initializeNVPTXLowerUnreachableLegacyPassPass(PassRegistry &)
LLVM_ABI char & RegisterCoalescerID
RegisterCoalescer - This pass merges live ranges to eliminate copies.
decltype(auto) dyn_cast(const From &Val)
dyn_cast<X> - Return the argument parameter cast to the specified type.
Definition Casting.h:643
ModulePass * createGenericToNVVMLegacyPass()
void initializeNVPTXExternalAAWrapperPass(PassRegistry &)
void initializeNVPTXPeepholeLegacyPassPass(PassRegistry &)
void initializeNVPTXPrologEpilogLegacyPassPass(PassRegistry &)
LLVM_ABI char & TailDuplicateLegacyID
TailDuplicate - Duplicate blocks with unconditional branches into tails of their predecessors.
LLVM_ABI Pass * createLoadStoreVectorizerPass()
Create a legacy pass manager instance of the LoadStoreVectorizer pass.
LLVM_ABI FunctionPass * createNaryReassociatePass()
LLVM_ABI char & PatchableFunctionID
This pass implements the "patchable-function" attribute.
ImmutablePass * createNVPTXExternalAAWrapperPass()
void initializeNVPTXLowerArgsLegacyPassPass(PassRegistry &)
LLVM_ABI char & PostRASchedulerID
PostRAScheduler - This pass performs post register allocation scheduling.
LLVM_ABI char & RemoveLoadsIntoFakeUsesID
RemoveLoadsIntoFakeUses pass.
MachineFunctionPass * createNVPTXReplaceImageHandlesLegacyPass()
void initializeNVPTXForwardParamsLegacyPassPass(PassRegistry &)
FunctionPass * createNVPTXLowerAggrCopiesLegacyPass()
ModulePass * createNVPTXAssignValidGlobalNamesLegacyPass()
LLVM_ABI char & MachineSchedulerID
MachineScheduler - This pass schedules machine instructions.
void initializeNVPTXAssignValidGlobalNamesLegacyPassPass(PassRegistry &)
FunctionPass * createNVPTXISelDag(NVPTXTargetMachine &TM, llvm::CodeGenOptLevel OptLevel)
createNVPTXISelDag - This pass converts a legalized DAG into a NVPTX-specific DAG,...
LLVM_ABI char & PrologEpilogCodeInserterID
PrologEpilogCodeInserter - This pass inserts prolog and epilog code, and eliminates abstract frame re...
MachineFunctionPass * createNVPTXAddressFolderLegacyPass()
void initializeNVPTXLowerAllocaLegacyPassPass(PassRegistry &)
void initializeGenericToNVVMLegacyPassPass(PassRegistry &)
void initializeNVPTXCtorDtorLoweringLegacyPass(PassRegistry &)
MachineFunctionPass * createNVPTXForwardParamsLegacyPass()
FunctionPass * createNVPTXTagInvariantLoadsPass()
LLVM_ABI char & MachineLoopInfoID
MachineLoopInfo - This pass is a loop analysis pass.
void initializeNVVMReflectLegacyPassPass(PassRegistry &)
void initializeNVPTXAddressFolderLegacyPassPass(PassRegistry &)
CodeModel::Model getEffectiveCodeModel(std::optional< CodeModel::Model > CM, CodeModel::Model Default)
Helper method for getting the code model, returning Default if CM does not have a value.
LLVM_ABI ModulePass * createExpandVariadicsPass(ExpandVariadicsMode)
LLVM_ABI char & ShrinkWrapID
ShrinkWrap pass. Look for the best place to insert save and restore.
LLVM_ABI char & MachineLateInstrsCleanupID
MachineLateInstrsCleanup - This pass removes redundant identical instructions after register allocati...
void initializeNVPTXAAWrapperPassPass(PassRegistry &)
decltype(auto) get(const PointerIntPair< PointerTy, IntBits, IntType, PtrTraits, Info > &Pair)
ModulePass * createNVPTXCanonicalizeDynamicSharedLegacyPass()
void initializeNVPTXIRPeepholePass(PassRegistry &)
ModulePass * createNVPTXLowerArgsPass()
LLVM_ABI FunctionPass * createSpeculativeExecutionPass()
LLVM_ABI char & StackMapLivenessID
StackMapLiveness - This pass analyses the register live-out set of stackmap/patchpoint intrinsics and...
FunctionPass * createNVPTXMarkKernelPtrsGlobalPass()
LLVM_ABI char & FuncletLayoutID
This pass lays out funclets contiguously.
void initializeNVVMIntrRangePass(PassRegistry &)
MachineFunctionPass * createNVPTXPrologEpilogLegacyPass()
LLVM_ABI char & PostRAMachineSinkingID
This pass perform post-ra machine sink for COPY instructions.
CodeGenOptLevel
Code generation optimization level.
Definition CodeGen.h:280
void initializeNVPTXCanonicalizeDynamicSharedLegacyPassPass(PassRegistry &)
void initializeNVPTXLowerAggrCopiesLegacyPassPass(PassRegistry &)
LLVM_ABI char & StackSlotColoringID
StackSlotColoring - This pass performs stack slot coloring.
ModulePass * createNVPTXPromoteParamAlignPass()
void initializeNVPTXAsmPrinterPass(PassRegistry &)
LLVM_ABI FunctionPass * createSeparateConstOffsetFromGEPPass(bool LowerGEP=false)
void initializeNVPTXProxyRegErasureLegacyPassPass(PassRegistry &)
LLVM_ABI char & ProcessImplicitDefsID
ProcessImpicitDefs pass - This pass removes IMPLICIT_DEFs.
void initializeNVPTXTagInvariantLoadLegacyPassPass(PassRegistry &)
void initializeNVPTXAtomicLowerLegacyPassPass(PassRegistry &)
MachineFunctionPass * createNVPTXPeepholeLegacyPass()
LLVM_ABI FunctionPass * createGVNPass()
Definition GVN.cpp:4442
FunctionPass * createNVPTXLowerAllocaLegacyPass()
ModulePass * createNVPTXCtorDtorLoweringLegacyPass()
void initializeNVPTXMarkKernelPtrsGlobalLegacyPassPass(PassRegistry &)
LLVM_ABI FunctionPass * createSROAPass(bool PreserveCFG=true, bool AggregateToVector=false)
Definition SROA.cpp:6687
Target & getTheNVPTXTarget64()
LLVM_ABI FunctionPass * createInferAddressSpacesPass(unsigned AddressSpace=~0u)
void initializeNVPTXAllocaHoistingLegacyPassPass(PassRegistry &)
ImmutablePass * createNVPTXAAWrapperPass()
FunctionPass * createNVPTXAllocaHoistingLegacyPass()
ModulePass * createNVVMReflectPass(unsigned int SmVersion)
LLVM_ABI char & MachineBlockPlacementID
MachineBlockPlacement - This pass places basic blocks based on branch probabilities.
LLVM_ABI char & TwoAddressInstructionPassID
TwoAddressInstruction - This pass reduces two-address instructions to use two operands.
void initializeNVPTXPromoteParamAlignLegacyPassPass(PassRegistry &)
LLVM_ABI FunctionPass * createAtomicExpandLegacyPass()
AtomicExpandPass - At IR level this pass replace atomic instructions with __atomic_* library calls,...
LLVM_ABI FunctionPass * createStraightLineStrengthReducePass()
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition Allocator.h:391
LLVM_ABI FunctionPass * createEarlyCSEPass(bool UseMemorySSA=false)
LLVM_ABI char & PHIEliminationID
PHIElimination - This pass eliminates machine instruction PHI nodes by inserting copy instructions.
MachineFunctionPass * createNVPTXProxyRegErasureLegacyPass()
LLVM_ABI char & MachineCopyPropagationID
MachineCopyPropagation - This pass performs copy propagation on machine instructions.
Target & getTheNVPTXTarget32()
void initializeNVPTXDAGToDAGISelLegacyPass(PassRegistry &)
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:878
MachineFunctionInfo - This class can be derived from and used by targets to hold private target-speci...
static FuncInfoTy * create(BumpPtrAllocator &Allocator, const Function &F, const SubtargetTy *STI)
Factory function: default behavior is to call new using the supplied allocator.
RegisterTargetMachine - Helper template for registering a target machine implementation,...