]> git.lizzy.rs Git - rust.git/commitdiff
Revert "Revert "Remove all usage of the global LLVMContextRef""
authorAlex Crichton <alex@alexcrichton.com>
Fri, 14 Jun 2013 04:25:12 +0000 (21:25 -0700)
committerAlex Crichton <alex@alexcrichton.com>
Fri, 14 Jun 2013 04:25:12 +0000 (21:25 -0700)
This reverts commit 541c657a738006d78171aa261125a6a46f283b35.

src/librustc/lib/llvm.rs
src/librustc/middle/trans/base.rs
src/librustc/middle/trans/build.rs
src/librustc/middle/trans/cabi_mips.rs
src/librustc/middle/trans/closure.rs
src/librustc/middle/trans/common.rs
src/librustc/middle/trans/debuginfo.rs
src/librustc/middle/trans/type_of.rs
src/librusti/rusti.rc
src/rustllvm/RustWrapper.cpp
src/rustllvm/rustllvm.def.in

index f6beb078e46f5a099d3bd99934b6c8a725f95113..0e9ea982d9f4c4fd067be0a2107cd6c89f98a0a7 100644 (file)
@@ -239,16 +239,12 @@ pub mod llvm {
         #[fast_ffi]
         pub unsafe fn LLVMContextCreate() -> ContextRef;
         #[fast_ffi]
-        pub unsafe fn LLVMGetGlobalContext() -> ContextRef;
-        #[fast_ffi]
         pub unsafe fn LLVMContextDispose(C: ContextRef);
         #[fast_ffi]
         pub unsafe fn LLVMGetMDKindIDInContext(C: ContextRef,
                                            Name: *c_char,
                                            SLen: c_uint)
                                         -> c_uint;
-        #[fast_ffi]
-        pub unsafe fn LLVMGetMDKindID(Name: *c_char, SLen: c_uint) -> c_uint;
 
         /* Create and destroy modules. */
         #[fast_ffi]
@@ -256,6 +252,8 @@ pub unsafe fn LLVMModuleCreateWithNameInContext(ModuleID: *c_char,
                                                     C: ContextRef)
                                                  -> ModuleRef;
         #[fast_ffi]
+        pub unsafe fn LLVMGetModuleContext(M: ModuleRef) -> ContextRef;
+        #[fast_ffi]
         pub unsafe fn LLVMDisposeModule(M: ModuleRef);
 
         /** Data layout. See Module::getDataLayout. */
@@ -300,18 +298,6 @@ pub unsafe fn LLVMModuleCreateWithNameInContext(ModuleID: *c_char,
         pub unsafe fn LLVMIntTypeInContext(C: ContextRef,
                                            NumBits: c_uint) -> TypeRef;
 
-        #[fast_ffi]
-        pub unsafe fn LLVMInt1Type() -> TypeRef;
-        #[fast_ffi]
-        pub unsafe fn LLVMInt8Type() -> TypeRef;
-        #[fast_ffi]
-        pub unsafe fn LLVMInt16Type() -> TypeRef;
-        #[fast_ffi]
-        pub unsafe fn LLVMInt32Type() -> TypeRef;
-        #[fast_ffi]
-        pub unsafe fn LLVMInt64Type() -> TypeRef;
-        #[fast_ffi]
-        pub unsafe fn LLVMIntType(NumBits: c_uint) -> TypeRef;
         #[fast_ffi]
         pub unsafe fn LLVMGetIntTypeWidth(IntegerTy: TypeRef) -> c_uint;
 
@@ -327,17 +313,6 @@ pub unsafe fn LLVMIntTypeInContext(C: ContextRef,
         #[fast_ffi]
         pub unsafe fn LLVMPPCFP128TypeInContext(C: ContextRef) -> TypeRef;
 
-        #[fast_ffi]
-        pub unsafe fn LLVMFloatType() -> TypeRef;
-        #[fast_ffi]
-        pub unsafe fn LLVMDoubleType() -> TypeRef;
-        #[fast_ffi]
-        pub unsafe fn LLVMX86FP80Type() -> TypeRef;
-        #[fast_ffi]
-        pub unsafe fn LLVMFP128Type() -> TypeRef;
-        #[fast_ffi]
-        pub unsafe fn LLVMPPCFP128Type() -> TypeRef;
-
         /* Operations on function types */
         #[fast_ffi]
         pub unsafe fn LLVMFunctionType(ReturnType: TypeRef,
@@ -361,11 +336,6 @@ pub unsafe fn LLVMStructTypeInContext(C: ContextRef,
                                               ElementCount: c_uint,
                                               Packed: Bool) -> TypeRef;
         #[fast_ffi]
-        pub unsafe fn LLVMStructType(ElementTypes: *TypeRef,
-                                     ElementCount: c_uint,
-                                     Packed: Bool)
-                                  -> TypeRef;
-        #[fast_ffi]
         pub unsafe fn LLVMCountStructElementTypes(StructTy: TypeRef)
                                                -> c_uint;
         #[fast_ffi]
@@ -403,13 +373,6 @@ pub unsafe fn LLVMGetPointerAddressSpace(PointerTy: TypeRef)
         #[fast_ffi]
         pub unsafe fn LLVMMetadataTypeInContext(C: ContextRef) -> TypeRef;
 
-        #[fast_ffi]
-        pub unsafe fn LLVMVoidType() -> TypeRef;
-        #[fast_ffi]
-        pub unsafe fn LLVMLabelType() -> TypeRef;
-        #[fast_ffi]
-        pub unsafe fn LLVMMetadataType() -> TypeRef;
-
         /* Operations on all values */
         #[fast_ffi]
         pub unsafe fn LLVMTypeOf(Val: ValueRef) -> TypeRef;
@@ -482,15 +445,11 @@ pub unsafe fn LLVMMDStringInContext(C: ContextRef,
                                         SLen: c_uint)
                                      -> ValueRef;
         #[fast_ffi]
-        pub unsafe fn LLVMMDString(Str: *c_char, SLen: c_uint) -> ValueRef;
-        #[fast_ffi]
         pub unsafe fn LLVMMDNodeInContext(C: ContextRef,
                                       Vals: *ValueRef,
                                       Count: c_uint)
                                    -> ValueRef;
         #[fast_ffi]
-        pub unsafe fn LLVMMDNode(Vals: *ValueRef, Count: c_uint) -> ValueRef;
-        #[fast_ffi]
         pub unsafe fn LLVMAddNamedMetadataOperand(M: ModuleRef, Str: *c_char,
                                        Val: ValueRef);
 
@@ -544,20 +503,11 @@ pub unsafe fn LLVMConstStructInContext(C: ContextRef,
                                                Packed: Bool) -> ValueRef;
 
         #[fast_ffi]
-        pub unsafe fn LLVMConstString(Str: *c_char,
-                                      Length: c_uint,
-                                      DontNullTerminate: Bool)
-                                   -> ValueRef;
-        #[fast_ffi]
         pub unsafe fn LLVMConstArray(ElementTy: TypeRef,
                                      ConstantVals: *ValueRef,
                                      Length: c_uint)
                                   -> ValueRef;
         #[fast_ffi]
-        pub unsafe fn LLVMConstStruct(ConstantVals: *ValueRef,
-                                      Count: c_uint,
-                                      Packed: Bool) -> ValueRef;
-        #[fast_ffi]
         pub unsafe fn LLVMConstVector(ScalarConstantVals: *ValueRef,
                                       Size: c_uint) -> ValueRef;
 
@@ -970,15 +920,6 @@ pub unsafe fn LLVMInsertBasicBlockInContext(C: ContextRef,
                                                     BB: BasicBlockRef,
                                                     Name: *c_char)
                                                  -> BasicBlockRef;
-
-        #[fast_ffi]
-        pub unsafe fn LLVMAppendBasicBlock(Fn: ValueRef,
-                                       Name: *c_char)
-                                    -> BasicBlockRef;
-        #[fast_ffi]
-        pub unsafe fn LLVMInsertBasicBlock(InsertBeforeBB: BasicBlockRef,
-                                       Name: *c_char)
-                                    -> BasicBlockRef;
         #[fast_ffi]
         pub unsafe fn LLVMDeleteBasicBlock(BB: BasicBlockRef);
 
@@ -1039,8 +980,6 @@ pub unsafe fn LLVMGetIncomingBlock(PhiNode: ValueRef,
         #[fast_ffi]
         pub unsafe fn LLVMCreateBuilderInContext(C: ContextRef) -> BuilderRef;
         #[fast_ffi]
-        pub unsafe fn LLVMCreateBuilder() -> BuilderRef;
-        #[fast_ffi]
         pub unsafe fn LLVMPositionBuilder(Builder: BuilderRef,
                                           Block: BasicBlockRef,
                                           Instr: ValueRef);
@@ -1893,7 +1832,8 @@ pub unsafe fn LLVMRustParseBitcode(MemBuf: MemoryBufferRef)
 
         /** Parses LLVM asm in the given file */
         #[fast_ffi]
-        pub unsafe fn LLVMRustParseAssemblyFile(Filename: *c_char)
+        pub unsafe fn LLVMRustParseAssemblyFile(Filename: *c_char,
+                                                C: ContextRef)
                                              -> ModuleRef;
 
         #[fast_ffi]
@@ -1909,6 +1849,9 @@ pub unsafe fn LLVMRustAddPrintModulePass(PM: PassManagerRef,
         #[fast_ffi]
         pub unsafe fn LLVMRustPrintPassTimings();
 
+        #[fast_ffi]
+        pub unsafe fn LLVMRustStartMultithreading() -> bool;
+
         #[fast_ffi]
         pub unsafe fn LLVMStructCreateNamed(C: ContextRef, Name: *c_char)
                                          -> TypeRef;
index 60725fa6b73468d668747afda41877a35e6087b8..3f6a37bf864b5727b1b052e1a3750272ec00711a 100644 (file)
@@ -29,7 +29,7 @@
 use back::{link, abi, upcall};
 use driver::session;
 use driver::session::Session;
-use lib::llvm::{ModuleRef, ValueRef, TypeRef, BasicBlockRef};
+use lib::llvm::{ContextRef, ModuleRef, ValueRef, TypeRef, BasicBlockRef};
 use lib::llvm::{True, False};
 use lib::llvm::{llvm, mk_target_data, mk_type_names};
 use lib;
@@ -73,6 +73,7 @@
 use core::str;
 use core::uint;
 use core::vec;
+use core::local_data;
 use extra::time;
 use syntax::ast::ident;
 use syntax::ast_map::{path, path_elt_to_str, path_name};
@@ -1187,7 +1188,7 @@ pub fn new_block(cx: fn_ctxt, parent: Option<block>, kind: block_kind,
     };
     unsafe {
         let llbb = str::as_c_str(cx.ccx.sess.str_of(s), |buf| {
-            llvm::LLVMAppendBasicBlock(cx.llfn, buf)
+            llvm::LLVMAppendBasicBlockInContext(cx.ccx.llcx, cx.llfn, buf)
         });
         let bcx = mk_block(llbb,
                            parent,
@@ -1554,11 +1555,12 @@ pub struct BasicBlocks {
 // Creates the standard set of basic blocks for a function
 pub fn mk_standard_basic_blocks(llfn: ValueRef) -> BasicBlocks {
     unsafe {
+        let cx = task_llcx();
         BasicBlocks {
             sa: str::as_c_str("static_allocas",
-                           |buf| llvm::LLVMAppendBasicBlock(llfn, buf)),
+                           |buf| llvm::LLVMAppendBasicBlockInContext(cx, llfn, buf)),
             rt: str::as_c_str("return",
-                           |buf| llvm::LLVMAppendBasicBlock(llfn, buf))
+                           |buf| llvm::LLVMAppendBasicBlockInContext(cx, llfn, buf))
         }
     }
 }
@@ -2341,7 +2343,7 @@ fn create_entry_fn(ccx: @CrateContext,
         };
         let llbb = str::as_c_str("top", |buf| {
             unsafe {
-                llvm::LLVMAppendBasicBlock(llfn, buf)
+                llvm::LLVMAppendBasicBlockInContext(ccx.llcx, llfn, buf)
             }
         });
         let bld = ccx.builder.B;
@@ -2659,10 +2661,10 @@ pub fn declare_intrinsics(llmod: ModuleRef) -> HashMap<&'static str, ValueRef> {
                            T_void()));
     let memcpy32 =
         decl_cdecl_fn(llmod, "llvm.memcpy.p0i8.p0i8.i32",
-                      T_fn(copy T_memcpy32_args, T_void()));
+                      T_fn(T_memcpy32_args, T_void()));
     let memcpy64 =
         decl_cdecl_fn(llmod, "llvm.memcpy.p0i8.p0i8.i64",
-                      T_fn(copy T_memcpy64_args, T_void()));
+                      T_fn(T_memcpy64_args, T_void()));
     let memmove32 =
         decl_cdecl_fn(llmod, "llvm.memmove.p0i8.p0i8.i32",
                       T_fn(T_memcpy32_args, T_void()));
@@ -3038,9 +3040,13 @@ pub fn trans_crate(sess: session::Session,
     let llmod_id = link_meta.name.to_owned() + ".rc";
 
     unsafe {
+        if !llvm::LLVMRustStartMultithreading() {
+            sess.bug("couldn't enable multi-threaded LLVM");
+        }
+        let llcx = llvm::LLVMContextCreate();
+        set_task_llcx(llcx);
         let llmod = str::as_c_str(llmod_id, |buf| {
-            llvm::LLVMModuleCreateWithNameInContext
-                (buf, llvm::LLVMGetGlobalContext())
+            llvm::LLVMModuleCreateWithNameInContext(buf, llcx)
         });
         let data_layout: &str = sess.targ_cfg.target_strs.data_layout;
         let targ_triple: &str = sess.targ_cfg.target_strs.target_triple;
@@ -3071,6 +3077,7 @@ pub fn trans_crate(sess: session::Session,
         let ccx = @CrateContext {
               sess: sess,
               llmod: llmod,
+              llcx: llcx,
               td: td,
               tn: tn,
               externs: @mut HashMap::new(),
@@ -3124,7 +3131,9 @@ pub fn trans_crate(sess: session::Session,
               int_type: int_type,
               float_type: float_type,
               opaque_vec_type: T_opaque_vec(targ_cfg),
-              builder: BuilderRef_res(unsafe { llvm::LLVMCreateBuilder() }),
+              builder: BuilderRef_res(unsafe {
+                  llvm::LLVMCreateBuilderInContext(llcx)
+              }),
               shape_cx: mk_ctxt(llmod),
               crate_map: crate_map,
               uses_gc: @mut false,
@@ -3172,3 +3181,16 @@ pub fn trans_crate(sess: session::Session,
         return (llmod, link_meta);
     }
 }
+
+fn task_local_llcx_key(_v: @ContextRef) {}
+
+pub fn task_llcx() -> ContextRef {
+    let opt = unsafe { local_data::local_data_get(task_local_llcx_key) };
+    *opt.expect("task-local LLVMContextRef wasn't ever set!")
+}
+
+fn set_task_llcx(c: ContextRef) {
+    unsafe {
+        local_data::local_data_set(task_local_llcx_key, @c);
+    }
+}
index 8ac47ed135ad49769b61c6bf3b4d089df9e600be..af10845181008cd1f779879eae2704a2d615125a 100644 (file)
@@ -564,7 +564,8 @@ pub fn LoadRangeAssert(cx: block, PointerVal: ValueRef, lo: c_ulonglong,
 
         do vec::as_imm_buf([min, max]) |ptr, len| {
             llvm::LLVMSetMetadata(value, lib::llvm::MD_range as c_uint,
-                                  llvm::LLVMMDNode(ptr, len as c_uint));
+                                  llvm::LLVMMDNodeInContext(cx.fcx.ccx.llcx,
+                                                            ptr, len as c_uint));
         }
     }
 
index 6be398c0bb2b145c42b73e2e8707b13af27a6a2c..366c0a90a4c2cf75ad5b139f3fdca2b1dc024366 100644 (file)
@@ -19,6 +19,7 @@
 use lib::llvm::{Struct, Array, Attribute};
 use lib::llvm::{StructRetAttribute};
 use lib::llvm::True;
+use middle::trans::base::task_llcx;
 use middle::trans::common::*;
 use middle::trans::cabi::*;
 
@@ -166,7 +167,7 @@ fn coerce_to_int(size: uint) -> ~[TypeRef] {
     let r = size % 32;
     if r > 0 {
         unsafe {
-            args.push(llvm::LLVMIntType(r as c_uint))
+            args.push(llvm::LLVMIntTypeInContext(task_llcx(), r as c_uint))
         }
     }
 
index d5d018c054355f932bdcbadb91400edb3def261a..4804058609a32c5bb92facdc5492ed985d558977 100644 (file)
@@ -327,7 +327,9 @@ pub fn load_environment(fcx: fn_ctxt,
                 str::as_c_str("load_env",
                               |buf|
                               unsafe {
-                                llvm::LLVMAppendBasicBlock(fcx.llfn, buf)
+                                llvm::LLVMAppendBasicBlockInContext(fcx.ccx.llcx,
+                                                                    fcx.llfn,
+                                                                    buf)
                               });
             fcx.llloadenv = Some(ll);
             ll
index a12ce790d041bc5c9ea582aaa64b4859eb2c72f0..7e47fc47bffcce30acc7791a5b2c73111c313b8a 100644 (file)
@@ -17,7 +17,7 @@
 use driver::session;
 use driver::session::Session;
 use lib::llvm::{ModuleRef, ValueRef, TypeRef, BasicBlockRef, BuilderRef};
-use lib::llvm::{True, False, Bool};
+use lib::llvm::{ContextRef, True, False, Bool};
 use lib::llvm::{llvm, TargetData, TypeNames, associate_type, name_has_type};
 use lib;
 use metadata::common::LinkMeta;
@@ -161,6 +161,7 @@ pub fn BuilderRef_res(B: BuilderRef) -> BuilderRef_res {
 pub struct CrateContext {
      sess: session::Session,
      llmod: ModuleRef,
+     llcx: ContextRef,
      td: TargetData,
      tn: @TypeNames,
      externs: ExternMap,
@@ -798,30 +799,44 @@ pub fn to_str(@mut self) -> ~str {
 
 // LLVM type constructors.
 pub fn T_void() -> TypeRef {
-    unsafe {
-        return llvm::LLVMVoidType();
-    }
+    unsafe { return llvm::LLVMVoidTypeInContext(base::task_llcx()); }
 }
 
 pub fn T_nil() -> TypeRef {
     return T_struct([], false)
 }
 
-pub fn T_metadata() -> TypeRef { unsafe { return llvm::LLVMMetadataType(); } }
+pub fn T_metadata() -> TypeRef {
+    unsafe { return llvm::LLVMMetadataTypeInContext(base::task_llcx()); }
+}
 
-pub fn T_i1() -> TypeRef { unsafe { return llvm::LLVMInt1Type(); } }
+pub fn T_i1() -> TypeRef {
+    unsafe { return llvm::LLVMInt1TypeInContext(base::task_llcx()); }
+}
 
-pub fn T_i8() -> TypeRef { unsafe { return llvm::LLVMInt8Type(); } }
+pub fn T_i8() -> TypeRef {
+    unsafe { return llvm::LLVMInt8TypeInContext(base::task_llcx()); }
+}
 
-pub fn T_i16() -> TypeRef { unsafe { return llvm::LLVMInt16Type(); } }
+pub fn T_i16() -> TypeRef {
+    unsafe { return llvm::LLVMInt16TypeInContext(base::task_llcx()); }
+}
 
-pub fn T_i32() -> TypeRef { unsafe { return llvm::LLVMInt32Type(); } }
+pub fn T_i32() -> TypeRef {
+    unsafe { return llvm::LLVMInt32TypeInContext(base::task_llcx()); }
+}
 
-pub fn T_i64() -> TypeRef { unsafe { return llvm::LLVMInt64Type(); } }
+pub fn T_i64() -> TypeRef {
+    unsafe { return llvm::LLVMInt64TypeInContext(base::task_llcx()); }
+}
 
-pub fn T_f32() -> TypeRef { unsafe { return llvm::LLVMFloatType(); } }
+pub fn T_f32() -> TypeRef {
+    unsafe { return llvm::LLVMFloatTypeInContext(base::task_llcx()); }
+}
 
-pub fn T_f64() -> TypeRef { unsafe { return llvm::LLVMDoubleType(); } }
+pub fn T_f64() -> TypeRef {
+    unsafe { return llvm::LLVMDoubleTypeInContext(base::task_llcx()); }
+}
 
 pub fn T_bool() -> TypeRef { return T_i8(); }
 
@@ -881,8 +896,8 @@ pub fn T_size_t(targ_cfg: @session::config) -> TypeRef {
 pub fn T_fn(inputs: &[TypeRef], output: TypeRef) -> TypeRef {
     unsafe {
         return llvm::LLVMFunctionType(output, to_ptr(inputs),
-                                   inputs.len() as c_uint,
-                                   False);
+                                      inputs.len() as c_uint,
+                                      False);
     }
 }
 
@@ -904,16 +919,18 @@ pub fn T_root(t: TypeRef, addrspace: addrspace) -> TypeRef {
 
 pub fn T_struct(elts: &[TypeRef], packed: bool) -> TypeRef {
     unsafe {
-        return llvm::LLVMStructType(to_ptr(elts),
-                                    elts.len() as c_uint,
-                                    packed as Bool);
+        return llvm::LLVMStructTypeInContext(base::task_llcx(),
+                                             to_ptr(elts),
+                                             elts.len() as c_uint,
+                                             packed as Bool);
     }
 }
 
 pub fn T_named_struct(name: &str) -> TypeRef {
     unsafe {
-        let c = llvm::LLVMGetGlobalContext();
-        return str::as_c_str(name, |buf| llvm::LLVMStructCreateNamed(c, buf));
+        return str::as_c_str(name, |buf| {
+            llvm::LLVMStructCreateNamed(base::task_llcx(), buf)
+        });
     }
 }
 
@@ -1167,7 +1184,8 @@ pub fn C_cstr(cx: @CrateContext, s: @str) -> ValueRef {
         }
 
         let sc = do str::as_c_str(s) |buf| {
-            llvm::LLVMConstString(buf, s.len() as c_uint, False)
+            llvm::LLVMConstStringInContext(cx.llcx, buf, s.len() as c_uint,
+                                           False)
         };
         let g =
             str::as_c_str(fmt!("str%u", (cx.names)("str").name),
@@ -1196,7 +1214,8 @@ pub fn C_estr_slice(cx: @CrateContext, s: @str) -> ValueRef {
 pub fn C_postr(s: &str) -> ValueRef {
     unsafe {
         return do str::as_c_str(s) |buf| {
-            llvm::LLVMConstString(buf, s.len() as c_uint, False)
+            llvm::LLVMConstStringInContext(base::task_llcx(),
+                                           buf, s.len() as c_uint, False)
         };
     }
 }
@@ -1215,7 +1234,8 @@ pub fn C_zero_byte_arr(size: uint) -> ValueRef {
 pub fn C_struct(elts: &[ValueRef]) -> ValueRef {
     unsafe {
         do vec::as_imm_buf(elts) |ptr, len| {
-            llvm::LLVMConstStruct(ptr, len as c_uint, False)
+            llvm::LLVMConstStructInContext(base::task_llcx(),
+                                           ptr, len as c_uint, False)
         }
     }
 }
@@ -1223,7 +1243,8 @@ pub fn C_struct(elts: &[ValueRef]) -> ValueRef {
 pub fn C_packed_struct(elts: &[ValueRef]) -> ValueRef {
     unsafe {
         do vec::as_imm_buf(elts) |ptr, len| {
-            llvm::LLVMConstStruct(ptr, len as c_uint, True)
+            llvm::LLVMConstStructInContext(base::task_llcx(),
+                                           ptr, len as c_uint, True)
         }
     }
 }
@@ -1239,13 +1260,13 @@ pub fn C_named_struct(T: TypeRef, elts: &[ValueRef]) -> ValueRef {
 pub fn C_array(ty: TypeRef, elts: &[ValueRef]) -> ValueRef {
     unsafe {
         return llvm::LLVMConstArray(ty, vec::raw::to_ptr(elts),
-                                 elts.len() as c_uint);
+                                    elts.len() as c_uint);
     }
 }
 
 pub fn C_bytes(bytes: &[u8]) -> ValueRef {
     unsafe {
-        return llvm::LLVMConstString(
+        return llvm::LLVMConstStringInContext(base::task_llcx(),
             cast::transmute(vec::raw::to_ptr(bytes)),
             bytes.len() as c_uint, True);
     }
@@ -1253,7 +1274,7 @@ pub fn C_bytes(bytes: &[u8]) -> ValueRef {
 
 pub fn C_bytes_plus_null(bytes: &[u8]) -> ValueRef {
     unsafe {
-        return llvm::LLVMConstString(
+        return llvm::LLVMConstStringInContext(base::task_llcx(),
             cast::transmute(vec::raw::to_ptr(bytes)),
             bytes.len() as c_uint, False);
     }
index 83c1bfdb0dd4c8bb5332f3f059e9a8f011e83afd..3bb9d4abab0f7b0de404e7c0c86b72f06c5c95c5 100644 (file)
@@ -13,6 +13,7 @@
 use driver::session;
 use lib::llvm::ValueRef;
 use lib::llvm::llvm;
+use middle::trans::base::task_llcx;
 use middle::trans::common::*;
 use middle::trans::machine;
 use middle::trans::type_of;
@@ -61,7 +62,9 @@
 fn llstr(s: &str) -> ValueRef {
     do str::as_c_str(s) |sbuf| {
         unsafe {
-            llvm::LLVMMDString(sbuf, s.len() as libc::c_uint)
+            llvm::LLVMMDStringInContext(task_llcx(),
+                                        sbuf,
+                                        s.len() as libc::c_uint)
         }
     }
 }
@@ -79,7 +82,9 @@ fn lli1(bval: bool) -> ValueRef {
 }
 fn llmdnode(elems: &[ValueRef]) -> ValueRef {
     unsafe {
-        llvm::LLVMMDNode(vec::raw::to_ptr(elems), elems.len() as libc::c_uint)
+        llvm::LLVMMDNodeInContext(task_llcx(),
+                                  vec::raw::to_ptr(elems),
+                                  elems.len() as libc::c_uint)
     }
 }
 fn llunused() -> ValueRef {
index e3c424f8e7ecfe0b0f21b82d135f86e7b5419527..2fff45678bcb54b203524770e8fd20c64f8a0d6e 100644 (file)
@@ -58,7 +58,7 @@ pub fn type_of_fn(cx: @CrateContext, inputs: &[ty::t], output: ty::t)
         if output_is_immediate {
             T_fn(atys, lloutputtype)
         } else {
-            T_fn(atys, llvm::LLVMVoidType())
+            T_fn(atys, llvm::LLVMVoidTypeInContext(cx.llcx))
         }
     }
 }
index 90a5a350b7fa4b2b9af68edf50731d70f8ea4c28..1a97c806027d541e9018344423bf9a2ce1175adb 100644 (file)
@@ -648,5 +648,9 @@ mod tests {
             fn f() {}
             f()
         ");
+
+        debug!("regression test for #5803");
+        run_cmds(["spawn( || println(\"Please don't segfault\") );",
+                  "do spawn { println(\"Please?\"); }"]);
     }
 }
index 4ee5df28d24ee3fd344d0b10108febc7d64e1f3b..17eb0f50b9bcdbd16d11b8042401944fcb883898 100644 (file)
@@ -447,9 +447,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 +500,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 +559,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;
+}
index 8ebdbd0f307a65ec58ffb49e447b7b1db7ca33ef..f8c68d798b9afb83485e60ef2d9fed8e67739296 100644 (file)
@@ -10,6 +10,7 @@ LLVMRustExecuteJIT
 LLVMRustParseBitcode
 LLVMRustParseAssemblyFile
 LLVMRustPrintPassTimings
+LLVMRustStartMultithreading
 LLVMCreateObjectFile
 LLVMDisposeObjectFile
 LLVMGetSections
@@ -319,7 +320,6 @@ LLVMGetFunctionAttr
 LLVMGetFunctionCallConv
 LLVMGetGC
 LLVMGetGlobalContext
-LLVMGetGlobalContext
 LLVMGetGlobalParent
 LLVMGetGlobalPassRegistry
 LLVMGetIncomingBlock
@@ -500,7 +500,6 @@ LLVMMDNode
 LLVMMDNodeInContext
 LLVMMDString
 LLVMMDStringInContext
-LLVMMetadataType
 LLVMMetadataTypeInContext
 LLVMModuleCreateWithName
 LLVMModuleCreateWithNameInContext