Skip to content

[Draft] Address space lowering for SYCL #18

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 22 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
4dba046
[SYCL] Optionally override addrspace map for SYCL device code
Nov 20, 2018
7c25c6b
[SYCL] Move static variables to global address space by default
Jun 18, 2019
3fee8b5
[SYCL] Turn new address space rules by default
Jun 18, 2019
f13f3f8
[SYCL] Put string literals to private address space
Jun 21, 2019
a3cdbbd
[SYCL] Insert implicit addrspacecast when casting between different AS
Jul 19, 2019
c44e81c
[SYCL] Insert addrspacecast for conditional operator
Jul 23, 2019
55afb9c
[SYCL][AddressSpace] Fix address space of a static variable initializer
Aug 12, 2019
396f77f
[SYCL] Fix address space of return values
Fznamznon Jul 2, 2019
ff0b370
[SYCL] Fix address space in generation of llvm.invariant.start intrinsic
Fznamznon Aug 12, 2019
5e436ad
[SYCL] Remove ASFixer and DISABLE_INFER_AS support (#893)
romanovvlad Dec 3, 2019
be3ab52
[SYCL] Fix unique-stable-name test after rebase
bader Jul 6, 2019
573f261
[SYCL] Expand assertion for SYCL
Fznamznon Aug 6, 2019
8528fa5
[SYCL] Insert addrspacecast for comparing operands
mlychkov Aug 20, 2019
eef2115
[SYCL] Re-use OpenCL address space attributes for SYCL (#1581)
Fznamznon Apr 27, 2020
44d5d1f
[SYCL] Added SYCLDevice env to triple.
vladimirlaz Jan 18, 2019
7a4bcd7
[SYCL][Test] Clang tests clean up (#979)
bader Jan 1, 2020
7247318
[SYCL][NFC] Added SPIRSYCLDevice target.
vladimirlaz Dec 28, 2018
0668e3d
Fixes.
bader Jun 9, 2020
df77c7e
[SYCL] Implement OpenCL kernel function generation
Fznamznon Jun 9, 2020
b277248
Fix tests
bader Jun 9, 2020
1b6cdc0
Revert "[SYCL] Implement OpenCL kernel function generation"
bader Jun 9, 2020
d48fce1
Test fixes.
bader Jun 9, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 6 additions & 1 deletion clang/include/clang/AST/Type.h
Original file line number Diff line number Diff line change
Expand Up @@ -488,7 +488,12 @@ class Qualifiers {
/// Returns true if the address space in these qualifiers is equal to or
/// a superset of the address space in the argument qualifiers.
bool isAddressSpaceSupersetOf(Qualifiers other) const {
return isAddressSpaceSupersetOf(getAddressSpace(), other.getAddressSpace());
return isAddressSpaceSupersetOf(getAddressSpace(),
other.getAddressSpace()) ||
(!hasAddressSpace() &&
(other.getAddressSpace() == LangAS::opencl_private ||
other.getAddressSpace() == LangAS::opencl_local ||
other.getAddressSpace() == LangAS::opencl_global));
}

/// Determines if these qualifiers compatibly include another set.
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/AST/ItaniumMangle.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2381,7 +2381,7 @@ void CXXNameMangler::mangleQualifiers(Qualifiers Quals, const DependentAddressSp
if (Context.getASTContext().addressSpaceMapManglingFor(AS)) {
// <target-addrspace> ::= "AS" <address-space-number>
unsigned TargetAS = Context.getASTContext().getTargetAddressSpace(AS);
if (TargetAS != 0)
if (TargetAS != 0 || (Context.getASTContext().getLangOpts().SYCLIsDevice))
ASString = "AS" + llvm::utostr(TargetAS);
} else {
switch (AS) {
Expand Down
24 changes: 18 additions & 6 deletions clang/lib/Basic/Targets.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -567,17 +567,29 @@ TargetInfo *AllocateTarget(const llvm::Triple &Triple,
}

case llvm::Triple::spir: {
if (Triple.getOS() != llvm::Triple::UnknownOS ||
Triple.getEnvironment() != llvm::Triple::UnknownEnvironment)
return nullptr;
if (Triple.getEnvironment() == llvm::Triple::SYCLDevice) {
switch (os) {
case llvm::Triple::Linux:
return new LinuxTargetInfo<SPIR32SYCLDeviceTargetInfo>(Triple, Opts);
default:
return new SPIR32SYCLDeviceTargetInfo(Triple, Opts);
}
}
return new SPIR32TargetInfo(Triple, Opts);
}

case llvm::Triple::spir64: {
if (Triple.getOS() != llvm::Triple::UnknownOS ||
Triple.getEnvironment() != llvm::Triple::UnknownEnvironment)
return nullptr;
if (Triple.getEnvironment() == llvm::Triple::SYCLDevice) {
switch (os) {
case llvm::Triple::Linux:
return new LinuxTargetInfo<SPIR64SYCLDeviceTargetInfo>(Triple, Opts);
default:
return new SPIR64SYCLDeviceTargetInfo(Triple, Opts);
}
}
return new SPIR64TargetInfo(Triple, Opts);
}

case llvm::Triple::wasm32:
if (Triple.getSubArch() != llvm::Triple::NoSubArch ||
Triple.getVendor() != llvm::Triple::UnknownVendor ||
Expand Down
60 changes: 55 additions & 5 deletions clang/lib/Basic/Targets/SPIR.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,18 +36,31 @@ static const unsigned SPIRAddrSpaceMap[] = {
0 // ptr64
};

static const unsigned SYCLAddrSpaceMap[] = {
4, // Default
1, // opencl_global
3, // opencl_local
2, // opencl_constant
0, // opencl_private
4, // opencl_generic
0, // cuda_device
0, // cuda_constant
0, // cuda_shared
0, // ptr32_sptr
0, // ptr32_uptr
0 // ptr64
};

class LLVM_LIBRARY_VISIBILITY SPIRTargetInfo : public TargetInfo {
public:
SPIRTargetInfo(const llvm::Triple &Triple, const TargetOptions &)
: TargetInfo(Triple) {
assert(getTriple().getOS() == llvm::Triple::UnknownOS &&
"SPIR target must use unknown OS");
assert(getTriple().getEnvironment() == llvm::Triple::UnknownEnvironment &&
"SPIR target must use unknown environment type");
TLSSupported = false;
VLASupported = false;
LongWidth = LongAlign = 64;
AddrSpaceMap = &SPIRAddrSpaceMap;
AddrSpaceMap = (Triple.getEnvironment() == llvm::Triple::SYCLDevice)
? &SYCLAddrSpaceMap
: &SPIRAddrSpaceMap;
UseAddrSpaceMapMangling = true;
HasLegalHalfType = true;
HasFloat16 = true;
Expand Down Expand Up @@ -132,6 +145,43 @@ class LLVM_LIBRARY_VISIBILITY SPIR64TargetInfo : public SPIRTargetInfo {
void getTargetDefines(const LangOptions &Opts,
MacroBuilder &Builder) const override;
};

class LLVM_LIBRARY_VISIBILITY SPIR32SYCLDeviceTargetInfo
: public SPIR32TargetInfo {
public:
SPIR32SYCLDeviceTargetInfo(const llvm::Triple &Triple,
const TargetOptions &Opts)
: SPIR32TargetInfo(Triple, Opts) {
// This is workaround for exception_ptr class.
// Exceptions is not allowed in sycl device code but we should be able
// to parse host code. So we allow compilation of exception_ptr but
// if exceptions are used in device code we should emit a diagnostic.
MaxAtomicInlineWidth = 32;
// This is workaround for mutex class.
// I'm not sure about this hack but I guess that mutex_class is same
// problem.
TLSSupported = true;
}
};

class LLVM_LIBRARY_VISIBILITY SPIR64SYCLDeviceTargetInfo
: public SPIR64TargetInfo {
public:
SPIR64SYCLDeviceTargetInfo(const llvm::Triple &Triple,
const TargetOptions &Opts)
: SPIR64TargetInfo(Triple, Opts) {
// This is workaround for exception_ptr class.
// Exceptions is not allowed in sycl device code but we should be able
// to parse host code. So we allow compilation of exception_ptr but
// if exceptions are used in device code we should emit a diagnostic.
MaxAtomicInlineWidth = 64;
// This is workaround for mutex class.
// I'm not sure about this hack but I guess that mutex_class is same
// problem.
TLSSupported = true;
}
};

} // namespace targets
} // namespace clang
#endif // LLVM_CLANG_LIB_BASIC_TARGETS_SPIR_H
25 changes: 25 additions & 0 deletions clang/lib/CodeGen/CGCall.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4558,6 +4558,17 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
V->getType()->isIntegerTy())
V = Builder.CreateZExt(V, ArgInfo.getCoerceToType());

if (FirstIRArg < IRFuncTy->getNumParams()) {
const auto *LHSPtrTy =
dyn_cast_or_null<llvm::PointerType>(V->getType());
const auto *RHSPtrTy = dyn_cast_or_null<llvm::PointerType>(
IRFuncTy->getParamType(FirstIRArg));
if (LHSPtrTy && RHSPtrTy &&
LHSPtrTy->getAddressSpace() != RHSPtrTy->getAddressSpace())
V = Builder.CreateAddrSpaceCast(V,
IRFuncTy->getParamType(FirstIRArg));
}

// If the argument doesn't match, perform a bitcast to coerce it. This
// can happen due to trivial type mismatches.
if (FirstIRArg < IRFuncTy->getNumParams() &&
Expand Down Expand Up @@ -4784,6 +4795,20 @@ RValue CodeGenFunction::EmitCall(const CGFunctionInfo &CallInfo,
if (!CallArgs.getCleanupsToDeactivate().empty())
deactivateArgCleanupsBeforeCall(*this, CallArgs);

// Addrspace cast to generic if necessary
for (unsigned i = 0; i < IRFuncTy->getNumParams(); ++i) {
if (auto *PtrTy = dyn_cast<llvm::PointerType>(IRCallArgs[i]->getType())) {
auto *ExpectedPtrType =
cast<llvm::PointerType>(IRFuncTy->getParamType(i));
unsigned ValueAS = PtrTy->getAddressSpace();
unsigned ExpectedAS = ExpectedPtrType->getAddressSpace();
if (ValueAS != ExpectedAS) {
IRCallArgs[i] = Builder.CreatePointerBitCastOrAddrSpaceCast(
IRCallArgs[i], ExpectedPtrType);
}
}
}

// Assert that the arguments we computed match up. The IR verifier
// will catch this, but this is a common enough source of problems
// during IRGen changes that it's way better for debugging to catch
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CGClass.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -336,7 +336,7 @@ Address CodeGenFunction::GetAddressOfBaseClass(
EmitTypeCheck(TCK_Upcast, Loc, Value.getPointer(),
DerivedTy, DerivedAlign, SkippedChecks);
}
return Builder.CreateBitCast(Value, BasePtrTy);
return Builder.CreatePointerBitCastOrAddrSpaceCast(Value, BasePtrTy);
}

llvm::BasicBlock *origBB = nullptr;
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CGDecl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ CodeGenFunction::AddInitializerToStaticVarDecl(const VarDecl &D,
OldGV->getLinkage(), Init, "",
/*InsertBefore*/ OldGV,
OldGV->getThreadLocalMode(),
CGM.getContext().getTargetAddressSpace(D.getType()));
OldGV->getType()->getPointerAddressSpace());
GV->setVisibility(OldGV->getVisibility());
GV->setDSOLocal(OldGV->isDSOLocal());
GV->setComdat(OldGV->getComdat());
Expand Down
18 changes: 11 additions & 7 deletions clang/lib/CodeGen/CGDeclCXX.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -27,10 +27,12 @@ using namespace CodeGen;

static void EmitDeclInit(CodeGenFunction &CGF, const VarDecl &D,
ConstantAddress DeclPtr) {
assert(
(D.hasGlobalStorage() ||
(D.hasLocalStorage() && CGF.getContext().getLangOpts().OpenCLCPlusPlus)) &&
"VarDecl must have global or local (in the case of OpenCL) storage!");
assert((D.hasGlobalStorage() ||
(D.hasLocalStorage() &&
(CGF.getContext().getLangOpts().OpenCLCPlusPlus ||
CGF.getContext().getLangOpts().SYCLIsDevice))) &&
"VarDecl must have global or local (in the case of OpenCL and SYCL) "
"storage!");
assert(!D.getType()->isReferenceType() &&
"Should not call EmitDeclInit on a reference!");

Expand Down Expand Up @@ -161,13 +163,15 @@ void CodeGenFunction::EmitInvariantStart(llvm::Constant *Addr, CharUnits Size) {
// Grab the llvm.invariant.start intrinsic.
llvm::Intrinsic::ID InvStartID = llvm::Intrinsic::invariant_start;
// Overloaded address space type.
llvm::Type *ObjectPtr[1] = {Int8PtrTy};
llvm::Type *ResTy = llvm::PointerType::getInt8PtrTy(
CGM.getLLVMContext(), Addr->getType()->getPointerAddressSpace());
llvm::Type *ObjectPtr[1] = {ResTy};
llvm::Function *InvariantStart = CGM.getIntrinsic(InvStartID, ObjectPtr);

// Emit a call with the size in bytes of the object.
uint64_t Width = Size.getQuantity();
llvm::Value *Args[2] = { llvm::ConstantInt::getSigned(Int64Ty, Width),
llvm::ConstantExpr::getBitCast(Addr, Int8PtrTy)};
llvm::Value *Args[2] = {llvm::ConstantInt::getSigned(Int64Ty, Width),
llvm::ConstantExpr::getBitCast(Addr, ResTy)};
Builder.CreateCall(InvariantStart, Args);
}

Expand Down
16 changes: 12 additions & 4 deletions clang/lib/CodeGen/CGExpr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1118,10 +1118,8 @@ Address CodeGenFunction::EmitPointerWithAlignment(const Expr *E,
CodeGenFunction::CFITCK_UnrelatedCast,
CE->getBeginLoc());
}
return CE->getCastKind() != CK_AddressSpaceConversion
? Builder.CreateBitCast(Addr, ConvertType(E->getType()))
: Builder.CreateAddrSpaceCast(Addr,
ConvertType(E->getType()));
return Builder.CreatePointerBitCastOrAddrSpaceCast(
Addr, ConvertType(E->getType()));
}
break;

Expand Down Expand Up @@ -1813,6 +1811,16 @@ void CodeGenFunction::EmitStoreOfScalar(llvm::Value *Value, Address Addr,
return;
}

if (auto *PtrTy = dyn_cast<llvm::PointerType>(Value->getType())) {
auto *ExpectedPtrType =
cast<llvm::PointerType>(Addr.getType()->getElementType());
unsigned ValueAS = PtrTy->getAddressSpace();
unsigned ExpectedAS = ExpectedPtrType->getAddressSpace();
if (ValueAS != ExpectedAS) {
Value =
Builder.CreatePointerBitCastOrAddrSpaceCast(Value, ExpectedPtrType);
}
}
llvm::StoreInst *Store = Builder.CreateStore(Value, Addr, Volatile);
if (isNontemporal) {
llvm::MDNode *Node =
Expand Down
Loading