diff options
| author | Luo <xionghu.luo@intel.com> | 2014-06-13 11:17:38 +0800 |
|---|---|---|
| committer | Zhigang Gong <zhigang.gong@intel.com> | 2014-06-13 17:20:25 +0800 |
| commit | 5ff5d6ce93ee28a677f6cc782716d463d1c9c049 (patch) | |
| tree | ce507b2a37921cee37c5e32dd706085528d2163d /backend/src | |
| parent | 8d25175926bd4e8437e69a3991b5bd1994f3dc35 (diff) | |
add [opencl-1.2] API clLinkProgram.
this API links a set of compiled program objects and libraries for all
the devices or a specific device(s) in the OpenCL context and creates
an executable.
the llvm bitcode in the compiled program objects are linked together and
built to Gen binary.
Signed-off-by: Luo <xionghu.luo@intel.com>
Reviewed-by: "Song, Ruiling" <ruiling.song@intel.com>
Conflicts:
src/cl_gbe_loader.h
Diffstat (limited to 'backend/src')
| -rw-r--r-- | backend/src/backend/gen_program.cpp | 84 | ||||
| -rw-r--r-- | backend/src/backend/program.cpp | 26 | ||||
| -rw-r--r-- | backend/src/backend/program.h | 28 |
3 files changed, 134 insertions, 4 deletions
diff --git a/backend/src/backend/gen_program.cpp b/backend/src/backend/gen_program.cpp index 1700bfeb..300741ee 100644 --- a/backend/src/backend/gen_program.cpp +++ b/backend/src/backend/gen_program.cpp @@ -33,6 +33,9 @@ #include "llvm/IR/DataLayout.h" #endif /* LLVM_VERSION_MINOR <= 2 */ +#include "llvm/Linker.h" +#include "llvm/Transforms/Utils/Cloning.h" + #include "backend/program.h" #include "backend/gen_program.h" #include "backend/gen_program.hpp" @@ -51,6 +54,7 @@ #include <memory> #include <iostream> #include <fstream> +#include <mutex> namespace gbe { @@ -250,6 +254,84 @@ namespace gbe { // Everything run fine return (gbe_program) program; } + + static void genProgramLinkFromLLVM(gbe_program dst_program, + gbe_program src_program, + size_t stringSize, + char * err, + size_t * errSize) + { +#ifdef GBE_COMPILER_AVAILABLE + using namespace gbe; + std::string errMsg; + if(((GenProgram*)dst_program)->module == NULL){ + ((GenProgram*)dst_program)->module = llvm::CloneModule((llvm::Module*)((GenProgram*)src_program)->module); + errSize = 0; + }else{ + //set the global variables and functions to link once to fix redefine. + llvm::Module* src = (llvm::Module*)((GenProgram*)src_program)->module; + for (llvm::Module::global_iterator I = src->global_begin(), E = src->global_end(); I != E; ++I) { + I->setLinkage(llvm::GlobalValue::LinkOnceAnyLinkage); + } + + for (llvm::Module::iterator I = src->begin(), E = src->end(); I != E; ++I) { + I->setLinkage(llvm::GlobalValue::LinkOnceAnyLinkage); + } + + llvm::Module* dst = (llvm::Module*)((GenProgram*)dst_program)->module; + llvm::Linker::LinkModules( dst, + src, + llvm::Linker::PreserveSource, + &errMsg); + if (errMsg.c_str() != NULL) { + if (err != NULL && errSize != NULL && stringSize > 0u) { + if(errMsg.length() < stringSize ) + stringSize = errMsg.length(); + strcpy(err, errMsg.c_str()); + err[stringSize+1] = '\0'; + } + } + } + // Everything run fine +#endif + } + + static void genProgramBuildFromLLVM(gbe_program program, + size_t stringSize, + char *err, + size_t *errSize, + const char * options) + { +#ifdef GBE_COMPILER_AVAILABLE + using namespace gbe; + std::string error; + + int optLevel = 1; + + if(options) { + char *p; + p = strstr(const_cast<char *>(options), "-cl-opt-disable"); + if (p) + optLevel = 0; + } + + GenProgram* p = (GenProgram*) program; + // Try to compile the program + acquireLLVMContextLock(); + llvm::Module* module = (llvm::Module*)p->module; + + if (p->buildFromLLVMFile(NULL, module, error, optLevel) == false) { + if (err != NULL && errSize != NULL && stringSize > 0u) { + const size_t msgSize = std::min(error.size(), stringSize-1u); + std::memcpy(err, error.c_str(), msgSize); + *errSize = error.size(); + } + GBE_DELETE(p); + } + releaseLLVMContextLock(); +#endif + } + } /* namespace gbe */ void genSetupCallBacks(void) @@ -258,4 +340,6 @@ void genSetupCallBacks(void) gbe_program_serialize_to_binary = gbe::genProgramSerializeToBinary; gbe_program_new_from_llvm = gbe::genProgramNewFromLLVM; gbe_program_new_gen_program = gbe::genProgramNewGenProgram; + gbe_program_link_from_llvm = gbe::genProgramLinkFromLLVM; + gbe_program_build_from_llvm = gbe::genProgramBuildFromLLVM; } diff --git a/backend/src/backend/program.cpp b/backend/src/backend/program.cpp index e225bb27..7432cc35 100644 --- a/backend/src/backend/program.cpp +++ b/backend/src/backend/program.cpp @@ -888,18 +888,14 @@ namespace gbe { if (buildModuleFromSource(clName.c_str(), &out_module, llvm_ctx, clOpt.c_str(), stringSize, err, errSize)) { // Now build the program from llvm - size_t clangErrSize = 0; if (err != NULL) { GBE_ASSERT(errSize != NULL); stringSize -= *errSize; err += *errSize; - clangErrSize = *errSize; } p = gbe_program_new_gen_program(deviceID, out_module, NULL); - if (err != NULL) - *errSize += clangErrSize; if (OCL_OUTPUT_BUILD_LOG && options) llvm::errs() << options; } else @@ -910,6 +906,24 @@ namespace gbe { } #endif +#ifdef GBE_COMPILER_AVAILABLE + static void programLinkProgram(gbe_program dst_program, + gbe_program src_program, + size_t stringSize, + char * err, + size_t * errSize) + { + acquireLLVMContextLock(); + + gbe_program_link_from_llvm(dst_program, src_program, stringSize, err, errSize); + + releaseLLVMContextLock(); + + if (OCL_OUTPUT_BUILD_LOG && err) + llvm::errs() << err; + } +#endif + static size_t programGetGlobalConstantSize(gbe_program gbeProgram) { if (gbeProgram == NULL) return 0; const gbe::Program *program = (const gbe::Program*) gbeProgram; @@ -1120,10 +1134,13 @@ void releaseLLVMContextLock() GBE_EXPORT_SYMBOL gbe_program_new_from_source_cb *gbe_program_new_from_source = NULL; GBE_EXPORT_SYMBOL gbe_program_compile_from_source_cb *gbe_program_compile_from_source = NULL; +GBE_EXPORT_SYMBOL gbe_program_link_program_cb *gbe_program_link_program = NULL; GBE_EXPORT_SYMBOL gbe_program_new_from_binary_cb *gbe_program_new_from_binary = NULL; GBE_EXPORT_SYMBOL gbe_program_serialize_to_binary_cb *gbe_program_serialize_to_binary = NULL; GBE_EXPORT_SYMBOL gbe_program_new_from_llvm_cb *gbe_program_new_from_llvm = NULL; GBE_EXPORT_SYMBOL gbe_program_new_gen_program_cb *gbe_program_new_gen_program = NULL; +GBE_EXPORT_SYMBOL gbe_program_link_from_llvm_cb *gbe_program_link_from_llvm = NULL; +GBE_EXPORT_SYMBOL gbe_program_build_from_llvm_cb *gbe_program_build_from_llvm = NULL; GBE_EXPORT_SYMBOL gbe_program_get_global_constant_size_cb *gbe_program_get_global_constant_size = NULL; GBE_EXPORT_SYMBOL gbe_program_get_global_constant_data_cb *gbe_program_get_global_constant_data = NULL; GBE_EXPORT_SYMBOL gbe_program_delete_cb *gbe_program_delete = NULL; @@ -1168,6 +1185,7 @@ namespace gbe CallBackInitializer(void) { gbe_program_new_from_source = gbe::programNewFromSource; gbe_program_compile_from_source = gbe::programCompileFromSource; + gbe_program_link_program = gbe::programLinkProgram; gbe_program_get_global_constant_size = gbe::programGetGlobalConstantSize; gbe_program_get_global_constant_data = gbe::programGetGlobalConstantData; gbe_program_delete = gbe::programDelete; diff --git a/backend/src/backend/program.h b/backend/src/backend/program.h index 7ddbd22b..e410221e 100644 --- a/backend/src/backend/program.h +++ b/backend/src/backend/program.h @@ -151,6 +151,13 @@ typedef gbe_program (gbe_program_compile_from_source_cb)(uint32_t deviceID, char *err, size_t *err_size); extern gbe_program_compile_from_source_cb *gbe_program_compile_from_source; +/*! link the programs. */ +typedef void (gbe_program_link_program_cb)(gbe_program dst_program, + gbe_program src_program, + size_t stringSize, + char * err, + size_t * errSize); +extern gbe_program_link_program_cb *gbe_program_link_program; /*! create s new genprogram for link. */ typedef gbe_program (gbe_program_new_gen_program_cb)(uint32_t deviceID, @@ -177,6 +184,27 @@ typedef gbe_program (gbe_program_new_from_llvm_cb)(uint32_t deviceID, int optLevel); extern gbe_program_new_from_llvm_cb *gbe_program_new_from_llvm; +/*! create s new genprogram for link. */ +typedef gbe_program (gbe_program_new_gen_program_cb)(uint32_t deviceID, + const void *module, + const void *act); +extern gbe_program_new_gen_program_cb *gbe_program_new_gen_program; + +/*! link the programs from llvm level. */ +typedef void (gbe_program_link_from_llvm_cb)(gbe_program dst_program, + gbe_program src_program, + size_t stringSize, + char * err, + size_t * errSize); +extern gbe_program_link_from_llvm_cb *gbe_program_link_from_llvm; +/* build the program to gen binary */ +typedef void gbe_program_build_from_llvm_cb(gbe_program program, + size_t stringSize, + char *err, + size_t *errSize, + const char * options); +extern gbe_program_build_from_llvm_cb *gbe_program_build_from_llvm; + /*! Get the size of global constants */ typedef size_t (gbe_program_get_global_constant_size_cb)(gbe_program gbeProgram); extern gbe_program_get_global_constant_size_cb *gbe_program_get_global_constant_size; |
