If application has static clProgram, when application exit, the static context has been deleted before delete static clProgram will cause segmentation fault. As the global static context is just for link, use the individual context of each llvm module, when link the llvm module, generate the new llvm module from src.
Signed-off-by: Yang Rong <rong.r.y...@intel.com> --- backend/src/backend/gen_program.cpp | 38 ++++++++++++++++++++++++------------- backend/src/backend/program.cpp | 15 +++++++-------- backend/src/llvm/llvm_to_gen.cpp | 7 ------- backend/src/llvm/llvm_to_gen.hpp | 4 ---- 4 files changed, 32 insertions(+), 32 deletions(-) diff --git a/backend/src/backend/gen_program.cpp b/backend/src/backend/gen_program.cpp index 6ba2e54..729c3b9 100644 --- a/backend/src/backend/gen_program.cpp +++ b/backend/src/backend/gen_program.cpp @@ -28,6 +28,8 @@ #include "llvm/IR/Module.h" #include "llvm/IR/DataLayout.h" #include "llvm-c/Linker.h" +#include "llvm-c/BitReader.h" +#include "llvm-c/BitWriter.h" #include "llvm/Transforms/Utils/Cloning.h" #if LLVM_VERSION_MAJOR * 10 + LLVM_VERSION_MINOR >= 40 #include "llvm/Bitcode/BitcodeWriter.h" @@ -126,10 +128,13 @@ namespace gbe { void GenProgram::CleanLlvmResource(void){ #ifdef GBE_COMPILER_AVAILABLE + llvm::LLVMContext* ctx = &((llvm::Module*)module)->getContext(); if(module){ delete (llvm::Module*)module; module = NULL; } + if (ctx != llvm_ctx) + delete ctx; if(llvm_ctx){ delete (llvm::LLVMContext*)llvm_ctx; @@ -353,19 +358,19 @@ namespace gbe { binary_content.assign(binary+1, size-1); llvm::StringRef llvm_bin_str(binary_content); #if LLVM_VERSION_MAJOR * 10 + LLVM_VERSION_MINOR >= 39 - llvm::LLVMContext& c = GBEGetLLVMContext(); + llvm::LLVMContext *c = new llvm::LLVMContext; #else - llvm::LLVMContext& c = llvm::getGlobalContext(); + llvm::LLVMContext *c = &llvm::getGlobalContext(); #endif llvm::SMDiagnostic Err; #if LLVM_VERSION_MAJOR * 10 + LLVM_VERSION_MINOR >= 36 std::unique_ptr<llvm::MemoryBuffer> memory_buffer = llvm::MemoryBuffer::getMemBuffer(llvm_bin_str, "llvm_bin_str"); acquireLLVMContextLock(); - llvm::Module* module = llvm::parseIR(memory_buffer->getMemBufferRef(), Err, c).release(); + llvm::Module* module = llvm::parseIR(memory_buffer->getMemBufferRef(), Err, *c).release(); #else llvm::MemoryBuffer* memory_buffer = llvm::MemoryBuffer::getMemBuffer(llvm_bin_str, "llvm_bin_str"); acquireLLVMContextLock(); - llvm::Module* module = llvm::ParseIR(memory_buffer, Err, c); + llvm::Module* module = llvm::ParseIR(memory_buffer, Err, *c); #endif // if load 32 bit spir binary, the triple should be spir-unknown-unknown. llvm::Triple triple(module->getTargetTriple()); @@ -506,23 +511,31 @@ namespace gbe { using namespace gbe; char* errMsg = NULL; if(((GenProgram*)dst_program)->module == NULL){ -#if LLVM_VERSION_MAJOR * 10 + LLVM_VERSION_MINOR >= 38 +#if LLVM_VERSION_MAJOR * 10 + LLVM_VERSION_MINOR >= 39 + LLVMModuleRef modRef; + LLVMParseBitcodeInContext2(wrap(new llvm::LLVMContext()), + LLVMWriteBitcodeToMemoryBuffer(wrap((llvm::Module*)((GenProgram*)src_program)->module)), + &modRef); + ((GenProgram*)dst_program)->module = llvm::unwrap(modRef); +#elif LLVM_VERSION_MAJOR * 10 + LLVM_VERSION_MINOR >= 38 ((GenProgram*)dst_program)->module = llvm::CloneModule((llvm::Module*)((GenProgram*)src_program)->module).release(); #else ((GenProgram*)dst_program)->module = llvm::CloneModule((llvm::Module*)((GenProgram*)src_program)->module); #endif errSize = 0; } else { -#if LLVM_VERSION_MAJOR * 10 + LLVM_VERSION_MINOR >= 39 - // Src now will be removed automatically. So clone it. - llvm::Module* src = llvm::CloneModule((llvm::Module*)((GenProgram*)src_program)->module).release(); -#else llvm::Module* src = (llvm::Module*)((GenProgram*)src_program)->module; -#endif llvm::Module* dst = (llvm::Module*)((GenProgram*)dst_program)->module; - #if LLVM_VERSION_MAJOR * 10 + LLVM_VERSION_MINOR >= 39 - if (LLVMLinkModules2(wrap(dst), wrap(src))) { + if (&src->getContext() != &dst->getContext()) { + LLVMModuleRef modRef; + LLVMParseBitcodeInContext2(wrap(&dst->getContext()), + LLVMWriteBitcodeToMemoryBuffer(wrap(src)), + &modRef); + src = llvm::unwrap(modRef); + } + llvm::Module* clone = llvm::CloneModule(src).release(); + if (LLVMLinkModules2(wrap(dst), wrap(clone))) { #elif LLVM_VERSION_MAJOR * 10 + LLVM_VERSION_MINOR >= 37 if (LLVMLinkModules(wrap(dst), wrap(src), LLVMLinkerPreserveSource_Removed, &errMsg)) { #else @@ -536,7 +549,6 @@ namespace gbe { return true; } } - // Everything run fine #endif return false; } diff --git a/backend/src/backend/program.cpp b/backend/src/backend/program.cpp index c06ae5a..19e7c88 100644 --- a/backend/src/backend/program.cpp +++ b/backend/src/backend/program.cpp @@ -1104,22 +1104,22 @@ EXTEND_QUOTE: return NULL; #if LLVM_VERSION_MAJOR * 10 + LLVM_VERSION_MINOR >= 39 - llvm::LLVMContext& c = GBEGetLLVMContext(); + llvm::LLVMContext *c = new llvm::LLVMContext; #else - llvm::LLVMContext& c = llvm::getGlobalContext(); + llvm::LLVMContext *c = llvm::getGlobalContext(); #endif // Get the module from its file llvm::SMDiagnostic errDiag; #if LLVM_VERSION_MAJOR * 10 + LLVM_VERSION_MINOR >= 36 - llvm::Module *module = parseIRFile(fileName, errDiag, c).release(); + llvm::Module *module = parseIRFile(fileName, errDiag, *c).release(); #else - llvm::Module *module = ParseIRFile(fileName, errDiag, c); + llvm::Module *module = ParseIRFile(fileName, errDiag, *c); #endif int optLevel = 1; //module will be delete in programCleanLlvmResource - p = gbe_program_new_from_llvm(deviceID, module, &c, NULL, + p = gbe_program_new_from_llvm(deviceID, module, c, NULL, string_size, err, err_size, optLevel, NULL); if (OCL_OUTPUT_BUILD_LOG && err && *err_size) llvm::errs() << err << "\n"; @@ -1152,11 +1152,10 @@ EXTEND_QUOTE: gbe_program p; acquireLLVMContextLock(); - //FIXME: if use new allocated context to link two modules there would be context mismatch - //for some functions, so we use global context now, need switch to new context later. + llvm::Module * out_module; #if LLVM_VERSION_MAJOR * 10 + LLVM_VERSION_MINOR >= 39 - llvm::LLVMContext* llvm_ctx = &GBEGetLLVMContext(); + llvm::LLVMContext* llvm_ctx = new llvm::LLVMContext; #else llvm::LLVMContext* llvm_ctx = &llvm::getGlobalContext(); #endif diff --git a/backend/src/llvm/llvm_to_gen.cpp b/backend/src/llvm/llvm_to_gen.cpp index 8546f73..7f7deff 100644 --- a/backend/src/llvm/llvm_to_gen.cpp +++ b/backend/src/llvm/llvm_to_gen.cpp @@ -46,13 +46,6 @@ namespace gbe BVAR(OCL_OUTPUT_CFG_GEN_IR, false); using namespace llvm; -#if LLVM_VERSION_MAJOR * 10 + LLVM_VERSION_MINOR >= 39 - llvm::LLVMContext& GBEGetLLVMContext() { - static llvm::LLVMContext GBEContext; - return GBEContext; - } -#endif - #if LLVM_VERSION_MAJOR * 10 + LLVM_VERSION_MINOR >= 37 #define TARGETLIBRARY TargetLibraryInfoImpl #else diff --git a/backend/src/llvm/llvm_to_gen.hpp b/backend/src/llvm/llvm_to_gen.hpp index 73e8819..d2247bb 100644 --- a/backend/src/llvm/llvm_to_gen.hpp +++ b/backend/src/llvm/llvm_to_gen.hpp @@ -37,10 +37,6 @@ namespace gbe { optLevel 0 equal to clang -O1 and 1 equal to clang -O2*/ bool llvmToGen(ir::Unit &unit, const void* module, int optLevel, bool strictMath, int profiling, std::string &errors); -#if LLVM_VERSION_MAJOR * 10 + LLVM_VERSION_MINOR >= 39 - extern llvm::LLVMContext& GBEGetLLVMContext(); -#endif - } /* namespace gbe */ #endif /* __GBE_IR_LLVM_TO_GEN_HPP__ */ -- 2.7.4 _______________________________________________ Beignet mailing list Beignet@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/beignet