summaryrefslogtreecommitdiffstats
path: root/clang/lib
diff options
context:
space:
mode:
authorPeter Collingbourne <peter@pcc.me.uk>2012-05-20 21:08:35 +0000
committerPeter Collingbourne <peter@pcc.me.uk>2012-05-20 21:08:35 +0000
commitf44bdf9c5fc347f1639d50c49de2b836f28017e2 (patch)
treea21092fbd172f3ac505a42a8bc578d9daeee9b77 /clang/lib
parent853a8a982bb9b3220e3625b725b15faa8ba91d99 (diff)
downloadbcm5719-llvm-f44bdf9c5fc347f1639d50c49de2b836f28017e2.tar.gz
bcm5719-llvm-f44bdf9c5fc347f1639d50c49de2b836f28017e2.zip
CUDA: add CodeGen support for global variable address spaces.
Because in CUDA types do not have associated address spaces, globals are declared in their "native" address space, and accessed by bitcasting the pointer to address space 0. This relies on address space 0 being a unified address space. llvm-svn: 157167
Diffstat (limited to 'clang/lib')
-rw-r--r--clang/lib/AST/ASTContext.cpp5
-rw-r--r--clang/lib/Basic/Targets.cpp10
-rw-r--r--clang/lib/CodeGen/CodeGenModule.cpp24
-rw-r--r--clang/lib/CodeGen/CodeGenModule.h6
4 files changed, 39 insertions, 6 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index a5028338cb6..27057883e5f 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -206,7 +206,10 @@ static const LangAS::Map *getAddressSpaceMap(const TargetInfo &T,
static const unsigned FakeAddrSpaceMap[] = {
1, // opencl_global
2, // opencl_local
- 3 // opencl_constant
+ 3, // opencl_constant
+ 4, // cuda_device
+ 5, // cuda_constant
+ 6 // cuda_shared
};
return &FakeAddrSpaceMap;
} else {
diff --git a/clang/lib/Basic/Targets.cpp b/clang/lib/Basic/Targets.cpp
index 045229e9fba..8e7cdf934d3 100644
--- a/clang/lib/Basic/Targets.cpp
+++ b/clang/lib/Basic/Targets.cpp
@@ -949,7 +949,10 @@ namespace {
static const unsigned PTXAddrSpaceMap[] = {
0, // opencl_global
4, // opencl_local
- 1 // opencl_constant
+ 1, // opencl_constant
+ 0, // cuda_device
+ 1, // cuda_constant
+ 4, // cuda_shared
};
class PTXTargetInfo : public TargetInfo {
static const char * const GCCRegNames[];
@@ -3384,7 +3387,10 @@ namespace {
static const unsigned TCEOpenCLAddrSpaceMap[] = {
3, // opencl_global
4, // opencl_local
- 5 // opencl_constant
+ 5, // opencl_constant
+ 0, // cuda_device
+ 0, // cuda_constant
+ 0 // cuda_shared
};
class TCETargetInfo : public TargetInfo{
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index f2dda5d658f..0da493ffb55 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -1172,11 +1172,12 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName,
DeferredDecls.erase(DDI);
}
+ unsigned AddrSpace = GetGlobalVarAddressSpace(D, Ty->getAddressSpace());
llvm::GlobalVariable *GV =
new llvm::GlobalVariable(getModule(), Ty->getElementType(), false,
llvm::GlobalValue::ExternalLinkage,
0, MangledName, 0,
- false, Ty->getAddressSpace());
+ false, AddrSpace);
// Handle things which are present even on external declarations.
if (D) {
@@ -1202,7 +1203,10 @@ CodeGenModule::GetOrCreateLLVMGlobal(StringRef MangledName,
GV->setThreadLocal(D->isThreadSpecified());
}
- return GV;
+ if (AddrSpace != Ty->getAddressSpace())
+ return llvm::ConstantExpr::getBitCast(GV, Ty);
+ else
+ return GV;
}
@@ -1487,6 +1491,20 @@ CodeGenModule::MaybeEmitGlobalStdInitializerListInitializer(const VarDecl *D,
return llvmInit;
}
+unsigned CodeGenModule::GetGlobalVarAddressSpace(const VarDecl *D,
+ unsigned AddrSpace) {
+ if (LangOpts.CUDA && CodeGenOpts.CUDAIsDevice) {
+ if (D->hasAttr<CUDAConstantAttr>())
+ AddrSpace = getContext().getTargetAddressSpace(LangAS::cuda_constant);
+ else if (D->hasAttr<CUDASharedAttr>())
+ AddrSpace = getContext().getTargetAddressSpace(LangAS::cuda_shared);
+ else
+ AddrSpace = getContext().getTargetAddressSpace(LangAS::cuda_device);
+ }
+
+ return AddrSpace;
+}
+
void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
llvm::Constant *Init = 0;
QualType ASTTy = D->getType();
@@ -1566,7 +1584,7 @@ void CodeGenModule::EmitGlobalVarDefinition(const VarDecl *D) {
if (GV == 0 ||
GV->getType()->getElementType() != InitType ||
GV->getType()->getAddressSpace() !=
- getContext().getTargetAddressSpace(ASTTy)) {
+ GetGlobalVarAddressSpace(D, getContext().getTargetAddressSpace(ASTTy))) {
// Move the old entry aside so that we'll create a new one.
Entry->setName(StringRef());
diff --git a/clang/lib/CodeGen/CodeGenModule.h b/clang/lib/CodeGen/CodeGenModule.h
index bde03a7cedf..8f3bd78ac42 100644
--- a/clang/lib/CodeGen/CodeGenModule.h
+++ b/clang/lib/CodeGen/CodeGenModule.h
@@ -517,6 +517,12 @@ public:
CreateOrReplaceCXXRuntimeVariable(StringRef Name, llvm::Type *Ty,
llvm::GlobalValue::LinkageTypes Linkage);
+ /// GetGlobalVarAddressSpace - Return the address space of the underlying
+ /// global variable for D, as determined by its declaration. Normally this
+ /// is the same as the address space of D's type, but in CUDA, address spaces
+ /// are associated with declarations, not types.
+ unsigned GetGlobalVarAddressSpace(const VarDecl *D, unsigned AddrSpace);
+
/// GetAddrOfGlobalVar - Return the llvm::Constant for the address of the
/// given global variable. If Ty is non-null and if the global doesn't exist,
/// then it will be greated with the specified type instead of whatever the
OpenPOWER on IntegriCloud