forked from OSchip/llvm-project
[OpenCL 2.0] Apply default address space (AS).
If AS of a variable/parameter declaration is not set by the source, OpenCL v2.0 s6.5 defines explicit rules for default ASes: - The AS of global and local static variables defaults to global; - All pointers point to generic AS. http://reviews.llvm.org/D13168 llvm-svn: 253863
This commit is contained in:
parent
5ef2bc316d
commit
784fb78274
|
@ -1564,8 +1564,7 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
|
||||||
// Apply any type attributes from the decl spec. This may cause the
|
// Apply any type attributes from the decl spec. This may cause the
|
||||||
// list of type attributes to be temporarily saved while the type
|
// list of type attributes to be temporarily saved while the type
|
||||||
// attributes are pushed around.
|
// attributes are pushed around.
|
||||||
if (AttributeList *attrs = DS.getAttributes().getList())
|
processTypeAttrs(state, Result, TAL_DeclSpec, DS.getAttributes().getList());
|
||||||
processTypeAttrs(state, Result, TAL_DeclSpec, attrs);
|
|
||||||
|
|
||||||
// Apply const/volatile/restrict qualifiers to T.
|
// Apply const/volatile/restrict qualifiers to T.
|
||||||
if (unsigned TypeQuals = DS.getTypeQualifiers()) {
|
if (unsigned TypeQuals = DS.getTypeQualifiers()) {
|
||||||
|
@ -2596,8 +2595,8 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
|
||||||
// Constructors and destructors don't have return types. Use
|
// Constructors and destructors don't have return types. Use
|
||||||
// "void" instead.
|
// "void" instead.
|
||||||
T = SemaRef.Context.VoidTy;
|
T = SemaRef.Context.VoidTy;
|
||||||
if (AttributeList *attrs = D.getDeclSpec().getAttributes().getList())
|
processTypeAttrs(state, T, TAL_DeclSpec,
|
||||||
processTypeAttrs(state, T, TAL_DeclSpec, attrs);
|
D.getDeclSpec().getAttributes().getList());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case UnqualifiedId::IK_ConversionFunctionId:
|
case UnqualifiedId::IK_ConversionFunctionId:
|
||||||
|
@ -4112,8 +4111,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
|
||||||
}
|
}
|
||||||
|
|
||||||
// See if there are any attributes on this declarator chunk.
|
// See if there are any attributes on this declarator chunk.
|
||||||
if (AttributeList *attrs = const_cast<AttributeList*>(DeclType.getAttrs()))
|
processTypeAttrs(state, T, TAL_DeclChunk,
|
||||||
processTypeAttrs(state, T, TAL_DeclChunk, attrs);
|
const_cast<AttributeList *>(DeclType.getAttrs()));
|
||||||
}
|
}
|
||||||
|
|
||||||
assert(!T.isNull() && "T must not be null after this point");
|
assert(!T.isNull() && "T must not be null after this point");
|
||||||
|
@ -4206,8 +4205,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
|
||||||
}
|
}
|
||||||
|
|
||||||
// Apply any undistributed attributes from the declarator.
|
// Apply any undistributed attributes from the declarator.
|
||||||
if (AttributeList *attrs = D.getAttributes())
|
processTypeAttrs(state, T, TAL_DeclName, D.getAttributes());
|
||||||
processTypeAttrs(state, T, TAL_DeclName, attrs);
|
|
||||||
|
|
||||||
// Diagnose any ignored type attributes.
|
// Diagnose any ignored type attributes.
|
||||||
state.diagnoseIgnoredTypeAttrs(T);
|
state.diagnoseIgnoredTypeAttrs(T);
|
||||||
|
@ -6176,10 +6174,11 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,
|
||||||
// type, but others can be present in the type specifiers even though they
|
// type, but others can be present in the type specifiers even though they
|
||||||
// apply to the decl. Here we apply type attributes and ignore the rest.
|
// apply to the decl. Here we apply type attributes and ignore the rest.
|
||||||
|
|
||||||
AttributeList *next;
|
bool hasOpenCLAddressSpace = false;
|
||||||
do {
|
while (attrs) {
|
||||||
AttributeList &attr = *attrs;
|
AttributeList &attr = *attrs;
|
||||||
next = attr.getNext();
|
attrs = attr.getNext(); // reset to the next here due to early loop continue
|
||||||
|
// stmts
|
||||||
|
|
||||||
// Skip attributes that were marked to be invalid.
|
// Skip attributes that were marked to be invalid.
|
||||||
if (attr.isInvalid())
|
if (attr.isInvalid())
|
||||||
|
@ -6238,6 +6237,7 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,
|
||||||
case AttributeList::AT_AddressSpace:
|
case AttributeList::AT_AddressSpace:
|
||||||
HandleAddressSpaceTypeAttribute(type, attr, state.getSema());
|
HandleAddressSpaceTypeAttribute(type, attr, state.getSema());
|
||||||
attr.setUsedAsTypeAttr();
|
attr.setUsedAsTypeAttr();
|
||||||
|
hasOpenCLAddressSpace = true;
|
||||||
break;
|
break;
|
||||||
OBJC_POINTER_TYPE_ATTRS_CASELIST:
|
OBJC_POINTER_TYPE_ATTRS_CASELIST:
|
||||||
if (!handleObjCPointerTypeAttr(state, attr, type))
|
if (!handleObjCPointerTypeAttr(state, attr, type))
|
||||||
|
@ -6332,7 +6332,39 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,
|
||||||
distributeFunctionTypeAttr(state, attr, type);
|
distributeFunctionTypeAttr(state, attr, type);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} while ((attrs = next));
|
}
|
||||||
|
|
||||||
|
// If address space is not set, OpenCL 2.0 defines non private default
|
||||||
|
// address spaces for some cases:
|
||||||
|
// OpenCL 2.0, section 6.5:
|
||||||
|
// The address space for a variable at program scope or a static variable
|
||||||
|
// inside a function can either be __global or __constant, but defaults to
|
||||||
|
// __global if not specified.
|
||||||
|
// (...)
|
||||||
|
// Pointers that are declared without pointing to a named address space point
|
||||||
|
// to the generic address space.
|
||||||
|
if (state.getSema().getLangOpts().OpenCLVersion >= 200 &&
|
||||||
|
!hasOpenCLAddressSpace && type.getAddressSpace() == 0 &&
|
||||||
|
(TAL == TAL_DeclSpec || TAL == TAL_DeclChunk)) {
|
||||||
|
Declarator &D = state.getDeclarator();
|
||||||
|
if (state.getCurrentChunkIndex() > 0 &&
|
||||||
|
D.getTypeObject(state.getCurrentChunkIndex() - 1).Kind ==
|
||||||
|
DeclaratorChunk::Pointer) {
|
||||||
|
type = state.getSema().Context.getAddrSpaceQualType(
|
||||||
|
type, LangAS::opencl_generic);
|
||||||
|
} else if (state.getCurrentChunkIndex() == 0 &&
|
||||||
|
D.getContext() == Declarator::FileContext &&
|
||||||
|
!D.isFunctionDeclarator() && !D.isFunctionDefinition() &&
|
||||||
|
D.getDeclSpec().getStorageClassSpec() != DeclSpec::SCS_typedef &&
|
||||||
|
!type->isSamplerT())
|
||||||
|
type = state.getSema().Context.getAddrSpaceQualType(
|
||||||
|
type, LangAS::opencl_global);
|
||||||
|
else if (state.getCurrentChunkIndex() == 0 &&
|
||||||
|
D.getContext() == Declarator::BlockContext &&
|
||||||
|
D.getDeclSpec().getStorageClassSpec() == DeclSpec::SCS_static)
|
||||||
|
type = state.getSema().Context.getAddrSpaceQualType(
|
||||||
|
type, LangAS::opencl_global);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// \brief Ensure that the type of the given expression is complete.
|
/// \brief Ensure that the type of the given expression is complete.
|
||||||
|
|
|
@ -1,27 +1,47 @@
|
||||||
// RUN: %clang_cc1 %s -ffake-address-space-map -emit-llvm -o - | FileCheck %s
|
// RUN: %clang_cc1 %s -O0 -ffake-address-space-map -emit-llvm -o - | FileCheck %s
|
||||||
|
// RUN: %clang_cc1 %s -O0 -DCL20 -cl-std=CL2.0 -ffake-address-space-map -emit-llvm -o - | FileCheck %s --check-prefix=CL20
|
||||||
|
|
||||||
void f__p(__private int *arg) { }
|
// CHECK: i32* %arg
|
||||||
// CHECK: i32* nocapture %arg
|
void f__p(__private int *arg) {}
|
||||||
|
|
||||||
void f__g(__global int *arg) { }
|
// CHECK: i32 addrspace(1)* %arg
|
||||||
// CHECK: i32 addrspace(1)* nocapture %arg
|
void f__g(__global int *arg) {}
|
||||||
|
|
||||||
void f__l(__local int *arg) { }
|
// CHECK: i32 addrspace(2)* %arg
|
||||||
// CHECK: i32 addrspace(2)* nocapture %arg
|
void f__l(__local int *arg) {}
|
||||||
|
|
||||||
void f__c(__constant int *arg) { }
|
// CHECK: i32 addrspace(3)* %arg
|
||||||
// CHECK: i32 addrspace(3)* nocapture %arg
|
void f__c(__constant int *arg) {}
|
||||||
|
|
||||||
|
// CHECK: i32* %arg
|
||||||
|
void fp(private int *arg) {}
|
||||||
|
|
||||||
void fp(private int *arg) { }
|
// CHECK: i32 addrspace(1)* %arg
|
||||||
// CHECK: i32* nocapture %arg
|
void fg(global int *arg) {}
|
||||||
|
|
||||||
void fg(global int *arg) { }
|
// CHECK: i32 addrspace(2)* %arg
|
||||||
// CHECK: i32 addrspace(1)* nocapture %arg
|
void fl(local int *arg) {}
|
||||||
|
|
||||||
void fl(local int *arg) { }
|
// CHECK: i32 addrspace(3)* %arg
|
||||||
// CHECK: i32 addrspace(2)* nocapture %arg
|
void fc(constant int *arg) {}
|
||||||
|
|
||||||
void fc(constant int *arg) { }
|
#ifdef CL20
|
||||||
// CHECK: i32 addrspace(3)* nocapture %arg
|
int i;
|
||||||
|
// CL20-DAG: @i = common addrspace(1) global i32 0
|
||||||
|
int *ptr;
|
||||||
|
// CL20-DAG: @ptr = common addrspace(1) global i32 addrspace(4)* null
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// CHECK: i32* %arg
|
||||||
|
// CL20-DAG: i32 addrspace(4)* %arg
|
||||||
|
void f(int *arg) {
|
||||||
|
|
||||||
|
int i;
|
||||||
|
// CHECK: %i = alloca i32,
|
||||||
|
// CL20-DAG: %i = alloca i32,
|
||||||
|
|
||||||
|
#ifdef CL20
|
||||||
|
static int ii;
|
||||||
|
// CL20-DAG: @f.ii = internal addrspace(1) global i32 0
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -DCL20 -cl-std=CL2.0
|
// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -DCL20 -cl-std=CL2.0
|
||||||
|
|
||||||
static constant int G1 = 0;
|
static constant int G1 = 0;
|
||||||
int G2 = 0;// expected-error{{program scope variable must reside in global or constant address space}}
|
int G2 = 0;
|
||||||
global int G3 = 0;
|
global int G3 = 0;
|
||||||
local int G4 = 0;// expected-error{{program scope variable must reside in global or constant address space}}
|
local int G4 = 0;// expected-error{{program scope variable must reside in global or constant address space}}
|
||||||
|
|
||||||
void kernel foo() {
|
void kernel foo() {
|
||||||
static int S1 = 5;// expected-error{{program scope variable must reside in global or constant address space}}
|
static int S1 = 5;
|
||||||
static global int S2 = 5;
|
static global int S2 = 5;
|
||||||
static private int S3 = 5;// expected-error{{program scope variable must reside in global or constant address space}}
|
static private int S3 = 5;// expected-error{{program scope variable must reside in global or constant address space}}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue