Skip to content

Commit

Permalink
[SYCL] Emit OpenCL/SPIR metadata and calling convention for SYCL
Browse files Browse the repository at this point in the history
device code.

Signed-off-by: Vladimir Lazarev <[email protected]>
  • Loading branch information
vladimirlaz committed Jan 22, 2019
1 parent 1e60aa6 commit f1a7138
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 3 deletions.
2 changes: 1 addition & 1 deletion clang/lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -9933,7 +9933,7 @@ void ASTContext::forEachMultiversionedFunctionVersion(
CallingConv ASTContext::getDefaultCallingConvention(bool IsVariadic,
bool IsCXXMethod) const {
// Pass through to the C++ ABI object
if (IsCXXMethod)
if (IsCXXMethod && !LangOpts.SYCL)
return ABI->getDefaultMethodCallConv(IsVariadic);

switch (LangOpts.getDefaultCallingConv()) {
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CodeGenFunction.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -945,7 +945,7 @@ void CodeGenFunction::StartFunction(GlobalDecl GD,
if (CGM.getCodeGenOpts().ProfileSampleAccurate)
Fn->addFnAttr("profile-sample-accurate");

if (getLangOpts().OpenCL) {
if (getLangOpts().OpenCL || getLangOpts().SYCL) {
// Add metadata for a kernel function.
if (const FunctionDecl *FD = dyn_cast_or_null<FunctionDecl>(D))
EmitOpenCLKernelMetadata(FD, Fn);
Expand Down
17 changes: 17 additions & 0 deletions clang/lib/CodeGen/CodeGenModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -552,6 +552,23 @@ void CodeGenModule::Release() {
}
}

// Emit SYCL specific module metadata: OpenCL/SPIR version.
if (LangOpts.SYCL) {
llvm::Metadata *OCLVerElts[] = {
llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(Int32Ty, 1)),
llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(Int32Ty, 2))};
llvm::NamedMDNode *OCLVerMD =
TheModule.getOrInsertNamedMetadata("opencl.ocl.version");
llvm::LLVMContext &Ctx = TheModule.getContext();
OCLVerMD->addOperand(llvm::MDNode::get(Ctx, OCLVerElts));
llvm::Metadata *SPIRVerElts[] = {
llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(Int32Ty, 1)),
llvm::ConstantAsMetadata::get(llvm::ConstantInt::get(Int32Ty, 2))};
llvm::NamedMDNode *SPIRVerMD =
TheModule.getOrInsertNamedMetadata("opencl.spir.version");
SPIRVerMD->addOperand(llvm::MDNode::get(Ctx, SPIRVerElts));
}

if (uint32_t PLevel = Context.getLangOpts().PICLevel) {
assert(PLevel < 3 && "Invalid PIC Level");
getModule().setPICLevel(static_cast<llvm::PICLevel::Level>(PLevel));
Expand Down
3 changes: 2 additions & 1 deletion clang/lib/Sema/SemaSYCL.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ FunctionDecl *CreateSYCLKernelFunction(ASTContext &Context, StringRef Name,
ArrayRef<DeclaratorDecl *> ArgDecls) {

DeclContext *DC = Context.getTranslationUnitDecl();
FunctionProtoType::ExtProtoInfo Info;
FunctionProtoType::ExtProtoInfo Info(CC_OpenCLKernel);
QualType RetTy = Context.VoidTy;
QualType FuncTy = Context.getFunctionType(RetTy, ArgTys, Info);
DeclarationName DN = DeclarationName(&Context.Idents.get(Name));
Expand Down Expand Up @@ -161,6 +161,7 @@ void BuildArgTys(ASTContext &Context,
if (TemplateDecl) {
QualType PointeeType = TemplateDecl->getTemplateArgs()[0].getAsType();
Qualifiers Quals = PointeeType.getQualifiers();
// TODO: get address space from accessor template parameter.
Quals.setAddressSpace(LangAS::opencl_global);
PointeeType =
Context.getQualifiedType(PointeeType.getUnqualifiedType(), Quals);
Expand Down
23 changes: 23 additions & 0 deletions clang/test/CodeGenSYCL/kernel-metadata.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
// RUN: %clang -cc1 -triple spir64-unknown-linux-sycldevice -std=c++11 -fsycl-is-device -S -I /sycl_include_path -I /opencl_include_path -I /usr/include/c++/4.8.5 -I /usr/include/c++/4.8.5/x86_64-redhat-linux -I /usr/include/c++/4.8.5/backward -I /include -I /usr/include -fcxx-exceptions -fexceptions -emit-llvm -x c++ %s -o - | FileCheck %s

// CHECK: define {{.*}}spir_kernel void @kernel_function() {{[^{]+}} !kernel_arg_addr_space ![[MD:[0-9]+]] !kernel_arg_access_qual ![[MD]] !kernel_arg_type ![[MD]] !kernel_arg_base_type ![[MD]] !kernel_arg_type_qual ![[MD]] {
// CHECK: ![[MD]] = !{}
// XFAIL: *

#include <CL/sycl.hpp>


using namespace cl::sycl;

int main() {

queue myQueue;

myQueue.submit([&](handler &cgh) {

cgh.single_task<class kernel_function>([=]() {
});
});

myQueue.wait();
}
27 changes: 27 additions & 0 deletions clang/test/CodeGenSYCL/spir-calling-conv.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
// RUN: %clang -cc1 -triple spir64-unknown-linux-sycldevice -std=c++11 -fsycl-is-device -S -I /sycl_include_path -I /opencl_include_path -I /usr/include/c++/4.8.5 -I /usr/include/c++/4.8.5/x86_64-redhat-linux -I /usr/include/c++/4.8.5/backward -I /include -I /usr/include -fcxx-exceptions -fexceptions -emit-llvm -x c++ %s -o - | FileCheck %s

// XFAIL: *

#include <CL/sycl.hpp>


using namespace cl::sycl;

int main() {

queue myQueue;

myQueue.submit([&](handler &cgh) {

// CHECK: define spir_kernel void @kernel_function()

// CHECK: call spir_func void @"_ZZZ4mainENK3$_0clERN2cl4sycl7handlerEENKUlvE_clEv"(%class.anon* %0)

// CHECK: define internal spir_func void @"_ZZZ4mainENK3$_0clERN2cl4sycl7handlerEENKUlvE_clEv"(%class.anon* %this)

cgh.single_task<class kernel_function>([=]() {
});
});

myQueue.wait();
}
25 changes: 25 additions & 0 deletions clang/test/CodeGenSYCL/spir-opencl-version.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
// RUN: %clang -cc1 -triple spir64-unknown-linux-sycldevice -std=c++11 -fsycl-is-device -S -I /sycl_include_path -I /opencl_include_path -I /usr/include/c++/4.8.5 -I /usr/include/c++/4.8.5/x86_64-redhat-linux -I /usr/include/c++/4.8.5/backward -I /include -I /usr/include -fcxx-exceptions -fexceptions -emit-llvm -x c++ %s -o - | FileCheck %s

// XFAIL: *

#include <CL/sycl.hpp>

using namespace cl::sycl;

int main() {

queue myQueue;

myQueue.submit([&](handler &cgh) {

cgh.single_task<class kernel_function>([=]() {
});
});

myQueue.wait();
}


// CHECK: !opencl.ocl.version = !{[[VER:![0-9]+]]}
// CHECK: !opencl.spir.version = !{[[VER]]}
// CHECK: [[VER]] = !{i32 1, i32 2}

0 comments on commit f1a7138

Please sign in to comment.