diff --git a/src/librustc/back/upcall.rs b/src/librustc/back/upcall.rs index 4d2ea4eb4a6..76bba481619 100644 --- a/src/librustc/back/upcall.rs +++ b/src/librustc/back/upcall.rs @@ -11,8 +11,8 @@ use driver::session; use middle::trans::base; -use middle::trans::common::{T_fn, T_i8, T_i32, T_int, T_ptr, T_void}; -use lib::llvm::{ModuleRef, ValueRef, TypeRef}; +use middle::trans::type_::Type; +use lib::llvm::{ModuleRef, ValueRef}; pub struct Upcalls { trace: ValueRef, @@ -22,40 +22,35 @@ pub struct Upcalls { reset_stack_limit: ValueRef } -pub fn declare_upcalls(targ_cfg: @session::config, - llmod: ModuleRef) -> @Upcalls { - fn decl(llmod: ModuleRef, prefix: ~str, name: ~str, - tys: ~[TypeRef], rv: TypeRef) -> - ValueRef { - let arg_tys = tys.map(|t| *t); - let fn_ty = T_fn(arg_tys, rv); - return base::decl_cdecl_fn(llmod, prefix + name, fn_ty); - } - fn nothrow(f: ValueRef) -> ValueRef { - base::set_no_unwind(f); f - } - let d: &fn(a: ~str, b: ~[TypeRef], c: TypeRef) -> ValueRef = - |a,b,c| decl(llmod, ~"upcall_", a, b, c); - let dv: &fn(a: ~str, b: ~[TypeRef]) -> ValueRef = - |a,b| decl(llmod, ~"upcall_", a, b, T_void()); +macro_rules! upcall ( + (fn $name:ident($($arg:expr),+) -> $ret:expr) => ({ + let fn_ty = Type::func([ $($arg),* ], &$ret); + base::decl_cdecl_fn(llmod, ~"upcall_" + stringify!($name), fn_ty) + }); + (nothrow fn $name:ident($($arg:expr),+) -> $ret:expr) => ({ + let fn_ty = Type::func([ $($arg),* ], &$ret); + let decl = base::decl_cdecl_fn(llmod, ~"upcall_" + stringify!($name), fn_ty); + base::set_no_unwind(decl); + decl + }); + (nothrow fn $name:ident -> $ret:expr) => ({ + let fn_ty = Type::func([], &$ret); + let decl = base::decl_cdecl_fn(llmod, ~"upcall_" + stringify!($name), fn_ty); + base::set_no_unwind(decl); + decl + }) +) - let int_t = T_int(targ_cfg); +pub fn declare_upcalls(targ_cfg: @session::config, llmod: ModuleRef) -> @Upcalls { + let opaque_ptr = Type::i8().ptr_to(); + let int_ty = Type::int(targ_cfg.arch); @Upcalls { - trace: dv(~"trace", ~[T_ptr(T_i8()), - T_ptr(T_i8()), - int_t]), - call_shim_on_c_stack: - d(~"call_shim_on_c_stack", - // arguments: void *args, void *fn_ptr - ~[T_ptr(T_i8()), T_ptr(T_i8())], - int_t), + trace: upcall!(fn trace(opaque_ptr, opaque_ptr, int_ty) -> Type::void()), + call_shim_on_c_stack: upcall!(fn call_shim_on_c_stack(opaque_ptr, opaque_ptr) -> int_ty), call_shim_on_rust_stack: - d(~"call_shim_on_rust_stack", - ~[T_ptr(T_i8()), T_ptr(T_i8())], int_t), - rust_personality: - nothrow(d(~"rust_personality", ~[], T_i32())), - reset_stack_limit: - nothrow(dv(~"reset_stack_limit", ~[])) + upcall!(fn call_shim_on_rust_stack(opaque_ptr, opaque_ptr) -> int_ty), + rust_personality: upcall!(nothrow fn rust_personality -> Type::i32()), + reset_stack_limit: upcall!(nothrow fn reset_stack_limit -> Type::void()) } } diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index 8d6cad62e75..4bc96117ff5 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -13,9 +13,9 @@ use core::prelude::*; use core::hashmap::HashMap; use core::libc::{c_uint, c_ushort}; use core::option; -use core::ptr; use core::str; -use core::vec; + +use middle::trans::type_::Type; pub type Opcode = u32; pub type Bool = c_uint; @@ -2121,155 +2121,90 @@ pub fn ConstFCmp(Pred: RealPredicate, V1: ValueRef, V2: ValueRef) -> ValueRef { /* Memory-managed object interface to type handles. */ pub struct TypeNames { - type_names: @mut HashMap, - named_types: @mut HashMap<@str, TypeRef> + type_names: HashMap, + named_types: HashMap<~str, TypeRef> } -pub fn associate_type(tn: @TypeNames, s: @str, t: TypeRef) { - assert!(tn.type_names.insert(t, s)); - assert!(tn.named_types.insert(s, t)); -} - -pub fn type_has_name(tn: @TypeNames, t: TypeRef) -> Option<@str> { - return tn.type_names.find(&t).map_consume(|x| *x); -} - -pub fn name_has_type(tn: @TypeNames, s: @str) -> Option { - return tn.named_types.find(&s).map_consume(|x| *x); -} - -pub fn mk_type_names() -> @TypeNames { - @TypeNames { - type_names: @mut HashMap::new(), - named_types: @mut HashMap::new() +impl TypeNames { + pub fn new() -> TypeNames { + TypeNames { + type_names: HashMap::new(), + named_types: HashMap::new() + } } -} -pub fn type_to_str(names: @TypeNames, ty: TypeRef) -> @str { - return type_to_str_inner(names, [], ty); -} + pub fn associate_type(&mut self, s: &str, t: &Type) { + assert!(self.type_names.insert(t.to_ref(), s.to_owned())); + assert!(self.named_types.insert(s.to_owned(), t.to_ref())); + } -pub fn type_to_str_inner(names: @TypeNames, outer0: &[TypeRef], ty: TypeRef) - -> @str { - unsafe { - match type_has_name(names, ty) { - option::Some(n) => return n, - _ => {} + pub fn find_name<'r>(&'r self, ty: &Type) -> Option<&'r str> { + match self.type_names.find(&ty.to_ref()) { + Some(a) => Some(a.slice(0, a.len())), + None => None + } + } + + pub fn find_type(&self, s: &str) -> Option { + self.named_types.find_equiv(&s).map_consume(|x| Type::from_ref(*x)) + } + + pub fn type_to_str(&self, ty: Type) -> ~str { + match self.find_name(&ty) { + option::Some(name) => return name.to_owned(), + None => () } - let outer = vec::append_one(outer0.to_owned(), ty); + unsafe { + let kind = ty.kind(); - let kind = llvm::LLVMGetTypeKind(ty); - - fn tys_str(names: @TypeNames, outer: &[TypeRef], - tys: ~[TypeRef]) -> @str { - let mut s = ~""; - let mut first: bool = true; - for tys.each |t| { - if first { first = false; } else { s += ", "; } - s += type_to_str_inner(names, outer, *t); - } - // [Note at-str] FIXME #2543: Could rewrite this without the copy, - // but need better @str support. - return s.to_managed(); - } - - match kind { - Void => return @"Void", - Half => return @"Half", - Float => return @"Float", - Double => return @"Double", - X86_FP80 => return @"X86_FP80", - FP128 => return @"FP128", - PPC_FP128 => return @"PPC_FP128", - Label => return @"Label", - Integer => { - // See [Note at-str] - return fmt!("i%d", llvm::LLVMGetIntTypeWidth(ty) - as int).to_managed(); - } - Function => { - let out_ty: TypeRef = llvm::LLVMGetReturnType(ty); - let n_args = llvm::LLVMCountParamTypes(ty) as uint; - let args = vec::from_elem(n_args, 0 as TypeRef); - llvm::LLVMGetParamTypes(ty, vec::raw::to_ptr(args)); - // See [Note at-str] - return fmt!("fn(%s) -> %s", - tys_str(names, outer, args), - type_to_str_inner(names, outer, out_ty)).to_managed(); - } - Struct => { - let elts = struct_tys(ty); - // See [Note at-str] - return fmt!("{%s}", tys_str(names, outer, elts)).to_managed(); - } - Array => { - let el_ty = llvm::LLVMGetElementType(ty); - // See [Note at-str] - return fmt!("[%s@ x %u", type_to_str_inner(names, outer, el_ty), - llvm::LLVMGetArrayLength(ty) as uint).to_managed(); - } - Pointer => { - let mut i = 0; - for outer0.each |tout| { - i += 1; - if *tout as int == ty as int { - let n = outer0.len() - i; - // See [Note at-str] - return fmt!("*\\%d", n as int).to_managed(); + match kind { + Void => ~"Void", + Half => ~"Half", + Double => ~"Double", + X86_FP80 => ~"X86_FP80", + FP128 => ~"FP128", + PPC_FP128 => ~"PPC_FP128", + Label => ~"Label", + Vector => ~"Vector", + Metadata => ~"Metadata", + X86_MMX => ~"X86_MMAX", + Integer => { + fmt!("i%d", llvm::LLVMGetIntTypeWidth(ty.to_ref()) as int) } - } - let addrstr = { - let addrspace = llvm::LLVMGetPointerAddressSpace(ty) as uint; - if addrspace == 0 { - ~"" - } else { - fmt!("addrspace(%u)", addrspace) + Function => { + let out_ty = ty.return_type(); + let args = ty.func_params(); + let args = args.map(|&ty| self.type_to_str(ty)).connect(", "); + let out_ty = self.type_to_str(out_ty); + fmt!("fn(%s) -> %s", args, out_ty) } - }; - // See [Note at-str] - return fmt!("%s*%s", addrstr, type_to_str_inner(names, - outer, - llvm::LLVMGetElementType(ty))).to_managed(); - } - Vector => return @"Vector", - Metadata => return @"Metadata", - X86_MMX => return @"X86_MMAX", - _ => fail!() + Struct => { + let tys = ty.field_types(); + let tys = tys.map(|&ty| self.type_to_str(ty)).connect(", "); + fmt!("{%s}", tys) + } + Array => { + let el_ty = ty.element_type(); + let el_ty = self.type_to_str(el_ty); + let len = ty.array_length(); + fmt!("[%s x %u]", el_ty, len) + } + Pointer => { + let el_ty = ty.element_type(); + let el_ty = self.type_to_str(el_ty); + fmt!("*%s", el_ty) + } + _ => fail!("Unknown Type Kind (%u)", kind as uint) + } } } -} -pub fn float_width(llt: TypeRef) -> uint { - unsafe { - return match llvm::LLVMGetTypeKind(llt) as int { - 1 => 32u, - 2 => 64u, - 3 => 80u, - 4 | 5 => 128u, - _ => fail!("llvm_float_width called on a non-float type") - }; - } -} - -pub fn fn_ty_param_tys(fn_ty: TypeRef) -> ~[TypeRef] { - unsafe { - let args = vec::from_elem(llvm::LLVMCountParamTypes(fn_ty) as uint, - 0 as TypeRef); - llvm::LLVMGetParamTypes(fn_ty, vec::raw::to_ptr(args)); - return args; - } -} - -pub fn struct_tys(struct_ty: TypeRef) -> ~[TypeRef] { - unsafe { - let n_elts = llvm::LLVMCountStructElementTypes(struct_ty) as uint; - if n_elts == 0 { - return ~[]; + pub fn val_to_str(&self, val: ValueRef) -> ~str { + unsafe { + let ty = Type::from_ref(llvm::LLVMTypeOf(val)); + self.type_to_str(ty) } - let mut elts = vec::from_elem(n_elts, ptr::null()); - llvm::LLVMGetStructElementTypes(struct_ty, &mut elts[0]); - return elts; } } diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 297b454bd83..ffb7a1daf35 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -50,7 +50,7 @@ use core::prelude::*; use middle::ty; use middle::typeck; -use util::ppaux::{ty_to_str, region_to_str, Repr}; +use util::ppaux::{ty_to_str, region_ptr_to_str, Repr}; use util::common::indenter; use core::uint; @@ -1026,7 +1026,7 @@ impl mem_categorization_ctxt { } pub fn region_to_str(&self, r: ty::Region) -> ~str { - region_to_str(self.tcx, r) + region_ptr_to_str(self.tcx, r) } } diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index 945f94a0877..a6e8cf666da 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -259,7 +259,7 @@ pub enum opt_result { range_result(Result, Result), } pub fn trans_opt(bcx: block, o: &Opt) -> opt_result { - let _icx = bcx.insn_ctxt("match::trans_opt"); + let _icx = push_ctxt("match::trans_opt"); let ccx = bcx.ccx(); let bcx = bcx; match *o { @@ -381,7 +381,7 @@ pub fn expand_nested_bindings<'r>(bcx: block, bcx.to_str(), matches_to_str(bcx, m), col, - bcx.val_str(val)); + bcx.val_to_str(val)); let _indenter = indenter(); do m.map |br| { @@ -428,7 +428,7 @@ pub fn enter_match<'r>(bcx: block, bcx.to_str(), matches_to_str(bcx, m), col, - bcx.val_str(val)); + bcx.val_to_str(val)); let _indenter = indenter(); let mut result = ~[]; @@ -474,7 +474,7 @@ pub fn enter_default<'r>(bcx: block, bcx.to_str(), matches_to_str(bcx, m), col, - bcx.val_str(val)); + bcx.val_to_str(val)); let _indenter = indenter(); do enter_match(bcx, dm, m, col, val) |p| { @@ -521,7 +521,7 @@ pub fn enter_opt<'r>(bcx: block, bcx.to_str(), matches_to_str(bcx, m), col, - bcx.val_str(val)); + bcx.val_to_str(val)); let _indenter = indenter(); let tcx = bcx.tcx(); @@ -632,7 +632,7 @@ pub fn enter_rec_or_struct<'r>(bcx: block, bcx.to_str(), matches_to_str(bcx, m), col, - bcx.val_str(val)); + bcx.val_to_str(val)); let _indenter = indenter(); let dummy = @ast::pat {id: 0, node: ast::pat_wild, span: dummy_sp()}; @@ -667,7 +667,7 @@ pub fn enter_tup<'r>(bcx: block, bcx.to_str(), matches_to_str(bcx, m), col, - bcx.val_str(val)); + bcx.val_to_str(val)); let _indenter = indenter(); let dummy = @ast::pat {id: 0, node: ast::pat_wild, span: dummy_sp()}; @@ -695,7 +695,7 @@ pub fn enter_tuple_struct<'r>(bcx: block, bcx.to_str(), matches_to_str(bcx, m), col, - bcx.val_str(val)); + bcx.val_to_str(val)); let _indenter = indenter(); let dummy = @ast::pat {id: 0, node: ast::pat_wild, span: dummy_sp()}; @@ -720,7 +720,7 @@ pub fn enter_box<'r>(bcx: block, bcx.to_str(), matches_to_str(bcx, m), col, - bcx.val_str(val)); + bcx.val_to_str(val)); let _indenter = indenter(); let dummy = @ast::pat {id: 0, node: ast::pat_wild, span: dummy_sp()}; @@ -747,7 +747,7 @@ pub fn enter_uniq<'r>(bcx: block, bcx.to_str(), matches_to_str(bcx, m), col, - bcx.val_str(val)); + bcx.val_to_str(val)); let _indenter = indenter(); let dummy = @ast::pat {id: 0, node: ast::pat_wild, span: dummy_sp()}; @@ -774,7 +774,7 @@ pub fn enter_region<'r>(bcx: block, bcx.to_str(), matches_to_str(bcx, m), col, - bcx.val_str(val)); + bcx.val_to_str(val)); let _indenter = indenter(); let dummy = @ast::pat { id: 0, node: ast::pat_wild, span: dummy_sp() }; @@ -870,7 +870,7 @@ pub fn extract_variant_args(bcx: block, disr_val: int, val: ValueRef) -> ExtractedBlock { - let _icx = bcx.insn_ctxt("match::extract_variant_args"); + let _icx = push_ctxt("match::extract_variant_args"); let args = do vec::from_fn(adt::num_args(repr, disr_val)) |i| { adt::trans_field_ptr(bcx, repr, val, disr_val, i) }; @@ -896,7 +896,7 @@ pub fn extract_vec_elems(bcx: block, val: ValueRef, count: ValueRef) -> ExtractedBlock { - let _icx = bcx.insn_ctxt("match::extract_vec_elems"); + let _icx = push_ctxt("match::extract_vec_elems"); let vec_datum = match_datum(bcx, val, pat_id); let (bcx, base, len) = vec_datum.get_vec_base_and_len(bcx, pat_span, pat_id, 0); @@ -911,7 +911,7 @@ pub fn extract_vec_elems(bcx: block, Sub(bcx, count, C_int(bcx.ccx(), (elem_count - i) as int))]) } - _ => unsafe { llvm::LLVMGetUndef(vt.llunit_ty) } + _ => unsafe { llvm::LLVMGetUndef(vt.llunit_ty.to_ref()) } } }; if slice.is_some() { @@ -1088,7 +1088,7 @@ pub fn compare_values(cx: block, rhs: ValueRef, rhs_t: ty::t) -> Result { - let _icx = cx.insn_ctxt("compare_values"); + let _icx = push_ctxt("compare_values"); if ty::type_is_scalar(rhs_t) { let rs = compare_scalar_types(cx, lhs, rhs, rhs_t, ast::eq); return rslt(rs.bcx, rs.val); @@ -1202,9 +1202,7 @@ fn insert_lllocals(bcx: block, } }; - debug!("binding %? to %s", - binding_info.id, - val_str(bcx.ccx().tn, llval)); + debug!("binding %? to %s", binding_info.id, bcx.val_to_str(llval)); llmap.insert(binding_info.id, llval); } return bcx; @@ -1221,7 +1219,7 @@ pub fn compile_guard(bcx: block, bcx.to_str(), bcx.expr_to_str(guard_expr), matches_to_str(bcx, m), - vals.map(|v| bcx.val_str(*v))); + vals.map(|v| bcx.val_to_str(*v))); let _indenter = indenter(); let mut bcx = bcx; @@ -1272,14 +1270,14 @@ pub fn compile_submatch(bcx: block, debug!("compile_submatch(bcx=%s, m=%s, vals=%?)", bcx.to_str(), matches_to_str(bcx, m), - vals.map(|v| bcx.val_str(*v))); + vals.map(|v| bcx.val_to_str(*v))); let _indenter = indenter(); /* For an empty match, a fall-through case must exist */ assert!((m.len() > 0u || chk.is_some())); - let _icx = bcx.insn_ctxt("match::compile_submatch"); + let _icx = push_ctxt("match::compile_submatch"); let mut bcx = bcx; let tcx = bcx.tcx(); let dm = tcx.def_map; @@ -1391,9 +1389,7 @@ pub fn compile_submatch(bcx: block, if any_box_pat(m, col) { bcx = root_pats_as_necessary(bcx, m, col, val); let llbox = Load(bcx, val); - let box_no_addrspace = non_gc_box_cast(bcx, llbox); - let unboxed = - GEPi(bcx, box_no_addrspace, [0u, abi::box_field_body]); + let unboxed = GEPi(bcx, llbox, [0u, abi::box_field_body]); compile_submatch(bcx, enter_box(bcx, dm, m, col, val), vec::append(~[unboxed], vals_left), chk); return; @@ -1401,9 +1397,7 @@ pub fn compile_submatch(bcx: block, if any_uniq_pat(m, col) { let llbox = Load(bcx, val); - let box_no_addrspace = non_gc_box_cast(bcx, llbox); - let unboxed = - GEPi(bcx, box_no_addrspace, [0u, abi::box_field_body]); + let unboxed = GEPi(bcx, llbox, [0u, abi::box_field_body]); compile_submatch(bcx, enter_uniq(bcx, dm, m, col, val), vec::append(~[unboxed], vals_left), chk); return; @@ -1619,7 +1613,7 @@ pub fn trans_match(bcx: block, discr_expr: @ast::expr, arms: ~[ast::arm], dest: Dest) -> block { - let _icx = bcx.insn_ctxt("match::trans_match"); + let _icx = push_ctxt("match::trans_match"); do with_scope(bcx, match_expr.info(), "match") |bcx| { trans_match_inner(bcx, discr_expr, arms, dest) } @@ -1646,7 +1640,7 @@ fn create_bindings_map(bcx: block, pat: @ast::pat) -> BindingsMap { // but during matching we need to store a *T as explained // above let is_move = ccx.maps.moves_map.contains(&p_id); - llmatch = alloca(bcx, T_ptr(llvariable_ty)); + llmatch = alloca(bcx, llvariable_ty.ptr_to()); trmode = TrByValue(is_move, alloca(bcx, llvariable_ty)); } ast::bind_by_ref(_) => { @@ -1666,7 +1660,7 @@ pub fn trans_match_inner(scope_cx: block, discr_expr: @ast::expr, arms: &[ast::arm], dest: Dest) -> block { - let _icx = scope_cx.insn_ctxt("match::trans_match_inner"); + let _icx = push_ctxt("match::trans_match_inner"); let mut bcx = scope_cx; let tcx = bcx.tcx(); @@ -1753,7 +1747,7 @@ pub fn bind_irrefutable_pat(bcx: block, make_copy: bool, binding_mode: IrrefutablePatternBindingMode) -> block { - let _icx = bcx.insn_ctxt("match::bind_irrefutable_pat"); + let _icx = push_ctxt("match::bind_irrefutable_pat"); let ccx = bcx.fcx.ccx; let mut bcx = bcx; diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs index 79b5aba227c..906c9d028eb 100644 --- a/src/librustc/middle/trans/adt.rs +++ b/src/librustc/middle/trans/adt.rs @@ -49,7 +49,7 @@ use core::libc::c_ulonglong; use core::option::{Option, Some, None}; use core::vec; -use lib::llvm::{ValueRef, TypeRef, True, IntEQ, IntNE}; +use lib::llvm::{ValueRef, True, IntEQ, IntNE}; use middle::trans::_match; use middle::trans::build::*; use middle::trans::common::*; @@ -59,6 +59,8 @@ use middle::ty; use syntax::ast; use util::ppaux::ty_to_str; +use middle::trans::type_::Type; + /// Representations. pub enum Repr { @@ -212,7 +214,7 @@ fn represent_type_uncached(cx: &mut CrateContext, t: ty::t) -> Repr { fn mk_struct(cx: &mut CrateContext, tys: &[ty::t], packed: bool) -> Struct { let lltys = tys.map(|&ty| type_of::sizing_type_of(cx, ty)); - let llty_rec = T_struct(lltys, packed); + let llty_rec = Type::struct_(lltys, packed); Struct { size: machine::llsize_of_alloc(cx, llty_rec) /*bad*/as u64, align: machine::llalign_of_min(cx, llty_rec) /*bad*/as u64, @@ -226,17 +228,16 @@ fn mk_struct(cx: &mut CrateContext, tys: &[ty::t], packed: bool) -> Struct { * All nominal types are LLVM structs, in order to be able to use * forward-declared opaque types to prevent circularity in `type_of`. */ -pub fn fields_of(cx: &mut CrateContext, r: &Repr) -> ~[TypeRef] { +pub fn fields_of(cx: &mut CrateContext, r: &Repr) -> ~[Type] { generic_fields_of(cx, r, false) } /// Like `fields_of`, but for `type_of::sizing_type_of` (q.v.). -pub fn sizing_fields_of(cx: &mut CrateContext, r: &Repr) -> ~[TypeRef] { +pub fn sizing_fields_of(cx: &mut CrateContext, r: &Repr) -> ~[Type] { generic_fields_of(cx, r, true) } -fn generic_fields_of(cx: &mut CrateContext, r: &Repr, sizing: bool) - -> ~[TypeRef] { +fn generic_fields_of(cx: &mut CrateContext, r: &Repr, sizing: bool) -> ~[Type] { match *r { - CEnum(*) => ~[T_enum_discrim(cx)], + CEnum(*) => ~[Type::enum_discrim(cx)], Univariant(ref st, _dtor) => struct_llfields(cx, st, sizing), NullablePointer{ nonnull: ref st, _ } => struct_llfields(cx, st, sizing), General(ref sts) => { @@ -262,13 +263,12 @@ fn generic_fields_of(cx: &mut CrateContext, r: &Repr, sizing: bool) let padding = largest_size - most_aligned.size; struct_llfields(cx, most_aligned, sizing) - + [T_array(T_i8(), padding /*bad*/as uint)] + + [Type::array(&Type::i8(), padding)] } } } -fn struct_llfields(cx: &mut CrateContext, st: &Struct, sizing: bool) - -> ~[TypeRef] { +fn struct_llfields(cx: &mut CrateContext, st: &Struct, sizing: bool) -> ~[Type] { if sizing { st.fields.map(|&ty| type_of::sizing_type_of(cx, ty)) } else { @@ -309,7 +309,7 @@ pub fn trans_get_discr(bcx: block, r: &Repr, scrutinee: ValueRef) (cases.len() - 1) as int), NullablePointer{ nonnull: ref nonnull, nndiscr, ptrfield, _ } => { ZExt(bcx, nullable_bitdiscr(bcx, nonnull, nndiscr, ptrfield, scrutinee), - T_enum_discrim(bcx.ccx())) + Type::enum_discrim(bcx.ccx())) } } } @@ -438,11 +438,11 @@ pub fn trans_field_ptr(bcx: block, r: &Repr, val: ValueRef, discr: int, } else { // The unit-like case might have a nonzero number of unit-like fields. // (e.g., Result or Either with () as one side.) - let llty = type_of::type_of(bcx.ccx(), nullfields[ix]); - assert_eq!(machine::llsize_of_alloc(bcx.ccx(), llty), 0); + let ty = type_of::type_of(bcx.ccx(), nullfields[ix]); + assert_eq!(machine::llsize_of_alloc(bcx.ccx(), ty), 0); // The contents of memory at this pointer can't matter, but use // the value that's "reasonable" in case of pointer comparison. - PointerCast(bcx, val, T_ptr(llty)) + PointerCast(bcx, val, ty.ptr_to()) } } } @@ -456,8 +456,8 @@ fn struct_field_ptr(bcx: block, st: &Struct, val: ValueRef, ix: uint, let fields = do st.fields.map |&ty| { type_of::type_of(ccx, ty) }; - let real_llty = T_struct(fields, st.packed); - PointerCast(bcx, val, T_ptr(real_llty)) + let real_ty = Type::struct_(fields, st.packed); + PointerCast(bcx, val, real_ty.ptr_to()) } else { val }; @@ -572,7 +572,7 @@ fn build_const_struct(ccx: &mut CrateContext, st: &Struct, vals: &[ValueRef]) } fn padding(size: u64) -> ValueRef { - C_undef(T_array(T_i8(), size /*bad*/as uint)) + C_undef(Type::array(&Type::i8(), size)) } // XXX this utility routine should be somewhere more general diff --git a/src/librustc/middle/trans/asm.rs b/src/librustc/middle/trans/asm.rs index 3814ff319f2..dd8b7ebc00b 100644 --- a/src/librustc/middle/trans/asm.rs +++ b/src/librustc/middle/trans/asm.rs @@ -20,6 +20,8 @@ use middle::trans::callee; use middle::trans::common::*; use middle::ty; +use middle::trans::type_::Type; + use core::str; use syntax::ast; @@ -110,11 +112,11 @@ pub fn trans_inline_asm(bcx: block, ia: &ast::inline_asm) -> block { // Depending on how many outputs we have, the return type is different let output = if numOutputs == 0 { - T_void() + Type::void() } else if numOutputs == 1 { val_ty(outputs[0]) } else { - T_struct(outputs.map(|o| val_ty(*o)), false) + Type::struct_(outputs.map(|o| val_ty(*o)), false) }; let dialect = match ia.dialect { @@ -130,12 +132,12 @@ pub fn trans_inline_asm(bcx: block, ia: &ast::inline_asm) -> block { // Again, based on how many outputs we have if numOutputs == 1 { - let op = PointerCast(bcx, aoutputs[0], T_ptr(val_ty(outputs[0]))); + let op = PointerCast(bcx, aoutputs[0], val_ty(outputs[0]).ptr_to()); Store(bcx, r, op); } else { for aoutputs.iter().enumerate().advance |(i, o)| { let v = ExtractValue(bcx, r, i); - let op = PointerCast(bcx, *o, T_ptr(val_ty(outputs[i]))); + let op = PointerCast(bcx, *o, val_ty(outputs[i]).ptr_to()); Store(bcx, v, op); } } diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index 1ba2f15ebda..7132af24d45 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -29,8 +29,8 @@ use back::link::{mangle_exported_name}; use back::{link, abi}; use driver::session; use driver::session::Session; -use lib::llvm::{ContextRef, ModuleRef, ValueRef, TypeRef, BasicBlockRef}; -use lib::llvm::{llvm, True, False}; +use lib::llvm::{ContextRef, ModuleRef, ValueRef, BasicBlockRef}; +use lib::llvm::{llvm, True}; use lib; use metadata::common::LinkMeta; use metadata::{csearch, cstore, encoder}; @@ -63,6 +63,8 @@ use middle::ty; use util::common::indenter; use util::ppaux::{Repr, ty_to_str}; +use middle::trans::type_::Type; + use core::hash; use core::hashmap::{HashMap}; use core::int; @@ -71,6 +73,7 @@ use core::libc::c_uint; 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}; @@ -86,49 +89,52 @@ use syntax::abi::{X86, X86_64, Arm, Mips}; pub use middle::trans::context::task_llcx; -pub struct icx_popper { - ccx: @mut CrateContext, +fn task_local_insn_key(_v: @~[&'static str]) {} + +pub fn with_insn_ctxt(blk: &fn(&[&'static str])) { + unsafe { + let opt = local_data::local_data_get(task_local_insn_key); + if opt.is_some() { + blk(*opt.unwrap()); + } + } } +pub fn init_insn_ctxt() { + unsafe { + local_data::local_data_set(task_local_insn_key, @~[]); + } +} + +pub struct _InsnCtxt { _x: () } + #[unsafe_destructor] -impl Drop for icx_popper { +impl Drop for _InsnCtxt { fn finalize(&self) { - if self.ccx.sess.count_llvm_insns() { - self.ccx.stats.llvm_insn_ctxt.pop(); + unsafe { + do local_data::local_data_modify(task_local_insn_key) |c| { + do c.map_consume |@ctx| { + let mut ctx = ctx; + ctx.pop(); + @ctx + } + } } } } -pub fn icx_popper(ccx: @mut CrateContext) -> icx_popper { - icx_popper { - ccx: ccx - } -} - -pub trait get_insn_ctxt { - fn insn_ctxt(&self, s: &str) -> icx_popper; -} - -impl get_insn_ctxt for @mut CrateContext { - fn insn_ctxt(&self, s: &str) -> icx_popper { - debug!("new insn_ctxt: %s", s); - if self.sess.count_llvm_insns() { - self.stats.llvm_insn_ctxt.push(str::to_owned(s)); +pub fn push_ctxt(s: &'static str) -> _InsnCtxt { + debug!("new InsnCtxt: %s", s); + unsafe { + do local_data::local_data_modify(task_local_insn_key) |c| { + do c.map_consume |@ctx| { + let mut ctx = ctx; + ctx.push(s); + @ctx + } } - icx_popper(*self) - } -} - -impl get_insn_ctxt for block { - fn insn_ctxt(&self, s: &str) -> icx_popper { - self.ccx().insn_ctxt(s) - } -} - -impl get_insn_ctxt for fn_ctxt { - fn insn_ctxt(&self, s: &str) -> icx_popper { - self.ccx.insn_ctxt(s) } + _InsnCtxt { _x: () } } fn fcx_has_nonzero_span(fcx: fn_ctxt) -> bool { @@ -138,49 +144,33 @@ fn fcx_has_nonzero_span(fcx: fn_ctxt) -> bool { } } -pub fn log_fn_time(ccx: @mut CrateContext, name: ~str, start: time::Timespec, - end: time::Timespec) { - let elapsed = 1000 * ((end.sec - start.sec) as int) + - ((end.nsec as int) - (start.nsec as int)) / 1000000; - ccx.stats.fn_times.push((name, elapsed)); -} - -pub fn decl_fn(llmod: ModuleRef, - name: &str, - cc: lib::llvm::CallConv, - llty: TypeRef) - -> ValueRef { - let llfn: ValueRef = str::as_c_str(name, |buf| { +pub fn decl_fn(llmod: ModuleRef, name: &str, cc: lib::llvm::CallConv, ty: Type) -> ValueRef { + let llfn: ValueRef = do name.as_c_str |buf| { unsafe { - llvm::LLVMGetOrInsertFunction(llmod, buf, llty) + llvm::LLVMGetOrInsertFunction(llmod, buf, ty.to_ref()) } - }); + }; lib::llvm::SetFunctionCallConv(llfn, cc); return llfn; } -pub fn decl_cdecl_fn(llmod: ModuleRef, name: &str, llty: TypeRef) - -> ValueRef { - return decl_fn(llmod, name, lib::llvm::CCallConv, llty); +pub fn decl_cdecl_fn(llmod: ModuleRef, name: &str, ty: Type) -> ValueRef { + return decl_fn(llmod, name, lib::llvm::CCallConv, ty); } // Only use this if you are going to actually define the function. It's // not valid to simply declare a function as internal. -pub fn decl_internal_cdecl_fn(llmod: ModuleRef, name: ~str, llty: TypeRef) -> - ValueRef { - let llfn = decl_cdecl_fn(llmod, name, llty); +pub fn decl_internal_cdecl_fn(llmod: ModuleRef, name: ~str, ty: Type) -> ValueRef { + let llfn = decl_cdecl_fn(llmod, name, ty); lib::llvm::SetLinkage(llfn, lib::llvm::InternalLinkage); return llfn; } -pub fn get_extern_fn(externs: &mut ExternMap, - llmod: ModuleRef, - name: @str, - cc: lib::llvm::CallConv, - ty: TypeRef) -> ValueRef { - match externs.find(&name) { - Some(n) => return copy *n, +pub fn get_extern_fn(externs: &mut ExternMap, llmod: ModuleRef, name: @str, + cc: lib::llvm::CallConv, ty: Type) -> ValueRef { + match externs.find_copy(&name) { + Some(n) => return n, None => () } let f = decl_fn(llmod, name, cc, ty); @@ -189,51 +179,27 @@ pub fn get_extern_fn(externs: &mut ExternMap, } pub fn get_extern_const(externs: &mut ExternMap, llmod: ModuleRef, - name: @str, ty: TypeRef) -> ValueRef { - match externs.find(&name) { - Some(n) => return copy *n, + name: @str, ty: Type) -> ValueRef { + match externs.find_copy(&name) { + Some(n) => return n, None => () } unsafe { - let c = str::as_c_str(name, |buf| { - llvm::LLVMAddGlobal(llmod, ty, buf) - }); + let c = do name.as_c_str |buf| { + llvm::LLVMAddGlobal(llmod, ty.to_ref(), buf) + }; externs.insert(name, c); return c; } } - -fn get_simple_extern_fn(cx: block, - externs: &mut ExternMap, - llmod: ModuleRef, - name: @str, - n_args: int) -> ValueRef { - let _icx = cx.insn_ctxt("get_simple_extern_fn"); - let ccx = cx.fcx.ccx; - let inputs = vec::from_elem(n_args as uint, ccx.int_type); - let output = ccx.int_type; - let t = T_fn(inputs, output); - return get_extern_fn(externs, llmod, name, lib::llvm::CCallConv, t); -} - -pub fn trans_foreign_call(cx: block, externs: &mut ExternMap, - llmod: ModuleRef, name: @str, args: &[ValueRef]) -> - ValueRef { - let _icx = cx.insn_ctxt("trans_foreign_call"); - let n = args.len() as int; - let llforeign: ValueRef = - get_simple_extern_fn(cx, externs, llmod, name, n); - return Call(cx, llforeign, args); -} - pub fn umax(cx: block, a: ValueRef, b: ValueRef) -> ValueRef { - let _icx = cx.insn_ctxt("umax"); + let _icx = push_ctxt("umax"); let cond = ICmp(cx, lib::llvm::IntULT, a, b); return Select(cx, cond, b, a); } pub fn umin(cx: block, a: ValueRef, b: ValueRef) -> ValueRef { - let _icx = cx.insn_ctxt("umin"); + let _icx = push_ctxt("umin"); let cond = ICmp(cx, lib::llvm::IntULT, a, b); return Select(cx, cond, a, b); } @@ -242,8 +208,8 @@ pub fn umin(cx: block, a: ValueRef, b: ValueRef) -> ValueRef { // The type of the returned pointer is always i8*. If you care about the // return type, use bump_ptr(). pub fn ptr_offs(bcx: block, base: ValueRef, sz: ValueRef) -> ValueRef { - let _icx = bcx.insn_ctxt("ptr_offs"); - let raw = PointerCast(bcx, base, T_ptr(T_i8())); + let _icx = push_ctxt("ptr_offs"); + let raw = PointerCast(bcx, base, Type::i8p()); InBoundsGEP(bcx, raw, [sz]) } @@ -251,10 +217,10 @@ pub fn ptr_offs(bcx: block, base: ValueRef, sz: ValueRef) -> ValueRef { // to a given type. pub fn bump_ptr(bcx: block, t: ty::t, base: ValueRef, sz: ValueRef) -> ValueRef { - let _icx = bcx.insn_ctxt("bump_ptr"); + let _icx = push_ctxt("bump_ptr"); let ccx = bcx.ccx(); let bumped = ptr_offs(bcx, base, sz); - let typ = T_ptr(type_of(ccx, t)); + let typ = type_of(ccx, t).ptr_to(); PointerCast(bcx, bumped, typ) } @@ -266,11 +232,11 @@ pub fn bump_ptr(bcx: block, t: ty::t, base: ValueRef, sz: ValueRef) -> pub fn opaque_box_body(bcx: block, body_t: ty::t, boxptr: ValueRef) -> ValueRef { - let _icx = bcx.insn_ctxt("opaque_box_body"); + let _icx = push_ctxt("opaque_box_body"); let ccx = bcx.ccx(); let ty = type_of(ccx, body_t); - let ty = T_box(ccx, ty); - let boxptr = PointerCast(bcx, boxptr, T_ptr(ty)); + let ty = Type::box(ccx, &ty); + let boxptr = PointerCast(bcx, boxptr, ty.ptr_to()); GEPi(bcx, boxptr, [0u, abi::box_field_body]) } @@ -280,7 +246,7 @@ pub fn malloc_raw_dyn(bcx: block, t: ty::t, heap: heap, size: ValueRef) -> Result { - let _icx = bcx.insn_ctxt("malloc_raw"); + let _icx = push_ctxt("malloc_raw"); let ccx = bcx.ccx(); let (mk_fn, langcall) = match heap { @@ -301,8 +267,8 @@ pub fn malloc_raw_dyn(bcx: block, glue::lazily_emit_all_tydesc_glue(ccx, static_ti); // Allocate space: - let tydesc = PointerCast(bcx, static_ti.tydesc, T_ptr(T_i8())); - let rval = alloca(bcx, T_ptr(T_i8())); + let tydesc = PointerCast(bcx, static_ti.tydesc, Type::i8p()); + let rval = alloca(bcx, Type::i8p()); let bcx = callee::trans_lang_call( bcx, langcall, @@ -313,25 +279,6 @@ pub fn malloc_raw_dyn(bcx: block, r } -/** -* Get the type of a box in the default address space. -* -* Shared box pointers live in address space 1 so the GC strategy can find -* them. Before taking a pointer to the inside of a box it should be cast into -* address space 0. Otherwise the resulting (non-box) pointer will be in the -* wrong address space and thus be the wrong type. -*/ -pub fn non_gc_box_cast(bcx: block, val: ValueRef) -> ValueRef { - unsafe { - debug!("non_gc_box_cast"); - add_comment(bcx, "non_gc_box_cast"); - assert!(llvm::LLVMGetPointerAddressSpace(val_ty(val)) == - gc_box_addrspace || bcx.unreachable); - let non_gc_t = T_ptr(llvm::LLVMGetElementType(val_ty(val))); - PointerCast(bcx, val, non_gc_t) - } -} - // malloc_raw: expects an unboxed type and returns a pointer to // enough space for a box of that type. This includes a rust_opaque_box // header. @@ -351,10 +298,9 @@ pub struct MallocResult { // and pulls out the body pub fn malloc_general_dyn(bcx: block, t: ty::t, heap: heap, size: ValueRef) -> MallocResult { - let _icx = bcx.insn_ctxt("malloc_general"); + let _icx = push_ctxt("malloc_general"); let Result {bcx: bcx, val: llbox} = malloc_raw_dyn(bcx, t, heap, size); - let non_gc_box = non_gc_box_cast(bcx, llbox); - let body = GEPi(bcx, non_gc_box, [0u, abi::box_field_body]); + let body = GEPi(bcx, llbox, [0u, abi::box_field_body]); MallocResult { bcx: bcx, box: llbox, body: body } } @@ -502,7 +448,7 @@ pub fn get_res_dtor(ccx: @mut CrateContext, parent_id: ast::def_id, substs: &[ty::t]) -> ValueRef { - let _icx = ccx.insn_ctxt("trans_res_dtor"); + let _icx = push_ctxt("trans_res_dtor"); if !substs.is_empty() { let did = if did.crate != ast::local_crate { inline::maybe_instantiate_inline(ccx, did, true) @@ -592,7 +538,7 @@ pub fn compare_scalar_values(cx: block, nt: scalar_type, op: ast::binop) -> ValueRef { - let _icx = cx.insn_ctxt("compare_scalar_values"); + let _icx = push_ctxt("compare_scalar_values"); fn die(cx: block) -> ! { cx.tcx().sess.bug("compare_scalar_values: must be a\ comparison operator"); @@ -661,12 +607,12 @@ pub fn store_inbounds(cx: block, v: ValueRef, p: ValueRef, idxs: &[uint]) { // Iterates through the elements of a structural type. pub fn iter_structural_ty(cx: block, av: ValueRef, t: ty::t, f: val_and_ty_fn) -> block { - let _icx = cx.insn_ctxt("iter_structural_ty"); + let _icx = push_ctxt("iter_structural_ty"); fn iter_variant(cx: block, repr: &adt::Repr, av: ValueRef, variant: ty::VariantInfo, tps: &[ty::t], f: val_and_ty_fn) -> block { - let _icx = cx.insn_ctxt("iter_variant"); + let _icx = push_ctxt("iter_variant"); let tcx = cx.tcx(); let mut cx = cx; @@ -761,22 +707,22 @@ pub fn cast_shift_expr_rhs(cx: block, op: ast::binop, pub fn cast_shift_const_rhs(op: ast::binop, lhs: ValueRef, rhs: ValueRef) -> ValueRef { cast_shift_rhs(op, lhs, rhs, - |a, b| unsafe { llvm::LLVMConstTrunc(a, b) }, - |a, b| unsafe { llvm::LLVMConstZExt(a, b) }) + |a, b| unsafe { llvm::LLVMConstTrunc(a, b.to_ref()) }, + |a, b| unsafe { llvm::LLVMConstZExt(a, b.to_ref()) }) } pub fn cast_shift_rhs(op: ast::binop, lhs: ValueRef, rhs: ValueRef, - trunc: &fn(ValueRef, TypeRef) -> ValueRef, - zext: &fn(ValueRef, TypeRef) -> ValueRef) + trunc: &fn(ValueRef, Type) -> ValueRef, + zext: &fn(ValueRef, Type) -> ValueRef) -> ValueRef { // Shifts may have any size int on the rhs unsafe { if ast_util::is_shift_binop(op) { let rhs_llty = val_ty(rhs); let lhs_llty = val_ty(lhs); - let rhs_sz = llvm::LLVMGetIntTypeWidth(rhs_llty); - let lhs_sz = llvm::LLVMGetIntTypeWidth(lhs_llty); + let rhs_sz = llvm::LLVMGetIntTypeWidth(rhs_llty.to_ref()); + let lhs_sz = llvm::LLVMGetIntTypeWidth(lhs_llty.to_ref()); if lhs_sz < rhs_sz { trunc(rhs, lhs_llty) } else if lhs_sz > rhs_sz { @@ -801,11 +747,11 @@ pub fn fail_if_zero(cx: block, span: span, divrem: ast::binop, }; let is_zero = match ty::get(rhs_t).sty { ty::ty_int(t) => { - let zero = C_integral(T_int_ty(cx.ccx(), t), 0u64, False); + let zero = C_integral(Type::int_from_ty(cx.ccx(), t), 0u64, false); ICmp(cx, lib::llvm::IntEQ, rhs, zero) } ty::ty_uint(t) => { - let zero = C_integral(T_uint_ty(cx.ccx(), t), 0u64, False); + let zero = C_integral(Type::uint_from_ty(cx.ccx(), t), 0u64, false); ICmp(cx, lib::llvm::IntEQ, rhs, zero) } _ => { @@ -819,7 +765,7 @@ pub fn fail_if_zero(cx: block, span: span, divrem: ast::binop, } pub fn null_env_ptr(bcx: block) -> ValueRef { - C_null(T_opaque_box_ptr(bcx.ccx())) + C_null(Type::opaque_box(bcx.ccx()).ptr_to()) } pub fn trans_external_path(ccx: &mut CrateContext, did: ast::def_id, t: ty::t) @@ -840,9 +786,9 @@ pub fn trans_external_path(ccx: &mut CrateContext, did: ast::def_id, t: ty::t) pub fn invoke(bcx: block, llfn: ValueRef, llargs: ~[ValueRef]) -> (ValueRef, block) { - let _icx = bcx.insn_ctxt("invoke_"); + let _icx = push_ctxt("invoke_"); if bcx.unreachable { - return (C_null(T_i8()), bcx); + return (C_null(Type::i8()), bcx); } match bcx.node_info { @@ -956,7 +902,7 @@ pub fn in_lpad_scope_cx(bcx: block, f: &fn(si: &mut scope_info)) { } pub fn get_landing_pad(bcx: block) -> BasicBlockRef { - let _icx = bcx.insn_ctxt("get_landing_pad"); + let _icx = push_ctxt("get_landing_pad"); let mut cached = None; let mut pad_bcx = bcx; // Guaranteed to be set below @@ -975,7 +921,7 @@ pub fn get_landing_pad(bcx: block) -> BasicBlockRef { // The landing pad return type (the type being propagated). Not sure what // this represents but it's determined by the personality function and // this is what the EH proposal example uses. - let llretty = T_struct([T_ptr(T_i8()), T_i32()], false); + let llretty = Type::struct_([Type::i8p(), Type::i32()], false); // The exception handling personality function. This is the C++ // personality function __gxx_personality_v0, wrapped in our naming // convention. @@ -1033,7 +979,7 @@ pub fn find_bcx_for_scope(bcx: block, scope_id: ast::node_id) -> block { pub fn do_spill(bcx: block, v: ValueRef, t: ty::t) -> ValueRef { if ty::type_is_bot(t) { - return C_null(T_ptr(T_i8())); + return C_null(Type::i8p()); } let llptr = alloc_ty(bcx, t); Store(bcx, v, llptr); @@ -1049,20 +995,20 @@ pub fn do_spill_noroot(cx: block, v: ValueRef) -> ValueRef { } pub fn spill_if_immediate(cx: block, v: ValueRef, t: ty::t) -> ValueRef { - let _icx = cx.insn_ctxt("spill_if_immediate"); + let _icx = push_ctxt("spill_if_immediate"); if ty::type_is_immediate(t) { return do_spill(cx, v, t); } return v; } pub fn load_if_immediate(cx: block, v: ValueRef, t: ty::t) -> ValueRef { - let _icx = cx.insn_ctxt("load_if_immediate"); + let _icx = push_ctxt("load_if_immediate"); if ty::type_is_immediate(t) { return Load(cx, v); } return v; } pub fn trans_trace(bcx: block, sp_opt: Option, trace_str: @str) { if !bcx.sess().trace() { return; } - let _icx = bcx.insn_ctxt("trans_trace"); + let _icx = push_ctxt("trans_trace"); add_comment(bcx, trace_str); let V_trace_str = C_cstr(bcx.ccx(), trace_str); let (V_filename, V_line) = match sp_opt { @@ -1076,14 +1022,14 @@ pub fn trans_trace(bcx: block, sp_opt: Option, trace_str: @str) { } }; let ccx = bcx.ccx(); - let V_trace_str = PointerCast(bcx, V_trace_str, T_ptr(T_i8())); - let V_filename = PointerCast(bcx, V_filename, T_ptr(T_i8())); + let V_trace_str = PointerCast(bcx, V_trace_str, Type::i8p()); + let V_filename = PointerCast(bcx, V_filename, Type::i8p()); let args = ~[V_trace_str, V_filename, C_int(ccx, V_line)]; Call(bcx, ccx.upcalls.trace, args); } pub fn build_return(bcx: block) { - let _icx = bcx.insn_ctxt("build_return"); + let _icx = push_ctxt("build_return"); Br(bcx, bcx.fcx.llreturn); } @@ -1099,7 +1045,7 @@ pub fn init_local(bcx: block, local: @ast::local) -> block { bcx.to_str(), local.node.id); let _indenter = indenter(); - let _icx = bcx.insn_ctxt("init_local"); + let _icx = push_ctxt("init_local"); let ty = node_id_type(bcx, local.node.id); debug!("ty=%s", bcx.ty_to_str(ty)); @@ -1147,7 +1093,7 @@ pub fn init_local(bcx: block, local: @ast::local) -> block { } pub fn trans_stmt(cx: block, s: &ast::stmt) -> block { - let _icx = cx.insn_ctxt("trans_stmt"); + let _icx = push_ctxt("trans_stmt"); debug!("trans_stmt(%s)", stmt_to_str(s, cx.tcx().sess.intr())); if cx.sess().asm_comments() { @@ -1275,7 +1221,7 @@ pub fn trans_block_cleanups_(bcx: block, cleanups: &[cleanup], /* cleanup_cx: block, */ is_lpad: bool) -> block { - let _icx = bcx.insn_ctxt("trans_block_cleanups"); + let _icx = push_ctxt("trans_block_cleanups"); // NB: Don't short-circuit even if this block is unreachable because // GC-based cleanup needs to the see that the roots are live. let no_lpads = @@ -1302,7 +1248,7 @@ pub fn trans_block_cleanups_(bcx: block, pub fn cleanup_and_leave(bcx: block, upto: Option, leave: Option) { - let _icx = bcx.insn_ctxt("cleanup_and_leave"); + let _icx = push_ctxt("cleanup_and_leave"); let mut cur = bcx; let mut bcx = bcx; let is_lpad = leave == None; @@ -1369,12 +1315,12 @@ pub fn cleanup_and_leave(bcx: block, } pub fn cleanup_and_Br(bcx: block, upto: block, target: BasicBlockRef) { - let _icx = bcx.insn_ctxt("cleanup_and_Br"); + let _icx = push_ctxt("cleanup_and_Br"); cleanup_and_leave(bcx, Some(upto.llbb), Some(target)); } pub fn leave_block(bcx: block, out_of: block) -> block { - let _icx = bcx.insn_ctxt("leave_block"); + let _icx = push_ctxt("leave_block"); let next_cx = sub_block(block_parent(out_of), "next"); if bcx.unreachable { Unreachable(next_cx); } cleanup_and_Br(bcx, out_of, next_cx.llbb); @@ -1385,7 +1331,7 @@ pub fn with_scope(bcx: block, opt_node_info: Option, name: &str, f: &fn(block) -> block) -> block { - let _icx = bcx.insn_ctxt("with_scope"); + let _icx = push_ctxt("with_scope"); debug!("with_scope(bcx=%s, opt_node_info=%?, name=%s)", bcx.to_str(), opt_node_info, name); @@ -1400,7 +1346,7 @@ pub fn with_scope_result(bcx: block, opt_node_info: Option, name: &str, f: &fn(block) -> Result) -> Result { - let _icx = bcx.insn_ctxt("with_scope_result"); + let _icx = push_ctxt("with_scope_result"); let scope_cx = scope_block(bcx, opt_node_info, name); Br(bcx, scope_cx.llbb); let Result {bcx, val} = f(scope_cx); @@ -1412,7 +1358,7 @@ pub fn with_scope_datumblock(bcx: block, opt_node_info: Option, -> datum::DatumBlock { use middle::trans::datum::DatumBlock; - let _icx = bcx.insn_ctxt("with_scope_result"); + let _icx = push_ctxt("with_scope_result"); let scope_cx = scope_block(bcx, opt_node_info, name); Br(bcx, scope_cx.llbb); let DatumBlock {bcx, datum} = f(scope_cx); @@ -1434,7 +1380,7 @@ pub fn block_locals(b: &ast::blk, it: &fn(@ast::local)) { } pub fn alloc_local(cx: block, local: @ast::local) -> block { - let _icx = cx.insn_ctxt("alloc_local"); + let _icx = push_ctxt("alloc_local"); let t = node_id_type(cx, local.node.id); let simple_name = match local.node.pat.node { ast::pat_ident(_, pth, None) => Some(path_to_ident(pth)), @@ -1456,7 +1402,7 @@ pub fn alloc_local(cx: block, local: @ast::local) -> block { pub fn with_cond(bcx: block, val: ValueRef, f: &fn(block) -> block) -> block { - let _icx = bcx.insn_ctxt("with_cond"); + let _icx = push_ctxt("with_cond"); let next_cx = base::sub_block(bcx, "next"); let cond_cx = base::sub_block(bcx, "cond"); CondBr(bcx, val, cond_cx.llbb, next_cx.llbb); @@ -1466,15 +1412,15 @@ pub fn with_cond(bcx: block, val: ValueRef, f: &fn(block) -> block) -> block { } pub fn call_memcpy(cx: block, dst: ValueRef, src: ValueRef, n_bytes: ValueRef, align: u32) { - let _icx = cx.insn_ctxt("call_memcpy"); + let _icx = push_ctxt("call_memcpy"); let ccx = cx.ccx(); let key = match ccx.sess.targ_cfg.arch { X86 | Arm | Mips => "llvm.memcpy.p0i8.p0i8.i32", X86_64 => "llvm.memcpy.p0i8.p0i8.i64" }; let memcpy = ccx.intrinsics.get_copy(&key); - let src_ptr = PointerCast(cx, src, T_ptr(T_i8())); - let dst_ptr = PointerCast(cx, dst, T_ptr(T_i8())); + let src_ptr = PointerCast(cx, src, Type::i8p()); + let dst_ptr = PointerCast(cx, dst, Type::i8p()); let size = IntCast(cx, n_bytes, ccx.int_type); let align = C_i32(align as i32); let volatile = C_i1(false); @@ -1482,7 +1428,7 @@ pub fn call_memcpy(cx: block, dst: ValueRef, src: ValueRef, n_bytes: ValueRef, a } pub fn memcpy_ty(bcx: block, dst: ValueRef, src: ValueRef, t: ty::t) { - let _icx = bcx.insn_ctxt("memcpy_ty"); + let _icx = push_ctxt("memcpy_ty"); let ccx = bcx.ccx(); if ty::type_is_structural(t) { let llty = type_of::type_of(ccx, t); @@ -1495,7 +1441,7 @@ pub fn memcpy_ty(bcx: block, dst: ValueRef, src: ValueRef, t: ty::t) { } pub fn zero_mem(cx: block, llptr: ValueRef, t: ty::t) { - let _icx = cx.insn_ctxt("zero_mem"); + let _icx = push_ctxt("zero_mem"); let bcx = cx; let ccx = cx.ccx(); let llty = type_of::type_of(ccx, t); @@ -1507,8 +1453,8 @@ pub fn zero_mem(cx: block, llptr: ValueRef, t: ty::t) { // allocation for large data structures, and the generated code will be // awful. (A telltale sign of this is large quantities of // `mov [byte ptr foo],0` in the generated code.) -pub fn memzero(cx: block, llptr: ValueRef, llty: TypeRef) { - let _icx = cx.insn_ctxt("memzero"); +pub fn memzero(cx: block, llptr: ValueRef, ty: Type) { + let _icx = push_ctxt("memzero"); let ccx = cx.ccx(); let intrinsic_key = match ccx.sess.targ_cfg.arch { @@ -1517,50 +1463,48 @@ pub fn memzero(cx: block, llptr: ValueRef, llty: TypeRef) { }; let llintrinsicfn = ccx.intrinsics.get_copy(&intrinsic_key); - let llptr = PointerCast(cx, llptr, T_ptr(T_i8())); + let llptr = PointerCast(cx, llptr, Type::i8().ptr_to()); let llzeroval = C_u8(0); - let size = IntCast(cx, machine::llsize_of(ccx, llty), ccx.int_type); - let align = C_i32(llalign_of_min(ccx, llty) as i32); + let size = IntCast(cx, machine::llsize_of(ccx, ty), ccx.int_type); + let align = C_i32(llalign_of_min(ccx, ty) as i32); let volatile = C_i1(false); Call(cx, llintrinsicfn, [llptr, llzeroval, size, align, volatile]); } pub fn alloc_ty(bcx: block, t: ty::t) -> ValueRef { - let _icx = bcx.insn_ctxt("alloc_ty"); + let _icx = push_ctxt("alloc_ty"); let ccx = bcx.ccx(); - let llty = type_of::type_of(ccx, t); - if ty::type_has_params(t) { debug!("%s", ty_to_str(ccx.tcx, t)); } - assert!(!ty::type_has_params(t)); - let val = alloca(bcx, llty); + let ty = type_of::type_of(ccx, t); + assert!(!ty::type_has_params(t), "Type has params: %s", ty_to_str(ccx.tcx, t)); + let val = alloca(bcx, ty); return val; } -pub fn alloca(cx: block, t: TypeRef) -> ValueRef { - alloca_maybe_zeroed(cx, t, false) +pub fn alloca(cx: block, ty: Type) -> ValueRef { + alloca_maybe_zeroed(cx, ty, false) } -pub fn alloca_maybe_zeroed(cx: block, t: TypeRef, zero: bool) -> ValueRef { - let _icx = cx.insn_ctxt("alloca"); +pub fn alloca_maybe_zeroed(cx: block, ty: Type, zero: bool) -> ValueRef { + let _icx = push_ctxt("alloca"); if cx.unreachable { unsafe { - return llvm::LLVMGetUndef(t); + return llvm::LLVMGetUndef(ty.to_ref()); } } let initcx = base::raw_block(cx.fcx, false, cx.fcx.llstaticallocas); - let p = Alloca(initcx, t); - if zero { memzero(initcx, p, t); } - return p; + let p = Alloca(initcx, ty); + if zero { memzero(initcx, p, ty); } + p } -pub fn arrayalloca(cx: block, t: TypeRef, v: ValueRef) -> ValueRef { - let _icx = cx.insn_ctxt("arrayalloca"); +pub fn arrayalloca(cx: block, ty: Type, v: ValueRef) -> ValueRef { + let _icx = push_ctxt("arrayalloca"); if cx.unreachable { unsafe { - return llvm::LLVMGetUndef(t); + return llvm::LLVMGetUndef(ty.to_ref()); } } - return ArrayAlloca( - base::raw_block(cx.fcx, false, cx.fcx.llstaticallocas), t, v); + return ArrayAlloca(base::raw_block(cx.fcx, false, cx.fcx.llstaticallocas), ty, v); } pub struct BasicBlocks { @@ -1630,7 +1574,7 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext, let fcx = @mut fn_ctxt_ { llfn: llfndecl, llenv: unsafe { - llvm::LLVMGetUndef(T_ptr(T_i8())) + llvm::LLVMGetUndef(Type::i8p().to_ref()) }, llretptr: None, llstaticallocas: llbbs.sa, @@ -1686,7 +1630,7 @@ pub fn create_llargs_for_fn_args(cx: fn_ctxt, self_arg: self_arg, args: &[ast::arg]) -> ~[ValueRef] { - let _icx = cx.insn_ctxt("create_llargs_for_fn_args"); + let _icx = push_ctxt("create_llargs_for_fn_args"); match self_arg { impl_self(tt) => { @@ -1734,7 +1678,7 @@ pub fn copy_args_to_allocas(fcx: fn_ctxt, args: &[ast::arg], raw_llargs: &[ValueRef], arg_tys: &[ty::t]) -> block { - let _icx = fcx.insn_ctxt("copy_args_to_allocas"); + let _icx = push_ctxt("copy_args_to_allocas"); let mut bcx = bcx; match fcx.llself { @@ -1748,7 +1692,7 @@ pub fn copy_args_to_allocas(fcx: fn_ctxt, Store(bcx, tmp, alloc); alloc } else { - PointerCast(bcx, slf.v, T_ptr(type_of(bcx.ccx(), slf.t))) + PointerCast(bcx, slf.v, type_of(bcx.ccx(), slf.t).ptr_to()) }; fcx.llself = Some(ValSelfData {v: self_val, ..slf}); @@ -1800,7 +1744,7 @@ pub fn copy_args_to_allocas(fcx: fn_ctxt, // Ties up the llstaticallocas -> llloadenv -> lltop edges, // and builds the return block. pub fn finish_fn(fcx: fn_ctxt, lltop: BasicBlockRef) { - let _icx = fcx.insn_ctxt("finish_fn"); + let _icx = push_ctxt("finish_fn"); tie_up_header_blocks(fcx, lltop); build_return_block(fcx); } @@ -1818,7 +1762,7 @@ pub fn build_return_block(fcx: fn_ctxt) { } pub fn tie_up_header_blocks(fcx: fn_ctxt, lltop: BasicBlockRef) { - let _icx = fcx.insn_ctxt("tie_up_header_blocks"); + let _icx = push_ctxt("tie_up_header_blocks"); match fcx.llloadenv { Some(ll) => { Br(raw_block(fcx, false, fcx.llstaticallocas), ll); @@ -1849,7 +1793,7 @@ pub fn trans_closure(ccx: @mut CrateContext, maybe_load_env: &fn(fn_ctxt), finish: &fn(block)) { ccx.stats.n_closures += 1; - let _icx = ccx.insn_ctxt("trans_closure"); + let _icx = push_ctxt("trans_closure"); set_uwtable(llfndecl); debug!("trans_closure(..., param_substs=%s)", @@ -1872,16 +1816,6 @@ pub fn trans_closure(ccx: @mut CrateContext, set_fixed_stack_segment(fcx.llfn); } - // Set GC for function. - if ccx.sess.opts.gc { - do str::as_c_str("generic") |strategy| { - unsafe { - llvm::LLVMSetGC(fcx.llfn, strategy); - } - } - ccx.uses_gc = true; - } - // Create the first basic block in the function and keep a handle on it to // pass to finish_fn later. let bcx_top = top_scope_block(fcx, body.info()); @@ -1938,7 +1872,7 @@ pub fn trans_fn(ccx: @mut CrateContext, debug!("trans_fn(self_arg=%?, param_substs=%s)", self_arg, param_substs.repr(ccx.tcx)); - let _icx = ccx.insn_ctxt("trans_fn"); + let _icx = push_ctxt("trans_fn"); ccx.stats.n_fns += 1; let the_path_str = path_str(ccx.sess, path); let output_type = ty::ty_fn_ret(ty::node_id_to_type(ccx.tcx, id)); @@ -1962,7 +1896,7 @@ pub fn trans_fn(ccx: @mut CrateContext, |_bcx| { }); if do_time { let end = time::get_time(); - log_fn_time(ccx, the_path_str, start, end); + ccx.log_fn_time(the_path_str, start, end); } } @@ -1973,7 +1907,7 @@ pub fn trans_enum_variant(ccx: @mut CrateContext, disr: int, param_substs: Option<@param_substs>, llfndecl: ValueRef) { - let _icx = ccx.insn_ctxt("trans_enum_variant"); + let _icx = push_ctxt("trans_enum_variant"); // Translate variant arguments to function arguments. let fn_args = do args.map |varg| { ast::arg { @@ -2047,7 +1981,7 @@ pub fn trans_tuple_struct(ccx: @mut CrateContext, ctor_id: ast::node_id, param_substs: Option<@param_substs>, llfndecl: ValueRef) { - let _icx = ccx.insn_ctxt("trans_tuple_struct"); + let _icx = push_ctxt("trans_tuple_struct"); // Translate struct fields to function arguments. let fn_args = do fields.map |field| { @@ -2133,7 +2067,7 @@ pub fn trans_enum_def(ccx: @mut CrateContext, enum_definition: &ast::enum_def, } pub fn trans_item(ccx: @mut CrateContext, item: &ast::item) { - let _icx = ccx.insn_ctxt("trans_item"); + let _icx = push_ctxt("trans_item"); let path = match ccx.tcx.items.get_copy(&item.id) { ast_map::node_item(_, p) => p, // tjc: ? @@ -2240,7 +2174,7 @@ pub fn trans_struct_def(ccx: @mut CrateContext, struct_def: @ast::struct_def) { // only as a convenience for humans working with the code, to organize names // and control visibility. pub fn trans_mod(ccx: @mut CrateContext, m: &ast::_mod) { - let _icx = ccx.insn_ctxt("trans_mod"); + let _icx = push_ctxt("trans_mod"); for m.items.each |item| { trans_item(ccx, *item); } @@ -2275,7 +2209,7 @@ pub fn register_fn_fuller(ccx: @mut CrateContext, attrs: &[ast::attribute], node_type: ty::t, cc: lib::llvm::CallConv, - llfty: TypeRef) + fn_ty: Type) -> ValueRef { debug!("register_fn_fuller creating fn for item %d with path %s", node_id, @@ -2287,12 +2221,11 @@ pub fn register_fn_fuller(ccx: @mut CrateContext, mangle_exported_name(ccx, /*bad*/copy path, node_type) }; - let llfn: ValueRef = decl_fn(ccx.llmod, ps, cc, llfty); + let llfn = decl_fn(ccx.llmod, ps, cc, fn_ty); ccx.item_symbols.insert(node_id, ps); // FIXME #4404 android JNI hacks - let is_entry = is_entry_fn(&ccx.sess, node_id) && - (!*ccx.sess.building_library || + let is_entry = is_entry_fn(&ccx.sess, node_id) && (!*ccx.sess.building_library || (*ccx.sess.building_library && ccx.sess.targ_cfg.os == session::os_android)); if is_entry { @@ -2352,7 +2285,7 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext, fn create_entry_fn(ccx: @mut CrateContext, rust_main: ValueRef, use_start_lang_item: bool) { - let llfty = T_fn([ccx.int_type, T_ptr(T_ptr(T_i8()))], ccx.int_type); + let llfty = Type::func([ccx.int_type, Type::i8().ptr_to().ptr_to()], &ccx.int_type); // FIXME #4404 android JNI hacks let llfn = if *ccx.sess.building_library { @@ -2381,10 +2314,9 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext, } let crate_map = ccx.crate_map; - let opaque_crate_map = llvm::LLVMBuildPointerCast(bld, - crate_map, - T_ptr(T_i8()), - noname()); + let opaque_crate_map = do "crate_map".as_c_str |buf| { + llvm::LLVMBuildPointerCast(bld, crate_map, Type::i8p().to_ref(), buf) + }; let (start_fn, args) = if use_start_lang_item { let start_def_id = ccx.tcx.lang_items.start_fn(); @@ -2397,11 +2329,12 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext, }; let args = { - let opaque_rust_main = llvm::LLVMBuildPointerCast( - bld, rust_main, T_ptr(T_i8()), noname()); + let opaque_rust_main = do "rust_main".as_c_str |buf| { + llvm::LLVMBuildPointerCast(bld, rust_main, Type::i8p().to_ref(), buf) + }; ~[ - C_null(T_opaque_box_ptr(ccx)), + C_null(Type::opaque_box(ccx).ptr_to()), opaque_rust_main, llvm::LLVMGetParam(llfn, 0), llvm::LLVMGetParam(llfn, 1), @@ -2413,7 +2346,7 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext, debug!("using user-defined start fn"); let args = { ~[ - C_null(T_opaque_box_ptr(ccx)), + C_null(Type::opaque_box(ccx).ptr_to()), llvm::LLVMGetParam(llfn, 0 as c_uint), llvm::LLVMGetParam(llfn, 1 as c_uint), opaque_crate_map @@ -2439,7 +2372,7 @@ pub fn fill_fn_pair(bcx: block, pair: ValueRef, llfn: ValueRef, let code_cell = GEPi(bcx, pair, [0u, abi::fn_field_code]); Store(bcx, llfn, code_cell); let env_cell = GEPi(bcx, pair, [0u, abi::fn_field_box]); - let llenvblobptr = PointerCast(bcx, llenvptr, T_opaque_box_ptr(ccx)); + let llenvblobptr = PointerCast(bcx, llenvptr, Type::opaque_box(ccx).ptr_to()); Store(bcx, llenvblobptr, env_cell); } @@ -2530,7 +2463,7 @@ pub fn get_item_val(ccx: @mut CrateContext, id: ast::node_id) -> ValueRef { let g = do str::as_c_str(ident) |buf| { unsafe { let ty = type_of(ccx, typ); - llvm::LLVMAddGlobal(ccx.llmod, ty, buf) + llvm::LLVMAddGlobal(ccx.llmod, ty.to_ref(), buf) } }; g @@ -2608,7 +2541,7 @@ pub fn register_method(ccx: @mut CrateContext, // The constant translation pass. pub fn trans_constant(ccx: @mut CrateContext, it: @ast::item) { - let _icx = ccx.insn_ctxt("trans_constant"); + let _icx = push_ctxt("trans_constant"); match it.node { ast::item_enum(ref enum_definition, _) => { let vi = ty::enum_variants(ccx.tcx, @@ -2626,7 +2559,7 @@ pub fn trans_constant(ccx: @mut CrateContext, it: @ast::item) { note_unique_llvm_symbol(ccx, s); let discrim_gvar = str::as_c_str(s, |buf| { unsafe { - llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type, buf) + llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type.to_ref(), buf) } }); unsafe { @@ -2659,219 +2592,102 @@ pub fn vp2i(cx: block, v: ValueRef) -> ValueRef { pub fn p2i(ccx: &CrateContext, v: ValueRef) -> ValueRef { unsafe { - return llvm::LLVMConstPtrToInt(v, ccx.int_type); + return llvm::LLVMConstPtrToInt(v, ccx.int_type.to_ref()); } } -pub fn declare_intrinsics(llmod: ModuleRef) -> HashMap<&'static str, ValueRef> { - let T_memcpy32_args: ~[TypeRef] = - ~[T_ptr(T_i8()), T_ptr(T_i8()), T_i32(), T_i32(), T_i1()]; - let T_memcpy64_args: ~[TypeRef] = - ~[T_ptr(T_i8()), T_ptr(T_i8()), T_i64(), T_i32(), T_i1()]; - let T_memset32_args: ~[TypeRef] = - ~[T_ptr(T_i8()), T_i8(), T_i32(), T_i32(), T_i1()]; - let T_memset64_args: ~[TypeRef] = - ~[T_ptr(T_i8()), T_i8(), T_i64(), T_i32(), T_i1()]; - let T_trap_args: ~[TypeRef] = ~[]; - let T_frameaddress_args: ~[TypeRef] = ~[T_i32()]; - let gcroot = - decl_cdecl_fn(llmod, "llvm.gcroot", - T_fn([T_ptr(T_ptr(T_i8())), T_ptr(T_i8())], - T_void())); - let gcread = - decl_cdecl_fn(llmod, "llvm.gcread", - T_fn([T_ptr(T_i8()), T_ptr(T_ptr(T_i8()))], - T_void())); - let memcpy32 = - decl_cdecl_fn(llmod, "llvm.memcpy.p0i8.p0i8.i32", - T_fn(T_memcpy32_args, T_void())); - let memcpy64 = - decl_cdecl_fn(llmod, "llvm.memcpy.p0i8.p0i8.i64", - 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())); - let memmove64 = - decl_cdecl_fn(llmod, "llvm.memmove.p0i8.p0i8.i64", - T_fn(T_memcpy64_args, T_void())); - let memset32 = - decl_cdecl_fn(llmod, "llvm.memset.p0i8.i32", - T_fn(T_memset32_args, T_void())); - let memset64 = - decl_cdecl_fn(llmod, "llvm.memset.p0i8.i64", - T_fn(T_memset64_args, T_void())); - let trap = decl_cdecl_fn(llmod, "llvm.trap", T_fn(T_trap_args, - T_void())); - let frameaddress = decl_cdecl_fn(llmod, "llvm.frameaddress", - T_fn(T_frameaddress_args, - T_ptr(T_i8()))); - let sqrtf32 = decl_cdecl_fn(llmod, "llvm.sqrt.f32", - T_fn([T_f32()], T_f32())); - let sqrtf64 = decl_cdecl_fn(llmod, "llvm.sqrt.f64", - T_fn([T_f64()], T_f64())); - let powif32 = decl_cdecl_fn(llmod, "llvm.powi.f32", - T_fn([T_f32(), T_i32()], T_f32())); - let powif64 = decl_cdecl_fn(llmod, "llvm.powi.f64", - T_fn([T_f64(), T_i32()], T_f64())); - let sinf32 = decl_cdecl_fn(llmod, "llvm.sin.f32", - T_fn([T_f32()], T_f32())); - let sinf64 = decl_cdecl_fn(llmod, "llvm.sin.f64", - T_fn([T_f64()], T_f64())); - let cosf32 = decl_cdecl_fn(llmod, "llvm.cos.f32", - T_fn([T_f32()], T_f32())); - let cosf64 = decl_cdecl_fn(llmod, "llvm.cos.f64", - T_fn([T_f64()], T_f64())); - let powf32 = decl_cdecl_fn(llmod, "llvm.pow.f32", - T_fn([T_f32(), T_f32()], T_f32())); - let powf64 = decl_cdecl_fn(llmod, "llvm.pow.f64", - T_fn([T_f64(), T_f64()], T_f64())); - let expf32 = decl_cdecl_fn(llmod, "llvm.exp.f32", - T_fn([T_f32()], T_f32())); - let expf64 = decl_cdecl_fn(llmod, "llvm.exp.f64", - T_fn([T_f64()], T_f64())); - let exp2f32 = decl_cdecl_fn(llmod, "llvm.exp2.f32", - T_fn([T_f32()], T_f32())); - let exp2f64 = decl_cdecl_fn(llmod, "llvm.exp2.f64", - T_fn([T_f64()], T_f64())); - let logf32 = decl_cdecl_fn(llmod, "llvm.log.f32", - T_fn([T_f32()], T_f32())); - let logf64 = decl_cdecl_fn(llmod, "llvm.log.f64", - T_fn([T_f64()], T_f64())); - let log10f32 = decl_cdecl_fn(llmod, "llvm.log10.f32", - T_fn([T_f32()], T_f32())); - let log10f64 = decl_cdecl_fn(llmod, "llvm.log10.f64", - T_fn([T_f64()], T_f64())); - let log2f32 = decl_cdecl_fn(llmod, "llvm.log2.f32", - T_fn([T_f32()], T_f32())); - let log2f64 = decl_cdecl_fn(llmod, "llvm.log2.f64", - T_fn([T_f64()], T_f64())); - let fmaf32 = decl_cdecl_fn(llmod, "llvm.fma.f32", - T_fn([T_f32(), T_f32(), T_f32()], T_f32())); - let fmaf64 = decl_cdecl_fn(llmod, "llvm.fma.f64", - T_fn([T_f64(), T_f64(), T_f64()], T_f64())); - let fabsf32 = decl_cdecl_fn(llmod, "llvm.fabs.f32", - T_fn([T_f32()], T_f32())); - let fabsf64 = decl_cdecl_fn(llmod, "llvm.fabs.f64", - T_fn([T_f64()], T_f64())); - let floorf32 = decl_cdecl_fn(llmod, "llvm.floor.f32", - T_fn([T_f32()], T_f32())); - let floorf64 = decl_cdecl_fn(llmod, "llvm.floor.f64", - T_fn([T_f64()], T_f64())); - let ceilf32 = decl_cdecl_fn(llmod, "llvm.ceil.f32", - T_fn([T_f32()], T_f32())); - let ceilf64 = decl_cdecl_fn(llmod, "llvm.ceil.f64", - T_fn([T_f64()], T_f64())); - let truncf32 = decl_cdecl_fn(llmod, "llvm.trunc.f32", - T_fn([T_f32()], T_f32())); - let truncf64 = decl_cdecl_fn(llmod, "llvm.trunc.f64", - T_fn([T_f64()], T_f64())); - let ctpop8 = decl_cdecl_fn(llmod, "llvm.ctpop.i8", - T_fn([T_i8()], T_i8())); - let ctpop16 = decl_cdecl_fn(llmod, "llvm.ctpop.i16", - T_fn([T_i16()], T_i16())); - let ctpop32 = decl_cdecl_fn(llmod, "llvm.ctpop.i32", - T_fn([T_i32()], T_i32())); - let ctpop64 = decl_cdecl_fn(llmod, "llvm.ctpop.i64", - T_fn([T_i64()], T_i64())); - let ctlz8 = decl_cdecl_fn(llmod, "llvm.ctlz.i8", - T_fn([T_i8(), T_i1()], T_i8())); - let ctlz16 = decl_cdecl_fn(llmod, "llvm.ctlz.i16", - T_fn([T_i16(), T_i1()], T_i16())); - let ctlz32 = decl_cdecl_fn(llmod, "llvm.ctlz.i32", - T_fn([T_i32(), T_i1()], T_i32())); - let ctlz64 = decl_cdecl_fn(llmod, "llvm.ctlz.i64", - T_fn([T_i64(), T_i1()], T_i64())); - let cttz8 = decl_cdecl_fn(llmod, "llvm.cttz.i8", - T_fn([T_i8(), T_i1()], T_i8())); - let cttz16 = decl_cdecl_fn(llmod, "llvm.cttz.i16", - T_fn([T_i16(), T_i1()], T_i16())); - let cttz32 = decl_cdecl_fn(llmod, "llvm.cttz.i32", - T_fn([T_i32(), T_i1()], T_i32())); - let cttz64 = decl_cdecl_fn(llmod, "llvm.cttz.i64", - T_fn([T_i64(), T_i1()], T_i64())); - let bswap16 = decl_cdecl_fn(llmod, "llvm.bswap.i16", - T_fn([T_i16()], T_i16())); - let bswap32 = decl_cdecl_fn(llmod, "llvm.bswap.i32", - T_fn([T_i32()], T_i32())); - let bswap64 = decl_cdecl_fn(llmod, "llvm.bswap.i64", - T_fn([T_i64()], T_i64())); +macro_rules! ifn ( + ($name:expr, $args:expr, $ret:expr) => ({ + let name = $name; + let f = decl_cdecl_fn(llmod, name, Type::func($args, &$ret)); + intrinsics.insert(name, f); + }) +) +pub fn declare_intrinsics(llmod: ModuleRef) -> HashMap<&'static str, ValueRef> { + let i8p = Type::i8p(); let mut intrinsics = HashMap::new(); - intrinsics.insert("llvm.gcroot", gcroot); - intrinsics.insert("llvm.gcread", gcread); - intrinsics.insert("llvm.memcpy.p0i8.p0i8.i32", memcpy32); - intrinsics.insert("llvm.memcpy.p0i8.p0i8.i64", memcpy64); - intrinsics.insert("llvm.memmove.p0i8.p0i8.i32", memmove32); - intrinsics.insert("llvm.memmove.p0i8.p0i8.i64", memmove64); - intrinsics.insert("llvm.memset.p0i8.i32", memset32); - intrinsics.insert("llvm.memset.p0i8.i64", memset64); - intrinsics.insert("llvm.trap", trap); - intrinsics.insert("llvm.frameaddress", frameaddress); - intrinsics.insert("llvm.sqrt.f32", sqrtf32); - intrinsics.insert("llvm.sqrt.f64", sqrtf64); - intrinsics.insert("llvm.powi.f32", powif32); - intrinsics.insert("llvm.powi.f64", powif64); - intrinsics.insert("llvm.sin.f32", sinf32); - intrinsics.insert("llvm.sin.f64", sinf64); - intrinsics.insert("llvm.cos.f32", cosf32); - intrinsics.insert("llvm.cos.f64", cosf64); - intrinsics.insert("llvm.pow.f32", powf32); - intrinsics.insert("llvm.pow.f64", powf64); - intrinsics.insert("llvm.exp.f32", expf32); - intrinsics.insert("llvm.exp.f64", expf64); - intrinsics.insert("llvm.exp2.f32", exp2f32); - intrinsics.insert("llvm.exp2.f64", exp2f64); - intrinsics.insert("llvm.log.f32", logf32); - intrinsics.insert("llvm.log.f64", logf64); - intrinsics.insert("llvm.log10.f32", log10f32); - intrinsics.insert("llvm.log10.f64", log10f64); - intrinsics.insert("llvm.log2.f32", log2f32); - intrinsics.insert("llvm.log2.f64", log2f64); - intrinsics.insert("llvm.fma.f32", fmaf32); - intrinsics.insert("llvm.fma.f64", fmaf64); - intrinsics.insert("llvm.fabs.f32", fabsf32); - intrinsics.insert("llvm.fabs.f64", fabsf64); - intrinsics.insert("llvm.floor.f32", floorf32); - intrinsics.insert("llvm.floor.f64", floorf64); - intrinsics.insert("llvm.ceil.f32", ceilf32); - intrinsics.insert("llvm.ceil.f64", ceilf64); - intrinsics.insert("llvm.trunc.f32", truncf32); - intrinsics.insert("llvm.trunc.f64", truncf64); - intrinsics.insert("llvm.ctpop.i8", ctpop8); - intrinsics.insert("llvm.ctpop.i16", ctpop16); - intrinsics.insert("llvm.ctpop.i32", ctpop32); - intrinsics.insert("llvm.ctpop.i64", ctpop64); - intrinsics.insert("llvm.ctlz.i8", ctlz8); - intrinsics.insert("llvm.ctlz.i16", ctlz16); - intrinsics.insert("llvm.ctlz.i32", ctlz32); - intrinsics.insert("llvm.ctlz.i64", ctlz64); - intrinsics.insert("llvm.cttz.i8", cttz8); - intrinsics.insert("llvm.cttz.i16", cttz16); - intrinsics.insert("llvm.cttz.i32", cttz32); - intrinsics.insert("llvm.cttz.i64", cttz64); - intrinsics.insert("llvm.bswap.i16", bswap16); - intrinsics.insert("llvm.bswap.i32", bswap32); - intrinsics.insert("llvm.bswap.i64", bswap64); + + ifn!("llvm.memcpy.p0i8.p0i8.i32", + [i8p, i8p, Type::i32(), Type::i32(), Type::i1()], Type::void()); + ifn!("llvm.memcpy.p0i8.p0i8.i64", + [i8p, i8p, Type::i64(), Type::i32(), Type::i1()], Type::void()); + ifn!("llvm.memmove.p0i8.p0i8.i32", + [i8p, i8p, Type::i32(), Type::i32(), Type::i1()], Type::void()); + ifn!("llvm.memmove.p0i8.p0i8.i64", + [i8p, i8p, Type::i64(), Type::i32(), Type::i1()], Type::void()); + ifn!("llvm.memset.p0i8.i32", + [i8p, Type::i8(), Type::i32(), Type::i32(), Type::i1()], Type::void()); + ifn!("llvm.memset.p0i8.i64", + [i8p, Type::i8(), Type::i64(), Type::i32(), Type::i1()], Type::void()); + + ifn!("llvm.trap", [], Type::void()); + ifn!("llvm.frameaddress", [Type::i32()], i8p); + + ifn!("llvm.powi.f32", [Type::f32(), Type::i32()], Type::f32()); + ifn!("llvm.powi.f64", [Type::f64(), Type::i32()], Type::f64()); + ifn!("llvm.pow.f32", [Type::f32(), Type::f32()], Type::f32()); + ifn!("llvm.pow.f64", [Type::f64(), Type::f64()], Type::f64()); + + ifn!("llvm.sqrt.f32", [Type::f32()], Type::f32()); + ifn!("llvm.sqrt.f64", [Type::f64()], Type::f64()); + ifn!("llvm.sin.f32", [Type::f32()], Type::f32()); + ifn!("llvm.sin.f64", [Type::f64()], Type::f64()); + ifn!("llvm.cos.f32", [Type::f32()], Type::f32()); + ifn!("llvm.cos.f64", [Type::f64()], Type::f64()); + ifn!("llvm.exp.f32", [Type::f32()], Type::f32()); + ifn!("llvm.exp.f64", [Type::f64()], Type::f64()); + ifn!("llvm.exp2.f32", [Type::f32()], Type::f32()); + ifn!("llvm.exp2.f64", [Type::f64()], Type::f64()); + ifn!("llvm.log.f32", [Type::f32()], Type::f32()); + ifn!("llvm.log.f64", [Type::f64()], Type::f64()); + ifn!("llvm.log10.f32",[Type::f32()], Type::f32()); + ifn!("llvm.log10.f64",[Type::f64()], Type::f64()); + ifn!("llvm.log2.f32", [Type::f32()], Type::f32()); + ifn!("llvm.log2.f64", [Type::f64()], Type::f64()); + + ifn!("llvm.fma.f32", [Type::f32(), Type::f32(), Type::f32()], Type::f32()); + ifn!("llvm.fma.f64", [Type::f64(), Type::f64(), Type::f64()], Type::f64()); + + ifn!("llvm.fabs.f32", [Type::f32()], Type::f32()); + ifn!("llvm.fabs.f64", [Type::f64()], Type::f64()); + ifn!("llvm.floor.f32",[Type::f32()], Type::f32()); + ifn!("llvm.floor.f64",[Type::f64()], Type::f64()); + ifn!("llvm.ceil.f32", [Type::f32()], Type::f32()); + ifn!("llvm.ceil.f64", [Type::f64()], Type::f64()); + ifn!("llvm.trunc.f32",[Type::f32()], Type::f32()); + ifn!("llvm.trunc.f64",[Type::f64()], Type::f64()); + + ifn!("llvm.ctpop.i8", [Type::i8()], Type::i8()); + ifn!("llvm.ctpop.i16",[Type::i16()], Type::i16()); + ifn!("llvm.ctpop.i32",[Type::i32()], Type::i32()); + ifn!("llvm.ctpop.i64",[Type::i64()], Type::i64()); + + ifn!("llvm.ctlz.i8", [Type::i8() , Type::i1()], Type::i8()); + ifn!("llvm.ctlz.i16", [Type::i16(), Type::i1()], Type::i16()); + ifn!("llvm.ctlz.i32", [Type::i32(), Type::i1()], Type::i32()); + ifn!("llvm.ctlz.i64", [Type::i64(), Type::i1()], Type::i64()); + + ifn!("llvm.cttz.i8", [Type::i8() , Type::i1()], Type::i8()); + ifn!("llvm.cttz.i16", [Type::i16(), Type::i1()], Type::i16()); + ifn!("llvm.cttz.i32", [Type::i32(), Type::i1()], Type::i32()); + ifn!("llvm.cttz.i64", [Type::i64(), Type::i1()], Type::i64()); + + ifn!("llvm.bswap.i16",[Type::i16()], Type::i16()); + ifn!("llvm.bswap.i32",[Type::i32()], Type::i32()); + ifn!("llvm.bswap.i64",[Type::i64()], Type::i64()); return intrinsics; } -pub fn declare_dbg_intrinsics(llmod: ModuleRef, - intrinsics: &mut HashMap<&'static str, ValueRef>) { - let declare = - decl_cdecl_fn(llmod, "llvm.dbg.declare", - T_fn([T_metadata(), T_metadata()], T_void())); - let value = - decl_cdecl_fn(llmod, "llvm.dbg.value", - T_fn([T_metadata(), T_i64(), T_metadata()], T_void())); - intrinsics.insert("llvm.dbg.declare", declare); - intrinsics.insert("llvm.dbg.value", value); +pub fn declare_dbg_intrinsics(llmod: ModuleRef, intrinsics: &mut HashMap<&'static str, ValueRef>) { + ifn!("llvm.dbg.declare", [Type::metadata(), Type::metadata()], Type::void()); + ifn!("llvm.dbg.value", [Type::metadata(), Type::i64(), Type::metadata()], Type::void()); } pub fn trap(bcx: block) { - let v: ~[ValueRef] = ~[]; - match bcx.ccx().intrinsics.find(& &"llvm.trap") { - Some(&x) => { Call(bcx, x, v); }, + match bcx.ccx().intrinsics.find_equiv(& &"llvm.trap") { + Some(&x) => { Call(bcx, x, []); }, _ => bcx.sess().bug("unbound llvm.trap in trap") } } @@ -2884,7 +2700,7 @@ pub fn decl_gc_metadata(ccx: &mut CrateContext, llmod_id: &str) { let gc_metadata_name = ~"_gc_module_metadata_" + llmod_id; let gc_metadata = do str::as_c_str(gc_metadata_name) |buf| { unsafe { - llvm::LLVMAddGlobal(ccx.llmod, T_i32(), buf) + llvm::LLVMAddGlobal(ccx.llmod, Type::i32().to_ref(), buf) } }; unsafe { @@ -2895,13 +2711,13 @@ pub fn decl_gc_metadata(ccx: &mut CrateContext, llmod_id: &str) { } pub fn create_module_map(ccx: &mut CrateContext) -> ValueRef { - let elttype = T_struct([ccx.int_type, ccx.int_type], false); - let maptype = T_array(elttype, ccx.module_data.len() + 1); - let map = str::as_c_str("_rust_mod_map", |buf| { + let elttype = Type::struct_([ccx.int_type, ccx.int_type], false); + let maptype = Type::array(&elttype, (ccx.module_data.len() + 1) as u64); + let map = do "_rust_mod_map".as_c_str |buf| { unsafe { - llvm::LLVMAddGlobal(ccx.llmod, maptype, buf) + llvm::LLVMAddGlobal(ccx.llmod, maptype.to_ref(), buf) } - }); + }; lib::llvm::SetLinkage(map, lib::llvm::InternalLinkage); let mut elts: ~[ValueRef] = ~[]; @@ -2933,7 +2749,7 @@ pub fn create_module_map(ccx: &mut CrateContext) -> ValueRef { pub fn decl_crate_map(sess: session::Session, mapmeta: LinkMeta, llmod: ModuleRef) -> ValueRef { let targ_cfg = sess.targ_cfg; - let int_type = T_int(targ_cfg); + let int_type = Type::int(targ_cfg.arch); let mut n_subcrates = 1; let cstore = sess.cstore; while cstore::have_crate_data(cstore, n_subcrates) { n_subcrates += 1; } @@ -2943,11 +2759,11 @@ pub fn decl_crate_map(sess: session::Session, mapmeta: LinkMeta, ~"toplevel" }; let sym_name = ~"_rust_crate_map_" + mapname; - let arrtype = T_array(int_type, n_subcrates as uint); - let maptype = T_struct([T_i32(), T_ptr(T_i8()), int_type, arrtype], false); + let arrtype = Type::array(&int_type, n_subcrates as u64); + let maptype = Type::struct_([Type::i32(), Type::i8p(), int_type, arrtype], false); let map = str::as_c_str(sym_name, |buf| { unsafe { - llvm::LLVMAddGlobal(llmod, maptype, buf) + llvm::LLVMAddGlobal(llmod, maptype.to_ref(), buf) } }); lib::llvm::SetLinkage(map, lib::llvm::ExternalLinkage); @@ -2966,7 +2782,7 @@ pub fn fill_crate_map(ccx: @mut CrateContext, map: ValueRef) { cstore::get_crate_hash(cstore, i)); let cr = str::as_c_str(nm, |buf| { unsafe { - llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type, buf) + llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type.to_ref(), buf) } }); subcrates.push(p2i(ccx, cr)); @@ -2990,8 +2806,7 @@ pub fn fill_crate_map(ccx: @mut CrateContext, map: ValueRef) { let mod_map = create_module_map(ccx); llvm::LLVMSetInitializer(map, C_struct( [C_i32(1), - lib::llvm::llvm::LLVMConstPointerCast(llannihilatefn, - T_ptr(T_i8())), + lib::llvm::llvm::LLVMConstPointerCast(llannihilatefn, Type::i8p().to_ref()), p2i(ccx, mod_map), C_array(ccx.int_type, subcrates)])); } @@ -3029,7 +2844,7 @@ pub fn write_metadata(cx: &mut CrateContext, crate: &ast::crate) { let llconst = C_struct([llmeta]); let mut llglobal = str::as_c_str("rust_metadata", |buf| { unsafe { - llvm::LLVMAddGlobal(cx.llmod, val_ty(llconst), buf) + llvm::LLVMAddGlobal(cx.llmod, val_ty(llconst).to_ref(), buf) } }); unsafe { @@ -3039,11 +2854,11 @@ pub fn write_metadata(cx: &mut CrateContext, crate: &ast::crate) { }); lib::llvm::SetLinkage(llglobal, lib::llvm::InternalLinkage); - let t_ptr_i8 = T_ptr(T_i8()); - llglobal = llvm::LLVMConstBitCast(llglobal, t_ptr_i8); - let llvm_used = str::as_c_str("llvm.used", |buf| { - llvm::LLVMAddGlobal(cx.llmod, T_array(t_ptr_i8, 1u), buf) - }); + let t_ptr_i8 = Type::i8p(); + llglobal = llvm::LLVMConstBitCast(llglobal, t_ptr_i8.to_ref()); + let llvm_used = do "llvm.used".as_c_str |buf| { + llvm::LLVMAddGlobal(cx.llmod, Type::array(&t_ptr_i8, 1).to_ref(), buf) + }; lib::llvm::SetLinkage(llvm_used, lib::llvm::AppendingLinkage); llvm::LLVMSetInitializer(llvm_used, C_array(t_ptr_i8, [llglobal])); } @@ -3051,8 +2866,7 @@ pub fn write_metadata(cx: &mut CrateContext, crate: &ast::crate) { // Writes the current ABI version into the crate. pub fn write_abi_version(ccx: &mut CrateContext) { - mk_global(ccx, "rust_abi_version", C_uint(ccx, abi::abi_version), - false); + mk_global(ccx, "rust_abi_version", C_uint(ccx, abi::abi_version), false); } pub fn trans_crate(sess: session::Session, @@ -3089,19 +2903,13 @@ pub fn trans_crate(sess: session::Session, let ccx = @mut CrateContext::new(sess, llmod_id, tcx, emap2, maps, symbol_hasher, link_meta, reachable); - // FIXME(#6511): get LLVM building with --enable-threads so this - // function can be called - // if !llvm::LLVMRustStartMultithreading() { - // sess.bug("couldn't enable multi-threaded LLVM"); - // } - { - let _icx = ccx.insn_ctxt("data"); + let _icx = push_ctxt("data"); trans_constants(ccx, crate); } { - let _icx = ccx.insn_ctxt("text"); + let _icx = push_ctxt("text"); trans_mod(ccx, &crate.node.module); } @@ -3135,6 +2943,7 @@ pub fn trans_crate(sess: session::Session, io::println(fmt!("%-7u %s", v, k)); } } + let llcx = ccx.llcx; let link_meta = ccx.link_meta; let llmod = ccx.llmod; diff --git a/src/librustc/middle/trans/build.rs b/src/librustc/middle/trans/build.rs index a55e89747f5..83c1a3c80db 100644 --- a/src/librustc/middle/trans/build.rs +++ b/src/librustc/middle/trans/build.rs @@ -13,15 +13,18 @@ use core::prelude::*; use lib::llvm::llvm; use lib::llvm::{CallConv, AtomicBinOp, AtomicOrdering, AsmDialect}; use lib::llvm::{Opcode, IntPredicate, RealPredicate, False}; -use lib::llvm::{ValueRef, TypeRef, BasicBlockRef, BuilderRef, ModuleRef}; +use lib::llvm::{ValueRef, BasicBlockRef, BuilderRef, ModuleRef}; use lib; use middle::trans::common::*; use middle::trans::machine::llalign_of_min; use syntax::codemap::span; +use middle::trans::base; +use middle::trans::type_::Type; + use core::cast; -use core::hashmap::HashMap; use core::libc::{c_uint, c_ulonglong, c_char}; +use core::hashmap::HashMap; use core::str; use core::vec; @@ -44,10 +47,8 @@ pub fn B(cx: block) -> BuilderRef { } pub fn count_insn(cx: block, category: &str) { - if cx.ccx().sess.count_llvm_insns() { - + do base::with_insn_ctxt |v| { let h = &mut cx.ccx().stats.llvm_insns; - let v : &[~str] = cx.ccx().stats.llvm_insn_ctxt; // Build version of path with cycles removed. @@ -186,13 +187,13 @@ pub fn Invoke(cx: block, Catch: BasicBlockRef) -> ValueRef { if cx.unreachable { - return C_null(T_i8()); + return C_null(Type::i8()); } check_not_terminated(cx); terminate(cx, "Invoke"); debug!("Invoke(%s with arguments (%s))", - val_str(cx.ccx().tn, Fn), - Args.map(|a| val_str(cx.ccx().tn, *a).to_owned()).connect(", ")); + cx.val_to_str(Fn), + Args.map(|a| cx.val_to_str(*a)).connect(", ")); unsafe { count_insn(cx, "invoke"); llvm::LLVMBuildInvoke(B(cx), @@ -232,7 +233,7 @@ pub fn Unreachable(cx: block) { pub fn _Undef(val: ValueRef) -> ValueRef { unsafe { - return llvm::LLVMGetUndef(val_ty(val)); + return llvm::LLVMGetUndef(val_ty(val).to_ref()); } } @@ -486,35 +487,35 @@ pub fn Not(cx: block, V: ValueRef) -> ValueRef { } /* Memory */ -pub fn Malloc(cx: block, Ty: TypeRef) -> ValueRef { +pub fn Malloc(cx: block, Ty: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_i8())); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::i8p().to_ref()); } count_insn(cx, "malloc"); - return llvm::LLVMBuildMalloc(B(cx), Ty, noname()); + return llvm::LLVMBuildMalloc(B(cx), Ty.to_ref(), noname()); } } -pub fn ArrayMalloc(cx: block, Ty: TypeRef, Val: ValueRef) -> ValueRef { +pub fn ArrayMalloc(cx: block, Ty: Type, Val: ValueRef) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_i8())); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::i8p().to_ref()); } count_insn(cx, "arraymalloc"); - return llvm::LLVMBuildArrayMalloc(B(cx), Ty, Val, noname()); + return llvm::LLVMBuildArrayMalloc(B(cx), Ty.to_ref(), Val, noname()); } } -pub fn Alloca(cx: block, Ty: TypeRef) -> ValueRef { +pub fn Alloca(cx: block, Ty: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(Ty)); } + if cx.unreachable { return llvm::LLVMGetUndef(Ty.ptr_to().to_ref()); } count_insn(cx, "alloca"); - return llvm::LLVMBuildAlloca(B(cx), Ty, noname()); + return llvm::LLVMBuildAlloca(B(cx), Ty.to_ref(), noname()); } } -pub fn ArrayAlloca(cx: block, Ty: TypeRef, Val: ValueRef) -> ValueRef { +pub fn ArrayAlloca(cx: block, Ty: Type, Val: ValueRef) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(Ty)); } + if cx.unreachable { return llvm::LLVMGetUndef(Ty.ptr_to().to_ref()); } count_insn(cx, "arrayalloca"); - return llvm::LLVMBuildArrayAlloca(B(cx), Ty, Val, noname()); + return llvm::LLVMBuildArrayAlloca(B(cx), Ty.to_ref(), Val, noname()); } } @@ -531,9 +532,12 @@ pub fn Load(cx: block, PointerVal: ValueRef) -> ValueRef { let ccx = cx.fcx.ccx; if cx.unreachable { let ty = val_ty(PointerVal); - let eltty = if llvm::LLVMGetTypeKind(ty) == lib::llvm::Array { - llvm::LLVMGetElementType(ty) } else { ccx.int_type }; - return llvm::LLVMGetUndef(eltty); + let eltty = if ty.kind() == lib::llvm::Array { + ty.element_type() + } else { + ccx.int_type + }; + return llvm::LLVMGetUndef(eltty.to_ref()); } count_insn(cx, "load"); return llvm::LLVMBuildLoad(B(cx), PointerVal, noname()); @@ -544,7 +548,7 @@ pub fn AtomicLoad(cx: block, PointerVal: ValueRef, order: AtomicOrdering) -> Val unsafe { let ccx = cx.fcx.ccx; if cx.unreachable { - return llvm::LLVMGetUndef(ccx.int_type); + return llvm::LLVMGetUndef(ccx.int_type.to_ref()); } count_insn(cx, "load.atomic"); let align = llalign_of_min(ccx, ccx.int_type); @@ -576,8 +580,8 @@ pub fn Store(cx: block, Val: ValueRef, Ptr: ValueRef) { unsafe { if cx.unreachable { return; } debug!("Store %s -> %s", - val_str(cx.ccx().tn, Val), - val_str(cx.ccx().tn, Ptr)); + cx.val_to_str(Val), + cx.val_to_str(Ptr)); count_insn(cx, "store"); llvm::LLVMBuildStore(B(cx), Val, Ptr); } @@ -587,8 +591,8 @@ pub fn AtomicStore(cx: block, Val: ValueRef, Ptr: ValueRef, order: AtomicOrderin unsafe { if cx.unreachable { return; } debug!("Store %s -> %s", - val_str(cx.ccx().tn, Val), - val_str(cx.ccx().tn, Ptr)); + cx.val_to_str(Val), + cx.val_to_str(Ptr)); count_insn(cx, "store.atomic"); let align = llalign_of_min(cx.ccx(), cx.ccx().int_type); llvm::LLVMBuildAtomicStore(B(cx), Val, Ptr, order, align as c_uint); @@ -597,7 +601,7 @@ pub fn AtomicStore(cx: block, Val: ValueRef, Ptr: ValueRef, order: AtomicOrderin pub fn GEP(cx: block, Pointer: ValueRef, Indices: &[ValueRef]) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_nil())); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::nil().ptr_to().to_ref()); } count_insn(cx, "gep"); return llvm::LLVMBuildGEP(B(cx), Pointer, vec::raw::to_ptr(Indices), Indices.len() as c_uint, noname()); @@ -614,21 +618,18 @@ pub fn GEPi(cx: block, base: ValueRef, ixs: &[uint]) -> ValueRef { return InBoundsGEP(cx, base, v); } -pub fn InBoundsGEP(cx: block, Pointer: ValueRef, Indices: &[ValueRef]) -> - ValueRef { +pub fn InBoundsGEP(cx: block, Pointer: ValueRef, Indices: &[ValueRef]) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_nil())); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::nil().ptr_to().to_ref()); } count_insn(cx, "inboundsgep"); - return llvm::LLVMBuildInBoundsGEP(B(cx), Pointer, - vec::raw::to_ptr(Indices), - Indices.len() as c_uint, - noname()); + return llvm::LLVMBuildInBoundsGEP( + B(cx), Pointer, vec::raw::to_ptr(Indices), Indices.len() as c_uint, noname()); } } pub fn StructGEP(cx: block, Pointer: ValueRef, Idx: uint) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_nil())); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::nil().ptr_to().to_ref()); } count_insn(cx, "structgep"); return llvm::LLVMBuildStructGEP(B(cx), Pointer, @@ -639,7 +640,7 @@ pub fn StructGEP(cx: block, Pointer: ValueRef, Idx: uint) -> ValueRef { pub fn GlobalString(cx: block, _Str: *c_char) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_i8())); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::i8p().to_ref()); } count_insn(cx, "globalstring"); return llvm::LLVMBuildGlobalString(B(cx), _Str, noname()); } @@ -647,163 +648,163 @@ pub fn GlobalString(cx: block, _Str: *c_char) -> ValueRef { pub fn GlobalStringPtr(cx: block, _Str: *c_char) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_ptr(T_i8())); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::i8p().to_ref()); } count_insn(cx, "globalstringptr"); return llvm::LLVMBuildGlobalStringPtr(B(cx), _Str, noname()); } } /* Casts */ -pub fn Trunc(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn Trunc(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "trunc"); - return llvm::LLVMBuildTrunc(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildTrunc(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn ZExt(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn ZExt(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "zext"); - return llvm::LLVMBuildZExt(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildZExt(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn SExt(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn SExt(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "sext"); - return llvm::LLVMBuildSExt(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildSExt(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn FPToUI(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn FPToUI(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "fptoui"); - return llvm::LLVMBuildFPToUI(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildFPToUI(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn FPToSI(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn FPToSI(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "fptosi"); - return llvm::LLVMBuildFPToSI(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildFPToSI(B(cx), Val, DestTy.to_ref(),noname()); } } -pub fn UIToFP(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn UIToFP(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "uitofp"); - return llvm::LLVMBuildUIToFP(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildUIToFP(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn SIToFP(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn SIToFP(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "sitofp"); - return llvm::LLVMBuildSIToFP(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildSIToFP(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn FPTrunc(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn FPTrunc(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "fptrunc"); - return llvm::LLVMBuildFPTrunc(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildFPTrunc(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn FPExt(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn FPExt(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "fpext"); - return llvm::LLVMBuildFPExt(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildFPExt(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn PtrToInt(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn PtrToInt(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "ptrtoint"); - return llvm::LLVMBuildPtrToInt(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildPtrToInt(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn IntToPtr(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn IntToPtr(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "inttoptr"); - return llvm::LLVMBuildIntToPtr(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildIntToPtr(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn BitCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn BitCast(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "bitcast"); - return llvm::LLVMBuildBitCast(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildBitCast(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn ZExtOrBitCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn ZExtOrBitCast(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "zextorbitcast"); - return llvm::LLVMBuildZExtOrBitCast(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildZExtOrBitCast(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn SExtOrBitCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn SExtOrBitCast(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "sextorbitcast"); - return llvm::LLVMBuildSExtOrBitCast(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildSExtOrBitCast(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn TruncOrBitCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn TruncOrBitCast(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "truncorbitcast"); - return llvm::LLVMBuildTruncOrBitCast(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildTruncOrBitCast(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn Cast(cx: block, Op: Opcode, Val: ValueRef, DestTy: TypeRef, _: *u8) +pub fn Cast(cx: block, Op: Opcode, Val: ValueRef, DestTy: Type, _: *u8) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } count_insn(cx, "cast"); - return llvm::LLVMBuildCast(B(cx), Op, Val, DestTy, noname()); + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } + return llvm::LLVMBuildCast(B(cx), Op, Val, DestTy.to_ref(), noname()); } } -pub fn PointerCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn PointerCast(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "pointercast"); - return llvm::LLVMBuildPointerCast(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildPointerCast(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn IntCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn IntCast(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "intcast"); - return llvm::LLVMBuildIntCast(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildIntCast(B(cx), Val, DestTy.to_ref(), noname()); } } -pub fn FPCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { +pub fn FPCast(cx: block, Val: ValueRef, DestTy: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(DestTy); } + if cx.unreachable { return llvm::LLVMGetUndef(DestTy.to_ref()); } count_insn(cx, "fpcast"); - return llvm::LLVMBuildFPCast(B(cx), Val, DestTy, noname()); + return llvm::LLVMBuildFPCast(B(cx), Val, DestTy.to_ref(), noname()); } } @@ -812,7 +813,7 @@ pub fn FPCast(cx: block, Val: ValueRef, DestTy: TypeRef) -> ValueRef { pub fn ICmp(cx: block, Op: IntPredicate, LHS: ValueRef, RHS: ValueRef) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_i1()); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::i1().to_ref()); } count_insn(cx, "icmp"); return llvm::LLVMBuildICmp(B(cx), Op as c_uint, LHS, RHS, noname()); } @@ -821,25 +822,25 @@ pub fn ICmp(cx: block, Op: IntPredicate, LHS: ValueRef, RHS: ValueRef) pub fn FCmp(cx: block, Op: RealPredicate, LHS: ValueRef, RHS: ValueRef) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_i1()); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::i1().to_ref()); } count_insn(cx, "fcmp"); return llvm::LLVMBuildFCmp(B(cx), Op as c_uint, LHS, RHS, noname()); } } /* Miscellaneous instructions */ -pub fn EmptyPhi(cx: block, Ty: TypeRef) -> ValueRef { +pub fn EmptyPhi(cx: block, Ty: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(Ty); } + if cx.unreachable { return llvm::LLVMGetUndef(Ty.to_ref()); } count_insn(cx, "emptyphi"); - return llvm::LLVMBuildPhi(B(cx), Ty, noname()); + return llvm::LLVMBuildPhi(B(cx), Ty.to_ref(), noname()); } } -pub fn Phi(cx: block, Ty: TypeRef, vals: &[ValueRef], bbs: &[BasicBlockRef]) +pub fn Phi(cx: block, Ty: Type, vals: &[ValueRef], bbs: &[BasicBlockRef]) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(Ty); } + if cx.unreachable { return llvm::LLVMGetUndef(Ty.to_ref()); } assert_eq!(vals.len(), bbs.len()); let phi = EmptyPhi(cx, Ty); count_insn(cx, "addincoming"); @@ -863,10 +864,13 @@ pub fn _UndefReturn(cx: block, Fn: ValueRef) -> ValueRef { unsafe { let ccx = cx.fcx.ccx; let ty = val_ty(Fn); - let retty = if llvm::LLVMGetTypeKind(ty) == lib::llvm::Integer { - llvm::LLVMGetReturnType(ty) } else { ccx.int_type }; - count_insn(cx, ""); - return llvm::LLVMGetUndef(retty); + let retty = if ty.kind() == lib::llvm::Integer { + ty.return_type() + } else { + ccx.int_type + }; + count_insn(cx, "ret_undef"); + return llvm::LLVMGetUndef(retty.to_ref()); } } @@ -886,20 +890,18 @@ pub fn add_comment(bcx: block, text: &str) { let sanitized = text.replace("$", ""); let comment_text = ~"# " + sanitized.replace("\n", "\n\t# "); - let asm = str::as_c_str(comment_text, |c| { - str::as_c_str("", |e| { - count_insn(bcx, "inlineasm"); - llvm::LLVMConstInlineAsm(T_fn([], T_void()), c, e, - False, False) - }) - }); + count_insn(bcx, "inlineasm"); + let asm = do comment_text.as_c_str |c| { + llvm::LLVMConstInlineAsm(Type::func([], &Type::void()).to_ref(), + c, noname(), False, False) + }; Call(bcx, asm, []); } } } pub fn InlineAsmCall(cx: block, asm: *c_char, cons: *c_char, - inputs: &[ValueRef], output: TypeRef, + inputs: &[ValueRef], output: Type, volatile: bool, alignstack: bool, dia: AsmDialect) -> ValueRef { unsafe { @@ -911,14 +913,13 @@ pub fn InlineAsmCall(cx: block, asm: *c_char, cons: *c_char, else { lib::llvm::False }; let argtys = do inputs.map |v| { - debug!("Asm Input Type: %?", val_str(cx.ccx().tn, *v)); + debug!("Asm Input Type: %?", cx.val_to_str(*v)); val_ty(*v) }; - debug!("Asm Output Type: %?", ty_str(cx.ccx().tn, output)); - let llfty = T_fn(argtys, output); - let v = llvm::LLVMInlineAsm(llfty, asm, cons, volatile, - alignstack, dia as c_uint); + debug!("Asm Output Type: %?", cx.ccx().tn.type_to_str(output)); + let fty = Type::func(argtys, &output); + let v = llvm::LLVMInlineAsm(fty.to_ref(), asm, cons, volatile, alignstack, dia as c_uint); Call(cx, v, inputs) } @@ -930,8 +931,8 @@ pub fn Call(cx: block, Fn: ValueRef, Args: &[ValueRef]) -> ValueRef { count_insn(cx, "call"); debug!("Call(Fn=%s, Args=%?)", - val_str(cx.ccx().tn, Fn), - Args.map(|arg| val_str(cx.ccx().tn, *arg))); + cx.val_to_str(Fn), + Args.map(|arg| cx.val_to_str(*arg))); do vec::as_imm_buf(Args) |ptr, len| { llvm::LLVMBuildCall(B(cx), Fn, ptr, len as c_uint, noname()) @@ -971,18 +972,18 @@ pub fn Select(cx: block, If: ValueRef, Then: ValueRef, Else: ValueRef) -> } } -pub fn VAArg(cx: block, list: ValueRef, Ty: TypeRef) -> ValueRef { +pub fn VAArg(cx: block, list: ValueRef, Ty: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(Ty); } + if cx.unreachable { return llvm::LLVMGetUndef(Ty.to_ref()); } count_insn(cx, "vaarg"); - return llvm::LLVMBuildVAArg(B(cx), list, Ty, noname()); + return llvm::LLVMBuildVAArg(B(cx), list, Ty.to_ref(), noname()); } } pub fn ExtractElement(cx: block, VecVal: ValueRef, Index: ValueRef) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_nil()); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::nil().to_ref()); } count_insn(cx, "extractelement"); return llvm::LLVMBuildExtractElement(B(cx), VecVal, Index, noname()); } @@ -991,7 +992,7 @@ pub fn ExtractElement(cx: block, VecVal: ValueRef, Index: ValueRef) -> pub fn InsertElement(cx: block, VecVal: ValueRef, EltVal: ValueRef, Index: ValueRef) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_nil()); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::nil().to_ref()); } count_insn(cx, "insertelement"); llvm::LLVMBuildInsertElement(B(cx), VecVal, EltVal, Index, noname()) } @@ -1000,7 +1001,7 @@ pub fn InsertElement(cx: block, VecVal: ValueRef, EltVal: ValueRef, pub fn ShuffleVector(cx: block, V1: ValueRef, V2: ValueRef, Mask: ValueRef) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_nil()); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::nil().to_ref()); } count_insn(cx, "shufflevector"); llvm::LLVMBuildShuffleVector(B(cx), V1, V2, Mask, noname()) } @@ -1008,15 +1009,16 @@ pub fn ShuffleVector(cx: block, V1: ValueRef, V2: ValueRef, pub fn VectorSplat(cx: block, NumElts: uint, EltVal: ValueRef) -> ValueRef { unsafe { - let Undef = llvm::LLVMGetUndef(T_vector(val_ty(EltVal), NumElts)); + let elt_ty = val_ty(EltVal); + let Undef = llvm::LLVMGetUndef(Type::vector(&elt_ty, NumElts as u64).to_ref()); let VecVal = InsertElement(cx, Undef, EltVal, C_i32(0)); - ShuffleVector(cx, VecVal, Undef, C_null(T_vector(T_i32(), NumElts))) + ShuffleVector(cx, VecVal, Undef, C_null(Type::vector(&Type::i32(), NumElts as u64))) } } pub fn ExtractValue(cx: block, AggVal: ValueRef, Index: uint) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_nil()); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::nil().to_ref()); } count_insn(cx, "extractvalue"); return llvm::LLVMBuildExtractValue( B(cx), AggVal, Index as c_uint, noname()); @@ -1035,7 +1037,7 @@ pub fn InsertValue(cx: block, AggVal: ValueRef, EltVal: ValueRef, pub fn IsNull(cx: block, Val: ValueRef) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_i1()); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::i1().to_ref()); } count_insn(cx, "isnull"); return llvm::LLVMBuildIsNull(B(cx), Val, noname()); } @@ -1043,7 +1045,7 @@ pub fn IsNull(cx: block, Val: ValueRef) -> ValueRef { pub fn IsNotNull(cx: block, Val: ValueRef) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(T_i1()); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::i1().to_ref()); } count_insn(cx, "isnotnull"); return llvm::LLVMBuildIsNotNull(B(cx), Val, noname()); } @@ -1052,7 +1054,7 @@ pub fn IsNotNull(cx: block, Val: ValueRef) -> ValueRef { pub fn PtrDiff(cx: block, LHS: ValueRef, RHS: ValueRef) -> ValueRef { unsafe { let ccx = cx.fcx.ccx; - if cx.unreachable { return llvm::LLVMGetUndef(ccx.int_type); } + if cx.unreachable { return llvm::LLVMGetUndef(ccx.int_type.to_ref()); } count_insn(cx, "ptrdiff"); return llvm::LLVMBuildPtrDiff(B(cx), LHS, RHS, noname()); } @@ -1071,19 +1073,18 @@ pub fn Trap(cx: block) { assert!((T as int != 0)); let Args: ~[ValueRef] = ~[]; count_insn(cx, "trap"); - llvm::LLVMBuildCall(b, T, vec::raw::to_ptr(Args), - Args.len() as c_uint, noname()); + llvm::LLVMBuildCall(b, T, vec::raw::to_ptr(Args), Args.len() as c_uint, noname()); } } -pub fn LandingPad(cx: block, Ty: TypeRef, PersFn: ValueRef, +pub fn LandingPad(cx: block, Ty: Type, PersFn: ValueRef, NumClauses: uint) -> ValueRef { unsafe { check_not_terminated(cx); assert!(!cx.unreachable); count_insn(cx, "landingpad"); - return llvm::LLVMBuildLandingPad(B(cx), Ty, PersFn, - NumClauses as c_uint, noname()); + return llvm::LLVMBuildLandingPad( + B(cx), Ty.to_ref(), PersFn, NumClauses as c_uint, noname()); } } diff --git a/src/librustc/middle/trans/cabi.rs b/src/librustc/middle/trans/cabi.rs index ced19ce57ad..4526af2da0f 100644 --- a/src/librustc/middle/trans/cabi.rs +++ b/src/librustc/middle/trans/cabi.rs @@ -8,25 +8,24 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use lib::llvm::{llvm, TypeRef, ValueRef, Attribute, Void}; +use lib::llvm::{llvm, ValueRef, Attribute, Void}; use middle::trans::base::*; use middle::trans::build::*; use middle::trans::common::*; +use middle::trans::type_::Type; + use core::libc::c_uint; use core::option; use core::vec; pub trait ABIInfo { - fn compute_info(&self, - atys: &[TypeRef], - rty: TypeRef, - ret_def: bool) -> FnType; + fn compute_info(&self, atys: &[Type], rty: Type, ret_def: bool) -> FnType; } pub struct LLVMType { cast: bool, - ty: TypeRef + ty: Type } pub struct FnType { @@ -37,10 +36,10 @@ pub struct FnType { } impl FnType { - pub fn decl_fn(&self, decl: &fn(fnty: TypeRef) -> ValueRef) -> ValueRef { + pub fn decl_fn(&self, decl: &fn(fnty: Type) -> ValueRef) -> ValueRef { let atys = vec::map(self.arg_tys, |t| t.ty); let rty = self.ret_ty.ty; - let fnty = T_fn(atys, rty); + let fnty = Type::func(atys, &rty); let llfn = decl(fnty); for self.attrs.iter().enumerate().advance |(i, a)| { @@ -57,10 +56,7 @@ impl FnType { return llfn; } - pub fn build_shim_args(&self, - bcx: block, - arg_tys: &[TypeRef], - llargbundle: ValueRef) + pub fn build_shim_args(&self, bcx: block, arg_tys: &[Type], llargbundle: ValueRef) -> ~[ValueRef] { let mut atys: &[LLVMType] = self.arg_tys; let mut attrs: &[option::Option] = self.attrs; @@ -80,7 +76,7 @@ impl FnType { while i < n { let llargval = if atys[i].cast { let arg_ptr = GEPi(bcx, llargbundle, [0u, i]); - let arg_ptr = BitCast(bcx, arg_ptr, T_ptr(atys[i].ty)); + let arg_ptr = BitCast(bcx, arg_ptr, atys[i].ty.ptr_to()); Load(bcx, arg_ptr) } else if attrs[i].is_some() { GEPi(bcx, llargbundle, [0u, i]) @@ -94,19 +90,13 @@ impl FnType { return llargvals; } - pub fn build_shim_ret(&self, - bcx: block, - arg_tys: &[TypeRef], - ret_def: bool, - llargbundle: ValueRef, - llretval: ValueRef) { + pub fn build_shim_ret(&self, bcx: block, arg_tys: &[Type], ret_def: bool, + llargbundle: ValueRef, llretval: ValueRef) { for self.attrs.iter().enumerate().advance |(i, a)| { match *a { option::Some(attr) => { unsafe { - llvm::LLVMAddInstrAttribute(llretval, - (i + 1u) as c_uint, - attr as c_uint); + llvm::LLVMAddInstrAttribute(llretval, (i + 1u) as c_uint, attr as c_uint); } } _ => () @@ -121,7 +111,7 @@ impl FnType { // R* llretloc = *llretptr; /* (args->r) */ let llretloc = Load(bcx, llretptr); if self.ret_ty.cast { - let tmp_ptr = BitCast(bcx, llretloc, T_ptr(self.ret_ty.ty)); + let tmp_ptr = BitCast(bcx, llretloc, self.ret_ty.ty.ptr_to()); // *args->r = r; Store(bcx, llretval, tmp_ptr); } else { @@ -130,11 +120,8 @@ impl FnType { }; } - pub fn build_wrap_args(&self, - bcx: block, - ret_ty: TypeRef, - llwrapfn: ValueRef, - llargbundle: ValueRef) { + pub fn build_wrap_args(&self, bcx: block, ret_ty: Type, + llwrapfn: ValueRef, llargbundle: ValueRef) { let mut atys: &[LLVMType] = self.arg_tys; let mut attrs: &[option::Option] = self.attrs; let mut j = 0u; @@ -145,7 +132,7 @@ impl FnType { get_param(llwrapfn, 0u) } else if self.ret_ty.cast { let retptr = alloca(bcx, self.ret_ty.ty); - BitCast(bcx, retptr, T_ptr(ret_ty)) + BitCast(bcx, retptr, ret_ty.ptr_to()) } else { alloca(bcx, ret_ty) }; @@ -159,7 +146,7 @@ impl FnType { store_inbounds(bcx, argval, llargbundle, [0u, i]); } else if atys[i].cast { let argptr = GEPi(bcx, llargbundle, [0u, i]); - let argptr = BitCast(bcx, argptr, T_ptr(atys[i].ty)); + let argptr = BitCast(bcx, argptr, atys[i].ty.ptr_to()); Store(bcx, argval, argptr); } else { store_inbounds(bcx, argval, llargbundle, [0u, i]); @@ -169,27 +156,20 @@ impl FnType { store_inbounds(bcx, llretptr, llargbundle, [0u, n]); } - pub fn build_wrap_ret(&self, - bcx: block, - arg_tys: &[TypeRef], - llargbundle: ValueRef) { - unsafe { - if llvm::LLVMGetTypeKind(self.ret_ty.ty) == Void { - return; - } + pub fn build_wrap_ret(&self, bcx: block, arg_tys: &[Type], llargbundle: ValueRef) { + if self.ret_ty.ty.kind() == Void { + return; } if bcx.fcx.llretptr.is_some() { let llretval = load_inbounds(bcx, llargbundle, [ 0, arg_tys.len() ]); let llretval = if self.ret_ty.cast { - let retptr = BitCast(bcx, llretval, T_ptr(self.ret_ty.ty)); + let retptr = BitCast(bcx, llretval, self.ret_ty.ty.ptr_to()); Load(bcx, retptr) } else { Load(bcx, llretval) }; - let llretptr = BitCast(bcx, - bcx.fcx.llretptr.get(), - T_ptr(self.ret_ty.ty)); + let llretptr = BitCast(bcx, bcx.fcx.llretptr.get(), self.ret_ty.ty.ptr_to()); Store(bcx, llretval, llretptr); } } diff --git a/src/librustc/middle/trans/cabi_arm.rs b/src/librustc/middle/trans/cabi_arm.rs index 9ad66c06671..2f4579afe9c 100644 --- a/src/librustc/middle/trans/cabi_arm.rs +++ b/src/librustc/middle/trans/cabi_arm.rs @@ -9,13 +9,10 @@ // except according to those terms. use lib::llvm::{llvm, Integer, Pointer, Float, Double, Struct, Array}; -use lib::llvm::struct_tys; -use lib::llvm::TypeRef; use lib::llvm::{Attribute, StructRetAttribute}; -use lib::llvm::True; use middle::trans::cabi::{ABIInfo, FnType, LLVMType}; -use middle::trans::common::{T_i8, T_i16, T_i32, T_i64}; -use middle::trans::common::{T_array, T_ptr, T_void}; + +use middle::trans::type_::Type; use core::option::{Option, None, Some}; use core::uint; @@ -24,108 +21,106 @@ fn align_up_to(off: uint, a: uint) -> uint { return (off + a - 1u) / a * a; } -fn align(off: uint, ty: TypeRef) -> uint { +fn align(off: uint, ty: Type) -> uint { let a = ty_align(ty); return align_up_to(off, a); } -fn ty_align(ty: TypeRef) -> uint { - unsafe { - return match llvm::LLVMGetTypeKind(ty) { - Integer => { - ((llvm::LLVMGetIntTypeWidth(ty) as uint) + 7) / 8 +fn ty_align(ty: Type) -> uint { + match ty.kind() { + Integer => { + unsafe { + ((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8 } - Pointer => 4, - Float => 4, - Double => 8, - Struct => { - if llvm::LLVMIsPackedStruct(ty) == True { - 1 - } else { - let str_tys = struct_tys(ty); - str_tys.iter().fold(1, |a, t| uint::max(a, ty_align(*t))) - } + } + Pointer => 4, + Float => 4, + Double => 8, + Struct => { + if ty.is_packed() { + 1 + } else { + let str_tys = ty.field_types(); + str_tys.iter().fold(1, |a, t| uint::max(a, ty_align(*t))) } - Array => { - let elt = llvm::LLVMGetElementType(ty); - ty_align(elt) - } - _ => fail!("ty_align: unhandled type") - }; + } + Array => { + let elt = ty.element_type(); + ty_align(elt) + } + _ => fail!("ty_align: unhandled type") } } -fn ty_size(ty: TypeRef) -> uint { - unsafe { - return match llvm::LLVMGetTypeKind(ty) { - Integer => { - ((llvm::LLVMGetIntTypeWidth(ty) as uint) + 7) / 8 +fn ty_size(ty: Type) -> uint { + match ty.kind() { + Integer => { + unsafe { + ((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8 } - Pointer => 4, - Float => 4, - Double => 8, - Struct => { - if llvm::LLVMIsPackedStruct(ty) == True { - let str_tys = struct_tys(ty); - str_tys.iter().fold(0, |s, t| s + ty_size(*t)) - } else { - let str_tys = struct_tys(ty); - let size = str_tys.iter().fold(0, |s, t| align(s, *t) + ty_size(*t)); - align(size, ty) - } + } + Pointer => 4, + Float => 4, + Double => 8, + Struct => { + if ty.is_packed() { + let str_tys = ty.field_types(); + str_tys.iter().fold(0, |s, t| s + ty_size(*t)) + } else { + let str_tys = ty.field_types(); + let size = str_tys.iter().fold(0, |s, t| align(s, *t) + ty_size(*t)); + align(size, ty) } - Array => { - let len = llvm::LLVMGetArrayLength(ty) as uint; - let elt = llvm::LLVMGetElementType(ty); - let eltsz = ty_size(elt); - len * eltsz - } - _ => fail!("ty_size: unhandled type") - }; + } + Array => { + let len = ty.array_length(); + let elt = ty.element_type(); + let eltsz = ty_size(elt); + len * eltsz + } + _ => fail!("ty_size: unhandled type") } } -fn classify_ret_ty(ty: TypeRef) -> (LLVMType, Option) { +fn classify_ret_ty(ty: Type) -> (LLVMType, Option) { if is_reg_ty(ty) { return (LLVMType { cast: false, ty: ty }, None); } let size = ty_size(ty); if size <= 4 { let llty = if size <= 1 { - T_i8() + Type::i8() } else if size <= 2 { - T_i16() + Type::i16() } else { - T_i32() + Type::i32() }; return (LLVMType { cast: true, ty: llty }, None); } - (LLVMType { cast: false, ty: T_ptr(ty) }, Some(StructRetAttribute)) + (LLVMType { cast: false, ty: ty.ptr_to() }, Some(StructRetAttribute)) } -fn classify_arg_ty(ty: TypeRef) -> (LLVMType, Option) { +fn classify_arg_ty(ty: Type) -> (LLVMType, Option) { if is_reg_ty(ty) { return (LLVMType { cast: false, ty: ty }, None); } let align = ty_align(ty); let size = ty_size(ty); let llty = if align <= 4 { - T_array(T_i32(), (size + 3) / 4) + Type::array(&Type::i32(), (size + 3) / 4 as u64) } else { - T_array(T_i64(), (size + 7) / 8) + Type::array(&Type::i64(), (size + 7) / 8 as u64) }; (LLVMType { cast: true, ty: llty }, None) } -fn is_reg_ty(ty: TypeRef) -> bool { - unsafe { - return match llvm::LLVMGetTypeKind(ty) { - Integer - | Pointer - | Float - | Double => true, - _ => false - }; +fn is_reg_ty(ty: Type) -> bool { + match ty.kind() { + Integer + | Pointer + | Float + | Double => true, + _ => false } } @@ -133,8 +128,8 @@ enum ARM_ABIInfo { ARM_ABIInfo } impl ABIInfo for ARM_ABIInfo { fn compute_info(&self, - atys: &[TypeRef], - rty: TypeRef, + atys: &[Type], + rty: Type, ret_def: bool) -> FnType { let mut arg_tys = ~[]; let mut attrs = ~[]; @@ -147,14 +142,14 @@ impl ABIInfo for ARM_ABIInfo { let mut (ret_ty, ret_attr) = if ret_def { classify_ret_ty(rty) } else { - (LLVMType { cast: false, ty: T_void() }, None) + (LLVMType { cast: false, ty: Type::void() }, None) }; let sret = ret_attr.is_some(); if sret { arg_tys.unshift(ret_ty); attrs.unshift(ret_attr); - ret_ty = LLVMType { cast: false, ty: T_void() }; + ret_ty = LLVMType { cast: false, ty: Type::void() }; } return FnType { diff --git a/src/librustc/middle/trans/cabi_mips.rs b/src/librustc/middle/trans/cabi_mips.rs index 0c771d21da5..ab5296b0c7a 100644 --- a/src/librustc/middle/trans/cabi_mips.rs +++ b/src/librustc/middle/trans/cabi_mips.rs @@ -11,104 +11,89 @@ use core::prelude::*; use core::libc::c_uint; -use core::ptr; use core::uint; use core::vec; -use lib::llvm::{llvm, TypeRef, Integer, Pointer, Float, Double}; -use lib::llvm::{Struct, Array, Attribute}; -use lib::llvm::{StructRetAttribute}; -use lib::llvm::True; +use lib::llvm::{llvm, Integer, Pointer, Float, Double, Struct, Array}; +use lib::llvm::{Attribute, StructRetAttribute}; use middle::trans::context::task_llcx; -use middle::trans::common::*; use middle::trans::cabi::*; +use middle::trans::type_::Type; + fn align_up_to(off: uint, a: uint) -> uint { return (off + a - 1u) / a * a; } -fn align(off: uint, ty: TypeRef) -> uint { +fn align(off: uint, ty: Type) -> uint { let a = ty_align(ty); return align_up_to(off, a); } -fn struct_tys(ty: TypeRef) -> ~[TypeRef] { - unsafe { - let n = llvm::LLVMCountStructElementTypes(ty); - if (n == 0) { - return ~[]; - } - let mut elts = vec::from_elem(n as uint, ptr::null()); - llvm::LLVMGetStructElementTypes(ty, &mut elts[0]); - return elts; +fn ty_align(ty: Type) -> uint { + match ty.kind() { + Integer => { + unsafe { + ((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8 + } + } + Pointer => 4, + Float => 4, + Double => 8, + Struct => { + if ty.is_packed() { + 1 + } else { + let str_tys = ty.field_types(); + str_tys.iter().fold(1, |a, t| uint::max(a, ty_align(*t))) + } + } + Array => { + let elt = ty.element_type(); + ty_align(elt) + } + _ => fail!("ty_size: unhandled type") } } -fn ty_align(ty: TypeRef) -> uint { - unsafe { - return match llvm::LLVMGetTypeKind(ty) { - Integer => { - ((llvm::LLVMGetIntTypeWidth(ty) as uint) + 7) / 8 +fn ty_size(ty: Type) -> uint { + match ty.kind() { + Integer => { + unsafe { + ((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8 } - Pointer => 4, - Float => 4, - Double => 8, - Struct => { - if llvm::LLVMIsPackedStruct(ty) == True { - 1 - } else { - let str_tys = struct_tys(ty); - str_tys.iter().fold(1, |a, t| uint::max(a, ty_align(*t))) - } + } + Pointer => 4, + Float => 4, + Double => 8, + Struct => { + if ty.is_packed() { + let str_tys = ty.field_types(); + str_tys.iter().fold(0, |s, t| s + ty_size(*t)) + } else { + let str_tys = ty.field_types(); + let size = str_tys.iter().fold(0, |s, t| align(s, *t) + ty_size(*t)); + align(size, ty) } - Array => { - let elt = llvm::LLVMGetElementType(ty); - ty_align(elt) - } - _ => fail!("ty_size: unhandled type") - }; + } + Array => { + let len = ty.array_length(); + let elt = ty.element_type(); + let eltsz = ty_size(elt); + len * eltsz + } + _ => fail!("ty_size: unhandled type") } } -fn ty_size(ty: TypeRef) -> uint { - unsafe { - return match llvm::LLVMGetTypeKind(ty) { - Integer => { - ((llvm::LLVMGetIntTypeWidth(ty) as uint) + 7) / 8 - } - Pointer => 4, - Float => 4, - Double => 8, - Struct => { - if llvm::LLVMIsPackedStruct(ty) == True { - let str_tys = struct_tys(ty); - str_tys.iter().fold(0, |s, t| s + ty_size(*t)) - } else { - let str_tys = struct_tys(ty); - let size = str_tys.iter().fold(0, |s, t| align(s, *t) + ty_size(*t)); - align(size, ty) - } - } - Array => { - let len = llvm::LLVMGetArrayLength(ty) as uint; - let elt = llvm::LLVMGetElementType(ty); - let eltsz = ty_size(elt); - len * eltsz - } - _ => fail!("ty_size: unhandled type") - }; - } -} - -fn classify_ret_ty(ty: TypeRef) -> (LLVMType, Option) { +fn classify_ret_ty(ty: Type) -> (LLVMType, Option) { return if is_reg_ty(ty) { (LLVMType { cast: false, ty: ty }, None) } else { - (LLVMType { cast: false, ty: T_ptr(ty) }, Some(StructRetAttribute)) + (LLVMType { cast: false, ty: ty.ptr_to() }, Some(StructRetAttribute)) }; } -fn classify_arg_ty(ty: TypeRef, - offset: &mut uint) -> (LLVMType, Option) { +fn classify_arg_ty(ty: Type, offset: &mut uint) -> (LLVMType, Option) { let orig_offset = *offset; let size = ty_size(ty) * 8; let mut align = ty_align(ty); @@ -133,28 +118,26 @@ fn classify_arg_ty(ty: TypeRef, }; } -fn is_reg_ty(ty: TypeRef) -> bool { - unsafe { - return match llvm::LLVMGetTypeKind(ty) { - Integer - | Pointer - | Float - | Double => true, - _ => false - }; - } +fn is_reg_ty(ty: Type) -> bool { + return match ty.kind() { + Integer + | Pointer + | Float + | Double => true, + _ => false + }; } -fn padding_ty(align: uint, offset: uint) -> Option { +fn padding_ty(align: uint, offset: uint) -> Option { if ((align - 1 ) & offset) > 0 { - return Some(T_i32()); + return Some(Type::i32()); } return None; } -fn coerce_to_int(size: uint) -> ~[TypeRef] { - let int_ty = T_i32(); +fn coerce_to_int(size: uint) -> ~[Type] { + let int_ty = Type::i32(); let mut args = ~[]; let mut n = size / 32; @@ -166,16 +149,16 @@ fn coerce_to_int(size: uint) -> ~[TypeRef] { let r = size % 32; if r > 0 { unsafe { - args.push(llvm::LLVMIntTypeInContext(task_llcx(), r as c_uint)) + args.push(Type::from_ref(llvm::LLVMIntTypeInContext(task_llcx(), r as c_uint))); } } - return args; + args } -fn struct_ty(ty: TypeRef, - padding: Option, - coerce: bool) -> TypeRef { +fn struct_ty(ty: Type, + padding: Option, + coerce: bool) -> Type { let size = ty_size(ty) * 8; let mut fields = padding.map_default(~[], |p| ~[*p]); @@ -185,20 +168,20 @@ fn struct_ty(ty: TypeRef, fields.push(ty); } - return T_struct(fields, false); + return Type::struct_(fields, false); } enum MIPS_ABIInfo { MIPS_ABIInfo } impl ABIInfo for MIPS_ABIInfo { fn compute_info(&self, - atys: &[TypeRef], - rty: TypeRef, + atys: &[Type], + rty: Type, ret_def: bool) -> FnType { let mut (ret_ty, ret_attr) = if ret_def { classify_ret_ty(rty) } else { - (LLVMType { cast: false, ty: T_void() }, None) + (LLVMType { cast: false, ty: Type::void() }, None) }; let sret = ret_attr.is_some(); @@ -215,7 +198,7 @@ impl ABIInfo for MIPS_ABIInfo { if sret { arg_tys = vec::append(~[ret_ty], arg_tys); attrs = vec::append(~[ret_attr], attrs); - ret_ty = LLVMType { cast: false, ty: T_void() }; + ret_ty = LLVMType { cast: false, ty: Type::void() }; } return FnType { diff --git a/src/librustc/middle/trans/cabi_x86.rs b/src/librustc/middle/trans/cabi_x86.rs index da7c0d5272d..8131fd009ee 100644 --- a/src/librustc/middle/trans/cabi_x86.rs +++ b/src/librustc/middle/trans/cabi_x86.rs @@ -12,19 +12,20 @@ use core::prelude::*; use driver::session::{os_win32, os_macos}; use lib::llvm::*; -use lib::llvm::llvm::*; use super::cabi::*; use super::common::*; use super::machine::*; +use middle::trans::type_::Type; + struct X86_ABIInfo { ccx: @mut CrateContext } impl ABIInfo for X86_ABIInfo { fn compute_info(&self, - atys: &[TypeRef], - rty: TypeRef, + atys: &[Type], + rty: Type, ret_def: bool) -> FnType { let mut arg_tys = do atys.map |a| { LLVMType { cast: false, ty: *a } @@ -41,7 +42,7 @@ impl ABIInfo for X86_ABIInfo { // http://www.angelcode.com/dev/callconv/callconv.html // Clang's ABI handling is in lib/CodeGen/TargetInfo.cpp let sret = { - let returning_a_struct = unsafe { LLVMGetTypeKind(rty) == Struct && ret_def }; + let returning_a_struct = rty.kind() == Struct && ret_def; let big_struct = match self.ccx.sess.targ_cfg.os { os_win32 | os_macos => llsize_of_alloc(self.ccx, rty) > 8, _ => true @@ -52,18 +53,18 @@ impl ABIInfo for X86_ABIInfo { if sret { let ret_ptr_ty = LLVMType { cast: false, - ty: T_ptr(ret_ty.ty) + ty: ret_ty.ty.ptr_to() }; arg_tys = ~[ret_ptr_ty] + arg_tys; attrs = ~[Some(StructRetAttribute)] + attrs; ret_ty = LLVMType { cast: false, - ty: T_void(), + ty: Type::void(), }; } else if !ret_def { ret_ty = LLVMType { cast: false, - ty: T_void() + ty: Type::void() }; } diff --git a/src/librustc/middle/trans/cabi_x86_64.rs b/src/librustc/middle/trans/cabi_x86_64.rs index 3ff54e9d3d8..4a92b940190 100644 --- a/src/librustc/middle/trans/cabi_x86_64.rs +++ b/src/librustc/middle/trans/cabi_x86_64.rs @@ -11,151 +11,169 @@ // The classification code for the x86_64 ABI is taken from the clay language // https://github.com/jckarter/clay/blob/master/compiler/src/externals.cpp -use lib::llvm::{llvm, TypeRef, Integer, Pointer, Float, Double}; +use lib::llvm::{llvm, Integer, Pointer, Float, Double}; use lib::llvm::{Struct, Array, Attribute}; use lib::llvm::{StructRetAttribute, ByValAttribute}; -use lib::llvm::struct_tys; -use lib::llvm::True; -use middle::trans::common::*; use middle::trans::cabi::*; -use core::libc::c_uint; +use middle::trans::type_::Type; + use core::option; use core::option::Option; use core::uint; use core::vec; #[deriving(Eq)] -enum x86_64_reg_class { - no_class, - integer_class, - sse_fs_class, - sse_fv_class, - sse_ds_class, - sse_dv_class, - sse_int_class, - sseup_class, - x87_class, - x87up_class, - complex_x87_class, - memory_class +enum RegClass { + NoClass, + Int, + SSEFs, + SSEFv, + SSEDs, + SSEDv, + SSEInt, + SSEUp, + X87, + X87Up, + ComplexX87, + Memory } -fn is_sse(c: x86_64_reg_class) -> bool { - return match c { - sse_fs_class | sse_fv_class | - sse_ds_class | sse_dv_class => true, - _ => false - }; +impl Type { + fn is_reg_ty(&self) -> bool { + match self.kind() { + Integer | Pointer | Float | Double => true, + _ => false + } + } } -fn is_ymm(cls: &[x86_64_reg_class]) -> bool { - let len = cls.len(); - return (len > 2u && - is_sse(cls[0]) && - cls[1] == sseup_class && - cls[2] == sseup_class) || - (len > 3u && - is_sse(cls[1]) && - cls[2] == sseup_class && - cls[3] == sseup_class); +impl RegClass { + fn is_sse(&self) -> bool { + match *self { + SSEFs | SSEFv | SSEDs | SSEDv => true, + _ => false + } + } } -fn classify_ty(ty: TypeRef) -> ~[x86_64_reg_class] { - fn align(off: uint, ty: TypeRef) -> uint { +trait ClassList { + fn is_pass_byval(&self) -> bool; + fn is_ret_bysret(&self) -> bool; +} + +impl<'self> ClassList for &'self [RegClass] { + fn is_pass_byval(&self) -> bool { + if self.len() == 0 { return false; } + + let class = self[0]; + class == Memory + || class == X87 + || class == ComplexX87 + } + + fn is_ret_bysret(&self) -> bool { + if self.len() == 0 { return false; } + + self[0] == Memory + } +} + +fn classify_ty(ty: Type) -> ~[RegClass] { + fn align(off: uint, ty: Type) -> uint { let a = ty_align(ty); return (off + a - 1u) / a * a; } - fn ty_align(ty: TypeRef) -> uint { - unsafe { - return match llvm::LLVMGetTypeKind(ty) { - Integer => { - ((llvm::LLVMGetIntTypeWidth(ty) as uint) + 7) / 8 + fn ty_align(ty: Type) -> uint { + match ty.kind() { + Integer => { + unsafe { + ((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8 } - Pointer => 8, - Float => 4, - Double => 8, - Struct => { - if llvm::LLVMIsPackedStruct(ty) == True { - 1 - } else { - let str_tys = struct_tys(ty); - str_tys.iter().fold(1, |a, t| uint::max(a, ty_align(*t))) - } - } - Array => { - let elt = llvm::LLVMGetElementType(ty); - ty_align(elt) - } - _ => fail!("ty_size: unhandled type") - }; + } + Pointer => 8, + Float => 4, + Double => 8, + Struct => { + if ty.is_packed() { + 1 + } else { + let str_tys = ty.field_types(); + str_tys.iter().fold(1, |a, t| uint::max(a, ty_align(*t))) + } + } + Array => { + let elt = ty.element_type(); + ty_align(elt) + } + _ => fail!("ty_size: unhandled type") } } - fn ty_size(ty: TypeRef) -> uint { - unsafe { - return match llvm::LLVMGetTypeKind(ty) { - Integer => { - ((llvm::LLVMGetIntTypeWidth(ty) as uint) + 7) / 8 + fn ty_size(ty: Type) -> uint { + match ty.kind() { + Integer => { + unsafe { + ((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8 } - Pointer => 8, - Float => 4, - Double => 8, - Struct => { - if llvm::LLVMIsPackedStruct(ty) == True { - let str_tys = struct_tys(ty); - str_tys.iter().fold(0, |s, t| s + ty_size(*t)) - } else { - let str_tys = struct_tys(ty); - let size = str_tys.iter().fold(0, |s, t| align(s, *t) + ty_size(*t)); - align(size, ty) - } + } + Pointer => 8, + Float => 4, + Double => 8, + Struct => { + if ty.is_packed() { + let str_tys = ty.field_types(); + str_tys.iter().fold(0, |s, t| s + ty_size(*t)) + } else { + let str_tys = ty.field_types(); + let size = str_tys.iter().fold(0, |s, t| align(s, *t) + ty_size(*t)); + align(size, ty) } - Array => { - let len = llvm::LLVMGetArrayLength(ty) as uint; - let elt = llvm::LLVMGetElementType(ty); - let eltsz = ty_size(elt); - len * eltsz - } - _ => fail!("ty_size: unhandled type") - }; + } + Array => { + let len = ty.array_length(); + let elt = ty.element_type(); + let eltsz = ty_size(elt); + len * eltsz + } + _ => fail!("ty_size: unhandled type") } } - fn all_mem(cls: &mut [x86_64_reg_class]) { + fn all_mem(cls: &mut [RegClass]) { for uint::range(0, cls.len()) |i| { - cls[i] = memory_class; + cls[i] = Memory; } } - fn unify(cls: &mut [x86_64_reg_class], + fn unify(cls: &mut [RegClass], i: uint, - newv: x86_64_reg_class) { + newv: RegClass) { if cls[i] == newv { return; - } else if cls[i] == no_class { + } else if cls[i] == NoClass { cls[i] = newv; - } else if newv == no_class { + } else if newv == NoClass { return; - } else if cls[i] == memory_class || newv == memory_class { - cls[i] = memory_class; - } else if cls[i] == integer_class || newv == integer_class { - cls[i] = integer_class; - } else if cls[i] == x87_class || - cls[i] == x87up_class || - cls[i] == complex_x87_class || - newv == x87_class || - newv == x87up_class || - newv == complex_x87_class { - cls[i] = memory_class; + } else if cls[i] == Memory || newv == Memory { + cls[i] = Memory; + } else if cls[i] == Int || newv == Int { + cls[i] = Int; + } else if cls[i] == X87 || + cls[i] == X87Up || + cls[i] == ComplexX87 || + newv == X87 || + newv == X87Up || + newv == ComplexX87 { + cls[i] = Memory; } else { cls[i] = newv; } } - fn classify_struct(tys: &[TypeRef], - cls: &mut [x86_64_reg_class], i: uint, + fn classify_struct(tys: &[Type], + cls: &mut [RegClass], i: uint, off: uint) { let mut field_off = off; for tys.each |ty| { @@ -165,108 +183,104 @@ fn classify_ty(ty: TypeRef) -> ~[x86_64_reg_class] { } } - fn classify(ty: TypeRef, - cls: &mut [x86_64_reg_class], ix: uint, + fn classify(ty: Type, + cls: &mut [RegClass], ix: uint, off: uint) { - unsafe { - let t_align = ty_align(ty); - let t_size = ty_size(ty); + let t_align = ty_align(ty); + let t_size = ty_size(ty); - let misalign = off % t_align; - if misalign != 0u { - let mut i = off / 8u; - let e = (off + t_size + 7u) / 8u; - while i < e { - unify(cls, ix + i, memory_class); + let misalign = off % t_align; + if misalign != 0u { + let mut i = off / 8u; + let e = (off + t_size + 7u) / 8u; + while i < e { + unify(cls, ix + i, Memory); + i += 1u; + } + return; + } + + match ty.kind() { + Integer | + Pointer => { + unify(cls, ix + off / 8u, Int); + } + Float => { + if off % 8u == 4u { + unify(cls, ix + off / 8u, SSEFv); + } else { + unify(cls, ix + off / 8u, SSEFs); + } + } + Double => { + unify(cls, ix + off / 8u, SSEDs); + } + Struct => { + classify_struct(ty.field_types(), cls, ix, off); + } + Array => { + let len = ty.array_length(); + let elt = ty.element_type(); + let eltsz = ty_size(elt); + let mut i = 0u; + while i < len { + classify(elt, cls, ix, off + i * eltsz); i += 1u; } - return; - } - - match llvm::LLVMGetTypeKind(ty) as int { - 8 /* integer */ | - 12 /* pointer */ => { - unify(cls, ix + off / 8u, integer_class); - } - 2 /* float */ => { - if off % 8u == 4u { - unify(cls, ix + off / 8u, sse_fv_class); - } else { - unify(cls, ix + off / 8u, sse_fs_class); - } - } - 3 /* double */ => { - unify(cls, ix + off / 8u, sse_ds_class); - } - 10 /* struct */ => { - classify_struct(struct_tys(ty), cls, ix, off); - } - 11 /* array */ => { - let elt = llvm::LLVMGetElementType(ty); - let eltsz = ty_size(elt); - let len = llvm::LLVMGetArrayLength(ty) as uint; - let mut i = 0u; - while i < len { - classify(elt, cls, ix, off + i * eltsz); - i += 1u; - } - } - _ => fail!("classify: unhandled type") } + _ => fail!("classify: unhandled type") } } - fn fixup(ty: TypeRef, cls: &mut [x86_64_reg_class]) { - unsafe { - let mut i = 0u; - let llty = llvm::LLVMGetTypeKind(ty) as int; - let e = cls.len(); - if cls.len() > 2u && - (llty == 10 /* struct */ || - llty == 11 /* array */) { - if is_sse(cls[i]) { - i += 1u; - while i < e { - if cls[i] != sseup_class { - all_mem(cls); - return; - } - i += 1u; + fn fixup(ty: Type, cls: &mut [RegClass]) { + let mut i = 0u; + let ty_kind = ty.kind(); + let e = cls.len(); + if cls.len() > 2u && + (ty_kind == Struct || + ty_kind == Array) { + if cls[i].is_sse() { + i += 1u; + while i < e { + if cls[i] != SSEUp { + all_mem(cls); + return; } - } else { - all_mem(cls); - return + i += 1u; } } else { - while i < e { - if cls[i] == memory_class { - all_mem(cls); - return; - } - if cls[i] == x87up_class { - // for darwin - // cls[i] = sse_ds_class; - all_mem(cls); - return; - } - if cls[i] == sseup_class { - cls[i] = sse_int_class; - } else if is_sse(cls[i]) { - i += 1; - while i != e && cls[i] == sseup_class { i += 1u; } - } else if cls[i] == x87_class { - i += 1; - while i != e && cls[i] == x87up_class { i += 1u; } - } else { - i += 1; - } + all_mem(cls); + return + } + } else { + while i < e { + if cls[i] == Memory { + all_mem(cls); + return; + } + if cls[i] == X87Up { + // for darwin + // cls[i] = SSEDs; + all_mem(cls); + return; + } + if cls[i] == SSEUp { + cls[i] = SSEInt; + } else if cls[i].is_sse() { + i += 1; + while i != e && cls[i] == SSEUp { i += 1u; } + } else if cls[i] == X87 { + i += 1; + while i != e && cls[i] == X87Up { i += 1u; } + } else { + i += 1; } } } } let words = (ty_size(ty) + 7) / 8; - let mut cls = vec::from_elem(words, no_class); + let mut cls = vec::from_elem(words, NoClass); if words > 4 { all_mem(cls); let cls = cls; @@ -277,11 +291,11 @@ fn classify_ty(ty: TypeRef) -> ~[x86_64_reg_class] { return cls; } -fn llreg_ty(cls: &[x86_64_reg_class]) -> TypeRef { - fn llvec_len(cls: &[x86_64_reg_class]) -> uint { +fn llreg_ty(cls: &[RegClass]) -> Type { + fn llvec_len(cls: &[RegClass]) -> uint { let mut len = 1u; for cls.each |c| { - if *c != sseup_class { + if *c != SSEUp { break; } len += 1u; @@ -289,103 +303,77 @@ fn llreg_ty(cls: &[x86_64_reg_class]) -> TypeRef { return len; } - unsafe { - let mut tys = ~[]; - let mut i = 0u; - let e = cls.len(); - while i < e { - match cls[i] { - integer_class => { - tys.push(T_i64()); - } - sse_fv_class => { - let vec_len = llvec_len(vec::tailn(cls, i + 1u)) * 2u; - let vec_ty = llvm::LLVMVectorType(T_f32(), - vec_len as c_uint); - tys.push(vec_ty); - i += vec_len; - loop; - } - sse_fs_class => { - tys.push(T_f32()); - } - sse_ds_class => { - tys.push(T_f64()); - } - _ => fail!("llregtype: unhandled class") + let mut tys = ~[]; + let mut i = 0u; + let e = cls.len(); + while i < e { + match cls[i] { + Int => { + tys.push(Type::i64()); } - i += 1u; + SSEFv => { + let vec_len = llvec_len(vec::tailn(cls, i + 1u)) * 2u; + let vec_ty = Type::vector(&Type::f32(), vec_len as u64); + tys.push(vec_ty); + i += vec_len; + loop; + } + SSEFs => { + tys.push(Type::f32()); + } + SSEDs => { + tys.push(Type::f64()); + } + _ => fail!("llregtype: unhandled class") } - return T_struct(tys, false); + i += 1u; } + return Type::struct_(tys, false); } -fn x86_64_tys(atys: &[TypeRef], - rty: TypeRef, +fn x86_64_tys(atys: &[Type], + rty: Type, ret_def: bool) -> FnType { - fn is_reg_ty(ty: TypeRef) -> bool { - unsafe { - return match llvm::LLVMGetTypeKind(ty) as int { - 8 /* integer */ | - 12 /* pointer */ | - 2 /* float */ | - 3 /* double */ => true, - _ => false - }; - } - } - fn is_pass_byval(cls: &[x86_64_reg_class]) -> bool { - return cls.len() > 0 && - (cls[0] == memory_class || - cls[0] == x87_class || - cls[0] == complex_x87_class); - } - - fn is_ret_bysret(cls: &[x86_64_reg_class]) -> bool { - return cls.len() > 0 && cls[0] == memory_class; - } - - fn x86_64_ty(ty: TypeRef, - is_mem_cls: &fn(cls: &[x86_64_reg_class]) -> bool, + fn x86_64_ty(ty: Type, + is_mem_cls: &fn(cls: &[RegClass]) -> bool, attr: Attribute) -> (LLVMType, Option) { - let mut cast = false; - let mut ty_attr = option::None; - let mut llty = ty; - if !is_reg_ty(ty) { + + let (cast, attr, ty) = if !ty.is_reg_ty() { let cls = classify_ty(ty); if is_mem_cls(cls) { - llty = T_ptr(ty); - ty_attr = option::Some(attr); + (false, option::Some(attr), ty.ptr_to()) } else { - cast = true; - llty = llreg_ty(cls); + (true, option::None, llreg_ty(cls)) } - } - return (LLVMType { cast: cast, ty: llty }, ty_attr); + } else { + (false, option::None, ty) + }; + + (LLVMType { cast: cast, ty: ty }, attr) } let mut arg_tys = ~[]; let mut attrs = ~[]; for atys.each |t| { - let (ty, attr) = x86_64_ty(*t, is_pass_byval, ByValAttribute); + let (ty, attr) = x86_64_ty(*t, |cls| cls.is_pass_byval(), ByValAttribute); arg_tys.push(ty); attrs.push(attr); } - let mut (ret_ty, ret_attr) = x86_64_ty(rty, is_ret_bysret, + let mut (ret_ty, ret_attr) = x86_64_ty(rty, |cls| cls.is_ret_bysret(), StructRetAttribute); let sret = ret_attr.is_some(); if sret { arg_tys = vec::append(~[ret_ty], arg_tys); ret_ty = LLVMType { cast: false, - ty: T_void() + ty: Type::void() }; attrs = vec::append(~[ret_attr], attrs); } else if !ret_def { ret_ty = LLVMType { cast: false, - ty: T_void() + ty: Type::void() }; } return FnType { @@ -400,8 +388,8 @@ enum X86_64_ABIInfo { X86_64_ABIInfo } impl ABIInfo for X86_64_ABIInfo { fn compute_info(&self, - atys: &[TypeRef], - rty: TypeRef, + atys: &[Type], + rty: Type, ret_def: bool) -> FnType { return x86_64_tys(atys, rty, ret_def); } diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 7666684f257..0809b1c124e 100644 --- a/src/librustc/middle/trans/callee.rs +++ b/src/librustc/middle/trans/callee.rs @@ -45,6 +45,8 @@ use middle::typeck; use middle::typeck::coherence::make_substs_for_receiver_types; use util::ppaux::Repr; +use middle::trans::type_::Type; + use core::vec; use syntax::ast; use syntax::ast_map; @@ -76,7 +78,7 @@ pub struct Callee { } pub fn trans(bcx: block, expr: @ast::expr) -> Callee { - let _icx = bcx.insn_ctxt("trans_callee"); + let _icx = push_ctxt("trans_callee"); debug!("callee::trans(expr=%s)", expr.repr(bcx.tcx())); // pick out special kinds of expressions that can be called: @@ -170,7 +172,7 @@ pub fn trans_fn_ref(bcx: block, * with id `def_id` into a function pointer. This may require * monomorphization or inlining. */ - let _icx = bcx.insn_ctxt("trans_fn_ref"); + let _icx = push_ctxt("trans_fn_ref"); let type_params = node_id_type_params(bcx, ref_id); let vtables = node_vtables(bcx, ref_id); @@ -214,7 +216,7 @@ pub fn trans_fn_ref_with_vtables( // - `type_params`: values for each of the fn/method's type parameters // - `vtables`: values for each bound on each of the type parameters - let _icx = bcx.insn_ctxt("trans_fn_ref_with_vtables"); + let _icx = push_ctxt("trans_fn_ref_with_vtables"); let ccx = bcx.ccx(); let tcx = ccx.tcx; @@ -326,7 +328,7 @@ pub fn trans_fn_ref_with_vtables( let ref_ty = common::node_id_type(bcx, ref_id); val = PointerCast( - bcx, val, T_ptr(type_of::type_of_fn_from_ty(ccx, ref_ty))); + bcx, val, type_of::type_of_fn_from_ty(ccx, ref_ty).ptr_to()); } return FnData {llfn: val}; } @@ -355,7 +357,7 @@ pub fn trans_call(in_cx: block, id: ast::node_id, dest: expr::Dest) -> block { - let _icx = in_cx.insn_ctxt("trans_call"); + let _icx = push_ctxt("trans_call"); trans_call_inner(in_cx, call_ex.info(), expr_ty(in_cx, f), @@ -373,7 +375,7 @@ pub fn trans_method_call(in_cx: block, args: CallArgs, dest: expr::Dest) -> block { - let _icx = in_cx.insn_ctxt("trans_method_call"); + let _icx = push_ctxt("trans_method_call"); debug!("trans_method_call(call_ex=%s, rcvr=%s)", call_ex.repr(in_cx.tcx()), rcvr.repr(in_cx.tcx())); @@ -516,7 +518,7 @@ pub fn trans_call_inner(in_cx: block, let mut bcx = callee.bcx; let ccx = cx.ccx(); let ret_flag = if ret_in_loop { - let flag = alloca(bcx, T_bool()); + let flag = alloca(bcx, Type::bool()); Store(bcx, C_bool(false), flag); Some(flag) } else { @@ -526,13 +528,13 @@ pub fn trans_call_inner(in_cx: block, let (llfn, llenv) = unsafe { match callee.data { Fn(d) => { - (d.llfn, llvm::LLVMGetUndef(T_opaque_box_ptr(ccx))) + (d.llfn, llvm::LLVMGetUndef(Type::opaque_box(ccx).ptr_to().to_ref())) } Method(d) => { // Weird but true: we pass self in the *environment* slot! let llself = PointerCast(bcx, d.llself, - T_opaque_box_ptr(ccx)); + Type::opaque_box(ccx).ptr_to()); (d.llfn, llself) } Closure(d) => { @@ -572,9 +574,9 @@ pub fn trans_call_inner(in_cx: block, // Uncomment this to debug calls. /* - io::println(fmt!("calling: %s", bcx.val_str(llfn))); + io::println(fmt!("calling: %s", bcx.val_to_str(llfn))); for llargs.each |llarg| { - io::println(fmt!("arg: %s", bcx.val_str(*llarg))); + io::println(fmt!("arg: %s", bcx.val_to_str(*llarg))); } io::println("---"); */ @@ -653,7 +655,7 @@ pub fn trans_ret_slot(bcx: block, fn_ty: ty::t, dest: expr::Dest) expr::Ignore => { if ty::type_is_nil(retty) { unsafe { - llvm::LLVMGetUndef(T_ptr(T_nil())) + llvm::LLVMGetUndef(Type::nil().ptr_to().to_ref()) } } else { alloc_ty(bcx, retty) @@ -669,7 +671,7 @@ pub fn trans_args(cx: block, autoref_arg: AutorefArg, llargs: &mut ~[ValueRef]) -> block { - let _icx = cx.insn_ctxt("trans_args"); + let _icx = push_ctxt("trans_args"); let mut temp_cleanups = ~[]; let arg_tys = ty::ty_fn_args(fn_ty); @@ -723,7 +725,7 @@ pub fn trans_arg_expr(bcx: block, temp_cleanups: &mut ~[ValueRef], ret_flag: Option, autoref_arg: AutorefArg) -> Result { - let _icx = bcx.insn_ctxt("trans_arg_expr"); + let _icx = push_ctxt("trans_arg_expr"); let ccx = bcx.ccx(); debug!("trans_arg_expr(formal_arg_ty=(%s), self_mode=%?, arg_expr=%s, \ @@ -731,7 +733,7 @@ pub fn trans_arg_expr(bcx: block, formal_arg_ty.repr(bcx.tcx()), self_mode, arg_expr.repr(bcx.tcx()), - ret_flag.map(|v| bcx.val_str(*v))); + ret_flag.map(|v| bcx.val_to_str(*v))); // translate the arg expr to a datum let arg_datumblock = match ret_flag { @@ -777,7 +779,7 @@ pub fn trans_arg_expr(bcx: block, // to have type lldestty (the callee's expected type). let llformal_arg_ty = type_of::type_of(ccx, formal_arg_ty); unsafe { - val = llvm::LLVMGetUndef(llformal_arg_ty); + val = llvm::LLVMGetUndef(llformal_arg_ty.to_ref()); } } else { // FIXME(#3548) use the adjustments table @@ -838,15 +840,15 @@ pub fn trans_arg_expr(bcx: block, // this could happen due to e.g. subtyping let llformal_arg_ty = type_of::type_of_explicit_arg(ccx, &formal_arg_ty); let llformal_arg_ty = match self_mode { - ty::ByRef => T_ptr(llformal_arg_ty), + ty::ByRef => llformal_arg_ty.ptr_to(), ty::ByCopy => llformal_arg_ty, }; debug!("casting actual type (%s) to match formal (%s)", - bcx.val_str(val), bcx.llty_str(llformal_arg_ty)); + bcx.val_to_str(val), bcx.llty_str(llformal_arg_ty)); val = PointerCast(bcx, val, llformal_arg_ty); } } - debug!("--- trans_arg_expr passing %s", val_str(bcx.ccx().tn, val)); + debug!("--- trans_arg_expr passing %s", bcx.val_to_str(val)); return rslt(bcx, val); } diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs index acb89755c7f..4ab9cd6c957 100644 --- a/src/librustc/middle/trans/closure.rs +++ b/src/librustc/middle/trans/closure.rs @@ -26,6 +26,8 @@ use middle::trans::type_of::*; use middle::ty; use util::ppaux::ty_to_str; +use middle::trans::type_::Type; + use core::str; use core::vec; use syntax::ast; @@ -72,7 +74,7 @@ use syntax::parse::token::special_idents; // closure". // // Typically an opaque closure suffices because we only manipulate it -// by ptr. The routine common::T_opaque_box_ptr() returns an +// by ptr. The routine Type::opaque_box().ptr_to() returns an // appropriate type for such an opaque closure; it allows access to // the box fields, but not the closure_data itself. // @@ -160,15 +162,15 @@ pub fn mk_closure_tys(tcx: ty::ctxt, pub fn allocate_cbox(bcx: block, sigil: ast::Sigil, cdata_ty: ty::t) -> Result { - let _icx = bcx.insn_ctxt("closure::allocate_cbox"); + let _icx = push_ctxt("closure::allocate_cbox"); let ccx = bcx.ccx(); let tcx = ccx.tcx; fn nuke_ref_count(bcx: block, llbox: ValueRef) { - let _icx = bcx.insn_ctxt("closure::nuke_ref_count"); + let _icx = push_ctxt("closure::nuke_ref_count"); // Initialize ref count to arbitrary value for debugging: let ccx = bcx.ccx(); - let llbox = PointerCast(bcx, llbox, T_opaque_box_ptr(ccx)); + let llbox = PointerCast(bcx, llbox, Type::opaque_box(ccx).ptr_to()); let ref_cnt = GEPi(bcx, llbox, [0u, abi::box_field_refcnt]); let rc = C_int(ccx, 0x12345678); Store(bcx, rc, ref_cnt); @@ -204,7 +206,7 @@ pub struct ClosureResult { pub fn store_environment(bcx: block, bound_values: ~[EnvValue], sigil: ast::Sigil) -> ClosureResult { - let _icx = bcx.insn_ctxt("closure::store_environment"); + let _icx = push_ctxt("closure::store_environment"); let ccx = bcx.ccx(); let tcx = ccx.tcx; @@ -258,7 +260,7 @@ pub fn build_closure(bcx0: block, cap_vars: &[moves::CaptureVar], sigil: ast::Sigil, include_ret_handle: Option) -> ClosureResult { - let _icx = bcx0.insn_ctxt("closure::build_closure"); + let _icx = push_ctxt("closure::build_closure"); // If we need to, package up the iterator body to call let bcx = bcx0; @@ -298,12 +300,11 @@ pub fn build_closure(bcx0: block, let ret_true = match bcx.fcx.loop_ret { Some((_, retptr)) => retptr, None => match bcx.fcx.llretptr { - None => C_null(T_ptr(T_nil())), - Some(retptr) => retptr, + None => C_null(Type::nil().ptr_to()), + Some(retptr) => PointerCast(bcx, retptr, Type::nil().ptr_to()), } }; - let ret_casted = PointerCast(bcx, ret_true, T_ptr(T_nil())); - let ret_datum = Datum {val: ret_casted, ty: ty::mk_nil(), + let ret_datum = Datum {val: ret_true, ty: ty::mk_nil(), mode: ByRef(ZeroMem)}; env_vals.push(EnvValue {action: EnvRef, datum: ret_datum}); @@ -320,7 +321,7 @@ pub fn load_environment(fcx: fn_ctxt, cap_vars: &[moves::CaptureVar], load_ret_handle: bool, sigil: ast::Sigil) { - let _icx = fcx.insn_ctxt("closure::load_environment"); + let _icx = push_ctxt("closure::load_environment"); let llloadenv = match fcx.llloadenv { Some(ll) => ll, @@ -391,7 +392,7 @@ pub fn trans_expr_fn(bcx: block, (fn ptr, env) pair */ - let _icx = bcx.insn_ctxt("closure::trans_expr_fn"); + let _icx = push_ctxt("closure::trans_expr_fn"); let dest_addr = match dest { expr::SaveIn(p) => p, @@ -468,7 +469,7 @@ pub fn make_closure_glue( v: ValueRef, t: ty::t, glue_fn: @fn(block, v: ValueRef, t: ty::t) -> block) -> block { - let _icx = cx.insn_ctxt("closure::make_closure_glue"); + let _icx = push_ctxt("closure::make_closure_glue"); let bcx = cx; let tcx = cx.tcx(); @@ -492,7 +493,7 @@ pub fn make_opaque_cbox_take_glue( cboxptr: ValueRef) // ptr to ptr to the opaque closure -> block { // Easy cases: - let _icx = bcx.insn_ctxt("closure::make_opaque_cbox_take_glue"); + let _icx = push_ctxt("closure::make_opaque_cbox_take_glue"); match sigil { ast::BorrowedSigil => { return bcx; @@ -509,22 +510,22 @@ pub fn make_opaque_cbox_take_glue( // ~fn requires a deep copy. let ccx = bcx.ccx(); let tcx = ccx.tcx; - let llopaquecboxty = T_opaque_box_ptr(ccx); + let llopaquecboxty = Type::opaque_box(ccx).ptr_to(); let cbox_in = Load(bcx, cboxptr); do with_cond(bcx, IsNotNull(bcx, cbox_in)) |bcx| { // Load the size from the type descr found in the cbox let cbox_in = PointerCast(bcx, cbox_in, llopaquecboxty); let tydescptr = GEPi(bcx, cbox_in, [0u, abi::box_field_tydesc]); let tydesc = Load(bcx, tydescptr); - let tydesc = PointerCast(bcx, tydesc, T_ptr(ccx.tydesc_type)); + let tydesc = PointerCast(bcx, tydesc, ccx.tydesc_type.ptr_to()); let sz = Load(bcx, GEPi(bcx, tydesc, [0u, abi::tydesc_field_size])); // Adjust sz to account for the rust_opaque_box header fields - let sz = Add(bcx, sz, machine::llsize_of(ccx, T_box_header(ccx))); + let sz = Add(bcx, sz, machine::llsize_of(ccx, Type::box_header(ccx))); // Allocate memory, update original ptr, and copy existing data - let opaque_tydesc = PointerCast(bcx, tydesc, T_ptr(T_i8())); - let rval = alloca(bcx, T_ptr(T_i8())); + let opaque_tydesc = PointerCast(bcx, tydesc, Type::i8p()); + let rval = alloca(bcx, Type::i8p()); let bcx = callee::trans_lang_call( bcx, bcx.tcx().lang_items.exchange_malloc_fn(), @@ -551,7 +552,7 @@ pub fn make_opaque_cbox_drop_glue( sigil: ast::Sigil, cboxptr: ValueRef) // ptr to the opaque closure -> block { - let _icx = bcx.insn_ctxt("closure::make_opaque_cbox_drop_glue"); + let _icx = push_ctxt("closure::make_opaque_cbox_drop_glue"); match sigil { ast::BorrowedSigil => bcx, ast::ManagedSigil => { @@ -572,7 +573,7 @@ pub fn make_opaque_cbox_free_glue( sigil: ast::Sigil, cbox: ValueRef) // ptr to ptr to the opaque closure -> block { - let _icx = bcx.insn_ctxt("closure::make_opaque_cbox_free_glue"); + let _icx = push_ctxt("closure::make_opaque_cbox_free_glue"); match sigil { ast::BorrowedSigil => { return bcx; @@ -585,7 +586,7 @@ pub fn make_opaque_cbox_free_glue( let ccx = bcx.ccx(); do with_cond(bcx, IsNotNull(bcx, cbox)) |bcx| { // Load the type descr found in the cbox - let lltydescty = T_ptr(ccx.tydesc_type); + let lltydescty = ccx.tydesc_type.ptr_to(); let cbox = Load(bcx, cbox); let tydescptr = GEPi(bcx, cbox, [0u, abi::box_field_tydesc]); let tydesc = Load(bcx, tydescptr); diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index e9a0d42f29b..21e173fd0b4 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -12,18 +12,16 @@ use core::prelude::*; -use back::{abi}; use driver::session; use driver::session::Session; -use lib::llvm::{ValueRef, TypeRef, BasicBlockRef, BuilderRef}; +use lib::llvm::{ValueRef, BasicBlockRef, BuilderRef}; use lib::llvm::{True, False, Bool}; -use lib::llvm::{llvm, TypeNames, associate_type, name_has_type}; +use lib::llvm::{llvm}; use lib; use middle::trans::base; use middle::trans::build; use middle::trans::datum; use middle::trans::glue; -use middle::trans::type_of; use middle::trans::write_guard; use middle::ty::substs; use middle::ty; @@ -31,20 +29,19 @@ use middle::typeck; use middle::borrowck::root_map_key; use util::ppaux::{Repr}; +use middle::trans::type_::Type; + use core::cast::transmute; use core::cast; use core::hashmap::{HashMap}; use core::libc::{c_uint, c_longlong, c_ulonglong}; -use core::str; use core::to_bytes; -use core::vec::raw::to_ptr; use core::vec; use syntax::ast::ident; use syntax::ast_map::{path, path_elt}; use syntax::codemap::span; use syntax::parse::token; use syntax::{ast, ast_map}; -use syntax::abi::{X86, X86_64, Arm, Mips}; pub use middle::trans::context::CrateContext; @@ -53,36 +50,16 @@ pub use middle::trans::context::CrateContext; pub type namegen = @fn(s: &str) -> ident; pub fn new_namegen() -> namegen { let f: @fn(s: &str) -> ident = |prefix| { - token::str_to_ident(fmt!("%s_%u", - prefix, - token::gensym(prefix))) + token::str_to_ident(fmt!("%s_%u", prefix, token::gensym(prefix))) }; f } -pub type addrspace = c_uint; - -// Address spaces communicate to LLVM which destructors need to run for -// specific types. -// 0 is ignored by the GC, and is used for all non-GC'd pointers. -// 1 is for opaque GC'd boxes. -// >= 2 are for specific types (e.g. resources). -pub static default_addrspace: addrspace = 0; -pub static gc_box_addrspace: addrspace = 1; - -pub type addrspace_gen = @fn() -> addrspace; -pub fn new_addrspace_gen() -> addrspace_gen { - let i = @mut 1; - let result: addrspace_gen = || { *i += 1; *i }; - result -} - pub struct tydesc_info { ty: ty::t, tydesc: ValueRef, size: ValueRef, align: ValueRef, - addrspace: addrspace, take_glue: Option, drop_glue: Option, free_glue: Option, @@ -124,7 +101,6 @@ pub struct Stats { n_monos: uint, n_inlines: uint, n_closures: uint, - llvm_insn_ctxt: ~[~str], llvm_insns: HashMap<~str, uint>, fn_times: ~[(~str, int)] // (ident, time) } @@ -347,39 +323,14 @@ pub fn cleanup_type(cx: ty::ctxt, ty: ty::t) -> cleantype { } } -// This is not the same as datum::Datum::root(), which is used to keep copies -// of @ values live for as long as a borrowed pointer to the interior exists. -// In the new GC, we can identify immediates on the stack without difficulty, -// but have trouble knowing where non-immediates are on the stack. For -// non-immediates, we must add an additional level of indirection, which -// allows us to alloca a pointer with the right addrspace. -pub fn root_for_cleanup(bcx: block, v: ValueRef, t: ty::t) - -> (ValueRef, bool) { - let ccx = bcx.ccx(); - - let addrspace = base::get_tydesc(ccx, t).addrspace; - if addrspace > gc_box_addrspace { - let llty = type_of::type_of_rooted(ccx, t); - let root = base::alloca(bcx, llty); - build::Store(bcx, build::PointerCast(bcx, v, llty), root); - (root, true) - } else { - (v, false) - } -} - pub fn add_clean(bcx: block, val: ValueRef, t: ty::t) { if !ty::type_needs_drop(bcx.tcx(), t) { return; } - debug!("add_clean(%s, %s, %s)", - bcx.to_str(), - val_str(bcx.ccx().tn, val), - t.repr(bcx.tcx())); - let (root, rooted) = root_for_cleanup(bcx, val, t); + + debug!("add_clean(%s, %s, %s)", bcx.to_str(), bcx.val_to_str(val), t.repr(bcx.tcx())); + let cleanup_type = cleanup_type(bcx.tcx(), t); do in_scope_cx(bcx) |scope_info| { - scope_info.cleanups.push( - clean(|a| glue::drop_ty_root(a, root, rooted, t), - cleanup_type)); + scope_info.cleanups.push(clean(|a| glue::drop_ty(a, val, t), cleanup_type)); grow_scope_clean(scope_info); } } @@ -387,7 +338,7 @@ pub fn add_clean(bcx: block, val: ValueRef, t: ty::t) { pub fn add_clean_temp_immediate(cx: block, val: ValueRef, ty: ty::t) { if !ty::type_needs_drop(cx.tcx(), ty) { return; } debug!("add_clean_temp_immediate(%s, %s, %s)", - cx.to_str(), val_str(cx.ccx().tn, val), + cx.to_str(), cx.val_to_str(val), ty.repr(cx.tcx())); let cleanup_type = cleanup_type(cx.tcx(), ty); do in_scope_cx(cx) |scope_info| { @@ -400,14 +351,11 @@ pub fn add_clean_temp_immediate(cx: block, val: ValueRef, ty: ty::t) { pub fn add_clean_temp_mem(bcx: block, val: ValueRef, t: ty::t) { if !ty::type_needs_drop(bcx.tcx(), t) { return; } debug!("add_clean_temp_mem(%s, %s, %s)", - bcx.to_str(), val_str(bcx.ccx().tn, val), + bcx.to_str(), bcx.val_to_str(val), t.repr(bcx.tcx())); - let (root, rooted) = root_for_cleanup(bcx, val, t); let cleanup_type = cleanup_type(bcx.tcx(), t); do in_scope_cx(bcx) |scope_info| { - scope_info.cleanups.push( - clean_temp(val, |a| glue::drop_ty_root(a, root, rooted, t), - cleanup_type)); + scope_info.cleanups.push(clean_temp(val, |a| glue::drop_ty(a, val, t), cleanup_type)); grow_scope_clean(scope_info); } } @@ -427,18 +375,14 @@ pub fn add_clean_return_to_mut(bcx: block, debug!("add_clean_return_to_mut(%s, %s, %s)", bcx.to_str(), - val_str(bcx.ccx().tn, frozen_val_ref), - val_str(bcx.ccx().tn, bits_val_ref)); + bcx.val_to_str(frozen_val_ref), + bcx.val_to_str(bits_val_ref)); do in_scope_cx(bcx) |scope_info| { scope_info.cleanups.push( clean_temp( frozen_val_ref, - |bcx| write_guard::return_to_mut(bcx, - root_key, - frozen_val_ref, - bits_val_ref, - filename_val, - line_val), + |bcx| write_guard::return_to_mut(bcx, root_key, frozen_val_ref, bits_val_ref, + filename_val, line_val), normal_exit_only)); grow_scope_clean(scope_info); } @@ -623,20 +567,12 @@ impl Result { } } -pub fn ty_str(tn: @TypeNames, t: TypeRef) -> @str { - return lib::llvm::type_to_str(tn, t); -} - -pub fn val_ty(v: ValueRef) -> TypeRef { +pub fn val_ty(v: ValueRef) -> Type { unsafe { - return llvm::LLVMTypeOf(v); + Type::from_ref(llvm::LLVMTypeOf(v)) } } -pub fn val_str(tn: @TypeNames, v: ValueRef) -> @str { - return ty_str(tn, val_ty(v)); -} - pub fn in_scope_cx(cx: block, f: &fn(si: @mut scope_info)) { let mut cur = cx; loop { @@ -664,27 +600,27 @@ pub fn block_parent(cx: block) -> block { // Accessors impl block_ { - pub fn ccx(@mut self) -> @mut CrateContext { self.fcx.ccx } - pub fn tcx(@mut self) -> ty::ctxt { self.fcx.ccx.tcx } - pub fn sess(@mut self) -> Session { self.fcx.ccx.sess } + pub fn ccx(&self) -> @mut CrateContext { self.fcx.ccx } + pub fn tcx(&self) -> ty::ctxt { self.fcx.ccx.tcx } + pub fn sess(&self) -> Session { self.fcx.ccx.sess } - pub fn node_id_to_str(@mut self, id: ast::node_id) -> ~str { + pub fn node_id_to_str(&self, id: ast::node_id) -> ~str { ast_map::node_id_to_str(self.tcx().items, id, self.sess().intr()) } - pub fn expr_to_str(@mut self, e: @ast::expr) -> ~str { + pub fn expr_to_str(&self, e: @ast::expr) -> ~str { e.repr(self.tcx()) } - pub fn expr_is_lval(@mut self, e: @ast::expr) -> bool { + pub fn expr_is_lval(&self, e: @ast::expr) -> bool { ty::expr_is_lval(self.tcx(), self.ccx().maps.method_map, e) } - pub fn expr_kind(@mut self, e: @ast::expr) -> ty::ExprKind { + pub fn expr_kind(&self, e: @ast::expr) -> ty::ExprKind { ty::expr_kind(self.tcx(), self.ccx().maps.method_map, e) } - pub fn def(@mut self, nid: ast::node_id) -> ast::def { + pub fn def(&self, nid: ast::node_id) -> ast::def { match self.tcx().def_map.find(&nid) { Some(&v) => v, None => { @@ -694,19 +630,19 @@ impl block_ { } } - pub fn val_str(@mut self, val: ValueRef) -> @str { - val_str(self.ccx().tn, val) + pub fn val_to_str(&self, val: ValueRef) -> ~str { + self.ccx().tn.val_to_str(val) } - pub fn llty_str(@mut self, llty: TypeRef) -> @str { - ty_str(self.ccx().tn, llty) + pub fn llty_str(&self, ty: Type) -> ~str { + self.ccx().tn.type_to_str(ty) } - pub fn ty_to_str(@mut self, t: ty::t) -> ~str { + pub fn ty_to_str(&self, t: ty::t) -> ~str { t.repr(self.tcx()) } - pub fn to_str(@mut self) -> ~str { + pub fn to_str(&self) -> ~str { unsafe { match self.node_info { Some(node_info) => fmt!("[block %d]", node_info.id), @@ -716,229 +652,6 @@ impl block_ { } } -// LLVM type constructors. -pub fn T_void() -> TypeRef { - unsafe { return llvm::LLVMVoidTypeInContext(base::task_llcx()); } -} - -pub fn T_nil() -> TypeRef { - return T_struct([], false) -} - -pub fn T_metadata() -> TypeRef { - unsafe { return llvm::LLVMMetadataTypeInContext(base::task_llcx()); } -} - -pub fn T_i1() -> TypeRef { - unsafe { return llvm::LLVMInt1TypeInContext(base::task_llcx()); } -} - -pub fn T_i8() -> TypeRef { - unsafe { return llvm::LLVMInt8TypeInContext(base::task_llcx()); } -} - -pub fn T_i16() -> TypeRef { - unsafe { return llvm::LLVMInt16TypeInContext(base::task_llcx()); } -} - -pub fn T_i32() -> TypeRef { - unsafe { return llvm::LLVMInt32TypeInContext(base::task_llcx()); } -} - -pub fn T_i64() -> TypeRef { - unsafe { return llvm::LLVMInt64TypeInContext(base::task_llcx()); } -} - -pub fn T_f32() -> TypeRef { - unsafe { return llvm::LLVMFloatTypeInContext(base::task_llcx()); } -} - -pub fn T_f64() -> TypeRef { - unsafe { return llvm::LLVMDoubleTypeInContext(base::task_llcx()); } -} - -pub fn T_bool() -> TypeRef { return T_i8(); } - -pub fn T_int(targ_cfg: &session::config) -> TypeRef { - return match targ_cfg.arch { - X86 => T_i32(), - X86_64 => T_i64(), - Arm => T_i32(), - Mips => T_i32() - }; -} - -pub fn T_int_ty(cx: &CrateContext, t: ast::int_ty) -> TypeRef { - match t { - ast::ty_i => cx.int_type, - ast::ty_char => T_char(), - ast::ty_i8 => T_i8(), - ast::ty_i16 => T_i16(), - ast::ty_i32 => T_i32(), - ast::ty_i64 => T_i64() - } -} - -pub fn T_uint_ty(cx: &CrateContext, t: ast::uint_ty) -> TypeRef { - match t { - ast::ty_u => cx.int_type, - ast::ty_u8 => T_i8(), - ast::ty_u16 => T_i16(), - ast::ty_u32 => T_i32(), - ast::ty_u64 => T_i64() - } -} - -pub fn T_float_ty(cx: &CrateContext, t: ast::float_ty) -> TypeRef { - match t { - ast::ty_f => cx.float_type, - ast::ty_f32 => T_f32(), - ast::ty_f64 => T_f64() - } -} - -pub fn T_float(targ_cfg: &session::config) -> TypeRef { - return match targ_cfg.arch { - X86 => T_f64(), - X86_64 => T_f64(), - Arm => T_f64(), - Mips => T_f64() - }; -} - -pub fn T_char() -> TypeRef { return T_i32(); } - -pub fn T_size_t(targ_cfg: &session::config) -> TypeRef { - return T_int(targ_cfg); -} - -pub fn T_fn(inputs: &[TypeRef], output: TypeRef) -> TypeRef { - unsafe { - return llvm::LLVMFunctionType(output, to_ptr(inputs), - inputs.len() as c_uint, - False); - } -} - -pub fn T_fn_pair(cx: &CrateContext, tfn: TypeRef) -> TypeRef { - return T_struct([T_ptr(tfn), T_opaque_cbox_ptr(cx)], false); -} - -pub fn T_ptr(t: TypeRef) -> TypeRef { - unsafe { - return llvm::LLVMPointerType(t, default_addrspace); - } -} - -pub fn T_root(t: TypeRef, addrspace: addrspace) -> TypeRef { - unsafe { - return llvm::LLVMPointerType(t, addrspace); - } -} - -pub fn T_struct(elts: &[TypeRef], packed: bool) -> TypeRef { - unsafe { - 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 { - return str::as_c_str(name, |buf| { - llvm::LLVMStructCreateNamed(base::task_llcx(), buf) - }); - } -} - -pub fn set_struct_body(t: TypeRef, elts: &[TypeRef], packed: bool) { - unsafe { - llvm::LLVMStructSetBody(t, - to_ptr(elts), - elts.len() as c_uint, - packed as Bool); - } -} - -pub fn T_empty_struct() -> TypeRef { return T_struct([], false); } - -// A vtable is, in reality, a vtable pointer followed by zero or more pointers -// to tydescs and other vtables that it closes over. But the types and number -// of those are rarely known to the code that needs to manipulate them, so -// they are described by this opaque type. -pub fn T_vtable() -> TypeRef { T_array(T_ptr(T_i8()), 1u) } - -pub fn T_tydesc_field(cx: &CrateContext, field: uint) -> TypeRef { - // Bit of a kludge: pick the fn typeref out of the tydesc.. - - unsafe { - let mut tydesc_elts: ~[TypeRef] = - vec::from_elem::(abi::n_tydesc_fields, - T_nil()); - llvm::LLVMGetStructElementTypes(cx.tydesc_type, &mut tydesc_elts[0]); - let t = llvm::LLVMGetElementType(tydesc_elts[field]); - return t; - } -} - -pub fn T_generic_glue_fn(cx: &mut CrateContext) -> TypeRef { - let s = @"glue_fn"; - match name_has_type(cx.tn, s) { - Some(t) => return t, - _ => () - } - let t = T_tydesc_field(cx, abi::tydesc_field_drop_glue); - associate_type(cx.tn, s, t); - return t; -} - -pub fn T_tydesc(targ_cfg: @session::config) -> TypeRef { - let tydesc = T_named_struct("tydesc"); - let tydescpp = T_ptr(T_ptr(tydesc)); - let pvoid = T_ptr(T_i8()); - let glue_fn_ty = - T_ptr(T_fn([T_ptr(T_nil()), tydescpp, pvoid], T_void())); - - let int_type = T_int(targ_cfg); - let elems = - ~[int_type, int_type, - glue_fn_ty, glue_fn_ty, glue_fn_ty, glue_fn_ty, - T_ptr(T_i8()), T_ptr(T_i8())]; - set_struct_body(tydesc, elems, false); - return tydesc; -} - -pub fn T_array(t: TypeRef, n: uint) -> TypeRef { - unsafe { - return llvm::LLVMArrayType(t, n as c_uint); - } -} - -pub fn T_vector(t: TypeRef, n: uint) -> TypeRef { - unsafe { - return llvm::LLVMVectorType(t, n as c_uint); - } -} - -// Interior vector. -pub fn T_vec2(targ_cfg: &session::config, t: TypeRef) -> TypeRef { - return T_struct([T_int(targ_cfg), // fill - T_int(targ_cfg), // alloc - T_array(t, 0u)], // elements - false); -} - -pub fn T_vec(ccx: &CrateContext, t: TypeRef) -> TypeRef { - return T_vec2(ccx.sess.targ_cfg, t); -} - -// Note that the size of this one is in bytes. -pub fn T_opaque_vec(targ_cfg: @session::config) -> TypeRef { - return T_vec2(targ_cfg, T_i8()); -} - // Let T be the content of a box @T. tuplify_box_ty(t) returns the // representation of @T as a tuple (i.e., the ty::t version of what T_box() // returns). @@ -952,111 +665,31 @@ pub fn tuplify_box_ty(tcx: ty::ctxt, t: ty::t) -> ty::t { t]); } -pub fn T_box_header_fields(cx: &CrateContext) -> ~[TypeRef] { - let ptr = T_ptr(T_i8()); - return ~[cx.int_type, T_ptr(cx.tydesc_type), ptr, ptr]; -} - -pub fn T_box_header(cx: &CrateContext) -> TypeRef { - return T_struct(T_box_header_fields(cx), false); -} - -pub fn T_box(cx: &CrateContext, t: TypeRef) -> TypeRef { - return T_struct(vec::append(T_box_header_fields(cx), [t]), false); -} - -pub fn T_box_ptr(t: TypeRef) -> TypeRef { - unsafe { - return llvm::LLVMPointerType(t, gc_box_addrspace); - } -} - -pub fn T_opaque_box(cx: &CrateContext) -> TypeRef { - return T_box(cx, T_i8()); -} - -pub fn T_opaque_box_ptr(cx: &CrateContext) -> TypeRef { - return T_box_ptr(T_opaque_box(cx)); -} - -pub fn T_unique(cx: &CrateContext, t: TypeRef) -> TypeRef { - return T_struct(vec::append(T_box_header_fields(cx), [t]), false); -} - -pub fn T_unique_ptr(t: TypeRef) -> TypeRef { - unsafe { - return llvm::LLVMPointerType(t, gc_box_addrspace); - } -} - -pub fn T_port(cx: &CrateContext, _t: TypeRef) -> TypeRef { - return T_struct([cx.int_type], false); // Refcount - -} - -pub fn T_chan(cx: &CrateContext, _t: TypeRef) -> TypeRef { - return T_struct([cx.int_type], false); // Refcount - -} - - -pub fn T_opaque_cbox_ptr(cx: &CrateContext) -> TypeRef { - // closures look like boxes (even when they are ~fn or &fn) - // see trans_closure.rs - return T_opaque_box_ptr(cx); -} - -pub fn T_enum_discrim(cx: &CrateContext) -> TypeRef { - return cx.int_type; -} - -pub fn T_captured_tydescs(cx: &CrateContext, n: uint) -> TypeRef { - return T_struct(vec::from_elem::(n, T_ptr(cx.tydesc_type)), false); -} - -pub fn T_opaque_trait(cx: &CrateContext, store: ty::TraitStore) -> TypeRef { - match store { - ty::BoxTraitStore => { - T_struct([T_ptr(cx.tydesc_type), T_opaque_box_ptr(cx)], false) - } - ty::UniqTraitStore => { - T_struct([T_ptr(cx.tydesc_type), - T_unique_ptr(T_unique(cx, T_i8()))], - false) - } - ty::RegionTraitStore(_) => { - T_struct([T_ptr(cx.tydesc_type), T_ptr(T_i8())], false) - } - } -} - -pub fn T_opaque_port_ptr() -> TypeRef { return T_ptr(T_i8()); } - -pub fn T_opaque_chan_ptr() -> TypeRef { return T_ptr(T_i8()); } - // LLVM constant constructors. -pub fn C_null(t: TypeRef) -> ValueRef { +pub fn C_null(t: Type) -> ValueRef { unsafe { - return llvm::LLVMConstNull(t); + llvm::LLVMConstNull(t.to_ref()) } } -pub fn C_undef(t: TypeRef) -> ValueRef { +pub fn C_undef(t: Type) -> ValueRef { unsafe { - return llvm::LLVMGetUndef(t); + llvm::LLVMGetUndef(t.to_ref()) } } -pub fn C_integral(t: TypeRef, u: u64, sign_extend: Bool) -> ValueRef { +pub fn C_integral(t: Type, u: u64, sign_extend: bool) -> ValueRef { unsafe { - return llvm::LLVMConstInt(t, u, sign_extend); + llvm::LLVMConstInt(t.to_ref(), u, sign_extend as Bool) } } -pub fn C_floating(s: &str, t: TypeRef) -> ValueRef { +pub fn C_floating(s: &str, t: Type) -> ValueRef { unsafe { - return str::as_c_str(s, |buf| llvm::LLVMConstRealOfString(t, buf)); + do s.as_c_str |buf| { + llvm::LLVMConstRealOfString(t.to_ref(), buf) + } } } @@ -1064,32 +697,32 @@ pub fn C_nil() -> ValueRef { return C_struct([]); } -pub fn C_bool(b: bool) -> ValueRef { - C_integral(T_bool(), if b { 1u64 } else { 0u64 }, False) +pub fn C_bool(val: bool) -> ValueRef { + C_integral(Type::bool(), val as u64, false) } -pub fn C_i1(b: bool) -> ValueRef { - return C_integral(T_i1(), if b { 1 } else { 0 }, False); +pub fn C_i1(val: bool) -> ValueRef { + C_integral(Type::i1(), val as u64, false) } pub fn C_i32(i: i32) -> ValueRef { - return C_integral(T_i32(), i as u64, True); + return C_integral(Type::i32(), i as u64, true); } pub fn C_i64(i: i64) -> ValueRef { - return C_integral(T_i64(), i as u64, True); + return C_integral(Type::i64(), i as u64, true); } pub fn C_int(cx: &CrateContext, i: int) -> ValueRef { - return C_integral(cx.int_type, i as u64, True); + return C_integral(cx.int_type, i as u64, true); } pub fn C_uint(cx: &CrateContext, i: uint) -> ValueRef { - return C_integral(cx.int_type, i as u64, False); + return C_integral(cx.int_type, i as u64, false); } pub fn C_u8(i: uint) -> ValueRef { - return C_integral(T_i8(), i as u64, False); + return C_integral(Type::i8(), i as u64, false); } @@ -1097,18 +730,19 @@ pub fn C_u8(i: uint) -> ValueRef { // our boxed-and-length-annotated strings. pub fn C_cstr(cx: &mut CrateContext, s: @str) -> ValueRef { unsafe { - match cx.const_cstr_cache.find(&s) { + match cx.const_cstr_cache.find_equiv(&s) { Some(&llval) => return llval, None => () } - let sc = do str::as_c_str(s) |buf| { - llvm::LLVMConstStringInContext(cx.llcx, buf, s.len() as c_uint, - False) + let sc = do s.as_c_str |buf| { + llvm::LLVMConstStringInContext(cx.llcx, buf, s.len() as c_uint, False) + }; + + let gsym = token::gensym("str"); + let g = do fmt!("str%u", gsym).as_c_str |buf| { + llvm::LLVMAddGlobal(cx.llmod, val_ty(sc).to_ref(), buf) }; - let g = - str::as_c_str(fmt!("str%u", (cx.names)("str").name), - |buf| llvm::LLVMAddGlobal(cx.llmod, val_ty(sc), buf)); llvm::LLVMSetInitializer(g, sc); llvm::LLVMSetGlobalConstant(g, True); lib::llvm::SetLinkage(g, lib::llvm::InternalLinkage); @@ -1124,7 +758,7 @@ pub fn C_cstr(cx: &mut CrateContext, s: @str) -> ValueRef { pub fn C_estr_slice(cx: &mut CrateContext, s: @str) -> ValueRef { unsafe { let len = s.len(); - let cs = llvm::LLVMConstPointerCast(C_cstr(cx, s), T_ptr(T_i8())); + let cs = llvm::LLVMConstPointerCast(C_cstr(cx, s), Type::i8p().to_ref()); C_struct([cs, C_uint(cx, len + 1u /* +1 for null */)]) } } @@ -1132,10 +766,9 @@ pub fn C_estr_slice(cx: &mut CrateContext, s: @str) -> ValueRef { // Returns a Plain Old LLVM String: pub fn C_postr(s: &str) -> ValueRef { unsafe { - return do str::as_c_str(s) |buf| { - llvm::LLVMConstStringInContext(base::task_llcx(), - buf, s.len() as c_uint, False) - }; + do s.as_c_str |buf| { + llvm::LLVMConstStringInContext(base::task_llcx(), buf, s.len() as c_uint, False) + } } } @@ -1144,17 +777,15 @@ pub fn C_zero_byte_arr(size: uint) -> ValueRef { let mut i = 0u; let mut elts: ~[ValueRef] = ~[]; while i < size { elts.push(C_u8(0u)); i += 1u; } - return llvm::LLVMConstArray(T_i8(), - vec::raw::to_ptr(elts), - elts.len() as c_uint); + return llvm::LLVMConstArray(Type::i8().to_ref(), + vec::raw::to_ptr(elts), elts.len() as c_uint); } } pub fn C_struct(elts: &[ValueRef]) -> ValueRef { unsafe { do vec::as_imm_buf(elts) |ptr, len| { - llvm::LLVMConstStructInContext(base::task_llcx(), - ptr, len as c_uint, False) + llvm::LLVMConstStructInContext(base::task_llcx(), ptr, len as c_uint, False) } } } @@ -1162,54 +793,50 @@ 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::LLVMConstStructInContext(base::task_llcx(), - ptr, len as c_uint, True) + llvm::LLVMConstStructInContext(base::task_llcx(), ptr, len as c_uint, True) } } } -pub fn C_named_struct(T: TypeRef, elts: &[ValueRef]) -> ValueRef { +pub fn C_named_struct(T: Type, elts: &[ValueRef]) -> ValueRef { unsafe { do vec::as_imm_buf(elts) |ptr, len| { - llvm::LLVMConstNamedStruct(T, ptr, len as c_uint) + llvm::LLVMConstNamedStruct(T.to_ref(), ptr, len as c_uint) } } } -pub fn C_array(ty: TypeRef, elts: &[ValueRef]) -> ValueRef { +pub fn C_array(ty: Type, elts: &[ValueRef]) -> ValueRef { unsafe { - return llvm::LLVMConstArray(ty, vec::raw::to_ptr(elts), - elts.len() as c_uint); + return llvm::LLVMConstArray(ty.to_ref(), vec::raw::to_ptr(elts), elts.len() as c_uint); } } pub fn C_bytes(bytes: &[u8]) -> ValueRef { unsafe { - return llvm::LLVMConstStringInContext(base::task_llcx(), - cast::transmute(vec::raw::to_ptr(bytes)), - bytes.len() as c_uint, True); + let ptr = cast::transmute(vec::raw::to_ptr(bytes)); + return llvm::LLVMConstStringInContext(base::task_llcx(), ptr, bytes.len() as c_uint, True); } } pub fn C_bytes_plus_null(bytes: &[u8]) -> ValueRef { unsafe { - return llvm::LLVMConstStringInContext(base::task_llcx(), - cast::transmute(vec::raw::to_ptr(bytes)), - bytes.len() as c_uint, False); + let ptr = cast::transmute(vec::raw::to_ptr(bytes)); + return llvm::LLVMConstStringInContext(base::task_llcx(), ptr, bytes.len() as c_uint,False); } } pub fn C_shape(ccx: &CrateContext, bytes: ~[u8]) -> ValueRef { unsafe { let llshape = C_bytes_plus_null(bytes); - let name = fmt!("shape%u", (ccx.names)("shape").name); - let llglobal = str::as_c_str(name, |buf| { - llvm::LLVMAddGlobal(ccx.llmod, val_ty(llshape), buf) - }); + let name = fmt!("shape%u", token::gensym("shape")); + let llglobal = do name.as_c_str |buf| { + llvm::LLVMAddGlobal(ccx.llmod, val_ty(llshape).to_ref(), buf) + }; llvm::LLVMSetInitializer(llglobal, llshape); llvm::LLVMSetGlobalConstant(llglobal, True); lib::llvm::SetLinkage(llglobal, lib::llvm::InternalLinkage); - return llvm::LLVMConstPointerCast(llglobal, T_ptr(T_i8())); + return llvm::LLVMConstPointerCast(llglobal, Type::i8p().to_ref()); } } @@ -1227,7 +854,7 @@ pub fn const_get_elt(cx: &CrateContext, v: ValueRef, us: &[c_uint]) }; debug!("const_get_elt(v=%s, us=%?, r=%s)", - val_str(cx.tn, v), us, val_str(cx.tn, r)); + cx.tn.val_to_str(v), us, cx.tn.val_to_str(r)); return r; } @@ -1484,7 +1111,7 @@ pub fn filename_and_line_num_from_span(bcx: block, span: span) -> (ValueRef, ValueRef) { let loc = bcx.sess().parse_sess.cm.lookup_char_pos(span.lo); let filename_cstr = C_cstr(bcx.ccx(), loc.file.name); - let filename = build::PointerCast(bcx, filename_cstr, T_ptr(T_i8())); + let filename = build::PointerCast(bcx, filename_cstr, Type::i8p()); let line = C_int(bcx.ccx(), loc.line as int); (filename, line) } diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs index dcdb53ec532..e40534773c2 100644 --- a/src/librustc/middle/trans/consts.rs +++ b/src/librustc/middle/trans/consts.rs @@ -11,8 +11,7 @@ use core::prelude::*; use back::abi; -use lib::llvm::{llvm, ConstFCmp, ConstICmp, SetLinkage, PrivateLinkage, ValueRef, TypeRef, Bool, - True, False}; +use lib::llvm::{llvm, ConstFCmp, ConstICmp, SetLinkage, PrivateLinkage, ValueRef, Bool, True}; use lib::llvm::{IntEQ, IntNE, IntUGT, IntUGE, IntULT, IntULE, IntSGT, IntSGE, IntSLT, IntSLE, RealOEQ, RealOGT, RealOGE, RealOLT, RealOLE, RealONE}; @@ -20,7 +19,7 @@ use metadata::csearch; use middle::const_eval; use middle::trans::adt; use middle::trans::base; -use middle::trans::base::get_insn_ctxt; +use middle::trans::base::push_ctxt; use middle::trans::common::*; use middle::trans::consts; use middle::trans::expr; @@ -30,36 +29,38 @@ use middle::trans::type_of; use middle::ty; use util::ppaux::{Repr, ty_to_str}; +use middle::trans::type_::Type; + use core::libc::c_uint; use core::str; use syntax::{ast, ast_util, ast_map}; pub fn const_lit(cx: @mut CrateContext, e: @ast::expr, lit: ast::lit) -> ValueRef { - let _icx = cx.insn_ctxt("trans_lit"); + let _icx = push_ctxt("trans_lit"); match lit.node { - ast::lit_int(i, t) => C_integral(T_int_ty(cx, t), i as u64, True), - ast::lit_uint(u, t) => C_integral(T_uint_ty(cx, t), u, False), + ast::lit_int(i, t) => C_integral(Type::int_from_ty(cx, t), i as u64, true), + ast::lit_uint(u, t) => C_integral(Type::uint_from_ty(cx, t), u, false), ast::lit_int_unsuffixed(i) => { let lit_int_ty = ty::node_id_to_type(cx.tcx, e.id); match ty::get(lit_int_ty).sty { ty::ty_int(t) => { - C_integral(T_int_ty(cx, t), i as u64, True) + C_integral(Type::int_from_ty(cx, t), i as u64, true) } ty::ty_uint(t) => { - C_integral(T_uint_ty(cx, t), i as u64, False) + C_integral(Type::uint_from_ty(cx, t), i as u64, false) } _ => cx.sess.span_bug(lit.span, fmt!("integer literal has type %s (expected int or uint)", ty_to_str(cx.tcx, lit_int_ty))) } } - ast::lit_float(fs, t) => C_floating(fs, T_float_ty(cx, t)), + ast::lit_float(fs, t) => C_floating(fs, Type::float_from_ty(cx, t)), ast::lit_float_unsuffixed(fs) => { let lit_float_ty = ty::node_id_to_type(cx.tcx, e.id); match ty::get(lit_float_ty).sty { ty::ty_float(t) => { - C_floating(fs, T_float_ty(cx, t)) + C_floating(fs, Type::float_from_ty(cx, t)) } _ => { cx.sess.span_bug(lit.span, @@ -73,16 +74,16 @@ pub fn const_lit(cx: @mut CrateContext, e: @ast::expr, lit: ast::lit) } } -pub fn const_ptrcast(cx: &mut CrateContext, a: ValueRef, t: TypeRef) -> ValueRef { +pub fn const_ptrcast(cx: &mut CrateContext, a: ValueRef, t: Type) -> ValueRef { unsafe { - let b = llvm::LLVMConstPointerCast(a, T_ptr(t)); + let b = llvm::LLVMConstPointerCast(a, t.ptr_to().to_ref()); assert!(cx.const_globals.insert(b as int, a)); b } } pub fn const_vec(cx: @mut CrateContext, e: @ast::expr, es: &[@ast::expr]) - -> (ValueRef, ValueRef, TypeRef) { + -> (ValueRef, ValueRef, Type) { unsafe { let vec_ty = ty::expr_ty(cx.tcx, e); let unit_ty = ty::sequence_element_type(cx.tcx, vec_ty); @@ -102,8 +103,8 @@ pub fn const_vec(cx: @mut CrateContext, e: @ast::expr, es: &[@ast::expr]) fn const_addr_of(cx: @mut CrateContext, cv: ValueRef) -> ValueRef { unsafe { - let gv = do str::as_c_str("const") |name| { - llvm::LLVMAddGlobal(cx.llmod, val_ty(cv), name) + let gv = do "const".as_c_str |name| { + llvm::LLVMAddGlobal(cx.llmod, val_ty(cv).to_ref(), name) }; llvm::LLVMSetInitializer(gv, cv); llvm::LLVMSetGlobalConstant(gv, True); @@ -180,7 +181,7 @@ pub fn const_expr(cx: @mut CrateContext, e: @ast::expr) -> ValueRef { match adjustment { None => { } Some(@ty::AutoAddEnv(ty::re_static, ast::BorrowedSigil)) => { - llconst = C_struct([llconst, C_null(T_opaque_box_ptr(cx))]) + llconst = C_struct([llconst, C_null(Type::opaque_box(cx).ptr_to())]) } Some(@ty::AutoAddEnv(ref r, ref s)) => { cx.sess.span_bug(e.span, fmt!("unexpected static function: \ @@ -248,7 +249,7 @@ pub fn const_expr(cx: @mut CrateContext, e: @ast::expr) -> ValueRef { fn const_expr_unadjusted(cx: @mut CrateContext, e: @ast::expr) -> ValueRef { unsafe { - let _icx = cx.insn_ctxt("const_expr"); + let _icx = push_ctxt("const_expr"); return match e.node { ast::expr_lit(lit) => consts::const_lit(cx, e, *lit), ast::expr_binary(_, b, e1, e2) => { @@ -349,9 +350,9 @@ fn const_expr_unadjusted(cx: @mut CrateContext, e: @ast::expr) -> ValueRef { ty::ty_bool => { // Somewhat questionable, but I believe this is // correct. - let te = llvm::LLVMConstTrunc(te, T_i1()); + let te = llvm::LLVMConstTrunc(te, Type::i1().to_ref()); let te = llvm::LLVMConstNot(te); - llvm::LLVMConstZExt(te, T_bool()) + llvm::LLVMConstZExt(te, Type::bool().to_ref()) } _ => llvm::LLVMConstNot(te), } @@ -426,21 +427,21 @@ fn const_expr_unadjusted(cx: @mut CrateContext, e: @ast::expr) -> ValueRef { (expr::cast_integral, expr::cast_integral) => { let s = ty::type_is_signed(basety) as Bool; - llvm::LLVMConstIntCast(v, llty, s) + llvm::LLVMConstIntCast(v, llty.to_ref(), s) } (expr::cast_integral, expr::cast_float) => { if ty::type_is_signed(basety) { - llvm::LLVMConstSIToFP(v, llty) + llvm::LLVMConstSIToFP(v, llty.to_ref()) } else { - llvm::LLVMConstUIToFP(v, llty) + llvm::LLVMConstUIToFP(v, llty.to_ref()) } } (expr::cast_float, expr::cast_float) => { - llvm::LLVMConstFPCast(v, llty) + llvm::LLVMConstFPCast(v, llty.to_ref()) } (expr::cast_float, expr::cast_integral) => { - if ty::type_is_signed(ety) { llvm::LLVMConstFPToSI(v, llty) } - else { llvm::LLVMConstFPToUI(v, llty) } + if ty::type_is_signed(ety) { llvm::LLVMConstFPToSI(v, llty.to_ref()) } + else { llvm::LLVMConstFPToUI(v, llty.to_ref()) } } (expr::cast_enum, expr::cast_integral) | (expr::cast_enum, expr::cast_float) => { @@ -451,18 +452,18 @@ fn const_expr_unadjusted(cx: @mut CrateContext, e: @ast::expr) -> ValueRef { match ety_cast { expr::cast_integral => { let s = ty::type_is_signed(ety) as Bool; - llvm::LLVMConstIntCast(iv, llty, s) + llvm::LLVMConstIntCast(iv, llty.to_ref(), s) } - expr::cast_float => llvm::LLVMConstUIToFP(iv, llty), + expr::cast_float => llvm::LLVMConstUIToFP(iv, llty.to_ref()), _ => cx.sess.bug("enum cast destination is not \ integral or float") } } (expr::cast_pointer, expr::cast_pointer) => { - llvm::LLVMConstPointerCast(v, llty) + llvm::LLVMConstPointerCast(v, llty.to_ref()) } (expr::cast_integral, expr::cast_pointer) => { - llvm::LLVMConstIntToPtr(v, llty) + llvm::LLVMConstIntToPtr(v, llty.to_ref()) } _ => { cx.sess.impossible_case(e.span, @@ -513,7 +514,7 @@ fn const_expr_unadjusted(cx: @mut CrateContext, e: @ast::expr) -> ValueRef { let (cv, sz, llunitty) = const_vec(cx, e, *es); let llty = val_ty(cv); let gv = do str::as_c_str("const") |name| { - llvm::LLVMAddGlobal(cx.llmod, llty, name) + llvm::LLVMAddGlobal(cx.llmod, llty.to_ref(), name) }; llvm::LLVMSetInitializer(gv, cv); llvm::LLVMSetGlobalConstant(gv, True); @@ -588,7 +589,7 @@ fn const_expr_unadjusted(cx: @mut CrateContext, e: @ast::expr) -> ValueRef { pub fn trans_const(ccx: @mut CrateContext, _e: @ast::expr, id: ast::node_id) { unsafe { - let _icx = ccx.insn_ctxt("trans_const"); + let _icx = push_ctxt("trans_const"); let g = base::get_item_val(ccx, id); // At this point, get_item_val has already translated the // constant's initializer to determine its LLVM type. diff --git a/src/librustc/middle/trans/context.rs b/src/librustc/middle/trans/context.rs index d6c7472424f..715b1c88327 100644 --- a/src/librustc/middle/trans/context.rs +++ b/src/librustc/middle/trans/context.rs @@ -12,10 +12,9 @@ use core::prelude::*; use back::{upcall}; use driver::session; -use lib::llvm::{ContextRef, ModuleRef, ValueRef, TypeRef}; +use lib::llvm::{ContextRef, ModuleRef, ValueRef}; use lib::llvm::{llvm, TargetData, TypeNames}; -use lib::llvm::{mk_target_data, mk_type_names}; -use lib; +use lib::llvm::{mk_target_data}; use metadata::common::LinkMeta; use middle::astencode; use middle::resolve; @@ -27,15 +26,17 @@ use middle::trans::shape; use middle::trans::type_use; use middle::ty; +use middle::trans::type_::Type; + use core::hash; use core::hashmap::{HashMap, HashSet}; use core::str; use core::local_data; +use extra::time; use syntax::ast; -use middle::trans::common::{ExternMap,tydesc_info,BuilderRef_res,Stats,namegen,addrspace_gen}; -use middle::trans::common::{mono_id,T_int,T_float,T_tydesc,T_opaque_vec}; -use middle::trans::common::{new_namegen,new_addrspace_gen}; +use middle::trans::common::{ExternMap,tydesc_info,BuilderRef_res,Stats,namegen}; +use middle::trans::common::{mono_id,new_namegen}; use middle::trans::base::{decl_crate_map}; @@ -46,7 +47,7 @@ pub struct CrateContext { llmod: ModuleRef, llcx: ContextRef, td: TargetData, - tn: @TypeNames, + tn: TypeNames, externs: ExternMap, intrinsics: HashMap<&'static str, ValueRef>, item_vals: HashMap, @@ -92,11 +93,10 @@ pub struct CrateContext { impl_method_cache: HashMap<(ast::def_id, ast::ident), ast::def_id>, module_data: HashMap<~str, ValueRef>, - lltypes: HashMap, - llsizingtypes: HashMap, + lltypes: HashMap, + llsizingtypes: HashMap, adt_reprs: HashMap, names: namegen, - next_addrspace: addrspace_gen, symbol_hasher: hash::State, type_hashcodes: HashMap, type_short_names: HashMap, @@ -105,10 +105,10 @@ pub struct CrateContext { maps: astencode::Maps, stats: Stats, upcalls: @upcall::Upcalls, - tydesc_type: TypeRef, - int_type: TypeRef, - float_type: TypeRef, - opaque_vec_type: TypeRef, + tydesc_type: Type, + int_type: Type, + float_type: Type, + opaque_vec_type: Type, builder: BuilderRef_res, shape_cx: shape::Ctxt, crate_map: ValueRef, @@ -136,16 +136,25 @@ impl CrateContext { str::as_c_str(data_layout, |buf| llvm::LLVMSetDataLayout(llmod, buf)); str::as_c_str(targ_triple, |buf| llvm::LLVMSetTarget(llmod, buf)); let targ_cfg = sess.targ_cfg; + let td = mk_target_data(sess.targ_cfg.target_strs.data_layout); - let tn = mk_type_names(); + let mut tn = TypeNames::new(); + let mut intrinsics = base::declare_intrinsics(llmod); if sess.opts.extra_debuginfo { base::declare_dbg_intrinsics(llmod, &mut intrinsics); } - let int_type = T_int(targ_cfg); - let float_type = T_float(targ_cfg); - let tydesc_type = T_tydesc(targ_cfg); - lib::llvm::associate_type(tn, @"tydesc", tydesc_type); + let int_type = Type::int(targ_cfg.arch); + let float_type = Type::float(targ_cfg.arch); + let tydesc_type = Type::tydesc(targ_cfg.arch); + let opaque_vec_type = Type::opaque_vec(targ_cfg.arch); + + let mut str_slice_ty = Type::named_struct("str_slice"); + str_slice_ty.set_struct_body([Type::i8p(), int_type], false); + + tn.associate_type("tydesc", &tydesc_type); + tn.associate_type("str_slice", &str_slice_ty); + let crate_map = decl_crate_map(sess, link_meta, llmod); let dbg_cx = if sess.opts.debuginfo { Some(debuginfo::DebugContext::new(llmod, name.to_owned())) @@ -153,6 +162,10 @@ impl CrateContext { None }; + if sess.count_llvm_insns() { + base::init_insn_ctxt() + } + CrateContext { sess: sess, llmod: llmod, @@ -186,7 +199,6 @@ impl CrateContext { llsizingtypes: HashMap::new(), adt_reprs: HashMap::new(), names: new_namegen(), - next_addrspace: new_addrspace_gen(), symbol_hasher: symbol_hasher, type_hashcodes: HashMap::new(), type_short_names: HashMap::new(), @@ -202,7 +214,6 @@ impl CrateContext { n_monos: 0u, n_inlines: 0u, n_closures: 0u, - llvm_insn_ctxt: ~[], llvm_insns: HashMap::new(), fn_times: ~[] }, @@ -210,7 +221,7 @@ impl CrateContext { tydesc_type: tydesc_type, int_type: int_type, float_type: float_type, - opaque_vec_type: T_opaque_vec(targ_cfg), + opaque_vec_type: opaque_vec_type, builder: BuilderRef_res(llvm::LLVMCreateBuilderInContext(llcx)), shape_cx: mk_ctxt(llmod), crate_map: crate_map, @@ -220,6 +231,12 @@ impl CrateContext { } } } + + pub fn log_fn_time(&mut self, name: ~str, start: time::Timespec, end: time::Timespec) { + let elapsed = 1000 * ((end.sec - start.sec) as int) + + ((end.nsec as int) - (start.nsec as int)) / 1000000; + self.stats.fn_times.push((name, elapsed)); + } } #[unsafe_destructor] @@ -232,7 +249,6 @@ impl Drop for CrateContext { } 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!") diff --git a/src/librustc/middle/trans/controlflow.rs b/src/librustc/middle/trans/controlflow.rs index 55436e5946e..6be26354db1 100644 --- a/src/librustc/middle/trans/controlflow.rs +++ b/src/librustc/middle/trans/controlflow.rs @@ -24,6 +24,8 @@ use middle::ty; use util::common::indenter; use util::ppaux; +use middle::trans::type_::Type; + use core::str; use core::vec; use syntax::ast; @@ -33,7 +35,7 @@ use syntax::ast_util; use syntax::codemap::span; pub fn trans_block(bcx: block, b: &ast::blk, dest: expr::Dest) -> block { - let _icx = bcx.insn_ctxt("trans_block"); + let _icx = push_ctxt("trans_block"); let mut bcx = bcx; do block_locals(b) |local| { bcx = alloc_local(bcx, local); @@ -65,7 +67,7 @@ pub fn trans_if(bcx: block, dest.to_str(bcx.ccx())); let _indenter = indenter(); - let _icx = bcx.insn_ctxt("trans_if"); + let _icx = push_ctxt("trans_if"); let Result {bcx, val: cond_val} = expr::trans_to_datum(bcx, cond).to_result(); @@ -124,7 +126,7 @@ pub fn join_blocks(parent_bcx: block, in_cxs: &[block]) -> block { } pub fn trans_while(bcx: block, cond: @ast::expr, body: &ast::blk) -> block { - let _icx = bcx.insn_ctxt("trans_while"); + let _icx = push_ctxt("trans_while"); let next_bcx = sub_block(bcx, "while next"); // bcx @@ -166,7 +168,7 @@ pub fn trans_loop(bcx:block, body: &ast::blk, opt_label: Option) -> block { - let _icx = bcx.insn_ctxt("trans_loop"); + let _icx = push_ctxt("trans_loop"); let next_bcx = sub_block(bcx, "next"); let body_bcx_in = loop_scope_block(bcx, next_bcx, opt_label, "`loop`", body.info()); @@ -180,7 +182,7 @@ pub fn trans_log(log_ex: @ast::expr, lvl: @ast::expr, bcx: block, e: @ast::expr) -> block { - let _icx = bcx.insn_ctxt("trans_log"); + let _icx = push_ctxt("trans_log"); let ccx = bcx.ccx(); let mut bcx = bcx; if ty::type_is_bot(expr_ty(bcx, lvl)) { @@ -204,10 +206,10 @@ pub fn trans_log(log_ex: @ast::expr, let global; unsafe { global = str::as_c_str(s, |buf| { - llvm::LLVMAddGlobal(ccx.llmod, T_i32(), buf) + llvm::LLVMAddGlobal(ccx.llmod, Type::i32().to_ref(), buf) }); llvm::LLVMSetGlobalConstant(global, False); - llvm::LLVMSetInitializer(global, C_null(T_i32())); + llvm::LLVMSetInitializer(global, C_null(Type::i32())); lib::llvm::SetLinkage(global, lib::llvm::InternalLinkage); } ccx.module_data.insert(modname, global); @@ -242,7 +244,7 @@ pub fn trans_break_cont(bcx: block, opt_label: Option, to_end: bool) -> block { - let _icx = bcx.insn_ctxt("trans_break_cont"); + let _icx = push_ctxt("trans_break_cont"); // Locate closest loop block, outputting cleanup as we go. let mut unwind = bcx; let mut target; @@ -296,7 +298,7 @@ pub fn trans_cont(bcx: block, label_opt: Option) -> block { } pub fn trans_ret(bcx: block, e: Option<@ast::expr>) -> block { - let _icx = bcx.insn_ctxt("trans_ret"); + let _icx = push_ctxt("trans_ret"); let mut bcx = bcx; let dest = match copy bcx.fcx.loop_ret { Some((flagptr, retptr)) => { @@ -307,7 +309,7 @@ pub fn trans_ret(bcx: block, e: Option<@ast::expr>) -> block { Store(bcx, C_bool(false), bcx.fcx.llretptr.get()); expr::SaveIn(match e { Some(x) => PointerCast(bcx, retptr, - T_ptr(type_of(bcx.ccx(), expr_ty(bcx, x)))), + type_of(bcx.ccx(), expr_ty(bcx, x)).ptr_to()), None => retptr }) } @@ -331,7 +333,7 @@ pub fn trans_fail_expr(bcx: block, sp_opt: Option, fail_expr: Option<@ast::expr>) -> block { - let _icx = bcx.insn_ctxt("trans_fail_expr"); + let _icx = push_ctxt("trans_fail_expr"); let mut bcx = bcx; match fail_expr { Some(arg_expr) => { @@ -359,7 +361,7 @@ pub fn trans_fail(bcx: block, sp_opt: Option, fail_str: @str) -> block { - let _icx = bcx.insn_ctxt("trans_fail"); + let _icx = push_ctxt("trans_fail"); let V_fail_str = C_cstr(bcx.ccx(), fail_str); return trans_fail_value(bcx, sp_opt, V_fail_str); } @@ -368,7 +370,7 @@ fn trans_fail_value(bcx: block, sp_opt: Option, V_fail_str: ValueRef) -> block { - let _icx = bcx.insn_ctxt("trans_fail_value"); + let _icx = push_ctxt("trans_fail_value"); let ccx = bcx.ccx(); let (V_filename, V_line) = match sp_opt { Some(sp) => { @@ -381,8 +383,8 @@ fn trans_fail_value(bcx: block, (C_cstr(bcx.ccx(), @""), 0) } }; - let V_str = PointerCast(bcx, V_fail_str, T_ptr(T_i8())); - let V_filename = PointerCast(bcx, V_filename, T_ptr(T_i8())); + let V_str = PointerCast(bcx, V_fail_str, Type::i8p()); + let V_filename = PointerCast(bcx, V_filename, Type::i8p()); let args = ~[V_str, V_filename, C_int(ccx, V_line)]; let bcx = callee::trans_lang_call( bcx, bcx.tcx().lang_items.fail_fn(), args, expr::Ignore); @@ -392,7 +394,7 @@ fn trans_fail_value(bcx: block, pub fn trans_fail_bounds_check(bcx: block, sp: span, index: ValueRef, len: ValueRef) -> block { - let _icx = bcx.insn_ctxt("trans_fail_bounds_check"); + let _icx = push_ctxt("trans_fail_bounds_check"); let (filename, line) = filename_and_line_num_from_span(bcx, sp); let args = ~[filename, line, index, len]; let bcx = callee::trans_lang_call( diff --git a/src/librustc/middle/trans/datum.rs b/src/librustc/middle/trans/datum.rs index b0276cf0e29..32d0f8887b9 100644 --- a/src/librustc/middle/trans/datum.rs +++ b/src/librustc/middle/trans/datum.rs @@ -273,14 +273,14 @@ impl Datum { * `store_to()` instead, which will move if possible but copy if * neccessary. */ - let _icx = bcx.insn_ctxt("copy_to"); + let _icx = push_ctxt("copy_to"); if ty::type_is_nil(self.ty) || ty::type_is_bot(self.ty) { return bcx; } debug!("copy_to(self=%s, action=%?, dst=%s)", - self.to_str(bcx.ccx()), action, bcx.val_str(dst)); + self.to_str(bcx.ccx()), action, bcx.val_to_str(dst)); // Watch out for the case where we are writing the copying the // value into the same location we read it out from. We want @@ -317,7 +317,7 @@ impl Datum { * A helper for `copy_to()` which does not check to see if we * are copying to/from the same value. */ - let _icx = bcx.insn_ctxt("copy_to_no_check"); + let _icx = push_ctxt("copy_to_no_check"); let mut bcx = bcx; if action == DROP_EXISTING { @@ -341,11 +341,11 @@ impl Datum { // pub fn move_to(&self, bcx: block, action: CopyAction, dst: ValueRef) -> block { - let _icx = bcx.insn_ctxt("move_to"); + let _icx = push_ctxt("move_to"); let mut bcx = bcx; debug!("move_to(self=%s, action=%?, dst=%s)", - self.to_str(bcx.ccx()), action, bcx.val_str(dst)); + self.to_str(bcx.ccx()), action, bcx.val_to_str(dst)); if ty::type_is_nil(self.ty) || ty::type_is_bot(self.ty) { return bcx; @@ -409,7 +409,7 @@ impl Datum { pub fn to_str(&self, ccx: &CrateContext) -> ~str { fmt!("Datum { val=%s, ty=%s, mode=%? }", - val_str(ccx.tn, self.val), + ccx.tn.val_to_str(self.val), ty_to_str(ccx.tcx, self.ty), self.mode) } @@ -474,7 +474,7 @@ impl Datum { ByRef(_) => self.val, ByValue => { if ty::type_is_nil(self.ty) || ty::type_is_bot(self.ty) { - C_null(T_ptr(type_of::type_of(bcx.ccx(), self.ty))) + C_null(type_of::type_of(bcx.ccx(), self.ty).ptr_to()) } else { let slot = alloc_ty(bcx, self.ty); Store(bcx, self.val, slot); @@ -740,7 +740,7 @@ impl Datum { expr_id: ast::node_id, max: uint) -> DatumBlock { - let _icx = bcx.insn_ctxt("autoderef"); + let _icx = push_ctxt("autoderef"); debug!("autoderef(expr_id=%d, max=%?, self=%?)", expr_id, max, self.to_str(bcx.ccx())); diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index d1467edd94d..44e571dfb2f 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -122,7 +122,7 @@ lvalues are *never* stored by value. use core::prelude::*; use back::abi; -use lib::llvm::{ValueRef, TypeRef, llvm}; +use lib::llvm::{ValueRef, llvm}; use lib; use metadata::csearch; use middle::trans::_match; @@ -152,6 +152,8 @@ use middle::ty; use util::common::indenter; use util::ppaux::Repr; +use middle::trans::type_::Type; + use core::cast::transmute; use core::hashmap::HashMap; use core::vec; @@ -173,7 +175,7 @@ pub enum Dest { impl Dest { pub fn to_str(&self, ccx: &CrateContext) -> ~str { match *self { - SaveIn(v) => fmt!("SaveIn(%s)", val_str(ccx.tn, v)), + SaveIn(v) => fmt!("SaveIn(%s)", ccx.tn.val_to_str(v)), Ignore => ~"Ignore" } } @@ -449,7 +451,7 @@ fn trans_to_datum_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock { } fn trans_rvalue_datum_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock { - let _icx = bcx.insn_ctxt("trans_rvalue_datum_unadjusted"); + let _icx = push_ctxt("trans_rvalue_datum_unadjusted"); trace_span!(bcx, expr.span, shorten(bcx.expr_to_str(expr))); @@ -500,7 +502,7 @@ fn trans_rvalue_datum_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock { fn trans_rvalue_stmt_unadjusted(bcx: block, expr: @ast::expr) -> block { let mut bcx = bcx; - let _icx = bcx.insn_ctxt("trans_rvalue_stmt"); + let _icx = push_ctxt("trans_rvalue_stmt"); if bcx.unreachable { return bcx; @@ -556,7 +558,7 @@ fn trans_rvalue_stmt_unadjusted(bcx: block, expr: @ast::expr) -> block { fn trans_rvalue_dps_unadjusted(bcx: block, expr: @ast::expr, dest: Dest) -> block { - let _icx = bcx.insn_ctxt("trans_rvalue_dps_unadjusted"); + let _icx = push_ctxt("trans_rvalue_dps_unadjusted"); let tcx = bcx.tcx(); trace_span!(bcx, expr.span, shorten(bcx.expr_to_str(expr))); @@ -705,7 +707,7 @@ fn trans_rvalue_dps_unadjusted(bcx: block, expr: @ast::expr, fn trans_def_dps_unadjusted(bcx: block, ref_expr: @ast::expr, def: ast::def, dest: Dest) -> block { - let _icx = bcx.insn_ctxt("trans_def_dps_unadjusted"); + let _icx = push_ctxt("trans_def_dps_unadjusted"); let ccx = bcx.ccx(); let lldest = match dest { @@ -753,7 +755,7 @@ fn trans_def_datum_unadjusted(bcx: block, ref_expr: @ast::expr, def: ast::def) -> DatumBlock { - let _icx = bcx.insn_ctxt("trans_def_datum_unadjusted"); + let _icx = push_ctxt("trans_def_datum_unadjusted"); match def { ast::def_fn(did, _) | ast::def_static_method(did, None, _) => { @@ -794,7 +796,7 @@ fn trans_def_datum_unadjusted(bcx: block, ty: ty::mk_mach_uint(ast::ty_u8), mutbl: ast::m_imm }); // *u8 - (rust_ty, PointerCast(bcx, fn_data.llfn, T_ptr(T_i8()))) + (rust_ty, PointerCast(bcx, fn_data.llfn, Type::i8p())) } else { let fn_ty = expr_ty(bcx, ref_expr); (fn_ty, fn_data.llfn) @@ -814,7 +816,7 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock { * Translates an lvalue expression, always yielding a by-ref * datum. Does not apply any adjustments. */ - let _icx = bcx.insn_ctxt("trans_lval"); + let _icx = push_ctxt("trans_lval"); let mut bcx = bcx; debug!("trans_lvalue(expr=%s)", bcx.expr_to_str(expr)); @@ -853,7 +855,7 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock { //! Translates `base.field`. let mut bcx = bcx; - let _icx = bcx.insn_ctxt("trans_rec_field"); + let _icx = push_ctxt("trans_rec_field"); let base_datum = unpack_datum!(bcx, trans_to_datum(bcx, base)); let repr = adt::represent_type(bcx.ccx(), base_datum.ty); @@ -876,7 +878,7 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock { idx: @ast::expr) -> DatumBlock { //! Translates `base[idx]`. - let _icx = bcx.insn_ctxt("trans_index"); + let _icx = push_ctxt("trans_index"); let ccx = bcx.ccx(); let base_ty = expr_ty(bcx, base); let mut bcx = bcx; @@ -914,8 +916,8 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock { len = Sub(bcx, len, C_uint(bcx.ccx(), 1u)); } - debug!("trans_index: base %s", val_str(bcx.ccx().tn, base)); - debug!("trans_index: len %s", val_str(bcx.ccx().tn, len)); + debug!("trans_index: base %s", bcx.val_to_str(base)); + debug!("trans_index: len %s", bcx.val_to_str(len)); let bounds_check = ICmp(bcx, lib::llvm::IntUGE, scaled_ix, len); let bcx = do with_cond(bcx, bounds_check) |bcx| { @@ -924,7 +926,7 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock { ix_val, unscaled_len) }; let elt = InBoundsGEP(bcx, base, [ix_val]); - let elt = PointerCast(bcx, elt, T_ptr(vt.llunit_ty)); + let elt = PointerCast(bcx, elt, vt.llunit_ty.ptr_to()); return DatumBlock { bcx: bcx, datum: Datum {val: elt, @@ -940,7 +942,7 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock { { //! Translates a reference to a path. - let _icx = bcx.insn_ctxt("trans_def_lvalue"); + let _icx = push_ctxt("trans_def_lvalue"); let ccx = bcx.ccx(); match def { ast::def_const(did) => { @@ -963,7 +965,7 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock { // which may not be equal to the enum's type for // non-C-like enums. let val = base::get_item_val(bcx.ccx(), did.node); - let pty = T_ptr(type_of(bcx.ccx(), const_ty)); + let pty = type_of(bcx.ccx(), const_ty).ptr_to(); PointerCast(bcx, val, pty) } else { { @@ -981,9 +983,7 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock { let symbol = csearch::get_symbol( bcx.ccx().sess.cstore, did); - let llval = llvm::LLVMAddGlobal( - bcx.ccx().llmod, - llty, + let llval = llvm::LLVMAddGlobal( bcx.ccx().llmod, llty.to_ref(), transmute::<&u8,*i8>(&symbol[0])); let extern_const_values = &mut bcx.ccx().extern_const_values; extern_const_values.insert(did, llval); @@ -1012,7 +1012,7 @@ fn trans_lvalue_unadjusted(bcx: block, expr: @ast::expr) -> DatumBlock { } pub fn trans_local_var(bcx: block, def: ast::def) -> Datum { - let _icx = bcx.insn_ctxt("trans_local_var"); + let _icx = push_ctxt("trans_local_var"); return match def { ast::def_upvar(nid, _, _, _) => { @@ -1054,7 +1054,7 @@ pub fn trans_local_var(bcx: block, def: ast::def) -> Datum { // This cast should not be necessary. We should cast self *once*, // but right now this conflicts with default methods. let real_self_ty = monomorphize_type(bcx, self_info.t); - let llselfty = T_ptr(type_of::type_of(bcx.ccx(), real_self_ty)); + let llselfty = type_of::type_of(bcx.ccx(), real_self_ty).ptr_to(); let casted_val = PointerCast(bcx, self_info.v, llselfty); Datum { @@ -1081,7 +1081,7 @@ pub fn trans_local_var(bcx: block, def: ast::def) -> Datum { }; let ty = node_id_type(bcx, nid); debug!("take_local(nid=%?, v=%s, ty=%s)", - nid, bcx.val_str(v), bcx.ty_to_str(ty)); + nid, bcx.val_to_str(v), bcx.ty_to_str(ty)); Datum { val: v, ty: ty, @@ -1143,7 +1143,7 @@ fn trans_rec_or_struct(bcx: block, id: ast::node_id, dest: Dest) -> block { - let _icx = bcx.insn_ctxt("trans_rec"); + let _icx = push_ctxt("trans_rec"); let bcx = bcx; let ty = node_id_type(bcx, id); @@ -1217,7 +1217,7 @@ fn trans_adt(bcx: block, repr: &adt::Repr, discr: int, fields: &[(uint, @ast::expr)], optbase: Option, dest: Dest) -> block { - let _icx = bcx.insn_ctxt("trans_adt"); + let _icx = push_ctxt("trans_adt"); let mut bcx = bcx; let addr = match dest { Ignore => { @@ -1263,7 +1263,7 @@ fn trans_adt(bcx: block, repr: &adt::Repr, discr: int, fn trans_immediate_lit(bcx: block, expr: @ast::expr, lit: ast::lit) -> DatumBlock { // must not be a string constant, that is a RvalueDpsExpr - let _icx = bcx.insn_ctxt("trans_immediate_lit"); + let _icx = push_ctxt("trans_immediate_lit"); let ty = expr_ty(bcx, expr); immediate_rvalue_bcx(bcx, consts::const_lit(bcx.ccx(), expr, lit), ty) } @@ -1272,7 +1272,7 @@ fn trans_unary_datum(bcx: block, un_expr: @ast::expr, op: ast::unop, sub_expr: @ast::expr) -> DatumBlock { - let _icx = bcx.insn_ctxt("trans_unary_datum"); + let _icx = push_ctxt("trans_unary_datum"); // if deref, would be LvalueExpr assert!(op != ast::deref); @@ -1333,7 +1333,7 @@ fn trans_unary_datum(bcx: block, contents: @ast::expr, contents_ty: ty::t, heap: heap) -> DatumBlock { - let _icx = bcx.insn_ctxt("trans_boxed_expr"); + let _icx = push_ctxt("trans_boxed_expr"); let base::MallocResult { bcx, box: bx, body } = base::malloc_general(bcx, contents_ty, heap); add_clean_free(bcx, bx, heap); @@ -1345,7 +1345,7 @@ fn trans_unary_datum(bcx: block, fn trans_addr_of(bcx: block, expr: @ast::expr, subexpr: @ast::expr) -> DatumBlock { - let _icx = bcx.insn_ctxt("trans_addr_of"); + let _icx = push_ctxt("trans_addr_of"); let mut bcx = bcx; let sub_datum = unpack_datum!(bcx, trans_to_datum(bcx, subexpr)); let llval = sub_datum.to_ref_llval(bcx); @@ -1361,7 +1361,7 @@ fn trans_eager_binop(bcx: block, lhs_datum: &Datum, rhs_datum: &Datum) -> DatumBlock { - let _icx = bcx.insn_ctxt("trans_eager_binop"); + let _icx = push_ctxt("trans_eager_binop"); let lhs = lhs_datum.to_appropriate_llval(bcx); let lhs_t = lhs_datum.ty; @@ -1438,7 +1438,7 @@ fn trans_eager_binop(bcx: block, } let cmpr = base::compare_scalar_types(bcx, lhs, rhs, rhs_t, op); bcx = cmpr.bcx; - ZExt(bcx, cmpr.val, T_i8()) + ZExt(bcx, cmpr.val, Type::i8()) } } _ => { @@ -1457,7 +1457,7 @@ fn trans_lazy_binop(bcx: block, op: lazy_binop_ty, a: @ast::expr, b: @ast::expr) -> DatumBlock { - let _icx = bcx.insn_ctxt("trans_lazy_binop"); + let _icx = push_ctxt("trans_lazy_binop"); let binop_ty = expr_ty(bcx, binop_expr); let bcx = bcx; @@ -1491,7 +1491,7 @@ fn trans_lazy_binop(bcx: block, } Br(past_rhs, join.llbb); - let phi = Phi(join, T_bool(), [lhs, rhs], [past_lhs.llbb, + let phi = Phi(join, Type::bool(), [lhs, rhs], [past_lhs.llbb, past_rhs.llbb]); return immediate_rvalue_bcx(join, phi, binop_ty); @@ -1503,7 +1503,7 @@ fn trans_binary(bcx: block, lhs: @ast::expr, rhs: @ast::expr) -> DatumBlock { - let _icx = bcx.insn_ctxt("trans_binary"); + let _icx = push_ctxt("trans_binary"); match op { ast::and => { @@ -1548,12 +1548,12 @@ fn trans_overloaded_op(bcx: block, DoAutorefArg) } -fn int_cast(bcx: block, lldsttype: TypeRef, llsrctype: TypeRef, +fn int_cast(bcx: block, lldsttype: Type, llsrctype: Type, llsrc: ValueRef, signed: bool) -> ValueRef { - let _icx = bcx.insn_ctxt("int_cast"); + let _icx = push_ctxt("int_cast"); unsafe { - let srcsz = llvm::LLVMGetIntTypeWidth(llsrctype); - let dstsz = llvm::LLVMGetIntTypeWidth(lldsttype); + let srcsz = llvm::LLVMGetIntTypeWidth(llsrctype.to_ref()); + let dstsz = llvm::LLVMGetIntTypeWidth(lldsttype.to_ref()); return if dstsz == srcsz { BitCast(bcx, llsrc, lldsttype) } else if srcsz > dstsz { @@ -1566,11 +1566,11 @@ fn int_cast(bcx: block, lldsttype: TypeRef, llsrctype: TypeRef, } } -fn float_cast(bcx: block, lldsttype: TypeRef, llsrctype: TypeRef, +fn float_cast(bcx: block, lldsttype: Type, llsrctype: Type, llsrc: ValueRef) -> ValueRef { - let _icx = bcx.insn_ctxt("float_cast"); - let srcsz = lib::llvm::float_width(llsrctype); - let dstsz = lib::llvm::float_width(lldsttype); + let _icx = push_ctxt("float_cast"); + let srcsz = llsrctype.float_width(); + let dstsz = lldsttype.float_width(); return if dstsz > srcsz { FPExt(bcx, llsrc, lldsttype) } else if srcsz > dstsz { @@ -1602,7 +1602,7 @@ pub fn cast_type_kind(t: ty::t) -> cast_kind { fn trans_imm_cast(bcx: block, expr: @ast::expr, id: ast::node_id) -> DatumBlock { - let _icx = bcx.insn_ctxt("trans_cast"); + let _icx = push_ctxt("trans_cast"); let ccx = bcx.ccx(); let t_out = node_id_type(bcx, id); @@ -1669,7 +1669,7 @@ fn trans_assign_op(bcx: block, dst: @ast::expr, src: @ast::expr) -> block { - let _icx = bcx.insn_ctxt("trans_assign_op"); + let _icx = push_ctxt("trans_assign_op"); let mut bcx = bcx; debug!("trans_assign_op(expr=%s)", bcx.expr_to_str(expr)); diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 9516a8b83ab..2d23942f601 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -11,8 +11,7 @@ use core::prelude::*; use back::{link, abi}; -use lib::llvm::{SequentiallyConsistent, Acquire, Release, Xchg}; -use lib::llvm::{TypeRef, ValueRef}; +use lib::llvm::{ValueRef}; use lib; use middle::trans::base::*; use middle::trans::cabi; @@ -45,6 +44,7 @@ use syntax::parse::token; use syntax::abi::{X86, X86_64, Arm, Mips}; use syntax::abi::{RustIntrinsic, Rust, Stdcall, Fastcall, Cdecl, Aapcs, C}; +use middle::trans::type_::Type; fn abi_info(ccx: @mut CrateContext) -> @cabi::ABIInfo { return match ccx.sess.targ_cfg.arch { @@ -73,10 +73,10 @@ struct ShimTypes { /// Type of the struct we will use to shuttle values back and forth. /// This is always derived from the llsig. - bundle_ty: TypeRef, + bundle_ty: Type, /// Type of the shim function itself. - shim_fn_ty: TypeRef, + shim_fn_ty: Type, /// Adapter object for handling native ABI rules (trust me, you /// don't want to know). @@ -84,8 +84,8 @@ struct ShimTypes { } struct LlvmSignature { - llarg_tys: ~[TypeRef], - llret_ty: TypeRef, + llarg_tys: ~[Type], + llret_ty: Type, sret: bool, } @@ -114,20 +114,16 @@ fn shim_types(ccx: @mut CrateContext, id: ast::node_id) -> ShimTypes { _ => ccx.sess.bug("c_arg_and_ret_lltys called on non-function type") }; let llsig = foreign_signature(ccx, &fn_sig); - let bundle_ty = T_struct(vec::append_one(copy llsig.llarg_tys, - T_ptr(llsig.llret_ty)), - false); + let bundle_ty = Type::struct_(llsig.llarg_tys + [llsig.llret_ty.ptr_to()], false); let ret_def = !ty::type_is_bot(fn_sig.output) && !ty::type_is_nil(fn_sig.output); - let fn_ty = abi_info(ccx).compute_info(llsig.llarg_tys, - llsig.llret_ty, - ret_def); + let fn_ty = abi_info(ccx).compute_info(llsig.llarg_tys, llsig.llret_ty, ret_def); ShimTypes { fn_sig: fn_sig, llsig: llsig, ret_def: ret_def, bundle_ty: bundle_ty, - shim_fn_ty: T_fn([T_ptr(bundle_ty)], T_void()), + shim_fn_ty: Type::func([bundle_ty.ptr_to()], &Type::void()), fn_ty: fn_ty } } @@ -192,7 +188,7 @@ fn build_wrap_fn_(ccx: @mut CrateContext, needs_c_return: bool, arg_builder: wrap_arg_builder, ret_builder: wrap_ret_builder) { - let _icx = ccx.insn_ctxt("foreign::build_wrap_fn_"); + let _icx = push_ctxt("foreign::build_wrap_fn_"); let fcx = new_fn_ctxt(ccx, ~[], llwrapfn, tys.fn_sig.output, None); // Patch up the return type if it's not immediate and we're returning via @@ -211,8 +207,8 @@ fn build_wrap_fn_(ccx: @mut CrateContext, arg_builder(bcx, tys, llwrapfn, llargbundle); // Create call itself. - let llshimfnptr = PointerCast(bcx, llshimfn, T_ptr(T_i8())); - let llrawargbundle = PointerCast(bcx, llargbundle, T_ptr(T_i8())); + let llshimfnptr = PointerCast(bcx, llshimfn, Type::i8p()); + let llrawargbundle = PointerCast(bcx, llargbundle, Type::i8p()); Call(bcx, shim_upcall, [llrawargbundle, llshimfnptr]); ret_builder(bcx, tys, llargbundle); @@ -221,28 +217,21 @@ fn build_wrap_fn_(ccx: @mut CrateContext, tie_up_header_blocks(fcx, lltop); // Then return according to the C ABI. - unsafe { - let return_context = raw_block(fcx, false, fcx.llreturn); + let return_context = raw_block(fcx, false, fcx.llreturn); - let llfunctiontype = val_ty(llwrapfn); - let llfunctiontype = - ::lib::llvm::llvm::LLVMGetElementType(llfunctiontype); - let llfunctionreturntype = - ::lib::llvm::llvm::LLVMGetReturnType(llfunctiontype); - if ::lib::llvm::llvm::LLVMGetTypeKind(llfunctionreturntype) == - ::lib::llvm::Void { - // XXX: This might be wrong if there are any functions for which - // the C ABI specifies a void output pointer and the Rust ABI - // does not. - RetVoid(return_context); - } else { - // Cast if we have to... - // XXX: This is ugly. - let llretptr = BitCast(return_context, - fcx.llretptr.get(), - T_ptr(llfunctionreturntype)); - Ret(return_context, Load(return_context, llretptr)); - } + let llfunctiontype = val_ty(llwrapfn); + let llfunctiontype = llfunctiontype.element_type(); + let return_type = llfunctiontype.return_type(); + if return_type.kind() == ::lib::llvm::Void { + // XXX: This might be wrong if there are any functions for which + // the C ABI specifies a void output pointer and the Rust ABI + // does not. + RetVoid(return_context); + } else { + // Cast if we have to... + // XXX: This is ugly. + let llretptr = BitCast(return_context, fcx.llretptr.get(), return_type.ptr_to()); + Ret(return_context, Load(return_context, llretptr)); } } @@ -285,7 +274,7 @@ fn build_wrap_fn_(ccx: @mut CrateContext, pub fn trans_foreign_mod(ccx: @mut CrateContext, path: &ast_map::path, foreign_mod: &ast::foreign_mod) { - let _icx = ccx.insn_ctxt("foreign::trans_foreign_mod"); + let _icx = push_ctxt("foreign::trans_foreign_mod"); let arch = ccx.sess.targ_cfg.arch; let abi = match foreign_mod.abis.for_arch(arch) { @@ -381,11 +370,11 @@ pub fn trans_foreign_mod(ccx: @mut CrateContext, * } */ - let _icx = ccx.insn_ctxt("foreign::build_shim_fn"); + let _icx = push_ctxt("foreign::build_shim_fn"); fn build_args(bcx: block, tys: &ShimTypes, llargbundle: ValueRef) -> ~[ValueRef] { - let _icx = bcx.insn_ctxt("foreign::shim::build_args"); + let _icx = push_ctxt("foreign::shim::build_args"); tys.fn_ty.build_shim_args(bcx, tys.llsig.llarg_tys, llargbundle) } @@ -393,7 +382,7 @@ pub fn trans_foreign_mod(ccx: @mut CrateContext, tys: &ShimTypes, llargbundle: ValueRef, llretval: ValueRef) { - let _icx = bcx.insn_ctxt("foreign::shim::build_ret"); + let _icx = push_ctxt("foreign::shim::build_ret"); tys.fn_ty.build_shim_ret(bcx, tys.llsig.llarg_tys, tys.ret_def, @@ -499,7 +488,7 @@ pub fn trans_foreign_mod(ccx: @mut CrateContext, * account for the Rust modes. */ - let _icx = ccx.insn_ctxt("foreign::build_wrap_fn"); + let _icx = push_ctxt("foreign::build_wrap_fn"); build_wrap_fn_(ccx, tys, @@ -514,7 +503,7 @@ pub fn trans_foreign_mod(ccx: @mut CrateContext, tys: &ShimTypes, llwrapfn: ValueRef, llargbundle: ValueRef) { - let _icx = bcx.insn_ctxt("foreign::wrap::build_args"); + let _icx = push_ctxt("foreign::wrap::build_args"); let ccx = bcx.ccx(); let n = tys.llsig.llarg_tys.len(); for uint::range(0, n) |i| { @@ -539,7 +528,7 @@ pub fn trans_foreign_mod(ccx: @mut CrateContext, fn build_ret(bcx: block, shim_types: &ShimTypes, llargbundle: ValueRef) { - let _icx = bcx.insn_ctxt("foreign::wrap::build_ret"); + let _icx = push_ctxt("foreign::wrap::build_ret"); let arg_count = shim_types.fn_sig.inputs.len(); for bcx.fcx.llretptr.iter().advance |&retptr| { let llretptr = load_inbounds(bcx, llargbundle, [0, arg_count]); @@ -578,118 +567,76 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, let mut bcx = top_scope_block(fcx, None); let lltop = bcx.llbb; let first_real_arg = fcx.arg_pos(0u); - match ccx.sess.str_of(item.ident).as_slice() { - "atomic_cxchg" => { - let old = AtomicCmpXchg(bcx, - get_param(decl, first_real_arg), + + let nm = ccx.sess.str_of(item.ident); + let name = nm.as_slice(); + + // This requires that atomic intrinsics follow a specific naming pattern: + // "atomic_[_], and no ordering means SeqCst + if name.starts_with("atomic_") { + let split : ~[&str] = name.split_iter('_').collect(); + assert!(split.len() >= 2, "Atomic intrinsic not correct format"); + let order = if split.len() == 2 { + lib::llvm::SequentiallyConsistent + } else { + match split[2] { + "relaxed" => lib::llvm::Monotonic, + "acq" => lib::llvm::Acquire, + "rel" => lib::llvm::Release, + "acqrel" => lib::llvm::AcquireRelease, + _ => ccx.sess.fatal("Unknown ordering in atomic intrinsic") + } + }; + + match split[1] { + "cxchg" => { + let old = AtomicCmpXchg(bcx, get_param(decl, first_real_arg), + get_param(decl, first_real_arg + 1u), + get_param(decl, first_real_arg + 2u), + order); + Store(bcx, old, fcx.llretptr.get()); + } + "load" => { + let old = AtomicLoad(bcx, get_param(decl, first_real_arg), + order); + Store(bcx, old, fcx.llretptr.get()); + } + "store" => { + AtomicStore(bcx, get_param(decl, first_real_arg + 1u), + get_param(decl, first_real_arg), + order); + } + op => { + // These are all AtomicRMW ops + let atom_op = match op { + "xchg" => lib::llvm::Xchg, + "xadd" => lib::llvm::Add, + "xsub" => lib::llvm::Sub, + "and" => lib::llvm::And, + "nand" => lib::llvm::Nand, + "or" => lib::llvm::Or, + "xor" => lib::llvm::Xor, + "max" => lib::llvm::Max, + "min" => lib::llvm::Min, + "umax" => lib::llvm::UMax, + "umin" => lib::llvm::UMin, + _ => ccx.sess.fatal("Unknown atomic operation") + }; + + let old = AtomicRMW(bcx, atom_op, get_param(decl, first_real_arg), get_param(decl, first_real_arg + 1u), - get_param(decl, first_real_arg + 2u), - SequentiallyConsistent); - Store(bcx, old, fcx.llretptr.get()); - } - "atomic_cxchg_acq" => { - let old = AtomicCmpXchg(bcx, - get_param(decl, first_real_arg), - get_param(decl, first_real_arg + 1u), - get_param(decl, first_real_arg + 2u), - Acquire); - Store(bcx, old, fcx.llretptr.get()); - } - "atomic_cxchg_rel" => { - let old = AtomicCmpXchg(bcx, - get_param(decl, first_real_arg), - get_param(decl, first_real_arg + 1u), - get_param(decl, first_real_arg + 2u), - Release); - Store(bcx, old, fcx.llretptr.get()); - } - "atomic_load" => { - let old = AtomicLoad(bcx, - get_param(decl, first_real_arg), - SequentiallyConsistent); - Store(bcx, old, fcx.llretptr.get()); - } - "atomic_load_acq" => { - let old = AtomicLoad(bcx, - get_param(decl, first_real_arg), - Acquire); - Store(bcx, old, fcx.llretptr.get()); - } - "atomic_store" => { - AtomicStore(bcx, - get_param(decl, first_real_arg + 1u), - get_param(decl, first_real_arg), - SequentiallyConsistent); - } - "atomic_store_rel" => { - AtomicStore(bcx, - get_param(decl, first_real_arg + 1u), - get_param(decl, first_real_arg), - Release); - } - "atomic_xchg" => { - let old = AtomicRMW(bcx, Xchg, - get_param(decl, first_real_arg), - get_param(decl, first_real_arg + 1u), - SequentiallyConsistent); - Store(bcx, old, fcx.llretptr.get()); - } - "atomic_xchg_acq" => { - let old = AtomicRMW(bcx, Xchg, - get_param(decl, first_real_arg), - get_param(decl, first_real_arg + 1u), - Acquire); - Store(bcx, old, fcx.llretptr.get()); - } - "atomic_xchg_rel" => { - let old = AtomicRMW(bcx, Xchg, - get_param(decl, first_real_arg), - get_param(decl, first_real_arg + 1u), - Release); - Store(bcx, old, fcx.llretptr.get()); - } - "atomic_xadd" => { - let old = AtomicRMW(bcx, lib::llvm::Add, - get_param(decl, first_real_arg), - get_param(decl, first_real_arg + 1u), - SequentiallyConsistent); - Store(bcx, old, fcx.llretptr.get()); - } - "atomic_xadd_acq" => { - let old = AtomicRMW(bcx, lib::llvm::Add, - get_param(decl, first_real_arg), - get_param(decl, first_real_arg + 1u), - Acquire); - Store(bcx, old, fcx.llretptr.get()); - } - "atomic_xadd_rel" => { - let old = AtomicRMW(bcx, lib::llvm::Add, - get_param(decl, first_real_arg), - get_param(decl, first_real_arg + 1u), - Release); - Store(bcx, old, fcx.llretptr.get()); - } - "atomic_xsub" => { - let old = AtomicRMW(bcx, lib::llvm::Sub, - get_param(decl, first_real_arg), - get_param(decl, first_real_arg + 1u), - SequentiallyConsistent); - Store(bcx, old, fcx.llretptr.get()); - } - "atomic_xsub_acq" => { - let old = AtomicRMW(bcx, lib::llvm::Sub, - get_param(decl, first_real_arg), - get_param(decl, first_real_arg + 1u), - Acquire); - Store(bcx, old, fcx.llretptr.get()); - } - "atomic_xsub_rel" => { - let old = AtomicRMW(bcx, lib::llvm::Sub, - get_param(decl, first_real_arg), - get_param(decl, first_real_arg + 1u), - Release); - Store(bcx, old, fcx.llretptr.get()); + order); + Store(bcx, old, fcx.llretptr.get()); + } } + + build_return(bcx); + finish_fn(fcx, lltop); + + return; + } + + match name { "size_of" => { let tp_ty = substs.tys[0]; let lltp_ty = type_of::type_of(ccx, tp_ty); @@ -734,9 +681,9 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, let static_ti = get_tydesc(ccx, tp_ty); glue::lazily_emit_all_tydesc_glue(ccx, static_ti); - // FIXME (#3727): change this to T_ptr(ccx.tydesc_ty) when the + // FIXME (#3727): change this to ccx.tydesc_ty.ptr_to() when the // core::sys copy of the get_tydesc interface dies off. - let td = PointerCast(bcx, static_ti.tydesc, T_ptr(T_nil())); + let td = PointerCast(bcx, static_ti.tydesc, Type::nil().ptr_to()); Store(bcx, td, fcx.llretptr.get()); } "init" => { @@ -780,7 +727,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, // code bloat when `transmute` is used on large structural // types. let lldestptr = fcx.llretptr.get(); - let lldestptr = PointerCast(bcx, lldestptr, T_ptr(T_i8())); + let lldestptr = PointerCast(bcx, lldestptr, Type::i8p()); let llsrcval = get_param(decl, first_real_arg); let llsrcptr = if ty::type_is_immediate(in_type) { @@ -790,7 +737,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, } else { llsrcval }; - let llsrcptr = PointerCast(bcx, llsrcptr, T_ptr(T_i8())); + let llsrcptr = PointerCast(bcx, llsrcptr, Type::i8p()); let llsize = llsize_of(ccx, llintype); call_memcpy(bcx, lldestptr, llsrcptr, llsize, 1); @@ -807,12 +754,9 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, let visitor = get_param(decl, first_real_arg + 1u); //let llvisitorptr = alloca(bcx, val_ty(visitor)); //Store(bcx, visitor, llvisitorptr); - let td = PointerCast(bcx, td, T_ptr(ccx.tydesc_type)); - glue::call_tydesc_glue_full(bcx, - visitor, - td, - abi::tydesc_field_visit_glue, - None); + let td = PointerCast(bcx, td, ccx.tydesc_type.ptr_to()); + glue::call_tydesc_glue_full(bcx, visitor, td, + abi::tydesc_field_visit_glue, None); } "frame_address" => { let frameaddress = ccx.intrinsics.get_copy(& &"llvm.frameaddress"); @@ -847,8 +791,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, let llfty = type_of_fn(bcx.ccx(), [], ty::mk_nil()); let morestack_addr = decl_cdecl_fn( bcx.ccx().llmod, "__morestack", llfty); - let morestack_addr = PointerCast(bcx, morestack_addr, - T_ptr(T_nil())); + let morestack_addr = PointerCast(bcx, morestack_addr, Type::nil().ptr_to()); Store(bcx, morestack_addr, fcx.llretptr.get()); } "memcpy32" => { @@ -857,8 +800,8 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); let size = C_i32(machine::llsize_of_real(ccx, lltp_ty) as i32); - let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), T_ptr(T_i8())); - let src_ptr = PointerCast(bcx, get_param(decl, first_real_arg + 1), T_ptr(T_i8())); + let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); + let src_ptr = PointerCast(bcx, get_param(decl, first_real_arg + 1), Type::i8p()); let count = get_param(decl, first_real_arg + 2); let volatile = C_i1(false); let llfn = bcx.ccx().intrinsics.get_copy(& &"llvm.memcpy.p0i8.p0i8.i32"); @@ -870,8 +813,8 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); let size = C_i64(machine::llsize_of_real(ccx, lltp_ty) as i64); - let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), T_ptr(T_i8())); - let src_ptr = PointerCast(bcx, get_param(decl, first_real_arg + 1), T_ptr(T_i8())); + let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); + let src_ptr = PointerCast(bcx, get_param(decl, first_real_arg + 1), Type::i8p()); let count = get_param(decl, first_real_arg + 2); let volatile = C_i1(false); let llfn = bcx.ccx().intrinsics.get_copy(& &"llvm.memcpy.p0i8.p0i8.i64"); @@ -883,8 +826,8 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); let size = C_i32(machine::llsize_of_real(ccx, lltp_ty) as i32); - let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), T_ptr(T_i8())); - let src_ptr = PointerCast(bcx, get_param(decl, first_real_arg + 1), T_ptr(T_i8())); + let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); + let src_ptr = PointerCast(bcx, get_param(decl, first_real_arg + 1), Type::i8p()); let count = get_param(decl, first_real_arg + 2); let volatile = C_i1(false); let llfn = bcx.ccx().intrinsics.get_copy(& &"llvm.memmove.p0i8.p0i8.i32"); @@ -896,8 +839,8 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); let size = C_i64(machine::llsize_of_real(ccx, lltp_ty) as i64); - let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), T_ptr(T_i8())); - let src_ptr = PointerCast(bcx, get_param(decl, first_real_arg + 1), T_ptr(T_i8())); + let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); + let src_ptr = PointerCast(bcx, get_param(decl, first_real_arg + 1), Type::i8p()); let count = get_param(decl, first_real_arg + 2); let volatile = C_i1(false); let llfn = bcx.ccx().intrinsics.get_copy(& &"llvm.memmove.p0i8.p0i8.i64"); @@ -909,7 +852,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); let size = C_i32(machine::llsize_of_real(ccx, lltp_ty) as i32); - let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), T_ptr(T_i8())); + let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); let val = get_param(decl, first_real_arg + 1); let count = get_param(decl, first_real_arg + 2); let volatile = C_i1(false); @@ -922,7 +865,7 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, let align = C_i32(machine::llalign_of_min(ccx, lltp_ty) as i32); let size = C_i64(machine::llsize_of_real(ccx, lltp_ty) as i64); - let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), T_ptr(T_i8())); + let dst_ptr = PointerCast(bcx, get_param(decl, first_real_arg), Type::i8p()); let val = get_param(decl, first_real_arg + 1); let count = get_param(decl, first_real_arg + 2); let volatile = C_i1(false); @@ -1212,7 +1155,7 @@ pub fn trans_foreign_fn(ccx: @mut CrateContext, body: &ast::blk, llwrapfn: ValueRef, id: ast::node_id) { - let _icx = ccx.insn_ctxt("foreign::build_foreign_fn"); + let _icx = push_ctxt("foreign::build_foreign_fn"); fn build_rust_fn(ccx: @mut CrateContext, path: ast_map::path, @@ -1220,7 +1163,7 @@ pub fn trans_foreign_fn(ccx: @mut CrateContext, body: &ast::blk, id: ast::node_id) -> ValueRef { - let _icx = ccx.insn_ctxt("foreign::foreign::build_rust_fn"); + let _icx = push_ctxt("foreign::foreign::build_rust_fn"); let t = ty::node_id_to_type(ccx.tcx, id); // XXX: Bad copy. let ps = link::mangle_internal_name_by_path( @@ -1262,11 +1205,11 @@ pub fn trans_foreign_fn(ccx: @mut CrateContext, * one of those types that is passed by pointer in Rust. */ - let _icx = ccx.insn_ctxt("foreign::foreign::build_shim_fn"); + let _icx = push_ctxt("foreign::foreign::build_shim_fn"); fn build_args(bcx: block, tys: &ShimTypes, llargbundle: ValueRef) -> ~[ValueRef] { - let _icx = bcx.insn_ctxt("foreign::extern::shim::build_args"); + let _icx = push_ctxt("foreign::extern::shim::build_args"); let ccx = bcx.ccx(); let mut llargvals = ~[]; let mut i = 0u; @@ -1277,7 +1220,7 @@ pub fn trans_foreign_fn(ccx: @mut CrateContext, llargvals.push(llretptr); } - let llenvptr = C_null(T_opaque_box_ptr(bcx.ccx())); + let llenvptr = C_null(Type::opaque_box(bcx.ccx()).ptr_to()); llargvals.push(llenvptr); while i < n { // Get a pointer to the argument: @@ -1341,7 +1284,7 @@ pub fn trans_foreign_fn(ccx: @mut CrateContext, * } */ - let _icx = ccx.insn_ctxt("foreign::foreign::build_wrap_fn"); + let _icx = push_ctxt("foreign::foreign::build_wrap_fn"); build_wrap_fn_(ccx, tys, @@ -1356,7 +1299,7 @@ pub fn trans_foreign_fn(ccx: @mut CrateContext, tys: &ShimTypes, llwrapfn: ValueRef, llargbundle: ValueRef) { - let _icx = bcx.insn_ctxt("foreign::foreign::wrap::build_args"); + let _icx = push_ctxt("foreign::foreign::wrap::build_args"); tys.fn_ty.build_wrap_args(bcx, tys.llsig.llret_ty, llwrapfn, @@ -1364,7 +1307,7 @@ pub fn trans_foreign_fn(ccx: @mut CrateContext, } fn build_ret(bcx: block, tys: &ShimTypes, llargbundle: ValueRef) { - let _icx = bcx.insn_ctxt("foreign::foreign::wrap::build_ret"); + let _icx = push_ctxt("foreign::foreign::wrap::build_ret"); tys.fn_ty.build_wrap_ret(bcx, tys.llsig.llarg_tys, llargbundle); build_return(bcx); } @@ -1386,7 +1329,7 @@ pub fn register_foreign_fn(ccx: @mut CrateContext, node_id: ast::node_id, attrs: &[ast::attribute]) -> ValueRef { - let _icx = ccx.insn_ctxt("foreign::register_foreign_fn"); + let _icx = push_ctxt("foreign::register_foreign_fn"); let t = ty::node_id_to_type(ccx.tcx, node_id); diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index 0ea63dde972..3e3fdf686e3 100644 --- a/src/librustc/middle/trans/glue.rs +++ b/src/librustc/middle/trans/glue.rs @@ -18,7 +18,7 @@ use back::abi; use back::link::*; use driver::session; use lib; -use lib::llvm::{llvm, ValueRef, TypeRef, True}; +use lib::llvm::{llvm, ValueRef, True}; use middle::trans::adt; use middle::trans::base::*; use middle::trans::callee; @@ -29,12 +29,14 @@ use middle::trans::expr; use middle::trans::machine::*; use middle::trans::reflect; use middle::trans::tvec; -use middle::trans::type_of::{type_of, type_of_glue_fn}; +use middle::trans::type_of::type_of; use middle::trans::uniq; use middle::ty; use util::ppaux; use util::ppaux::ty_to_short_str; +use middle::trans::type_::Type; + use core::io; use core::libc::c_uint; use core::str; @@ -43,26 +45,24 @@ use extra::time; use syntax::ast; pub fn trans_free(cx: block, v: ValueRef) -> block { - let _icx = cx.insn_ctxt("trans_free"); - callee::trans_lang_call( - cx, + let _icx = push_ctxt("trans_free"); + callee::trans_lang_call(cx, cx.tcx().lang_items.free_fn(), - [PointerCast(cx, v, T_ptr(T_i8()))], + [PointerCast(cx, v, Type::i8p())], expr::Ignore) } pub fn trans_exchange_free(cx: block, v: ValueRef) -> block { - let _icx = cx.insn_ctxt("trans_exchange_free"); - callee::trans_lang_call( - cx, + let _icx = push_ctxt("trans_exchange_free"); + callee::trans_lang_call(cx, cx.tcx().lang_items.exchange_free_fn(), - [PointerCast(cx, v, T_ptr(T_i8()))], + [PointerCast(cx, v, Type::i8p())], expr::Ignore) } pub fn take_ty(cx: block, v: ValueRef, t: ty::t) -> block { // NB: v is an *alias* of type t here, not a direct value. - let _icx = cx.insn_ctxt("take_ty"); + let _icx = push_ctxt("take_ty"); if ty::type_needs_drop(cx.tcx(), t) { return call_tydesc_glue(cx, v, t, abi::tydesc_field_take_glue); } @@ -71,38 +71,24 @@ pub fn take_ty(cx: block, v: ValueRef, t: ty::t) -> block { pub fn drop_ty(cx: block, v: ValueRef, t: ty::t) -> block { // NB: v is an *alias* of type t here, not a direct value. - let _icx = cx.insn_ctxt("drop_ty"); + let _icx = push_ctxt("drop_ty"); if ty::type_needs_drop(cx.tcx(), t) { return call_tydesc_glue(cx, v, t, abi::tydesc_field_drop_glue); } return cx; } -pub fn drop_ty_root(bcx: block, - v: ValueRef, - rooted: bool, - t: ty::t) - -> block { - if rooted { - // NB: v is a raw ptr to an addrspace'd ptr to the value. - let v = PointerCast(bcx, Load(bcx, v), T_ptr(type_of(bcx.ccx(), t))); - drop_ty(bcx, v, t) - } else { - drop_ty(bcx, v, t) - } -} - pub fn drop_ty_immediate(bcx: block, v: ValueRef, t: ty::t) -> block { - let _icx = bcx.insn_ctxt("drop_ty_immediate"); + let _icx = push_ctxt("drop_ty_immediate"); match ty::get(t).sty { - ty::ty_uniq(_) | - ty::ty_evec(_, ty::vstore_uniq) | - ty::ty_estr(ty::vstore_uniq) => { + ty::ty_uniq(_) + | ty::ty_evec(_, ty::vstore_uniq) + | ty::ty_estr(ty::vstore_uniq) => { free_ty_immediate(bcx, v, t) } - ty::ty_box(_) | ty::ty_opaque_box | - ty::ty_evec(_, ty::vstore_box) | - ty::ty_estr(ty::vstore_box) => { + ty::ty_box(_) | ty::ty_opaque_box + | ty::ty_evec(_, ty::vstore_box) + | ty::ty_estr(ty::vstore_box) => { decr_refcnt_maybe_free(bcx, v, None, t) } _ => bcx.tcx().sess.bug("drop_ty_immediate: non-box ty") @@ -110,7 +96,7 @@ pub fn drop_ty_immediate(bcx: block, v: ValueRef, t: ty::t) -> block { } pub fn take_ty_immediate(bcx: block, v: ValueRef, t: ty::t) -> Result { - let _icx = bcx.insn_ctxt("take_ty_immediate"); + let _icx = push_ctxt("take_ty_immediate"); match ty::get(t).sty { ty::ty_box(_) | ty::ty_opaque_box | ty::ty_evec(_, ty::vstore_box) | @@ -131,7 +117,7 @@ pub fn take_ty_immediate(bcx: block, v: ValueRef, t: ty::t) -> Result { pub fn free_ty(cx: block, v: ValueRef, t: ty::t) -> block { // NB: v is an *alias* of type t here, not a direct value. - let _icx = cx.insn_ctxt("free_ty"); + let _icx = push_ctxt("free_ty"); if ty::type_needs_drop(cx.tcx(), t) { return call_tydesc_glue(cx, v, t, abi::tydesc_field_free_glue); } @@ -139,7 +125,7 @@ pub fn free_ty(cx: block, v: ValueRef, t: ty::t) -> block { } pub fn free_ty_immediate(bcx: block, v: ValueRef, t: ty::t) -> block { - let _icx = bcx.insn_ctxt("free_ty_immediate"); + let _icx = push_ctxt("free_ty_immediate"); match ty::get(t).sty { ty::ty_uniq(_) | ty::ty_evec(_, ty::vstore_uniq) | @@ -221,7 +207,7 @@ pub fn simplified_glue_type(tcx: ty::ctxt, field: uint, t: ty::t) -> ty::t { pub fn lazily_emit_simplified_tydesc_glue(ccx: @mut CrateContext, field: uint, ti: @mut tydesc_info) -> bool { - let _icx = ccx.insn_ctxt("lazily_emit_simplified_tydesc_glue"); + let _icx = push_ctxt("lazily_emit_simplified_tydesc_glue"); let simpl = simplified_glue_type(ccx.tcx, field, ti.ty); if simpl != ti.ty { let simpl_ti = get_tydesc(ccx, simpl); @@ -246,7 +232,7 @@ pub fn lazily_emit_simplified_tydesc_glue(ccx: @mut CrateContext, pub fn lazily_emit_tydesc_glue(ccx: @mut CrateContext, field: uint, ti: @mut tydesc_info) { - let _icx = ccx.insn_ctxt("lazily_emit_tydesc_glue"); + let _icx = push_ctxt("lazily_emit_tydesc_glue"); let llfnty = type_of_glue_fn(ccx); if lazily_emit_simplified_tydesc_glue(ccx, field, ti) { @@ -314,7 +300,7 @@ pub fn call_tydesc_glue_full(bcx: block, tydesc: ValueRef, field: uint, static_ti: Option<@mut tydesc_info>) { - let _icx = bcx.insn_ctxt("call_tydesc_glue_full"); + let _icx = push_ctxt("call_tydesc_glue_full"); let ccx = bcx.ccx(); // NB: Don't short-circuit even if this block is unreachable because // GC-based cleanup needs to the see that the roots are live. @@ -340,7 +326,7 @@ pub fn call_tydesc_glue_full(bcx: block, } }; - let llrawptr = PointerCast(bcx, v, T_ptr(T_i8())); + let llrawptr = PointerCast(bcx, v, Type::i8p()); let llfn = { match static_glue_fn { @@ -353,26 +339,26 @@ pub fn call_tydesc_glue_full(bcx: block, } }; - Call(bcx, llfn, [C_null(T_ptr(T_nil())), - C_null(T_ptr(T_ptr(bcx.ccx().tydesc_type))), + Call(bcx, llfn, [C_null(Type::nil().ptr_to()), + C_null(bcx.ccx().tydesc_type.ptr_to().ptr_to()), llrawptr]); } // See [Note-arg-mode] pub fn call_tydesc_glue(cx: block, v: ValueRef, t: ty::t, field: uint) -> block { - let _icx = cx.insn_ctxt("call_tydesc_glue"); + let _icx = push_ctxt("call_tydesc_glue"); let ti = get_tydesc(cx.ccx(), t); call_tydesc_glue_full(cx, v, ti.tydesc, field, Some(ti)); return cx; } pub fn make_visit_glue(bcx: block, v: ValueRef, t: ty::t) { - let _icx = bcx.insn_ctxt("make_visit_glue"); + let _icx = push_ctxt("make_visit_glue"); let bcx = do with_scope(bcx, None, "visitor cleanup") |bcx| { let mut bcx = bcx; let (visitor_trait, object_ty) = ty::visitor_object_ty(bcx.tcx()); - let v = PointerCast(bcx, v, T_ptr(type_of::type_of(bcx.ccx(), object_ty))); + let v = PointerCast(bcx, v, type_of::type_of(bcx.ccx(), object_ty).ptr_to()); bcx = reflect::emit_calls_to_trait_visit_ty(bcx, t, v, visitor_trait.def_id); // The visitor is a boxed object and needs to be dropped add_clean(bcx, v, object_ty); @@ -383,14 +369,11 @@ pub fn make_visit_glue(bcx: block, v: ValueRef, t: ty::t) { pub fn make_free_glue(bcx: block, v: ValueRef, t: ty::t) { // NB: v0 is an *alias* of type t here, not a direct value. - let _icx = bcx.insn_ctxt("make_free_glue"); - let ccx = bcx.ccx(); + let _icx = push_ctxt("make_free_glue"); let bcx = match ty::get(t).sty { ty::ty_box(body_mt) => { let v = Load(bcx, v); let body = GEPi(bcx, v, [0u, abi::box_field_body]); - // Cast away the addrspace of the box pointer. - let body = PointerCast(bcx, body, T_ptr(type_of(ccx, body_mt.ty))); let bcx = drop_ty(bcx, body, body_mt.ty); trans_free(bcx, v) } @@ -442,8 +425,8 @@ pub fn trans_struct_drop(bcx: block, // The second argument is the "self" argument for drop let params = unsafe { - lib::llvm::fn_ty_param_tys( - llvm::LLVMGetElementType(llvm::LLVMTypeOf(dtor_addr))) + let ty = Type::from_ref(llvm::LLVMTypeOf(dtor_addr)); + ty.element_type().func_params() }; // Class dtors have no explicit args, so the params should @@ -475,7 +458,7 @@ pub fn trans_struct_drop(bcx: block, pub fn make_drop_glue(bcx: block, v0: ValueRef, t: ty::t) { // NB: v0 is an *alias* of type t here, not a direct value. - let _icx = bcx.insn_ctxt("make_drop_glue"); + let _icx = push_ctxt("make_drop_glue"); let ccx = bcx.ccx(); let bcx = match ty::get(t).sty { ty::ty_box(_) | ty::ty_opaque_box | @@ -517,9 +500,8 @@ pub fn make_drop_glue(bcx: block, v0: ValueRef, t: ty::t) { let llvtable = Load(bcx, GEPi(bcx, v0, [0, abi::trt_field_vtable])); // Cast the vtable to a pointer to a pointer to a tydesc. - let llvtable = PointerCast(bcx, - llvtable, - T_ptr(T_ptr(ccx.tydesc_type))); + let llvtable = PointerCast(bcx, llvtable, + ccx.tydesc_type.ptr_to().ptr_to()); let lltydesc = Load(bcx, llvtable); call_tydesc_glue_full(bcx, lluniquevalue, @@ -547,7 +529,7 @@ pub fn decr_refcnt_maybe_free(bcx: block, box_ptr: ValueRef, box_ptr_ptr: Option, t: ty::t) -> block { - let _icx = bcx.insn_ctxt("decr_refcnt_maybe_free"); + let _icx = push_ctxt("decr_refcnt_maybe_free"); let ccx = bcx.ccx(); do with_cond(bcx, IsNotNull(bcx, box_ptr)) |bcx| { @@ -566,7 +548,7 @@ pub fn decr_refcnt_maybe_free(bcx: block, box_ptr: ValueRef, pub fn make_take_glue(bcx: block, v: ValueRef, t: ty::t) { - let _icx = bcx.insn_ctxt("make_take_glue"); + let _icx = push_ctxt("make_take_glue"); // NB: v is a *pointer* to type t here, not a direct value. let bcx = match ty::get(t).sty { ty::ty_box(_) | ty::ty_opaque_box | @@ -615,7 +597,7 @@ pub fn make_take_glue(bcx: block, v: ValueRef, t: ty::t) { } pub fn incr_refcnt_of_boxed(cx: block, box_ptr: ValueRef) { - let _icx = cx.insn_ctxt("incr_refcnt_of_boxed"); + let _icx = push_ctxt("incr_refcnt_of_boxed"); let ccx = cx.ccx(); let rc_ptr = GEPi(cx, box_ptr, [0u, abi::box_field_refcnt]); let rc = Load(cx, rc_ptr); @@ -624,20 +606,6 @@ pub fn incr_refcnt_of_boxed(cx: block, box_ptr: ValueRef) { } -// Chooses the addrspace for newly declared types. -pub fn declare_tydesc_addrspace(ccx: &CrateContext, t: ty::t) -> addrspace { - if !ty::type_needs_drop(ccx.tcx, t) { - return default_addrspace; - } else if ty::type_is_immediate(t) { - // For immediate types, we don't actually need an addrspace, because - // e.g. boxed types include pointers to their contents which are - // already correctly tagged with addrspaces. - return default_addrspace; - } else { - return (ccx.next_addrspace)(); - } -} - // Generates the declaration for (but doesn't emit) a type descriptor. pub fn declare_tydesc(ccx: &mut CrateContext, t: ty::t) -> @mut tydesc_info { // If emit_tydescs already ran, then we shouldn't be creating any new @@ -647,20 +615,18 @@ pub fn declare_tydesc(ccx: &mut CrateContext, t: ty::t) -> @mut tydesc_info { let llty = type_of(ccx, t); if ccx.sess.count_type_sizes() { - io::println(fmt!("%u\t%s", - llsize_of_real(ccx, llty), + io::println(fmt!("%u\t%s", llsize_of_real(ccx, llty), ppaux::ty_to_str(ccx.tcx, t))); } let llsize = llsize_of(ccx, llty); let llalign = llalign_of(ccx, llty); - let addrspace = declare_tydesc_addrspace(ccx, t); let name = mangle_internal_name_by_type_and_seq(ccx, t, "tydesc").to_managed(); note_unique_llvm_symbol(ccx, name); debug!("+++ declare_tydesc %s %s", ppaux::ty_to_str(ccx.tcx, t), name); let gvar = str::as_c_str(name, |buf| { unsafe { - llvm::LLVMAddGlobal(ccx.llmod, ccx.tydesc_type, buf) + llvm::LLVMAddGlobal(ccx.llmod, ccx.tydesc_type.to_ref(), buf) } }); let inf = @mut tydesc_info { @@ -668,7 +634,6 @@ pub fn declare_tydesc(ccx: &mut CrateContext, t: ty::t) -> @mut tydesc_info { tydesc: gvar, size: llsize, align: llalign, - addrspace: addrspace, take_glue: None, drop_glue: None, free_glue: None, @@ -680,9 +645,9 @@ pub fn declare_tydesc(ccx: &mut CrateContext, t: ty::t) -> @mut tydesc_info { pub type glue_helper = @fn(block, ValueRef, ty::t); -pub fn declare_generic_glue(ccx: @mut CrateContext, t: ty::t, llfnty: TypeRef, +pub fn declare_generic_glue(ccx: @mut CrateContext, t: ty::t, llfnty: Type, name: ~str) -> ValueRef { - let _icx = ccx.insn_ctxt("declare_generic_glue"); + let _icx = push_ctxt("declare_generic_glue"); let name = name; let fn_nm = mangle_internal_name_by_type_and_seq(ccx, t, (~"glue_" + name)).to_managed(); debug!("%s is for type %s", fn_nm, ppaux::ty_to_str(ccx.tcx, t)); @@ -697,7 +662,7 @@ pub fn make_generic_glue_inner(ccx: @mut CrateContext, llfn: ValueRef, helper: glue_helper) -> ValueRef { - let _icx = ccx.insn_ctxt("make_generic_glue_inner"); + let _icx = push_ctxt("make_generic_glue_inner"); let fcx = new_fn_ctxt(ccx, ~[], llfn, ty::mk_nil(), None); lib::llvm::SetLinkage(llfn, lib::llvm::InternalLinkage); ccx.stats.n_glues_created += 1u; @@ -711,9 +676,13 @@ pub fn make_generic_glue_inner(ccx: @mut CrateContext, let rawptr0_arg = fcx.arg_pos(1u); let llrawptr0 = unsafe { llvm::LLVMGetParam(llfn, rawptr0_arg as c_uint) }; let llty = type_of(ccx, t); - let llrawptr0 = PointerCast(bcx, llrawptr0, T_ptr(llty)); + let llrawptr0 = PointerCast(bcx, llrawptr0, llty.ptr_to()); helper(bcx, llrawptr0, t); - finish_fn(fcx, lltop); + + // This is from the general finish fn, but that emits a ret {} that we don't want + Br(raw_block(fcx, false, fcx.llstaticallocas), lltop); + RetVoid(raw_block(fcx, false, fcx.llreturn)); + return llfn; } @@ -723,7 +692,7 @@ pub fn make_generic_glue(ccx: @mut CrateContext, helper: glue_helper, name: &str) -> ValueRef { - let _icx = ccx.insn_ctxt("make_generic_glue"); + let _icx = push_ctxt("make_generic_glue"); if !ccx.sess.trans_stats() { return make_generic_glue_inner(ccx, t, llfn, helper); } @@ -731,18 +700,15 @@ pub fn make_generic_glue(ccx: @mut CrateContext, let start = time::get_time(); let llval = make_generic_glue_inner(ccx, t, llfn, helper); let end = time::get_time(); - log_fn_time(ccx, - fmt!("glue %s %s", name, ty_to_short_str(ccx.tcx, t)), - start, - end); + ccx.log_fn_time(fmt!("glue %s %s", name, ty_to_short_str(ccx.tcx, t)), start, end); return llval; } pub fn emit_tydescs(ccx: &mut CrateContext) { - //let _icx = ccx.insn_ctxt("emit_tydescs"); + let _icx = push_ctxt("emit_tydescs"); // As of this point, allow no more tydescs to be created. ccx.finished_tydescs = true; - let glue_fn_ty = T_ptr(T_generic_glue_fn(ccx)); + let glue_fn_ty = Type::generic_glue_fn(ccx); let tyds = &mut ccx.tydescs; for tyds.each_value |&val| { let ti = val; @@ -757,7 +723,7 @@ pub fn emit_tydescs(ccx: &mut CrateContext) { Some(v) => { unsafe { ccx.stats.n_real_glues += 1u; - llvm::LLVMConstPointerCast(v, glue_fn_ty) + llvm::LLVMConstPointerCast(v, glue_fn_ty.to_ref()) } } }; @@ -767,7 +733,7 @@ pub fn emit_tydescs(ccx: &mut CrateContext) { Some(v) => { unsafe { ccx.stats.n_real_glues += 1u; - llvm::LLVMConstPointerCast(v, glue_fn_ty) + llvm::LLVMConstPointerCast(v, glue_fn_ty.to_ref()) } } }; @@ -777,7 +743,7 @@ pub fn emit_tydescs(ccx: &mut CrateContext) { Some(v) => { unsafe { ccx.stats.n_real_glues += 1u; - llvm::LLVMConstPointerCast(v, glue_fn_ty) + llvm::LLVMConstPointerCast(v, glue_fn_ty.to_ref()) } } }; @@ -787,16 +753,16 @@ pub fn emit_tydescs(ccx: &mut CrateContext) { Some(v) => { unsafe { ccx.stats.n_real_glues += 1u; - llvm::LLVMConstPointerCast(v, glue_fn_ty) + llvm::LLVMConstPointerCast(v, glue_fn_ty.to_ref()) } } }; - let shape = C_null(T_ptr(T_i8())); - let shape_tables = C_null(T_ptr(T_i8())); - let tydesc = - C_named_struct(ccx.tydesc_type, + let shape = C_null(Type::i8p()); + let shape_tables = C_null(Type::i8p()); + + let tydesc = C_named_struct(ccx.tydesc_type, [ti.size, // size ti.align, // align take_glue, // take_glue @@ -812,18 +778,11 @@ pub fn emit_tydescs(ccx: &mut CrateContext) { llvm::LLVMSetGlobalConstant(gvar, True); lib::llvm::SetLinkage(gvar, lib::llvm::InternalLinkage); - // Index tydesc by addrspace. - if ti.addrspace > gc_box_addrspace { - let llty = T_ptr(ccx.tydesc_type); - let addrspace_name = fmt!("_gc_addrspace_metadata_%u", - ti.addrspace as uint); - let addrspace_gvar = str::as_c_str(addrspace_name, |buf| { - llvm::LLVMAddGlobal(ccx.llmod, llty, buf) - }); - lib::llvm::SetLinkage(addrspace_gvar, - lib::llvm::InternalLinkage); - llvm::LLVMSetInitializer(addrspace_gvar, gvar); - } } }; } + +fn type_of_glue_fn(ccx: &CrateContext) -> Type { + let tydescpp = ccx.tydesc_type.ptr_to().ptr_to(); + Type::func([ Type::nil().ptr_to(), tydescpp, Type::i8p() ], &Type::void()) +} diff --git a/src/librustc/middle/trans/inline.rs b/src/librustc/middle/trans/inline.rs index 00afece9197..01849ac6e8f 100644 --- a/src/librustc/middle/trans/inline.rs +++ b/src/librustc/middle/trans/inline.rs @@ -12,8 +12,7 @@ use core::prelude::*; use metadata::csearch; use middle::astencode; -use middle::trans::base::{get_insn_ctxt}; -use middle::trans::base::{impl_owned_self, impl_self, no_self}; +use middle::trans::base::{push_ctxt,impl_owned_self, impl_self, no_self}; use middle::trans::base::{trans_item, get_item_val, trans_fn}; use middle::trans::common::*; use middle::ty; @@ -30,7 +29,7 @@ use syntax::ast_util::local_def; pub fn maybe_instantiate_inline(ccx: @mut CrateContext, fn_id: ast::def_id, translate: bool) -> ast::def_id { - let _icx = ccx.insn_ctxt("maybe_instantiate_inline"); + let _icx = push_ctxt("maybe_instantiate_inline"); match ccx.external.find(&fn_id) { Some(&Some(node_id)) => { // Already inline diff --git a/src/librustc/middle/trans/machine.rs b/src/librustc/middle/trans/machine.rs index fb94fe4752a..6fcab95996e 100644 --- a/src/librustc/middle/trans/machine.rs +++ b/src/librustc/middle/trans/machine.rs @@ -10,7 +10,7 @@ // Information concerning the machine representation of various types. -use lib::llvm::{ValueRef, TypeRef}; +use lib::llvm::{ValueRef}; use lib::llvm::False; use lib::llvm::llvm; use middle::trans::common::*; @@ -18,21 +18,23 @@ use middle::trans::type_of; use middle::ty; use util::ppaux::ty_to_str; +use middle::trans::type_::Type; + // ______________________________________________________________________ // compute sizeof / alignof // Returns the number of bytes clobbered by a Store to this type. -pub fn llsize_of_store(cx: &CrateContext, t: TypeRef) -> uint { +pub fn llsize_of_store(cx: &CrateContext, ty: Type) -> uint { unsafe { - return llvm::LLVMStoreSizeOfType(cx.td.lltd, t) as uint; + return llvm::LLVMStoreSizeOfType(cx.td.lltd, ty.to_ref()) as uint; } } // Returns the number of bytes between successive elements of type T in an // array of T. This is the "ABI" size. It includes any ABI-mandated padding. -pub fn llsize_of_alloc(cx: &CrateContext, t: TypeRef) -> uint { +pub fn llsize_of_alloc(cx: &CrateContext, ty: Type) -> uint { unsafe { - return llvm::LLVMABISizeOfType(cx.td.lltd, t) as uint; + return llvm::LLVMABISizeOfType(cx.td.lltd, ty.to_ref()) as uint; } } @@ -44,9 +46,9 @@ pub fn llsize_of_alloc(cx: &CrateContext, t: TypeRef) -> uint { // that LLVM *does* distinguish between e.g. a 1-bit value and an 8-bit value // at the codegen level! In general you should prefer `llbitsize_of_real` // below. -pub fn llsize_of_real(cx: &CrateContext, t: TypeRef) -> uint { +pub fn llsize_of_real(cx: &CrateContext, ty: Type) -> uint { unsafe { - let nbits = llvm::LLVMSizeOfTypeInBits(cx.td.lltd, t) as uint; + let nbits = llvm::LLVMSizeOfTypeInBits(cx.td.lltd, ty.to_ref()) as uint; if nbits & 7u != 0u { // Not an even number of bytes, spills into "next" byte. 1u + (nbits >> 3) @@ -57,14 +59,14 @@ pub fn llsize_of_real(cx: &CrateContext, t: TypeRef) -> uint { } /// Returns the "real" size of the type in bits. -pub fn llbitsize_of_real(cx: &CrateContext, t: TypeRef) -> uint { +pub fn llbitsize_of_real(cx: &CrateContext, ty: Type) -> uint { unsafe { - llvm::LLVMSizeOfTypeInBits(cx.td.lltd, t) as uint + llvm::LLVMSizeOfTypeInBits(cx.td.lltd, ty.to_ref()) as uint } } /// Returns the size of the type as an LLVM constant integer value. -pub fn llsize_of(cx: &CrateContext, t: TypeRef) -> ValueRef { +pub fn llsize_of(cx: &CrateContext, ty: Type) -> ValueRef { // Once upon a time, this called LLVMSizeOf, which does a // getelementptr(1) on a null pointer and casts to an int, in // order to obtain the type size as a value without requiring the @@ -72,17 +74,17 @@ pub fn llsize_of(cx: &CrateContext, t: TypeRef) -> ValueRef { // there's no need for that contrivance. The instruction // selection DAG generator would flatten that GEP(1) node into a // constant of the type's alloc size, so let's save it some work. - return C_uint(cx, llsize_of_alloc(cx, t)); + return C_uint(cx, llsize_of_alloc(cx, ty)); } // Returns the "default" size of t (see above), or 1 if the size would // be zero. This is important for things like vectors that expect // space to be consumed. -pub fn nonzero_llsize_of(cx: &CrateContext, t: TypeRef) -> ValueRef { - if llbitsize_of_real(cx, t) == 0 { - unsafe { llvm::LLVMConstInt(cx.int_type, 1, False) } +pub fn nonzero_llsize_of(cx: &CrateContext, ty: Type) -> ValueRef { + if llbitsize_of_real(cx, ty) == 0 { + unsafe { llvm::LLVMConstInt(cx.int_type.to_ref(), 1, False) } } else { - llsize_of(cx, t) + llsize_of(cx, ty) } } @@ -90,28 +92,28 @@ pub fn nonzero_llsize_of(cx: &CrateContext, t: TypeRef) -> ValueRef { // The preferred alignment may be larger than the alignment used when // packing the type into structs. This will be used for things like // allocations inside a stack frame, which LLVM has a free hand in. -pub fn llalign_of_pref(cx: &CrateContext, t: TypeRef) -> uint { +pub fn llalign_of_pref(cx: &CrateContext, ty: Type) -> uint { unsafe { - return llvm::LLVMPreferredAlignmentOfType(cx.td.lltd, t) as uint; + return llvm::LLVMPreferredAlignmentOfType(cx.td.lltd, ty.to_ref()) as uint; } } // Returns the minimum alignment of a type required by the platform. // This is the alignment that will be used for struct fields, arrays, // and similar ABI-mandated things. -pub fn llalign_of_min(cx: &CrateContext, t: TypeRef) -> uint { +pub fn llalign_of_min(cx: &CrateContext, ty: Type) -> uint { unsafe { - return llvm::LLVMABIAlignmentOfType(cx.td.lltd, t) as uint; + return llvm::LLVMABIAlignmentOfType(cx.td.lltd, ty.to_ref()) as uint; } } // Returns the "default" alignment of t, which is calculated by casting // null to a record containing a single-bit followed by a t value, then // doing gep(0,1) to get at the trailing (and presumably padded) t cell. -pub fn llalign_of(cx: &CrateContext, t: TypeRef) -> ValueRef { +pub fn llalign_of(cx: &CrateContext, ty: Type) -> ValueRef { unsafe { return llvm::LLVMConstIntCast( - llvm::LLVMAlignOf(t), cx.int_type, False); + llvm::LLVMAlignOf(ty.to_ref()), cx.int_type.to_ref(), False); } } @@ -140,9 +142,9 @@ pub fn static_size_of_enum(cx: &mut CrateContext, t: ty::t) -> uint { debug!("static_size_of_enum: variant %s type %s", cx.tcx.sess.str_of(variant.name), - ty_str(cx.tn, T_struct(lltypes, false))); + cx.tn.type_to_str(Type::struct_(lltypes, false))); - let this_size = llsize_of_real(cx, T_struct(lltypes, false)); + let this_size = llsize_of_real(cx, Type::struct_(lltypes, false)); if max_size < this_size { max_size = this_size; } diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index 8b327c196e6..3a8efb55c15 100644 --- a/src/librustc/middle/trans/meth.rs +++ b/src/librustc/middle/trans/meth.rs @@ -30,6 +30,8 @@ use middle::typeck; use util::common::indenter; use util::ppaux::Repr; +use middle::trans::type_::Type; + use core::str; use core::vec; use syntax::ast_map::{path, path_mod, path_name}; @@ -49,7 +51,7 @@ pub fn trans_impl(ccx: @mut CrateContext, generics: &ast::Generics, self_ty: Option, id: ast::node_id) { - let _icx = ccx.insn_ctxt("impl::trans_impl"); + let _icx = push_ctxt("impl::trans_impl"); let tcx = ccx.tcx; debug!("trans_impl(path=%s, name=%s, self_ty=%s, id=%?)", @@ -157,7 +159,7 @@ pub fn trans_method(ccx: @mut CrateContext, pub fn trans_self_arg(bcx: block, base: @ast::expr, mentry: typeck::method_map_entry) -> Result { - let _icx = bcx.insn_ctxt("impl::trans_self_arg"); + let _icx = push_ctxt("impl::trans_self_arg"); let mut temp_cleanups = ~[]; // Compute the type of self. @@ -185,7 +187,7 @@ pub fn trans_method_callee(bcx: block, this: @ast::expr, mentry: typeck::method_map_entry) -> Callee { - let _icx = bcx.insn_ctxt("impl::trans_method_callee"); + let _icx = push_ctxt("impl::trans_method_callee"); let tcx = bcx.tcx(); debug!("trans_method_callee(callee_id=%?, this=%s, mentry=%s)", @@ -291,7 +293,7 @@ pub fn trans_static_method_callee(bcx: block, trait_id: ast::def_id, callee_id: ast::node_id) -> FnData { - let _icx = bcx.insn_ctxt("impl::trans_static_method_callee"); + let _icx = push_ctxt("impl::trans_static_method_callee"); let ccx = bcx.ccx(); debug!("trans_static_method_callee(method_id=%?, trait_id=%s, \ @@ -363,7 +365,7 @@ pub fn trans_static_method_callee(bcx: block, Some(callee_origins)); let callee_ty = node_id_type(bcx, callee_id); - let llty = T_ptr(type_of_fn_from_ty(ccx, callee_ty)); + let llty = type_of_fn_from_ty(ccx, callee_ty).ptr_to(); FnData {llfn: PointerCast(bcx, lval, llty)} } _ => { @@ -435,7 +437,7 @@ pub fn trans_monomorphized_callee(bcx: block, n_method: uint, vtbl: typeck::vtable_origin) -> Callee { - let _icx = bcx.insn_ctxt("impl::trans_monomorphized_callee"); + let _icx = push_ctxt("impl::trans_monomorphized_callee"); return match vtbl { typeck::vtable_static(impl_did, ref rcvr_substs, rcvr_origins) => { let ccx = bcx.ccx(); @@ -463,7 +465,7 @@ pub fn trans_monomorphized_callee(bcx: block, // create a llvalue that represents the fn ptr let fn_ty = node_id_type(bcx, callee_id); - let llfn_ty = T_ptr(type_of_fn_from_ty(ccx, fn_ty)); + let llfn_ty = type_of_fn_from_ty(ccx, fn_ty).ptr_to(); let llfn_val = PointerCast(bcx, callee.llfn, llfn_ty); // combine the self environment with the rest @@ -584,7 +586,7 @@ pub fn trans_trait_callee(bcx: block, // first evaluate the self expression (expected a by-ref result) and then // extract the self data and vtable out of the pair. - let _icx = bcx.insn_ctxt("impl::trans_trait_callee"); + let _icx = push_ctxt("impl::trans_trait_callee"); let mut bcx = bcx; let self_datum = unpack_datum!(bcx, expr::trans_to_datum(bcx, self_expr)); @@ -617,18 +619,18 @@ pub fn trans_trait_callee_from_llval(bcx: block, // Same as `trans_trait_callee()` above, except that it is given // a by-ref pointer to the @Trait pair. - let _icx = bcx.insn_ctxt("impl::trans_trait_callee"); + let _icx = push_ctxt("impl::trans_trait_callee"); let ccx = bcx.ccx(); let mut bcx = bcx; // Load the vtable from the @Trait pair debug!("(translating trait callee) loading vtable from pair %s", - val_str(bcx.ccx().tn, llpair)); + bcx.val_to_str(llpair)); let llvtable = Load(bcx, PointerCast(bcx, GEPi(bcx, llpair, [0u, abi::trt_field_vtable]), - T_ptr(T_ptr(T_vtable())))); + Type::vtable().ptr_to().ptr_to())); // Load the box from the @Trait pair and GEP over the box header if // necessary: @@ -705,7 +707,7 @@ pub fn trans_trait_callee_from_llval(bcx: block, // Plus one in order to skip past the type descriptor. let mptr = Load(bcx, GEPi(bcx, llvtable, [0u, n_method + 1])); - let mptr = PointerCast(bcx, mptr, T_ptr(llcallee_ty)); + let mptr = PointerCast(bcx, mptr, llcallee_ty.ptr_to()); return Callee { bcx: bcx, @@ -768,7 +770,7 @@ pub fn make_vtable(ccx: @mut CrateContext, ptrs: &[ValueRef]) -> ValueRef { unsafe { - let _icx = ccx.insn_ctxt("impl::make_vtable"); + let _icx = push_ctxt("impl::make_vtable"); let mut components = ~[ tydesc.tydesc ]; for ptrs.each |&ptr| { @@ -778,7 +780,7 @@ pub fn make_vtable(ccx: @mut CrateContext, let tbl = C_struct(components); let vtable = ccx.sess.str_of((ccx.names)("vtable")); let vt_gvar = do str::as_c_str(vtable) |buf| { - llvm::LLVMAddGlobal(ccx.llmod, val_ty(tbl), buf) + llvm::LLVMAddGlobal(ccx.llmod, val_ty(tbl).to_ref(), buf) }; llvm::LLVMSetInitializer(vt_gvar, tbl); llvm::LLVMSetGlobalConstant(vt_gvar, lib::llvm::True); @@ -795,7 +797,7 @@ pub fn make_impl_vtable(bcx: block, vtables: typeck::vtable_res) -> ValueRef { let ccx = bcx.ccx(); - let _icx = ccx.insn_ctxt("impl::make_impl_vtable"); + let _icx = push_ctxt("impl::make_impl_vtable"); let tcx = ccx.tcx; let trt_id = match ty::impl_trait_ref(tcx, impl_id) { @@ -814,7 +816,7 @@ pub fn make_impl_vtable(bcx: block, if im.generics.has_type_params() || ty::type_has_self(fty) { debug!("(making impl vtable) method has self or type params: %s", tcx.sess.str_of(im.ident)); - C_null(T_ptr(T_nil())) + C_null(Type::nil().ptr_to()) } else { debug!("(making impl vtable) adding method to vtable: %s", tcx.sess.str_of(im.ident)); @@ -839,7 +841,7 @@ pub fn trans_trait_cast(bcx: block, _store: ty::TraitStore) -> block { let mut bcx = bcx; - let _icx = bcx.insn_ctxt("impl::trans_cast"); + let _icx = push_ctxt("impl::trans_cast"); let lldest = match dest { Ignore => { @@ -857,7 +859,7 @@ pub fn trans_trait_cast(bcx: block, // have no type descriptor field.) llboxdest = PointerCast(bcx, llboxdest, - T_ptr(type_of(bcx.ccx(), v_ty))); + type_of(bcx.ccx(), v_ty).ptr_to()); bcx = expr::trans_into(bcx, val, SaveIn(llboxdest)); // Store the vtable into the pair or triple. @@ -866,7 +868,7 @@ pub fn trans_trait_cast(bcx: block, let vtable = get_vtable(bcx, v_ty, orig); Store(bcx, vtable, PointerCast(bcx, GEPi(bcx, lldest, [0u, abi::trt_field_vtable]), - T_ptr(val_ty(vtable)))); + val_ty(vtable).ptr_to())); bcx } diff --git a/src/librustc/middle/trans/mod.rs b/src/librustc/middle/trans/mod.rs index 49cadfbcc81..1345b92418e 100644 --- a/src/librustc/middle/trans/mod.rs +++ b/src/librustc/middle/trans/mod.rs @@ -42,3 +42,4 @@ pub mod reachable; pub mod machine; pub mod adt; pub mod asm; +pub mod type_; diff --git a/src/librustc/middle/trans/monomorphize.rs b/src/librustc/middle/trans/monomorphize.rs index f082150e394..ac5f53c243e 100644 --- a/src/librustc/middle/trans/monomorphize.rs +++ b/src/librustc/middle/trans/monomorphize.rs @@ -13,9 +13,8 @@ use core::prelude::*; use back::link::mangle_exported_name; use driver::session; use lib::llvm::ValueRef; -use middle::trans::base::{get_insn_ctxt}; use middle::trans::base::{set_inline_hint_if_appr, set_inline_hint}; -use middle::trans::base::{trans_enum_variant}; +use middle::trans::base::{trans_enum_variant,push_ctxt}; use middle::trans::base::{trans_fn, decl_internal_cdecl_fn}; use middle::trans::base::{get_item_val, no_self}; use middle::trans::base; @@ -61,7 +60,7 @@ pub fn monomorphic_fn(ccx: @mut CrateContext, ref_id); assert!(real_substs.tps.iter().all(|t| !ty::type_needs_infer(*t))); - let _icx = ccx.insn_ctxt("monomorphic_fn"); + let _icx = push_ctxt("monomorphic_fn"); let mut must_cast = false; let substs = vec::map(real_substs.tps, |t| { match normalize_for_monomorphization(ccx.tcx, *t) { diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs index 16a6d62f176..cb68a2af92b 100644 --- a/src/librustc/middle/trans/reflect.rs +++ b/src/librustc/middle/trans/reflect.rs @@ -9,7 +9,7 @@ // except according to those terms. use back::link::mangle_internal_name_by_path_and_seq; -use lib::llvm::{TypeRef, ValueRef, llvm}; +use lib::llvm::{ValueRef, llvm}; use middle::trans::adt; use middle::trans::base::*; use middle::trans::build::*; @@ -33,11 +33,13 @@ use syntax::ast; use syntax::ast_map::path_name; use syntax::parse::token::special_idents; +use middle::trans::type_::Type; + pub struct Reflector { visitor_val: ValueRef, visitor_methods: @~[@ty::Method], final_bcx: block, - tydesc_ty: TypeRef, + tydesc_ty: Type, bcx: block } @@ -58,7 +60,7 @@ impl Reflector { let str_ty = ty::mk_estr(bcx.tcx(), str_vstore); let scratch = scratch_datum(bcx, str_ty, false); let len = C_uint(bcx.ccx(), s.len() + 1); - let c_str = PointerCast(bcx, C_cstr(bcx.ccx(), s), T_ptr(T_i8())); + let c_str = PointerCast(bcx, C_cstr(bcx.ccx(), s), Type::i8p()); Store(bcx, c_str, GEPi(bcx, scratch.val, [ 0, 0 ])); Store(bcx, len, GEPi(bcx, scratch.val, [ 0, 1 ])); scratch.val @@ -76,7 +78,7 @@ impl Reflector { let bcx = self.bcx; let static_ti = get_tydesc(bcx.ccx(), t); glue::lazily_emit_all_tydesc_glue(bcx.ccx(), static_ti); - PointerCast(bcx, static_ti.tydesc, T_ptr(self.tydesc_ty)) + PointerCast(bcx, static_ti.tydesc, self.tydesc_ty.ptr_to()) } pub fn c_mt(&mut self, mt: &ty::mt) -> ~[ValueRef] { @@ -96,7 +98,7 @@ impl Reflector { debug!("passing %u args:", args.len()); let bcx = self.bcx; for args.iter().enumerate().advance |(i, a)| { - debug!("arg %u: %s", i, val_str(bcx.ccx().tn, *a)); + debug!("arg %u: %s", i, bcx.val_to_str(*a)); } let bool_ty = ty::mk_bool(); let scratch = scratch_datum(bcx, bool_ty, false); @@ -271,7 +273,7 @@ impl Reflector { let ccx = bcx.ccx(); let repr = adt::represent_type(bcx.ccx(), t); let variants = ty::substd_enum_variants(ccx.tcx, did, substs); - let llptrty = T_ptr(type_of(ccx, t)); + let llptrty = type_of(ccx, t).ptr_to(); let (_, opaquety) = ccx.tcx.intrinsic_defs.find_copy(&ccx.sess.ident_of("Opaque")) .expect("Failed to resolve intrinsic::Opaque"); diff --git a/src/librustc/middle/trans/shape.rs b/src/librustc/middle/trans/shape.rs index 89ffb4b5bba..4118291dca0 100644 --- a/src/librustc/middle/trans/shape.rs +++ b/src/librustc/middle/trans/shape.rs @@ -15,7 +15,8 @@ use lib::llvm::llvm; use lib::llvm::{True, ModuleRef, ValueRef}; use middle::trans::common::*; -use middle::trans; + +use middle::trans::type_::Type; use core::str; @@ -32,7 +33,7 @@ pub fn mk_global(ccx: &CrateContext, -> ValueRef { unsafe { let llglobal = do str::as_c_str(name) |buf| { - llvm::LLVMAddGlobal(ccx.llmod, val_ty(llval), buf) + llvm::LLVMAddGlobal(ccx.llmod, val_ty(llval).to_ref(), buf) }; llvm::LLVMSetInitializer(llglobal, llval); llvm::LLVMSetGlobalConstant(llglobal, True); @@ -48,28 +49,15 @@ pub fn mk_global(ccx: &CrateContext, pub fn mk_ctxt(llmod: ModuleRef) -> Ctxt { unsafe { - let llshapetablesty = trans::common::T_named_struct("shapes"); - let _llshapetables = str::as_c_str("shapes", |buf| { - llvm::LLVMAddGlobal(llmod, llshapetablesty, buf) - }); + let llshapetablesty = Type::named_struct("shapes"); + do "shapes".as_c_str |buf| { + llvm::LLVMAddGlobal(llmod, llshapetablesty.to_ref(), buf) + }; - return Ctxt { + Ctxt { next_tag_id: 0u16, pad: 0u16, pad2: 0u32 - }; + } } } - -/* -Although these two functions are never called, they are here -for a VERY GOOD REASON. See #3670 -*/ -pub fn add_u16(dest: &mut ~[u8], val: u16) { - *dest += [(val & 0xffu16) as u8, (val >> 8u16) as u8]; -} - -pub fn add_substr(dest: &mut ~[u8], src: ~[u8]) { - add_u16(&mut *dest, src.len() as u16); - *dest += src; -} diff --git a/src/librustc/middle/trans/tvec.rs b/src/librustc/middle/trans/tvec.rs index 09905a76187..d543b2cc61c 100644 --- a/src/librustc/middle/trans/tvec.rs +++ b/src/librustc/middle/trans/tvec.rs @@ -11,7 +11,7 @@ use back::abi; use lib; -use lib::llvm::{llvm, ValueRef, TypeRef}; +use lib::llvm::{llvm, ValueRef}; use middle::trans::base; use middle::trans::base::*; use middle::trans::build::*; @@ -27,6 +27,8 @@ use middle::ty; use util::common::indenter; use util::ppaux::ty_to_str; +use middle::trans::type_::Type; + use core::option::None; use syntax::ast; use syntax::codemap; @@ -51,7 +53,7 @@ pub fn expand_boxed_vec_ty(tcx: ty::ctxt, t: ty::t) -> ty::t { } pub fn get_fill(bcx: block, vptr: ValueRef) -> ValueRef { - let _icx = bcx.insn_ctxt("tvec::get_fill"); + let _icx = push_ctxt("tvec::get_fill"); Load(bcx, GEPi(bcx, vptr, [0u, abi::vec_elt_fill])) } pub fn set_fill(bcx: block, vptr: ValueRef, fill: ValueRef) { @@ -62,24 +64,24 @@ pub fn get_alloc(bcx: block, vptr: ValueRef) -> ValueRef { } pub fn get_bodyptr(bcx: block, vptr: ValueRef) -> ValueRef { - base::non_gc_box_cast(bcx, GEPi(bcx, vptr, [0u, abi::box_field_body])) + GEPi(bcx, vptr, [0u, abi::box_field_body]) } pub fn get_dataptr(bcx: block, vptr: ValueRef) -> ValueRef { - let _icx = bcx.insn_ctxt("tvec::get_dataptr"); + let _icx = push_ctxt("tvec::get_dataptr"); GEPi(bcx, vptr, [0u, abi::vec_elt_elems, 0u]) } pub fn pointer_add(bcx: block, ptr: ValueRef, bytes: ValueRef) -> ValueRef { - let _icx = bcx.insn_ctxt("tvec::pointer_add"); + let _icx = push_ctxt("tvec::pointer_add"); let old_ty = val_ty(ptr); - let bptr = PointerCast(bcx, ptr, T_ptr(T_i8())); + let bptr = PointerCast(bcx, ptr, Type::i8p()); return PointerCast(bcx, InBoundsGEP(bcx, bptr, [bytes]), old_ty); } pub fn alloc_raw(bcx: block, unit_ty: ty::t, fill: ValueRef, alloc: ValueRef, heap: heap) -> Result { - let _icx = bcx.insn_ctxt("tvec::alloc_uniq"); + let _icx = push_ctxt("tvec::alloc_uniq"); let ccx = bcx.ccx(); let vecbodyty = ty::mk_mut_unboxed_vec(bcx.tcx(), unit_ty); @@ -103,7 +105,7 @@ pub fn alloc_vec(bcx: block, elts: uint, heap: heap) -> Result { - let _icx = bcx.insn_ctxt("tvec::alloc_uniq"); + let _icx = push_ctxt("tvec::alloc_uniq"); let ccx = bcx.ccx(); let llunitty = type_of::type_of(ccx, unit_ty); let unit_sz = nonzero_llsize_of(ccx, llunitty); @@ -117,7 +119,7 @@ pub fn alloc_vec(bcx: block, } pub fn duplicate_uniq(bcx: block, vptr: ValueRef, vec_ty: ty::t) -> Result { - let _icx = bcx.insn_ctxt("tvec::duplicate_uniq"); + let _icx = push_ctxt("tvec::duplicate_uniq"); let fill = get_fill(bcx, get_bodyptr(bcx, vptr)); let unit_ty = ty::sequence_element_type(bcx.tcx(), vec_ty); @@ -135,7 +137,7 @@ pub fn duplicate_uniq(bcx: block, vptr: ValueRef, vec_ty: ty::t) -> Result { pub fn make_drop_glue_unboxed(bcx: block, vptr: ValueRef, vec_ty: ty::t) -> block { - let _icx = bcx.insn_ctxt("tvec::make_drop_glue_unboxed"); + let _icx = push_ctxt("tvec::make_drop_glue_unboxed"); let tcx = bcx.tcx(); let unit_ty = ty::sequence_element_type(tcx, vec_ty); if ty::type_needs_drop(tcx, unit_ty) { @@ -146,7 +148,7 @@ pub fn make_drop_glue_unboxed(bcx: block, vptr: ValueRef, vec_ty: ty::t) -> pub struct VecTypes { vec_ty: ty::t, unit_ty: ty::t, - llunit_ty: TypeRef, + llunit_ty: Type, llunit_size: ValueRef } @@ -155,8 +157,8 @@ impl VecTypes { fmt!("VecTypes {vec_ty=%s, unit_ty=%s, llunit_ty=%s, llunit_size=%s}", ty_to_str(ccx.tcx, self.vec_ty), ty_to_str(ccx.tcx, self.unit_ty), - ty_str(ccx.tn, self.llunit_ty), - val_str(ccx.tn, self.llunit_size)) + ccx.tn.type_to_str(self.llunit_ty), + ccx.tn.val_to_str(self.llunit_size)) } } @@ -227,7 +229,7 @@ pub fn trans_slice_vstore(bcx: block, let fixed_ty = ty::mk_evec(bcx.tcx(), ty::mt {ty: vt.unit_ty, mutbl: ast::m_mutbl}, ty::vstore_fixed(count)); - let llfixed_ty = T_ptr(type_of::type_of(bcx.ccx(), fixed_ty)); + let llfixed_ty = type_of::type_of(bcx.ccx(), fixed_ty).ptr_to(); let llfixed_casted = BitCast(bcx, llfixed, llfixed_ty); add_clean(bcx, llfixed_casted, fixed_ty); @@ -271,13 +273,10 @@ pub fn trans_lit_str(bcx: block, let bytes = str_lit.len() + 1; // count null-terminator too let llbytes = C_uint(bcx.ccx(), bytes); let llcstr = C_cstr(bcx.ccx(), str_lit); - let llcstr = llvm::LLVMConstPointerCast(llcstr, - T_ptr(T_i8())); - Store(bcx, - llcstr, + let llcstr = llvm::LLVMConstPointerCast(llcstr, Type::i8p().to_ref()); + Store(bcx, llcstr, GEPi(bcx, lldest, [0u, abi::slice_elt_base])); - Store(bcx, - llbytes, + Store(bcx, llbytes, GEPi(bcx, lldest, [0u, abi::slice_elt_len])); bcx } @@ -286,9 +285,7 @@ pub fn trans_lit_str(bcx: block, } -pub fn trans_uniq_or_managed_vstore(bcx: block, - heap: heap, - vstore_expr: @ast::expr, +pub fn trans_uniq_or_managed_vstore(bcx: block, heap: heap, vstore_expr: @ast::expr, content_expr: @ast::expr) -> DatumBlock { //! // @@ -307,7 +304,7 @@ pub fn trans_uniq_or_managed_vstore(bcx: block, node: ast::lit_str(s), _ }) => { let llptrval = C_cstr(bcx.ccx(), s); - let llptrval = PointerCast(bcx, llptrval, T_ptr(T_i8())); + let llptrval = PointerCast(bcx, llptrval, Type::i8p()); let llsizeval = C_uint(bcx.ccx(), s.len()); let typ = ty::mk_estr(bcx.tcx(), ty::vstore_uniq); let lldestval = scratch_datum(bcx, typ, false); @@ -336,7 +333,7 @@ pub fn trans_uniq_or_managed_vstore(bcx: block, let dataptr = get_dataptr(bcx, get_bodyptr(bcx, val)); debug!("alloc_vec() returned val=%s, dataptr=%s", - bcx.val_str(val), bcx.val_str(dataptr)); + bcx.val_to_str(val), bcx.val_to_str(dataptr)); let bcx = write_content(bcx, &vt, vstore_expr, content_expr, SaveIn(dataptr)); @@ -352,7 +349,7 @@ pub fn write_content(bcx: block, content_expr: @ast::expr, dest: Dest) -> block { - let _icx = bcx.insn_ctxt("tvec::write_content"); + let _icx = push_ctxt("tvec::write_content"); let mut bcx = bcx; debug!("write_content(vt=%s, dest=%s, vstore_expr=%?)", @@ -389,7 +386,7 @@ pub fn write_content(bcx: block, for elements.iter().enumerate().advance |(i, element)| { let lleltptr = GEPi(bcx, lldest, [i]); debug!("writing index %? with lleltptr=%?", - i, bcx.val_str(lleltptr)); + i, bcx.val_to_str(lleltptr)); bcx = expr::trans_into(bcx, *element, SaveIn(lleltptr)); add_clean_temp_mem(bcx, lleltptr, vt.unit_ty); @@ -551,7 +548,7 @@ pub type iter_vec_block<'self> = &'self fn(block, ValueRef, ty::t) -> block; pub fn iter_vec_raw(bcx: block, data_ptr: ValueRef, vec_ty: ty::t, fill: ValueRef, f: iter_vec_block) -> block { - let _icx = bcx.insn_ctxt("tvec::iter_vec_raw"); + let _icx = push_ctxt("tvec::iter_vec_raw"); let unit_ty = ty::sequence_element_type(bcx.tcx(), vec_ty); @@ -582,14 +579,14 @@ pub fn iter_vec_raw(bcx: block, data_ptr: ValueRef, vec_ty: ty::t, pub fn iter_vec_uniq(bcx: block, vptr: ValueRef, vec_ty: ty::t, fill: ValueRef, f: iter_vec_block) -> block { - let _icx = bcx.insn_ctxt("tvec::iter_vec_uniq"); + let _icx = push_ctxt("tvec::iter_vec_uniq"); let data_ptr = get_dataptr(bcx, get_bodyptr(bcx, vptr)); iter_vec_raw(bcx, data_ptr, vec_ty, fill, f) } pub fn iter_vec_unboxed(bcx: block, body_ptr: ValueRef, vec_ty: ty::t, f: iter_vec_block) -> block { - let _icx = bcx.insn_ctxt("tvec::iter_vec_unboxed"); + let _icx = push_ctxt("tvec::iter_vec_unboxed"); let fill = get_fill(bcx, body_ptr); let dataptr = get_dataptr(bcx, body_ptr); return iter_vec_raw(bcx, dataptr, vec_ty, fill, f); diff --git a/src/librustc/middle/trans/type_.rs b/src/librustc/middle/trans/type_.rs new file mode 100644 index 00000000000..34a15033109 --- /dev/null +++ b/src/librustc/middle/trans/type_.rs @@ -0,0 +1,374 @@ +// Copyright 2013 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +use core::prelude::*; + +use lib::llvm::{llvm, TypeRef, Bool, False, True, TypeKind}; +use lib::llvm::{Float, Double, X86_FP80, PPC_FP128, FP128}; + +use middle::ty; + +use middle::trans::context::CrateContext; +use middle::trans::base; + +use syntax::ast; +use syntax::abi::{Architecture, X86, X86_64, Arm, Mips}; +use back::abi; + +use core::vec; +use core::cast; + +use core::libc::{c_uint}; + +#[deriving(Eq)] +pub struct Type { + priv rf: TypeRef +} + +macro_rules! ty ( + ($e:expr) => ( Type::from_ref(unsafe { $e })) +) + +/** + * Wrapper for LLVM TypeRef + */ +impl Type { + #[inline(always)] + pub fn from_ref(r: TypeRef) -> Type { + Type { + rf: r + } + } + + #[inline(always)] // So it doesn't kill --opt-level=0 builds of the compiler + pub fn to_ref(&self) -> TypeRef { + self.rf + } + + pub fn void() -> Type { + ty!(llvm::LLVMVoidTypeInContext(base::task_llcx())) + } + + pub fn nil() -> Type { + Type::empty_struct() + } + + pub fn metadata() -> Type { + ty!(llvm::LLVMMetadataTypeInContext(base::task_llcx())) + } + + pub fn i1() -> Type { + ty!(llvm::LLVMInt1TypeInContext(base::task_llcx())) + } + + pub fn i8() -> Type { + ty!(llvm::LLVMInt8TypeInContext(base::task_llcx())) + } + + pub fn i16() -> Type { + ty!(llvm::LLVMInt16TypeInContext(base::task_llcx())) + } + + pub fn i32() -> Type { + ty!(llvm::LLVMInt32TypeInContext(base::task_llcx())) + } + + pub fn i64() -> Type { + ty!(llvm::LLVMInt64TypeInContext(base::task_llcx())) + } + + pub fn f32() -> Type { + ty!(llvm::LLVMFloatTypeInContext(base::task_llcx())) + } + + pub fn f64() -> Type { + ty!(llvm::LLVMDoubleTypeInContext(base::task_llcx())) + } + + pub fn bool() -> Type { + Type::i8() + } + + pub fn char() -> Type { + Type::i32() + } + + pub fn i8p() -> Type { + Type::i8().ptr_to() + } + + pub fn int(arch: Architecture) -> Type { + match arch { + X86 | Arm | Mips => Type::i32(), + X86_64 => Type::i64() + } + } + + pub fn float(_: Architecture) -> Type { + // All architectures currently just use doubles as the default + // float size + Type::f64() + } + + pub fn int_from_ty(ctx: &CrateContext, t: ast::int_ty) -> Type { + match t { + ast::ty_i => ctx.int_type, + ast::ty_char => Type::char(), + ast::ty_i8 => Type::i8(), + ast::ty_i16 => Type::i16(), + ast::ty_i32 => Type::i32(), + ast::ty_i64 => Type::i64() + } + } + + pub fn uint_from_ty(ctx: &CrateContext, t: ast::uint_ty) -> Type { + match t { + ast::ty_u => ctx.int_type, + ast::ty_u8 => Type::i8(), + ast::ty_u16 => Type::i16(), + ast::ty_u32 => Type::i32(), + ast::ty_u64 => Type::i64() + } + } + + pub fn float_from_ty(ctx: &CrateContext, t: ast::float_ty) -> Type { + match t { + ast::ty_f => ctx.float_type, + ast::ty_f32 => Type::f32(), + ast::ty_f64 => Type::f64() + } + } + + pub fn size_t(arch: Architecture) -> Type { + Type::int(arch) + } + + pub fn func(args: &[Type], ret: &Type) -> Type { + let vec : &[TypeRef] = unsafe { cast::transmute(args) }; + ty!(llvm::LLVMFunctionType(ret.to_ref(), vec::raw::to_ptr(vec), + args.len() as c_uint, False)) + } + + pub fn func_pair(cx: &CrateContext, fn_ty: &Type) -> Type { + Type::struct_([fn_ty.ptr_to(), Type::opaque_cbox_ptr(cx)], false) + } + + pub fn ptr(ty: Type) -> Type { + ty!(llvm::LLVMPointerType(ty.to_ref(), 0 as c_uint)) + } + + pub fn struct_(els: &[Type], packed: bool) -> Type { + let els : &[TypeRef] = unsafe { cast::transmute(els) }; + ty!(llvm::LLVMStructTypeInContext(base::task_llcx(), vec::raw::to_ptr(els), + els.len() as c_uint, packed as Bool)) + } + + pub fn named_struct(name: &str) -> Type { + let ctx = base::task_llcx(); + ty!(name.as_c_str(|s| llvm::LLVMStructCreateNamed(ctx, s))) + } + + pub fn empty_struct() -> Type { + Type::struct_([], false) + } + + pub fn vtable() -> Type { + Type::array(&Type::i8().ptr_to(), 1) + } + + pub fn generic_glue_fn(cx: &mut CrateContext) -> Type { + match cx.tn.find_type("glue_fn") { + Some(ty) => return ty, + None => () + } + + let ty = cx.tydesc_type.get_field(abi::tydesc_field_drop_glue); + cx.tn.associate_type("glue_fn", &ty); + + return ty; + } + + pub fn tydesc(arch: Architecture) -> Type { + let mut tydesc = Type::named_struct("tydesc"); + let tydescpp = tydesc.ptr_to().ptr_to(); + let pvoid = Type::i8p(); + let glue_fn_ty = Type::func([ Type::nil().ptr_to(), tydescpp, pvoid ], + &Type::void()).ptr_to(); + + let int_ty = Type::int(arch); + + let elems = [ + int_ty, int_ty, + glue_fn_ty, glue_fn_ty, glue_fn_ty, glue_fn_ty, + pvoid, pvoid + ]; + + tydesc.set_struct_body(elems, false); + + return tydesc; + } + + pub fn array(ty: &Type, len: u64) -> Type { + ty!(llvm::LLVMArrayType(ty.to_ref(), len as c_uint)) + } + + pub fn vector(ty: &Type, len: u64) -> Type { + ty!(llvm::LLVMVectorType(ty.to_ref(), len as c_uint)) + } + + pub fn vec(arch: Architecture, ty: &Type) -> Type { + Type::struct_( + [ Type::int(arch), Type::int(arch), Type::array(ty, 0) ], + false) + } + + pub fn opaque_vec(arch: Architecture) -> Type { + Type::vec(arch, &Type::i8()) + } + + #[inline] + pub fn box_header_fields(ctx: &CrateContext) -> ~[Type] { + ~[ + ctx.int_type, ctx.tydesc_type.ptr_to(), + Type::i8().ptr_to(), Type::i8().ptr_to() + ] + } + + pub fn box_header(ctx: &CrateContext) -> Type { + Type::struct_(Type::box_header_fields(ctx), false) + } + + pub fn box(ctx: &CrateContext, ty: &Type) -> Type { + Type::struct_(Type::box_header_fields(ctx) + [*ty], false) + } + + pub fn opaque_box(ctx: &CrateContext) -> Type { + Type::box(ctx, &Type::i8()) + } + + pub fn unique(ctx: &CrateContext, ty: &Type) -> Type { + Type::box(ctx, ty) + } + + pub fn opaque_cbox_ptr(cx: &CrateContext) -> Type { + Type::opaque_box(cx).ptr_to() + } + + pub fn enum_discrim(cx: &CrateContext) -> Type { + cx.int_type + } + + pub fn captured_tydescs(ctx: &CrateContext, num: uint) -> Type { + Type::struct_(vec::from_elem(num, ctx.tydesc_type.ptr_to()), false) + } + + pub fn opaque_trait(ctx: &CrateContext, store: ty::TraitStore) -> Type { + let tydesc_ptr = ctx.tydesc_type.ptr_to(); + match store { + ty::BoxTraitStore => { + Type::struct_( + [ tydesc_ptr, Type::opaque_box(ctx).ptr_to() ], + false) + } + ty::UniqTraitStore => { + Type::struct_( + [ tydesc_ptr, Type::unique(ctx, &Type::i8()).ptr_to()], + false) + } + ty::RegionTraitStore(*) => { + Type::struct_( + [ tydesc_ptr, Type::i8().ptr_to() ], + false) + } + } + } + + pub fn kind(&self) -> TypeKind { + unsafe { + llvm::LLVMGetTypeKind(self.to_ref()) + } + } + + pub fn set_struct_body(&mut self, els: &[Type], packed: bool) { + unsafe { + let vec : &[TypeRef] = cast::transmute(els); + llvm::LLVMStructSetBody(self.to_ref(), vec::raw::to_ptr(vec), + els.len() as c_uint, packed as Bool) + } + } + + pub fn ptr_to(&self) -> Type { + ty!(llvm::LLVMPointerType(self.to_ref(), 0)) + } + + pub fn get_field(&self, idx: uint) -> Type { + unsafe { + let num_fields = llvm::LLVMCountStructElementTypes(self.to_ref()) as uint; + let mut elems = vec::from_elem(num_fields, 0 as TypeRef); + + llvm::LLVMGetStructElementTypes(self.to_ref(), vec::raw::to_mut_ptr(elems)); + + Type::from_ref(elems[idx]) + } + } + + pub fn is_packed(&self) -> bool { + unsafe { + llvm::LLVMIsPackedStruct(self.to_ref()) == True + } + } + + pub fn element_type(&self) -> Type { + unsafe { + Type::from_ref(llvm::LLVMGetElementType(self.to_ref())) + } + } + + pub fn array_length(&self) -> uint { + unsafe { + llvm::LLVMGetArrayLength(self.to_ref()) as uint + } + } + + pub fn field_types(&self) -> ~[Type] { + unsafe { + let n_elts = llvm::LLVMCountStructElementTypes(self.to_ref()) as uint; + if n_elts == 0 { + return ~[]; + } + let mut elts = vec::from_elem(n_elts, 0 as TypeRef); + llvm::LLVMGetStructElementTypes(self.to_ref(), &mut elts[0]); + cast::transmute(elts) + } + } + + pub fn return_type(&self) -> Type { + ty!(llvm::LLVMGetReturnType(self.to_ref())) + } + + pub fn func_params(&self) -> ~[Type] { + unsafe { + let n_args = llvm::LLVMCountParamTypes(self.to_ref()) as uint; + let args = vec::from_elem(n_args, 0 as TypeRef); + llvm::LLVMGetParamTypes(self.to_ref(), vec::raw::to_ptr(args)); + cast::transmute(args) + } + } + + pub fn float_width(&self) -> uint { + match self.kind() { + Float => 32, + Double => 64, + X86_FP80 => 80, + FP128 | PPC_FP128 => 128, + _ => fail!("llvm_float_width called on a non-float type") + } + } +} diff --git a/src/librustc/middle/trans/type_of.rs b/src/librustc/middle/trans/type_of.rs index 058a6b9f48e..448ded6b70f 100644 --- a/src/librustc/middle/trans/type_of.rs +++ b/src/librustc/middle/trans/type_of.rs @@ -10,61 +10,60 @@ use core::prelude::*; -use lib::llvm::llvm; -use lib::llvm::{TypeRef}; use middle::trans::adt; -use middle::trans::base; use middle::trans::common::*; -use middle::trans::common; use middle::ty; use util::ppaux; +use middle::trans::type_::Type; + use syntax::ast; pub fn arg_is_indirect(_: &CrateContext, arg_ty: &ty::t) -> bool { !ty::type_is_immediate(*arg_ty) } -pub fn type_of_explicit_arg(ccx: &mut CrateContext, arg_ty: &ty::t) -> TypeRef { +pub fn type_of_explicit_arg(ccx: &mut CrateContext, arg_ty: &ty::t) -> Type { let llty = type_of(ccx, *arg_ty); - if arg_is_indirect(ccx, arg_ty) {T_ptr(llty)} else {llty} + if arg_is_indirect(ccx, arg_ty) { + llty.ptr_to() + } else { + llty + } } pub fn type_of_explicit_args(ccx: &mut CrateContext, - inputs: &[ty::t]) -> ~[TypeRef] { + inputs: &[ty::t]) -> ~[Type] { inputs.map(|arg_ty| type_of_explicit_arg(ccx, arg_ty)) } -pub fn type_of_fn(cx: &mut CrateContext, inputs: &[ty::t], output: ty::t) - -> TypeRef { - unsafe { - let mut atys: ~[TypeRef] = ~[]; +pub fn type_of_fn(cx: &mut CrateContext, inputs: &[ty::t], output: ty::t) -> Type { + let mut atys: ~[Type] = ~[]; - // Arg 0: Output pointer. - // (if the output type is non-immediate) - let output_is_immediate = ty::type_is_immediate(output); - let lloutputtype = type_of(cx, output); - if !output_is_immediate { - atys.push(T_ptr(lloutputtype)); - } + // Arg 0: Output pointer. + // (if the output type is non-immediate) + let output_is_immediate = ty::type_is_immediate(output); + let lloutputtype = type_of(cx, output); + if !output_is_immediate { + atys.push(lloutputtype.ptr_to()); + } - // Arg 1: Environment - atys.push(T_opaque_box_ptr(cx)); + // Arg 1: Environment + atys.push(Type::opaque_box(cx).ptr_to()); - // ... then explicit args. - atys.push_all(type_of_explicit_args(cx, inputs)); + // ... then explicit args. + atys.push_all(type_of_explicit_args(cx, inputs)); - // Use the output as the actual return value if it's immediate. - if output_is_immediate && !ty::type_is_nil(output) { - T_fn(atys, lloutputtype) - } else { - T_fn(atys, llvm::LLVMVoidTypeInContext(cx.llcx)) - } + // Use the output as the actual return value if it's immediate. + if output_is_immediate && !ty::type_is_nil(output) { + Type::func(atys, &lloutputtype) + } else { + Type::func(atys, &Type::void()) } } // Given a function type and a count of ty params, construct an llvm type -pub fn type_of_fn_from_ty(cx: &mut CrateContext, fty: ty::t) -> TypeRef { +pub fn type_of_fn_from_ty(cx: &mut CrateContext, fty: ty::t) -> Type { match ty::get(fty).sty { ty::ty_closure(ref f) => type_of_fn(cx, f.sig.inputs, f.sig.output), ty::ty_bare_fn(ref f) => type_of_fn(cx, f.sig.inputs, f.sig.output), @@ -74,7 +73,7 @@ pub fn type_of_fn_from_ty(cx: &mut CrateContext, fty: ty::t) -> TypeRef { } } -pub fn type_of_non_gc_box(cx: &mut CrateContext, t: ty::t) -> TypeRef { +pub fn type_of_non_gc_box(cx: &mut CrateContext, t: ty::t) -> Type { assert!(!ty::type_needs_infer(t)); let t_norm = ty::normalize_ty(cx.tcx, t); @@ -84,11 +83,11 @@ pub fn type_of_non_gc_box(cx: &mut CrateContext, t: ty::t) -> TypeRef { match ty::get(t).sty { ty::ty_box(mt) => { let ty = type_of(cx, mt.ty); - T_ptr(T_box(cx, ty)) + Type::box(cx, &ty).ptr_to() } ty::ty_uniq(mt) => { let ty = type_of(cx, mt.ty); - T_ptr(T_unique(cx, ty)) + Type::unique(cx, &ty).ptr_to() } _ => { cx.sess.bug("non-box in type_of_non_gc_box"); @@ -109,18 +108,18 @@ pub fn type_of_non_gc_box(cx: &mut CrateContext, t: ty::t) -> TypeRef { // recursive types. For example, `static_size_of_enum()` relies on this // behavior. -pub fn sizing_type_of(cx: &mut CrateContext, t: ty::t) -> TypeRef { - match cx.llsizingtypes.find(&t) { - Some(t) => return *t, +pub fn sizing_type_of(cx: &mut CrateContext, t: ty::t) -> Type { + match cx.llsizingtypes.find_copy(&t) { + Some(t) => return t, None => () } let llsizingty = match ty::get(t).sty { - ty::ty_nil | ty::ty_bot => T_nil(), - ty::ty_bool => T_bool(), - ty::ty_int(t) => T_int_ty(cx, t), - ty::ty_uint(t) => T_uint_ty(cx, t), - ty::ty_float(t) => T_float_ty(cx, t), + ty::ty_nil | ty::ty_bot => Type::nil(), + ty::ty_bool => Type::bool(), + ty::ty_int(t) => Type::int_from_ty(cx, t), + ty::ty_uint(t) => Type::uint_from_ty(cx, t), + ty::ty_float(t) => Type::float_from_ty(cx, t), ty::ty_estr(ty::vstore_uniq) | ty::ty_estr(ty::vstore_box) | @@ -132,48 +131,46 @@ pub fn sizing_type_of(cx: &mut CrateContext, t: ty::t) -> TypeRef { ty::ty_ptr(*) | ty::ty_rptr(*) | ty::ty_type | - ty::ty_opaque_closure_ptr(*) => T_ptr(T_i8()), + ty::ty_opaque_closure_ptr(*) => Type::i8p(), ty::ty_estr(ty::vstore_slice(*)) | ty::ty_evec(_, ty::vstore_slice(*)) => { - T_struct([T_ptr(T_i8()), T_ptr(T_i8())], false) + Type::struct_([Type::i8p(), Type::i8p()], false) } - ty::ty_bare_fn(*) => T_ptr(T_i8()), - ty::ty_closure(*) => T_struct([T_ptr(T_i8()), T_ptr(T_i8())], false), - ty::ty_trait(_, _, store, _) => T_opaque_trait(cx, store), + ty::ty_bare_fn(*) => Type::i8p(), + ty::ty_closure(*) => Type::struct_([Type::i8p(), Type::i8p()], false), + ty::ty_trait(_, _, store, _) => Type::opaque_trait(cx, store), - ty::ty_estr(ty::vstore_fixed(size)) => T_array(T_i8(), size), + ty::ty_estr(ty::vstore_fixed(size)) => Type::array(&Type::i8(), size as u64), ty::ty_evec(mt, ty::vstore_fixed(size)) => { - T_array(sizing_type_of(cx, mt.ty), size) + Type::array(&sizing_type_of(cx, mt.ty), size as u64) } ty::ty_unboxed_vec(mt) => { let sz_ty = sizing_type_of(cx, mt.ty); - T_vec(cx, sz_ty) + Type::vec(cx.sess.targ_cfg.arch, &sz_ty) } ty::ty_tup(*) | ty::ty_enum(*) => { let repr = adt::represent_type(cx, t); - T_struct(adt::sizing_fields_of(cx, repr), false) + Type::struct_(adt::sizing_fields_of(cx, repr), false) } ty::ty_struct(did, _) => { if ty::type_is_simd(cx.tcx, t) { let et = ty::simd_type(cx.tcx, t); let n = ty::simd_size(cx.tcx, t); - T_vector(type_of(cx, et), n) + Type::vector(&type_of(cx, et), n as u64) } else { let repr = adt::represent_type(cx, t); let packed = ty::lookup_packed(cx.tcx, did); - T_struct(adt::sizing_fields_of(cx, repr), packed) + Type::struct_(adt::sizing_fields_of(cx, repr), packed) } } ty::ty_self(_) | ty::ty_infer(*) | ty::ty_param(*) | ty::ty_err(*) => { - cx.tcx.sess.bug( - fmt!("fictitious type %? in sizing_type_of()", - ty::get(t).sty)) + cx.tcx.sess.bug(fmt!("fictitious type %? in sizing_type_of()", ty::get(t).sty)) } }; @@ -182,7 +179,7 @@ pub fn sizing_type_of(cx: &mut CrateContext, t: ty::t) -> TypeRef { } // NB: If you update this, be sure to update `sizing_type_of()` as well. -pub fn type_of(cx: &mut CrateContext, t: ty::t) -> TypeRef { +pub fn type_of(cx: &mut CrateContext, t: ty::t) -> Type { debug!("type_of %?: %?", t, ty::get(t)); // Check the cache. @@ -204,14 +201,14 @@ pub fn type_of(cx: &mut CrateContext, t: ty::t) -> TypeRef { return llty; } - let llty = match ty::get(t).sty { - ty::ty_nil | ty::ty_bot => T_nil(), - ty::ty_bool => T_bool(), - ty::ty_int(t) => T_int_ty(cx, t), - ty::ty_uint(t) => T_uint_ty(cx, t), - ty::ty_float(t) => T_float_ty(cx, t), + let mut llty = match ty::get(t).sty { + ty::ty_nil | ty::ty_bot => Type::nil(), + ty::ty_bool => Type::bool(), + ty::ty_int(t) => Type::int_from_ty(cx, t), + ty::ty_uint(t) => Type::uint_from_ty(cx, t), + ty::ty_float(t) => Type::float_from_ty(cx, t), ty::ty_estr(ty::vstore_uniq) => { - T_unique_ptr(T_unique(cx, T_vec(cx, T_i8()))) + Type::unique(cx, &Type::vec(cx.sess.targ_cfg.arch, &Type::i8())).ptr_to() } ty::ty_enum(did, ref substs) => { // Only create the named struct, but don't fill it in. We @@ -219,84 +216,79 @@ pub fn type_of(cx: &mut CrateContext, t: ty::t) -> TypeRef { // avoids creating more than one copy of the enum when one // of the enum's variants refers to the enum itself. - common::T_named_struct(llvm_type_name(cx, - an_enum, - did, - substs.tps)) + Type::named_struct(llvm_type_name(cx, an_enum, did, substs.tps)) } ty::ty_estr(ty::vstore_box) => { - T_box_ptr(T_box(cx, T_vec(cx, T_i8()))) + Type::box(cx, &Type::vec(cx.sess.targ_cfg.arch, &Type::i8())).ptr_to() } ty::ty_evec(ref mt, ty::vstore_box) => { let e_ty = type_of(cx, mt.ty); - let v_ty = T_vec(cx, e_ty); - T_box_ptr(T_box(cx, v_ty)) + let v_ty = Type::vec(cx.sess.targ_cfg.arch, &e_ty); + Type::box(cx, &v_ty).ptr_to() } ty::ty_box(ref mt) => { let ty = type_of(cx, mt.ty); - T_box_ptr(T_box(cx, ty)) + Type::box(cx, &ty).ptr_to() } - ty::ty_opaque_box => T_box_ptr(T_box(cx, T_i8())), + ty::ty_opaque_box => Type::opaque_box(cx).ptr_to(), ty::ty_uniq(ref mt) => { let ty = type_of(cx, mt.ty); - T_unique_ptr(T_unique(cx, ty)) + Type::unique(cx, &ty).ptr_to() } ty::ty_evec(ref mt, ty::vstore_uniq) => { let ty = type_of(cx, mt.ty); - let ty = T_vec(cx, ty); - T_unique_ptr(T_unique(cx, ty)) + let ty = Type::vec(cx.sess.targ_cfg.arch, &ty); + Type::unique(cx, &ty).ptr_to() } ty::ty_unboxed_vec(ref mt) => { let ty = type_of(cx, mt.ty); - T_vec(cx, ty) + Type::vec(cx.sess.targ_cfg.arch, &ty) } - ty::ty_ptr(ref mt) => T_ptr(type_of(cx, mt.ty)), - ty::ty_rptr(_, ref mt) => T_ptr(type_of(cx, mt.ty)), + ty::ty_ptr(ref mt) => type_of(cx, mt.ty).ptr_to(), + ty::ty_rptr(_, ref mt) => type_of(cx, mt.ty).ptr_to(), ty::ty_evec(ref mt, ty::vstore_slice(_)) => { - let p_ty = T_ptr(type_of(cx, mt.ty)); - let u_ty = T_uint_ty(cx, ast::ty_u); - T_struct([p_ty, u_ty], false) + let p_ty = type_of(cx, mt.ty).ptr_to(); + let u_ty = Type::uint_from_ty(cx, ast::ty_u); + Type::struct_([p_ty, u_ty], false) } ty::ty_estr(ty::vstore_slice(_)) => { - T_struct([T_ptr(T_i8()), T_uint_ty(cx, ast::ty_u)], false) + // This means we get a nicer name in the output + cx.tn.find_type("str_slice").get() } ty::ty_estr(ty::vstore_fixed(n)) => { - T_array(T_i8(), n + 1u /* +1 for trailing null */) + Type::array(&Type::i8(), (n + 1u) as u64) } ty::ty_evec(ref mt, ty::vstore_fixed(n)) => { - T_array(type_of(cx, mt.ty), n) + Type::array(&type_of(cx, mt.ty), n as u64) } - ty::ty_bare_fn(_) => T_ptr(type_of_fn_from_ty(cx, t)), + ty::ty_bare_fn(_) => type_of_fn_from_ty(cx, t).ptr_to(), ty::ty_closure(_) => { let ty = type_of_fn_from_ty(cx, t); - T_fn_pair(cx, ty) + Type::func_pair(cx, &ty) } - ty::ty_trait(_, _, store, _) => T_opaque_trait(cx, store), - ty::ty_type => T_ptr(cx.tydesc_type), + ty::ty_trait(_, _, store, _) => Type::opaque_trait(cx, store), + ty::ty_type => cx.tydesc_type.ptr_to(), ty::ty_tup(*) => { let repr = adt::represent_type(cx, t); - T_struct(adt::fields_of(cx, repr), false) + Type::struct_(adt::fields_of(cx, repr), false) } - ty::ty_opaque_closure_ptr(_) => T_opaque_box_ptr(cx), + ty::ty_opaque_closure_ptr(_) => Type::opaque_box(cx).ptr_to(), ty::ty_struct(did, ref substs) => { - if ty::type_is_simd(cx.tcx, t) { - let et = ty::simd_type(cx.tcx, t); - let n = ty::simd_size(cx.tcx, t); - T_vector(type_of(cx, et), n) - } else { - // Only create the named struct, but don't fill it in. We fill it - // in *after* placing it into the type cache. This prevents - // infinite recursion with recursive struct types. - T_named_struct(llvm_type_name(cx, - a_struct, - did, - substs.tps)) - } + if ty::type_is_simd(cx.tcx, t) { + let et = ty::simd_type(cx.tcx, t); + let n = ty::simd_size(cx.tcx, t); + Type::vector(&type_of(cx, et), n as u64) + } else { + // Only create the named struct, but don't fill it in. We fill it + // in *after* placing it into the type cache. This prevents + // infinite recursion with recursive struct types. + Type::named_struct(llvm_type_name(cx, a_struct, did, substs.tps)) + } } ty::ty_self(*) => cx.tcx.sess.unimpl("type_of: ty_self"), ty::ty_infer(*) => cx.tcx.sess.bug("type_of with ty_infer"), @@ -310,16 +302,14 @@ pub fn type_of(cx: &mut CrateContext, t: ty::t) -> TypeRef { match ty::get(t).sty { ty::ty_enum(*) => { let repr = adt::represent_type(cx, t); - common::set_struct_body(llty, adt::fields_of(cx, repr), - false); + llty.set_struct_body(adt::fields_of(cx, repr), false); } ty::ty_struct(did, _) => { if !ty::type_is_simd(cx.tcx, t) { let repr = adt::represent_type(cx, t); let packed = ty::lookup_packed(cx.tcx, did); - common::set_struct_body(llty, adt::fields_of(cx, repr), - packed); + llty.set_struct_body(adt::fields_of(cx, repr), packed); } } _ => () @@ -336,33 +326,18 @@ pub fn llvm_type_name(cx: &CrateContext, did: ast::def_id, tps: &[ty::t]) -> ~str { let name = match what { - a_struct => { "~struct" } - an_enum => { "~enum" } + a_struct => { "struct" } + an_enum => { "enum" } }; - return fmt!( - "%s %s[#%d]", - name, - ppaux::parameterized( - cx.tcx, - ty::item_path_str(cx.tcx, did), - None, - tps), - did.crate - ); + let tstr = ppaux::parameterized(cx.tcx, ty::item_path_str(cx.tcx, did), None, tps); + if did.crate == 0 { + fmt!("%s.%s", name, tstr) + } else { + fmt!("%s.%s[#%d]", name, tstr, did.crate) + } } -pub fn type_of_dtor(ccx: &mut CrateContext, self_ty: ty::t) -> TypeRef { - T_fn([T_ptr(type_of(ccx, self_ty))] /* self */, T_void()) -} - -pub fn type_of_rooted(ccx: &mut CrateContext, t: ty::t) -> TypeRef { - let addrspace = base::get_tydesc(ccx, t).addrspace; - debug!("type_of_rooted %s in addrspace %u", - ppaux::ty_to_str(ccx.tcx, t), addrspace as uint); - return T_root(type_of(ccx, t), addrspace); -} - -pub fn type_of_glue_fn(ccx: &CrateContext) -> TypeRef { - let tydescpp = T_ptr(T_ptr(ccx.tydesc_type)); - return T_fn([T_ptr(T_nil()), tydescpp, T_ptr(T_i8())], T_void()); +pub fn type_of_dtor(ccx: &mut CrateContext, self_ty: ty::t) -> Type { + let self_ty = type_of(ccx, self_ty).ptr_to(); + Type::func([self_ty], &Type::void()) } diff --git a/src/librustc/middle/trans/type_use.rs b/src/librustc/middle/trans/type_use.rs index 8c4ff441564..4f532885c92 100644 --- a/src/librustc/middle/trans/type_use.rs +++ b/src/librustc/middle/trans/type_use.rs @@ -117,46 +117,43 @@ pub fn type_uses_for(ccx: @mut CrateContext, fn_id: def_id, n_tps: uint) _, _) => { if abi.is_intrinsic() { - let flags = match cx.ccx.sess.str_of(i.ident).as_slice() { - "size_of" | "pref_align_of" | "min_align_of" | - "uninit" | "init" | "transmute" | "move_val" | - "move_val_init" => use_repr, + let nm = cx.ccx.sess.str_of(i.ident); + let name = nm.as_slice(); + let flags = if name.starts_with("atomic_") { + 0 + } else { + match name { + "size_of" | "pref_align_of" | "min_align_of" | + "uninit" | "init" | "transmute" | "move_val" | + "move_val_init" => use_repr, - "get_tydesc" | "needs_drop" => use_tydesc, + "get_tydesc" | "needs_drop" => use_tydesc, - "atomic_cxchg" | "atomic_cxchg_acq"| - "atomic_cxchg_rel"| "atomic_load" | - "atomic_load_acq" | "atomic_store" | - "atomic_store_rel"| "atomic_xchg" | - "atomic_xadd" | "atomic_xsub" | - "atomic_xchg_acq" | "atomic_xadd_acq" | - "atomic_xsub_acq" | "atomic_xchg_rel" | - "atomic_xadd_rel" | "atomic_xsub_rel" => 0, + "visit_tydesc" | "forget" | "frame_address" | + "morestack_addr" => 0, - "visit_tydesc" | "forget" | "frame_address" | - "morestack_addr" => 0, + "memcpy32" | "memcpy64" | "memmove32" | "memmove64" | + "memset32" | "memset64" => use_repr, - "memcpy32" | "memcpy64" | "memmove32" | "memmove64" | - "memset32" | "memset64" => use_repr, + "sqrtf32" | "sqrtf64" | "powif32" | "powif64" | + "sinf32" | "sinf64" | "cosf32" | "cosf64" | + "powf32" | "powf64" | "expf32" | "expf64" | + "exp2f32" | "exp2f64" | "logf32" | "logf64" | + "log10f32"| "log10f64"| "log2f32" | "log2f64" | + "fmaf32" | "fmaf64" | "fabsf32" | "fabsf64" | + "floorf32"| "floorf64"| "ceilf32" | "ceilf64" | + "truncf32"| "truncf64" => 0, - "sqrtf32" | "sqrtf64" | "powif32" | "powif64" | - "sinf32" | "sinf64" | "cosf32" | "cosf64" | - "powf32" | "powf64" | "expf32" | "expf64" | - "exp2f32" | "exp2f64" | "logf32" | "logf64" | - "log10f32"| "log10f64"| "log2f32" | "log2f64" | - "fmaf32" | "fmaf64" | "fabsf32" | "fabsf64" | - "floorf32"| "floorf64"| "ceilf32" | "ceilf64" | - "truncf32"| "truncf64" => 0, + "ctpop8" | "ctpop16" | "ctpop32" | "ctpop64" => 0, - "ctpop8" | "ctpop16" | "ctpop32" | "ctpop64" => 0, + "ctlz8" | "ctlz16" | "ctlz32" | "ctlz64" => 0, + "cttz8" | "cttz16" | "cttz32" | "cttz64" => 0, - "ctlz8" | "ctlz16" | "ctlz32" | "ctlz64" => 0, - "cttz8" | "cttz16" | "cttz32" | "cttz64" => 0, + "bswap16" | "bswap32" | "bswap64" => 0, - "bswap16" | "bswap32" | "bswap64" => 0, - - // would be cool to make these an enum instead of strings! - _ => fail!("unknown intrinsic in type_use") + // would be cool to make these an enum instead of strings! + _ => fail!("unknown intrinsic in type_use") + } }; for uint::range(0u, n_tps) |n| { cx.uses[n] |= flags;} } diff --git a/src/librustc/middle/trans/uniq.rs b/src/librustc/middle/trans/uniq.rs index 4ce2b780011..d27d6efb241 100644 --- a/src/librustc/middle/trans/uniq.rs +++ b/src/librustc/middle/trans/uniq.rs @@ -21,7 +21,7 @@ use middle::ty; pub fn make_free_glue(bcx: block, vptrptr: ValueRef, box_ty: ty::t) -> block { - let _icx = bcx.insn_ctxt("uniq::make_free_glue"); + let _icx = push_ctxt("uniq::make_free_glue"); let box_datum = immediate_rvalue(Load(bcx, vptrptr), box_ty); let not_null = IsNotNull(bcx, box_datum.val); @@ -38,7 +38,7 @@ pub fn make_free_glue(bcx: block, vptrptr: ValueRef, box_ty: ty::t) } pub fn duplicate(bcx: block, src_box: ValueRef, src_ty: ty::t) -> Result { - let _icx = bcx.insn_ctxt("uniq::duplicate"); + let _icx = push_ctxt("uniq::duplicate"); // Load the body of the source (*src) let src_datum = immediate_rvalue(src_box, src_ty); diff --git a/src/librustc/middle/trans/write_guard.rs b/src/librustc/middle/trans/write_guard.rs index d76d4642801..eb5376da696 100644 --- a/src/librustc/middle/trans/write_guard.rs +++ b/src/librustc/middle/trans/write_guard.rs @@ -28,6 +28,8 @@ use middle::ty; use syntax::codemap::span; use syntax::ast; +use middle::trans::type_::Type; + pub fn root_and_write_guard(datum: &Datum, mut bcx: block, span: span, @@ -64,20 +66,15 @@ pub fn return_to_mut(mut bcx: block, debug!("write_guard::return_to_mut(root_key=%?, %s, %s, %s)", root_key, bcx.to_str(), - val_str(bcx.ccx().tn, frozen_val_ref), - val_str(bcx.ccx().tn, bits_val_ref)); + bcx.val_to_str(frozen_val_ref), + bcx.val_to_str(bits_val_ref)); - let box_ptr = - Load(bcx, PointerCast(bcx, - frozen_val_ref, - T_ptr(T_ptr(T_i8())))); + let box_ptr = Load(bcx, PointerCast(bcx, frozen_val_ref, Type::i8p().ptr_to())); - let bits_val = - Load(bcx, bits_val_ref); + let bits_val = Load(bcx, bits_val_ref); if bcx.tcx().sess.debug_borrows() { - bcx = callee::trans_lang_call( - bcx, + bcx = callee::trans_lang_call( bcx, bcx.tcx().lang_items.unrecord_borrow_fn(), [ box_ptr, @@ -146,10 +143,7 @@ fn root(datum: &Datum, DynaMut => bcx.tcx().lang_items.borrow_as_mut_fn(), }; - let box_ptr = Load(bcx, - PointerCast(bcx, - scratch.val, - T_ptr(T_ptr(T_i8())))); + let box_ptr = Load(bcx, PointerCast(bcx, scratch.val, Type::i8p().ptr_to())); bcx = callee::trans_lang_call( bcx, @@ -194,6 +188,6 @@ fn perform_write_guard(datum: &Datum, callee::trans_lang_call( bcx, bcx.tcx().lang_items.check_not_borrowed_fn(), - [PointerCast(bcx, llval, T_ptr(T_i8())), filename, line], + [PointerCast(bcx, llval, Type::i8p()), filename, line], expr::Ignore) } diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index 8595adcd1c7..e67955505f6 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -21,7 +21,7 @@ use middle::ty; use middle::subst::Subst; use middle::typeck; use middle; -use util::ppaux::{note_and_explain_region, bound_region_to_str}; +use util::ppaux::{note_and_explain_region, bound_region_to_str, bound_region_ptr_to_str}; use util::ppaux::{trait_store_to_str, ty_to_str, vstore_to_str}; use util::ppaux::{Repr, UserString}; use util::common::{indenter}; @@ -3531,12 +3531,12 @@ pub fn type_err_to_str(cx: ctxt, err: &type_err) -> ~str { terr_regions_insufficiently_polymorphic(br, _) => { fmt!("expected bound lifetime parameter %s, \ but found concrete lifetime", - bound_region_to_str(cx, br)) + bound_region_ptr_to_str(cx, br)) } terr_regions_overly_polymorphic(br, _) => { fmt!("expected concrete lifetime, \ but found bound lifetime parameter %s", - bound_region_to_str(cx, br)) + bound_region_ptr_to_str(cx, br)) } terr_vstores_differ(k, ref values) => { fmt!("%s storage differs: expected %s but found %s", diff --git a/src/librustc/middle/typeck/check/mod.rs b/src/librustc/middle/typeck/check/mod.rs index 13ded501679..a8ae9041482 100644 --- a/src/librustc/middle/typeck/check/mod.rs +++ b/src/librustc/middle/typeck/check/mod.rs @@ -107,7 +107,7 @@ use middle::typeck::{isr_alist, lookup_def_ccx}; use middle::typeck::no_params; use middle::typeck::{require_same_types, method_map, vtable_map}; use util::common::{block_query, indenter, loop_query}; -use util::ppaux::{bound_region_to_str}; +use util::ppaux::{bound_region_to_str,bound_region_ptr_to_str}; use util::ppaux; @@ -680,7 +680,7 @@ impl FnCtxt { } else { result::Err(RegionError { msg: fmt!("named region `%s` not in scope here", - bound_region_to_str(self.tcx(), br)), + bound_region_ptr_to_str(self.tcx(), br)), replacement: self.infcx().next_region_var_nb(span) }) } @@ -3434,252 +3434,268 @@ pub fn check_intrinsic_type(ccx: @mut CrateCtxt, it: @ast::foreign_item) { } let tcx = ccx.tcx; - let str = ccx.tcx.sess.str_of(it.ident); - let (n_tps, inputs, output) = match str.as_slice() { - "size_of" | - "pref_align_of" | "min_align_of" => (1u, ~[], ty::mk_uint()), - "init" => (1u, ~[], param(ccx, 0u)), - "uninit" => (1u, ~[], param(ccx, 0u)), - "forget" => (1u, ~[ param(ccx, 0) ], ty::mk_nil()), - "transmute" => (2, ~[ param(ccx, 0) ], param(ccx, 1)), - "move_val" | "move_val_init" => { - (1u, - ~[ - ty::mk_mut_rptr(tcx, ty::re_bound(ty::br_anon(0)), param(ccx, 0)), - param(ccx, 0u) - ], - ty::mk_nil()) - } - "needs_drop" => (1u, ~[], ty::mk_bool()), + let nm = ccx.tcx.sess.str_of(it.ident); + let name = nm.as_slice(); + let (n_tps, inputs, output) = if name.starts_with("atomic_") { + let split : ~[&str] = name.split_iter('_').collect(); + assert!(split.len() >= 2, "Atomic intrinsic not correct format"); - "atomic_cxchg" | "atomic_cxchg_acq"| "atomic_cxchg_rel" => { - (0, - ~[ - ty::mk_mut_rptr(tcx, - ty::re_bound(ty::br_anon(0)), - ty::mk_int()), - ty::mk_int(), - ty::mk_int() - ], - ty::mk_int()) - } - "atomic_load" | "atomic_load_acq" => { - (0, - ~[ - ty::mk_imm_rptr(tcx, ty::re_bound(ty::br_anon(0)), ty::mk_int()) - ], - ty::mk_int()) - } - "atomic_store" | "atomic_store_rel" => { - (0, - ~[ - ty::mk_mut_rptr(tcx, ty::re_bound(ty::br_anon(0)), ty::mk_int()), - ty::mk_int() - ], - ty::mk_nil()) - } - "atomic_xchg" | "atomic_xadd" | "atomic_xsub" | - "atomic_xchg_acq" | "atomic_xadd_acq" | "atomic_xsub_acq" | - "atomic_xchg_rel" | "atomic_xadd_rel" | "atomic_xsub_rel" => { - (0, - ~[ - ty::mk_mut_rptr(tcx, ty::re_bound(ty::br_anon(0)), ty::mk_int()), - ty::mk_int() - ], - ty::mk_int()) + //We only care about the operation here + match split[1] { + "cxchg" => (0, ~[ty::mk_mut_rptr(tcx, + ty::re_bound(ty::br_anon(0)), + ty::mk_int()), + ty::mk_int(), + ty::mk_int() + ], ty::mk_int()), + "load" => (0, + ~[ + ty::mk_imm_rptr(tcx, ty::re_bound(ty::br_anon(0)), ty::mk_int()) + ], + ty::mk_int()), + "store" => (0, + ~[ + ty::mk_mut_rptr(tcx, ty::re_bound(ty::br_anon(0)), ty::mk_int()), + ty::mk_int() + ], + ty::mk_nil()), + + "xchg" | "xadd" | "xsub" | "and" | "nand" | "or" | "xor" | "max" | + "min" | "umax" | "umin" => { + (0, ~[ty::mk_mut_rptr(tcx, + ty::re_bound(ty::br_anon(0)), + ty::mk_int()), ty::mk_int() ], ty::mk_int()) + } + + op => { + tcx.sess.span_err(it.span, + fmt!("unrecognized atomic operation function: `%s`", + op)); + return; + } } - "get_tydesc" => { - // FIXME (#3730): return *intrinsic::tydesc, not *() - (1u, ~[], ty::mk_nil_ptr(ccx.tcx)) - } - "visit_tydesc" => { - let tydesc_name = special_idents::tydesc; - assert!(tcx.intrinsic_defs.contains_key(&tydesc_name)); - let (_, tydesc_ty) = tcx.intrinsic_defs.get_copy(&tydesc_name); - let (_, visitor_object_ty) = ty::visitor_object_ty(tcx); - let td_ptr = ty::mk_ptr(ccx.tcx, ty::mt { - ty: tydesc_ty, - mutbl: ast::m_imm - }); - (0, ~[ td_ptr, visitor_object_ty ], ty::mk_nil()) - } - "frame_address" => { - let fty = ty::mk_closure(ccx.tcx, ty::ClosureTy { - purity: ast::impure_fn, - sigil: ast::BorrowedSigil, - onceness: ast::Once, - region: ty::re_bound(ty::br_anon(0)), - bounds: ty::EmptyBuiltinBounds(), - sig: ty::FnSig { - bound_lifetime_names: opt_vec::Empty, - inputs: ~[ty::mk_imm_ptr(ccx.tcx, ty::mk_mach_uint(ast::ty_u8))], - output: ty::mk_nil() - } - }); - (0u, ~[fty], ty::mk_nil()) - } - "morestack_addr" => { - (0u, ~[], ty::mk_nil_ptr(ccx.tcx)) - } - "memcpy32" => { - (1, - ~[ - ty::mk_ptr(tcx, ty::mt { - ty: param(ccx, 0), - mutbl: ast::m_mutbl - }), - ty::mk_ptr(tcx, ty::mt { - ty: param(ccx, 0), + } else { + match name { + "size_of" | + "pref_align_of" | "min_align_of" => (1u, ~[], ty::mk_uint()), + "init" => (1u, ~[], param(ccx, 0u)), + "uninit" => (1u, ~[], param(ccx, 0u)), + "forget" => (1u, ~[ param(ccx, 0) ], ty::mk_nil()), + "transmute" => (2, ~[ param(ccx, 0) ], param(ccx, 1)), + "move_val" | "move_val_init" => { + (1u, + ~[ + ty::mk_mut_rptr(tcx, ty::re_bound(ty::br_anon(0)), param(ccx, 0)), + param(ccx, 0u) + ], + ty::mk_nil()) + } + "needs_drop" => (1u, ~[], ty::mk_bool()), + + "atomic_xchg" | "atomic_xadd" | "atomic_xsub" | + "atomic_xchg_acq" | "atomic_xadd_acq" | "atomic_xsub_acq" | + "atomic_xchg_rel" | "atomic_xadd_rel" | "atomic_xsub_rel" => { + (0, + ~[ + ty::mk_mut_rptr(tcx, ty::re_bound(ty::br_anon(0)), ty::mk_int()), + ty::mk_int() + ], + ty::mk_int()) + } + + "get_tydesc" => { + // FIXME (#3730): return *intrinsic::tydesc, not *() + (1u, ~[], ty::mk_nil_ptr(ccx.tcx)) + } + "visit_tydesc" => { + let tydesc_name = special_idents::tydesc; + assert!(tcx.intrinsic_defs.contains_key(&tydesc_name)); + let (_, tydesc_ty) = tcx.intrinsic_defs.get_copy(&tydesc_name); + let (_, visitor_object_ty) = ty::visitor_object_ty(tcx); + let td_ptr = ty::mk_ptr(ccx.tcx, ty::mt { + ty: tydesc_ty, mutbl: ast::m_imm - }), - ty::mk_u32() - ], - ty::mk_nil()) - } - "memcpy64" => { - (1, - ~[ - ty::mk_ptr(tcx, ty::mt { - ty: param(ccx, 0), - mutbl: ast::m_mutbl - }), - ty::mk_ptr(tcx, ty::mt { - ty: param(ccx, 0), - mutbl: ast::m_imm - }), - ty::mk_u64() - ], - ty::mk_nil()) - } - "memmove32" => { - (1, - ~[ - ty::mk_ptr(tcx, ty::mt { - ty: param(ccx, 0), - mutbl: ast::m_mutbl - }), - ty::mk_ptr(tcx, ty::mt { - ty: param(ccx, 0), - mutbl: ast::m_imm - }), - ty::mk_u32() - ], - ty::mk_nil()) - } - "memmove64" => { - (1, - ~[ - ty::mk_ptr(tcx, ty::mt { - ty: param(ccx, 0), - mutbl: ast::m_mutbl - }), - ty::mk_ptr(tcx, ty::mt { - ty: param(ccx, 0), - mutbl: ast::m_imm - }), - ty::mk_u64() - ], - ty::mk_nil()) - } - "memset32" => { - (1, - ~[ - ty::mk_ptr(tcx, ty::mt { - ty: param(ccx, 0), - mutbl: ast::m_mutbl - }), - ty::mk_u8(), - ty::mk_u32() - ], - ty::mk_nil()) - } - "memset64" => { - (1, - ~[ - ty::mk_ptr(tcx, ty::mt { - ty: param(ccx, 0), - mutbl: ast::m_mutbl - }), - ty::mk_u8(), - ty::mk_u64() - ], - ty::mk_nil()) - } - "sqrtf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), - "sqrtf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), - "powif32" => { - (0, - ~[ ty::mk_f32(), ty::mk_i32() ], - ty::mk_f32()) - } - "powif64" => { - (0, - ~[ ty::mk_f64(), ty::mk_i32() ], - ty::mk_f64()) - } - "sinf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), - "sinf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), - "cosf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), - "cosf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), - "powf32" => { - (0, - ~[ ty::mk_f32(), ty::mk_f32() ], - ty::mk_f32()) - } - "powf64" => { - (0, - ~[ ty::mk_f64(), ty::mk_f64() ], - ty::mk_f64()) - } - "expf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), - "expf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), - "exp2f32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), - "exp2f64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), - "logf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), - "logf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), - "log10f32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), - "log10f64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), - "log2f32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), - "log2f64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), - "fmaf32" => { - (0, - ~[ ty::mk_f32(), ty::mk_f32(), ty::mk_f32() ], - ty::mk_f32()) - } - "fmaf64" => { - (0, - ~[ ty::mk_f64(), ty::mk_f64(), ty::mk_f64() ], - ty::mk_f64()) - } - "fabsf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), - "fabsf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), - "floorf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), - "floorf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), - "ceilf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), - "ceilf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), - "truncf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), - "truncf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), - "ctpop8" => (0, ~[ ty::mk_i8() ], ty::mk_i8()), - "ctpop16" => (0, ~[ ty::mk_i16() ], ty::mk_i16()), - "ctpop32" => (0, ~[ ty::mk_i32() ], ty::mk_i32()), - "ctpop64" => (0, ~[ ty::mk_i64() ], ty::mk_i64()), - "ctlz8" => (0, ~[ ty::mk_i8() ], ty::mk_i8()), - "ctlz16" => (0, ~[ ty::mk_i16() ], ty::mk_i16()), - "ctlz32" => (0, ~[ ty::mk_i32() ], ty::mk_i32()), - "ctlz64" => (0, ~[ ty::mk_i64() ], ty::mk_i64()), - "cttz8" => (0, ~[ ty::mk_i8() ], ty::mk_i8()), - "cttz16" => (0, ~[ ty::mk_i16() ], ty::mk_i16()), - "cttz32" => (0, ~[ ty::mk_i32() ], ty::mk_i32()), - "cttz64" => (0, ~[ ty::mk_i64() ], ty::mk_i64()), - "bswap16" => (0, ~[ ty::mk_i16() ], ty::mk_i16()), - "bswap32" => (0, ~[ ty::mk_i32() ], ty::mk_i32()), - "bswap64" => (0, ~[ ty::mk_i64() ], ty::mk_i64()), - ref other => { - tcx.sess.span_err(it.span, - fmt!("unrecognized intrinsic function: `%s`", - *other)); - return; + }); + (0, ~[ td_ptr, visitor_object_ty ], ty::mk_nil()) + } + "frame_address" => { + let fty = ty::mk_closure(ccx.tcx, ty::ClosureTy { + purity: ast::impure_fn, + sigil: ast::BorrowedSigil, + onceness: ast::Once, + region: ty::re_bound(ty::br_anon(0)), + bounds: ty::EmptyBuiltinBounds(), + sig: ty::FnSig { + bound_lifetime_names: opt_vec::Empty, + inputs: ~[ty::mk_imm_ptr(ccx.tcx, ty::mk_mach_uint(ast::ty_u8))], + output: ty::mk_nil() + } + }); + (0u, ~[fty], ty::mk_nil()) + } + "morestack_addr" => { + (0u, ~[], ty::mk_nil_ptr(ccx.tcx)) + } + "memcpy32" => { + (1, + ~[ + ty::mk_ptr(tcx, ty::mt { + ty: param(ccx, 0), + mutbl: ast::m_mutbl + }), + ty::mk_ptr(tcx, ty::mt { + ty: param(ccx, 0), + mutbl: ast::m_imm + }), + ty::mk_u32() + ], + ty::mk_nil()) + } + "memcpy64" => { + (1, + ~[ + ty::mk_ptr(tcx, ty::mt { + ty: param(ccx, 0), + mutbl: ast::m_mutbl + }), + ty::mk_ptr(tcx, ty::mt { + ty: param(ccx, 0), + mutbl: ast::m_imm + }), + ty::mk_u64() + ], + ty::mk_nil()) + } + "memmove32" => { + (1, + ~[ + ty::mk_ptr(tcx, ty::mt { + ty: param(ccx, 0), + mutbl: ast::m_mutbl + }), + ty::mk_ptr(tcx, ty::mt { + ty: param(ccx, 0), + mutbl: ast::m_imm + }), + ty::mk_u32() + ], + ty::mk_nil()) + } + "memmove64" => { + (1, + ~[ + ty::mk_ptr(tcx, ty::mt { + ty: param(ccx, 0), + mutbl: ast::m_mutbl + }), + ty::mk_ptr(tcx, ty::mt { + ty: param(ccx, 0), + mutbl: ast::m_imm + }), + ty::mk_u64() + ], + ty::mk_nil()) + } + "memset32" => { + (1, + ~[ + ty::mk_ptr(tcx, ty::mt { + ty: param(ccx, 0), + mutbl: ast::m_mutbl + }), + ty::mk_u8(), + ty::mk_u32() + ], + ty::mk_nil()) + } + "memset64" => { + (1, + ~[ + ty::mk_ptr(tcx, ty::mt { + ty: param(ccx, 0), + mutbl: ast::m_mutbl + }), + ty::mk_u8(), + ty::mk_u64() + ], + ty::mk_nil()) + } + "sqrtf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), + "sqrtf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), + "powif32" => { + (0, + ~[ ty::mk_f32(), ty::mk_i32() ], + ty::mk_f32()) + } + "powif64" => { + (0, + ~[ ty::mk_f64(), ty::mk_i32() ], + ty::mk_f64()) + } + "sinf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), + "sinf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), + "cosf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), + "cosf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), + "powf32" => { + (0, + ~[ ty::mk_f32(), ty::mk_f32() ], + ty::mk_f32()) + } + "powf64" => { + (0, + ~[ ty::mk_f64(), ty::mk_f64() ], + ty::mk_f64()) + } + "expf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), + "expf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), + "exp2f32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), + "exp2f64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), + "logf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), + "logf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), + "log10f32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), + "log10f64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), + "log2f32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), + "log2f64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), + "fmaf32" => { + (0, + ~[ ty::mk_f32(), ty::mk_f32(), ty::mk_f32() ], + ty::mk_f32()) + } + "fmaf64" => { + (0, + ~[ ty::mk_f64(), ty::mk_f64(), ty::mk_f64() ], + ty::mk_f64()) + } + "fabsf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), + "fabsf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), + "floorf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), + "floorf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), + "ceilf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), + "ceilf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), + "truncf32" => (0, ~[ ty::mk_f32() ], ty::mk_f32()), + "truncf64" => (0, ~[ ty::mk_f64() ], ty::mk_f64()), + "ctpop8" => (0, ~[ ty::mk_i8() ], ty::mk_i8()), + "ctpop16" => (0, ~[ ty::mk_i16() ], ty::mk_i16()), + "ctpop32" => (0, ~[ ty::mk_i32() ], ty::mk_i32()), + "ctpop64" => (0, ~[ ty::mk_i64() ], ty::mk_i64()), + "ctlz8" => (0, ~[ ty::mk_i8() ], ty::mk_i8()), + "ctlz16" => (0, ~[ ty::mk_i16() ], ty::mk_i16()), + "ctlz32" => (0, ~[ ty::mk_i32() ], ty::mk_i32()), + "ctlz64" => (0, ~[ ty::mk_i64() ], ty::mk_i64()), + "cttz8" => (0, ~[ ty::mk_i8() ], ty::mk_i8()), + "cttz16" => (0, ~[ ty::mk_i16() ], ty::mk_i16()), + "cttz32" => (0, ~[ ty::mk_i32() ], ty::mk_i32()), + "cttz64" => (0, ~[ ty::mk_i64() ], ty::mk_i64()), + "bswap16" => (0, ~[ ty::mk_i16() ], ty::mk_i16()), + "bswap32" => (0, ~[ ty::mk_i32() ], ty::mk_i32()), + "bswap64" => (0, ~[ ty::mk_i64() ], ty::mk_i64()), + ref other => { + tcx.sess.span_err(it.span, + fmt!("unrecognized intrinsic function: `%s`", + *other)); + return; + } } }; let fty = ty::mk_bare_fn(tcx, ty::BareFnTy { diff --git a/src/librustc/middle/typeck/check/regionck.rs b/src/librustc/middle/typeck/check/regionck.rs index 4cedb71245a..2ff8ffdd6b2 100644 --- a/src/librustc/middle/typeck/check/regionck.rs +++ b/src/librustc/middle/typeck/check/regionck.rs @@ -690,13 +690,13 @@ fn constrain_regions_in_type( let tcx = rcx.fcx.ccx.tcx; debug!("constrain_regions_in_type(minimum_lifetime=%s, ty=%s)", - region_to_str(tcx, minimum_lifetime), + region_to_str(tcx, "", false, minimum_lifetime), ty_to_str(tcx, ty)); do relate_nested_regions(tcx, Some(minimum_lifetime), ty) |r_sub, r_sup| { debug!("relate(r_sub=%s, r_sup=%s)", - region_to_str(tcx, r_sub), - region_to_str(tcx, r_sup)); + region_to_str(tcx, "", false, r_sub), + region_to_str(tcx, "", false, r_sup)); if r_sup.is_bound() || r_sub.is_bound() { // a bound region is one which appears inside an fn type. diff --git a/src/librustc/middle/typeck/check/regionmanip.rs b/src/librustc/middle/typeck/check/regionmanip.rs index 9db873a25b0..54b449eeb40 100644 --- a/src/librustc/middle/typeck/check/regionmanip.rs +++ b/src/librustc/middle/typeck/check/regionmanip.rs @@ -149,7 +149,7 @@ pub fn replace_bound_regions_in_fn_sig( tcx.sess.bug( fmt!("Bound region not found in \ in_scope_regions list: %s", - region_to_str(tcx, r))); + region_to_str(tcx, "", false, r))); } } } diff --git a/src/librustc/middle/typeck/infer/mod.rs b/src/librustc/middle/typeck/infer/mod.rs index 410e2fe23c1..2e83acfa9f4 100644 --- a/src/librustc/middle/typeck/infer/mod.rs +++ b/src/librustc/middle/typeck/infer/mod.rs @@ -821,7 +821,7 @@ impl InferCtxt { // debug message. let rvar = self.next_region_var_nb(span); debug!("Bound region %s maps to %?", - bound_region_to_str(self.tcx, br), + bound_region_to_str(self.tcx, "", false, br), rvar); rvar }); diff --git a/src/librustc/middle/typeck/infer/sub.rs b/src/librustc/middle/typeck/infer/sub.rs index b0f055dc77d..c5e0e2c8f01 100644 --- a/src/librustc/middle/typeck/infer/sub.rs +++ b/src/librustc/middle/typeck/infer/sub.rs @@ -179,7 +179,7 @@ impl Combine for Sub { None, b) |br| { let skol = self.infcx.region_vars.new_skolemized(br); debug!("Bound region %s skolemized to %?", - bound_region_to_str(self.infcx.tcx, br), + bound_region_to_str(self.infcx.tcx, "", false, br), skol); skol } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index 64af555bb37..8994c81bfb9 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -112,7 +112,7 @@ pub fn explain_region_and_span(cx: ctxt, region: ty::Region) idx + 1), br_fresh(_) => fmt!("an anonymous lifetime defined on"), _ => fmt!("the lifetime %s as defined on", - bound_region_to_str(cx, fr.bound_region)) + bound_region_ptr_to_str(cx, fr.bound_region)) }; match cx.items.find(&fr.scope_id) { @@ -147,22 +147,23 @@ pub fn explain_region_and_span(cx: ctxt, region: ty::Region) } } -pub fn bound_region_to_str(cx: ctxt, br: bound_region) -> ~str { - bound_region_to_str_space(cx, "&", br) +pub fn bound_region_ptr_to_str(cx: ctxt, br: bound_region) -> ~str { + bound_region_to_str(cx, "&", true, br) } -pub fn bound_region_to_str_space(cx: ctxt, - prefix: &str, - br: bound_region) - -> ~str { - if cx.sess.verbose() { return fmt!("%s%? ", prefix, br); } +pub fn bound_region_to_str(cx: ctxt, + prefix: &str, space: bool, + br: bound_region) -> ~str { + let space_str = if space { " " } else { "" }; + + if cx.sess.verbose() { return fmt!("%s%?%s", prefix, br, space_str); } match br { - br_named(id) => fmt!("%s'%s ", prefix, cx.sess.str_of(id)), - br_self => fmt!("%s'self ", prefix), + br_named(id) => fmt!("%s'%s%s", prefix, cx.sess.str_of(id), space_str), + br_self => fmt!("%s'self%s", prefix, space_str), br_anon(_) => prefix.to_str(), br_fresh(_) => prefix.to_str(), - br_cap_avoid(_, br) => bound_region_to_str_space(cx, prefix, *br) + br_cap_avoid(_, br) => bound_region_to_str(cx, prefix, space, *br) } } @@ -208,13 +209,15 @@ pub fn re_scope_id_to_str(cx: ctxt, node_id: ast::node_id) -> ~str { // In general, if you are giving a region error message, // you should use `explain_region()` or, better yet, // `note_and_explain_region()` -pub fn region_to_str(cx: ctxt, region: Region) -> ~str { - region_to_str_space(cx, "&", region) +pub fn region_ptr_to_str(cx: ctxt, region: Region) -> ~str { + region_to_str(cx, "&", true, region) } -pub fn region_to_str_space(cx: ctxt, prefix: &str, region: Region) -> ~str { +pub fn region_to_str(cx: ctxt, prefix: &str, space: bool, region: Region) -> ~str { + let space_str = if space { " " } else { "" }; + if cx.sess.verbose() { - return fmt!("%s%? ", prefix, region); + return fmt!("%s%?%s", prefix, region, space_str); } // These printouts are concise. They do not contain all the information @@ -223,14 +226,14 @@ pub fn region_to_str_space(cx: ctxt, prefix: &str, region: Region) -> ~str { // `explain_region()` or `note_and_explain_region()`. match region { re_scope(_) => prefix.to_str(), - re_bound(br) => bound_region_to_str_space(cx, prefix, br), - re_free(ref fr) => bound_region_to_str_space(cx, prefix, fr.bound_region), + re_bound(br) => bound_region_to_str(cx, prefix, space, br), + re_free(ref fr) => bound_region_to_str(cx, prefix, space, fr.bound_region), re_infer(ReSkolemized(_, br)) => { - bound_region_to_str_space(cx, prefix, br) + bound_region_to_str(cx, prefix, space, br) } re_infer(ReVar(_)) => prefix.to_str(), - re_static => fmt!("%s'static ", prefix), - re_empty => fmt!("%s' ", prefix) + re_static => fmt!("%s'static%s", prefix, space_str), + re_empty => fmt!("%s'%s", prefix, space_str) } } @@ -256,7 +259,7 @@ pub fn vstore_to_str(cx: ctxt, vs: ty::vstore) -> ~str { ty::vstore_fixed(n) => fmt!("%u", n), ty::vstore_uniq => ~"~", ty::vstore_box => ~"@", - ty::vstore_slice(r) => region_to_str_space(cx, "&", r) + ty::vstore_slice(r) => region_ptr_to_str(cx, r) } } @@ -264,7 +267,7 @@ pub fn trait_store_to_str(cx: ctxt, s: ty::TraitStore) -> ~str { match s { ty::UniqTraitStore => ~"~", ty::BoxTraitStore => ~"@", - ty::RegionTraitStore(r) => region_to_str_space(cx, "&", r) + ty::RegionTraitStore(r) => region_ptr_to_str(cx, r) } } @@ -340,7 +343,7 @@ pub fn ty_to_str(cx: ctxt, typ: t) -> ~str { (ast::OwnedSigil, ty::re_static) => {} (_, region) => { - s.push_str(region_to_str_space(cx, "", region)); + s.push_str(region_to_str(cx, "", true, region)); } } @@ -414,7 +417,7 @@ pub fn ty_to_str(cx: ctxt, typ: t) -> ~str { ty_uniq(ref tm) => ~"~" + mt_to_str(cx, tm), ty_ptr(ref tm) => ~"*" + mt_to_str(cx, tm), ty_rptr(r, ref tm) => { - region_to_str_space(cx, "&", r) + mt_to_str(cx, tm) + region_ptr_to_str(cx, r) + mt_to_str(cx, tm) } ty_unboxed_vec(ref tm) => { fmt!("unboxed_vec<%s>", mt_to_str(cx, tm)) } ty_type => ~"type", @@ -431,13 +434,15 @@ pub fn ty_to_str(cx: ctxt, typ: t) -> ~str { ty_infer(infer_ty) => infer_ty.to_str(), ty_err => ~"[type error]", ty_param(param_ty {idx: id, def_id: did}) => { + let mut parm = (('T' as uint) + id) as char; + if (parm as uint) > ('Z' as uint) { + parm = (parm as uint - 26) as char; + } + if cx.sess.verbose() { - fmt!("'%s:%?", - str::from_bytes([('a' as u8) + (id as u8)]), - did) + fmt!("%c:%?", parm, did) } else { - fmt!("'%s", - str::from_bytes([('a' as u8) + (id as u8)])) + fmt!("%c", parm) } } ty_self(*) => ~"Self", @@ -457,9 +462,9 @@ pub fn ty_to_str(cx: ctxt, typ: t) -> ~str { } ty_estr(vs) => fmt!("%s%s", vstore_to_str(cx, vs), "str"), ty_opaque_box => ~"@?", - ty_opaque_closure_ptr(ast::BorrowedSigil) => ~"closure&", - ty_opaque_closure_ptr(ast::ManagedSigil) => ~"closure@", - ty_opaque_closure_ptr(ast::OwnedSigil) => ~"closure~", + ty_opaque_closure_ptr(ast::BorrowedSigil) => ~"&closure", + ty_opaque_closure_ptr(ast::ManagedSigil) => ~"@closure", + ty_opaque_closure_ptr(ast::OwnedSigil) => ~"~closure", } } @@ -468,18 +473,20 @@ pub fn parameterized(cx: ctxt, self_r: Option, tps: &[ty::t]) -> ~str { - let r_str = match self_r { - None => ~"", - Some(r) => { - fmt!("/%s", region_to_str(cx, r)) - } + let mut strs = ~[]; + match self_r { + None => (), + Some(r) => { + strs.push(region_to_str(cx, "", false, r)) + } }; - if tps.len() > 0u { - let strs = vec::map(tps, |t| ty_to_str(cx, *t)); - fmt!("%s%s<%s>", base, r_str, strs.connect(",")) + strs += vec::map(tps, |t| ty_to_str(cx, *t)); + + if strs.len() > 0u { + fmt!("%s<%s>", base, strs.connect(",")) } else { - fmt!("%s%s", base, r_str) + fmt!("%s", base) } } @@ -597,7 +604,7 @@ impl Repr for @ast::pat { impl Repr for ty::Region { fn repr(&self, tcx: ctxt) -> ~str { - region_to_str(tcx, *self) + region_to_str(tcx, "", false, *self) } } diff --git a/src/libstd/unstable/intrinsics.rs b/src/libstd/unstable/intrinsics.rs index 13425007785..c38b013a75a 100644 --- a/src/libstd/unstable/intrinsics.rs +++ b/src/libstd/unstable/intrinsics.rs @@ -42,22 +42,38 @@ pub extern "rust-intrinsic" { /// Atomic compare and exchange, release ordering. pub fn atomic_cxchg_rel(dst: &mut int, old: int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_cxchg_acqrel(dst: &mut int, old: int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_cxchg_relaxed(dst: &mut int, old: int, src: int) -> int; + + /// Atomic load, sequentially consistent. pub fn atomic_load(src: &int) -> int; /// Atomic load, acquire ordering. pub fn atomic_load_acq(src: &int) -> int; + #[cfg(not(stage0))] + pub fn atomic_load_relaxed(src: &int) -> int; + /// Atomic store, sequentially consistent. pub fn atomic_store(dst: &mut int, val: int); /// Atomic store, release ordering. pub fn atomic_store_rel(dst: &mut int, val: int); + #[cfg(not(stage0))] + pub fn atomic_store_relaxed(dst: &mut int, val: int); + /// Atomic exchange, sequentially consistent. pub fn atomic_xchg(dst: &mut int, src: int) -> int; /// Atomic exchange, acquire ordering. pub fn atomic_xchg_acq(dst: &mut int, src: int) -> int; /// Atomic exchange, release ordering. pub fn atomic_xchg_rel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_xchg_acqrel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_xchg_relaxed(dst: &mut int, src: int) -> int; /// Atomic addition, sequentially consistent. pub fn atomic_xadd(dst: &mut int, src: int) -> int; @@ -65,6 +81,10 @@ pub extern "rust-intrinsic" { pub fn atomic_xadd_acq(dst: &mut int, src: int) -> int; /// Atomic addition, release ordering. pub fn atomic_xadd_rel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_xadd_acqrel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_xadd_relaxed(dst: &mut int, src: int) -> int; /// Atomic subtraction, sequentially consistent. pub fn atomic_xsub(dst: &mut int, src: int) -> int; @@ -72,6 +92,98 @@ pub extern "rust-intrinsic" { pub fn atomic_xsub_acq(dst: &mut int, src: int) -> int; /// Atomic subtraction, release ordering. pub fn atomic_xsub_rel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_xsub_acqrel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_xsub_relaxed(dst: &mut int, src: int) -> int; + + #[cfg(not(stage0))] + pub fn atomic_and(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_and_acq(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_and_rel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_and_acqrel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_and_relaxed(dst: &mut int, src: int) -> int; + + #[cfg(not(stage0))] + pub fn atomic_nand(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_nand_acq(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_nand_rel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_nand_acqrel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_nand_relaxed(dst: &mut int, src: int) -> int; + + #[cfg(not(stage0))] + pub fn atomic_or(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_or_acq(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_or_rel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_or_acqrel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_or_relaxed(dst: &mut int, src: int) -> int; + + #[cfg(not(stage0))] + pub fn atomic_xor(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_xor_acq(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_xor_rel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_xor_acqrel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_xor_relaxed(dst: &mut int, src: int) -> int; + + #[cfg(not(stage0))] + pub fn atomic_max(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_max_acq(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_max_rel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_max_acqrel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_max_relaxed(dst: &mut int, src: int) -> int; + + #[cfg(not(stage0))] + pub fn atomic_min(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_min_acq(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_min_rel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_min_acqrel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_min_relaxed(dst: &mut int, src: int) -> int; + + #[cfg(not(stage0))] + pub fn atomic_umin(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_umin_acq(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_umin_rel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_umin_acqrel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_umin_relaxed(dst: &mut int, src: int) -> int; + + #[cfg(not(stage0))] + pub fn atomic_umax(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_umax_acq(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_umax_rel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_umax_acqrel(dst: &mut int, src: int) -> int; + #[cfg(not(stage0))] + pub fn atomic_umax_relaxed(dst: &mut int, src: int) -> int; /// The size of a type in bytes. /// diff --git a/src/test/compile-fail/regions-bounds.rs b/src/test/compile-fail/regions-bounds.rs index ab2620d46fd..35ba3862438 100644 --- a/src/test/compile-fail/regions-bounds.rs +++ b/src/test/compile-fail/regions-bounds.rs @@ -16,11 +16,11 @@ struct an_enum<'self>(&'self int); struct a_class<'self> { x:&'self int } fn a_fn1<'a,'b>(e: an_enum<'a>) -> an_enum<'b> { - return e; //~ ERROR mismatched types: expected `an_enum/&'b ` but found `an_enum/&'a ` + return e; //~ ERROR mismatched types: expected `an_enum<'b>` but found `an_enum<'a>` } fn a_fn3<'a,'b>(e: a_class<'a>) -> a_class<'b> { - return e; //~ ERROR mismatched types: expected `a_class/&'b ` but found `a_class/&'a ` + return e; //~ ERROR mismatched types: expected `a_class<'b>` but found `a_class<'a>` } fn a_fn4<'a,'b>() {