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.cpp57
1 files changed, 55 insertions, 2 deletions
diff --git a/llvm/lib/Target/AMDGPU/AMDGPUMachineFunction.cpp b/llvm/lib/Target/AMDGPU/AMDGPUMachineFunction.cpp
index 488b3be..d8133a9 100644
--- a/llvm/lib/Target/AMDGPU/AMDGPUMachineFunction.cpp
+++ b/llvm/lib/Target/AMDGPU/AMDGPUMachineFunction.cpp
@@ -84,6 +84,24 @@ unsigned AMDGPUMachineFunction::allocateLDSGlobal(const DataLayout &DL,
return Offset;
}
+static constexpr StringLiteral ModuleLDSName = "llvm.amdgcn.module.lds";
+
+bool AMDGPUMachineFunction::isKnownAddressLDSGlobal(const GlobalVariable &GV) {
+ auto name = GV.getName();
+ return (name == ModuleLDSName) ||
+ (name.startswith("llvm.amdgcn.kernel.") && name.endswith(".lds"));
+}
+
+const Function *AMDGPUMachineFunction::getKernelLDSFunctionFromGlobal(
+ const GlobalVariable &GV) {
+ const Module &M = *GV.getParent();
+ StringRef N(GV.getName());
+ if (N.consume_front("llvm.amdgcn.kernel.") && N.consume_back(".lds")) {
+ return M.getFunction(N);
+ }
+ return nullptr;
+}
+
const GlobalVariable *
AMDGPUMachineFunction::getKernelLDSGlobalFromFunction(const Function &F) {
const Module *M = F.getParent();
@@ -98,6 +116,37 @@ static bool canElideModuleLDS(const Function &F) {
return F.hasFnAttribute("amdgpu-elide-module-lds");
}
+unsigned AMDGPUMachineFunction::calculateKnownAddressOfLDSGlobal(
+ const GlobalVariable &GV) {
+ // module.lds, then alignment padding, then kernel.lds, then other variables
+ // if any
+
+ assert(isKnownAddressLDSGlobal(GV));
+ unsigned Offset = 0;
+
+ if (GV.getName() == ModuleLDSName) {
+ return 0;
+ }
+
+ const Module *M = GV.getParent();
+ const DataLayout &DL = M->getDataLayout();
+
+ const GlobalVariable *GVM = M->getNamedGlobal(ModuleLDSName);
+ const Function *f = getKernelLDSFunctionFromGlobal(GV);
+
+ // Account for module.lds if allocated for this function
+ if (GVM && f && !canElideModuleLDS(*f)) {
+ // allocator aligns this to var align, but it's zero to begin with
+ Offset += DL.getTypeAllocSize(GVM->getValueType());
+ }
+
+ // No dynamic LDS alignment done by allocateModuleLDSGlobal
+ Offset = alignTo(
+ Offset, DL.getValueOrABITypeAlignment(GV.getAlign(), GV.getValueType()));
+
+ return Offset;
+}
+
void AMDGPUMachineFunction::allocateKnownAddressLDSGlobal(const Function &F) {
const Module *M = F.getParent();
@@ -124,21 +173,25 @@ void AMDGPUMachineFunction::allocateKnownAddressLDSGlobal(const Function &F) {
// }
// other variables, e.g. dynamic lds, allocated after this call
- const GlobalVariable *GV = M->getNamedGlobal("llvm.amdgcn.module.lds");
+ const GlobalVariable *GV = M->getNamedGlobal(ModuleLDSName);
const GlobalVariable *KV = getKernelLDSGlobalFromFunction(F);
if (GV && !canElideModuleLDS(F)) {
+ assert(isKnownAddressLDSGlobal(*GV));
unsigned Offset = allocateLDSGlobal(M->getDataLayout(), *GV, Align());
(void)Offset;
- assert(Offset == 0 &&
+ assert(Offset == calculateKnownAddressOfLDSGlobal(*GV) &&
"Module LDS expected to be allocated before other LDS");
}
if (KV) {
// The per-kernel offset is deterministic because it is allocated
// before any other non-module LDS variables.
+ assert(isKnownAddressLDSGlobal(*KV));
unsigned Offset = allocateLDSGlobal(M->getDataLayout(), *KV, Align());
(void)Offset;
+ assert(Offset == calculateKnownAddressOfLDSGlobal(*KV) &&
+ "Kernel LDS expected to be immediately after module LDS");
}
}
}