r303072 - [OpenCL] Emit function-scope variable in constant address space as static variable
Yaxun Liu via cfe-commits
cfe-commits at lists.llvm.org
Mon May 15 07:47:48 PDT 2017
Author: yaxunl
Date: Mon May 15 09:47:47 2017
New Revision: 303072
URL: http://llvm.org/viewvc/llvm-project?rev=303072&view=rev
Log:
[OpenCL] Emit function-scope variable in constant address space as static variable
Differential Revision: https://reviews.llvm.org/D32977
Modified:
cfe/trunk/include/clang/AST/Decl.h
cfe/trunk/lib/CodeGen/CGDecl.cpp
cfe/trunk/lib/Sema/SemaDecl.cpp
cfe/trunk/test/CodeGenOpenCL/amdgpu-debug-info-pointer-address-space.cl
cfe/trunk/test/CodeGenOpenCL/amdgpu-debug-info-variable-expression.cl
cfe/trunk/test/CodeGenOpenCL/constant-addr-space-globals.cl
cfe/trunk/test/SemaOpenCL/storageclass.cl
Modified: cfe/trunk/include/clang/AST/Decl.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Decl.h?rev=303072&r1=303071&r2=303072&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Decl.h (original)
+++ cfe/trunk/include/clang/AST/Decl.h Mon May 15 09:47:47 2017
@@ -966,9 +966,16 @@ public:
/// hasLocalStorage - Returns true if a variable with function scope
/// is a non-static local variable.
bool hasLocalStorage() const {
- if (getStorageClass() == SC_None)
+ if (getStorageClass() == SC_None) {
+ // OpenCL v1.2 s6.5.3: The __constant or constant address space name is
+ // used to describe variables allocated in global memory and which are
+ // accessed inside a kernel(s) as read-only variables. As such, variables
+ // in constant address space cannot have local storage.
+ if (getType().getAddressSpace() == LangAS::opencl_constant)
+ return false;
// Second check is for C++11 [dcl.stc]p4.
return !isFileVarDecl() && getTSCSpec() == TSCS_unspecified;
+ }
// Global Named Register (GNU extension)
if (getStorageClass() == SC_Register && !isLocalVarDeclOrParm())
Modified: cfe/trunk/lib/CodeGen/CGDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGDecl.cpp?rev=303072&r1=303071&r2=303072&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGDecl.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGDecl.cpp Mon May 15 09:47:47 2017
@@ -152,7 +152,14 @@ void CodeGenFunction::EmitDecl(const Dec
/// EmitVarDecl - This method handles emission of any variable declaration
/// inside a function, including static vars etc.
void CodeGenFunction::EmitVarDecl(const VarDecl &D) {
- if (D.isStaticLocal()) {
+ if (D.hasExternalStorage())
+ // Don't emit it now, allow it to be emitted lazily on its first use.
+ return;
+
+ // Some function-scope variable does not have static storage but still
+ // needs to be emitted like a static variable, e.g. a function-scope
+ // variable in constant address space in OpenCL.
+ if (D.getStorageDuration() != SD_Automatic) {
llvm::GlobalValue::LinkageTypes Linkage =
CGM.getLLVMLinkageVarDefinition(&D, /*isConstant=*/false);
@@ -163,10 +170,6 @@ void CodeGenFunction::EmitVarDecl(const
return EmitStaticVarDecl(D, Linkage);
}
- if (D.hasExternalStorage())
- // Don't emit it now, allow it to be emitted lazily on its first use.
- return;
-
if (D.getType().getAddressSpace() == LangAS::opencl_local)
return CGM.getOpenCLRuntime().EmitWorkGroupLocalVarDecl(*this, D);
Modified: cfe/trunk/lib/Sema/SemaDecl.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaDecl.cpp?rev=303072&r1=303071&r2=303072&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaDecl.cpp (original)
+++ cfe/trunk/lib/Sema/SemaDecl.cpp Mon May 15 09:47:47 2017
@@ -10394,23 +10394,36 @@ void Sema::AddInitializerToDecl(Decl *Re
VDecl->setInit(Init);
if (VDecl->isLocalVarDecl()) {
+ // Don't check the initializer if the declaration is malformed.
+ if (VDecl->isInvalidDecl()) {
+ // do nothing
+
+ // OpenCL v1.2 s6.5.3: __constant locals must be constant-initialized.
+ // This is true even in OpenCL C++.
+ } else if (VDecl->getType().getAddressSpace() == LangAS::opencl_constant) {
+ CheckForConstantInitializer(Init, DclT);
+
+ // Otherwise, C++ does not restrict the initializer.
+ } else if (getLangOpts().CPlusPlus) {
+ // do nothing
+
// C99 6.7.8p4: All the expressions in an initializer for an object that has
// static storage duration shall be constant expressions or string literals.
- // C++ does not have this restriction.
- if (!getLangOpts().CPlusPlus && !VDecl->isInvalidDecl()) {
+ } else if (VDecl->getStorageClass() == SC_Static) {
+ CheckForConstantInitializer(Init, DclT);
+
+ // C89 is stricter than C99 for aggregate initializers.
+ // C89 6.5.7p3: All the expressions [...] in an initializer list
+ // for an object that has aggregate or union type shall be
+ // constant expressions.
+ } else if (!getLangOpts().C99 && VDecl->getType()->isAggregateType() &&
+ isa<InitListExpr>(Init)) {
const Expr *Culprit;
- if (VDecl->getStorageClass() == SC_Static)
- CheckForConstantInitializer(Init, DclT);
- // C89 is stricter than C99 for non-static aggregate types.
- // C89 6.5.7p3: All the expressions [...] in an initializer list
- // for an object that has aggregate or union type shall be
- // constant expressions.
- else if (!getLangOpts().C99 && VDecl->getType()->isAggregateType() &&
- isa<InitListExpr>(Init) &&
- !Init->isConstantInitializer(Context, false, &Culprit))
+ if (!Init->isConstantInitializer(Context, false, &Culprit)) {
Diag(Culprit->getExprLoc(),
diag::ext_aggregate_init_not_constant)
<< Culprit->getSourceRange();
+ }
}
} else if (VDecl->isStaticDataMember() && !VDecl->isInline() &&
VDecl->getLexicalDeclContext()->isRecord()) {
Modified: cfe/trunk/test/CodeGenOpenCL/amdgpu-debug-info-pointer-address-space.cl
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenOpenCL/amdgpu-debug-info-pointer-address-space.cl?rev=303072&r1=303071&r2=303072&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenOpenCL/amdgpu-debug-info-pointer-address-space.cl (original)
+++ cfe/trunk/test/CodeGenOpenCL/amdgpu-debug-info-pointer-address-space.cl Mon May 15 09:47:47 2017
@@ -58,16 +58,16 @@ kernel void kernel1(
// CHECK-DAG: !DILocalVariable(name: "FuncVar4", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]])
int *FuncVar4 = Tmp1;
- // CHECK-DAG: !DILocalVariable(name: "FuncVar5", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]])
- global int *constant FuncVar5 = KernelArg0;
- // CHECK-DAG: !DILocalVariable(name: "FuncVar6", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]])
- constant int *constant FuncVar6 = KernelArg1;
- // CHECK-DAG: !DILocalVariable(name: "FuncVar7", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_LOCAL]])
- local int *constant FuncVar7 = KernelArg2;
- // CHECK-DAG: !DILocalVariable(name: "FuncVar8", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_PRIVATE]])
- private int *constant FuncVar8 = Tmp0;
- // CHECK-DAG: !DILocalVariable(name: "FuncVar9", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]])
- int *constant FuncVar9 = Tmp1;
+ // CHECK-DAG: distinct !DIGlobalVariable(name: "FuncVar5", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: true, isDefinition: true)
+ global int *constant FuncVar5 = 0;
+ // CHECK-DAG: distinct !DIGlobalVariable(name: "FuncVar6", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: true, isDefinition: true)
+ constant int *constant FuncVar6 = 0;
+ // CHECK-DAG: distinct !DIGlobalVariable(name: "FuncVar7", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_LOCAL]], isLocal: true, isDefinition: true)
+ local int *constant FuncVar7 = 0;
+ // CHECK-DAG: distinct !DIGlobalVariable(name: "FuncVar8", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_PRIVATE]], isLocal: true, isDefinition: true)
+ private int *constant FuncVar8 = 0;
+ // CHECK-DAG: distinct !DIGlobalVariable(name: "FuncVar9", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: true, isDefinition: true)
+ int *constant FuncVar9 = 0;
// CHECK-DAG: distinct !DIGlobalVariable(name: "FuncVar10", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: true, isDefinition: true)
global int *local FuncVar10; FuncVar10 = KernelArg0;
Modified: cfe/trunk/test/CodeGenOpenCL/amdgpu-debug-info-variable-expression.cl
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenOpenCL/amdgpu-debug-info-variable-expression.cl?rev=303072&r1=303071&r2=303072&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenOpenCL/amdgpu-debug-info-variable-expression.cl (original)
+++ cfe/trunk/test/CodeGenOpenCL/amdgpu-debug-info-variable-expression.cl Mon May 15 09:47:47 2017
@@ -80,21 +80,21 @@ kernel void kernel1(
// CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(4)** {{.*}}, metadata ![[FUNCVAR4]], metadata ![[PRIVATE]]), !dbg !{{[0-9]+}}
int *FuncVar4 = Tmp1;
- // CHECK-DAG: ![[FUNCVAR5:[0-9]+]] = !DILocalVariable(name: "FuncVar5", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
- // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(1)** {{.*}}, metadata ![[FUNCVAR5]], metadata ![[NONE:[0-9]+]]), !dbg !{{[0-9]+}}
- global int *constant FuncVar5 = KernelArg0;
- // CHECK-DAG: ![[FUNCVAR6:[0-9]+]] = !DILocalVariable(name: "FuncVar6", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
- // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(2)** {{.*}}, metadata ![[FUNCVAR6]], metadata ![[NONE]]), !dbg !{{[0-9]+}}
- constant int *constant FuncVar6 = KernelArg1;
- // CHECK-DAG: ![[FUNCVAR7:[0-9]+]] = !DILocalVariable(name: "FuncVar7", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
- // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(3)** {{.*}}, metadata ![[FUNCVAR7]], metadata ![[NONE]]), !dbg !{{[0-9]+}}
- local int *constant FuncVar7 = KernelArg2;
- // CHECK-DAG: ![[FUNCVAR8:[0-9]+]] = !DILocalVariable(name: "FuncVar8", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
- // CHECK-DAG: call void @llvm.dbg.declare(metadata i32** {{.*}}, metadata ![[FUNCVAR8]], metadata ![[NONE]]), !dbg !{{[0-9]+}}
- private int *constant FuncVar8 = Tmp0;
- // CHECK-DAG: ![[FUNCVAR9:[0-9]+]] = !DILocalVariable(name: "FuncVar9", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
- // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(4)** {{.*}}, metadata ![[FUNCVAR9]], metadata ![[NONE]]), !dbg !{{[0-9]+}}
- int *constant FuncVar9 = Tmp1;
+ // CHECK-DAG: ![[FUNCVAR5:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar5", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
+ // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR5]])
+ global int *constant FuncVar5 = 0;
+ // CHECK-DAG: ![[FUNCVAR6:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar6", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
+ // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR6]])
+ constant int *constant FuncVar6 = 0;
+ // CHECK-DAG: ![[FUNCVAR7:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar7", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
+ // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR7]])
+ local int *constant FuncVar7 = 0;
+ // CHECK-DAG: ![[FUNCVAR8:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar8", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
+ // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR8]])
+ private int *constant FuncVar8 = 0;
+ // CHECK-DAG: ![[FUNCVAR9:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar9", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
+ // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR9]])
+ int *constant FuncVar9 = 0;
// CHECK-DAG: ![[FUNCVAR10:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar10", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR10]], expr: ![[LOCAL]])
Modified: cfe/trunk/test/CodeGenOpenCL/constant-addr-space-globals.cl
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenOpenCL/constant-addr-space-globals.cl?rev=303072&r1=303071&r2=303072&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenOpenCL/constant-addr-space-globals.cl (original)
+++ cfe/trunk/test/CodeGenOpenCL/constant-addr-space-globals.cl Mon May 15 09:47:47 2017
@@ -11,10 +11,11 @@ kernel void test(global float *out) {
// but create a copy in the original address space (unless a variable itself is
// in the constant address space).
-void foo(constant const int *p1, const int *p2, const int *p3);
+void foo(constant int* p, constant const int *p1, const int *p2, const int *p3);
// CHECK: @k.arr1 = internal addrspace(2) constant [3 x i32] [i32 1, i32 2, i32 3]
// CHECK: @k.arr2 = private unnamed_addr addrspace(2) constant [3 x i32] [i32 4, i32 5, i32 6]
// CHECK: @k.arr3 = private unnamed_addr addrspace(2) constant [3 x i32] [i32 7, i32 8, i32 9]
+// CHECK: @k.var1 = internal addrspace(2) constant i32 1
kernel void k(void) {
// CHECK-NOT: %arr1 = alloca [3 x i32]
constant const int arr1[] = {1, 2, 3};
@@ -23,5 +24,8 @@ kernel void k(void) {
// CHECK: %arr3 = alloca [3 x i32]
int arr3[] = {7, 8, 9};
- foo(arr1, arr2, arr3);
+ constant int var1 = 1;
+
+ // CHECK: call spir_func void @foo(i32 addrspace(2)* @k.var1, i32 addrspace(2)* getelementptr inbounds ([3 x i32], [3 x i32] addrspace(2)* @k.arr1, i32 0, i32 0)
+ foo(&var1, arr1, arr2, arr3);
}
Modified: cfe/trunk/test/SemaOpenCL/storageclass.cl
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaOpenCL/storageclass.cl?rev=303072&r1=303071&r2=303072&view=diff
==============================================================================
--- cfe/trunk/test/SemaOpenCL/storageclass.cl (original)
+++ cfe/trunk/test/SemaOpenCL/storageclass.cl Mon May 15 09:47:47 2017
@@ -5,7 +5,7 @@ constant int G2 = 0;
int G3 = 0; // expected-error{{program scope variable must reside in constant address space}}
global int G4 = 0; // expected-error{{program scope variable must reside in constant address space}}
-void kernel foo() {
+void kernel foo(int x) {
// static is not allowed at local scope before CL2.0
static int S1 = 5; // expected-error{{variables in function scope cannot be declared static}}
static constant int S2 = 5; // expected-error{{variables in function scope cannot be declared static}}
@@ -15,6 +15,12 @@ void kernel foo() {
auto int L3 = 7; // expected-error{{OpenCL version 1.2 does not support the 'auto' storage class specifier}}
global int L4; // expected-error{{function scope variable cannot be declared in global address space}}
+
+ constant int L5 = x; // expected-error {{initializer element is not a compile-time constant}}
+ global int *constant L6 = &G4;
+ private int *constant L7 = &x; // expected-error {{initializer element is not a compile-time constant}}
+ constant int *constant L8 = &L1;
+ local int *constant L9 = &L2; // expected-error {{initializer element is not a compile-time constant}}
}
static void kernel bar() { // expected-error{{kernel functions cannot be declared static}}
@@ -29,4 +35,7 @@ void f() {
}
global int L3; // expected-error{{function scope variable cannot be declared in global address space}}
extern constant float L4;
+ extern local float L5; // expected-error{{extern variable must reside in constant address space}}
+ static int L6 = 0; // expected-error{{variables in function scope cannot be declared static}}
+ static int L7; // expected-error{{variables in function scope cannot be declared static}}
}
More information about the cfe-commits
mailing list