yaxunl created this revision.
yaxunl added reviewers: rjmccall, tstellarAMD, arsenm.
yaxunl added a subscriber: cfe-commits.
Herald added a subscriber: wdng.
By default, if a variable is declared without address space qualifier, clang
will assume address space 0 in codegen. This is OK for most targets.
However since AMDGPU target has separate address spaces for different memory
regions, and address space 0 is used for private memory regions. It is desired
to use address space 4 (so called generic address space) as the default address
space. This is especially important for supporting address-space-agnostic
languages e.g. HCC (a variant of C++ which does not have explicit address space
https://github.com/RadeonOpenCompute/hcc).
This patch introduce a virtual function
TargetInfo::getDefaultTargetAddressSpace which allows each target to specify
the default target address space based on language options.
https://reviews.llvm.org/D27627
Files:
include/clang/AST/ASTContext.h
include/clang/Basic/TargetInfo.h
lib/AST/ASTContext.cpp
lib/Basic/Targets.cpp
test/CodeGen/default-addr-space.cpp
Index: test/CodeGen/default-addr-space.cpp
===================================================================
--- /dev/null
+++ test/CodeGen/default-addr-space.cpp
@@ -0,0 +1,14 @@
+// RUN: %clang_cc1 -O0 -std=c++11 -emit-llvm -o - -triple amdgcn-- %s | FileCheck %s
+
+// CHECK-LABEL: @_Z1fPi(i32 addrspace(4)* %a)
+// CHECK: %[[a_addr:.*]] = alloca i32 addrspace(4)*
+// CHECK: %b = alloca i32
+// CHECK: store i32 addrspace(4)* %a, i32 addrspace(4)** %[[a_addr]]
+// CHECK: store i32 1, i32* %b
+// CHECK: %[[r0:.*]] = load i32, i32* %b
+// CHECK: %[[r1:.*]] = load i32 addrspace(4)*, i32 addrspace(4)** %[[a_addr]]
+// CHECK: store i32 %[[r0]], i32 addrspace(4)* %[[r1]]
+void f(int* a) {
+ int b = 1;
+ *a = b;
+}
Index: lib/Basic/Targets.cpp
===================================================================
--- lib/Basic/Targets.cpp
+++ lib/Basic/Targets.cpp
@@ -1978,16 +1978,6 @@
}
};
-static const unsigned AMDGPUAddrSpaceMap[] = {
- 1, // opencl_global
- 3, // opencl_local
- 2, // opencl_constant
- 4, // opencl_generic
- 1, // cuda_device
- 2, // cuda_constant
- 3 // cuda_shared
-};
-
// If you edit the description strings, make sure you update
// getPointerWidthV().
@@ -2001,9 +1991,18 @@
"-v192:256-v256:256-v512:512-v1024:1024-v2048:2048-n32:64";
class AMDGPUTargetInfo final : public TargetInfo {
+ static const unsigned AddrSpaceMap_[7];
static const Builtin::Info BuiltinInfo[];
static const char * const GCCRegNames[];
+ enum AddrSpaceKind {
+ AS_Private = 0,
+ AS_Global = 1,
+ AS_Constant = 2,
+ AS_Local = 3,
+ AS_Generic = 4
+ };
+
/// \brief The GPU profiles supported by the AMDGPU target.
enum GPUKind {
GK_NONE,
@@ -2046,7 +2045,7 @@
resetDataLayout(getTriple().getArch() == llvm::Triple::amdgcn ?
DataLayoutStringSI : DataLayoutStringR600);
- AddrSpaceMap = &AMDGPUAddrSpaceMap;
+ AddrSpaceMap = &AddrSpaceMap_;
UseAddrSpaceMapMangling = true;
}
@@ -2232,6 +2231,14 @@
}
}
+ unsigned getDefaultTargetAddressSpace(LangOptions &Opts) const override {
+ // OpenCL sets address space explicitly in AST. The default case (type
+ // qualifier containing no address space) represents private address space.
+ if (Opts.OpenCL)
+ return AS_Private;
+ return AS_Generic;
+ }
+
LangAS::ID getOpenCLImageAddrSpace() const override {
return LangAS::opencl_constant;
}
@@ -2254,6 +2261,16 @@
}
};
+const unsigned AMDGPUTargetInfo::AddrSpaceMap_[] = {
+ AS_Global, // opencl_global
+ AS_Local, // opencl_local
+ AS_Constant, // opencl_constant
+ AS_Generic, // opencl_generic
+ AS_Global, // cuda_device
+ AS_Constant, // cuda_constant
+ AS_Local // cuda_shared
+};
+
const Builtin::Info AMDGPUTargetInfo::BuiltinInfo[] = {
#define BUILTIN(ID, TYPE, ATTRS) \
{ #ID, TYPE, ATTRS, nullptr, ALL_LANGUAGES, nullptr },
Index: lib/AST/ASTContext.cpp
===================================================================
--- lib/AST/ASTContext.cpp
+++ lib/AST/ASTContext.cpp
@@ -9436,6 +9436,12 @@
return getTargetInfo().getNullPointerValue(AS);
}
+unsigned ASTContext::getTargetAddressSpace(Qualifiers Q) const {
+ return Q.hasAddressSpace()
+ ? getTargetAddressSpace(Q.getAddressSpace())
+ : getTargetInfo().getDefaultTargetAddressSpace(LangOpts);
+}
+
// Explicitly instantiate this in case a Redeclarable<T> is used from a TU that
// doesn't include ASTContext.h
template
Index: include/clang/Basic/TargetInfo.h
===================================================================
--- include/clang/Basic/TargetInfo.h
+++ include/clang/Basic/TargetInfo.h
@@ -945,6 +945,10 @@
return *AddrSpaceMap;
}
+ virtual unsigned getDefaultTargetAddressSpace(LangOptions &Opt) const {
+ return 0;
+ }
+
/// \brief Retrieve the name of the platform as it is used in the
/// availability attribute.
StringRef getPlatformName() const { return PlatformName; }
Index: include/clang/AST/ASTContext.h
===================================================================
--- include/clang/AST/ASTContext.h
+++ include/clang/AST/ASTContext.h
@@ -2250,9 +2250,7 @@
return getTargetAddressSpace(T.getQualifiers());
}
- unsigned getTargetAddressSpace(Qualifiers Q) const {
- return getTargetAddressSpace(Q.getAddressSpace());
- }
+ unsigned getTargetAddressSpace(Qualifiers Q) const;
unsigned getTargetAddressSpace(unsigned AS) const {
if (AS < LangAS::Offset || AS >= LangAS::Offset + LangAS::Count)
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits