Movatterモバイル変換


[0]ホーム

URL:


LLVM 20.0.0git
AMDGPUMachineFunction.cpp
Go to the documentation of this file.
1//===-- AMDGPUMachineFunctionInfo.cpp ---------------------------------------=//
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#include "AMDGPUMachineFunction.h"
10#include "AMDGPU.h"
11#include "AMDGPUMemoryUtils.h"
12#include "AMDGPUSubtarget.h"
13#include "Utils/AMDGPUBaseInfo.h"
14#include "llvm/CodeGen/MachineModuleInfo.h"
15#include "llvm/IR/ConstantRange.h"
16#include "llvm/IR/Constants.h"
17#include "llvm/IR/Metadata.h"
18#include "llvm/Target/TargetMachine.h"
19
20using namespacellvm;
21
22staticconstGlobalVariable *
23getKernelDynLDSGlobalFromFunction(constFunction &F) {
24constModule *M =F.getParent();
25SmallString<64> KernelDynLDSName("llvm.amdgcn.");
26 KernelDynLDSName +=F.getName();
27 KernelDynLDSName +=".dynlds";
28return M->getNamedGlobal(KernelDynLDSName);
29}
30
31staticboolhasLDSKernelArgument(constFunction &F) {
32for (constArgument &Arg :F.args()) {
33Type *ArgTy = Arg.getType();
34if (auto *PtrTy = dyn_cast<PointerType>(ArgTy)) {
35if (PtrTy->getAddressSpace() ==AMDGPUAS::LOCAL_ADDRESS)
36returntrue;
37 }
38 }
39returnfalse;
40}
41
42AMDGPUMachineFunction::AMDGPUMachineFunction(constFunction &F,
43constAMDGPUSubtarget &ST)
44 : IsEntryFunction(AMDGPU::isEntryFunctionCC(F.getCallingConv())),
45 IsModuleEntryFunction(
46 AMDGPU::isModuleEntryFunctionCC(F.getCallingConv())),
47 IsChainFunction(AMDGPU::isChainCC(F.getCallingConv())) {
48
49// FIXME: Should initialize KernArgSize based on ExplicitKernelArgOffset,
50// except reserved size is not correctly aligned.
51
52Attribute MemBoundAttr =F.getFnAttribute("amdgpu-memory-bound");
53MemoryBound = MemBoundAttr.getValueAsBool();
54
55Attribute WaveLimitAttr =F.getFnAttribute("amdgpu-wave-limiter");
56WaveLimiter = WaveLimitAttr.getValueAsBool();
57
58// FIXME: How is this attribute supposed to interact with statically known
59// global sizes?
60StringRef S =F.getFnAttribute("amdgpu-gds-size").getValueAsString();
61if (!S.empty())
62 S.consumeInteger(0,GDSSize);
63
64// Assume the attribute allocates before any known GDS globals.
65StaticGDSSize =GDSSize;
66
67// Second value, if present, is the maximum value that can be assigned.
68// Useful in PromoteAlloca or for LDS spills. Could be used for diagnostics
69// during codegen.
70 std::pair<unsigned, unsigned> LDSSizeRange =AMDGPU::getIntegerPairAttribute(
71F,"amdgpu-lds-size", {0, UINT32_MAX},true);
72
73// The two separate variables are only profitable when the LDS module lowering
74// pass is disabled. If graphics does not use dynamic LDS, this is never
75// profitable. Leaving cleanup for a later change.
76LDSSize = LDSSizeRange.first;
77StaticLDSSize =LDSSize;
78
79CallingConv::IDCC =F.getCallingConv();
80if (CC ==CallingConv::AMDGPU_KERNEL ||CC ==CallingConv::SPIR_KERNEL)
81ExplicitKernArgSize = ST.getExplicitKernArgSize(F,MaxKernArgAlign);
82
83// FIXME: Shouldn't be target specific
84Attribute NSZAttr =F.getFnAttribute("no-signed-zeros-fp-math");
85NoSignedZerosFPMath =
86 NSZAttr.isStringAttribute() && NSZAttr.getValueAsString() =="true";
87
88constGlobalVariable *DynLdsGlobal =getKernelDynLDSGlobalFromFunction(F);
89if (DynLdsGlobal ||hasLDSKernelArgument(F))
90UsesDynamicLDS =true;
91}
92
93unsignedAMDGPUMachineFunction::allocateLDSGlobal(constDataLayout &DL,
94constGlobalVariable &GV,
95Align Trailing) {
96auto Entry = LocalMemoryObjects.insert(std::pair(&GV, 0));
97if (!Entry.second)
98return Entry.first->second;
99
100Align Alignment =
101DL.getValueOrABITypeAlignment(GV.getAlign(), GV.getValueType());
102
103unsignedOffset;
104if (GV.getAddressSpace() ==AMDGPUAS::LOCAL_ADDRESS) {
105if (AMDGPU::isNamedBarrier(GV)) {
106 std::optional<unsigned> BarAddr =getLDSAbsoluteAddress(GV);
107if (!BarAddr)
108llvm_unreachable("named barrier should have an assigned address");
109 Entry.first->second = BarAddr.value();
110return BarAddr.value();
111 }
112
113 std::optional<uint32_t> MaybeAbs =getLDSAbsoluteAddress(GV);
114if (MaybeAbs) {
115// Absolute address LDS variables that exist prior to the LDS lowering
116// pass raise a fatal error in that pass. These failure modes are only
117// reachable if that lowering pass is disabled or broken. If/when adding
118// support for absolute addresses on user specified variables, the
119// alignment check moves to the lowering pass and the frame calculation
120// needs to take the user variables into consideration.
121
122uint32_t ObjectStart = *MaybeAbs;
123
124if (ObjectStart !=alignTo(ObjectStart, Alignment)) {
125report_fatal_error("Absolute address LDS variable inconsistent with "
126"variable alignment");
127 }
128
129if (isModuleEntryFunction()) {
130// If this is a module entry function, we can also sanity check against
131// the static frame. Strictly it would be better to check against the
132// attribute, i.e. that the variable is within the always-allocated
133// section, and not within some other non-absolute-address object
134// allocated here, but the extra error detection is minimal and we would
135// have to pass the Function around or cache the attribute value.
136uint32_t ObjectEnd =
137 ObjectStart +DL.getTypeAllocSize(GV.getValueType());
138if (ObjectEnd >StaticLDSSize) {
139report_fatal_error(
140"Absolute address LDS variable outside of static frame");
141 }
142 }
143
144 Entry.first->second = ObjectStart;
145return ObjectStart;
146 }
147
148 /// TODO: We should sort these to minimize wasted space due to alignment
149 /// padding. Currently the padding is decided by the first encountered use
150 /// during lowering.
151Offset =StaticLDSSize =alignTo(StaticLDSSize, Alignment);
152
153StaticLDSSize +=DL.getTypeAllocSize(GV.getValueType());
154
155// Align LDS size to trailing, e.g. for aligning dynamic shared memory
156LDSSize =alignTo(StaticLDSSize, Trailing);
157 }else {
158assert(GV.getAddressSpace() ==AMDGPUAS::REGION_ADDRESS &&
159"expected region address space");
160
161Offset =StaticGDSSize =alignTo(StaticGDSSize, Alignment);
162StaticGDSSize +=DL.getTypeAllocSize(GV.getValueType());
163
164// FIXME: Apply alignment of dynamic GDS
165GDSSize =StaticGDSSize;
166 }
167
168 Entry.first->second =Offset;
169returnOffset;
170}
171
172std::optional<uint32_t>
173AMDGPUMachineFunction::getLDSKernelIdMetadata(constFunction &F) {
174// TODO: Would be more consistent with the abs symbols to use a range
175MDNode *MD =F.getMetadata("llvm.amdgcn.lds.kernel.id");
176if (MD && MD->getNumOperands() == 1) {
177if (ConstantInt *KnownSize =
178 mdconst::extract<ConstantInt>(MD->getOperand(0))) {
179uint64_t ZExt = KnownSize->getZExtValue();
180if (ZExt <= UINT32_MAX) {
181return ZExt;
182 }
183 }
184 }
185return {};
186}
187
188std::optional<uint32_t>
189AMDGPUMachineFunction::getLDSAbsoluteAddress(constGlobalValue &GV) {
190if (GV.getAddressSpace() !=AMDGPUAS::LOCAL_ADDRESS)
191return {};
192
193 std::optional<ConstantRange> AbsSymRange = GV.getAbsoluteSymbolRange();
194if (!AbsSymRange)
195return {};
196
197if (constAPInt *V = AbsSymRange->getSingleElement()) {
198 std::optional<uint64_t> ZExt = V->tryZExtValue();
199if (ZExt && (*ZExt <= UINT32_MAX)) {
200return *ZExt;
201 }
202 }
203
204return {};
205}
206
207voidAMDGPUMachineFunction::setDynLDSAlign(constFunction &F,
208constGlobalVariable &GV) {
209constModule *M =F.getParent();
210constDataLayout &DL = M->getDataLayout();
211assert(DL.getTypeAllocSize(GV.getValueType()).isZero());
212
213Align Alignment =
214DL.getValueOrABITypeAlignment(GV.getAlign(), GV.getValueType());
215if (Alignment <=DynLDSAlign)
216return;
217
218LDSSize =alignTo(StaticLDSSize, Alignment);
219DynLDSAlign = Alignment;
220
221// If there is a dynamic LDS variable associated with this function F, every
222// further dynamic LDS instance (allocated by calling setDynLDSAlign) must
223// map to the same address. This holds because no LDS is allocated after the
224// lowering pass if there are dynamic LDS variables present.
225constGlobalVariable *Dyn =getKernelDynLDSGlobalFromFunction(F);
226if (Dyn) {
227unsignedOffset =LDSSize;// return this?
228 std::optional<uint32_t> Expect =getLDSAbsoluteAddress(*Dyn);
229if (!Expect || (Offset != *Expect)) {
230report_fatal_error("Inconsistent metadata on dynamic LDS variable");
231 }
232 }
233}
234
235voidAMDGPUMachineFunction::setUsesDynamicLDS(bool DynLDS) {
236UsesDynamicLDS = DynLDS;
237}
238
239boolAMDGPUMachineFunction::isDynamicLDSUsed() const{returnUsesDynamicLDS; }
AMDGPUBaseInfo.h
hasLDSKernelArgument
static bool hasLDSKernelArgument(const Function &F)
Definition:AMDGPUMachineFunction.cpp:31
getKernelDynLDSGlobalFromFunction
static const GlobalVariable * getKernelDynLDSGlobalFromFunction(const Function &F)
Definition:AMDGPUMachineFunction.cpp:23
AMDGPUMachineFunction.h
AMDGPUMemoryUtils.h
AMDGPUSubtarget.h
Base class for AMDGPU specific classes of TargetSubtarget.
AMDGPU.h
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition:ARMSLSHardening.cpp:73
ConstantRange.h
Constants.h
This file contains the declarations for the subclasses of Constant, which represent the different fla...
F
#define F(x, y, z)
Definition:MD5.cpp:55
MachineModuleInfo.h
Metadata.h
This file contains the declarations for metadata subclasses.
CC
auto CC
Definition:RISCVRedundantCopyElimination.cpp:79
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::AMDGPUMachineFunction::AMDGPUMachineFunction
AMDGPUMachineFunction(const Function &F, const AMDGPUSubtarget &ST)
Definition:AMDGPUMachineFunction.cpp:42
llvm::AMDGPUMachineFunction::getLDSKernelIdMetadata
static std::optional< uint32_t > getLDSKernelIdMetadata(const Function &F)
Definition:AMDGPUMachineFunction.cpp:173
llvm::AMDGPUMachineFunction::DynLDSAlign
Align DynLDSAlign
Align for dynamic shared memory if any.
Definition:AMDGPUMachineFunction.h:47
llvm::AMDGPUMachineFunction::isDynamicLDSUsed
bool isDynamicLDSUsed() const
Definition:AMDGPUMachineFunction.cpp:239
llvm::AMDGPUMachineFunction::setUsesDynamicLDS
void setUsesDynamicLDS(bool DynLDS)
Definition:AMDGPUMachineFunction.cpp:235
llvm::AMDGPUMachineFunction::WaveLimiter
bool WaveLimiter
Definition:AMDGPUMachineFunction.h:68
llvm::AMDGPUMachineFunction::StaticGDSSize
uint32_t StaticGDSSize
Definition:AMDGPUMachineFunction.h:40
llvm::AMDGPUMachineFunction::LDSSize
uint32_t LDSSize
Number of bytes in the LDS that are being used.
Definition:AMDGPUMachineFunction.h:34
llvm::AMDGPUMachineFunction::setDynLDSAlign
void setDynLDSAlign(const Function &F, const GlobalVariable &GV)
Definition:AMDGPUMachineFunction.cpp:207
llvm::AMDGPUMachineFunction::MaxKernArgAlign
Align MaxKernArgAlign
Definition:AMDGPUMachineFunction.h:31
llvm::AMDGPUMachineFunction::getLDSAbsoluteAddress
static std::optional< uint32_t > getLDSAbsoluteAddress(const GlobalValue &GV)
Definition:AMDGPUMachineFunction.cpp:189
llvm::AMDGPUMachineFunction::GDSSize
uint32_t GDSSize
Definition:AMDGPUMachineFunction.h:35
llvm::AMDGPUMachineFunction::MemoryBound
bool MemoryBound
Definition:AMDGPUMachineFunction.h:65
llvm::AMDGPUMachineFunction::ExplicitKernArgSize
uint64_t ExplicitKernArgSize
Definition:AMDGPUMachineFunction.h:30
llvm::AMDGPUMachineFunction::allocateLDSGlobal
unsigned allocateLDSGlobal(const DataLayout &DL, const GlobalVariable &GV)
Definition:AMDGPUMachineFunction.h:117
llvm::AMDGPUMachineFunction::UsesDynamicLDS
bool UsesDynamicLDS
Definition:AMDGPUMachineFunction.h:50
llvm::AMDGPUMachineFunction::isModuleEntryFunction
bool isModuleEntryFunction() const
Definition:AMDGPUMachineFunction.h:93
llvm::AMDGPUMachineFunction::StaticLDSSize
uint32_t StaticLDSSize
Number of bytes in the LDS allocated statically.
Definition:AMDGPUMachineFunction.h:39
llvm::AMDGPUMachineFunction::NoSignedZerosFPMath
bool NoSignedZerosFPMath
Definition:AMDGPUMachineFunction.h:62
llvm::AMDGPUSubtarget
Definition:AMDGPUSubtarget.h:29
llvm::APInt
Class for arbitrary precision integers.
Definition:APInt.h:78
llvm::Argument
This class represents an incoming formal argument to a Function.
Definition:Argument.h:31
llvm::Attribute
Definition:Attributes.h:67
llvm::Attribute::isStringAttribute
bool isStringAttribute() const
Return true if the attribute is a string (target-dependent) attribute.
Definition:Attributes.cpp:348
llvm::Attribute::getValueAsBool
bool getValueAsBool() const
Return the attribute's value as a boolean.
Definition:Attributes.cpp:378
llvm::Attribute::getValueAsString
StringRef getValueAsString() const
Return the attribute's value as a string.
Definition:Attributes.cpp:392
llvm::ConstantInt
This is the shared class of boolean and integer constants.
Definition:Constants.h:83
llvm::DataLayout
A parsed version of the target data layout string in and methods for querying it.
Definition:DataLayout.h:63
llvm::Function
Definition:Function.h:63
llvm::GlobalObject::getAlign
MaybeAlign getAlign() const
Returns the alignment of the given variable or function.
Definition:GlobalObject.h:79
llvm::GlobalValue
Definition:GlobalValue.h:48
llvm::GlobalValue::getAddressSpace
unsigned getAddressSpace() const
Definition:GlobalValue.h:206
llvm::GlobalValue::getAbsoluteSymbolRange
std::optional< ConstantRange > getAbsoluteSymbolRange() const
If this is an absolute symbol reference, returns the range of the symbol, otherwise returns std::null...
Definition:Globals.cpp:413
llvm::GlobalValue::getValueType
Type * getValueType() const
Definition:GlobalValue.h:297
llvm::GlobalVariable
Definition:GlobalVariable.h:39
llvm::MDNode
Metadata node.
Definition:Metadata.h:1073
llvm::MDNode::getOperand
const MDOperand & getOperand(unsigned I) const
Definition:Metadata.h:1434
llvm::MDNode::getNumOperands
unsigned getNumOperands() const
Return number of MDNode operands.
Definition:Metadata.h:1440
llvm::Module
A Module instance is used to store all the information related to an LLVM module.
Definition:Module.h:65
llvm::SmallString
SmallString - A SmallString is just a SmallVector with methods and accessors that make it work better...
Definition:SmallString.h:26
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition:StringRef.h:51
llvm::StringRef::consumeInteger
bool consumeInteger(unsigned Radix, T &Result)
Parse the current string as an integer of the specified radix.
Definition:StringRef.h:499
llvm::StringRef::empty
constexpr bool empty() const
empty - Check if the string is empty.
Definition:StringRef.h:147
llvm::Type
The instances of the Type class are immutable: once they are created, they are never changed.
Definition:Type.h:45
uint32_t
uint64_t
unsigned
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition:ErrorHandling.h:143
TargetMachine.h
llvm::AMDGPUAS::REGION_ADDRESS
@ REGION_ADDRESS
Address space for region memory. (GDS)
Definition:AMDGPUAddrSpace.h:32
llvm::AMDGPUAS::LOCAL_ADDRESS
@ LOCAL_ADDRESS
Address space for local memory.
Definition:AMDGPUAddrSpace.h:35
llvm::AMDGPU::isNamedBarrier
TargetExtType * isNamedBarrier(const GlobalVariable &GV)
Definition:AMDGPUMemoryUtils.cpp:34
llvm::AMDGPU::getIntegerPairAttribute
std::pair< unsigned, unsigned > getIntegerPairAttribute(const Function &F, StringRef Name, std::pair< unsigned, unsigned > Default, bool OnlyFirstRequired)
Definition:AMDGPUBaseInfo.cpp:1332
llvm::CallingConv::AMDGPU_KERNEL
@ AMDGPU_KERNEL
Used for AMDGPU code object kernels.
Definition:CallingConv.h:200
llvm::CallingConv::SPIR_KERNEL
@ SPIR_KERNEL
Used for SPIR kernel functions.
Definition:CallingConv.h:144
llvm
This is an optimization pass for GlobalISel generic memory operations.
Definition:AddressRanges.h:18
llvm::Offset
@ Offset
Definition:DWP.cpp:480
llvm::report_fatal_error
void report_fatal_error(Error Err, bool gen_crash_diag=true)
Report a serious error, calling any installed error handler.
Definition:Error.cpp:167
llvm::alignTo
uint64_t alignTo(uint64_t Size, Align A)
Returns a multiple of A needed to store Size bytes.
Definition:Alignment.h:155
llvm::Align
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition:Alignment.h:39

Generated on Fri Jul 18 2025 13:10:41 for LLVM by doxygen 1.9.6
[8]ページ先頭

©2009-2025 Movatter.jp