summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backend/CMakeLists.txt8
-rw-r--r--backend/src/CMakeLists.txt135
-rw-r--r--backend/src/GBEConfig.h.in5
-rw-r--r--backend/src/backend/program.cpp276
-rw-r--r--backend/src/libocl/CMakeLists.txt209
-rw-r--r--backend/src/libocl/include/ocl.h23
-rw-r--r--backend/src/llvm/llvm_to_gen.cpp70
-rw-r--r--utests/setenv.sh.in5
8 files changed, 379 insertions, 352 deletions
diff --git a/backend/CMakeLists.txt b/backend/CMakeLists.txt
index ca674cfb..832eda86 100644
--- a/backend/CMakeLists.txt
+++ b/backend/CMakeLists.txt
@@ -99,12 +99,14 @@ include_directories (${CMAKE_CURRENT_BINARY_DIR})
# Project source code
##############################################################
add_subdirectory (src)
-set(LOCAL_PCH_OBJECT_DIR ${LOCAL_PCH_OBJECT_DIR} PARENT_SCOPE)
-set(LOCAL_PCM_OBJECT_DIR ${LOCAL_PCM_OBJECT_DIR} PARENT_SCOPE)
+set(LOCAL_OCL_BITCODE_BIN "${LOCAL_OCL_BITCODE_BIN}" PARENT_SCOPE)
+set(LOCAL_OCL_HEADER_DIR "${LOCAL_OCL_HEADER_DIR}" PARENT_SCOPE)
+set(LOCAL_OCL_PCH_OBJECT "${LOCAL_OCL_PCH_OBJECT}" PARENT_SCOPE)
+
set(LOCAL_GBE_OBJECT_DIR ${LOCAL_GBE_OBJECT_DIR} PARENT_SCOPE)
set(LOCAL_INTERP_OBJECT_DIR ${LOCAL_INTERP_OBJECT_DIR} PARENT_SCOPE)
set (GBE_BIN_GENERATER
- OCL_PCM_PATH=${LOCAL_PCM_OBJECT_DIR} OCL_PCH_PATH=${LOCAL_PCH_OBJECT_DIR} LD_LIBRARY_PATH=${CMAKE_CURRENT_BINARY_DIR}/src ${CMAKE_CURRENT_BINARY_DIR}/src/gbe_bin_generater
+ OCL_BITCODE_BIN=${LOCAL_OCL_BITCODE_BIN} OCL_HEADER_DIR=${LOCAL_OCL_HEADER_DIR} OCL_PCH_OBJECT=${LOCAL_OCL_PCH_OBJECT} LD_LIBRARY_PATH=${CMAKE_CURRENT_BINARY_DIR}/src ${CMAKE_CURRENT_BINARY_DIR}/src/gbe_bin_generater
PARENT_SCOPE)
diff --git a/backend/src/CMakeLists.txt b/backend/src/CMakeLists.txt
index 85b5e21e..1df87324 100644
--- a/backend/src/CMakeLists.txt
+++ b/backend/src/CMakeLists.txt
@@ -1,95 +1,25 @@
-set (ocl_vector_spec_file ${GBE_SOURCE_DIR}/src/builtin_vector_proto.def)
-set (ocl_vector_file ${GBE_SOURCE_DIR}/src/ocl_vector.h)
-set (ocl_as_file ${GBE_SOURCE_DIR}/src/ocl_as.h)
-set (ocl_convert_file ${GBE_SOURCE_DIR}/src/ocl_convert.h)
-set (ocl_stdlib_tmpl_file ${GBE_SOURCE_DIR}/src/ocl_stdlib.tmpl.h)
-set (ocl_common_header_file ${GBE_SOURCE_DIR}/src/ocl_common_defines.h)
-set (ocl_blob_file ${CMAKE_CURRENT_BINARY_DIR}${BEIGNET_INSTALL_DIR}ocl_stdlib.h)
-set (ocl_blob_cpp_file ${GBE_SOURCE_DIR}/src/ocl_stdlib_str.cpp)
-set (ocl_gen_blob_cmd ${GBE_SOURCE_DIR}/src/update_blob_ocl_header.py)
-set (ocl_gen_vector_cmd ${GBE_SOURCE_DIR}/src/gen_builtin_vector.py)
-
-set (string_header "\\\"string\\\"")
-add_custom_command(
- OUTPUT ${ocl_blob_cpp_file}
- COMMAND rm -rf ${ocl_blob_cpp_file}
- COMMAND echo "\\\#include ${string_header}" >> ${ocl_blob_cpp_file}
- COMMAND echo "namespace gbe {" >> ${ocl_blob_cpp_file}
- COMMAND echo "std::string ocl_stdlib_str = " >> ${ocl_blob_cpp_file}
- # Yeah!!! welcome to back slash hell
- COMMAND cat ${ocl_blob_file} |sed 's/\\\\/\\\\\\\\/g' | sed 's/\\\"/\\\\\\\"/g' | awk '{ printf \(\"\\"%s\\\\n\\"\\n\", $$0\) }' >> ${ocl_blob_cpp_file}
- COMMAND echo "\;" >> ${ocl_blob_cpp_file}
- COMMAND echo "}" >> ${ocl_blob_cpp_file}
- COMMAND echo "" >> ${ocl_blob_cpp_file}
- DEPENDS ${ocl_blob_file})
-
-set_property(DIRECTORY APPEND PROPERTY ADDITIONAL_MAKE_CLEAN_FILES "ocl_vector.h;${ocl_blob_file}")
-
-add_custom_command(
- OUTPUT ${ocl_vector_file}
- COMMAND ${PYTHON_EXECUTABLE} ${ocl_gen_vector_cmd} ${ocl_vector_spec_file} ${ocl_vector_file}
- DEPENDS ${ocl_gen_vector_cmd} ${ocl_vector_spec_file}
- )
-
-add_custom_command(
- OUTPUT ${ocl_blob_file}
- COMMAND mkdir -p ${CMAKE_CURRENT_BINARY_DIR}/${BEIGNET_INSTALL_DIR}
- COMMAND ${PYTHON_EXECUTABLE} ${ocl_gen_blob_cmd} ${ocl_stdlib_tmpl_file} ${ocl_blob_file}
- DEPENDS ${ocl_gen_blob_cmd} ${ocl_stdlib_tmpl_file} ${ocl_common_header_file} ${ocl_vector_file} ${ocl_as_file} ${ocl_convert_file}
- )
-
-set (pch_object ${ocl_blob_file}.pch)
-set (local_pch_object ${ocl_blob_file}.local.pch)
-# generate pch object
-if (LLVM_VERSION_NODOT VERSION_GREATER 32)
- set (clang_cmd -cc1 -x cl -triple spir -ffp-contract=off -cl-kernel-arg-info)
-else (LLVM_VERSION_NODOT VERSION_GREATER 32)
- if (LLVM_VERSION_NODOT VERSION_GREATER 31)
- set (clang_cmd -cc1 -x cl -triple nvptx -ffp-contract=off)
- else (LLVM_VERSION_NODOT VERSION_GREATER 31)
- set (clang_cmd -cc1 -x cl -triple ptx32)
- endif (LLVM_VERSION_NODOT VERSION_GREATER 31)
-endif (LLVM_VERSION_NODOT VERSION_GREATER 32)
-set (clang_cmd ${clang_cmd} -fno-builtin -DGEN7_SAMPLER_CLAMP_BORDER_WORKAROUND)
+set (OCL_BITCODE_BIN "${BEIGNET_INSTALL_DIR}beignet.bc:${CMAKE_CURRENT_BINARY_DIR}/libocl/lib/beignet.bc")
+set (OCL_HEADER_DIR "${CMAKE_INSTALL_PREFIX}/include/CL/ocl/:${CMAKE_CURRENT_BINARY_DIR}/libocl/include/")
+set (OCL_PCH_OBJECT "${BEIGNET_INSTALL_DIR}beignet.pch:${CMAKE_CURRENT_BINARY_DIR}/libocl/lib/beignet.pch")
+set (GBE_OBJECT_DIR "${BEIGNET_INSTALL_DIR}/libgbe.so")
+set (INTERP_OBJECT_DIR "${BEIGNET_INSTALL_DIR}/libgbeinterp.so")
-add_custom_command(
- OUTPUT ${pch_object}
- COMMAND rm -f ${pch_object}
- COMMAND ${LLVM_INSTALL_DIR}clang ${clang_cmd} --relocatable-pch -emit-pch -isysroot ${CMAKE_CURRENT_BINARY_DIR} ${ocl_blob_file} -o ${pch_object}
- COMMAND ${LLVM_INSTALL_DIR}clang ${clang_cmd} -emit-pch ${ocl_blob_file} -o ${local_pch_object}
- DEPENDS ${ocl_blob_file}
- )
+set (LOCAL_GBE_OBJECT_DIR "${CMAKE_CURRENT_BINARY_DIR}/libgbe.so" PARENT_SCOPE)
+set (LOCAL_OCL_BITCODE_BIN "${CMAKE_CURRENT_BINARY_DIR}/libocl/lib/beignet.bc" PARENT_SCOPE)
+set (LOCAL_OCL_HEADER_DIR "${CMAKE_CURRENT_BINARY_DIR}/libocl/include/" PARENT_SCOPE)
+set (LOCAL_OCL_PCH_OBJECT "${CMAKE_CURRENT_BINARY_DIR}/libocl/lib/beignet.pch" PARENT_SCOPE)
+set (LOCAL_INTERP_OBJECT_DIR "${CMAKE_CURRENT_BINARY_DIR}/libgbeinterp.so" PARENT_SCOPE)
-add_custom_target(pch_object
- DEPENDS ${pch_object})
+configure_file (
+ "GBEConfig.h.in"
+ "GBEConfig.h"
+)
-macro(ll_add_library ll_lib ll_sources)
- foreach (ll ${${ll_sources}})
- add_custom_command(
- OUTPUT ${ll}.bc
- COMMAND rm -f ${ll}.bc
- COMMAND ${LLVM_INSTALL_DIR}llvm-as -o ${ll}.bc ${GBE_SOURCE_DIR}/src/${ll}
- DEPENDS ${ll}
- )
- set (ll_objects ${ll_objects} ${ll}.bc)
- endforeach (ll ${ll_sources})
- add_custom_command(
- OUTPUT ${ll_lib}
- COMMAND ${LLVM_INSTALL_DIR}llvm-link -o ${ll_lib} ${ll_objects}
- DEPENDS ${ll_objects}
- )
- add_custom_target(${ll_lib}
- DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${ll_lib})
-endmacro(ll_add_library)
+add_subdirectory(libocl)
+add_dependencies(beignet_bitcode libocl)
-if (GBE_USE_BLOB)
- set (GBE_SRC
- blob.cpp
- backend/gen/gen_mesa_disasm.c)
-else (GBE_USE_BLOB)
- set (GBE_SRC
+set (GBE_SRC
${ocl_blob_file}
- ocl_stdlib_str.cpp # this file is auto-generated.
sys/vector.hpp
sys/hash_map.hpp
sys/map.hpp
@@ -143,6 +73,7 @@ else (GBE_USE_BLOB)
backend/program.cpp
backend/program.hpp
backend/program.h
+ llvm/llvm_bitcode_link.cpp
llvm/llvm_gen_backend.cpp
llvm/llvm_passes.cpp
llvm/llvm_scalarize.cpp
@@ -176,19 +107,13 @@ else (GBE_USE_BLOB)
backend/gen75_encoder.cpp
)
-endif (GBE_USE_BLOB)
include_directories (.)
link_directories (${LLVM_LIBRARY_DIRS} ${DRM_LIBDIR})
include_directories(${LLVM_INCLUDE_DIRS})
add_library (gbe SHARED ${GBE_SRC})
-# for pre compiled module library.
-set (pcm_lib "beignet.bc")
-set (pcm_sources ocl_barrier.ll ocl_memset.ll ocl_memcpy.ll)
-ll_add_library (${pcm_lib} pcm_sources)
-ADD_DEPENDENCIES (gbe pch_object ${pcm_lib})
target_link_libraries(
gbe
${DRM_INTEL_LIBRARIES}
@@ -201,6 +126,8 @@ target_link_libraries(
add_library(gbeinterp SHARED gbe_bin_interpreter.cpp)
+add_dependencies(gbe beignet_bitcode)
+
if (LLVM_VERSION_NODOT VERSION_EQUAL 34)
find_library(TERMINFO NAMES tinfo ncurses)
if (${TERMINFO} STREQUAL TERMINFO-NOTFOUND)
@@ -217,22 +144,6 @@ TARGET_LINK_LIBRARIES(gbe_bin_generater gbe)
install (TARGETS gbe LIBRARY DESTINATION ${BEIGNET_INSTALL_DIR})
install (TARGETS gbeinterp LIBRARY DESTINATION ${BEIGNET_INSTALL_DIR})
-#install (FILES backend/program.h DESTINATION include/gen)
-install (FILES ${ocl_blob_file} DESTINATION ${BEIGNET_INSTALL_DIR})
-install (FILES ${pch_object} DESTINATION ${BEIGNET_INSTALL_DIR})
-install (FILES ${CMAKE_CURRENT_BINARY_DIR}/${pcm_lib} DESTINATION ${BEIGNET_INSTALL_DIR})
-# When build beignet itself, we need to export the local precompiled header file and precompiled module
-# file to libcl and utests.
-set (LOCAL_PCH_OBJECT_DIR "${local_pch_object}:${BEIGNET_INSTALL_DIR}/ocl_stdlib.h.pch" PARENT_SCOPE)
-set (LOCAL_PCM_OBJECT_DIR "${CMAKE_CURRENT_BINARY_DIR}/${pcm_lib}:${BEIGNET_INSTALL_DIR}/${pcm_lib}" PARENT_SCOPE)
-set (LOCAL_GBE_OBJECT_DIR "${CMAKE_CURRENT_BINARY_DIR}/libgbe.so" PARENT_SCOPE)
-set (LOCAL_INTERP_OBJECT_DIR "${CMAKE_CURRENT_BINARY_DIR}/libgbeinterp.so" PARENT_SCOPE)
-
-set (PCH_OBJECT_DIR "${BEIGNET_INSTALL_DIR}/ocl_stdlib.h.pch")
-set (PCM_OBJECT_DIR "${BEIGNET_INSTALL_DIR}/${pcm_lib}")
-set (GBE_OBJECT_DIR "${BEIGNET_INSTALL_DIR}/libgbe.so")
-set (INTERP_OBJECT_DIR "${BEIGNET_INSTALL_DIR}/libgbeinterp.so")
-configure_file (
- "GBEConfig.h.in"
- "GBEConfig.h"
-)
+install (FILES ${CMAKE_CURRENT_BINARY_DIR}/libocl/lib/beignet.bc DESTINATION ${BEIGNET_INSTALL_DIR})
+install (FILES ${CMAKE_CURRENT_BINARY_DIR}/libocl/lib/beignet.pch DESTINATION ${BEIGNET_INSTALL_DIR})
+install (DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}/libocl/include/ DESTINATION ${CMAKE_INSTALL_PREFIX}/include/CL/ocl/ PATTERN *.h)
diff --git a/backend/src/GBEConfig.h.in b/backend/src/GBEConfig.h.in
index f5c69c68..b5bec14a 100644
--- a/backend/src/GBEConfig.h.in
+++ b/backend/src/GBEConfig.h.in
@@ -1,7 +1,8 @@
// the configured options and settings for LIBGBE
#define LIBGBE_VERSION_MAJOR @LIBGBE_VERSION_MAJOR@
#define LIBGBE_VERSION_MINOR @LIBGBE_VERSION_MINOR@
-#define PCH_OBJECT_DIR "@PCH_OBJECT_DIR@"
-#define PCM_OBJECT_DIR "@PCM_OBJECT_DIR@"
#define GBE_OBJECT_DIR "@GBE_OBJECT_DIR@"
#define INTERP_OBJECT_DIR "@INTERP_OBJECT_DIR@"
+#define OCL_BITCODE_BIN "@OCL_BITCODE_BIN@"
+#define OCL_HEADER_DIR "@OCL_HEADER_DIR@"
+#define OCL_PCH_OBJECT "@OCL_PCH_OBJECT@"
diff --git a/backend/src/backend/program.cpp b/backend/src/backend/program.cpp
index 20471f94..ac651d51 100644
--- a/backend/src/backend/program.cpp
+++ b/backend/src/backend/program.cpp
@@ -491,38 +491,6 @@ namespace gbe {
/*********************** End of Program class member function *************************/
-#define REDEF_MATH_FUNC(x) "#ifdef "#x"\n#undef "#x"\n#endif\n#define "#x" __gen_ocl_internal_fastpath_"#x"\n"
- std::string ocl_mathfunc_fastpath_str =
- REDEF_MATH_FUNC(acosh)
- REDEF_MATH_FUNC(asinh)
- REDEF_MATH_FUNC(atanh)
- REDEF_MATH_FUNC(cbrt)
- REDEF_MATH_FUNC(cos)
- REDEF_MATH_FUNC(cosh)
- REDEF_MATH_FUNC(cospi)
- REDEF_MATH_FUNC(exp)
- REDEF_MATH_FUNC(exp10)
- REDEF_MATH_FUNC(expm1)
- REDEF_MATH_FUNC(fmod)
- REDEF_MATH_FUNC(hypot)
- REDEF_MATH_FUNC(ilogb)
- REDEF_MATH_FUNC(ldexp)
- REDEF_MATH_FUNC(log)
- REDEF_MATH_FUNC(log2)
- REDEF_MATH_FUNC(log10)
- REDEF_MATH_FUNC(log1p)
- REDEF_MATH_FUNC(logb)
- REDEF_MATH_FUNC(remainder)
- REDEF_MATH_FUNC(rootn)
- REDEF_MATH_FUNC(sin)
- REDEF_MATH_FUNC(sincos)
- REDEF_MATH_FUNC(sinh)
- REDEF_MATH_FUNC(sinpi)
- REDEF_MATH_FUNC(tan)
- REDEF_MATH_FUNC(tanh)
- "\n"
- ;
-
static void programDelete(gbe_program gbeProgram) {
gbe::Program *program = (gbe::Program*)(gbeProgram);
GBE_SAFE_DELETE(program);
@@ -535,38 +503,21 @@ namespace gbe {
#ifdef GBE_COMPILER_AVAILABLE
BVAR(OCL_OUTPUT_BUILD_LOG, false);
- SVAR(OCL_PCH_PATH, PCH_OBJECT_DIR);
- SVAR(OCL_PCM_PATH, PCM_OBJECT_DIR);
- static bool buildModuleFromSource(const char* input, llvm::Module** out_module, llvm::LLVMContext* llvm_ctx, std::string options,
- size_t stringSize, char *err, size_t *errSize) {
+ static bool buildModuleFromSource(const char* input, llvm::Module** out_module, llvm::LLVMContext* llvm_ctx,
+ std::vector<std::string>& options, size_t stringSize, char *err,
+ size_t *errSize) {
// Arguments to pass to the clang frontend
vector<const char *> args;
bool bFastMath = false;
- vector<std::string> useless; //hold substrings to avoid c_str free
- size_t start = 0, end = 0;
- /* FIXME
- clang unsupport options:
- -cl-denorms-are-zero, -cl-strict-aliasing
- -cl-no-signed-zeros, -cl-fp32-correctly-rounded-divide-sqrt
- all support options, refer to clang/include/clang/Driver/Options.inc
- */
- //Handle -cl-opt-disable in llvmToGen, skip here
- const std::string unsupportedOptions("-cl-denorms-are-zero, -cl-strict-aliasing, -cl-opt-disable,"
- "-cl-no-signed-zeros, -cl-fp32-correctly-rounded-divide-sqrt");
- while (end != std::string::npos) {
- end = options.find(' ', start);
- std::string str = options.substr(start, end - start);
- start = end + 1;
- if(str.size() == 0)
- continue;
- if(str == "-cl-fast-relaxed-math") bFastMath = true;
- if(unsupportedOptions.find(str) != std::string::npos)
- continue;
- useless.push_back(str);
- args.push_back(str.c_str());
+ for (auto &s : options) {
+ args.push_back(s.c_str());
}
+
+ args.push_back("-cl-kernel-arg-info");
+ args.push_back("-Dcl_khr_fp64");
+
args.push_back("-mllvm");
args.push_back("-inline-threshold=200000");
#ifdef GEN7_SAMPLER_CLAMP_BORDER_WORKAROUND
@@ -590,28 +541,21 @@ namespace gbe {
#endif /* LLVM_VERSION_MINOR <= 2 */
args.push_back(input);
+ args.push_back("-ffp-contract=off");
+
// The compiler invocation needs a DiagnosticsEngine so it can report problems
std::string ErrorString;
llvm::raw_string_ostream ErrorInfo(ErrorString);
llvm::IntrusiveRefCntPtr<clang::DiagnosticOptions> DiagOpts = new clang::DiagnosticOptions();
DiagOpts->ShowCarets = false;
DiagOpts->ShowPresumedLoc = true;
-#if LLVM_VERSION_MINOR <= 1
- args.push_back("-triple");
- args.push_back("ptx32");
-
- clang::TextDiagnosticPrinter *DiagClient =
- new clang::TextDiagnosticPrinter(ErrorInfo, *DiagOpts)
- llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagID(new clang::DiagnosticIDs());
- clang::DiagnosticsEngine Diags(DiagID, DiagClient);
-#else
- args.push_back("-ffp-contract=off");
+
clang::TextDiagnosticPrinter *DiagClient =
new clang::TextDiagnosticPrinter(ErrorInfo, &*DiagOpts);
llvm::IntrusiveRefCntPtr<clang::DiagnosticIDs> DiagID(new clang::DiagnosticIDs());
clang::DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagClient);
-#endif /* LLVM_VERSION_MINOR <= 1 */
+
// Create the compiler invocation
std::unique_ptr<clang::CompilerInvocation> CI(new clang::CompilerInvocation);
clang::CompilerInvocation::CreateFromArgs(*CI,
@@ -623,11 +567,7 @@ namespace gbe {
clang::CompilerInstance Clang;
Clang.setInvocation(CI.release());
// Get ready to report problems
-#if LLVM_VERSION_MINOR <= 2
- Clang.createDiagnostics(args.size(), &args[0]);
-#else
Clang.createDiagnostics(DiagClient, false);
-#endif /* LLVM_VERSION_MINOR <= 2 */
Clang.getDiagnosticOpts().ShowCarets = false;
if (!Clang.hasDiagnostics())
@@ -636,10 +576,7 @@ namespace gbe {
// Set Language
clang::LangOptions & lang_opts = Clang.getLangOpts();
lang_opts.OpenCL = 1;
-
- clang::PreprocessorOptions& prep_opt = Clang.getPreprocessorOpts();
- prep_opt.DisablePCHValidation = 1;
-
+
//llvm flags need command line parsing to take effect
if (!Clang.getFrontendOpts().LLVMArgs.empty()) {
unsigned NumArgs = Clang.getFrontendOpts().LLVMArgs.size();
@@ -652,32 +589,17 @@ namespace gbe {
llvm::cl::ParseCommandLineOptions(NumArgs + 1, Args);
delete [] Args;
}
-
+
// Create an action and make the compiler instance carry it out
std::unique_ptr<clang::CodeGenAction> Act(new clang::EmitLLVMOnlyAction(llvm_ctx));
-
- std::string dirs = OCL_PCM_PATH;
- std::string pcmFileName;
- std::istringstream idirs(dirs);
- bool findPcm = false;
-
- while (getline(idirs, pcmFileName, ':')) {
- if(access(pcmFileName.c_str(), R_OK) == 0) {
- findPcm |= true;
- break;
- }
- }
-
- GBE_ASSERT(findPcm && "Could not find pre compiled module library.\n");
-
- Clang.getCodeGenOpts().LinkBitcodeFile = pcmFileName;
+
auto retVal = Clang.ExecuteAction(*Act);
if (err != NULL) {
GBE_ASSERT(errSize != NULL);
*errSize = ErrorString.copy(err, stringSize - 1, 0);
}
-
+
if (err == NULL || OCL_OUTPUT_BUILD_LOG) {
// flush the error messages to the errs() if there is no
// error string buffer.
@@ -693,137 +615,70 @@ namespace gbe {
return true;
}
- extern std::string ocl_stdlib_str;
- BVAR(OCL_USE_PCH, true);
+ SVAR(OCL_HEADER_FILE_DIR, OCL_HEADER_DIR);
+
static void processSourceAndOption(const char *source,
const char *options,
const char *temp_header_path,
- std::string& clOpt,
+ std::vector<std::string>& clOpt,
std::string& clName,
int& optLevel)
{
- char clStr[] = "/tmp/XXXXXX.cl";
- int clFd = mkstemps(clStr, 3);
- clName = std::string(clStr);
-
- FILE *clFile = fdopen(clFd, "w");
- FATAL_IF(clFile == NULL, "Failed to open temporary file");
-
- bool usePCH = OCL_USE_PCH;
- bool findPCH = false;
-
- /* Because our header file is so big, we want to avoid recompile the header from
- scratch. We use the PCH support of Clang to save the huge compiling time.
- We just use the most general build opt to build the PCH header file, so if
- user pass new build options here, the PCH can not pass the Clang's compitable
- validating. Clang will do three kinds of compatible check: Language Option,
- Target Option and Preprocessing Option. Other kinds of options such as the
- CodeGen options will not affect the AST result, so no need to check.
-
- According to OpenCL 1.1's spec, the CL build options:
- -D name=definition
- If the definition is not used in our header, it is compitable
-
- -cl-single-precision-constant
- -cl-denorms-are-zero
- -cl-std=
- Language options, really affect.
-
- -cl-opt-disable
- -cl-mad-enable
- -cl-no-signed-zeros
- -cl-unsafe-math-optimizations
- -cl-finite-math-only
- -cl-fast-relaxed-math
- CodeGen options, not affect
-
- -Werror
- -w
- Our header should not block the compiling because of warning.
-
- So we just disable the PCH validation of Clang and do the judgement by ourself. */
-
- /* We always add -cl-kernel-arg-info to the options. This option just generate the arg
- information for the backend, no other side effect and does not have performance issue. */
- if (!options || !strstr(const_cast<char *>(options), "-cl-kernel-arg-info"))
- clOpt += "-cl-kernel-arg-info ";
+ size_t start = 0, end = 0;
- if (options) {
- char *p;
- /* FIXME: Though we can disable the pch valid check, and load pch successfully,
- but these language opts and pre-defined macro will still generate the diag msg
- to the diag engine of the Clang and cause the Clang to report error.
- We filter them all here to avoid these. */
- const char * incompatible_opts[] = {
- "-cl-single-precision-constant",
-// "-cl-denorms-are-zero",
- "-cl-fast-relaxed-math",
- "-cl-std=",
- };
- const char * incompatible_defs[] = {
- "GET_FLOAT_WORD",
- "__NV_CL_C_VERSION",
- "GEN7_SAMPLER_CLAMP_BORDER_WORKAROUND"
- };
-
- for (unsigned int i = 0; i < sizeof(incompatible_opts)/sizeof(char *); i++ ) {
- p = strstr(const_cast<char *>(options), incompatible_opts[i]);
- if (p) {
- usePCH = false;
- break;
- }
- }
+ std::string hdirs = OCL_HEADER_FILE_DIR;
+ std::istringstream hidirs(hdirs);
+ std::string headerFilePath;
+ bool findOcl = false;
- if (usePCH) {
- for (unsigned int i = 0; i < sizeof(incompatible_defs)/sizeof(char *); i++ ) {
- p = strstr(const_cast<char *>(options), incompatible_defs[i]);
- if (p) {
- usePCH = false;
- break;
- }
- }
+ while (getline(hidirs, headerFilePath, ':')) {
+ std::string oclDotHName = headerFilePath + "/ocl.h";
+ if(access(oclDotHName.c_str(), R_OK) == 0) {
+ findOcl = true;
+ break;
}
-
- p = strstr(const_cast<char *>(options), "-cl-opt-disable");
- if (p)
- optLevel = 0;
-
- clOpt += options;
}
+ assert(findOcl);
+ std::string includePath = "-I" + headerFilePath;
+ clOpt.push_back(includePath);
- std::string dirs = OCL_PCH_PATH;
- std::istringstream idirs(dirs);
- std::string pchFileName;
-
- while (getline(idirs, pchFileName, ':')) {
- if(access(pchFileName.c_str(), R_OK) == 0) {
- findPCH = true;
- break;
+ if (options) {
+ char *str = (char *)malloc(sizeof(char) * (strlen(options) + 1));
+ memcpy(str, options, strlen(options) + 1);
+ std::string optionStr(str);
+ const std::string unsupportedOptions("-cl-denorms-are-zero, -cl-strict-aliasing, -cl-opt-disable,"
+ "-cl-no-signed-zeros, -cl-fp32-correctly-rounded-divide-sqrt");
+ while (end != std::string::npos) {
+ end = optionStr.find(' ', start);
+ std::string str = optionStr.substr(start, end - start);
+ start = end + 1;
+ if(str.size() == 0)
+ continue;
+
+ if(unsupportedOptions.find(str) != std::string::npos)
+ continue;
+
+ clOpt.push_back(str);
}
+ free(str);
}
- if (usePCH && findPCH) {
- clOpt += " -include-pch ";
- clOpt += pchFileName;
- clOpt += " ";
- } else
- fwrite(ocl_stdlib_str.c_str(), strlen(ocl_stdlib_str.c_str()), 1, clFile);
-
//for clCompilerProgram usage.
if(temp_header_path){
- clOpt += " -I ";
- clOpt += temp_header_path;
- clOpt += " ";
+ clOpt.push_back("-I");
+ clOpt.push_back(temp_header_path);
}
- if (!OCL_STRICT_CONFORMANCE) {
- fwrite(ocl_mathfunc_fastpath_str.c_str(), strlen(ocl_mathfunc_fastpath_str.c_str()), 1, clFile);
- }
+ char clStr[] = "/tmp/XXXXXX.cl";
+ int clFd = mkstemps(clStr, 3);
+ clName = std::string(clStr);
+
+ FILE *clFile = fdopen(clFd, "w");
+ FATAL_IF(clFile == NULL, "Failed to open temporary file");
- // reset the file number in case we have inserted something into the kernel
- std::string resetFileNum = "#line 1\n";
- fwrite(resetFileNum.c_str(), strlen(resetFileNum.c_str()), 1, clFile);
+ clOpt.push_back("-include");
+ clOpt.push_back("ocl.h");
// Write the source to the cl file
fwrite(source, strlen(source), 1, clFile);
@@ -838,7 +693,7 @@ namespace gbe {
size_t *errSize)
{
int optLevel = 1;
- std::string clOpt;
+ std::vector<std::string> clOpt;
std::string clName;
processSourceAndOption(source, options, NULL, clOpt, clName, optLevel);
@@ -846,12 +701,11 @@ namespace gbe {
// will delete the module and act in GenProgram::CleanLlvmResource().
llvm::Module * out_module;
llvm::LLVMContext* llvm_ctx = new llvm::LLVMContext;
-
static std::mutex llvm_mutex;
if (!llvm::llvm_is_multithreaded())
llvm_mutex.lock();
- if (buildModuleFromSource(clName.c_str(), &out_module, llvm_ctx, clOpt.c_str(),
+ if (buildModuleFromSource(clName.c_str(), &out_module, llvm_ctx, clOpt,
stringSize, err, errSize)) {
// Now build the program from llvm
size_t clangErrSize = 0;
@@ -890,7 +744,7 @@ namespace gbe {
size_t *errSize)
{
int optLevel = 1;
- std::string clOpt;
+ std::vector<std::string> clOpt;
std::string clName;
processSourceAndOption(source, options, temp_header_path, clOpt, clName, optLevel);
@@ -900,7 +754,7 @@ namespace gbe {
//for some functions, so we use global context now, need switch to new context later.
llvm::Module * out_module;
llvm::LLVMContext* llvm_ctx = &llvm::getGlobalContext();
- if (buildModuleFromSource(clName.c_str(), &out_module, llvm_ctx, clOpt.c_str(),
+ if (buildModuleFromSource(clName.c_str(), &out_module, llvm_ctx, clOpt,
stringSize, err, errSize)) {
// Now build the program from llvm
if (err != NULL) {
diff --git a/backend/src/libocl/CMakeLists.txt b/backend/src/libocl/CMakeLists.txt
new file mode 100644
index 00000000..d4e3a536
--- /dev/null
+++ b/backend/src/libocl/CMakeLists.txt
@@ -0,0 +1,209 @@
+PROJECT(LIBOCL)
+
+SET (OCL_HEADER_FILES ${LIBOCL_BINARY_DIR}/include/ocl_defines.h)
+SET (OCL_SOURCE_FILES "")
+
+ADD_CUSTOM_COMMAND(OUTPUT ${LIBOCL_BINARY_DIR}/include/ocl_defines.h
+ COMMAND mkdir -p ${LIBOCL_BINARY_DIR}/include/
+ # COMMAND echo "cat ${LIBOCL_SOURCE_DIR}/tmpl/ocl_defines.tmpl.h \\> ${LIBOCL_BINARY_DIR}/include/ocl_defines.h"
+ COMMAND cat ${LIBOCL_SOURCE_DIR}/tmpl/ocl_defines.tmpl.h > ${LIBOCL_BINARY_DIR}/include/ocl_defines.h
+ # COMMAND echo "cat ${LIBOCL_SOURCE_DIR}/../ocl_common_defines.h \\>\\> ${LIBOCL_BINARY_DIR}/include/ocl_defines.h"
+ COMMAND cat ${LIBOCL_SOURCE_DIR}/../ocl_common_defines.h >> ${LIBOCL_BINARY_DIR}/include/ocl_defines.h
+ DEPENDS ${LIBOCL_SOURCE_DIR}/tmpl/ocl_defines.tmpl.h ${LIBOCL_SOURCE_DIR}/../ocl_common_defines.h
+ COMMENT "Generate the header: ${LIBOCL_BINARY_DIR}/include/ocl_defines.h"
+ )
+
+#other module just copy.
+MACRO(COPY_THE_HEADER _mod)
+ # Use the python script to generate the header files.
+ STRING(REGEX REPLACE "\(o.*\)" "${LIBOCL_BINARY_DIR}/include/\\1.h" output_name ${_mod})
+ STRING(REGEX REPLACE "\(o.*\)" "${LIBOCL_SOURCE_DIR}/include/\\1.h" orgin_name ${_mod})
+ SET(OCL_HEADER_FILES ${OCL_HEADER_FILES} ${output_name})
+ IF(orgin_name STREQUAL output_name)
+ ELSE(orgin_name STREQUAL output_name)
+ ADD_CUSTOM_COMMAND(OUTPUT ${output_name}
+ COMMAND mkdir -p ${LIBOCL_BINARY_DIR}/include/
+ #COMMAND echo "cp ${orgin_name} ${output_name}"
+ COMMAND cp ${orgin_name} ${output_name}
+ DEPENDS ${orgin_name}
+ COMMENT "Copy the header: ${output_name}"
+ )
+ ENDIF(orgin_name STREQUAL output_name)
+ENDMACRO(COPY_THE_HEADER)
+MACRO(COPY_THE_SOURCE _mod)
+ # Use the python script to generate the header files.
+ STRING(REGEX REPLACE "\(o.*\)" "${LIBOCL_BINARY_DIR}/src/\\1.cl" output_name ${_mod})
+ STRING(REGEX REPLACE "\(o.*\)" "${LIBOCL_SOURCE_DIR}/src/\\1.cl" orgin_name ${_mod})
+ SET(OCL_SOURCE_FILES ${OCL_SOURCE_FILES} ${output_name})
+ IF(orgin_name STREQUAL output_name)
+ ELSE(orgin_name STREQUAL output_name)
+ ADD_CUSTOM_COMMAND(OUTPUT ${output_name}
+ COMMAND mkdir -p ${LIBOCL_BINARY_DIR}/src/
+ #COMMAND echo "cp ${orgin_name} ${output_name}"
+ COMMAND cp ${orgin_name} ${output_name}
+ DEPENDS ${orgin_name}
+ COMMENT "Copy the source: ${output_name}"
+ )
+ ENDIF(orgin_name STREQUAL output_name)
+ENDMACRO(COPY_THE_SOURCE)
+
+SET (OCL_COPY_HEADERS ocl ocl_types ocl_float ocl_printf)
+FOREACH(M ${OCL_COPY_HEADERS})
+ COPY_THE_HEADER(${M})
+ENDFOREACH(M)
+
+SET (OCL_COPY_MODULES ocl_workitem ocl_atom ocl_async ocl_sync ocl_misc ocl_vload ocl_geometric ocl_image)
+FOREACH(M ${OCL_COPY_MODULES})
+ COPY_THE_HEADER(${M})
+ COPY_THE_SOURCE(${M})
+ENDFOREACH(M)
+
+
+MACRO(GENERATE_HEADER_PY _mod)
+ STRING(REGEX REPLACE "\(o.*\)" "${LIBOCL_BINARY_DIR}/include/\\1.h" output_name ${_mod})
+ STRING(REGEX REPLACE "\(o.*\)" "${LIBOCL_SOURCE_DIR}/tmpl/\\1.tmpl.h" tmpl_name ${_mod})
+ STRING(REGEX REPLACE "\(o.*\)" "${LIBOCL_SOURCE_DIR}/script/\\1.def" def_name ${_mod})
+ SET(OCL_HEADER_FILES ${OCL_HEADER_FILES} ${output_name})
+ ADD_CUSTOM_COMMAND(OUTPUT ${output_name}
+ COMMAND mkdir -p ${LIBOCL_BINARY_DIR}/include/
+ #COMMAND echo "cat ${tmpl_name} \\> ${output_name}"
+ COMMAND cat ${tmpl_name} > ${output_name}
+ #COMMAND echo "${LIBOCL_SOURCE_DIR}/script/gen_vector.py ${def_name} ${output_name} 1"
+ COMMAND ${LIBOCL_SOURCE_DIR}/script/gen_vector.py ${def_name} ${output_name} 1
+ #COMMAND echo "echo \\#endif \\>\\> ${output_name}"
+ COMMAND echo "\\#endif" >> ${output_name}
+ DEPENDS ${tmpl_name}
+ COMMENT "Generate the header by python: ${output_name}"
+ )
+ENDMACRO(GENERATE_HEADER_PY)
+MACRO(GENERATE_SOURCE_PY _mod)
+ STRING(REGEX REPLACE "\(o.*\)" "${LIBOCL_BINARY_DIR}/src/\\1.cl" output_name ${_mod})
+ STRING(REGEX REPLACE "\(o.*\)" "${LIBOCL_SOURCE_DIR}/tmpl/\\1.tmpl.cl" tmpl_name ${_mod})
+ STRING(REGEX REPLACE "\(o.*\)" "${LIBOCL_SOURCE_DIR}/script/\\1.def" def_name ${_mod})
+ SET(OCL_SOURCE_FILES ${OCL_SOURCE_FILES} ${output_name})
+ ADD_CUSTOM_COMMAND(OUTPUT ${output_name}
+ COMMAND mkdir -p ${LIBOCL_BINARY_DIR}/src/
+ COMMAND cat ${tmpl_name} > ${output_name}
+ COMMAND ${LIBOCL_SOURCE_DIR}/script/gen_vector.py ${def_name} ${output_name} 0
+ DEPENDS ${tmpl_name}
+ COMMENT "Generate the source by python: ${output_name}"
+ )
+ENDMACRO(GENERATE_SOURCE_PY)
+
+SET (OCL_PY_GENERATED_MODULES ocl_common ocl_relational ocl_integer ocl_math)
+FOREACH(M ${OCL_PY_GENERATED_MODULES})
+ GENERATE_HEADER_PY(${M})
+ GENERATE_SOURCE_PY(${M})
+ENDFOREACH(M)
+
+
+MACRO(GENERATE_HEADER_BASH _mod)
+ # Use the python script to generate the header files.
+ STRING(REGEX REPLACE "\(o.*\)" "${LIBOCL_BINARY_DIR}/include/\\1.h" output_name ${_mod})
+ STRING(REGEX REPLACE "\(o.*\)" "${LIBOCL_SOURCE_DIR}/script/\\1.sh" sh_name ${_mod})
+ SET(OCL_HEADER_FILES ${OCL_HEADER_FILES} ${output_name})
+ ADD_CUSTOM_COMMAND(OUTPUT ${output_name}
+ COMMAND mkdir -p ${LIBOCL_BINARY_DIR}/include/
+ COMMAND ${sh_name} -p > ${output_name}
+ DEPENDS ${sh_name}
+ COMMENT "Generate the header by script: ${output_name}"
+ )
+ENDMACRO(GENERATE_HEADER_BASH)
+MACRO(GENERATE_SOURCE_BASH _mod)
+ # Use the python script to generate the header files.
+ STRING(REGEX REPLACE "\(o.*\)" "${LIBOCL_BINARY_DIR}/src/\\1.cl" output_name ${_mod})
+ STRING(REGEX REPLACE "\(o.*\)" "${LIBOCL_SOURCE_DIR}/script/\\1.sh" def_name ${_mod})
+ SET(OCL_SOURCE_FILES ${OCL_SOURCE_FILES} ${output_name})
+ ADD_CUSTOM_COMMAND(OUTPUT ${output_name}
+ COMMAND mkdir -p ${LIBOCL_BINARY_DIR}/src/
+ COMMAND ${sh_name} > ${output_name}
+ DEPENDS ${sh_name}
+ COMMENT "Generate the source by script: ${output_name}"
+ )
+ENDMACRO(GENERATE_SOURCE_BASH)
+
+SET (OCL_BASH_GENERATED_MODULES ocl_as ocl_convert)
+FOREACH(M ${OCL_BASH_GENERATED_MODULES})
+ GENERATE_HEADER_BASH(${M})
+ GENERATE_SOURCE_BASH(${M})
+ENDFOREACH(M)
+
+
+SET (CLANG_OCL_FLAGS -fno-builtin -Dcl_khr_fp64 -ffp-contract=off -cl-kernel-arg-info -DGEN7_SAMPLER_CLAMP_BORDER_WORKAROUND)
+
+MACRO(ADD_CL_TO_BC_TARGET _file)
+ # CMake seems can not add pattern rule, use MACRO to replace.
+ STRING(REGEX REPLACE "${LIBOCL_BINARY_DIR}/src/\(o.*\)\\.cl" "${LIBOCL_BINARY_DIR}/lib/\\1.bc" output_name ${_file})
+ ADD_CUSTOM_COMMAND(OUTPUT ${output_name}
+ COMMAND mkdir -p ${LIBOCL_BINARY_DIR}/lib/
+ #COMMAND echo ${LLVM_INSTALL_DIR}clang -cc1 ${CLANG_OCL_FLAGS} -I ${LIBOCL_BINARY_DIR}/include/ -emit-llvm-bc -triple spir -o ${output_name} -x cl ${_file}
+ COMMAND ${LLVM_INSTALL_DIR}clang -cc1 ${CLANG_OCL_FLAGS} -I ${LIBOCL_BINARY_DIR}/include/ -emit-llvm-bc -triple spir -o ${output_name} -x cl ${_file}
+ DEPENDS ${_file} ${OCL_HEADER_FILES}
+ COMMENT "Compiling ${_file}"
+ )
+ENDMACRO(ADD_CL_TO_BC_TARGET)
+
+
+FOREACH(f ${OCL_SOURCE_FILES})
+ ADD_CL_TO_BC_TARGET(${f})
+ENDFOREACH(f)
+
+FOREACH(f ${OCL_SOURCE_FILES})
+ STRING(REGEX REPLACE "${LIBOCL_BINARY_DIR}/src/\(o.*\)\\.cl" "${LIBOCL_BINARY_DIR}/lib/\\1.bc" bc_name ${f})
+ SET(OCL_BC_FILES ${OCL_BC_FILES} ${bc_name})
+ENDFOREACH(f)
+
+
+# handle the ll files
+MACRO(COPY_THE_LL _mod)
+ # Use the python script to generate the header files.
+ STRING(REGEX REPLACE "\(o.*\)" "${LIBOCL_BINARY_DIR}/src/\\1.ll" output_name ${_mod})
+ STRING(REGEX REPLACE "\(o.*\)" "${LIBOCL_SOURCE_DIR}/src/\\1.ll" orgin_name ${_mod})
+ IF(orgin_name STREQUAL output_name)
+ ELSE(orgin_name STREQUAL output_name)
+ ADD_CUSTOM_COMMAND(OUTPUT ${output_name}
+ COMMAND mkdir -p ${LIBOCL_BINARY_DIR}/src/
+ #COMMAND echo "cp ${orgin_name} ${output_name}"
+ COMMAND cp ${orgin_name} ${output_name}
+ DEPENDS ${orgin_name}
+ COMMENT "Copy the LL file: ${output_name}"
+ )
+ ENDIF(orgin_name STREQUAL output_name)
+ENDMACRO(COPY_THE_LL)
+MACRO(ADD_LL_TO_BC_TARGET M)
+ STRING(REGEX REPLACE "\(o.*\)" "${LIBOCL_BINARY_DIR}/lib/\\1.bc" output_name ${M})
+ STRING(REGEX REPLACE "\(o.*\)" "${LIBOCL_BINARY_DIR}/src/\\1.ll" srcll_name ${M})
+ ADD_CUSTOM_COMMAND(OUTPUT ${output_name}
+ COMMAND mkdir -p ${LIBOCL_BINARY_DIR}/lib/
+ #COMMAND echo ${LLVM_INSTALL_DIR}llvm-as -o ${output_name} ${srcll_name}
+ COMMAND ${LLVM_INSTALL_DIR}llvm-as -o ${output_name} ${srcll_name}
+ DEPENDS ${srcll_name}
+ COMMENT "Compiling ${srcll_name}"
+ )
+ENDMACRO(ADD_LL_TO_BC_TARGET)
+
+SET (OCL_LL_MODULES ocl_barrier ocl_memcpy ocl_memset)
+FOREACH(f ${OCL_LL_MODULES})
+ COPY_THE_LL(${f})
+ ADD_LL_TO_BC_TARGET(${f})
+ STRING(REGEX REPLACE "\(o.*\)" "${LIBOCL_BINARY_DIR}/lib/\\1.bc" bc_name ${f})
+ SET(OCL_BC_FILES ${OCL_BC_FILES} ${bc_name})
+ENDFOREACH(f)
+
+
+ADD_CUSTOM_COMMAND(OUTPUT ${LIBOCL_BINARY_DIR}/lib/beignet.bc
+ COMMAND mkdir -p ${LIBOCL_BINARY_DIR}/lib/
+ #COMMAND echo llvm-link -o ${LIBOCL_BINARY_DIR}/lib/beignet.bc ${OCL_BC_FILES}
+ COMMAND ${LLVM_INSTALL_DIR}llvm-link -o ${LIBOCL_BINARY_DIR}/lib/beignet.bc ${OCL_BC_FILES}
+ DEPENDS ${OCL_BC_FILES}
+ COMMENT "Generate the bitcode file: ${LIBOCL_BINARY_DIR}/lib/beignet.bc"
+ )
+
+ADD_CUSTOM_COMMAND(OUTPUT ${LIBOCL_BINARY_DIR}/lib/beignet.pch
+ COMMAND mkdir -p ${LIBOCL_BINARY_DIR}/lib/
+ COMMAND ${LLVM_INSTALL_DIR}clang -cc1 ${CLANG_OCL_FLAGS} -triple spir -I ${LIBOCL_BINARY_DIR}/include/ -emit-pch -x cl ${LIBOCL_BINARY_DIR}/include/ocl.h -o ${LIBOCL_BINARY_DIR}/lib/beignet.pch
+ DEPENDS ${OCL_HEADER_FILES}
+ COMMENT "Generate the pch file: ${LIBOCL_BINARY_DIR}/lib/beignet.pch"
+ )
+
+add_custom_target(beignet_bitcode ALL DEPENDS ${LIBOCL_BINARY_DIR}/lib/beignet.bc ${LIBOCL_BINARY_DIR}/lib/beignet.pch)
diff --git a/backend/src/libocl/include/ocl.h b/backend/src/libocl/include/ocl.h
new file mode 100644
index 00000000..a7d03e69
--- /dev/null
+++ b/backend/src/libocl/include/ocl.h
@@ -0,0 +1,23 @@
+#ifndef __OCL_H__
+#define __OCL_H__
+
+#include "ocl_defines.h"
+#include "ocl_types.h"
+#include "ocl_as.h"
+#include "ocl_async.h"
+#include "ocl_atom.h"
+#include "ocl_common.h"
+#include "ocl_convert.h"
+#include "ocl_float.h"
+#include "ocl_geometric.h"
+#include "ocl_image.h"
+#include "ocl_integer.h"
+#include "ocl_math.h"
+#include "ocl_misc.h"
+#include "ocl_printf.h"
+#include "ocl_relational.h"
+#include "ocl_sync.h"
+#include "ocl_vload.h"
+#include "ocl_workitem.h"
+
+#endif
diff --git a/backend/src/llvm/llvm_to_gen.cpp b/backend/src/llvm/llvm_to_gen.cpp
index beb36c01..8e49cbb9 100644
--- a/backend/src/llvm/llvm_to_gen.cpp
+++ b/backend/src/llvm/llvm_to_gen.cpp
@@ -72,10 +72,8 @@
namespace gbe
{
- BVAR(OCL_OUTPUT_LLVM, false);
BVAR(OCL_OUTPUT_CFG, false);
BVAR(OCL_OUTPUT_CFG_ONLY, false);
- BVAR(OCL_OUTPUT_LLVM_BEFORE_EXTRA_PASS, false);
using namespace llvm;
void runFuntionPass(Module &mod, TargetLibraryInfo *libraryInfo)
@@ -177,29 +175,68 @@ namespace gbe
MPM.run(mod);
}
+
+#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 5
+#define OUTPUT_BITCODE(STAGE, MOD) do { \
+ llvm::PassManager passes__; \
+ if (OCL_OUTPUT_LLVM_##STAGE) { \
+ passes__.add(createPrintModulePass(*o)); \
+ passes__.run(MOD); \
+ } \
+ }while(0)
+#else
+#define OUTPUT_BITCODE(STAGE, MOD) do { \
+ llvm::PassManager passes__; \
+ if (OCL_OUTPUT_LLVM_##STAGE) { \
+ passes__.add(createPrintModulePass(&*o)); \
+ passes__.run(MOD); \
+ } \
+ }while(0)
+#endif
+
+ BVAR(OCL_OUTPUT_LLVM_BEFORE_LINK, false);
+ BVAR(OCL_OUTPUT_LLVM_AFTER_LINK, false);
+ BVAR(OCL_OUTPUT_LLVM_AFTER_GEN, false);
+
bool llvmToGen(ir::Unit &unit, const char *fileName,const void* module, int optLevel)
{
std::string errInfo;
std::unique_ptr<llvm::raw_fd_ostream> o = NULL;
- if (OCL_OUTPUT_LLVM_BEFORE_EXTRA_PASS || OCL_OUTPUT_LLVM)
+ if (OCL_OUTPUT_LLVM_BEFORE_LINK || OCL_OUTPUT_LLVM_AFTER_LINK || OCL_OUTPUT_LLVM_AFTER_GEN)
o = std::unique_ptr<llvm::raw_fd_ostream>(new llvm::raw_fd_ostream(fileno(stdout), false));
// Get the module from its file
llvm::SMDiagnostic Err;
- std::unique_ptr<Module> M;
- if(fileName){
- // only when module is null, Get the global LLVM context
+ Module* cl_mod = NULL;
+ if (module) {
+ cl_mod = reinterpret_cast<Module*>(const_cast<void*>(module));
+ } else if (fileName){
llvm::LLVMContext& c = llvm::getGlobalContext();
- M.reset(ParseIRFile(fileName, Err, c));
- if (M.get() == 0) return false;
+ cl_mod = ParseIRFile(fileName, Err, c);
}
- Module &mod = (module!=NULL)?*(llvm::Module*)module:*M.get();
+
+ if (!cl_mod) return false;
+
+ OUTPUT_BITCODE(BEFORE_LINK, (*cl_mod));
+
+ std::unique_ptr<Module> M;
+
+ /* Before do any thing, we first filter in all CL functions in bitcode. */
+ M.reset(runBitCodeLinker(cl_mod));
+ if (!module)
+ delete cl_mod;
+ if (M.get() == 0)
+ return false;
+
+ Module &mod = *M.get();
Triple TargetTriple(mod.getTargetTriple());
TargetLibraryInfo *libraryInfo = new TargetLibraryInfo(TargetTriple);
libraryInfo->disableAllFunctions();
+ OUTPUT_BITCODE(AFTER_LINK, mod);
+
runFuntionPass(mod, libraryInfo);
runModulePass(mod, libraryInfo, optLevel);
@@ -210,12 +247,6 @@ namespace gbe
passes.add(new DataLayout(&mod));
#endif
// Print the code before further optimizations
- if (OCL_OUTPUT_LLVM_BEFORE_EXTRA_PASS)
-#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 5
- passes.add(createPrintModulePass(*o));
-#else
- passes.add(createPrintModulePass(&*o));
-#endif
passes.add(createIntrinsicLoweringPass());
passes.add(createFunctionInliningPass(200000));
passes.add(createScalarReplAggregatesPass()); // Break up allocas
@@ -237,15 +268,10 @@ namespace gbe
if(OCL_OUTPUT_CFG_ONLY)
passes.add(createCFGOnlyPrinterPass());
passes.add(createGenPass(unit));
+ passes.run(mod);
// Print the code extra optimization passes
- if (OCL_OUTPUT_LLVM)
-#if LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR >= 5
- passes.add(createPrintModulePass(*o));
-#else
- passes.add(createPrintModulePass(&*o));
-#endif
- passes.run(mod);
+ OUTPUT_BITCODE(AFTER_GEN, mod);
const ir::Unit::FunctionSet& fs = unit.getFunctionSet();
ir::Unit::FunctionSet::const_iterator iter = fs.begin();
diff --git a/utests/setenv.sh.in b/utests/setenv.sh.in
index b0f575fc..ac06b105 100644
--- a/utests/setenv.sh.in
+++ b/utests/setenv.sh.in
@@ -1,7 +1,8 @@
#!/bin/sh
#
-export OCL_PCM_PATH=@LOCAL_PCM_OBJECT_DIR@
-export OCL_PCH_PATH=@LOCAL_PCH_OBJECT_DIR@
+export OCL_BITCODE_LIB_PATH=@LOCAL_OCL_BITCODE_BIN@
+export OCL_HEADER_FILE_DIR=@LOCAL_OCL_HEADER_DIR@
+export OCL_PCH_PATH=@LOCAL_OCL_PCH_OBJECT@
export OCL_KERNEL_PATH=@CMAKE_CURRENT_SOURCE_DIR@/../kernels
export OCL_GBE_PATH=@LOCAL_GBE_OBJECT_DIR@
export OCL_INTERP_PATH=@LOCAL_INTERP_OBJECT_DIR@