summaryrefslogtreecommitdiffstats
path: root/lib/CodeGen/CodeGenModule.cpp
diff options
context:
space:
mode:
authorYaxun Liu <Yaxun.Liu@amd.com>2017-07-08 13:24:52 +0000
committerYaxun Liu <Yaxun.Liu@amd.com>2017-07-08 13:24:52 +0000
commit2ce35b601db031549e4a2113fc40deafe24751fe (patch)
treed2e6acd66f794051e0eaeafe0e24dcf13ea2f9a8 /lib/CodeGen/CodeGenModule.cpp
parente1e45e872fe06f853a7d717c7fe92eee9d0c856c (diff)
CodeGen: Fix address space of global variable
Certain targets (e.g. amdgcn) require global variable to stay in global or constant address space. In C or C++ global variables are emitted in the default (generic) address space. This patch introduces virtual functions TargetCodeGenInfo::getGlobalVarAddressSpace and TargetInfo::getConstantAddressSpace to handle this in a general approach. It only affects IR generated for amdgcn target. Differential Revision: https://reviews.llvm.org/D33842 git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@307470 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/CodeGen/CodeGenModule.cpp')
-rw-r--r--lib/CodeGen/CodeGenModule.cpp66
1 files changed, 44 insertions, 22 deletions
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index 10838b751c..e1866ea138 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -2367,11 +2367,13 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName,
return llvm::ConstantExpr::getBitCast(Entry, Ty);
}
- unsigned AddrSpace = GetGlobalVarAddressSpace(D, Ty->getAddressSpace());
+ auto AddrSpace = GetGlobalVarAddressSpace(D);
+ auto TargetAddrSpace = getContext().getTargetAddressSpace(AddrSpace);
+
auto *GV = new llvm::GlobalVariable(
getModule(), Ty->getElementType(), false,
llvm::GlobalValue::ExternalLinkage, nullptr, MangledName, nullptr,
- llvm::GlobalVariable::NotThreadLocal, AddrSpace);
+ llvm::GlobalVariable::NotThreadLocal, TargetAddrSpace);
// If we already created a global with the same mangled name (but different
// type) before, take its name and remove it from its parent.
@@ -2428,8 +2430,14 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName,
GV->setSection(".cp.rodata");
}
- if (AddrSpace != Ty->getAddressSpace())
- return llvm::ConstantExpr::getAddrSpaceCast(GV, Ty);
+ auto ExpectedAS =
+ D ? D->getType().getAddressSpace()
+ : (LangOpts.OpenCL ? LangAS::opencl_global : LangAS::Default);
+ auto ExpectedTargetAS = getContext().getTargetAddressSpace(ExpectedAS);
+ assert(ExpectedTargetAS == Ty->getPointerAddressSpace());
+ if (AddrSpace != ExpectedAS)
+ return getTargetCodeGenInfo().performAddrSpaceCast(*this, GV, AddrSpace,
+ ExpectedAS, Ty);
return GV;
}
@@ -2563,18 +2571,27 @@ CharUnits CodeGenModule::GetTargetTypeStoreSize(llvm::Type *Ty) const {
getDataLayout().getTypeStoreSizeInBits(Ty));
}
-unsigned CodeGenModule::GetGlobalVarAddressSpace(const VarDecl *D,
- unsigned AddrSpace) {
- if (D && LangOpts.CUDA && LangOpts.CUDAIsDevice) {
- if (D->hasAttr<CUDAConstantAttr>())
- AddrSpace = getContext().getTargetAddressSpace(LangAS::cuda_constant);
- else if (D->hasAttr<CUDASharedAttr>())
- AddrSpace = getContext().getTargetAddressSpace(LangAS::cuda_shared);
+unsigned CodeGenModule::GetGlobalVarAddressSpace(const VarDecl *D) {
+ unsigned AddrSpace;
+ if (LangOpts.OpenCL) {
+ AddrSpace = D ? D->getType().getAddressSpace() : LangAS::opencl_global;
+ assert(AddrSpace == LangAS::opencl_global ||
+ AddrSpace == LangAS::opencl_constant ||
+ AddrSpace == LangAS::opencl_local ||
+ AddrSpace >= LangAS::FirstTargetAddressSpace);
+ return AddrSpace;
+ }
+
+ if (LangOpts.CUDA && LangOpts.CUDAIsDevice) {
+ if (D && D->hasAttr<CUDAConstantAttr>())
+ return LangAS::cuda_constant;
+ else if (D && D->hasAttr<CUDASharedAttr>())
+ return LangAS::cuda_shared;
else
- AddrSpace = getContext().getTargetAddressSpace(LangAS::cuda_device);
+ return LangAS::cuda_device;
}
- return AddrSpace;
+ return getTargetCodeGenInfo().getGlobalVarAddressSpace(*this, D);
}
template<typename SomeDecl>
@@ -2727,10 +2744,9 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D,
// "extern int x[];") and then a definition of a different type (e.g.
// "int x[10];"). This also happens when an initializer has a different type
// from the type of the global (this happens with unions).
- if (!GV ||
- GV->getType()->getElementType() != InitType ||
+ if (!GV || GV->getType()->getElementType() != InitType ||
GV->getType()->getAddressSpace() !=
- GetGlobalVarAddressSpace(D, getContext().getTargetAddressSpace(ASTTy))) {
+ getContext().getTargetAddressSpace(GetGlobalVarAddressSpace(D))) {
// Move the old entry aside so that we'll create a new one.
Entry->setName(StringRef());
@@ -3739,20 +3755,26 @@ ConstantAddress CodeGenModule::GetAddrOfGlobalTemporary(
Linkage = llvm::GlobalVariable::InternalLinkage;
}
}
- unsigned AddrSpace = GetGlobalVarAddressSpace(
- VD, getContext().getTargetAddressSpace(MaterializedType));
+ unsigned AddrSpace =
+ VD ? GetGlobalVarAddressSpace(VD) : MaterializedType.getAddressSpace();
+ auto TargetAS = getContext().getTargetAddressSpace(AddrSpace);
auto *GV = new llvm::GlobalVariable(
getModule(), Type, Constant, Linkage, InitialValue, Name.c_str(),
- /*InsertBefore=*/nullptr, llvm::GlobalVariable::NotThreadLocal,
- AddrSpace);
+ /*InsertBefore=*/nullptr, llvm::GlobalVariable::NotThreadLocal, TargetAS);
setGlobalVisibility(GV, VD);
GV->setAlignment(Align.getQuantity());
if (supportsCOMDAT() && GV->isWeakForLinker())
GV->setComdat(TheModule.getOrInsertComdat(GV->getName()));
if (VD->getTLSKind())
setTLSMode(GV, *VD);
- MaterializedGlobalTemporaryMap[E] = GV;
- return ConstantAddress(GV, Align);
+ llvm::Constant *CV = GV;
+ if (AddrSpace != LangAS::Default)
+ CV = getTargetCodeGenInfo().performAddrSpaceCast(
+ *this, GV, AddrSpace, LangAS::Default,
+ Type->getPointerTo(
+ getContext().getTargetAddressSpace(LangAS::Default)));
+ MaterializedGlobalTemporaryMap[E] = CV;
+ return ConstantAddress(CV, Align);
}
/// EmitObjCPropertyImplementations - Emit information for synthesized