diff --git a/CMakeLists.txt b/CMakeLists.txt index ea0b1d94..b074aa47 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -116,6 +116,7 @@ add_public_tablegen_target(CClangCompileOptions) # Source code # set(TARGET_INCLUDE_FILES + exceptions.h common_clang.h options.h binary_result.h diff --git a/cl_headers/CMakeLists.txt b/cl_headers/CMakeLists.txt index 3dd2ea4c..fcf3c59a 100644 --- a/cl_headers/CMakeLists.txt +++ b/cl_headers/CMakeLists.txt @@ -18,13 +18,57 @@ else(USE_PREBUILT_LLVM) set(OPENCL_HEADERS_DIR "${CLANG_SOURCE_DIR}/lib/Headers") endif(USE_PREBUILT_LLVM) copy_file(${OPENCL_HEADERS_DIR}/opencl-c.h opencl-c.h) +copy_file(${CMAKE_CURRENT_SOURCE_DIR}/module.modulemap module.modulemap) add_custom_target ( opencl.headers.target DEPENDS + module.modulemap opencl-c.h ) +function(create_pcm DST MODULE HEADER OPTS DEPS) + add_custom_command ( + OUTPUT ${DST} + MAIN_DEPENDENCY ${MODMAP} + DEPENDS ${HEADER} ${DEPS} + 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(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() + +create_pcm(opencl-c-12-spir.pcm cl12spir opencl-c.h "${SPIR_TRIPLE};${CL12};${OPTS}" "${DEPS}") +create_pcm(opencl-c-20-spir.pcm cl20spir opencl-c.h "${SPIR_TRIPLE};${CL20};${OPTS}" "${DEPS}") +create_pcm(opencl-c-12-spir64.pcm cl12spir64 opencl-c.h "${SPIR64_TRIPLE};${CL12};${OPTS}" "${DEPS}") +create_pcm(opencl-c-20-spir64.pcm cl20spir64 opencl-c.h "${SPIR64_TRIPLE};${CL20};${OPTS}" "${DEPS}") + +add_custom_target ( + opencl.pcm.target + DEPENDS + opencl.headers.target + opencl-c-12-spir.pcm + opencl-c-20-spir.pcm + opencl-c-12-spir64.pcm + opencl-c-20-spir64.pcm +) function(pack_to_obj SRC DST TAG) add_custom_command ( @@ -41,7 +85,21 @@ else() pack_to_obj(opencl-c.h opencl-c.h.cpp "PCM_OPENCL_C_H") list(APPEND CL_HEADERS_SRC opencl-c.h.cpp + opencl-c-12-spir.mod.cpp + opencl-c-20-spir.mod.cpp + opencl-c-12-spir64.mod.cpp + opencl-c-20-spir64.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-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(module.modulemap module.modulemap.cpp "PCM_OPENCL_C_MODULE_MAP") + endif() add_library(${CL_HEADERS_LIB} OBJECT @@ -49,3 +107,8 @@ add_library(${CL_HEADERS_LIB} OBJECT ) add_dependencies(${CL_HEADERS_LIB} opencl.headers.target) +install(FILES + ${CMAKE_CURRENT_BINARY_DIR}/opencl-c.h + ${CMAKE_CURRENT_BINARY_DIR}/module.modulemap + DESTINATION include/cclang +) diff --git a/cl_headers/OpenCL.rc b/cl_headers/OpenCL.rc index 955c3c3a..a13c1791 100644 --- a/cl_headers/OpenCL.rc +++ b/cl_headers/OpenCL.rc @@ -12,3 +12,10 @@ END // OPENCL_C_H PCM "opencl-c.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_12_SPIR64_PCM PCM "opencl-c-12-spir64.pcm" +OPENCL_C_20_SPIR64_PCM PCM "opencl-c-20-spir64.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..48cb1efc --- /dev/null +++ b/cl_headers/module.modulemap @@ -0,0 +1,16 @@ +module cl12spir { + header "opencl-c.h" + export * +} +module cl20spir { + header "opencl-c.h" + export * +} +module cl12spir64 { + header "opencl-c.h" + export * +} +module cl20spir64 { + header "opencl-c.h" + export * +} diff --git a/cl_headers/module.mudulemap b/cl_headers/module.mudulemap new file mode 100644 index 00000000..48cb1efc --- /dev/null +++ b/cl_headers/module.mudulemap @@ -0,0 +1,16 @@ +module cl12spir { + header "opencl-c.h" + export * +} +module cl20spir { + header "opencl-c.h" + export * +} +module cl12spir64 { + header "opencl-c.h" + export * +} +module cl20spir64 { + header "opencl-c.h" + export * +} diff --git a/cl_headers/resource.h b/cl_headers/resource.h index c03b11bc..2ddc815f 100644 --- a/cl_headers/resource.h +++ b/cl_headers/resource.h @@ -20,5 +20,10 @@ Copyright (c) Intel Corporation (2009-2017). #define __RESOURCE__ #define OPENCL_C_H "OPENCL_C_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_12_SPIR64_PCM "OPENCL_C_12_SPIR64_PCM" +#define OPENCL_C_20_SPIR64_PCM "OPENCL_C_20_SPIR64_PCM" +#define OPENCL_C_MODULE_MAP "OPENCL_C_MODULE_MAP" #endif /* __RESOURCE__ */ diff --git a/common_clang.cpp b/common_clang.cpp index ee1ec9b1..f576fa64 100644 --- a/common_clang.cpp +++ b/common_clang.cpp @@ -19,6 +19,7 @@ Copyright (c) Intel Corporation (2009-2017). #include "common_clang.h" #include "pch_mgr.h" #include "cl_headers/resource.h" +#include "exceptions.h" #include "binary_result.h" #include "options.h" @@ -115,6 +116,11 @@ void CommonClangInitialize() { static bool GetHeaders(std::vector &Result) { struct {const char *ID; const char *Name;} Headers[] = { {OPENCL_C_H, "opencl-c.h"}, + {OPENCL_C_12_SPIR_PCM, "opencl-c-12-spir.pcm"}, + {OPENCL_C_20_SPIR_PCM, "opencl-c-20-spir.pcm"}, + {OPENCL_C_12_SPIR64_PCM, "opencl-c-12-spir64.pcm"}, + {OPENCL_C_20_SPIR64_PCM, "opencl-c-20-spir64.pcm"}, + {OPENCL_C_MODULE_MAP, "module.modulemap"} }; Result.clear(); @@ -337,5 +343,11 @@ Compile(const char *pszProgramSource, const char **pInputHeaders, *pBinaryResult = NULL; } return CL_OUT_OF_HOST_MEMORY; + } catch (pch_error &) { + if (pBinaryResult) { + *pBinaryResult = NULL; + } + assert(false && " Common_clang. Something wrong with PCHs."); + return CL_COMPILE_PROGRAM_FAILURE; } } diff --git a/common_clang.map b/common_clang.map index 7dea9161..5a2c684d 100644 --- a/common_clang.map +++ b/common_clang.map @@ -7,6 +7,11 @@ global: Link; GetKernelArgInfo; PCM_OPENCL_C_H*; + PCM_OPENCL_C_12_SPIR_PCM*; + PCM_OPENCL_C_20_SPIR_PCM*; + PCM_OPENCL_C_12_SPIR64_PCM*; + PCM_OPENCL_C_20_SPIR64_PCM*; + PCM_OPENCL_C_MODULE_MAP*; }; local: *; }; diff --git a/exceptions.h b/exceptions.h new file mode 100644 index 00000000..4d67ed5f --- /dev/null +++ b/exceptions.h @@ -0,0 +1,25 @@ +/*****************************************************************************\ +Copyright (c) Intel Corporation (2009-2020). + INTEL MAKES NO WARRANTY OF ANY KIND REGARDING THE CODE. THIS CODE IS + LICENSED ON AN "AS IS" BASIS AND INTEL WILL NOT PROVIDE ANY SUPPORT, + ASSISTANCE, INSTALLATION, TRAINING OR OTHER SERVICES. INTEL DOES NOT + PROVIDE ANY UPDATES, ENHANCEMENTS OR EXTENSIONS. INTEL SPECIFICALLY + DISCLAIMS ANY WARRANTY OF MERCHANTABILITY, NONINFRINGEMENT, FITNESS FOR ANY + PARTICULAR PURPOSE, OR ANY OTHER WARRANTY. Intel disclaims all liability, + including liability for infringement of any proprietary rights, relating to + use of the code. No license, express or implied, by estoppel or otherwise, + to any intellectual property rights is granted herein. + \file exceptions.h +\*****************************************************************************/ + +#pragma once +#include + +/// macro for convenient definition of common clang exceptions +#define DEFINE_COMMON_CLANG_EXCEPTION(__name) \ + class __name : public std::domain_error { \ + public: \ + __name(const std::string &str) : std::domain_error(str) {} \ + }; + +DEFINE_COMMON_CLANG_EXCEPTION(pch_error) diff --git a/options_compile.cpp b/options_compile.cpp index 6b52bc3d..3de980b5 100644 --- a/options_compile.cpp +++ b/options_compile.cpp @@ -196,6 +196,21 @@ std::string EffectiveOptionsFilter::processOptions(const OpenCLArgList &args, effectiveArgs.push_back(szTriple); + effectiveArgs.push_back("-fmodules"); + if (szTriple.find("spir64") != szTriple.npos) { + if (iCLStdSet <= 120) { + effectiveArgs.push_back("-fmodule-file=opencl-c-12-spir64.pcm"); + } else { + effectiveArgs.push_back("-fmodule-file=opencl-c-20-spir64.pcm"); + } + } else if (szTriple.find("spir") != szTriple.npos) { + if (iCLStdSet <= 120) { + effectiveArgs.push_back("-fmodule-file=opencl-c-12-spir.pcm"); + } else { + effectiveArgs.push_back("-fmodule-file=opencl-c-20-spir.pcm"); + } + } + effectiveArgs.push_back("-include"); effectiveArgs.push_back("opencl-c.h"); diff --git a/pch_mgr.cpp b/pch_mgr.cpp index 67d7e7a9..ad89f443 100644 --- a/pch_mgr.cpp +++ b/pch_mgr.cpp @@ -17,6 +17,7 @@ Copyright (c) Intel Corporation (2009-2017). \*****************************************************************************/ #include "pch_mgr.h" +#include "exceptions.h" #include "llvm/Object/ELF.h" #include "llvm/ADT/Twine.h"