mirror of
git://git.yoctoproject.org/meta-intel.git
synced 2025-07-19 21:09:03 +02:00
clang: build Intel common-clang and spirv
Common clang is a thin wrapper library around clang. Common clang has OpenCL-oriented API and is capable to compile OpenCL C kernels to SPIR-V modules. This adds a bbappend to clang recipe from meta-clang to build the necessary components and moves it to dynamic layers so it's built only when clang-layer is included. Signed-off-by: Anuj Mittal <anuj.mittal@intel.com>
This commit is contained in:
parent
613bc1ffc3
commit
a12a2f0346
|
@ -20,5 +20,9 @@ LAYERRECOMMENDS_intel = "dpdk intel-qat"
|
||||||
LAYERVERSION_intel = "5"
|
LAYERVERSION_intel = "5"
|
||||||
LAYERSERIES_COMPAT_intel = "thud warrior"
|
LAYERSERIES_COMPAT_intel = "thud warrior"
|
||||||
|
|
||||||
|
BBFILES_DYNAMIC += " \
|
||||||
|
clang-layer:${LAYERDIR}/dynamic-layers/clang-layer/*/*/*.bb \
|
||||||
|
clang-layer:${LAYERDIR}/dynamic-layers/clang-layer/*/*/*.bbappend \
|
||||||
|
"
|
||||||
|
|
||||||
require ${LAYERDIR}/conf/include/maintainers.inc
|
require ${LAYERDIR}/conf/include/maintainers.inc
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
FILESEXTRAPATHS_prepend_intel-x86-common := "${THISDIR}/files:"
|
||||||
|
|
||||||
|
DEPENDS_append = " opencl-clang-native"
|
||||||
|
LLVM_TARGETS_TO_BUILD = "X86"
|
||||||
|
|
||||||
|
do_install_append_intel-x86-common() {
|
||||||
|
DESTDIR=${D} ninja -v install-cmake-exports
|
||||||
|
}
|
||||||
|
|
||||||
|
LIBCPLUSPLUS = ""
|
||||||
|
|
||||||
|
# undefined reference to `__atomic_load' on i*86.
|
||||||
|
COMPATIBLE_HOST = '(x86_64).*-linux'
|
|
@ -0,0 +1,156 @@
|
||||||
|
From 39a3ac0065c23d1e2d55dfd8792cc28a146a4307 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Alexey Bader <alexey.bader@intel.com>
|
||||||
|
Date: Tue, 19 Feb 2019 15:19:06 +0000
|
||||||
|
Subject: [PATCH 1/2] [OpenCL] Change type of block pointer for OpenCL
|
||||||
|
|
||||||
|
Summary:
|
||||||
|
|
||||||
|
For some reason OpenCL blocks in LLVM IR are represented as function pointers.
|
||||||
|
These pointers do not point to any real function and never get called. Actually
|
||||||
|
they point to some structure, which in turn contains pointer to the real block
|
||||||
|
invoke function.
|
||||||
|
This patch changes represntation of OpenCL blocks in LLVM IR from function
|
||||||
|
pointers to pointers to `%struct.__block_literal_generic`.
|
||||||
|
Such representation allows to avoid unnecessary bitcasts and simplifies
|
||||||
|
further processing (e.g. translation to SPIR-V ) of the module for targets
|
||||||
|
which do not support function pointers.
|
||||||
|
|
||||||
|
Patch by: Alexey Sotkin.
|
||||||
|
|
||||||
|
Reviewers: Anastasia, yaxunl, svenvh
|
||||||
|
|
||||||
|
Reviewed By: Anastasia
|
||||||
|
|
||||||
|
Subscribers: alexbatashev, cfe-commits
|
||||||
|
|
||||||
|
Tags: #clang
|
||||||
|
|
||||||
|
Differential Revision: https://reviews.llvm.org/D58277
|
||||||
|
|
||||||
|
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@354337 91177308-0d34-0410-b5e6-96231b3b80d8
|
||||||
|
|
||||||
|
Upstream-Status: Backport
|
||||||
|
[https://github.com/llvm-mirror/clang/commit/283f308bdb5893bab1f36791711346e746045f94]
|
||||||
|
Signed-off-by: Anuj Mittal <anuj.mittal@intel.com>
|
||||||
|
---
|
||||||
|
lib/CodeGen/CodeGenTypes.cpp | 4 +++-
|
||||||
|
test/CodeGenOpenCL/blocks.cl | 18 ++++++++----------
|
||||||
|
test/CodeGenOpenCL/cl20-device-side-enqueue.cl | 18 +++++++++---------
|
||||||
|
3 files changed, 20 insertions(+), 20 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp
|
||||||
|
index 2acf1ac..93b3ebf 100644
|
||||||
|
--- a/lib/CodeGen/CodeGenTypes.cpp
|
||||||
|
+++ b/lib/CodeGen/CodeGenTypes.cpp
|
||||||
|
@@ -637,7 +637,9 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
|
||||||
|
|
||||||
|
case Type::BlockPointer: {
|
||||||
|
const QualType FTy = cast<BlockPointerType>(Ty)->getPointeeType();
|
||||||
|
- llvm::Type *PointeeType = ConvertTypeForMem(FTy);
|
||||||
|
+ llvm::Type *PointeeType = CGM.getLangOpts().OpenCL
|
||||||
|
+ ? CGM.getGenericBlockLiteralType()
|
||||||
|
+ : ConvertTypeForMem(FTy);
|
||||||
|
unsigned AS = Context.getTargetAddressSpace(FTy);
|
||||||
|
ResultType = llvm::PointerType::get(PointeeType, AS);
|
||||||
|
break;
|
||||||
|
diff --git a/test/CodeGenOpenCL/blocks.cl b/test/CodeGenOpenCL/blocks.cl
|
||||||
|
index 675240c..19aacc3 100644
|
||||||
|
--- a/test/CodeGenOpenCL/blocks.cl
|
||||||
|
+++ b/test/CodeGenOpenCL/blocks.cl
|
||||||
|
@@ -35,11 +35,10 @@ void foo(){
|
||||||
|
// SPIR: %[[block_captured:.*]] = getelementptr inbounds <{ i32, i32, i8 addrspace(4)*, i32 }>, <{ i32, i32, i8 addrspace(4)*, i32 }>* %[[block]], i32 0, i32 3
|
||||||
|
// SPIR: %[[i_value:.*]] = load i32, i32* %i
|
||||||
|
// SPIR: store i32 %[[i_value]], i32* %[[block_captured]],
|
||||||
|
- // SPIR: %[[blk_ptr:.*]] = bitcast <{ i32, i32, i8 addrspace(4)*, i32 }>* %[[block]] to i32 ()*
|
||||||
|
- // SPIR: %[[blk_gen_ptr:.*]] = addrspacecast i32 ()* %[[blk_ptr]] to i32 () addrspace(4)*
|
||||||
|
- // SPIR: store i32 () addrspace(4)* %[[blk_gen_ptr]], i32 () addrspace(4)** %[[block_B:.*]],
|
||||||
|
- // SPIR: %[[blk_gen_ptr:.*]] = load i32 () addrspace(4)*, i32 () addrspace(4)** %[[block_B]]
|
||||||
|
- // SPIR: %[[block_literal:.*]] = bitcast i32 () addrspace(4)* %[[blk_gen_ptr]] to %struct.__opencl_block_literal_generic addrspace(4)*
|
||||||
|
+ // SPIR: %[[blk_ptr:.*]] = bitcast <{ i32, i32, i8 addrspace(4)*, i32 }>* %[[block]] to %struct.__opencl_block_literal_generic*
|
||||||
|
+ // SPIR: %[[blk_gen_ptr:.*]] = addrspacecast %struct.__opencl_block_literal_generic* %[[blk_ptr]] to %struct.__opencl_block_literal_generic addrspace(4)*
|
||||||
|
+ // SPIR: store %struct.__opencl_block_literal_generic addrspace(4)* %[[blk_gen_ptr]], %struct.__opencl_block_literal_generic addrspace(4)** %[[block_B:.*]],
|
||||||
|
+ // SPIR: %[[block_literal:.*]] = load %struct.__opencl_block_literal_generic addrspace(4)*, %struct.__opencl_block_literal_generic addrspace(4)** %[[block_B]]
|
||||||
|
// SPIR: %[[invoke_addr:.*]] = getelementptr inbounds %struct.__opencl_block_literal_generic, %struct.__opencl_block_literal_generic addrspace(4)* %[[block_literal]], i32 0, i32 2
|
||||||
|
// SPIR: %[[blk_gen_ptr:.*]] = bitcast %struct.__opencl_block_literal_generic addrspace(4)* %[[block_literal]] to i8 addrspace(4)*
|
||||||
|
// SPIR: %[[invoke_func_ptr:.*]] = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %[[invoke_addr]]
|
||||||
|
@@ -50,11 +49,10 @@ void foo(){
|
||||||
|
// AMDGCN: %[[block_captured:.*]] = getelementptr inbounds <{ i32, i32, i8*, i32 }>, <{ i32, i32, i8*, i32 }> addrspace(5)* %[[block]], i32 0, i32 3
|
||||||
|
// AMDGCN: %[[i_value:.*]] = load i32, i32 addrspace(5)* %i
|
||||||
|
// AMDGCN: store i32 %[[i_value]], i32 addrspace(5)* %[[block_captured]],
|
||||||
|
- // AMDGCN: %[[blk_ptr:.*]] = bitcast <{ i32, i32, i8*, i32 }> addrspace(5)* %[[block]] to i32 () addrspace(5)*
|
||||||
|
- // AMDGCN: %[[blk_gen_ptr:.*]] = addrspacecast i32 () addrspace(5)* %[[blk_ptr]] to i32 ()*
|
||||||
|
- // AMDGCN: store i32 ()* %[[blk_gen_ptr]], i32 ()* addrspace(5)* %[[block_B:.*]],
|
||||||
|
- // AMDGCN: %[[blk_gen_ptr:.*]] = load i32 ()*, i32 ()* addrspace(5)* %[[block_B]]
|
||||||
|
- // AMDGCN: %[[block_literal:.*]] = bitcast i32 ()* %[[blk_gen_ptr]] to %struct.__opencl_block_literal_generic*
|
||||||
|
+ // AMDGCN: %[[blk_ptr:.*]] = bitcast <{ i32, i32, i8*, i32 }> addrspace(5)* %[[block]] to %struct.__opencl_block_literal_generic addrspace(5)*
|
||||||
|
+ // AMDGCN: %[[blk_gen_ptr:.*]] = addrspacecast %struct.__opencl_block_literal_generic addrspace(5)* %[[blk_ptr]] to %struct.__opencl_block_literal_generic*
|
||||||
|
+ // AMDGCN: store %struct.__opencl_block_literal_generic* %[[blk_gen_ptr]], %struct.__opencl_block_literal_generic* addrspace(5)* %[[block_B:.*]],
|
||||||
|
+ // AMDGCN: %[[block_literal:.*]] = load %struct.__opencl_block_literal_generic*, %struct.__opencl_block_literal_generic* addrspace(5)* %[[block_B]]
|
||||||
|
// AMDGCN: %[[invoke_addr:.*]] = getelementptr inbounds %struct.__opencl_block_literal_generic, %struct.__opencl_block_literal_generic* %[[block_literal]], i32 0, i32 2
|
||||||
|
// AMDGCN: %[[blk_gen_ptr:.*]] = bitcast %struct.__opencl_block_literal_generic* %[[block_literal]] to i8*
|
||||||
|
// AMDGCN: %[[invoke_func_ptr:.*]] = load i8*, i8** %[[invoke_addr]]
|
||||||
|
diff --git a/test/CodeGenOpenCL/cl20-device-side-enqueue.cl b/test/CodeGenOpenCL/cl20-device-side-enqueue.cl
|
||||||
|
index 4732194..8445016 100644
|
||||||
|
--- a/test/CodeGenOpenCL/cl20-device-side-enqueue.cl
|
||||||
|
+++ b/test/CodeGenOpenCL/cl20-device-side-enqueue.cl
|
||||||
|
@@ -11,7 +11,7 @@ typedef struct {int a;} ndrange_t;
|
||||||
|
|
||||||
|
// For a block global variable, first emit the block literal as a global variable, then emit the block variable itself.
|
||||||
|
// COMMON: [[BL_GLOBAL:@__block_literal_global[^ ]*]] = internal addrspace(1) constant { i32, i32, i8 addrspace(4)* } { i32 {{[0-9]+}}, i32 {{[0-9]+}}, i8 addrspace(4)* addrspacecast (i8* bitcast (void (i8 addrspace(4)*, i8 addrspace(3)*)* [[INV_G:@[^ ]+]] to i8*) to i8 addrspace(4)*) }
|
||||||
|
-// COMMON: @block_G = addrspace(1) constant void (i8 addrspace(3)*) addrspace(4)* addrspacecast (void (i8 addrspace(3)*) addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BL_GLOBAL]] to void (i8 addrspace(3)*) addrspace(1)*) to void (i8 addrspace(3)*) addrspace(4)*)
|
||||||
|
+// COMMON: @block_G = addrspace(1) constant %struct.__opencl_block_literal_generic addrspace(4)* addrspacecast (%struct.__opencl_block_literal_generic addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BL_GLOBAL]] to %struct.__opencl_block_literal_generic addrspace(1)*) to %struct.__opencl_block_literal_generic addrspace(4)*)
|
||||||
|
|
||||||
|
// For anonymous blocks without captures, emit block literals as global variable.
|
||||||
|
// COMMON: [[BLG1:@__block_literal_global[^ ]*]] = internal addrspace(1) constant { i32, i32, i8 addrspace(4)* } { i32 {{[0-9]+}}, i32 {{[0-9]+}}, i8 addrspace(4)* addrspacecast (i8* bitcast (void (i8 addrspace(4)*, i8 addrspace(3)*)* {{@[^ ]+}} to i8*) to i8 addrspace(4)*) }
|
||||||
|
@@ -77,9 +77,9 @@ kernel void device_side_enqueue(global int *a, global int *b, int i) {
|
||||||
|
// COMMON: [[DEF_Q:%[0-9]+]] = load %opencl.queue_t{{.*}}*, %opencl.queue_t{{.*}}** %default_queue
|
||||||
|
// COMMON: [[FLAGS:%[0-9]+]] = load i32, i32* %flags
|
||||||
|
// COMMON: store i8 addrspace(4)* addrspacecast (i8* bitcast (void (i8 addrspace(4)*)* [[INVL1:@__device_side_enqueue_block_invoke[^ ]*]] to i8*) to i8 addrspace(4)*), i8 addrspace(4)** %block.invoke
|
||||||
|
- // B32: [[BL:%[0-9]+]] = bitcast <{ i32, i32, i8 addrspace(4)*, i32 addrspace(1)*, i32, i32 addrspace(1)* }>* %block to void ()*
|
||||||
|
- // B64: [[BL:%[0-9]+]] = bitcast <{ i32, i32, i8 addrspace(4)*, i32 addrspace(1)*, i32 addrspace(1)*, i32 }>* %block to void ()*
|
||||||
|
- // COMMON: [[BL_I8:%[0-9]+]] = addrspacecast void ()* [[BL]] to i8 addrspace(4)*
|
||||||
|
+ // B32: [[BL:%[0-9]+]] = bitcast <{ i32, i32, i8 addrspace(4)*, i32 addrspace(1)*, i32, i32 addrspace(1)* }>* %block to %struct.__opencl_block_literal_generic*
|
||||||
|
+ // B64: [[BL:%[0-9]+]] = bitcast <{ i32, i32, i8 addrspace(4)*, i32 addrspace(1)*, i32 addrspace(1)*, i32 }>* %block to %struct.__opencl_block_literal_generic*
|
||||||
|
+ // COMMON: [[BL_I8:%[0-9]+]] = addrspacecast %struct.__opencl_block_literal_generic* [[BL]] to i8 addrspace(4)*
|
||||||
|
// COMMON-LABEL: call i32 @__enqueue_kernel_basic(
|
||||||
|
// COMMON-SAME: %opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %struct.ndrange_t* byval [[NDR]]{{([0-9]+)?}},
|
||||||
|
// COMMON-SAME: i8 addrspace(4)* addrspacecast (i8* bitcast ({{.*}} [[INVLK1:[^ ]+_kernel]] to i8*) to i8 addrspace(4)*),
|
||||||
|
@@ -95,8 +95,8 @@ kernel void device_side_enqueue(global int *a, global int *b, int i) {
|
||||||
|
// COMMON: [[WAIT_EVNT:%[0-9]+]] = addrspacecast %opencl.clk_event_t{{.*}}** %event_wait_list to %opencl.clk_event_t{{.*}}* addrspace(4)*
|
||||||
|
// COMMON: [[EVNT:%[0-9]+]] = addrspacecast %opencl.clk_event_t{{.*}}** %clk_event to %opencl.clk_event_t{{.*}}* addrspace(4)*
|
||||||
|
// COMMON: store i8 addrspace(4)* addrspacecast (i8* bitcast (void (i8 addrspace(4)*)* [[INVL2:@__device_side_enqueue_block_invoke[^ ]*]] to i8*) to i8 addrspace(4)*), i8 addrspace(4)** %block.invoke
|
||||||
|
- // COMMON: [[BL:%[0-9]+]] = bitcast <{ i32, i32, i8 addrspace(4)*, i32{{.*}}, i32{{.*}}, i32{{.*}} }>* %block3 to void ()*
|
||||||
|
- // COMMON: [[BL_I8:%[0-9]+]] = addrspacecast void ()* [[BL]] to i8 addrspace(4)*
|
||||||
|
+ // COMMON: [[BL:%[0-9]+]] = bitcast <{ i32, i32, i8 addrspace(4)*, i32{{.*}}, i32{{.*}}, i32{{.*}} }>* %block3 to %struct.__opencl_block_literal_generic*
|
||||||
|
+ // COMMON: [[BL_I8:%[0-9]+]] = addrspacecast %struct.__opencl_block_literal_generic* [[BL]] to i8 addrspace(4)*
|
||||||
|
// COMMON-LABEL: call i32 @__enqueue_kernel_basic_events
|
||||||
|
// COMMON-SAME: (%opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %struct.ndrange_t* {{.*}}, i32 2, %opencl.clk_event_t{{.*}}* addrspace(4)* [[WAIT_EVNT]], %opencl.clk_event_t{{.*}}* addrspace(4)* [[EVNT]],
|
||||||
|
// COMMON-SAME: i8 addrspace(4)* addrspacecast (i8* bitcast ({{.*}} [[INVLK2:[^ ]+_kernel]] to i8*) to i8 addrspace(4)*),
|
||||||
|
@@ -300,13 +300,13 @@ kernel void device_side_enqueue(global int *a, global int *b, int i) {
|
||||||
|
// Emits global block literal [[BLG8]] and invoke function [[INVG8]].
|
||||||
|
// The full type of these expressions are long (and repeated elsewhere), so we
|
||||||
|
// capture it as part of the regex for convenience and clarity.
|
||||||
|
- // COMMON: store void () addrspace(4)* addrspacecast (void () addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BLG8]] to void () addrspace(1)*) to void () addrspace(4)*), void () addrspace(4)** %block_A
|
||||||
|
+ // COMMON: store %struct.__opencl_block_literal_generic addrspace(4)* addrspacecast (%struct.__opencl_block_literal_generic addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BLG8]] to %struct.__opencl_block_literal_generic addrspace(1)*) to %struct.__opencl_block_literal_generic addrspace(4)*), %struct.__opencl_block_literal_generic addrspace(4)** %block_A
|
||||||
|
void (^const block_A)(void) = ^{
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
// Emits global block literal [[BLG9]] and invoke function [[INVG9]].
|
||||||
|
- // COMMON: store void (i8 addrspace(3)*) addrspace(4)* addrspacecast (void (i8 addrspace(3)*) addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BLG9]] to void (i8 addrspace(3)*) addrspace(1)*) to void (i8 addrspace(3)*) addrspace(4)*), void (i8 addrspace(3)*) addrspace(4)** %block_B
|
||||||
|
+ // COMMON: store %struct.__opencl_block_literal_generic addrspace(4)* addrspacecast (%struct.__opencl_block_literal_generic addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BLG9]] to %struct.__opencl_block_literal_generic addrspace(1)*) to %struct.__opencl_block_literal_generic addrspace(4)*), %struct.__opencl_block_literal_generic addrspace(4)** %block_B
|
||||||
|
void (^const block_B)(local void *) = ^(local void *a) {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
@@ -346,7 +346,7 @@ kernel void device_side_enqueue(global int *a, global int *b, int i) {
|
||||||
|
// COMMON: store i8 addrspace(4)* addrspacecast (i8* bitcast (void (i8 addrspace(4)*)* [[INVL3:@__device_side_enqueue_block_invoke[^ ]*]] to i8*) to i8 addrspace(4)*), i8 addrspace(4)** %block.invoke
|
||||||
|
// COMMON: [[DEF_Q:%[0-9]+]] = load %opencl.queue_t{{.*}}*, %opencl.queue_t{{.*}}** %default_queue
|
||||||
|
// COMMON: [[FLAGS:%[0-9]+]] = load i32, i32* %flags
|
||||||
|
- // COMMON: [[BL_I8:%[0-9]+]] = addrspacecast void ()* {{.*}} to i8 addrspace(4)*
|
||||||
|
+ // COMMON: [[BL_I8:%[0-9]+]] = addrspacecast %struct.__opencl_block_literal_generic* {{.*}} to i8 addrspace(4)*
|
||||||
|
// COMMON-LABEL: call i32 @__enqueue_kernel_basic(
|
||||||
|
// COMMON-SAME: %opencl.queue_t{{.*}}* [[DEF_Q]], i32 [[FLAGS]], %struct.ndrange_t* byval [[NDR]]{{([0-9]+)?}},
|
||||||
|
// COMMON-SAME: i8 addrspace(4)* addrspacecast (i8* bitcast ({{.*}} [[INVLK3:[^ ]+_kernel]] to i8*) to i8 addrspace(4)*),
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,66 @@
|
||||||
|
From 7bbd0058362ac3bb5edd7a82d43e1785810776b3 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Anuj Mittal <anuj.mittal@intel.com>
|
||||||
|
Date: Fri, 29 Mar 2019 08:56:53 +0800
|
||||||
|
Subject: [PATCH] dont export targets for binaries
|
||||||
|
|
||||||
|
The projects using LLVM cmake modules look for target binaries in
|
||||||
|
sysroot as a result which isn't desirable in this case and isn't needed
|
||||||
|
either.
|
||||||
|
|
||||||
|
Upstream-Status: Inappropriate [cross-compile specific]
|
||||||
|
|
||||||
|
Signed-off-by: Anuj Mittal <anuj.mittal@intel.com>
|
||||||
|
---
|
||||||
|
llvm/cmake/modules/AddLLVM.cmake | 9 ---------
|
||||||
|
llvm/cmake/modules/TableGen.cmake | 6 ------
|
||||||
|
2 files changed, 15 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/llvm/cmake/modules/AddLLVM.cmake b/llvm/cmake/modules/AddLLVM.cmake
|
||||||
|
index 0df6845..b79f4fa 100644
|
||||||
|
--- a/llvm/cmake/modules/AddLLVM.cmake
|
||||||
|
+++ b/llvm/cmake/modules/AddLLVM.cmake
|
||||||
|
@@ -866,12 +866,6 @@ macro(add_llvm_tool name)
|
||||||
|
|
||||||
|
if ( ${name} IN_LIST LLVM_TOOLCHAIN_TOOLS OR NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
|
||||||
|
if( LLVM_BUILD_TOOLS )
|
||||||
|
- if(${name} IN_LIST LLVM_DISTRIBUTION_COMPONENTS OR
|
||||||
|
- NOT LLVM_DISTRIBUTION_COMPONENTS)
|
||||||
|
- set(export_to_llvmexports EXPORT LLVMExports)
|
||||||
|
- set_property(GLOBAL PROPERTY LLVM_HAS_EXPORTS True)
|
||||||
|
- endif()
|
||||||
|
-
|
||||||
|
install(TARGETS ${name}
|
||||||
|
${export_to_llvmexports}
|
||||||
|
RUNTIME DESTINATION ${LLVM_TOOLS_INSTALL_DIR}
|
||||||
|
@@ -884,9 +878,6 @@ macro(add_llvm_tool name)
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
endif()
|
||||||
|
- if( LLVM_BUILD_TOOLS )
|
||||||
|
- set_property(GLOBAL APPEND PROPERTY LLVM_EXPORTS ${name})
|
||||||
|
- endif()
|
||||||
|
set_target_properties(${name} PROPERTIES FOLDER "Tools")
|
||||||
|
endmacro(add_llvm_tool name)
|
||||||
|
|
||||||
|
diff --git a/llvm/cmake/modules/TableGen.cmake b/llvm/cmake/modules/TableGen.cmake
|
||||||
|
index 3c84ae7..141219f 100644
|
||||||
|
--- a/llvm/cmake/modules/TableGen.cmake
|
||||||
|
+++ b/llvm/cmake/modules/TableGen.cmake
|
||||||
|
@@ -164,14 +164,8 @@ macro(add_tablegen target project)
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if (${project} STREQUAL LLVM AND NOT LLVM_INSTALL_TOOLCHAIN_ONLY)
|
||||||
|
- if(${target} IN_LIST LLVM_DISTRIBUTION_COMPONENTS OR
|
||||||
|
- NOT LLVM_DISTRIBUTION_COMPONENTS)
|
||||||
|
- set(export_to_llvmexports EXPORT LLVMExports)
|
||||||
|
- endif()
|
||||||
|
-
|
||||||
|
install(TARGETS ${target}
|
||||||
|
${export_to_llvmexports}
|
||||||
|
RUNTIME DESTINATION ${LLVM_TOOLS_INSTALL_DIR})
|
||||||
|
endif()
|
||||||
|
- set_property(GLOBAL APPEND PROPERTY LLVM_EXPORTS ${target})
|
||||||
|
endmacro()
|
||||||
|
--
|
||||||
|
2.7.4
|
||||||
|
|
|
@ -0,0 +1,59 @@
|
||||||
|
From 6c33fb58869ffb17106047c45ab8d3856966eaf7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Anuj Mittal <anuj.mittal@intel.com>
|
||||||
|
Date: Tue, 26 Mar 2019 14:11:29 +0800
|
||||||
|
Subject: [PATCH] point to correct clang project and tblgen
|
||||||
|
|
||||||
|
Point to correct path for clang project as per the way we unpack. Also
|
||||||
|
let llvm-tblgen path be passed from recipe itself.
|
||||||
|
|
||||||
|
Also since we're going to do the patching ourselves, no need to look for
|
||||||
|
git through cmake.
|
||||||
|
|
||||||
|
Upstream-Status: Inappropriate [OE specific]
|
||||||
|
---
|
||||||
|
CMakeLists.txt | 8 ++++----
|
||||||
|
1 file changed, 4 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/CMakeLists.txt b/CMakeLists.txt
|
||||||
|
index 174133b..c769f08 100644
|
||||||
|
--- a/CMakeLists.txt
|
||||||
|
+++ b/CMakeLists.txt
|
||||||
|
@@ -53,7 +53,7 @@ endif(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
|
||||||
|
include(AddLLVM)
|
||||||
|
include(TableGen)
|
||||||
|
|
||||||
|
-find_package(Git REQUIRED)
|
||||||
|
+#find_package(Git REQUIRED)
|
||||||
|
|
||||||
|
if (NOT WIN32)
|
||||||
|
add_subdirectory( linux_linker )
|
||||||
|
@@ -80,7 +80,7 @@ set(TARGET_NAME ${COMMON_CLANG_LIBRARY_NAME}${BUILD_PLATFORM} )
|
||||||
|
|
||||||
|
if(NOT USE_PREBUILT_LLVM)
|
||||||
|
set(TARGET_BRANCH "ocl-open-80")
|
||||||
|
- set(CLANG_SOURCE_DIR ${LLVM_SOURCE_DIR}/tools/clang)
|
||||||
|
+ set(CLANG_SOURCE_DIR ${LLVM_SOURCE_DIR}/../clang)
|
||||||
|
set(CLANG_BASE_REVISION a03da8be08a208122e292016cb6cea1f30229677)
|
||||||
|
|
||||||
|
set(SPIRV_SOURCE_DIR ${LLVM_SOURCE_DIR}/projects/llvm-spirv)
|
||||||
|
@@ -102,7 +102,7 @@ endif(NOT USE_PREBUILT_LLVM)
|
||||||
|
set (COMPILE_OPTIONS_TD opencl_clang_options.td)
|
||||||
|
set (COMPILE_OPTIONS_INC opencl_clang_options.inc)
|
||||||
|
|
||||||
|
-set(LLVM_TABLEGEN_EXE "llvm-tblgen")
|
||||||
|
+#set(LLVM_TABLEGEN_EXE "llvm-tblgen")
|
||||||
|
set(LLVM_TARGET_DEFINITIONS ${COMPILE_OPTIONS_TD})
|
||||||
|
if(USE_PREBUILT_LLVM)
|
||||||
|
set(TABLEGEN_ADDITIONAL -I ${LLVM_INCLUDE_DIRS})
|
||||||
|
@@ -153,7 +153,7 @@ endif()
|
||||||
|
|
||||||
|
if(NOT USE_PREBUILT_LLVM)
|
||||||
|
set(CLANG_BINARY_DIR ${LLVM_BINARY_DIR}/tools/clang/)
|
||||||
|
- set(CLANG_SOURCE_DIR ${LLVM_MAIN_SRC_DIR}/tools/clang/)
|
||||||
|
+ set(CLANG_SOURCE_DIR ${LLVM_MAIN_SRC_DIR}/../clang/)
|
||||||
|
include_directories(
|
||||||
|
${CLANG_BINARY_DIR}/include # for tablegened includes
|
||||||
|
${CLANG_SOURCE_DIR}/include # for basic headers
|
||||||
|
--
|
||||||
|
2.19.1
|
||||||
|
|
|
@ -0,0 +1,294 @@
|
||||||
|
From c94ec28600255098ffb9d73d1b386a7c8a535590 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Andrew Savonichev <andrew.savonichev@intel.com>
|
||||||
|
Date: Thu, 21 Feb 2019 11:02:10 +0000
|
||||||
|
Subject: [PATCH 2/2] [OpenCL] Simplify LLVM IR generated for OpenCL blocks
|
||||||
|
|
||||||
|
Summary:
|
||||||
|
Emit direct call of block invoke functions when possible, i.e. in case the
|
||||||
|
block is not passed as a function argument.
|
||||||
|
Also doing some refactoring of `CodeGenFunction::EmitBlockCallExpr()`
|
||||||
|
|
||||||
|
Reviewers: Anastasia, yaxunl, svenvh
|
||||||
|
|
||||||
|
Reviewed By: Anastasia
|
||||||
|
|
||||||
|
Subscribers: cfe-commits
|
||||||
|
|
||||||
|
Tags: #clang
|
||||||
|
|
||||||
|
Differential Revision: https://reviews.llvm.org/D58388
|
||||||
|
|
||||||
|
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@354568 91177308-0d34-0410-b5e6-96231b3b80d8
|
||||||
|
|
||||||
|
Upstream-Status: Backport
|
||||||
|
[https://github.com/llvm-mirror/clang/commit/eae71f8d05ce550c4e2595c9b7082cc2c7882c58]
|
||||||
|
Signed-off-by: Anuj Mittal <anuj.mittal@intel.com>
|
||||||
|
---
|
||||||
|
lib/CodeGen/CGBlocks.cpp | 77 +++++++++++++-------------
|
||||||
|
lib/CodeGen/CGOpenCLRuntime.cpp | 30 +++++++---
|
||||||
|
lib/CodeGen/CGOpenCLRuntime.h | 4 ++
|
||||||
|
test/CodeGenOpenCL/blocks.cl | 10 +---
|
||||||
|
test/CodeGenOpenCL/cl20-device-side-enqueue.cl | 34 +++++++++---
|
||||||
|
5 files changed, 91 insertions(+), 64 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp
|
||||||
|
index fa3c3ee..10a0238 100644
|
||||||
|
--- a/lib/CodeGen/CGBlocks.cpp
|
||||||
|
+++ b/lib/CodeGen/CGBlocks.cpp
|
||||||
|
@@ -1261,52 +1261,49 @@ RValue CodeGenFunction::EmitBlockCallExpr(const CallExpr *E,
|
||||||
|
ReturnValueSlot ReturnValue) {
|
||||||
|
const BlockPointerType *BPT =
|
||||||
|
E->getCallee()->getType()->getAs<BlockPointerType>();
|
||||||
|
-
|
||||||
|
llvm::Value *BlockPtr = EmitScalarExpr(E->getCallee());
|
||||||
|
-
|
||||||
|
- // Get a pointer to the generic block literal.
|
||||||
|
- // For OpenCL we generate generic AS void ptr to be able to reuse the same
|
||||||
|
- // block definition for blocks with captures generated as private AS local
|
||||||
|
- // variables and without captures generated as global AS program scope
|
||||||
|
- // variables.
|
||||||
|
- unsigned AddrSpace = 0;
|
||||||
|
- if (getLangOpts().OpenCL)
|
||||||
|
- AddrSpace = getContext().getTargetAddressSpace(LangAS::opencl_generic);
|
||||||
|
-
|
||||||
|
- llvm::Type *BlockLiteralTy =
|
||||||
|
- llvm::PointerType::get(CGM.getGenericBlockLiteralType(), AddrSpace);
|
||||||
|
-
|
||||||
|
- // Bitcast the callee to a block literal.
|
||||||
|
- BlockPtr =
|
||||||
|
- Builder.CreatePointerCast(BlockPtr, BlockLiteralTy, "block.literal");
|
||||||
|
-
|
||||||
|
- // Get the function pointer from the literal.
|
||||||
|
- llvm::Value *FuncPtr =
|
||||||
|
- Builder.CreateStructGEP(CGM.getGenericBlockLiteralType(), BlockPtr,
|
||||||
|
- CGM.getLangOpts().OpenCL ? 2 : 3);
|
||||||
|
-
|
||||||
|
- // Add the block literal.
|
||||||
|
+ llvm::Type *GenBlockTy = CGM.getGenericBlockLiteralType();
|
||||||
|
+ llvm::Value *Func = nullptr;
|
||||||
|
+ QualType FnType = BPT->getPointeeType();
|
||||||
|
+ ASTContext &Ctx = getContext();
|
||||||
|
CallArgList Args;
|
||||||
|
|
||||||
|
- QualType VoidPtrQualTy = getContext().VoidPtrTy;
|
||||||
|
- llvm::Type *GenericVoidPtrTy = VoidPtrTy;
|
||||||
|
if (getLangOpts().OpenCL) {
|
||||||
|
- GenericVoidPtrTy = CGM.getOpenCLRuntime().getGenericVoidPointerType();
|
||||||
|
- VoidPtrQualTy =
|
||||||
|
- getContext().getPointerType(getContext().getAddrSpaceQualType(
|
||||||
|
- getContext().VoidTy, LangAS::opencl_generic));
|
||||||
|
- }
|
||||||
|
-
|
||||||
|
- BlockPtr = Builder.CreatePointerCast(BlockPtr, GenericVoidPtrTy);
|
||||||
|
- Args.add(RValue::get(BlockPtr), VoidPtrQualTy);
|
||||||
|
-
|
||||||
|
- QualType FnType = BPT->getPointeeType();
|
||||||
|
+ // For OpenCL, BlockPtr is already casted to generic block literal.
|
||||||
|
+
|
||||||
|
+ // First argument of a block call is a generic block literal casted to
|
||||||
|
+ // generic void pointer, i.e. i8 addrspace(4)*
|
||||||
|
+ llvm::Value *BlockDescriptor = Builder.CreatePointerCast(
|
||||||
|
+ BlockPtr, CGM.getOpenCLRuntime().getGenericVoidPointerType());
|
||||||
|
+ QualType VoidPtrQualTy = Ctx.getPointerType(
|
||||||
|
+ Ctx.getAddrSpaceQualType(Ctx.VoidTy, LangAS::opencl_generic));
|
||||||
|
+ Args.add(RValue::get(BlockDescriptor), VoidPtrQualTy);
|
||||||
|
+ // And the rest of the arguments.
|
||||||
|
+ EmitCallArgs(Args, FnType->getAs<FunctionProtoType>(), E->arguments());
|
||||||
|
+
|
||||||
|
+ // We *can* call the block directly unless it is a function argument.
|
||||||
|
+ if (!isa<ParmVarDecl>(E->getCalleeDecl()))
|
||||||
|
+ Func = CGM.getOpenCLRuntime().getInvokeFunction(E->getCallee());
|
||||||
|
+ else {
|
||||||
|
+ llvm::Value *FuncPtr = Builder.CreateStructGEP(GenBlockTy, BlockPtr, 2);
|
||||||
|
+ Func = Builder.CreateAlignedLoad(FuncPtr, getPointerAlign());
|
||||||
|
+ }
|
||||||
|
+ } else {
|
||||||
|
+ // Bitcast the block literal to a generic block literal.
|
||||||
|
+ BlockPtr = Builder.CreatePointerCast(
|
||||||
|
+ BlockPtr, llvm::PointerType::get(GenBlockTy, 0), "block.literal");
|
||||||
|
+ // Get pointer to the block invoke function
|
||||||
|
+ llvm::Value *FuncPtr = Builder.CreateStructGEP(GenBlockTy, BlockPtr, 3);
|
||||||
|
|
||||||
|
- // And the rest of the arguments.
|
||||||
|
- EmitCallArgs(Args, FnType->getAs<FunctionProtoType>(), E->arguments());
|
||||||
|
+ // First argument is a block literal casted to a void pointer
|
||||||
|
+ BlockPtr = Builder.CreatePointerCast(BlockPtr, VoidPtrTy);
|
||||||
|
+ Args.add(RValue::get(BlockPtr), Ctx.VoidPtrTy);
|
||||||
|
+ // And the rest of the arguments.
|
||||||
|
+ EmitCallArgs(Args, FnType->getAs<FunctionProtoType>(), E->arguments());
|
||||||
|
|
||||||
|
- // Load the function.
|
||||||
|
- llvm::Value *Func = Builder.CreateAlignedLoad(FuncPtr, getPointerAlign());
|
||||||
|
+ // Load the function.
|
||||||
|
+ Func = Builder.CreateAlignedLoad(FuncPtr, getPointerAlign());
|
||||||
|
+ }
|
||||||
|
|
||||||
|
const FunctionType *FuncTy = FnType->castAs<FunctionType>();
|
||||||
|
const CGFunctionInfo &FnInfo =
|
||||||
|
diff --git a/lib/CodeGen/CGOpenCLRuntime.cpp b/lib/CodeGen/CGOpenCLRuntime.cpp
|
||||||
|
index 7f6f595..75003e5 100644
|
||||||
|
--- a/lib/CodeGen/CGOpenCLRuntime.cpp
|
||||||
|
+++ b/lib/CodeGen/CGOpenCLRuntime.cpp
|
||||||
|
@@ -123,6 +123,23 @@ llvm::PointerType *CGOpenCLRuntime::getGenericVoidPointerType() {
|
||||||
|
CGM.getContext().getTargetAddressSpace(LangAS::opencl_generic));
|
||||||
|
}
|
||||||
|
|
||||||
|
+// Get the block literal from an expression derived from the block expression.
|
||||||
|
+// OpenCL v2.0 s6.12.5:
|
||||||
|
+// Block variable declarations are implicitly qualified with const. Therefore
|
||||||
|
+// all block variables must be initialized at declaration time and may not be
|
||||||
|
+// reassigned.
|
||||||
|
+static const BlockExpr *getBlockExpr(const Expr *E) {
|
||||||
|
+ const Expr *Prev = nullptr; // to make sure we do not stuck in infinite loop.
|
||||||
|
+ while(!isa<BlockExpr>(E) && E != Prev) {
|
||||||
|
+ Prev = E;
|
||||||
|
+ E = E->IgnoreCasts();
|
||||||
|
+ if (auto DR = dyn_cast<DeclRefExpr>(E)) {
|
||||||
|
+ E = cast<VarDecl>(DR->getDecl())->getInit();
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+ return cast<BlockExpr>(E);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/// Record emitted llvm invoke function and llvm block literal for the
|
||||||
|
/// corresponding block expression.
|
||||||
|
void CGOpenCLRuntime::recordBlockInfo(const BlockExpr *E,
|
||||||
|
@@ -137,20 +154,17 @@ void CGOpenCLRuntime::recordBlockInfo(const BlockExpr *E,
|
||||||
|
EnqueuedBlockMap[E].Kernel = nullptr;
|
||||||
|
}
|
||||||
|
|
||||||
|
+llvm::Function *CGOpenCLRuntime::getInvokeFunction(const Expr *E) {
|
||||||
|
+ return EnqueuedBlockMap[getBlockExpr(E)].InvokeFunc;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
CGOpenCLRuntime::EnqueuedBlockInfo
|
||||||
|
CGOpenCLRuntime::emitOpenCLEnqueuedBlock(CodeGenFunction &CGF, const Expr *E) {
|
||||||
|
CGF.EmitScalarExpr(E);
|
||||||
|
|
||||||
|
// The block literal may be assigned to a const variable. Chasing down
|
||||||
|
// to get the block literal.
|
||||||
|
- if (auto DR = dyn_cast<DeclRefExpr>(E)) {
|
||||||
|
- E = cast<VarDecl>(DR->getDecl())->getInit();
|
||||||
|
- }
|
||||||
|
- E = E->IgnoreImplicit();
|
||||||
|
- if (auto Cast = dyn_cast<CastExpr>(E)) {
|
||||||
|
- E = Cast->getSubExpr();
|
||||||
|
- }
|
||||||
|
- auto *Block = cast<BlockExpr>(E);
|
||||||
|
+ const BlockExpr *Block = getBlockExpr(E);
|
||||||
|
|
||||||
|
assert(EnqueuedBlockMap.find(Block) != EnqueuedBlockMap.end() &&
|
||||||
|
"Block expression not emitted");
|
||||||
|
diff --git a/lib/CodeGen/CGOpenCLRuntime.h b/lib/CodeGen/CGOpenCLRuntime.h
|
||||||
|
index 750721f..4effc7e 100644
|
||||||
|
--- a/lib/CodeGen/CGOpenCLRuntime.h
|
||||||
|
+++ b/lib/CodeGen/CGOpenCLRuntime.h
|
||||||
|
@@ -92,6 +92,10 @@ public:
|
||||||
|
/// \param Block block literal emitted for the block expression.
|
||||||
|
void recordBlockInfo(const BlockExpr *E, llvm::Function *InvokeF,
|
||||||
|
llvm::Value *Block);
|
||||||
|
+
|
||||||
|
+ /// \return LLVM block invoke function emitted for an expression derived from
|
||||||
|
+ /// the block expression.
|
||||||
|
+ llvm::Function *getInvokeFunction(const Expr *E);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
diff --git a/test/CodeGenOpenCL/blocks.cl b/test/CodeGenOpenCL/blocks.cl
|
||||||
|
index 19aacc3..ab5a2c6 100644
|
||||||
|
--- a/test/CodeGenOpenCL/blocks.cl
|
||||||
|
+++ b/test/CodeGenOpenCL/blocks.cl
|
||||||
|
@@ -39,11 +39,8 @@ void foo(){
|
||||||
|
// SPIR: %[[blk_gen_ptr:.*]] = addrspacecast %struct.__opencl_block_literal_generic* %[[blk_ptr]] to %struct.__opencl_block_literal_generic addrspace(4)*
|
||||||
|
// SPIR: store %struct.__opencl_block_literal_generic addrspace(4)* %[[blk_gen_ptr]], %struct.__opencl_block_literal_generic addrspace(4)** %[[block_B:.*]],
|
||||||
|
// SPIR: %[[block_literal:.*]] = load %struct.__opencl_block_literal_generic addrspace(4)*, %struct.__opencl_block_literal_generic addrspace(4)** %[[block_B]]
|
||||||
|
- // SPIR: %[[invoke_addr:.*]] = getelementptr inbounds %struct.__opencl_block_literal_generic, %struct.__opencl_block_literal_generic addrspace(4)* %[[block_literal]], i32 0, i32 2
|
||||||
|
// SPIR: %[[blk_gen_ptr:.*]] = bitcast %struct.__opencl_block_literal_generic addrspace(4)* %[[block_literal]] to i8 addrspace(4)*
|
||||||
|
- // SPIR: %[[invoke_func_ptr:.*]] = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* %[[invoke_addr]]
|
||||||
|
- // SPIR: %[[invoke_func:.*]] = addrspacecast i8 addrspace(4)* %[[invoke_func_ptr]] to i32 (i8 addrspace(4)*)*
|
||||||
|
- // SPIR: call {{.*}}i32 %[[invoke_func]](i8 addrspace(4)* %[[blk_gen_ptr]])
|
||||||
|
+ // SPIR: call {{.*}}i32 @__foo_block_invoke(i8 addrspace(4)* %[[blk_gen_ptr]])
|
||||||
|
// AMDGCN: %[[block_invoke:.*]] = getelementptr inbounds <{ i32, i32, i8*, i32 }>, <{ i32, i32, i8*, i32 }> addrspace(5)* %[[block:.*]], i32 0, i32 2
|
||||||
|
// AMDGCN: store i8* bitcast (i32 (i8*)* @__foo_block_invoke to i8*), i8* addrspace(5)* %[[block_invoke]]
|
||||||
|
// AMDGCN: %[[block_captured:.*]] = getelementptr inbounds <{ i32, i32, i8*, i32 }>, <{ i32, i32, i8*, i32 }> addrspace(5)* %[[block]], i32 0, i32 3
|
||||||
|
@@ -53,11 +50,8 @@ void foo(){
|
||||||
|
// AMDGCN: %[[blk_gen_ptr:.*]] = addrspacecast %struct.__opencl_block_literal_generic addrspace(5)* %[[blk_ptr]] to %struct.__opencl_block_literal_generic*
|
||||||
|
// AMDGCN: store %struct.__opencl_block_literal_generic* %[[blk_gen_ptr]], %struct.__opencl_block_literal_generic* addrspace(5)* %[[block_B:.*]],
|
||||||
|
// AMDGCN: %[[block_literal:.*]] = load %struct.__opencl_block_literal_generic*, %struct.__opencl_block_literal_generic* addrspace(5)* %[[block_B]]
|
||||||
|
- // AMDGCN: %[[invoke_addr:.*]] = getelementptr inbounds %struct.__opencl_block_literal_generic, %struct.__opencl_block_literal_generic* %[[block_literal]], i32 0, i32 2
|
||||||
|
// AMDGCN: %[[blk_gen_ptr:.*]] = bitcast %struct.__opencl_block_literal_generic* %[[block_literal]] to i8*
|
||||||
|
- // AMDGCN: %[[invoke_func_ptr:.*]] = load i8*, i8** %[[invoke_addr]]
|
||||||
|
- // AMDGCN: %[[invoke_func:.*]] = bitcast i8* %[[invoke_func_ptr]] to i32 (i8*)*
|
||||||
|
- // AMDGCN: call {{.*}}i32 %[[invoke_func]](i8* %[[blk_gen_ptr]])
|
||||||
|
+ // AMDGCN: call {{.*}}i32 @__foo_block_invoke(i8* %[[blk_gen_ptr]])
|
||||||
|
|
||||||
|
int (^ block_B)(void) = ^{
|
||||||
|
return i;
|
||||||
|
diff --git a/test/CodeGenOpenCL/cl20-device-side-enqueue.cl b/test/CodeGenOpenCL/cl20-device-side-enqueue.cl
|
||||||
|
index 8445016..1566912 100644
|
||||||
|
--- a/test/CodeGenOpenCL/cl20-device-side-enqueue.cl
|
||||||
|
+++ b/test/CodeGenOpenCL/cl20-device-side-enqueue.cl
|
||||||
|
@@ -312,9 +312,7 @@ kernel void device_side_enqueue(global int *a, global int *b, int i) {
|
||||||
|
};
|
||||||
|
|
||||||
|
// Uses global block literal [[BLG8]] and invoke function [[INVG8]].
|
||||||
|
- // COMMON: [[r1:%.*]] = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* getelementptr inbounds (%struct.__opencl_block_literal_generic, %struct.__opencl_block_literal_generic addrspace(4)* addrspacecast (%struct.__opencl_block_literal_generic addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BLG8]] to %struct.__opencl_block_literal_generic addrspace(1)*) to %struct.__opencl_block_literal_generic addrspace(4)*), i32 0, i32 2)
|
||||||
|
- // COMMON: [[r2:%.*]] = addrspacecast i8 addrspace(4)* [[r1]] to void (i8 addrspace(4)*)*
|
||||||
|
- // COMMON: call spir_func void [[r2]](i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BLG8]] to i8 addrspace(1)*) to i8 addrspace(4)*))
|
||||||
|
+ // COMMON: call spir_func void @__device_side_enqueue_block_invoke_11(i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BLG8]] to i8 addrspace(1)*) to i8 addrspace(4)*))
|
||||||
|
block_A();
|
||||||
|
|
||||||
|
// Emits global block literal [[BLG8]] and block kernel [[INVGK8]]. [[INVGK8]] calls [[INVG8]].
|
||||||
|
@@ -333,15 +331,35 @@ kernel void device_side_enqueue(global int *a, global int *b, int i) {
|
||||||
|
unsigned size = get_kernel_work_group_size(block_A);
|
||||||
|
|
||||||
|
// Uses global block literal [[BLG8]] and invoke function [[INVG8]]. Make sure no redundant block literal and invoke functions are emitted.
|
||||||
|
- // COMMON: [[r1:%.*]] = load i8 addrspace(4)*, i8 addrspace(4)* addrspace(4)* getelementptr inbounds (%struct.__opencl_block_literal_generic, %struct.__opencl_block_literal_generic addrspace(4)* addrspacecast (%struct.__opencl_block_literal_generic addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BLG8]] to %struct.__opencl_block_literal_generic addrspace(1)*) to %struct.__opencl_block_literal_generic addrspace(4)*), i32 0, i32 2)
|
||||||
|
- // COMMON: [[r2:%.*]] = addrspacecast i8 addrspace(4)* [[r1]] to void (i8 addrspace(4)*)*
|
||||||
|
- // COMMON: call spir_func void [[r2]](i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BLG8]] to i8 addrspace(1)*) to i8 addrspace(4)*))
|
||||||
|
+ // COMMON: call spir_func void @__device_side_enqueue_block_invoke_11(i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BLG8]] to i8 addrspace(1)*) to i8 addrspace(4)*))
|
||||||
|
block_A();
|
||||||
|
|
||||||
|
+ // Make sure that block invoke function is resolved correctly after sequence of assignements.
|
||||||
|
+ // COMMON: store %struct.__opencl_block_literal_generic addrspace(4)*
|
||||||
|
+ // COMMON-SAME: addrspacecast (%struct.__opencl_block_literal_generic addrspace(1)*
|
||||||
|
+ // COMMON-SAME: bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BL_GLOBAL]] to %struct.__opencl_block_literal_generic addrspace(1)*)
|
||||||
|
+ // COMMON-SAME: to %struct.__opencl_block_literal_generic addrspace(4)*),
|
||||||
|
+ // COMMON-SAME: %struct.__opencl_block_literal_generic addrspace(4)** %b1,
|
||||||
|
+ bl_t b1 = block_G;
|
||||||
|
+ // COMMON: store %struct.__opencl_block_literal_generic addrspace(4)*
|
||||||
|
+ // COMMON-SAME: addrspacecast (%struct.__opencl_block_literal_generic addrspace(1)*
|
||||||
|
+ // COMMON-SAME: bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BL_GLOBAL]] to %struct.__opencl_block_literal_generic addrspace(1)*)
|
||||||
|
+ // COMMON-SAME: to %struct.__opencl_block_literal_generic addrspace(4)*),
|
||||||
|
+ // COMMON-SAME: %struct.__opencl_block_literal_generic addrspace(4)** %b2,
|
||||||
|
+ bl_t b2 = b1;
|
||||||
|
+ // COMMON: call spir_func void @block_G_block_invoke(i8 addrspace(4)* addrspacecast (i8 addrspace(1)*
|
||||||
|
+ // COMMON-SAME: bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BL_GLOBAL]] to i8 addrspace(1)*)
|
||||||
|
+ // COOMON-SAME: to i8 addrspace(4)*), i8 addrspace(3)* null)
|
||||||
|
+ b2(0);
|
||||||
|
+ // Uses global block literal [[BL_GLOBAL]] and block kernel [[INV_G_K]]. [[INV_G_K]] calls [[INV_G]].
|
||||||
|
+ // COMMON: call i32 @__get_kernel_preferred_work_group_size_multiple_impl(
|
||||||
|
+ // COMMON-SAME: i8 addrspace(4)* addrspacecast (i8* bitcast ({{.*}} [[INV_G_K:[^ ]+_kernel]] to i8*) to i8 addrspace(4)*),
|
||||||
|
+ // COMMON-SAME: i8 addrspace(4)* addrspacecast (i8 addrspace(1)* bitcast ({ i32, i32, i8 addrspace(4)* } addrspace(1)* [[BL_GLOBAL]] to i8 addrspace(1)*) to i8 addrspace(4)*))
|
||||||
|
+ size = get_kernel_preferred_work_group_size_multiple(b2);
|
||||||
|
+
|
||||||
|
void (^block_C)(void) = ^{
|
||||||
|
callee(i, a);
|
||||||
|
};
|
||||||
|
-
|
||||||
|
// Emits block literal on stack and block kernel [[INVLK3]].
|
||||||
|
// COMMON: store i8 addrspace(4)* addrspacecast (i8* bitcast (void (i8 addrspace(4)*)* [[INVL3:@__device_side_enqueue_block_invoke[^ ]*]] to i8*) to i8 addrspace(4)*), i8 addrspace(4)** %block.invoke
|
||||||
|
// COMMON: [[DEF_Q:%[0-9]+]] = load %opencl.queue_t{{.*}}*, %opencl.queue_t{{.*}}** %default_queue
|
||||||
|
@@ -404,8 +422,8 @@ kernel void device_side_enqueue(global int *a, global int *b, int i) {
|
||||||
|
// COMMON: define internal spir_func void [[INVG8]](i8 addrspace(4)*{{.*}})
|
||||||
|
// COMMON: define internal spir_func void [[INVG9]](i8 addrspace(4)*{{.*}}, i8 addrspace(3)* %{{.*}})
|
||||||
|
// COMMON: define internal spir_kernel void [[INVGK8]](i8 addrspace(4)*{{.*}})
|
||||||
|
+// COMMON: define internal spir_kernel void [[INV_G_K]](i8 addrspace(4)*{{.*}}, i8 addrspace(3)*{{.*}})
|
||||||
|
// COMMON: define internal spir_kernel void [[INVLK3]](i8 addrspace(4)*{{.*}})
|
||||||
|
// COMMON: define internal spir_kernel void [[INVGK9]](i8 addrspace(4)*{{.*}}, i8 addrspace(3)*{{.*}})
|
||||||
|
-// COMMON: define internal spir_kernel void [[INV_G_K]](i8 addrspace(4)*{{.*}}, i8 addrspace(3)*{{.*}})
|
||||||
|
// COMMON: define internal spir_kernel void [[INVGK10]](i8 addrspace(4)*{{.*}})
|
||||||
|
// COMMON: define internal spir_kernel void [[INVGK11]](i8 addrspace(4)*{{.*}})
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
|
@ -0,0 +1,61 @@
|
||||||
|
From 29e2813a2ab7d5569860bb07892dfef7b5374d96 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Yaxun Liu <Yaxun.Liu@amd.com>
|
||||||
|
Date: Tue, 26 Feb 2019 16:20:41 +0000
|
||||||
|
Subject: [PATCH] [OpenCL] Fix assertion due to blocks
|
||||||
|
|
||||||
|
A recent change caused assertion in CodeGenFunction::EmitBlockCallExpr when a block is called.
|
||||||
|
|
||||||
|
There is code
|
||||||
|
|
||||||
|
Func = CGM.getOpenCLRuntime().getInvokeFunction(E->getCallee());
|
||||||
|
getCalleeDecl calls Expr::getReferencedDeclOfCallee, which does not handle
|
||||||
|
BlockExpr and returns nullptr, which causes isa to assert.
|
||||||
|
|
||||||
|
This patch fixes that.
|
||||||
|
|
||||||
|
Differential Revision: https://reviews.llvm.org/D58658
|
||||||
|
|
||||||
|
|
||||||
|
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@354893 91177308-0d34-0410-b5e6-96231b3b80d8
|
||||||
|
|
||||||
|
Upstream-Status: Backport
|
||||||
|
[https://github.com/llvm-mirror/clang/commit/29e2813a2ab7d5569860bb07892dfef7b5374d96]
|
||||||
|
Signed-off-by: Anuj Mittal <anuj.mittal@intel.com>
|
||||||
|
---
|
||||||
|
lib/AST/Expr.cpp | 2 ++
|
||||||
|
test/CodeGenOpenCL/blocks.cl | 6 ++++++
|
||||||
|
2 files changed, 8 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp
|
||||||
|
index aef1eab..85690c7 100644
|
||||||
|
--- a/lib/AST/Expr.cpp
|
||||||
|
+++ b/lib/AST/Expr.cpp
|
||||||
|
@@ -1358,6 +1358,8 @@ Decl *Expr::getReferencedDeclOfCallee() {
|
||||||
|
return DRE->getDecl();
|
||||||
|
if (MemberExpr *ME = dyn_cast<MemberExpr>(CEE))
|
||||||
|
return ME->getMemberDecl();
|
||||||
|
+ if (auto *BE = dyn_cast<BlockExpr>(CEE))
|
||||||
|
+ return BE->getBlockDecl();
|
||||||
|
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
diff --git a/test/CodeGenOpenCL/blocks.cl b/test/CodeGenOpenCL/blocks.cl
|
||||||
|
index ab5a2c6..c3e2685 100644
|
||||||
|
--- a/test/CodeGenOpenCL/blocks.cl
|
||||||
|
+++ b/test/CodeGenOpenCL/blocks.cl
|
||||||
|
@@ -90,6 +90,12 @@ int get42() {
|
||||||
|
return blockArgFunc(^{return 42;});
|
||||||
|
}
|
||||||
|
|
||||||
|
+// COMMON-LABEL: define {{.*}}@call_block
|
||||||
|
+// call {{.*}}@__call_block_block_invoke
|
||||||
|
+int call_block() {
|
||||||
|
+ return ^int(int num) { return num; } (11);
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
// CHECK-DEBUG: !DIDerivedType(tag: DW_TAG_member, name: "__size"
|
||||||
|
// CHECK-DEBUG: !DIDerivedType(tag: DW_TAG_member, name: "__align"
|
||||||
|
|
||||||
|
--
|
||||||
|
1.8.3.1
|
||||||
|
|
|
@ -0,0 +1,16 @@
|
||||||
|
FILESEXTRAPATHS_prepend_intel-x86-common := "${THISDIR}/files:"
|
||||||
|
|
||||||
|
SRC_URI_append_intel-x86-common = " \
|
||||||
|
git://github.com/intel/opencl-clang.git;protocol=https;branch=ocl-open-80;destsuffix=git/llvm/projects/opencl-clang;name=opencl-clang \
|
||||||
|
git://github.com/KhronosGroup/SPIRV-LLVM-Translator.git;protocol=https;branch=llvm_release_80;destsuffix=git/llvm/projects/llvm-spirv;name=spirv \
|
||||||
|
file://0001-point-to-correct-clang.patch;patchdir=llvm/projects/opencl-clang \
|
||||||
|
file://0001-OpenCL-Change-type-of-block-pointer-for-OpenCL.patch;patchdir=clang \
|
||||||
|
file://0002-OpenCL-Simplify-LLVM-IR-generated-for-OpenCL-blocks.patch;patchdir=clang \
|
||||||
|
file://0003-OpenCL-Fix-assertion-due-to-blocks.patch;patchdir=clang \
|
||||||
|
file://0001-dont-export-targets-for-binaries.patch \
|
||||||
|
file://0001-Update-LowerOpenCL-pass-to-handle-new-blocks-represn.patch;patchdir=llvm/projects/llvm-spirv \
|
||||||
|
"
|
||||||
|
|
||||||
|
SRCREV_opencl-clang = "daf5e4dd718477ae8cf89a283c653939d9182f15"
|
||||||
|
SRCREV_spirv = "bd0f28fb92061d49c0f120b4dac3fd8956006745"
|
||||||
|
|
Loading…
Reference in New Issue
Block a user