aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Target/AMDGPU/AMDGPUMachineFunction.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Target/AMDGPU/AMDGPUMachineFunction.cpp')
-rw-r--r--llvm/lib/Target/AMDGPU/AMDGPUMachineFunction.cpp40
1 files changed, 39 insertions, 1 deletions
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUMachineFunction.cpp b/llvm/lib/Target/AMDGPU/AMDGPUMachineFunction.cpp
index 6c6cc012..5a12782 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUMachineFunction.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUMachineFunction.cpp
@@ -99,6 +99,15 @@ static const GlobalVariable *getKernelLDSGlobalFromFunction(const Function &F) {
return M->getNamedGlobal(KernelLDSName);
}
+static const GlobalVariable *
+getKernelDynLDSGlobalFromFunction(const Function &F) {
+ const Module *M = F.getParent();
+ std::string KernelDynLDSName = "llvm.amdgcn.";
+ KernelDynLDSName += F.getName();
+ KernelDynLDSName += ".dynlds";
+ return M->getNamedGlobal(KernelDynLDSName);
+}
+
// This kernel calls no functions that require the module lds struct
static bool canElideModuleLDS(const Function &F) {
return F.hasFnAttribute("amdgpu-elide-module-lds");
@@ -131,6 +140,7 @@ void AMDGPUMachineFunction::allocateKnownAddressLDSGlobal(const Function &F) {
const GlobalVariable *GV = M->getNamedGlobal(ModuleLDSName);
const GlobalVariable *KV = getKernelLDSGlobalFromFunction(F);
+ const GlobalVariable *Dyn = getKernelDynLDSGlobalFromFunction(F);
if (GV && !canElideModuleLDS(F)) {
unsigned Offset = allocateLDSGlobal(M->getDataLayout(), *GV, Align());
@@ -149,6 +159,19 @@ void AMDGPUMachineFunction::allocateKnownAddressLDSGlobal(const Function &F) {
report_fatal_error("Inconsistent metadata on kernel LDS variable");
}
}
+
+ if (Dyn) {
+ // The dynamic LDS is deterministic because the per-kernel one has the
+ // maximum alignment of any reachable and all remaining LDS variables,
+ // if this is present, are themselves dynamic LDS and will be allocated
+ // at the same address.
+ setDynLDSAlign(F, *Dyn);
+ unsigned Offset = LDSSize;
+ std::optional<uint32_t> Expect = getLDSAbsoluteAddress(*Dyn);
+ if (!Expect || (Offset != *Expect)) {
+ report_fatal_error("Inconsistent metadata on dynamic LDS variable");
+ }
+ }
}
}
@@ -187,8 +210,10 @@ AMDGPUMachineFunction::getLDSAbsoluteAddress(const GlobalValue &GV) {
return {};
}
-void AMDGPUMachineFunction::setDynLDSAlign(const DataLayout &DL,
+void AMDGPUMachineFunction::setDynLDSAlign(const Function &F,
const GlobalVariable &GV) {
+ const Module *M = F.getParent();
+ const DataLayout &DL = M->getDataLayout();
assert(DL.getTypeAllocSize(GV.getValueType()).isZero());
Align Alignment =
@@ -198,4 +223,17 @@ void AMDGPUMachineFunction::setDynLDSAlign(const DataLayout &DL,
LDSSize = alignTo(StaticLDSSize, Alignment);
DynLDSAlign = Alignment;
+
+ // If there is a dynamic LDS variable associated with this function F, every
+ // further dynamic LDS instance (allocated by calling setDynLDSAlign) must
+ // map to the same address. This holds because no LDS is allocated after the
+ // lowering pass if there are dynamic LDS variables present.
+ const GlobalVariable *Dyn = getKernelDynLDSGlobalFromFunction(F);
+ if (Dyn) {
+ unsigned Offset = LDSSize; // return this?
+ std::optional<uint32_t> Expect = getLDSAbsoluteAddress(*Dyn);
+ if (!Expect || (Offset != *Expect)) {
+ report_fatal_error("Inconsistent metadata on dynamic LDS variable");
+ }
+ }
}