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
cfe-commits@lists.llvm.org
http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to