summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen/CodeGenModule.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'clang/lib/CodeGen/CodeGenModule.cpp')
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp66
1 files changed, 44 insertions, 22 deletions
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 10838b751c8..e1866ea138f 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/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
OpenPOWER on IntegriCloud