diff options
| author | bors <bors@rust-lang.org> | 2013-06-11 13:46:54 -0700 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2013-06-11 13:46:54 -0700 |
| commit | da9172af60e04d40aad2f0184e81e2a74916eeba (patch) | |
| tree | 5a951c6914bfa500be7f11c1d3c1a9d6488ebd58 /src/rustllvm/RustWrapper.cpp | |
| parent | d0b197900485c98cf2a09298823ea274db50c4d9 (diff) | |
| parent | 5c5095d25e3652c434c8d4ec178e6844877e3c2d (diff) | |
| download | rust-da9172af60e04d40aad2f0184e81e2a74916eeba.tar.gz rust-da9172af60e04d40aad2f0184e81e2a74916eeba.zip | |
auto merge of #7040 : alexcrichton/rust/issue-6511-threadsafe-llvm, r=graydon
This is a reopening of #6570, and almost fixes #6511. Note that this doesn't actually enable building a threadsafe LLVM, because that will require an LLVM rebuild which will be bundled with the upgrades in #6713. What this does do, however, is removes all thread-unsafe usage of LLVM from the compiler.
Diffstat (limited to 'src/rustllvm/RustWrapper.cpp')
| -rw-r--r-- | src/rustllvm/RustWrapper.cpp | 59 |
1 files changed, 36 insertions, 23 deletions
diff --git a/src/rustllvm/RustWrapper.cpp b/src/rustllvm/RustWrapper.cpp index 4ee5df28d24..30e01b53ab7 100644 --- a/src/rustllvm/RustWrapper.cpp +++ b/src/rustllvm/RustWrapper.cpp @@ -329,12 +329,12 @@ LLVMRustLoadCrate(void* mem, const char* crate) { return true; } -extern "C" void* -LLVMRustExecuteJIT(void* mem, - LLVMPassManagerRef PMR, - LLVMModuleRef M, - CodeGenOpt::Level OptLevel, - bool EnableSegmentedStacks) { +extern "C" LLVMExecutionEngineRef +LLVMRustBuildJIT(void* mem, + LLVMPassManagerRef PMR, + LLVMModuleRef M, + CodeGenOpt::Level OptLevel, + bool EnableSegmentedStacks) { InitializeNativeTarget(); InitializeNativeTargetAsmPrinter(); @@ -371,21 +371,15 @@ LLVMRustExecuteJIT(void* mem, if(!EE || Err != "") { LLVMRustError = Err.c_str(); - return 0; + // The EngineBuilder only takes ownership of these two structures if the + // create() call is successful, but here it wasn't successful. + LLVMDisposeModule(M); + delete MM; + return NULL; } MM->invalidateInstructionCache(); - Function* func = EE->FindFunctionNamed("_rust_main"); - - if(!func || Err != "") { - LLVMRustError = Err.c_str(); - return 0; - } - - void* entry = EE->getPointerToFunction(func); - assert(entry); - - return entry; + return wrap(EE); } extern "C" bool @@ -447,9 +441,10 @@ LLVMRustWriteOutputFile(LLVMPassManagerRef PMR, return true; } -extern "C" LLVMModuleRef LLVMRustParseAssemblyFile(const char *Filename) { +extern "C" LLVMModuleRef LLVMRustParseAssemblyFile(LLVMContextRef C, + const char *Filename) { SMDiagnostic d; - Module *m = ParseAssemblyFile(Filename, d, getGlobalContext()); + Module *m = ParseAssemblyFile(Filename, d, *unwrap(C)); if (m) { return wrap(m); } else { @@ -499,9 +494,6 @@ extern "C" LLVMValueRef LLVMGetOrInsertFunction(LLVMModuleRef M, extern "C" LLVMTypeRef LLVMMetadataTypeInContext(LLVMContextRef C) { return wrap(Type::getMetadataTy(*unwrap(C))); } -extern "C" LLVMTypeRef LLVMMetadataType(void) { - return LLVMMetadataTypeInContext(LLVMGetGlobalContext()); -} extern "C" LLVMValueRef LLVMBuildAtomicLoad(LLVMBuilderRef B, LLVMValueRef source, @@ -561,3 +553,24 @@ extern "C" LLVMValueRef LLVMInlineAsm(LLVMTypeRef Ty, Constraints, HasSideEffects, IsAlignStack, (InlineAsm::AsmDialect) Dialect)); } + +/** + * This function is intended to be a threadsafe interface into enabling a + * multithreaded LLVM. This is invoked at the start of the translation phase of + * compilation to ensure that LLVM is ready. + * + * All of trans properly isolates LLVM with the use of a different + * LLVMContextRef per task, thus allowing parallel compilation of different + * crates in the same process. At the time of this writing, the use case for + * this is unit tests for rusti, but there are possible other applications. + */ +extern "C" bool LLVMRustStartMultithreading() { + static Mutex lock; + bool ret = true; + assert(lock.acquire()); + if (!LLVMIsMultithreaded()) { + ret = LLVMStartMultithreaded(); + } + assert(lock.release()); + return ret; +} |
