1
Fork 0

Remove all usage of the global LLVMContextRef

This allows parallel usage of the rustc library
This commit is contained in:
Alex Crichton 2013-05-16 23:40:42 -04:00
parent 1310212c27
commit 779191cd4b
10 changed files with 126 additions and 113 deletions

View file

@ -239,16 +239,12 @@ pub mod llvm {
#[fast_ffi] #[fast_ffi]
pub unsafe fn LLVMContextCreate() -> ContextRef; pub unsafe fn LLVMContextCreate() -> ContextRef;
#[fast_ffi] #[fast_ffi]
pub unsafe fn LLVMGetGlobalContext() -> ContextRef;
#[fast_ffi]
pub unsafe fn LLVMContextDispose(C: ContextRef); pub unsafe fn LLVMContextDispose(C: ContextRef);
#[fast_ffi] #[fast_ffi]
pub unsafe fn LLVMGetMDKindIDInContext(C: ContextRef, pub unsafe fn LLVMGetMDKindIDInContext(C: ContextRef,
Name: *c_char, Name: *c_char,
SLen: c_uint) SLen: c_uint)
-> c_uint; -> c_uint;
#[fast_ffi]
pub unsafe fn LLVMGetMDKindID(Name: *c_char, SLen: c_uint) -> c_uint;
/* Create and destroy modules. */ /* Create and destroy modules. */
#[fast_ffi] #[fast_ffi]
@ -256,6 +252,8 @@ pub mod llvm {
C: ContextRef) C: ContextRef)
-> ModuleRef; -> ModuleRef;
#[fast_ffi] #[fast_ffi]
pub unsafe fn LLVMGetModuleContext(M: ModuleRef) -> ContextRef;
#[fast_ffi]
pub unsafe fn LLVMDisposeModule(M: ModuleRef); pub unsafe fn LLVMDisposeModule(M: ModuleRef);
/** Data layout. See Module::getDataLayout. */ /** Data layout. See Module::getDataLayout. */
@ -300,18 +298,6 @@ pub mod llvm {
pub unsafe fn LLVMIntTypeInContext(C: ContextRef, pub unsafe fn LLVMIntTypeInContext(C: ContextRef,
NumBits: c_uint) -> TypeRef; 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] #[fast_ffi]
pub unsafe fn LLVMGetIntTypeWidth(IntegerTy: TypeRef) -> c_uint; pub unsafe fn LLVMGetIntTypeWidth(IntegerTy: TypeRef) -> c_uint;
@ -327,17 +313,6 @@ pub mod llvm {
#[fast_ffi] #[fast_ffi]
pub unsafe fn LLVMPPCFP128TypeInContext(C: ContextRef) -> TypeRef; 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 */ /* Operations on function types */
#[fast_ffi] #[fast_ffi]
pub unsafe fn LLVMFunctionType(ReturnType: TypeRef, pub unsafe fn LLVMFunctionType(ReturnType: TypeRef,
@ -361,11 +336,6 @@ pub mod llvm {
ElementCount: c_uint, ElementCount: c_uint,
Packed: Bool) -> TypeRef; Packed: Bool) -> TypeRef;
#[fast_ffi] #[fast_ffi]
pub unsafe fn LLVMStructType(ElementTypes: *TypeRef,
ElementCount: c_uint,
Packed: Bool)
-> TypeRef;
#[fast_ffi]
pub unsafe fn LLVMCountStructElementTypes(StructTy: TypeRef) pub unsafe fn LLVMCountStructElementTypes(StructTy: TypeRef)
-> c_uint; -> c_uint;
#[fast_ffi] #[fast_ffi]
@ -403,13 +373,6 @@ pub mod llvm {
#[fast_ffi] #[fast_ffi]
pub unsafe fn LLVMMetadataTypeInContext(C: ContextRef) -> TypeRef; 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 */ /* Operations on all values */
#[fast_ffi] #[fast_ffi]
pub unsafe fn LLVMTypeOf(Val: ValueRef) -> TypeRef; pub unsafe fn LLVMTypeOf(Val: ValueRef) -> TypeRef;
@ -482,15 +445,11 @@ pub mod llvm {
SLen: c_uint) SLen: c_uint)
-> ValueRef; -> ValueRef;
#[fast_ffi] #[fast_ffi]
pub unsafe fn LLVMMDString(Str: *c_char, SLen: c_uint) -> ValueRef;
#[fast_ffi]
pub unsafe fn LLVMMDNodeInContext(C: ContextRef, pub unsafe fn LLVMMDNodeInContext(C: ContextRef,
Vals: *ValueRef, Vals: *ValueRef,
Count: c_uint) Count: c_uint)
-> ValueRef; -> ValueRef;
#[fast_ffi] #[fast_ffi]
pub unsafe fn LLVMMDNode(Vals: *ValueRef, Count: c_uint) -> ValueRef;
#[fast_ffi]
pub unsafe fn LLVMAddNamedMetadataOperand(M: ModuleRef, Str: *c_char, pub unsafe fn LLVMAddNamedMetadataOperand(M: ModuleRef, Str: *c_char,
Val: ValueRef); Val: ValueRef);
@ -544,20 +503,11 @@ pub mod llvm {
Packed: Bool) -> ValueRef; Packed: Bool) -> ValueRef;
#[fast_ffi] #[fast_ffi]
pub unsafe fn LLVMConstString(Str: *c_char,
Length: c_uint,
DontNullTerminate: Bool)
-> ValueRef;
#[fast_ffi]
pub unsafe fn LLVMConstArray(ElementTy: TypeRef, pub unsafe fn LLVMConstArray(ElementTy: TypeRef,
ConstantVals: *ValueRef, ConstantVals: *ValueRef,
Length: c_uint) Length: c_uint)
-> ValueRef; -> ValueRef;
#[fast_ffi] #[fast_ffi]
pub unsafe fn LLVMConstStruct(ConstantVals: *ValueRef,
Count: c_uint,
Packed: Bool) -> ValueRef;
#[fast_ffi]
pub unsafe fn LLVMConstVector(ScalarConstantVals: *ValueRef, pub unsafe fn LLVMConstVector(ScalarConstantVals: *ValueRef,
Size: c_uint) -> ValueRef; Size: c_uint) -> ValueRef;
@ -970,15 +920,6 @@ pub mod llvm {
BB: BasicBlockRef, BB: BasicBlockRef,
Name: *c_char) Name: *c_char)
-> BasicBlockRef; -> 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] #[fast_ffi]
pub unsafe fn LLVMDeleteBasicBlock(BB: BasicBlockRef); pub unsafe fn LLVMDeleteBasicBlock(BB: BasicBlockRef);
@ -1039,8 +980,6 @@ pub mod llvm {
#[fast_ffi] #[fast_ffi]
pub unsafe fn LLVMCreateBuilderInContext(C: ContextRef) -> BuilderRef; pub unsafe fn LLVMCreateBuilderInContext(C: ContextRef) -> BuilderRef;
#[fast_ffi] #[fast_ffi]
pub unsafe fn LLVMCreateBuilder() -> BuilderRef;
#[fast_ffi]
pub unsafe fn LLVMPositionBuilder(Builder: BuilderRef, pub unsafe fn LLVMPositionBuilder(Builder: BuilderRef,
Block: BasicBlockRef, Block: BasicBlockRef,
Instr: ValueRef); Instr: ValueRef);
@ -1893,7 +1832,8 @@ pub mod llvm {
/** Parses LLVM asm in the given file */ /** Parses LLVM asm in the given file */
#[fast_ffi] #[fast_ffi]
pub unsafe fn LLVMRustParseAssemblyFile(Filename: *c_char) pub unsafe fn LLVMRustParseAssemblyFile(Filename: *c_char,
C: ContextRef)
-> ModuleRef; -> ModuleRef;
#[fast_ffi] #[fast_ffi]
@ -1909,6 +1849,9 @@ pub mod llvm {
#[fast_ffi] #[fast_ffi]
pub unsafe fn LLVMRustPrintPassTimings(); pub unsafe fn LLVMRustPrintPassTimings();
#[fast_ffi]
pub unsafe fn LLVMRustStartMultithreading() -> bool;
#[fast_ffi] #[fast_ffi]
pub unsafe fn LLVMStructCreateNamed(C: ContextRef, Name: *c_char) pub unsafe fn LLVMStructCreateNamed(C: ContextRef, Name: *c_char)
-> TypeRef; -> TypeRef;

View file

@ -29,7 +29,7 @@ use back::link::{mangle_exported_name};
use back::{link, abi, upcall}; use back::{link, abi, upcall};
use driver::session; use driver::session;
use driver::session::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::{True, False};
use lib::llvm::{llvm, mk_target_data, mk_type_names}; use lib::llvm::{llvm, mk_target_data, mk_type_names};
use lib; use lib;
@ -73,6 +73,7 @@ use core::libc::c_uint;
use core::str; use core::str;
use core::uint; use core::uint;
use core::vec; use core::vec;
use core::local_data;
use extra::time; use extra::time;
use syntax::ast::ident; use syntax::ast::ident;
use syntax::ast_map::{path, path_elt_to_str, path_name}; use syntax::ast_map::{path, path_elt_to_str, path_name};
@ -1186,7 +1187,7 @@ pub fn new_block(cx: fn_ctxt, parent: Option<block>, kind: block_kind,
}; };
unsafe { unsafe {
let llbb = str::as_c_str(*cx.ccx.sess.str_of(s), |buf| { 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, let bcx = mk_block(llbb,
parent, parent,
@ -1560,11 +1561,12 @@ pub struct BasicBlocks {
// Creates the standard set of basic blocks for a function // Creates the standard set of basic blocks for a function
pub fn mk_standard_basic_blocks(llfn: ValueRef) -> BasicBlocks { pub fn mk_standard_basic_blocks(llfn: ValueRef) -> BasicBlocks {
unsafe { unsafe {
let cx = task_llcx();
BasicBlocks { BasicBlocks {
sa: str::as_c_str("static_allocas", sa: str::as_c_str("static_allocas",
|buf| llvm::LLVMAppendBasicBlock(llfn, buf)), |buf| llvm::LLVMAppendBasicBlockInContext(cx, llfn, buf)),
rt: str::as_c_str("return", rt: str::as_c_str("return",
|buf| llvm::LLVMAppendBasicBlock(llfn, buf)) |buf| llvm::LLVMAppendBasicBlockInContext(cx, llfn, buf))
} }
} }
} }
@ -2347,7 +2349,7 @@ pub fn create_entry_wrapper(ccx: @CrateContext,
}; };
let llbb = str::as_c_str("top", |buf| { let llbb = str::as_c_str("top", |buf| {
unsafe { unsafe {
llvm::LLVMAppendBasicBlock(llfn, buf) llvm::LLVMAppendBasicBlockInContext(ccx.llcx, llfn, buf)
} }
}); });
let bld = ccx.builder.B; let bld = ccx.builder.B;
@ -2665,10 +2667,10 @@ pub fn declare_intrinsics(llmod: ModuleRef) -> HashMap<~str, ValueRef> {
T_void())); T_void()));
let memcpy32 = let memcpy32 =
decl_cdecl_fn(llmod, "llvm.memcpy.p0i8.p0i8.i32", 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 = let memcpy64 =
decl_cdecl_fn(llmod, "llvm.memcpy.p0i8.p0i8.i64", 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 = let memmove32 =
decl_cdecl_fn(llmod, "llvm.memmove.p0i8.p0i8.i32", decl_cdecl_fn(llmod, "llvm.memmove.p0i8.p0i8.i32",
T_fn(T_memcpy32_args, T_void())); T_fn(T_memcpy32_args, T_void()));
@ -3043,9 +3045,13 @@ pub fn trans_crate(sess: session::Session,
let llmod_id = link_meta.name.to_owned() + ".rc"; let llmod_id = link_meta.name.to_owned() + ".rc";
unsafe { 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| { let llmod = str::as_c_str(llmod_id, |buf| {
llvm::LLVMModuleCreateWithNameInContext llvm::LLVMModuleCreateWithNameInContext(buf, llcx)
(buf, llvm::LLVMGetGlobalContext())
}); });
let data_layout: &str = sess.targ_cfg.target_strs.data_layout; let data_layout: &str = sess.targ_cfg.target_strs.data_layout;
let targ_triple: &str = sess.targ_cfg.target_strs.target_triple; let targ_triple: &str = sess.targ_cfg.target_strs.target_triple;
@ -3079,6 +3085,7 @@ pub fn trans_crate(sess: session::Session,
let ccx = @CrateContext { let ccx = @CrateContext {
sess: sess, sess: sess,
llmod: llmod, llmod: llmod,
llcx: llcx,
td: td, td: td,
tn: tn, tn: tn,
externs: @mut HashMap::new(), externs: @mut HashMap::new(),
@ -3133,7 +3140,9 @@ pub fn trans_crate(sess: session::Session,
float_type: float_type, float_type: float_type,
task_type: task_type, task_type: task_type,
opaque_vec_type: T_opaque_vec(targ_cfg), 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), shape_cx: mk_ctxt(llmod),
crate_map: crate_map, crate_map: crate_map,
uses_gc: @mut false, uses_gc: @mut false,
@ -3181,3 +3190,16 @@ pub fn trans_crate(sess: session::Session,
return (llmod, link_meta); 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);
}
}

View file

@ -564,7 +564,8 @@ pub fn LoadRangeAssert(cx: block, PointerVal: ValueRef, lo: c_ulonglong,
do vec::as_imm_buf([min, max]) |ptr, len| { do vec::as_imm_buf([min, max]) |ptr, len| {
llvm::LLVMSetMetadata(value, lib::llvm::MD_range as c_uint, 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));
} }
} }

View file

@ -19,6 +19,7 @@ use lib::llvm::{llvm, TypeRef, Integer, Pointer, Float, Double};
use lib::llvm::{Struct, Array, Attribute}; use lib::llvm::{Struct, Array, Attribute};
use lib::llvm::{StructRetAttribute}; use lib::llvm::{StructRetAttribute};
use lib::llvm::True; use lib::llvm::True;
use middle::trans::base::task_llcx;
use middle::trans::common::*; use middle::trans::common::*;
use middle::trans::cabi::*; use middle::trans::cabi::*;
@ -166,7 +167,7 @@ fn coerce_to_int(size: uint) -> ~[TypeRef] {
let r = size % 32; let r = size % 32;
if r > 0 { if r > 0 {
unsafe { unsafe {
args.push(llvm::LLVMIntType(r as c_uint)) args.push(llvm::LLVMIntTypeInContext(task_llcx(), r as c_uint))
} }
} }

View file

@ -326,7 +326,9 @@ pub fn load_environment(fcx: fn_ctxt,
str::as_c_str("load_env", str::as_c_str("load_env",
|buf| |buf|
unsafe { unsafe {
llvm::LLVMAppendBasicBlock(fcx.llfn, buf) llvm::LLVMAppendBasicBlockInContext(fcx.ccx.llcx,
fcx.llfn,
buf)
}); });
fcx.llloadenv = Some(ll); fcx.llloadenv = Some(ll);
ll ll

View file

@ -16,7 +16,7 @@ use back::{abi, upcall};
use driver::session; use driver::session;
use driver::session::Session; use driver::session::Session;
use lib::llvm::{ModuleRef, ValueRef, TypeRef, BasicBlockRef, BuilderRef}; 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::llvm::{llvm, TargetData, TypeNames, associate_type, name_has_type};
use lib; use lib;
use metadata::common::LinkMeta; use metadata::common::LinkMeta;
@ -160,6 +160,7 @@ pub type ExternMap = @mut HashMap<@str, ValueRef>;
pub struct CrateContext { pub struct CrateContext {
sess: session::Session, sess: session::Session,
llmod: ModuleRef, llmod: ModuleRef,
llcx: ContextRef,
td: TargetData, td: TargetData,
tn: @TypeNames, tn: @TypeNames,
externs: ExternMap, externs: ExternMap,
@ -798,30 +799,44 @@ impl block_ {
// LLVM type constructors. // LLVM type constructors.
pub fn T_void() -> TypeRef { pub fn T_void() -> TypeRef {
unsafe { unsafe { return llvm::LLVMVoidTypeInContext(base::task_llcx()); }
return llvm::LLVMVoidType();
}
} }
pub fn T_nil() -> TypeRef { pub fn T_nil() -> TypeRef {
return T_struct([], false) 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(); } 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 { pub fn T_fn(inputs: &[TypeRef], output: TypeRef) -> TypeRef {
unsafe { unsafe {
return llvm::LLVMFunctionType(output, to_ptr(inputs), return llvm::LLVMFunctionType(output, to_ptr(inputs),
inputs.len() as c_uint, inputs.len() as c_uint,
False); False);
} }
} }
@ -904,16 +919,18 @@ pub fn T_root(t: TypeRef, addrspace: addrspace) -> TypeRef {
pub fn T_struct(elts: &[TypeRef], packed: bool) -> TypeRef { pub fn T_struct(elts: &[TypeRef], packed: bool) -> TypeRef {
unsafe { unsafe {
return llvm::LLVMStructType(to_ptr(elts), return llvm::LLVMStructTypeInContext(base::task_llcx(),
elts.len() as c_uint, to_ptr(elts),
packed as Bool); elts.len() as c_uint,
packed as Bool);
} }
} }
pub fn T_named_struct(name: &str) -> TypeRef { pub fn T_named_struct(name: &str) -> TypeRef {
unsafe { unsafe {
let c = llvm::LLVMGetGlobalContext(); return str::as_c_str(name, |buf| {
return str::as_c_str(name, |buf| llvm::LLVMStructCreateNamed(c, buf)); llvm::LLVMStructCreateNamed(base::task_llcx(), buf)
});
} }
} }
@ -1191,7 +1208,8 @@ pub fn C_cstr(cx: @CrateContext, s: @~str) -> ValueRef {
} }
let sc = do str::as_c_str(*s) |buf| { 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 = let g =
str::as_c_str(fmt!("str%u", (cx.names)("str").name), str::as_c_str(fmt!("str%u", (cx.names)("str").name),
@ -1220,7 +1238,8 @@ pub fn C_estr_slice(cx: @CrateContext, s: @~str) -> ValueRef {
pub fn C_postr(s: &str) -> ValueRef { pub fn C_postr(s: &str) -> ValueRef {
unsafe { unsafe {
return do str::as_c_str(s) |buf| { 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)
}; };
} }
} }
@ -1239,7 +1258,8 @@ pub fn C_zero_byte_arr(size: uint) -> ValueRef {
pub fn C_struct(elts: &[ValueRef]) -> ValueRef { pub fn C_struct(elts: &[ValueRef]) -> ValueRef {
unsafe { unsafe {
do vec::as_imm_buf(elts) |ptr, len| { 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)
} }
} }
} }
@ -1247,7 +1267,8 @@ pub fn C_struct(elts: &[ValueRef]) -> ValueRef {
pub fn C_packed_struct(elts: &[ValueRef]) -> ValueRef { pub fn C_packed_struct(elts: &[ValueRef]) -> ValueRef {
unsafe { unsafe {
do vec::as_imm_buf(elts) |ptr, len| { 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)
} }
} }
} }
@ -1263,13 +1284,13 @@ pub fn C_named_struct(T: TypeRef, elts: &[ValueRef]) -> ValueRef {
pub fn C_array(ty: TypeRef, elts: &[ValueRef]) -> ValueRef { pub fn C_array(ty: TypeRef, elts: &[ValueRef]) -> ValueRef {
unsafe { unsafe {
return llvm::LLVMConstArray(ty, vec::raw::to_ptr(elts), 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 { pub fn C_bytes(bytes: &[u8]) -> ValueRef {
unsafe { unsafe {
return llvm::LLVMConstString( return llvm::LLVMConstStringInContext(base::task_llcx(),
cast::transmute(vec::raw::to_ptr(bytes)), cast::transmute(vec::raw::to_ptr(bytes)),
bytes.len() as c_uint, True); bytes.len() as c_uint, True);
} }
@ -1277,7 +1298,7 @@ pub fn C_bytes(bytes: &[u8]) -> ValueRef {
pub fn C_bytes_plus_null(bytes: &[u8]) -> ValueRef { pub fn C_bytes_plus_null(bytes: &[u8]) -> ValueRef {
unsafe { unsafe {
return llvm::LLVMConstString( return llvm::LLVMConstStringInContext(base::task_llcx(),
cast::transmute(vec::raw::to_ptr(bytes)), cast::transmute(vec::raw::to_ptr(bytes)),
bytes.len() as c_uint, False); bytes.len() as c_uint, False);
} }

View file

@ -13,6 +13,7 @@ use core::prelude::*;
use driver::session; use driver::session;
use lib::llvm::ValueRef; use lib::llvm::ValueRef;
use lib::llvm::llvm; use lib::llvm::llvm;
use middle::trans::base::task_llcx;
use middle::trans::common::*; use middle::trans::common::*;
use middle::trans::machine; use middle::trans::machine;
use middle::trans::type_of; use middle::trans::type_of;
@ -61,7 +62,9 @@ static DW_ATE_unsigned_char: int = 0x08;
fn llstr(s: &str) -> ValueRef { fn llstr(s: &str) -> ValueRef {
do str::as_c_str(s) |sbuf| { do str::as_c_str(s) |sbuf| {
unsafe { 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 { fn llmdnode(elems: &[ValueRef]) -> ValueRef {
unsafe { 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 { fn llunused() -> ValueRef {

View file

@ -58,7 +58,7 @@ pub fn type_of_fn(cx: @CrateContext, inputs: &[ty::t], output: ty::t)
if output_is_immediate { if output_is_immediate {
T_fn(atys, lloutputtype) T_fn(atys, lloutputtype)
} else { } else {
T_fn(atys, llvm::LLVMVoidType()) T_fn(atys, llvm::LLVMVoidTypeInContext(cx.llcx))
} }
} }
} }

View file

@ -447,9 +447,10 @@ LLVMRustWriteOutputFile(LLVMPassManagerRef PMR,
return true; return true;
} }
extern "C" LLVMModuleRef LLVMRustParseAssemblyFile(const char *Filename) { extern "C" LLVMModuleRef LLVMRustParseAssemblyFile(LLVMContextRef C,
const char *Filename) {
SMDiagnostic d; SMDiagnostic d;
Module *m = ParseAssemblyFile(Filename, d, getGlobalContext()); Module *m = ParseAssemblyFile(Filename, d, *unwrap(C));
if (m) { if (m) {
return wrap(m); return wrap(m);
} else { } else {
@ -499,9 +500,6 @@ extern "C" LLVMValueRef LLVMGetOrInsertFunction(LLVMModuleRef M,
extern "C" LLVMTypeRef LLVMMetadataTypeInContext(LLVMContextRef C) { extern "C" LLVMTypeRef LLVMMetadataTypeInContext(LLVMContextRef C) {
return wrap(Type::getMetadataTy(*unwrap(C))); return wrap(Type::getMetadataTy(*unwrap(C)));
} }
extern "C" LLVMTypeRef LLVMMetadataType(void) {
return LLVMMetadataTypeInContext(LLVMGetGlobalContext());
}
extern "C" LLVMValueRef LLVMBuildAtomicLoad(LLVMBuilderRef B, extern "C" LLVMValueRef LLVMBuildAtomicLoad(LLVMBuilderRef B,
LLVMValueRef source, LLVMValueRef source,
@ -561,3 +559,24 @@ extern "C" LLVMValueRef LLVMInlineAsm(LLVMTypeRef Ty,
Constraints, HasSideEffects, Constraints, HasSideEffects,
IsAlignStack, (InlineAsm::AsmDialect) Dialect)); 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;
}

View file

@ -10,6 +10,7 @@ LLVMRustExecuteJIT
LLVMRustParseBitcode LLVMRustParseBitcode
LLVMRustParseAssemblyFile LLVMRustParseAssemblyFile
LLVMRustPrintPassTimings LLVMRustPrintPassTimings
LLVMRustStartMultithreading
LLVMCreateObjectFile LLVMCreateObjectFile
LLVMDisposeObjectFile LLVMDisposeObjectFile
LLVMGetSections LLVMGetSections
@ -319,7 +320,6 @@ LLVMGetFunctionAttr
LLVMGetFunctionCallConv LLVMGetFunctionCallConv
LLVMGetGC LLVMGetGC
LLVMGetGlobalContext LLVMGetGlobalContext
LLVMGetGlobalContext
LLVMGetGlobalParent LLVMGetGlobalParent
LLVMGetGlobalPassRegistry LLVMGetGlobalPassRegistry
LLVMGetIncomingBlock LLVMGetIncomingBlock
@ -500,7 +500,6 @@ LLVMMDNode
LLVMMDNodeInContext LLVMMDNodeInContext
LLVMMDString LLVMMDString
LLVMMDStringInContext LLVMMDStringInContext
LLVMMetadataType
LLVMMetadataTypeInContext LLVMMetadataTypeInContext
LLVMModuleCreateWithName LLVMModuleCreateWithName
LLVMModuleCreateWithNameInContext LLVMModuleCreateWithNameInContext