about summary refs log tree commit diff
path: root/src/rustllvm
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2013-06-11 13:46:54 -0700
committerbors <bors@rust-lang.org>2013-06-11 13:46:54 -0700
commitda9172af60e04d40aad2f0184e81e2a74916eeba (patch)
tree5a951c6914bfa500be7f11c1d3c1a9d6488ebd58 /src/rustllvm
parentd0b197900485c98cf2a09298823ea274db50c4d9 (diff)
parent5c5095d25e3652c434c8d4ec178e6844877e3c2d (diff)
downloadrust-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')
-rw-r--r--src/rustllvm/RustWrapper.cpp59
-rw-r--r--src/rustllvm/rustllvm.def.in7
-rw-r--r--src/rustllvm/rustllvm.h1
3 files changed, 41 insertions, 26 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;
+}
diff --git a/src/rustllvm/rustllvm.def.in b/src/rustllvm/rustllvm.def.in
index 8ebdbd0f307..f5397165781 100644
--- a/src/rustllvm/rustllvm.def.in
+++ b/src/rustllvm/rustllvm.def.in
@@ -6,12 +6,14 @@ LLVMRustConstSmallInt
 LLVMRustConstInt
 LLVMRustLoadCrate
 LLVMRustPrepareJIT
-LLVMRustExecuteJIT
+LLVMRustBuildJIT
 LLVMRustParseBitcode
 LLVMRustParseAssemblyFile
 LLVMRustPrintPassTimings
+LLVMRustStartMultithreading
 LLVMCreateObjectFile
 LLVMDisposeObjectFile
+LLVMDisposeExecutionEngine
 LLVMGetSections
 LLVMDisposeSectionIterator
 LLVMIsSectionIteratorAtEnd
@@ -319,7 +321,6 @@ LLVMGetFunctionAttr
 LLVMGetFunctionCallConv
 LLVMGetGC
 LLVMGetGlobalContext
-LLVMGetGlobalContext
 LLVMGetGlobalParent
 LLVMGetGlobalPassRegistry
 LLVMGetIncomingBlock
@@ -356,6 +357,7 @@ LLVMGetParamParent
 LLVMGetParamTypes
 LLVMGetParams
 LLVMGetPointerAddressSpace
+LLVMGetPointerToGlobal
 LLVMGetPreviousBasicBlock
 LLVMGetPreviousFunction
 LLVMGetPreviousGlobal
@@ -500,7 +502,6 @@ LLVMMDNode
 LLVMMDNodeInContext
 LLVMMDString
 LLVMMDStringInContext
-LLVMMetadataType
 LLVMMetadataTypeInContext
 LLVMModuleCreateWithName
 LLVMModuleCreateWithNameInContext
diff --git a/src/rustllvm/rustllvm.h b/src/rustllvm/rustllvm.h
index 1c8842f7b4a..394146eea20 100644
--- a/src/rustllvm/rustllvm.h
+++ b/src/rustllvm/rustllvm.h
@@ -45,6 +45,7 @@
 #include "llvm/Transforms/Vectorize.h"
 #include "llvm-c/Core.h"
 #include "llvm-c/BitReader.h"
+#include "llvm-c/ExecutionEngine.h"
 #include "llvm-c/Object.h"
 
 // Used by RustMCJITMemoryManager::getPointerToNamedFunction()