Skip to content

Commit b7318e0

Browse files
committed
[OpenCL] Add LangAS::opencl_private to represent private address space in AST
Currently Clang uses default address space (0) to represent private address space for OpenCL in AST. There are two issues with this: Multiple address spaces including private address space cannot be diagnosed. There is no mangling for default address space. For example, if private int* is emitted as i32 addrspace(5)* in IR. It is supposed to be mangled as PUAS5i but it is mangled as Pi instead. This patch attempts to represent OpenCL private address space explicitly in AST. It adds a new enum LangAS::opencl_private and adds it to the variable types which are implicitly private: automatic variables without address space qualifier function parameter pointee type without address space qualifier (OpenCL 1.2 and below) Differential Revision: https://reviews.llvm.org/D35082 llvm-svn: 315668
1 parent 662bb00 commit b7318e0

21 files changed

+319
-107
lines changed

clang/include/clang/Basic/AddressSpaces.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -25,16 +25,17 @@ namespace LangAS {
2525
///
2626
enum ID {
2727
// The default value 0 is the value used in QualType for the the situation
28-
// where there is no address space qualifier. For most languages, this also
29-
// corresponds to the situation where there is no address space qualifier in
30-
// the source code, except for OpenCL, where the address space value 0 in
31-
// QualType represents private address space in OpenCL source code.
28+
// where there is no address space qualifier.
3229
Default = 0,
3330

3431
// OpenCL specific address spaces.
32+
// In OpenCL each l-value must have certain non-default address space, each
33+
// r-value must have no address space (i.e. the default address space). The
34+
// pointee of a pointer must have non-default address space.
3535
opencl_global,
3636
opencl_local,
3737
opencl_constant,
38+
opencl_private,
3839
opencl_generic,
3940

4041
// CUDA specific address spaces.

clang/lib/AST/ASTContext.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -707,6 +707,7 @@ static const LangAS::Map *getAddressSpaceMap(const TargetInfo &T,
707707
1, // opencl_global
708708
3, // opencl_local
709709
2, // opencl_constant
710+
0, // opencl_private
710711
4, // opencl_generic
711712
5, // cuda_device
712713
6, // cuda_constant

clang/lib/AST/Expr.cpp

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -3293,20 +3293,20 @@ Expr::isNullPointerConstant(ASTContext &Ctx,
32933293
// Check that it is a cast to void*.
32943294
if (const PointerType *PT = CE->getType()->getAs<PointerType>()) {
32953295
QualType Pointee = PT->getPointeeType();
3296-
Qualifiers Q = Pointee.getQualifiers();
3297-
// In OpenCL v2.0 generic address space acts as a placeholder
3298-
// and should be ignored.
3299-
bool IsASValid = true;
3300-
if (Ctx.getLangOpts().OpenCLVersion >= 200) {
3301-
if (Pointee.getAddressSpace() == LangAS::opencl_generic)
3302-
Q.removeAddressSpace();
3303-
else
3304-
IsASValid = false;
3305-
}
3306-
3307-
if (IsASValid && !Q.hasQualifiers() &&
3308-
Pointee->isVoidType() && // to void*
3309-
CE->getSubExpr()->getType()->isIntegerType()) // from int.
3296+
// Only (void*)0 or equivalent are treated as nullptr. If pointee type
3297+
// has non-default address space it is not treated as nullptr.
3298+
// (__generic void*)0 in OpenCL 2.0 should not be treated as nullptr
3299+
// since it cannot be assigned to a pointer to constant address space.
3300+
bool PointeeHasDefaultAS =
3301+
Pointee.getAddressSpace() == LangAS::Default ||
3302+
(Ctx.getLangOpts().OpenCLVersion >= 200 &&
3303+
Pointee.getAddressSpace() == LangAS::opencl_generic) ||
3304+
(Ctx.getLangOpts().OpenCL &&
3305+
Ctx.getLangOpts().OpenCLVersion < 200 &&
3306+
Pointee.getAddressSpace() == LangAS::opencl_private);
3307+
3308+
if (PointeeHasDefaultAS && Pointee->isVoidType() && // to void*
3309+
CE->getSubExpr()->getType()->isIntegerType()) // from int.
33103310
return CE->getSubExpr()->isNullPointerConstant(Ctx, NPC);
33113311
}
33123312
}

clang/lib/AST/ItaniumMangle.cpp

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2227,23 +2227,26 @@ void CXXNameMangler::mangleQualifiers(Qualifiers Quals, const DependentAddressSp
22272227
if (Context.getASTContext().addressSpaceMapManglingFor(AS)) {
22282228
// <target-addrspace> ::= "AS" <address-space-number>
22292229
unsigned TargetAS = Context.getASTContext().getTargetAddressSpace(AS);
2230-
ASString = "AS" + llvm::utostr(TargetAS);
2230+
if (TargetAS != 0)
2231+
ASString = "AS" + llvm::utostr(TargetAS);
22312232
} else {
22322233
switch (AS) {
22332234
default: llvm_unreachable("Not a language specific address space");
2234-
// <OpenCL-addrspace> ::= "CL" [ "global" | "local" | "constant |
2235-
// "generic" ]
2235+
// <OpenCL-addrspace> ::= "CL" [ "global" | "local" | "constant" |
2236+
// "private"| "generic" ]
22362237
case LangAS::opencl_global: ASString = "CLglobal"; break;
22372238
case LangAS::opencl_local: ASString = "CLlocal"; break;
22382239
case LangAS::opencl_constant: ASString = "CLconstant"; break;
2240+
case LangAS::opencl_private: ASString = "CLprivate"; break;
22392241
case LangAS::opencl_generic: ASString = "CLgeneric"; break;
22402242
// <CUDA-addrspace> ::= "CU" [ "device" | "constant" | "shared" ]
22412243
case LangAS::cuda_device: ASString = "CUdevice"; break;
22422244
case LangAS::cuda_constant: ASString = "CUconstant"; break;
22432245
case LangAS::cuda_shared: ASString = "CUshared"; break;
22442246
}
22452247
}
2246-
mangleVendorQualifier(ASString);
2248+
if (!ASString.empty())
2249+
mangleVendorQualifier(ASString);
22472250
}
22482251

22492252
// The ARC ownership qualifiers start with underscores.

clang/lib/AST/TypePrinter.cpp

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1677,16 +1677,19 @@ void Qualifiers::print(raw_ostream &OS, const PrintingPolicy& Policy,
16771677
addSpace = true;
16781678
}
16791679
if (unsigned addrspace = getAddressSpace()) {
1680-
if (addSpace)
1681-
OS << ' ';
1682-
addSpace = true;
1683-
switch (addrspace) {
1680+
if (addrspace != LangAS::opencl_private) {
1681+
if (addSpace)
1682+
OS << ' ';
1683+
addSpace = true;
1684+
switch (addrspace) {
16841685
case LangAS::opencl_global:
16851686
OS << "__global";
16861687
break;
16871688
case LangAS::opencl_local:
16881689
OS << "__local";
16891690
break;
1691+
case LangAS::opencl_private:
1692+
break;
16901693
case LangAS::opencl_constant:
16911694
case LangAS::cuda_constant:
16921695
OS << "__constant";
@@ -1705,6 +1708,7 @@ void Qualifiers::print(raw_ostream &OS, const PrintingPolicy& Policy,
17051708
OS << "__attribute__((address_space(";
17061709
OS << addrspace - LangAS::FirstTargetAddressSpace;
17071710
OS << ")))";
1711+
}
17081712
}
17091713
}
17101714
if (Qualifiers::GC gc = getObjCGCAttr()) {

clang/lib/Basic/Targets/AMDGPU.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ static const LangAS::Map AMDGPUPrivIsZeroDefIsGenMap = {
4747
1, // opencl_global
4848
3, // opencl_local
4949
2, // opencl_constant
50+
0, // opencl_private
5051
4, // opencl_generic
5152
1, // cuda_device
5253
2, // cuda_constant
@@ -58,6 +59,7 @@ static const LangAS::Map AMDGPUGenIsZeroDefIsGenMap = {
5859
1, // opencl_global
5960
3, // opencl_local
6061
2, // opencl_constant
62+
5, // opencl_private
6163
0, // opencl_generic
6264
1, // cuda_device
6365
2, // cuda_constant
@@ -69,6 +71,7 @@ static const LangAS::Map AMDGPUPrivIsZeroDefIsPrivMap = {
6971
1, // opencl_global
7072
3, // opencl_local
7173
2, // opencl_constant
74+
0, // opencl_private
7275
4, // opencl_generic
7376
1, // cuda_device
7477
2, // cuda_constant
@@ -80,6 +83,7 @@ static const LangAS::Map AMDGPUGenIsZeroDefIsPrivMap = {
8083
1, // opencl_global
8184
3, // opencl_local
8285
2, // opencl_constant
86+
5, // opencl_private
8387
0, // opencl_generic
8488
1, // cuda_device
8589
2, // cuda_constant

clang/lib/Basic/Targets/NVPTX.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ static const unsigned NVPTXAddrSpaceMap[] = {
2828
1, // opencl_global
2929
3, // opencl_local
3030
4, // opencl_constant
31+
0, // opencl_private
3132
// FIXME: generic has to be added to the target
3233
0, // opencl_generic
3334
1, // cuda_device

clang/lib/Basic/Targets/SPIR.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ static const unsigned SPIRAddrSpaceMap[] = {
2727
1, // opencl_global
2828
3, // opencl_local
2929
2, // opencl_constant
30+
0, // opencl_private
3031
4, // opencl_generic
3132
0, // cuda_device
3233
0, // cuda_constant

clang/lib/Basic/Targets/TCE.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ static const unsigned TCEOpenCLAddrSpaceMap[] = {
3535
3, // opencl_global
3636
4, // opencl_local
3737
5, // opencl_constant
38+
0, // opencl_private
3839
// FIXME: generic has to be added to the target
3940
0, // opencl_generic
4041
0, // cuda_device

clang/lib/CodeGen/CGDecl.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -956,7 +956,9 @@ void CodeGenFunction::EmitLifetimeEnd(llvm::Value *Size, llvm::Value *Addr) {
956956
CodeGenFunction::AutoVarEmission
957957
CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
958958
QualType Ty = D.getType();
959-
assert(Ty.getAddressSpace() == LangAS::Default);
959+
assert(
960+
Ty.getAddressSpace() == LangAS::Default ||
961+
(Ty.getAddressSpace() == LangAS::opencl_private && getLangOpts().OpenCL));
960962

961963
AutoVarEmission emission(D);
962964

clang/lib/Sema/SemaChecking.cpp

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -340,7 +340,7 @@ static bool SemaOpenCLBuiltinNDRangeAndBlock(Sema &S, CallExpr *TheCall) {
340340

341341
// First argument is an ndrange_t type.
342342
Expr *NDRangeArg = TheCall->getArg(0);
343-
if (NDRangeArg->getType().getAsString() != "ndrange_t") {
343+
if (NDRangeArg->getType().getUnqualifiedType().getAsString() != "ndrange_t") {
344344
S.Diag(NDRangeArg->getLocStart(),
345345
diag::err_opencl_builtin_expected_type)
346346
<< TheCall->getDirectCallee() << "'ndrange_t'";
@@ -784,8 +784,11 @@ static bool SemaOpenCLBuiltinToAddr(Sema &S, unsigned BuiltinID,
784784
case Builtin::BIto_local:
785785
Qual.setAddressSpace(LangAS::opencl_local);
786786
break;
787+
case Builtin::BIto_private:
788+
Qual.setAddressSpace(LangAS::opencl_private);
789+
break;
787790
default:
788-
Qual.removeAddressSpace();
791+
llvm_unreachable("Invalid builtin function");
789792
}
790793
Call->setType(S.Context.getPointerType(S.Context.getQualifiedType(
791794
RT.getUnqualifiedType(), Qual)));

clang/lib/Sema/SemaDecl.cpp

Lines changed: 12 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -6324,7 +6324,7 @@ NamedDecl *Sema::ActOnVariableDeclarator(
63246324
// The event type cannot be used with the __local, __constant and __global
63256325
// address space qualifiers.
63266326
if (R->isEventT()) {
6327-
if (R.getAddressSpace()) {
6327+
if (R.getAddressSpace() != LangAS::opencl_private) {
63286328
Diag(D.getLocStart(), diag::err_event_t_addr_space_qual);
63296329
D.setInvalidType();
63306330
}
@@ -7427,7 +7427,7 @@ void Sema::CheckVariableDeclarationType(VarDecl *NewVD) {
74277427
return;
74287428
}
74297429
}
7430-
} else if (T.getAddressSpace() != LangAS::Default) {
7430+
} else if (T.getAddressSpace() != LangAS::opencl_private) {
74317431
// Do not allow other address spaces on automatic variable.
74327432
Diag(NewVD->getLocation(), diag::err_as_qualified_auto_decl) << 1;
74337433
NewVD->setInvalidDecl();
@@ -8062,7 +8062,8 @@ static OpenCLParamType getOpenCLKernelParameterType(Sema &S, QualType PT) {
80628062
if (PointeeType->isPointerType())
80638063
return PtrPtrKernelParam;
80648064
if (PointeeType.getAddressSpace() == LangAS::opencl_generic ||
8065-
PointeeType.getAddressSpace() == 0)
8065+
PointeeType.getAddressSpace() == LangAS::opencl_private ||
8066+
PointeeType.getAddressSpace() == LangAS::Default)
80668067
return InvalidAddrSpacePtrKernelParam;
80678068
return PtrKernelParam;
80688069
}
@@ -8832,9 +8833,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
88328833
// OpenCL v1.1 s6.5: Using an address space qualifier in a function return
88338834
// type declaration will generate a compilation error.
88348835
unsigned AddressSpace = NewFD->getReturnType().getAddressSpace();
8835-
if (AddressSpace == LangAS::opencl_local ||
8836-
AddressSpace == LangAS::opencl_global ||
8837-
AddressSpace == LangAS::opencl_constant) {
8836+
if (AddressSpace != LangAS::Default) {
88388837
Diag(NewFD->getLocation(),
88398838
diag::err_opencl_return_value_with_address_space);
88408839
NewFD->setInvalidDecl();
@@ -11939,13 +11938,13 @@ ParmVarDecl *Sema::CheckParameter(DeclContext *DC, SourceLocation StartLoc,
1193911938
// duration shall not be qualified by an address-space qualifier."
1194011939
// Since all parameters have automatic store duration, they can not have
1194111940
// an address space.
11942-
if (T.getAddressSpace() != 0) {
11943-
// OpenCL allows function arguments declared to be an array of a type
11944-
// to be qualified with an address space.
11945-
if (!(getLangOpts().OpenCL && T->isArrayType())) {
11946-
Diag(NameLoc, diag::err_arg_with_address_space);
11947-
New->setInvalidDecl();
11948-
}
11941+
if (T.getAddressSpace() != LangAS::Default &&
11942+
// OpenCL allows function arguments declared to be an array of a type
11943+
// to be qualified with an address space.
11944+
!(getLangOpts().OpenCL &&
11945+
(T->isArrayType() || T.getAddressSpace() == LangAS::opencl_private))) {
11946+
Diag(NameLoc, diag::err_arg_with_address_space);
11947+
New->setInvalidDecl();
1194911948
}
1195011949

1195111950
return New;

0 commit comments

Comments
 (0)