Skip to content

Commit 7818906

Browse files
committed
[SYCL] Implement SYCL address space attributes handling
Default address space (applies when no explicit address space was specified) maps to generic (4) address space. Added SYCL named address spaces `sycl_global`, `sycl_local` and `sycl_private` defined as sub-sets of the default address space. Static variables without address space now reside in global address space when compile for SPIR target, unless they have an explicit address space qualifier in source code. Differential Revision: https://reviews.llvm.org/D89909
1 parent 691badc commit 7818906

22 files changed

+449
-44
lines changed

clang/include/clang/AST/Type.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -488,7 +488,11 @@ class Qualifiers {
488488
B == LangAS::opencl_global_host)) ||
489489
// Consider pointer size address spaces to be equivalent to default.
490490
((isPtrSizeAddressSpace(A) || A == LangAS::Default) &&
491-
(isPtrSizeAddressSpace(B) || B == LangAS::Default));
491+
(isPtrSizeAddressSpace(B) || B == LangAS::Default)) ||
492+
// Default is a superset of SYCL address spaces.
493+
(A == LangAS::Default &&
494+
(B == LangAS::sycl_private || B == LangAS::sycl_local ||
495+
B == LangAS::sycl_global));
492496
}
493497

494498
/// Returns true if the address space in these qualifiers is equal to or

clang/include/clang/Basic/AddressSpaces.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,11 @@ enum class LangAS : unsigned {
4444
cuda_constant,
4545
cuda_shared,
4646

47+
// SYCL specific address spaces.
48+
sycl_global,
49+
sycl_local,
50+
sycl_private,
51+
4752
// Pointer size and extension address spaces.
4853
ptr32_sptr,
4954
ptr32_uptr,

clang/include/clang/Sema/ParsedAttr.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -628,8 +628,8 @@ class ParsedAttr final
628628
/// a Spelling enumeration, the value UINT_MAX is returned.
629629
unsigned getSemanticSpelling() const;
630630

631-
/// If this is an OpenCL addr space attribute returns its representation
632-
/// in LangAS, otherwise returns default addr space.
631+
/// If this is an OpenCL address space attribute returns its representation
632+
/// in LangAS, otherwise returns default address space.
633633
LangAS asOpenCLLangAS() const {
634634
switch (getParsedKind()) {
635635
case ParsedAttr::AT_OpenCLConstantAddressSpace:
@@ -651,6 +651,22 @@ class ParsedAttr final
651651
}
652652
}
653653

654+
/// If this is an OpenCL address space attribute returns its SYCL
655+
/// representation in LangAS, otherwise returns default address space.
656+
LangAS asSYCLLangAS() const {
657+
switch (getKind()) {
658+
case ParsedAttr::AT_OpenCLGlobalAddressSpace:
659+
return LangAS::sycl_global;
660+
case ParsedAttr::AT_OpenCLLocalAddressSpace:
661+
return LangAS::sycl_local;
662+
case ParsedAttr::AT_OpenCLPrivateAddressSpace:
663+
return LangAS::sycl_private;
664+
case ParsedAttr::AT_OpenCLGenericAddressSpace:
665+
default:
666+
return LangAS::Default;
667+
}
668+
}
669+
654670
AttributeCommonInfo::Kind getKind() const {
655671
return AttributeCommonInfo::Kind(Info.AttrKind);
656672
}

clang/lib/AST/ASTContext.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -931,6 +931,9 @@ static const LangASMap *getAddressSpaceMap(const TargetInfo &T,
931931
7, // cuda_device
932932
8, // cuda_constant
933933
9, // cuda_shared
934+
1, // sycl_global
935+
3, // sycl_local
936+
0, // sycl_private
934937
10, // ptr32_sptr
935938
11, // ptr32_uptr
936939
12 // ptr64

clang/lib/AST/ItaniumMangle.cpp

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2462,7 +2462,8 @@ void CXXNameMangler::mangleQualifiers(Qualifiers Quals, const DependentAddressSp
24622462
if (Context.getASTContext().addressSpaceMapManglingFor(AS)) {
24632463
// <target-addrspace> ::= "AS" <address-space-number>
24642464
unsigned TargetAS = Context.getASTContext().getTargetAddressSpace(AS);
2465-
if (TargetAS != 0)
2465+
if (TargetAS != 0 ||
2466+
Context.getASTContext().getTargetAddressSpace(LangAS::Default) != 0)
24662467
ASString = "AS" + llvm::utostr(TargetAS);
24672468
} else {
24682469
switch (AS) {
@@ -2491,6 +2492,16 @@ void CXXNameMangler::mangleQualifiers(Qualifiers Quals, const DependentAddressSp
24912492
case LangAS::opencl_generic:
24922493
ASString = "CLgeneric";
24932494
break;
2495+
// <SYCL-addrspace> ::= "SY" [ "global" | "local" | "private" ]
2496+
case LangAS::sycl_global:
2497+
ASString = "SYglobal";
2498+
break;
2499+
case LangAS::sycl_local:
2500+
ASString = "SYlocal";
2501+
break;
2502+
case LangAS::sycl_private:
2503+
ASString = "SYprivate";
2504+
break;
24942505
// <CUDA-addrspace> ::= "CU" [ "device" | "constant" | "shared" ]
24952506
case LangAS::cuda_device:
24962507
ASString = "CUdevice";

clang/lib/AST/TypePrinter.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2111,10 +2111,13 @@ std::string Qualifiers::getAddrSpaceAsString(LangAS AS) {
21112111
case LangAS::Default:
21122112
return "";
21132113
case LangAS::opencl_global:
2114+
case LangAS::sycl_global:
21142115
return "__global";
21152116
case LangAS::opencl_local:
2117+
case LangAS::sycl_local:
21162118
return "__local";
21172119
case LangAS::opencl_private:
2120+
case LangAS::sycl_private:
21182121
return "__private";
21192122
case LangAS::opencl_constant:
21202123
return "__constant";

clang/lib/Basic/Targets/AMDGPU.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ const LangASMap AMDGPUTargetInfo::AMDGPUDefIsGenMap = {
5151
Global, // cuda_device
5252
Constant, // cuda_constant
5353
Local, // cuda_shared
54+
Global, // sycl_global
55+
Local, // sycl_local
56+
Private, // sycl_private
5457
Generic, // ptr32_sptr
5558
Generic, // ptr32_uptr
5659
Generic // ptr64
@@ -68,6 +71,10 @@ const LangASMap AMDGPUTargetInfo::AMDGPUDefIsPrivMap = {
6871
Global, // cuda_device
6972
Constant, // cuda_constant
7073
Local, // cuda_shared
74+
// SYCL address space values for this map are dummy
75+
Generic, // sycl_global
76+
Generic, // sycl_local
77+
Generic, // sycl_private
7178
Generic, // ptr32_sptr
7279
Generic, // ptr32_uptr
7380
Generic // ptr64

clang/lib/Basic/Targets/NVPTX.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ static const unsigned NVPTXAddrSpaceMap[] = {
3535
1, // cuda_device
3636
4, // cuda_constant
3737
3, // cuda_shared
38+
1, // sycl_global
39+
3, // sycl_local
40+
0, // sycl_private
3841
0, // ptr32_sptr
3942
0, // ptr32_uptr
4043
0 // ptr64

clang/lib/Basic/Targets/SPIR.h

Lines changed: 44 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121
namespace clang {
2222
namespace targets {
2323

24-
static const unsigned SPIRAddrSpaceMap[] = {
24+
static const unsigned SPIRDefIsPrivMap[] = {
2525
0, // Default
2626
1, // opencl_global
2727
3, // opencl_local
@@ -33,6 +33,31 @@ static const unsigned SPIRAddrSpaceMap[] = {
3333
0, // cuda_device
3434
0, // cuda_constant
3535
0, // cuda_shared
36+
// SYCL address space values for this map are dummy
37+
0, // sycl_global
38+
0, // sycl_local
39+
0, // sycl_private
40+
0, // ptr32_sptr
41+
0, // ptr32_uptr
42+
0 // ptr64
43+
};
44+
45+
static const unsigned SPIRDefIsGenMap[] = {
46+
4, // Default
47+
// OpenCL address space values for this map are dummy and they can't be used
48+
0, // opencl_global
49+
0, // opencl_local
50+
0, // opencl_constant
51+
0, // opencl_private
52+
0, // opencl_generic
53+
0, // opencl_global_device
54+
0, // opencl_global_host
55+
0, // cuda_device
56+
0, // cuda_constant
57+
0, // cuda_shared
58+
1, // sycl_global
59+
3, // sycl_local
60+
0, // sycl_private
3661
0, // ptr32_sptr
3762
0, // ptr32_uptr
3863
0 // ptr64
@@ -49,7 +74,7 @@ class LLVM_LIBRARY_VISIBILITY SPIRTargetInfo : public TargetInfo {
4974
TLSSupported = false;
5075
VLASupported = false;
5176
LongWidth = LongAlign = 64;
52-
AddrSpaceMap = &SPIRAddrSpaceMap;
77+
AddrSpaceMap = &SPIRDefIsPrivMap;
5378
UseAddrSpaceMapMangling = true;
5479
HasLegalHalfType = true;
5580
HasFloat16 = true;
@@ -97,6 +122,22 @@ class LLVM_LIBRARY_VISIBILITY SPIRTargetInfo : public TargetInfo {
97122
return CC_SpirFunction;
98123
}
99124

125+
void setAddressSpaceMap(bool DefaultIsGeneric) {
126+
AddrSpaceMap = DefaultIsGeneric ? &SPIRDefIsGenMap : &SPIRDefIsPrivMap;
127+
}
128+
129+
void adjust(LangOptions &Opts) override {
130+
TargetInfo::adjust(Opts);
131+
// FIXME: SYCL specification considers unannotated pointers and references
132+
// to be pointing to the generic address space. See section 5.9.3 of
133+
// SYCL 2020 specification.
134+
// Currently, there is no way of representing SYCL's default address space
135+
// language semantic along with the semantics of embedded C's default
136+
// address space in the same address space map. Hence the map needs to be
137+
// reset to allow mapping to the desired value of 'Default' entry for SYCL.
138+
setAddressSpaceMap(/*DefaultIsGeneric=*/Opts.SYCLIsDevice);
139+
}
140+
100141
void setSupportedOpenCLOpts() override {
101142
// Assume all OpenCL extensions and optional core features are supported
102143
// for SPIR since it is a generic target.
@@ -107,6 +148,7 @@ class LLVM_LIBRARY_VISIBILITY SPIRTargetInfo : public TargetInfo {
107148

108149
bool hasInt128Type() const override { return false; }
109150
};
151+
110152
class LLVM_LIBRARY_VISIBILITY SPIR32TargetInfo : public SPIRTargetInfo {
111153
public:
112154
SPIR32TargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)

clang/lib/Basic/Targets/TCE.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,9 @@ static const unsigned TCEOpenCLAddrSpaceMap[] = {
4242
0, // cuda_device
4343
0, // cuda_constant
4444
0, // cuda_shared
45+
3, // sycl_global
46+
4, // sycl_local
47+
0, // sycl_private
4548
0, // ptr32_sptr
4649
0, // ptr32_uptr
4750
0, // ptr64

clang/lib/Basic/Targets/X86.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ static const unsigned X86AddrSpaceMap[] = {
3535
0, // cuda_device
3636
0, // cuda_constant
3737
0, // cuda_shared
38+
0, // sycl_global
39+
0, // sycl_local
40+
0, // sycl_private
3841
270, // ptr32_sptr
3942
271, // ptr32_uptr
4043
272 // ptr64

clang/lib/CodeGen/CGDecl.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1122,7 +1122,7 @@ Address CodeGenModule::createUnnamedGlobalFrom(const VarDecl &D,
11221122
bool isConstant = true;
11231123
llvm::GlobalVariable *InsertBefore = nullptr;
11241124
unsigned AS =
1125-
getContext().getTargetAddressSpace(getStringLiteralAddressSpace());
1125+
getContext().getTargetAddressSpace(GetGlobalConstantAddressSpace());
11261126
std::string Name;
11271127
if (D.hasGlobalStorage())
11281128
Name = getMangledName(&D).str() + ".const";

clang/lib/CodeGen/CGExpr.cpp

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -404,24 +404,22 @@ static Address createReferenceTemporary(CodeGenFunction &CGF,
404404
(Ty->isArrayType() || Ty->isRecordType()) &&
405405
CGF.CGM.isTypeConstant(Ty, true))
406406
if (auto Init = ConstantEmitter(CGF).tryEmitAbstract(Inner, Ty)) {
407-
if (auto AddrSpace = CGF.getTarget().getConstantAddressSpace()) {
408-
auto AS = AddrSpace.getValue();
409-
auto *GV = new llvm::GlobalVariable(
410-
CGF.CGM.getModule(), Init->getType(), /*isConstant=*/true,
411-
llvm::GlobalValue::PrivateLinkage, Init, ".ref.tmp", nullptr,
412-
llvm::GlobalValue::NotThreadLocal,
413-
CGF.getContext().getTargetAddressSpace(AS));
414-
CharUnits alignment = CGF.getContext().getTypeAlignInChars(Ty);
415-
GV->setAlignment(alignment.getAsAlign());
416-
llvm::Constant *C = GV;
417-
if (AS != LangAS::Default)
418-
C = TCG.performAddrSpaceCast(
419-
CGF.CGM, GV, AS, LangAS::Default,
420-
GV->getValueType()->getPointerTo(
421-
CGF.getContext().getTargetAddressSpace(LangAS::Default)));
422-
// FIXME: Should we put the new global into a COMDAT?
423-
return Address(C, alignment);
424-
}
407+
auto AS = CGF.CGM.GetGlobalConstantAddressSpace();
408+
auto *GV = new llvm::GlobalVariable(
409+
CGF.CGM.getModule(), Init->getType(), /*isConstant=*/true,
410+
llvm::GlobalValue::PrivateLinkage, Init, ".ref.tmp", nullptr,
411+
llvm::GlobalValue::NotThreadLocal,
412+
CGF.getContext().getTargetAddressSpace(AS));
413+
CharUnits alignment = CGF.getContext().getTypeAlignInChars(Ty);
414+
GV->setAlignment(alignment.getAsAlign());
415+
llvm::Constant *C = GV;
416+
if (AS != LangAS::Default)
417+
C = TCG.performAddrSpaceCast(
418+
CGF.CGM, GV, AS, LangAS::Default,
419+
GV->getValueType()->getPointerTo(
420+
CGF.getContext().getTargetAddressSpace(LangAS::Default)));
421+
// FIXME: Should we put the new global into a COMDAT?
422+
return Address(C, alignment);
425423
}
426424
return CGF.CreateMemTemp(Ty, "ref.tmp", Alloca);
427425
}

clang/lib/CodeGen/CodeGenModule.cpp

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4116,6 +4116,10 @@ LangAS CodeGenModule::GetGlobalVarAddressSpace(const VarDecl *D) {
41164116
return AddrSpace;
41174117
}
41184118

4119+
if (LangOpts.SYCLIsDevice &&
4120+
(!D || D->getType().getAddressSpace() == LangAS::Default))
4121+
return LangAS::sycl_global;
4122+
41194123
if (LangOpts.CUDA && LangOpts.CUDAIsDevice) {
41204124
if (D && D->hasAttr<CUDAConstantAttr>())
41214125
return LangAS::cuda_constant;
@@ -4137,10 +4141,12 @@ LangAS CodeGenModule::GetGlobalVarAddressSpace(const VarDecl *D) {
41374141
return getTargetCodeGenInfo().getGlobalVarAddressSpace(*this, D);
41384142
}
41394143

4140-
LangAS CodeGenModule::getStringLiteralAddressSpace() const {
4144+
LangAS CodeGenModule::GetGlobalConstantAddressSpace() const {
41414145
// OpenCL v1.2 s6.5.3: a string literal is in the constant address space.
41424146
if (LangOpts.OpenCL)
41434147
return LangAS::opencl_constant;
4148+
if (LangOpts.SYCLIsDevice)
4149+
return LangAS::sycl_global;
41444150
if (auto AS = getTarget().getConstantAddressSpace())
41454151
return AS.getValue();
41464152
return LangAS::Default;
@@ -4159,13 +4165,12 @@ castStringLiteralToDefaultAddressSpace(CodeGenModule &CGM,
41594165
llvm::GlobalVariable *GV) {
41604166
llvm::Constant *Cast = GV;
41614167
if (!CGM.getLangOpts().OpenCL) {
4162-
if (auto AS = CGM.getTarget().getConstantAddressSpace()) {
4163-
if (AS != LangAS::Default)
4164-
Cast = CGM.getTargetCodeGenInfo().performAddrSpaceCast(
4165-
CGM, GV, AS.getValue(), LangAS::Default,
4166-
GV->getValueType()->getPointerTo(
4167-
CGM.getContext().getTargetAddressSpace(LangAS::Default)));
4168-
}
4168+
auto AS = CGM.GetGlobalConstantAddressSpace();
4169+
if (AS != LangAS::Default)
4170+
Cast = CGM.getTargetCodeGenInfo().performAddrSpaceCast(
4171+
CGM, GV, AS, LangAS::Default,
4172+
GV->getValueType()->getPointerTo(
4173+
CGM.getContext().getTargetAddressSpace(LangAS::Default)));
41694174
}
41704175
return Cast;
41714176
}
@@ -5277,7 +5282,7 @@ GenerateStringLiteral(llvm::Constant *C, llvm::GlobalValue::LinkageTypes LT,
52775282
CodeGenModule &CGM, StringRef GlobalName,
52785283
CharUnits Alignment) {
52795284
unsigned AddrSpace = CGM.getContext().getTargetAddressSpace(
5280-
CGM.getStringLiteralAddressSpace());
5285+
CGM.GetGlobalConstantAddressSpace());
52815286

52825287
llvm::Module &M = CGM.getModule();
52835288
// Create a global variable for this string

clang/lib/CodeGen/CodeGenModule.h

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -855,6 +855,13 @@ class CodeGenModule : public CodeGenTypeCache {
855855
/// space, target-specific global or constant address space may be returned.
856856
LangAS GetGlobalVarAddressSpace(const VarDecl *D);
857857

858+
/// Return the AST address space of constant literal, which is used to emit
859+
/// the constant literal as global variable in LLVM IR.
860+
/// Note: This is not necessarily the address space of the constant literal
861+
/// in AST. For address space agnostic language, e.g. C++, constant literal
862+
/// in AST is always in default address space.
863+
LangAS GetGlobalConstantAddressSpace() const;
864+
858865
/// Return the llvm::Constant for the address of the given global variable.
859866
/// If Ty is non-null and if the global doesn't exist, then it will be created
860867
/// with the specified type instead of whatever the normal requested type
@@ -866,13 +873,6 @@ class CodeGenModule : public CodeGenTypeCache {
866873
ForDefinition_t IsForDefinition
867874
= NotForDefinition);
868875

869-
/// Return the AST address space of string literal, which is used to emit
870-
/// the string literal as global variable in LLVM IR.
871-
/// Note: This is not necessarily the address space of the string literal
872-
/// in AST. For address space agnostic language, e.g. C++, string literal
873-
/// in AST is always in default address space.
874-
LangAS getStringLiteralAddressSpace() const;
875-
876876
/// Return the address of the given function. If Ty is non-null, then this
877877
/// function will use the specified type if it has to create it.
878878
llvm::Constant *GetAddrOfFunction(GlobalDecl GD, llvm::Type *Ty = nullptr,

clang/lib/CodeGen/TargetInfo.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10068,6 +10068,12 @@ class SPIRTargetCodeGenInfo : public TargetCodeGenInfo {
1006810068
public:
1006910069
SPIRTargetCodeGenInfo(CodeGen::CodeGenTypes &CGT)
1007010070
: TargetCodeGenInfo(std::make_unique<SPIRABIInfo>(CGT)) {}
10071+
10072+
LangAS getASTAllocaAddressSpace() const override {
10073+
return getLangASFromTargetAS(
10074+
getABIInfo().getDataLayout().getAllocaAddrSpace());
10075+
}
10076+
1007110077
unsigned getOpenCLKernelCallingConv() const override;
1007210078
};
1007310079

0 commit comments

Comments
 (0)