From 28d6d9ad2c87274929445b79f4c94086f1a177ca Mon Sep 17 00:00:00 2001 From: Yifei1 He Date: Tue, 23 Jun 2020 17:24:44 +0800 Subject: [PATCH] Enable precompiled headers --- cl_headers/CMakeLists.txt | 85 ++++++++++++++++++++++++++++++++- cl_headers/OpenCL.rc | 13 ++++- cl_headers/module.modulemap | 40 ++++++++++++++++ cl_headers/resource.h | 10 ++++ common_clang.cpp | 9 ++++ common_clang.map | 9 ++++ options_compile.cpp | 95 ++++++++++++++++++++++++++++++++++++- 7 files changed, 258 insertions(+), 3 deletions(-) create mode 100644 cl_headers/module.modulemap diff --git a/cl_headers/CMakeLists.txt b/cl_headers/CMakeLists.txt index 519d210a..9dae6b45 100644 --- a/cl_headers/CMakeLists.txt +++ b/cl_headers/CMakeLists.txt @@ -19,14 +19,68 @@ 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} + 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() + +set(OPTS -cl-ext=+all,-cl_khr_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-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}") +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-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}") + +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 + opencl-c-12-spir-fp64.pcm + opencl-c-20-spir-fp64.pcm + opencl-c-12-spir64-fp64.pcm + opencl-c-20-spir64-fp64.pcm +) function(pack_to_obj SRC DST TAG) add_custom_command ( @@ -40,16 +94,45 @@ endfunction(pack_to_obj) if(WIN32) list(APPEND CL_HEADERS_SRC OpenCL.rc) else() + pack_to_obj(opencl-c.h opencl-c.h.cpp "PCM_OPENCL_C_H") pack_to_obj(opencl-c-base.h opencl-c-base.h.cpp "PCM_OPENCL_C_BASE_H") 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-12-spir64.mod.cpp + opencl-c-20-spir64.mod.cpp + opencl-c-12-spir-fp64.mod.cpp + opencl-c-20-spir-fp64.mod.cpp + opencl-c-12-spir64-fp64.mod.cpp + opencl-c-20-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-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-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-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(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..bcfe7791 100644 --- a/cl_headers/OpenCL.rc +++ b/cl_headers/OpenCL.rc @@ -12,4 +12,15 @@ END // OPENCL_C_H PCM "opencl-c.h" -OPENCL_C_BASE_H PCM "opencl-c-base.h" \ No newline at end of file +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_12_SPIR64_PCM PCM "opencl-c-12-spir64.pcm" +OPENCL_C_20_SPIR64_PCM PCM "opencl-c-20-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_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_MODULE_MAP PCM "module.modulemap" diff --git a/cl_headers/module.modulemap b/cl_headers/module.modulemap new file mode 100644 index 00000000..5c4adf82 --- /dev/null +++ b/cl_headers/module.modulemap @@ -0,0 +1,40 @@ +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 cl12spir64 { + header "opencl-c.h" + header "opencl-c-base.h" + export * +} +module cl20spir64 { + 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 cl12spir64fp64 { + header "opencl-c.h" + header "opencl-c-base.h" + export * +} +module cl20spir64fp64 { + header "opencl-c.h" + header "opencl-c-base.h" + export * +} diff --git a/cl_headers/resource.h b/cl_headers/resource.h index 474b5650..53b79c95 100644 --- a/cl_headers/resource.h +++ b/cl_headers/resource.h @@ -22,4 +22,14 @@ Copyright (c) Intel Corporation (2009-2017). #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_12_SPIR64_PCM "OPENCL_C_12_SPIR64_PCM" +#define OPENCL_C_20_SPIR64_PCM "OPENCL_C_20_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_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_MODULE_MAP "OPENCL_C_MODULE_MAP" + #endif /* __RESOURCE__ */ diff --git a/common_clang.cpp b/common_clang.cpp index 3d682aae..e4202e12 100644 --- a/common_clang.cpp +++ b/common_clang.cpp @@ -116,6 +116,15 @@ 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"}, + {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_12_SPIR_FP64_PCM, "opencl-c-12-spir-fp64.pcm"}, + {OPENCL_C_20_SPIR_FP64_PCM, "opencl-c-20-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_MODULE_MAP, "module.modulemap"} }; Result.clear(); diff --git a/common_clang.map b/common_clang.map index b91ae9ce..74cbf7a8 100644 --- a/common_clang.map +++ b/common_clang.map @@ -8,6 +8,15 @@ 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_12_SPIR64_PCM*; + PCM_OPENCL_C_20_SPIR64_PCM*; + PCM_OPENCL_C_12_SPIR_FP64_PCM*; + PCM_OPENCL_C_20_SPIR_FP64_PCM*; + PCM_OPENCL_C_12_SPIR64_FP64_PCM*; + PCM_OPENCL_C_20_SPIR64_FP64_PCM*; + PCM_OPENCL_C_MODULE_MAP*; }; local: *; }; diff --git a/options_compile.cpp b/options_compile.cpp index a187cb34..609f9f4c 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; + int fp64Enable = 0; std::string szTriple; std::string sourceName(llvm::Twine(s_progID++).str()); @@ -199,7 +202,6 @@ std::string EffectiveOptionsFilter::processOptions(const OpenCLArgList &args, } effectiveArgs.push_back(szTriple); - effectiveArgs.push_back("-include"); effectiveArgs.push_back("opencl-c.h"); @@ -228,6 +230,97 @@ std::string EffectiveOptionsFilter::processOptions(const OpenCLArgList &args, std::back_insert_iterator it(std::back_inserter(effectiveArgs)); quoted_tokenize(it, pszOptionsEx, " \t", '"', '\x00'); + for (ArgsVector::iterator it = effectiveArgs.begin(), + end = effectiveArgs.end(); + it != end; ++it) { + if (it->compare("-Dcl_khr_fp64") == 0) { + fp64Enable = true; + } + } + + std::map extMap { + {"cl_khr_3d_image_writes", true}, + {"cl_khr_depth_images", true}, + {"cl_khr_fp16", true}, + {"cl_khr_gl_msaa_sharing", true}, + {"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 (llvm::StringRef 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); + 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(), + [](decltype(*begin(extMap))p) {return p.second == false;}); + + if (useModules) { + effectiveArgs.push_back("-fmodules"); + if (fp64Enable == 0) { + 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"); + } + } + } else if (fp64Enable == 1) { + if (szTriple.find("spir64") != szTriple.npos) { + if (iCLStdSet <= 120) { + effectiveArgs.push_back("-fmodule-file=opencl-c-12-spir64-fp64.pcm"); + } else { + effectiveArgs.push_back("-fmodule-file=opencl-c-20-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 { + effectiveArgs.push_back("-fmodule-file=opencl-c-20-spir-fp64.pcm"); + } + } + } + } + // add source name to options as an input file assert(!sourceName.empty() && "Empty source name."); effectiveArgs.push_back(sourceName);