summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorYang Rong <rong.r.yang@intel.com>2017-08-22 12:33:55 +0800
committerYang Rong <rong.r.yang@intel.com>2017-09-21 17:47:29 +0800
commit2f2342ddc986cf23af7e1aaa5a26fd6252887393 (patch)
treec0fc739a7b71693eca87405b9497e8951d60f075
parent269c230fbd8ad1e524abe169af88fadc405e5056 (diff)
GBE: remove static context to fix Segmentation fault.
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. V2: fix llvm 3.8 build error and CleanLlvmResource delete bug. Signed-off-by: Yang Rong <rong.r.yang@intel.com> Reviewed-by: Ruiling Song <ruiling.song@intel.com>
-rw-r--r--backend/src/backend/gen_program.cpp46
-rw-r--r--backend/src/backend/program.cpp15
-rw-r--r--backend/src/llvm/llvm_to_gen.cpp7
-rw-r--r--backend/src/llvm/llvm_to_gen.hpp4
4 files changed, 39 insertions, 33 deletions
diff --git a/backend/src/backend/gen_program.cpp b/backend/src/backend/gen_program.cpp
index 6ba2e549..e06ed40c 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,16 +128,25 @@ namespace gbe {
void GenProgram::CleanLlvmResource(void){
#ifdef GBE_COMPILER_AVAILABLE
+ llvm::LLVMContext* ctx = NULL;
if(module){
+ ctx = &((llvm::Module*)module)->getContext();
+ (void)ctx;
delete (llvm::Module*)module;
module = NULL;
}
-
+//llvm's version < 3.9, ctx is global ctx, can't be deleted.
+#if LLVM_VERSION_MAJOR * 10 + LLVM_VERSION_MINOR >= 39
+ //each module's context is individual, just delete it, ignaor llvm_ctx.
+ if (ctx != NULL)
+ delete ctx;
+#else
if(llvm_ctx){
delete (llvm::LLVMContext*)llvm_ctx;
llvm_ctx = NULL;
}
#endif
+#endif
}
/*! We must avoid spilling at all cost with Gen */
@@ -353,19 +364,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 +517,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 +555,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 c06ae5a1..c37c5951 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 8546f730..7f7deffe 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 73e88194..d2247bbf 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__ */