From db91b25473348f50c3cca92ae2c50237a6de6d74 Mon Sep 17 00:00:00 2001 From: haonanya Date: Tue, 14 Dec 2021 19:39:09 +0800 Subject: [PATCH] Enable precompiled headers Also cherry-pick https://github.com/intel/opencl-clang/pull/249, https://github.com/intel/opencl-clang/pull/265 and https://github.com/intel/opencl-clang/pull/346 to address cross build issues. Signed-off-by: Haonan Yang --- CMakeLists.txt | 34 +++++++++-- README.md | 4 +- cl_headers/CMakeLists.txt | 111 +++++++++++++++++++++++++++++++++++- cl_headers/OpenCL.rc | 17 +++++- cl_headers/module.modulemap | 60 +++++++++++++++++++ cl_headers/resource.h | 17 +++++- common_clang.cpp | 25 ++++++-- common_clang.map | 13 +++++ linux_linker/CMakeLists.txt | 12 +++- options_compile.cpp | 100 ++++++++++++++++++++++++++++++++ 10 files changed, 374 insertions(+), 19 deletions(-) create mode 100644 cl_headers/module.modulemap diff --git a/CMakeLists.txt b/CMakeLists.txt index 18344c88..23d2aea5 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,6 +1,27 @@ -project( common_clang ) cmake_minimum_required(VERSION 3.4.3) +if(NOT DEFINED BASE_LLVM_VERSION) + set(BASE_LLVM_VERSION 16.0.0) +endif(NOT DEFINED BASE_LLVM_VERSION) +set(OPENCL_CLANG_VERSION ${BASE_LLVM_VERSION}.0) + +if(NOT DEFINED OPENCL_CLANG_BUILD_EXTERNAL) + # check if we build inside llvm or not + if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) + set(OPENCL_CLANG_BUILD_EXTERNAL YES) + endif(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) +endif(NOT DEFINED OPENCL_CLANG_BUILD_EXTERNAL) + +if(OPENCL_CLANG_BUILD_EXTERNAL) + project(OPENCL_CLANG + VERSION + ${OPENCL_CLANG_VERSION} + LANGUAGES + CXX + C + ) +endif() + # Do not omit TARGET_OBJECTS expression from the SOURCES target # property # `cmake --help-policy CMP0051` for details. @@ -14,13 +35,18 @@ set(CMAKE_MODULE_PATH include(CMakeFunctions) +if(LLVM_USE_HOST_TOOLS AND OPENCL_CLANG_BUILD_EXTERNAL) + include(CrossCompile) + llvm_create_cross_target(${PROJECT_NAME} NATIVE "" Release) +endif() + if(CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR) set(USE_PREBUILT_LLVM ON) add_definitions(-DUSE_PREBUILT_LLVM) if(NOT PREFERRED_LLVM_VERSION) - set(PREFERRED_LLVM_VERSION "12.0.0") + set(PREFERRED_LLVM_VERSION "16.0.0") endif(NOT PREFERRED_LLVM_VERSION) message(STATUS "[OPENCL-CLANG] Looking for LLVM version ${PREFERRED_LLVM_VERSION}") find_package(LLVM ${PREFERRED_LLVM_VERSION} REQUIRED) @@ -55,7 +81,7 @@ include(AddLLVM) include(TableGen) if (NOT WIN32) - add_subdirectory( linux_linker ) + add_subdirectory( linux_linker bin) endif() if (CMAKE_SIZEOF_VOID_P EQUAL 4) @@ -137,7 +163,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") +find_program(LLVM_TABLEGEN_EXE "llvm-tblgen" ${LLVM_TOOLS_BINARY_DIR}) set(LLVM_TARGET_DEFINITIONS ${COMPILE_OPTIONS_TD}) if(USE_PREBUILT_LLVM) set(TABLEGEN_ADDITIONAL -I ${LLVM_INCLUDE_DIRS}) diff --git a/README.md b/README.md index fc558311..a90e692c 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,8 @@ To build opencl-clang as a standalone project, you need to obtain pre-built LLVM and SPIR-V Translator libraries. **Note:** currently this kind of build is supported on Linux only. +If opencl-clang is used as part of another CMake project, you will need to define `OPENCL_CLANG_BUILD_EXTERNAL`. + Integration with pre-built LLVM is done using standard `find_package` way as documented in [Embedding LLVM in your project](https://llvm.org/docs/CMake.html#embedding-llvm-in-your-project). @@ -68,7 +70,7 @@ make all -j`nproc` ##### Preferred LLVM version -By default, openclc-clang's cmake script is searching for LLVM 12.0.0. You can +By default, openclc-clang's cmake script is searching for LLVM 16.0.0. You can override target version of LLVM by using the `PREFERRED_LLVM_VERSION` cmake option: diff --git a/cl_headers/CMakeLists.txt b/cl_headers/CMakeLists.txt index 519d210a..5ec9dd01 100644 --- a/cl_headers/CMakeLists.txt +++ b/cl_headers/CMakeLists.txt @@ -1,5 +1,8 @@ set(CL_HEADERS_LIB cl_headers) -set(CLANG_COMMAND clang) +set(CLANG_COMMAND $ ) +if(LLVM_USE_HOST_TOOLS AND NOT OPENCL_CLANG_BUILD_EXTERNAL) + build_native_tool(clang CLANG_COMMAND) +endif() set(LINUX_RESOURCE_LINKER_COMMAND linux_resource_linker) function(copy_file SRC DST) @@ -19,19 +22,86 @@ else(USE_PREBUILT_LLVM) endif(USE_PREBUILT_LLVM) copy_file(${OPENCL_HEADERS_DIR}/opencl-c.h opencl-c.h) copy_file(${OPENCL_HEADERS_DIR}/opencl-c-base.h opencl-c-base.h) +copy_file(${CMAKE_CURRENT_SOURCE_DIR}/module.modulemap module.modulemap) add_custom_target ( opencl.headers.target DEPENDS + module.modulemap opencl-c.h opencl-c-base.h ) +function(create_pcm DST MODULE HEADER OPTS DEPS) + add_custom_command ( + OUTPUT ${DST} + MAIN_DEPENDENCY ${MODMAP} + DEPENDS ${HEADER} ${DEPS} ${CLANG_COMMAND} + COMMAND + ${CLANG_COMMAND} -cc1 -x cl + -I. -O0 ${OPTS} + -fmodules -fmodule-name=${MODULE} -fmodule-map-file-home-is-cwd + -emit-module "module.modulemap" + -fno-validate-pch + -o ${DST} + VERBATIM + COMMENT "Generating ${DST}" + ) +endfunction(create_pcm) + +set(CL12 "-cl-std=CL1.2") +set(CL20 "-cl-std=CL2.0") +set(CL30 "-cl-std=CL3.0") +# Add OpenCL C 3.0 Optional features +set(OPTS30 "-cl-ext=+__opencl_c_3d_image_writes,+__opencl_c_atomic_order_acq_rel,+__opencl_c_atomic_order_seq_cst,+__opencl_c_atomic_scope_device,+__opencl_c_atomic_scope_all_devices,+__opencl_c_device_enqueue,+__opencl_c_generic_address_space,+__opencl_c_images,+__opencl_c_int64,+__opencl_c_pipes,+__opencl_c_program_scope_global_variables,+__opencl_c_read_write_images,+__opencl_c_subgroups,+__opencl_c_work_group_collective_functions") +set(OPTS30_FP64 "-D__opencl_c_fp64=1") + +set(SPIR_TRIPLE "-triple;spir-unknown-unknown") +set(SPIR64_TRIPLE "-triple;spir64-unknown-unknown") + +if (BUILD_X64) + set(HOST_TRIPLE "${SPIR64_TRIPLE}") +else() + set(HOST_TRIPLE "${SPIR_TRIPLE}") +endif() + +set(OPTS -cl-ext=+all,-cl_khr_fp64,-__opencl_c_fp64) +create_pcm(opencl-c-12-spir.pcm cl12spir opencl-c-base.h "${SPIR_TRIPLE};${CL12};${OPTS}" "${DEPS}") +create_pcm(opencl-c-20-spir.pcm cl20spir opencl-c-base.h "${SPIR_TRIPLE};${CL20};${OPTS}" "${DEPS}") +create_pcm(opencl-c-30-spir.pcm cl30spir opencl-c-base.h "${SPIR_TRIPLE};${CL30};${OPTS};${OPTS30}" "${DEPS}") +create_pcm(opencl-c-12-spir64.pcm cl12spir64 opencl-c-base.h "${SPIR64_TRIPLE};${CL12};${OPTS}" "${DEPS}") +create_pcm(opencl-c-20-spir64.pcm cl20spir64 opencl-c-base.h "${SPIR64_TRIPLE};${CL20};${OPTS}" "${DEPS}") +create_pcm(opencl-c-30-spir64.pcm cl30spir64 opencl-c-base.h "${SPIR64_TRIPLE};${CL30};${OPTS};${OPTS30}" "${DEPS}") +set(OPTS -cl-ext=+all) +create_pcm(opencl-c-12-spir-fp64.pcm cl12spirfp64 opencl-c-base.h "${SPIR_TRIPLE};${CL12};${OPTS}" "${DEPS}") +create_pcm(opencl-c-20-spir-fp64.pcm cl20spirfp64 opencl-c-base.h "${SPIR_TRIPLE};${CL20};${OPTS}" "${DEPS}") +create_pcm(opencl-c-30-spir-fp64.pcm cl30spirfp64 opencl-c-base.h "${SPIR_TRIPLE};${CL30};${OPTS};${OPTS30};${OPTS30_FP64}" "${DEPS}") +create_pcm(opencl-c-12-spir64-fp64.pcm cl12spir64fp64 opencl-c-base.h "${SPIR64_TRIPLE};${CL12};${OPTS}" "${DEPS}") +create_pcm(opencl-c-20-spir64-fp64.pcm cl20spir64fp64 opencl-c-base.h "${SPIR64_TRIPLE};${CL20};${OPTS}" "${DEPS}") +create_pcm(opencl-c-30-spir64-fp64.pcm cl30spir64fp64 opencl-c-base.h "${SPIR64_TRIPLE};${CL30};${OPTS};${OPTS30};${OPTS30_FP64}" "${DEPS}") + +add_custom_target ( + opencl.pcm.target + DEPENDS + opencl.headers.target + opencl-c-12-spir.pcm + opencl-c-20-spir.pcm + opencl-c-30-spir.pcm + opencl-c-12-spir64.pcm + opencl-c-20-spir64.pcm + opencl-c-30-spir64.pcm + opencl-c-12-spir-fp64.pcm + opencl-c-20-spir-fp64.pcm + opencl-c-30-spir-fp64.pcm + opencl-c-12-spir64-fp64.pcm + opencl-c-20-spir64-fp64.pcm + opencl-c-30-spir64-fp64.pcm +) function(pack_to_obj SRC DST TAG) add_custom_command ( OUTPUT ${DST} - DEPENDS ${SRC} ${LINUX_RESOURCE_LINKER_COMMAND} + DEPENDS ${SRC} linux_resource_linker COMMAND ${LINUX_RESOURCE_LINKER_COMMAND} "${SRC}" "${DST}" "${TAG}" COMMENT "Packing ${SRC}" ) @@ -45,11 +115,46 @@ else() list(APPEND CL_HEADERS_SRC opencl-c.h.cpp opencl-c-base.h.cpp + opencl-c-12-spir.mod.cpp + opencl-c-20-spir.mod.cpp + opencl-c-30-spir.mod.cpp + opencl-c-12-spir64.mod.cpp + opencl-c-20-spir64.mod.cpp + opencl-c-30-spir64.mod.cpp + opencl-c-12-spir-fp64.mod.cpp + opencl-c-20-spir-fp64.mod.cpp + opencl-c-30-spir-fp64.mod.cpp + opencl-c-12-spir64-fp64.mod.cpp + opencl-c-20-spir64-fp64.mod.cpp + opencl-c-30-spir64-fp64.mod.cpp + module.modulemap.cpp ) + # note the .pcm -> .mod extension change + # this is a workaround for CMake bug that caused + # dependency cycle in generated build rules + pack_to_obj(opencl-c-12-spir.pcm opencl-c-12-spir.mod.cpp "PCM_OPENCL_C_12_SPIR_PCM") + pack_to_obj(opencl-c-20-spir.pcm opencl-c-20-spir.mod.cpp "PCM_OPENCL_C_20_SPIR_PCM") + pack_to_obj(opencl-c-30-spir.pcm opencl-c-30-spir.mod.cpp "PCM_OPENCL_C_30_SPIR_PCM") + pack_to_obj(opencl-c-12-spir64.pcm opencl-c-12-spir64.mod.cpp "PCM_OPENCL_C_12_SPIR64_PCM") + pack_to_obj(opencl-c-20-spir64.pcm opencl-c-20-spir64.mod.cpp "PCM_OPENCL_C_20_SPIR64_PCM") + pack_to_obj(opencl-c-30-spir64.pcm opencl-c-30-spir64.mod.cpp "PCM_OPENCL_C_30_SPIR64_PCM") + pack_to_obj(opencl-c-12-spir-fp64.pcm opencl-c-12-spir-fp64.mod.cpp "PCM_OPENCL_C_12_SPIR_FP64_PCM") + pack_to_obj(opencl-c-20-spir-fp64.pcm opencl-c-20-spir-fp64.mod.cpp "PCM_OPENCL_C_20_SPIR_FP64_PCM") + pack_to_obj(opencl-c-30-spir-fp64.pcm opencl-c-30-spir-fp64.mod.cpp "PCM_OPENCL_C_30_SPIR_FP64_PCM") + pack_to_obj(opencl-c-12-spir64-fp64.pcm opencl-c-12-spir64-fp64.mod.cpp "PCM_OPENCL_C_12_SPIR64_FP64_PCM") + pack_to_obj(opencl-c-20-spir64-fp64.pcm opencl-c-20-spir64-fp64.mod.cpp "PCM_OPENCL_C_20_SPIR64_FP64_PCM") + pack_to_obj(opencl-c-30-spir64-fp64.pcm opencl-c-30-spir64-fp64.mod.cpp "PCM_OPENCL_C_30_SPIR64_FP64_PCM") + pack_to_obj(module.modulemap module.modulemap.cpp "PCM_OPENCL_C_MODULE_MAP") endif() add_library(${CL_HEADERS_LIB} OBJECT ${CL_HEADERS_SRC} ) -add_dependencies(${CL_HEADERS_LIB} opencl.headers.target) +add_dependencies(${CL_HEADERS_LIB} opencl.pcm.target) +install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/opencl-c.h + ${CMAKE_CURRENT_BINARY_DIR}/opencl-c-base.h + ${CMAKE_CURRENT_BINARY_DIR}/module.modulemap + DESTINATION include/cclang +) diff --git a/cl_headers/OpenCL.rc b/cl_headers/OpenCL.rc index aee05876..c63cc7da 100644 --- a/cl_headers/OpenCL.rc +++ b/cl_headers/OpenCL.rc @@ -11,5 +11,18 @@ END // Module with OpenCL C declarations with corresponding headers // -OPENCL_C_H PCM "opencl-c.h" -OPENCL_C_BASE_H PCM "opencl-c-base.h" \ No newline at end of file +OPENCL_C_H PCM "opencl-c.h" +OPENCL_C_BASE_H PCM "opencl-c-base.h" +OPENCL_C_12_SPIR_PCM PCM "opencl-c-12-spir.pcm" +OPENCL_C_20_SPIR_PCM PCM "opencl-c-20-spir.pcm" +OPENCL_C_30_SPIR_PCM PCM "opencl-c-30-spir.pcm" +OPENCL_C_12_SPIR64_PCM PCM "opencl-c-12-spir64.pcm" +OPENCL_C_20_SPIR64_PCM PCM "opencl-c-20-spir64.pcm" +OPENCL_C_30_SPIR64_PCM PCM "opencl-c-30-spir64.pcm" +OPENCL_C_12_SPIR_FP64_PCM PCM "opencl-c-12-spir-fp64.pcm" +OPENCL_C_20_SPIR_FP64_PCM PCM "opencl-c-20-spir-fp64.pcm" +OPENCL_C_30_SPIR_FP64_PCM PCM "opencl-c-30-spir-fp64.pcm" +OPENCL_C_12_SPIR64_FP64_PCM PCM "opencl-c-12-spir64-fp64.pcm" +OPENCL_C_20_SPIR64_FP64_PCM PCM "opencl-c-20-spir64-fp64.pcm" +OPENCL_C_30_SPIR64_FP64_PCM PCM "opencl-c-30-spir64-fp64.pcm" +OPENCL_C_MODULE_MAP PCM "module.modulemap" diff --git a/cl_headers/module.modulemap b/cl_headers/module.modulemap new file mode 100644 index 00000000..fda1526b --- /dev/null +++ b/cl_headers/module.modulemap @@ -0,0 +1,60 @@ +module cl12spir { + header "opencl-c.h" + header "opencl-c-base.h" + export * +} +module cl20spir { + header "opencl-c.h" + header "opencl-c-base.h" + export * +} +module cl30spir { + header "opencl-c.h" + header "opencl-c-base.h" + export * +} +module cl12spir64 { + header "opencl-c.h" + header "opencl-c-base.h" + export * +} +module cl20spir64 { + header "opencl-c.h" + header "opencl-c-base.h" + export * +} +module cl30spir64 { + header "opencl-c.h" + header "opencl-c-base.h" + export * +} +module cl12spirfp64 { + header "opencl-c.h" + header "opencl-c-base.h" + export * +} +module cl20spirfp64 { + header "opencl-c.h" + header "opencl-c-base.h" + export * +} +module cl30spirfp64 { + header "opencl-c.h" + header "opencl-c-base.h" + export * +} +module cl12spir64fp64 { + header "opencl-c.h" + header "opencl-c-base.h" + export * +} +module cl20spir64fp64 { + header "opencl-c.h" + header "opencl-c-base.h" + export * +} +module cl30spir64fp64 { + header "opencl-c.h" + header "opencl-c-base.h" + export * +} diff --git a/cl_headers/resource.h b/cl_headers/resource.h index 474b5650..790db2c6 100644 --- a/cl_headers/resource.h +++ b/cl_headers/resource.h @@ -19,7 +19,20 @@ Copyright (c) Intel Corporation (2009-2017). #ifndef __RESOURCE__ #define __RESOURCE__ -#define OPENCL_C_H "OPENCL_C_H" -#define OPENCL_C_BASE_H "OPENCL_C_BASE_H" +#define OPENCL_C_H "OPENCL_C_H" +#define OPENCL_C_BASE_H "OPENCL_C_BASE_H" +#define OPENCL_C_12_SPIR_PCM "OPENCL_C_12_SPIR_PCM" +#define OPENCL_C_20_SPIR_PCM "OPENCL_C_20_SPIR_PCM" +#define OPENCL_C_30_SPIR_PCM "OPENCL_C_30_SPIR_PCM" +#define OPENCL_C_12_SPIR64_PCM "OPENCL_C_12_SPIR64_PCM" +#define OPENCL_C_20_SPIR64_PCM "OPENCL_C_20_SPIR64_PCM" +#define OPENCL_C_30_SPIR64_PCM "OPENCL_C_30_SPIR64_PCM" +#define OPENCL_C_12_SPIR_FP64_PCM "OPENCL_C_12_SPIR_FP64_PCM" +#define OPENCL_C_20_SPIR_FP64_PCM "OPENCL_C_20_SPIR_FP64_PCM" +#define OPENCL_C_30_SPIR_FP64_PCM "OPENCL_C_30_SPIR_FP64_PCM" +#define OPENCL_C_12_SPIR64_FP64_PCM "OPENCL_C_12_SPIR64_FP64_PCM" +#define OPENCL_C_20_SPIR64_FP64_PCM "OPENCL_C_20_SPIR64_FP64_PCM" +#define OPENCL_C_30_SPIR64_FP64_PCM "OPENCL_C_30_SPIR64_FP64_PCM" +#define OPENCL_C_MODULE_MAP "OPENCL_C_MODULE_MAP" #endif /* __RESOURCE__ */ diff --git a/common_clang.cpp b/common_clang.cpp index 4d4432a8..79abbd79 100644 --- a/common_clang.cpp +++ b/common_clang.cpp @@ -113,17 +113,30 @@ void CommonClangInitialize() { } static bool GetHeaders(std::vector &Result) { - struct {const char *ID; const char *Name;} Headers[] = { - {OPENCL_C_H, "opencl-c.h"}, - {OPENCL_C_BASE_H, "opencl-c-base.h"}, - }; + struct { + const char *ID; + const char *Name; + } Headers[] = {{OPENCL_C_H, "opencl-c.h"}, + {OPENCL_C_BASE_H, "opencl-c-base.h"}, + {OPENCL_C_12_SPIR_PCM, "opencl-c-12-spir.pcm"}, + {OPENCL_C_20_SPIR_PCM, "opencl-c-20-spir.pcm"}, + {OPENCL_C_30_SPIR_PCM, "opencl-c-30-spir.pcm"}, + {OPENCL_C_12_SPIR64_PCM, "opencl-c-12-spir64.pcm"}, + {OPENCL_C_20_SPIR64_PCM, "opencl-c-20-spir64.pcm"}, + {OPENCL_C_30_SPIR64_PCM, "opencl-c-30-spir64.pcm"}, + {OPENCL_C_12_SPIR_FP64_PCM, "opencl-c-12-spir-fp64.pcm"}, + {OPENCL_C_20_SPIR_FP64_PCM, "opencl-c-20-spir-fp64.pcm"}, + {OPENCL_C_30_SPIR_FP64_PCM, "opencl-c-30-spir-fp64.pcm"}, + {OPENCL_C_12_SPIR64_FP64_PCM, "opencl-c-12-spir64-fp64.pcm"}, + {OPENCL_C_20_SPIR64_FP64_PCM, "opencl-c-20-spir64-fp64.pcm"}, + {OPENCL_C_30_SPIR64_FP64_PCM, "opencl-c-30-spir64-fp64.pcm"}, + {OPENCL_C_MODULE_MAP, "module.modulemap"}}; Result.clear(); Result.reserve(sizeof(Headers) / sizeof(*Headers)); ResourceManager &RM = ResourceManager::instance(); - - for (auto Header:Headers) { + for (auto Header : Headers) { Resource R = RM.get_resource(Header.Name, Header.ID, "PCM", true); if (!R) { assert(0 && "Resource not found"); diff --git a/common_clang.map b/common_clang.map index b91ae9ce..62e059d4 100644 --- a/common_clang.map +++ b/common_clang.map @@ -8,6 +8,19 @@ global: GetKernelArgInfo; PCM_OPENCL_C_H*; PCM_OPENCL_C_BASE_H*; + PCM_OPENCL_C_12_SPIR_PCM*; + PCM_OPENCL_C_20_SPIR_PCM*; + PCM_OPENCL_C_30_SPIR_PCM*; + PCM_OPENCL_C_12_SPIR64_PCM*; + PCM_OPENCL_C_20_SPIR64_PCM*; + PCM_OPENCL_C_30_SPIR64_PCM*; + PCM_OPENCL_C_12_SPIR_FP64_PCM*; + PCM_OPENCL_C_20_SPIR_FP64_PCM*; + PCM_OPENCL_C_30_SPIR_FP64_PCM*; + PCM_OPENCL_C_12_SPIR64_FP64_PCM*; + PCM_OPENCL_C_20_SPIR64_FP64_PCM*; + PCM_OPENCL_C_30_SPIR64_FP64_PCM*; + PCM_OPENCL_C_MODULE_MAP*; }; local: *; }; diff --git a/linux_linker/CMakeLists.txt b/linux_linker/CMakeLists.txt index 800e7098..aad5ffa4 100644 --- a/linux_linker/CMakeLists.txt +++ b/linux_linker/CMakeLists.txt @@ -1 +1,11 @@ -ADD_EXECUTABLE(linux_resource_linker linux_resource_linker) +add_executable(linux_resource_linker linux_resource_linker.cpp) + +if(LLVM_USE_HOST_TOOLS) + build_native_tool(linux_resource_linker LINUX_RESOURCE_LINKER_COMMAND) + add_custom_target(linux_resource_linker-host DEPENDS ${LINUX_RESOURCE_LINKER_COMMAND} ) + add_dependencies(linux_resource_linker linux_resource_linker-host) +else() + set(LINUX_RESOURCE_LINKER_COMMAND linux_resource_linker) +endif() + +set(LINUX_RESOURCE_LINKER_COMMAND ${LINUX_RESOURCE_LINKER_COMMAND} PARENT_SCOPE) diff --git a/options_compile.cpp b/options_compile.cpp index 84997da3..b74056d3 100644 --- a/options_compile.cpp +++ b/options_compile.cpp @@ -25,6 +25,8 @@ Copyright (c) Intel Corporation (2009-2017). #include "llvm/Support/ManagedStatic.h" #include "llvm/Support/Mutex.h" +#include +#include #include #define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE; @@ -64,6 +66,7 @@ std::string EffectiveOptionsFilter::processOptions(const OpenCLArgList &args, ArgsVector &effectiveArgs) { // Reset args int iCLStdSet = 0; + bool fp64Enabled = false; std::string szTriple; std::string sourceName(llvm::Twine(s_progID++).str()); @@ -225,6 +228,103 @@ std::string EffectiveOptionsFilter::processOptions(const OpenCLArgList &args, std::back_insert_iterator it(std::back_inserter(effectiveArgs)); quoted_tokenize(it, pszOptionsEx, " \t", '"', '\x00'); + for (auto it = effectiveArgs.begin(), end = effectiveArgs.end(); it != end; + ++it) { + if (it->compare("-Dcl_khr_fp64") == 0) + fp64Enabled = true; + } + + std::map extMap{ + {"cl_khr_3d_image_writes", true}, + {"cl_khr_depth_images", true}, + {"cl_khr_fp16", true}, +#ifdef _WIN32 + // cl_khr_gl_msaa_sharing is only supported on Windows [NEO]. + {"cl_khr_gl_msaa_sharing", true}, +#endif + {"cl_khr_global_int32_base_atomics", true}, + {"cl_khr_global_int32_extended_atomics", true}, + {"cl_khr_int64_base_atomics", true}, + {"cl_khr_int64_extended_atomics", true}, + {"cl_khr_local_int32_base_atomics", true}, + {"cl_khr_local_int32_extended_atomics", true}, + {"cl_khr_mipmap_image", true}, + {"cl_khr_mipmap_image_writes", true}, + {"cl_khr_subgroups", true}, + {"cl_intel_device_side_avc_motion_estimation", true}, + {"cl_intel_planar_yuv", true}, + {"cl_intel_subgroups", true}, + {"cl_intel_subgroups_short", true}}; + + auto parseClExt = [&](const std::string &clExtStr) { + llvm::StringRef clExtRef(clExtStr); + clExtRef.consume_front("-cl-ext="); + llvm::SmallVector parsedExt; + clExtRef.split(parsedExt, ','); + for (auto ext : parsedExt) { + char sign = ext.front(); + bool enabled = sign != '-'; + llvm::StringRef extName = ext; + if (sign == '+' || sign == '-') + extName = extName.drop_front(); + if (extName == "all") { + for (auto &p : extMap) + p.second = enabled; + continue; + } + auto it = extMap.find(extName.str()); + if (it != extMap.end()) + it->second = enabled; + } + }; + std::for_each(effectiveArgs.begin(), effectiveArgs.end(), + [&](const ArgsVector::value_type &a) { + if (a.find("-cl-ext=") == 0) + parseClExt(a); + }); + // extension is enabled in PCH but disabled or not specifed in options => + // disable pch + bool useModules = + !std::any_of(extMap.begin(), extMap.end(), + [](const auto &p) { return p.second == false; }); + + if (useModules) { + effectiveArgs.push_back("-fmodules"); + if (!fp64Enabled) { + if (szTriple.find("spir64") != szTriple.npos) { + if (iCLStdSet <= 120) + effectiveArgs.push_back("-fmodule-file=opencl-c-12-spir64.pcm"); + else if (iCLStdSet == 200) + effectiveArgs.push_back("-fmodule-file=opencl-c-20-spir64.pcm"); + else if (iCLStdSet == 300) + effectiveArgs.push_back("-fmodule-file=opencl-c-30-spir64.pcm"); + } else if (szTriple.find("spir") != szTriple.npos) { + if (iCLStdSet <= 120) + effectiveArgs.push_back("-fmodule-file=opencl-c-12-spir.pcm"); + else if (iCLStdSet == 200) + effectiveArgs.push_back("-fmodule-file=opencl-c-20-spir.pcm"); + else if (iCLStdSet == 300) + effectiveArgs.push_back("-fmodule-file=opencl-c-30-spir.pcm"); + } + } else { + if (szTriple.find("spir64") != szTriple.npos) { + if (iCLStdSet <= 120) + effectiveArgs.push_back("-fmodule-file=opencl-c-12-spir64-fp64.pcm"); + else if (iCLStdSet == 200) + effectiveArgs.push_back("-fmodule-file=opencl-c-20-spir64-fp64.pcm"); + else if (iCLStdSet == 300) + effectiveArgs.push_back("-fmodule-file=opencl-c-30-spir64-fp64.pcm"); + } else if (szTriple.find("spir") != szTriple.npos) { + if (iCLStdSet <= 120) + effectiveArgs.push_back("-fmodule-file=opencl-c-12-spir-fp64.pcm"); + else if (iCLStdSet == 200) + effectiveArgs.push_back("-fmodule-file=opencl-c-20-spir-fp64.pcm"); + else if (iCLStdSet == 300) + effectiveArgs.push_back("-fmodule-file=opencl-c-30-spir-fp64.pcm"); + } + } + } + // add source name to options as an input file assert(!sourceName.empty() && "Empty source name."); effectiveArgs.push_back(sourceName);