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
|
||||
// list of type attributes to be temporarily saved while the type
|
||||
// attributes are pushed around.
|
||||
if (AttributeList *attrs = DS.getAttributes().getList())
|
||||
processTypeAttrs(state, Result, TAL_DeclSpec, attrs);
|
||||
processTypeAttrs(state, Result, TAL_DeclSpec, DS.getAttributes().getList());
|
||||
|
||||
// Apply const/volatile/restrict qualifiers to T.
|
||||
if (unsigned TypeQuals = DS.getTypeQualifiers()) {
|
||||
|
@ -2596,8 +2595,8 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
|
|||
// Constructors and destructors don't have return types. Use
|
||||
// "void" instead.
|
||||
T = SemaRef.Context.VoidTy;
|
||||
if (AttributeList *attrs = D.getDeclSpec().getAttributes().getList())
|
||||
processTypeAttrs(state, T, TAL_DeclSpec, attrs);
|
||||
processTypeAttrs(state, T, TAL_DeclSpec,
|
||||
D.getDeclSpec().getAttributes().getList());
|
||||
break;
|
||||
|
||||
case UnqualifiedId::IK_ConversionFunctionId:
|
||||
|
@ -4112,8 +4111,8 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
|
|||
}
|
||||
|
||||
// See if there are any attributes on this declarator chunk.
|
||||
if (AttributeList *attrs = const_cast<AttributeList*>(DeclType.getAttrs()))
|
||||
processTypeAttrs(state, T, TAL_DeclChunk, attrs);
|
||||
processTypeAttrs(state, T, TAL_DeclChunk,
|
||||
const_cast<AttributeList *>(DeclType.getAttrs()));
|
||||
}
|
||||
|
||||
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.
|
||||
if (AttributeList *attrs = D.getAttributes())
|
||||
processTypeAttrs(state, T, TAL_DeclName, attrs);
|
||||
processTypeAttrs(state, T, TAL_DeclName, D.getAttributes());
|
||||
|
||||
// Diagnose any ignored type attributes.
|
||||
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
|
||||
// apply to the decl. Here we apply type attributes and ignore the rest.
|
||||
|
||||
AttributeList *next;
|
||||
do {
|
||||
bool hasOpenCLAddressSpace = false;
|
||||
while (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.
|
||||
if (attr.isInvalid())
|
||||
|
@ -6238,6 +6237,7 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,
|
|||
case AttributeList::AT_AddressSpace:
|
||||
HandleAddressSpaceTypeAttribute(type, attr, state.getSema());
|
||||
attr.setUsedAsTypeAttr();
|
||||
hasOpenCLAddressSpace = true;
|
||||
break;
|
||||
OBJC_POINTER_TYPE_ATTRS_CASELIST:
|
||||
if (!handleObjCPointerTypeAttr(state, attr, type))
|
||||
|
@ -6332,7 +6332,39 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,
|
|||
distributeFunctionTypeAttr(state, attr, type);
|
||||
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.
|
||||
|
|
|
@ -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* nocapture %arg
|
||||
// CHECK: i32* %arg
|
||||
void f__p(__private int *arg) {}
|
||||
|
||||
void f__g(__global int *arg) { }
|
||||
// CHECK: i32 addrspace(1)* nocapture %arg
|
||||
// CHECK: i32 addrspace(1)* %arg
|
||||
void f__g(__global int *arg) {}
|
||||
|
||||
void f__l(__local int *arg) { }
|
||||
// CHECK: i32 addrspace(2)* nocapture %arg
|
||||
// CHECK: i32 addrspace(2)* %arg
|
||||
void f__l(__local int *arg) {}
|
||||
|
||||
void f__c(__constant int *arg) { }
|
||||
// CHECK: i32 addrspace(3)* nocapture %arg
|
||||
// CHECK: i32 addrspace(3)* %arg
|
||||
void f__c(__constant int *arg) {}
|
||||
|
||||
// CHECK: i32* %arg
|
||||
void fp(private int *arg) {}
|
||||
|
||||
void fp(private int *arg) { }
|
||||
// CHECK: i32* nocapture %arg
|
||||
// CHECK: i32 addrspace(1)* %arg
|
||||
void fg(global int *arg) {}
|
||||
|
||||
void fg(global int *arg) { }
|
||||
// CHECK: i32 addrspace(1)* nocapture %arg
|
||||
// CHECK: i32 addrspace(2)* %arg
|
||||
void fl(local int *arg) {}
|
||||
|
||||
void fl(local int *arg) { }
|
||||
// CHECK: i32 addrspace(2)* nocapture %arg
|
||||
// CHECK: i32 addrspace(3)* %arg
|
||||
void fc(constant int *arg) {}
|
||||
|
||||
void fc(constant int *arg) { }
|
||||
// CHECK: i32 addrspace(3)* nocapture %arg
|
||||
#ifdef CL20
|
||||
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
|
||||
|
||||
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;
|
||||
local int G4 = 0;// expected-error{{program scope variable must reside in global or constant address space}}
|
||||
|
||||
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 private int S3 = 5;// expected-error{{program scope variable must reside in global or constant address space}}
|
||||
|
||||
|
|
Loading…
Reference in New Issue