diff options
30 files changed, 517 insertions, 886 deletions
diff --git a/src/librustc/back/upcall.rs b/src/librustc/back/upcall.rs index 731fa1c0ad7..76bba481619 100644 --- a/src/librustc/back/upcall.rs +++ b/src/librustc/back/upcall.rs @@ -24,17 +24,17 @@ pub struct Upcalls { macro_rules! upcall ( (fn $name:ident($($arg:expr),+) -> $ret:expr) => ({ - let fn_ty = Type::func([ $($arg),* ], $ret); + 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 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 fn_ty = Type::func([], &$ret); let decl = base::decl_cdecl_fn(llmod, ~"upcall_" + stringify!($name), fn_ty); base::set_no_unwind(decl); decl @@ -42,7 +42,7 @@ macro_rules! upcall ( ) pub fn declare_upcalls(targ_cfg: @session::config, llmod: ModuleRef) -> @Upcalls { - let opaque_ptr = Type::i8().to_ptr(); + let opaque_ptr = Type::i8().ptr_to(); let int_ty = Type::int(targ_cfg.arch); @Upcalls { diff --git a/src/librustc/lib/llvm.rs b/src/librustc/lib/llvm.rs index 627474b2189..ec3bf61608c 100644 --- a/src/librustc/lib/llvm.rs +++ b/src/librustc/lib/llvm.rs @@ -2141,7 +2141,7 @@ impl TypeNames { } pub fn find_name<'r>(&'r self, ty: &Type) -> Option<&'r str> { - match self.type_names.find(ty.to_ref()) { + match self.type_names.find(&ty.to_ref()) { Some(a) => Some(a.slice(0, a.len())), None => None } @@ -2151,14 +2151,14 @@ impl TypeNames { self.named_types.find_equiv(&s).map_consume(|x| Type::from_ref(*x)) } - pub fn type_to_str(&self, ty: TypeRef) -> ~str { + pub fn type_to_str(&self, ty: Type) -> ~str { match self.find_name(&ty) { option::Some(name) => return name.to_owned(), None => () } unsafe { - let kind = llvm::LLVMGetTypeKind(ty); + let kind = ty.kind(); match kind { Void => ~"Void", @@ -2172,31 +2172,28 @@ impl TypeNames { Metadata => ~"Metadata", X86_MMX => ~"X86_MMAX", Integer => { - fmt!("i%d", llvm::LLVMGetIntTypeWidth(ty) as int) + fmt!("i%d", llvm::LLVMGetIntTypeWidth(ty.to_ref()) as int) } Function => { - let out_ty = 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)); - + 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) } Struct => { - let tys = struct_tys(ty); + let tys = ty.field_types(); let tys = tys.map(|&ty| self.type_to_str(ty)).connect(", "); fmt!("{%s}", tys) } Array => { - let el_ty = llvm::LLVMGetElementType(ty); + let el_ty = ty.element_type(); let el_ty = self.type_to_str(el_ty); - let len = llvm::LLVMGetArrayLength(ty) as uint; + let len = ty.array_length(); fmt!("[%s x %u]", el_ty, len) } Pointer => { - let el_ty = llvm::LLVMGetElementType(ty); + let el_ty = ty.element_type(); let el_ty = self.type_to_str(el_ty); fmt!("*%s", el_ty) } @@ -2207,32 +2204,12 @@ impl TypeNames { pub fn val_to_str(&self, val: ValueRef) -> ~str { unsafe { - self.type_to_str(llvm::LLVMTypeOf(val)) + let ty = Type::from_ref(llvm::LLVMTypeOf(val)); + self.type_to_str(ty) } } } -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; - } -} - /* Memory-managed interface to target data. */ diff --git a/src/librustc/middle/trans/_match.rs b/src/librustc/middle/trans/_match.rs index db5a642019c..72da71afed6 100644 --- a/src/librustc/middle/trans/_match.rs +++ b/src/librustc/middle/trans/_match.rs @@ -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() { diff --git a/src/librustc/middle/trans/adt.rs b/src/librustc/middle/trans/adt.rs index 65163e384b1..906c9d028eb 100644 --- a/src/librustc/middle/trans/adt.rs +++ b/src/librustc/middle/trans/adt.rs @@ -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 { @@ -260,10 +262,8 @@ fn generic_fields_of(cx: &mut CrateContext, r: &Repr, sizing: bool) -> ~[Type] { let most_aligned = most_aligned.get(); let padding = largest_size - most_aligned.size; - assert!(padding >= 0); - struct_llfields(cx, most_aligned, sizing) - + [Type::array(Type::i8(), padding /*bad*/as uint)] + + [Type::array(&Type::i8(), padding)] } } } @@ -439,7 +439,7 @@ pub fn trans_field_ptr(bcx: block, r: &Repr, val: ValueRef, discr: int, // The unit-like case might have a nonzero number of unit-like fields. // (e.g., Result or Either with () as one side.) let ty = type_of::type_of(bcx.ccx(), nullfields[ix]); - assert_eq!(machine::llsize_of_alloc(bcx.ccx(), llty), 0); + 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, ty.ptr_to()) @@ -457,7 +457,7 @@ fn struct_field_ptr(bcx: block, st: &Struct, val: ValueRef, ix: uint, type_of::type_of(ccx, ty) }; let real_ty = Type::struct_(fields, st.packed); - PointerCast(bcx, val, real_llty.to_ptr().to_ref()) + 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(Type::array(Type::i8(), size).to_ref()) + 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 17294107ce3..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; diff --git a/src/librustc/middle/trans/base.rs b/src/librustc/middle/trans/base.rs index de91a9c593a..8ec05f447ee 100644 --- a/src/librustc/middle/trans/base.rs +++ b/src/librustc/middle/trans/base.rs @@ -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; @@ -150,7 +152,7 @@ pub fn decl_fn(llmod: ModuleRef, name: &str, cc: lib::llvm::CallConv, ty: Type) } pub fn decl_cdecl_fn(llmod: ModuleRef, name: &str, ty: Type) -> ValueRef { - return decl_fn(llmod, name, lib::llvm::CCallConv, llty); + return decl_fn(llmod, name, lib::llvm::CCallConv, ty); } // Only use this if you are going to actually define the function. It's @@ -229,7 +231,7 @@ pub fn opaque_box_body(bcx: block, let _icx = bcx.insn_ctxt("opaque_box_body"); let ccx = bcx.ccx(); let ty = type_of(ccx, body_t); - let ty = Type::box(ccx, ty); + let ty = Type::box(ccx, &ty); let boxptr = PointerCast(bcx, boxptr, ty.ptr_to()); GEPi(bcx, boxptr, [0u, abi::box_field_body]) } @@ -281,15 +283,8 @@ pub fn malloc_raw_dyn(bcx: block, * 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 = llvm::LLVMGetElementType(val_ty(val)).ptr_to(); - PointerCast(bcx, val, non_gc_t) - } +pub fn non_gc_box_cast(_: block, val: ValueRef) -> ValueRef { + val } // malloc_raw: expects an unboxed type and returns a pointer to @@ -721,8 +716,8 @@ 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, @@ -735,8 +730,8 @@ pub fn cast_shift_rhs(op: ast::binop, 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 { @@ -761,11 +756,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(Type::int_from_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(Type::uint_from_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) } _ => { @@ -779,7 +774,7 @@ pub fn fail_if_zero(cx: block, span: span, divrem: ast::binop, } pub fn null_env_ptr(bcx: block) -> ValueRef { - C_null(Type::opaque_box(bcx.ccx()).to_ptr()) + C_null(Type::opaque_box(bcx.ccx()).ptr_to()) } pub fn trans_external_path(ccx: &mut CrateContext, did: ast::def_id, t: ty::t) @@ -1479,7 +1474,7 @@ pub fn memzero(cx: block, llptr: ValueRef, llty: TypeRef) { let llintrinsicfn = ccx.intrinsics.get_copy(&intrinsic_key); let llptr = PointerCast(cx, llptr, Type::i8().ptr_to()); let llzeroval = C_u8(0); - let size = IntCast(cx, machine::llsize_of(ccx, ty), ccx.int_type.to_ref()); + 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]); @@ -1506,7 +1501,7 @@ pub fn alloca_maybe_zeroed(cx: block, t: TypeRef, zero: bool) -> ValueRef { } } let initcx = base::raw_block(cx.fcx, false, cx.fcx.llstaticallocas); - let p = Alloca(initcx, ty.to_ref()); + let p = Alloca(initcx, ty); if zero { memzero(initcx, p, ty); } p } @@ -1515,10 +1510,10 @@ pub fn arrayalloca(cx: block, t: TypeRef, v: ValueRef) -> ValueRef { let _icx = cx.insn_ctxt("arrayalloca"); if cx.unreachable { unsafe { - return llvm::LLVMGetUndef(ty); + return llvm::LLVMGetUndef(ty.to_ref()); } } - return ArrayAlloca(base::raw_block(cx.fcx, false, cx.fcx.llstaticallocas), ty.to_ref(), v); + return ArrayAlloca(base::raw_block(cx.fcx, false, cx.fcx.llstaticallocas), ty, v); } pub struct BasicBlocks { @@ -1588,7 +1583,7 @@ pub fn new_fn_ctxt_w_id(ccx: @mut CrateContext, let fcx = @mut fn_ctxt_ { llfn: llfndecl, llenv: unsafe { - llvm::LLVMGetUndef(Type::i8p()) + llvm::LLVMGetUndef(Type::i8p().to_ref()) }, llretptr: None, llstaticallocas: llbbs.sa, @@ -2309,7 +2304,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 = Type::func([ccx.int_type, Type::i8().ptr_to().ptr_to()], 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 { @@ -2338,10 +2333,9 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext, } let crate_map = ccx.crate_map; - let opaque_crate_map = llvm::LLVMBuildPointerCast(bld, - crate_map, - Type::i8p(), - 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(); @@ -2354,8 +2348,9 @@ pub fn create_entry_wrapper(ccx: @mut CrateContext, }; let args = { - let opaque_rust_main = llvm::LLVMBuildPointerCast( - bld, rust_main, Type::i8p(), noname()); + let opaque_rust_main = do "rust_main".as_c_str |buf| { + llvm::LLVMBuildPointerCast(bld, rust_main, Type::i8p().to_ref(), buf) + }; ~[ C_null(Type::opaque_box(ccx).ptr_to()), @@ -2487,7 +2482,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 @@ -2583,7 +2578,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 { @@ -2616,14 +2611,14 @@ 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()); } } macro_rules! ifn ( ($name:expr, $args:expr, $ret:expr) => ({ let name = $name; - let f = decl_cdecl_fn(llmod, name, Type::func($args, $ret)); + let f = decl_cdecl_fn(llmod, name, Type::func($args, &$ret)); intrinsics.insert(name, f); }) ) @@ -2642,7 +2637,7 @@ pub fn declare_intrinsics(llmod: ModuleRef) -> HashMap<&'static str, ValueRef> { [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.memcpy.p0i8.i64", + ifn!("llvm.memset.p0i8.i64", [i8p, Type::i8(), Type::i64(), Type::i32(), Type::i1()], Type::void()); ifn!("llvm.trap", [], Type::void()); @@ -2710,7 +2705,7 @@ pub fn declare_dbg_intrinsics(llmod: ModuleRef, intrinsics: &mut HashMap<&'stati } pub fn trap(bcx: block) { - match bcx.ccx().intrinsics.find_equiv("llvm.trap") { + match bcx.ccx().intrinsics.find_equiv(& &"llvm.trap") { Some(&x) => { Call(bcx, x, []); }, _ => bcx.sess().bug("unbound llvm.trap in trap") } @@ -2724,7 +2719,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, Type::i32(), buf) + llvm::LLVMAddGlobal(ccx.llmod, Type::i32().to_ref(), buf) } }; unsafe { @@ -2736,12 +2731,12 @@ pub fn decl_gc_metadata(ccx: &mut CrateContext, llmod_id: &str) { pub fn create_module_map(ccx: &mut CrateContext) -> ValueRef { let elttype = Type::struct_([ccx.int_type, ccx.int_type], false); - let maptype = Type::array(elttype, ccx.module_data.len() + 1); - let map = str::as_c_str("_rust_mod_map", |buf| { + 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] = ~[]; @@ -2783,11 +2778,11 @@ pub fn decl_crate_map(sess: session::Session, mapmeta: LinkMeta, ~"toplevel" }; let sym_name = ~"_rust_crate_map_" + mapname; - let arrtype = Type::array(int_type, n_subcrates as u64); + 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); @@ -2806,7 +2801,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)); @@ -2830,8 +2825,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, - Type::i8p()), + lib::llvm::llvm::LLVMConstPointerCast(llannihilatefn, Type::i8p().to_ref()), p2i(ccx, mod_map), C_array(ccx.int_type, subcrates)])); } @@ -2869,7 +2863,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 { @@ -2880,9 +2874,9 @@ pub fn write_metadata(cx: &mut CrateContext, crate: &ast::crate) { lib::llvm::SetLinkage(llglobal, lib::llvm::InternalLinkage); let t_ptr_i8 = Type::i8p(); - llglobal = llvm::LLVMConstBitCast(llglobal, t_ptr_i8); + 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, 1u), 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])); diff --git a/src/librustc/middle/trans/build.rs b/src/librustc/middle/trans/build.rs index be14da66a16..3e5a23cb18e 100644 --- a/src/librustc/middle/trans/build.rs +++ b/src/librustc/middle/trans/build.rs @@ -13,12 +13,14 @@ 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, Type, 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::type_::Type; + use core::cast; use core::hashmap::HashMap; use core::libc::{c_uint, c_ulonglong, c_char}; @@ -232,7 +234,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()); } } @@ -504,7 +506,7 @@ pub fn ArrayMalloc(cx: block, Ty: Type, Val: ValueRef) -> ValueRef { pub fn Alloca(cx: block, Ty: Type) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(Ty.to_ptr().to_ref()); } + if cx.unreachable { return llvm::LLVMGetUndef(Ty.ptr_to().to_ref()); } count_insn(cx, "alloca"); return llvm::LLVMBuildAlloca(B(cx), Ty.to_ref(), noname()); } @@ -512,7 +514,7 @@ pub fn Alloca(cx: block, Ty: Type) -> ValueRef { pub fn ArrayAlloca(cx: block, Ty: Type, Val: ValueRef) -> ValueRef { unsafe { - if cx.unreachable { return llvm::LLVMGetUndef(Ty.to_ptr().to_ref()); } + if cx.unreachable { return llvm::LLVMGetUndef(Ty.ptr_to().to_ref()); } count_insn(cx, "arrayalloca"); return llvm::LLVMBuildArrayAlloca(B(cx), Ty.to_ref(), Val, noname()); } @@ -531,9 +533,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 +549,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); @@ -639,7 +644,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(Type::i8p()); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::i8p().to_ref()); } count_insn(cx, "globalstring"); return llvm::LLVMBuildGlobalString(B(cx), _Str, noname()); } @@ -647,7 +652,7 @@ 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(Type::i8p()); } + if cx.unreachable { return llvm::LLVMGetUndef(Type::i8p().to_ref()); } count_insn(cx, "globalstringptr"); return llvm::LLVMBuildGlobalStringPtr(B(cx), _Str, noname()); } @@ -841,7 +846,7 @@ pub fn Phi(cx: block, Ty: Type, vals: &[ValueRef], bbs: &[BasicBlockRef]) unsafe { if cx.unreachable { return llvm::LLVMGetUndef(Ty.to_ref()); } assert_eq!(vals.len(), bbs.len()); - let phi = EmptyPhi(cx, Ty.to_ref()); + let phi = EmptyPhi(cx, Ty); count_insn(cx, "addincoming"); llvm::LLVMAddIncoming(phi, vec::raw::to_ptr(vals), vec::raw::to_ptr(bbs), @@ -863,10 +868,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()); } } @@ -887,9 +895,10 @@ pub fn add_comment(bcx: block, text: &str) { let comment_text = ~"# " + sanitized.replace("\n", "\n\t# "); count_insn(bcx, "inlineasm"); - let asm = str::as_c_str(comment_text, |c| { - llvm::LLVMConstInlineAsm(Type::func([], Type::void()), c, noname(), False, False) - }); + let asm = do comment_text.as_c_str |c| { + llvm::LLVMConstInlineAsm(Type::func([], &Type::void()).to_ref(), + c, noname(), False, False) + }; Call(bcx, asm, []); } } @@ -913,8 +922,8 @@ pub fn InlineAsmCall(cx: block, asm: *c_char, cons: *c_char, }; debug!("Asm Output Type: %?", cx.ccx().tn.type_to_str(output)); - let fty = Type::func(argtys, output); - let v = llvm::LLVMInlineAsm(llfty.to_ref(), asm, cons, volatile, alignstack, dia as c_uint); + 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) } @@ -1005,9 +1014,9 @@ pub fn ShuffleVector(cx: block, V1: ValueRef, V2: ValueRef, pub fn VectorSplat(cx: block, NumElts: uint, EltVal: ValueRef) -> ValueRef { unsafe { let elt_ty = val_ty(EltVal); - let Undef = llvm::LLVMGetUndef(Type::vector(elt_ty, NumElts).to_ref()); + 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(Type::vector(Type::i32().to_ref(), NumElts))) + ShuffleVector(cx, VecVal, Undef, C_null(Type::vector(&Type::i32(), NumElts as u64))) } } @@ -1049,7 +1058,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()); } diff --git a/src/librustc/middle/trans/cabi.rs b/src/librustc/middle/trans/cabi.rs index 036f34b1974..dffa5a7f1ad 100644 --- a/src/librustc/middle/trans/cabi.rs +++ b/src/librustc/middle/trans/cabi.rs @@ -8,20 +8,19 @@ // 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 { @@ -40,7 +39,7 @@ impl FnType { 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 = Type::func(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: &[Type], - 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<Attribute>] = 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,14 @@ impl FnType { return llargvals; } - pub fn build_shim_ret(&self, - bcx: block, - arg_tys: &[Type], - 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 vec::eachi(self.attrs) |i, a| { 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 +112,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 +121,8 @@ impl FnType { }; } - pub fn build_wrap_args(&self, - bcx: block, - ret_ty: Type, - 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<Attribute>] = self.attrs; let mut j = 0u; @@ -159,7 +147,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,14 +157,9 @@ 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() { @@ -187,9 +170,7 @@ impl FnType { } else { Load(bcx, llretval) }; - let llretptr = BitCast(bcx, - bcx.fcx.llretptr.get(), - self.ret_ty.ty.ptr_to()); + 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 f29ccad76b1..69896972ef0 100644 --- a/src/librustc/middle/trans/cabi_arm.rs +++ b/src/librustc/middle/trans/cabi_arm.rs @@ -9,11 +9,12 @@ // except according to those terms. use lib::llvm::{llvm, Integer, Pointer, Float, Double, Struct, Array}; -use lib::llvm::struct_tys; use lib::llvm::{Attribute, StructRetAttribute}; use lib::llvm::True; use middle::trans::cabi::{ABIInfo, FnType, LLVMType}; +use middle::trans::type_::Type; + use core::option::{Option, None, Some}; use core::uint; @@ -27,58 +28,58 @@ fn align(off: uint, ty: Type) -> uint { } fn ty_align(ty: Type) -> uint { - unsafe { - match ty.kind() { - Integer => { + 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) + } + 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))) } - _ => fail!("ty_align: unhandled type") } + Array => { + let elt = ty.element_type(); + ty_align(elt) + } + _ => fail!("ty_align: unhandled type") } } fn ty_size(ty: Type) -> uint { - unsafe { - match ty.kind() { - Integer => { + 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() { - 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 = ty.array_length(); - let elt = ty.element_type(); - let eltsz = ty_size(elt); - len * eltsz + } + 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) } - _ => 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") } } @@ -107,9 +108,9 @@ fn classify_arg_ty(ty: Type) -> (LLVMType, Option<Attribute>) { let align = ty_align(ty); let size = ty_size(ty); let llty = if align <= 4 { - Type::array(Type::i32(), (size + 3) / 4) + Type::array(&Type::i32(), (size + 3) / 4 as u64) } else { - Type::array(Type::i64(), (size + 7) / 8) + Type::array(&Type::i64(), (size + 7) / 8 as u64) }; (LLVMType { cast: true, ty: llty }, None) } @@ -122,7 +123,7 @@ fn is_reg_ty(ty: Type) -> bool { | Float | Double => true, _ => false - }; + } } } diff --git a/src/librustc/middle/trans/cabi_mips.rs b/src/librustc/middle/trans/cabi_mips.rs index 73d26b91672..27ac267895b 100644 --- a/src/librustc/middle/trans/cabi_mips.rs +++ b/src/librustc/middle/trans/cabi_mips.rs @@ -15,13 +15,14 @@ use core::ptr; use core::uint; use core::vec; use lib::llvm::{llvm, Integer, Pointer, Float, Double, Struct, Array}; -use lib::llvm::struct_tys; use lib::llvm::{Attribute, StructRetAttribute}; use lib::llvm::True; 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; } @@ -32,58 +33,58 @@ fn align(off: uint, ty: Type) -> uint { } fn ty_align(ty: Type) -> uint { - unsafe { - return match llvm::LLVMGetTypeKind(ty) { - Integer => { - ((llvm::LLVMGetIntTypeWidth(ty) as uint) + 7) / 8 - } - Pointer => 4, - Float => 4, - Double => 8, - Struct => { - if ty.is_packed() { - 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) + match ty.kind() { + Integer => { + unsafe { + ((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8 } - _ => fail!("ty_size: unhandled type") - }; + } + 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_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 = ty.field_types(); - let size = str_tys.iter().fold(0, |s, t| align(s, *t) + ty_size(*t)); - align(size, ty) - } - } - Array => { - let len = ty.array_length(); - let elt = ty.element_type(); - let eltsz = ty_size(elt); - len * eltsz + } + 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) } - _ => 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") } } @@ -120,7 +121,7 @@ fn classify_arg_ty(ty: Type, offset: &mut uint) -> (LLVMType, Option<Attribute>) }; } -fn is_reg_ty(ty: TypeRef) -> bool { +fn is_reg_ty(ty: Type) -> bool { unsafe { return match ty.kind() { Integer @@ -153,11 +154,11 @@ fn coerce_to_int(size: uint) -> ~[Type] { let r = size % 32; if r > 0 { unsafe { - Type::from_ref(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: Type, diff --git a/src/librustc/middle/trans/cabi_x86.rs b/src/librustc/middle/trans/cabi_x86.rs index 0f02f7d2f86..bdfe0e3d77d 100644 --- a/src/librustc/middle/trans/cabi_x86.rs +++ b/src/librustc/middle/trans/cabi_x86.rs @@ -17,6 +17,8 @@ use super::cabi::*; use super::common::*; use super::machine::*; +use middle::trans::type_::Type; + struct X86_ABIInfo { ccx: @mut CrateContext } diff --git a/src/librustc/middle/trans/cabi_x86_64.rs b/src/librustc/middle/trans/cabi_x86_64.rs index e0f9ad85e10..01ec4a90cb0 100644 --- a/src/librustc/middle/trans/cabi_x86_64.rs +++ b/src/librustc/middle/trans/cabi_x86_64.rs @@ -11,14 +11,15 @@ // 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 middle::trans::type_::Type; + use core::libc::c_uint; use core::option; use core::option::Option; @@ -28,7 +29,7 @@ use core::vec; #[deriving(Eq)] enum RegClass { NoClass, - Integer, + Int, SSEFs, SSEFv, SSEDs, @@ -43,7 +44,7 @@ enum RegClass { impl Type { fn is_reg_ty(&self) -> bool { - match ty.kind() { + match self.kind() { Integer | Pointer | Float | Double => true, _ => false } @@ -59,6 +60,11 @@ impl RegClass { } } +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; } @@ -83,64 +89,64 @@ fn classify_ty(ty: Type) -> ~[RegClass] { } fn ty_align(ty: Type) -> uint { - unsafe { - match ty.kind() { - Integer => { + match ty.kind() { + Integer => { + unsafe { ((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8 } - 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") - }; + } + 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 { - match ty.kind() { - Integer => { - ((llvm::LLVMGetIntTypeWidth(ty) as uint) + 7) / 8 - } - 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) - } + fn ty_size(ty: Type) -> uint { + match ty.kind() { + Integer => { + unsafe { + ((llvm::LLVMGetIntTypeWidth(ty.to_ref()) as uint) + 7) / 8 } - Array => { - let len = ty.array_length(); - let elt = ty.element_type(); - let eltsz = ty_size(elt); - len * eltsz + } + 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) } - _ => 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 [RegClass]) { for uint::range(0, cls.len()) |i| { - cls[i] = memory_class; + cls[i] = Memory; } } @@ -149,21 +155,21 @@ fn classify_ty(ty: Type) -> ~[RegClass] { 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; } @@ -192,7 +198,7 @@ fn classify_ty(ty: Type) -> ~[RegClass] { let mut i = off / 8u; let e = (off + t_size + 7u) / 8u; while i < e { - unify(cls, ix + i, memory_class); + unify(cls, ix + i, Memory); i += 1u; } return; @@ -201,17 +207,17 @@ fn classify_ty(ty: Type) -> ~[RegClass] { match ty.kind() { Integer | Pointer => { - unify(cls, ix + off / 8u, integer_class); + unify(cls, ix + off / 8u, Int); } Float => { if off % 8u == 4u { - unify(cls, ix + off / 8u, sse_fv_class); + unify(cls, ix + off / 8u, SSEFv); } else { - unify(cls, ix + off / 8u, sse_fs_class); + unify(cls, ix + off / 8u, SSEFs); } } Double => { - unify(cls, ix + off / 8u, sse_ds_class); + unify(cls, ix + off / 8u, SSEDs); } Struct => { classify_struct(ty.field_types(), cls, ix, off); @@ -242,7 +248,7 @@ fn classify_ty(ty: Type) -> ~[RegClass] { if cls[i].is_sse() { i += 1u; while i < e { - if cls[i] != sseup_class { + if cls[i] != SSEUp { all_mem(cls); return; } @@ -254,24 +260,24 @@ fn classify_ty(ty: Type) -> ~[RegClass] { } } else { while i < e { - if cls[i] == memory_class { + if cls[i] == Memory { all_mem(cls); return; } - if cls[i] == x87up_class { + if cls[i] == X87Up { // for darwin - // cls[i] = sse_ds_class; + // cls[i] = SSEDs; all_mem(cls); return; } - if cls[i] == sseup_class { - cls[i] = sse_int_class; + if cls[i] == SSEUp { + cls[i] = SSEInt; } else if cls[i].is_sse() { i += 1; - while i != e && cls[i] == sseup_class { i += 1u; } - } else if cls[i] == x87_class { + while i != e && cls[i] == SSEUp { i += 1u; } + } else if cls[i] == X87 { i += 1; - while i != e && cls[i] == x87up_class { i += 1u; } + while i != e && cls[i] == X87Up { i += 1u; } } else { i += 1; } @@ -281,7 +287,7 @@ fn classify_ty(ty: Type) -> ~[RegClass] { } 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; @@ -296,7 +302,7 @@ 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; @@ -310,20 +316,20 @@ fn llreg_ty(cls: &[RegClass]) -> Type { let e = cls.len(); while i < e { match cls[i] { - integer_class => { + Int => { tys.push(Type::i64()); } - sse_fv_class => { + SSEFv => { let vec_len = llvec_len(vec::tailn(cls, i + 1u)) * 2u; - let vec_ty = Type::vector(Type::f32(), vec_len); + let vec_ty = Type::vector(&Type::f32(), vec_len as u64); tys.push(vec_ty); i += vec_len; loop; } - sse_fs_class => { + SSEFs => { tys.push(Type::f32()); } - sse_ds_class => { + SSEDs => { tys.push(Type::f64()); } _ => fail!("llregtype: unhandled class") @@ -341,6 +347,7 @@ fn x86_64_tys(atys: &[Type], fn x86_64_ty(ty: Type, is_mem_cls: &fn(cls: &[RegClass]) -> bool, attr: Attribute) -> (LLVMType, Option<Attribute>) { + let (cast, attr, ty) = if !ty.is_reg_ty() { let cls = classify_ty(ty); if is_mem_cls(cls) { @@ -348,8 +355,11 @@ fn x86_64_tys(atys: &[Type], } else { (true, option::None, llreg_ty(cls)) } + } else { + (false, option::None, ty) }; - return (LLVMType { cast: cast, ty: ty }, attr); + + (LLVMType { cast: cast, ty: ty }, attr) } let mut arg_tys = ~[]; diff --git a/src/librustc/middle/trans/callee.rs b/src/librustc/middle/trans/callee.rs index 6d2446f0137..c74a2320b5b 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; @@ -526,7 +528,7 @@ pub fn trans_call_inner(in_cx: block, let (llfn, llenv) = unsafe { match callee.data { Fn(d) => { - (d.llfn, llvm::LLVMGetUndef(Type::opaque_box(ccx).ptr_to())) + (d.llfn, llvm::LLVMGetUndef(Type::opaque_box(ccx).ptr_to().to_ref())) } Method(d) => { // Weird but true: we pass self in the *environment* slot! @@ -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(Type::nil().ptr_to()) + llvm::LLVMGetUndef(Type::nil().ptr_to().to_ref()) } } else { alloc_ty(bcx, retty) @@ -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 diff --git a/src/librustc/middle/trans/closure.rs b/src/librustc/middle/trans/closure.rs index 35e8e866039..7d7c024640a 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; diff --git a/src/librustc/middle/trans/common.rs b/src/librustc/middle/trans/common.rs index 01b0411a07b..3f9f39ac852 100644 --- a/src/librustc/middle/trans/common.rs +++ b/src/librustc/middle/trans/common.rs @@ -31,6 +31,8 @@ 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}; @@ -58,29 +60,11 @@ pub fn new_namegen() -> namegen { 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<ValueRef>, drop_glue: Option<ValueRef>, free_glue: Option<ValueRef>, @@ -345,39 +329,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(), - bcx.val_to_str(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); } } @@ -400,12 +359,9 @@ pub fn add_clean_temp_mem(bcx: block, val: ValueRef, t: ty::t) { debug!("add_clean_temp_mem(%s, %s, %s)", 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); } } @@ -431,12 +387,8 @@ pub fn add_clean_return_to_mut(bcx: block, 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); } @@ -621,9 +573,9 @@ impl Result { } } -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)) } } @@ -706,313 +658,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::<TypeRef>(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 cx.tn.find_type(s) { - Some(t) => return t, - _ => () - } - let t = T_tydesc_field(cx, abi::tydesc_field_drop_glue); - cx.tn.associate_type(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()); -} - -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::<TypeRef>(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()); } -*/ - // 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). @@ -1101,7 +746,7 @@ pub fn C_cstr(cx: &mut CrateContext, s: @str) -> ValueRef { }; let gsym = token::gensym("str"); - let g = fmt!("str%u", gsym).as_c_str |buf| { + let g = do fmt!("str%u", gsym).as_c_str |buf| { llvm::LLVMAddGlobal(cx.llmod, val_ty(sc).to_ref(), buf) }; llvm::LLVMSetInitializer(g, sc); @@ -1138,7 +783,8 @@ 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(Type::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); } } @@ -1158,17 +804,17 @@ pub fn C_packed_struct(elts: &[ValueRef]) -> ValueRef { } } -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); } } @@ -1193,7 +839,7 @@ pub fn C_shape(ccx: &CrateContext, bytes: ~[u8]) -> ValueRef { let llglobal = do name.as_c_str |buf| { llvm::LLVMAddGlobal(ccx.llmod, val_ty(llshape).to_ref(), buf) }; - llvm::LLVMSetInitializer(llglobal, llshape.to_ref()); + llvm::LLVMSetInitializer(llglobal, llshape); llvm::LLVMSetGlobalConstant(llglobal, True); lib::llvm::SetLinkage(llglobal, lib::llvm::InternalLinkage); return llvm::LLVMConstPointerCast(llglobal, Type::i8p().to_ref()); diff --git a/src/librustc/middle/trans/consts.rs b/src/librustc/middle/trans/consts.rs index dcdb53ec532..456dc6edfb6 100644 --- a/src/librustc/middle/trans/consts.rs +++ b/src/librustc/middle/trans/consts.rs @@ -11,7 +11,7 @@ use core::prelude::*; use back::abi; -use lib::llvm::{llvm, ConstFCmp, ConstICmp, SetLinkage, PrivateLinkage, ValueRef, TypeRef, Bool, +use lib::llvm::{llvm, ConstFCmp, ConstICmp, SetLinkage, PrivateLinkage, ValueRef, Bool, True, False}; use lib::llvm::{IntEQ, IntNE, IntUGT, IntUGE, IntULT, IntULE, IntSGT, IntSGE, IntSLT, IntSLE, RealOEQ, RealOGT, RealOGE, RealOLT, RealOLE, RealONE}; @@ -30,6 +30,8 @@ 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}; @@ -38,28 +40,28 @@ pub fn const_lit(cx: @mut CrateContext, e: @ast::expr, lit: ast::lit) -> ValueRef { let _icx = cx.insn_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 +75,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 +104,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 +182,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: \ @@ -349,9 +351,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 +428,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 +453,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 +515,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); diff --git a/src/librustc/middle/trans/context.rs b/src/librustc/middle/trans/context.rs index bf9d3932298..a709600cb9d 100644 --- a/src/librustc/middle/trans/context.rs +++ b/src/librustc/middle/trans/context.rs @@ -12,7 +12,7 @@ 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}; use lib; @@ -36,8 +36,8 @@ 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,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}; @@ -94,11 +94,10 @@ pub struct CrateContext { impl_method_cache: HashMap<(ast::def_id, ast::ident), ast::def_id>, module_data: HashMap<~str, ValueRef>, - lltypes: HashMap<ty::t, TypeRef>, - llsizingtypes: HashMap<ty::t, TypeRef>, + lltypes: HashMap<ty::t, Type>, + llsizingtypes: HashMap<ty::t, Type>, adt_reprs: HashMap<ty::t, @adt::Repr>, names: namegen, - next_addrspace: addrspace_gen, symbol_hasher: hash::State, type_hashcodes: HashMap<ty::t, @str>, type_short_names: HashMap<ty::t, ~str>, @@ -151,8 +150,8 @@ impl CrateContext { let tydesc_type = Type::tydesc(targ_cfg.arch); let opaque_vec_type = Type::opaque_vec(targ_cfg.arch); - let str_slice_ty = Type::named_struct("str_slice"); - str_slice_ty.set_struct_body([Type::i8p(), int_type]); + 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); @@ -197,7 +196,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(), diff --git a/src/librustc/middle/trans/controlflow.rs b/src/librustc/middle/trans/controlflow.rs index 17009afda49..a9892b34ccd 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; @@ -204,7 +206,7 @@ pub fn trans_log(log_ex: @ast::expr, let global; unsafe { global = str::as_c_str(s, |buf| { - llvm::LLVMAddGlobal(ccx.llmod, Type::i32(), buf) + llvm::LLVMAddGlobal(ccx.llmod, Type::i32().to_ref(), buf) }); llvm::LLVMSetGlobalConstant(global, False); llvm::LLVMSetInitializer(global, C_null(Type::i32())); diff --git a/src/librustc/middle/trans/expr.rs b/src/librustc/middle/trans/expr.rs index 92cbf2c0957..c0a3b76aca4 100644 --- a/src/librustc/middle/trans/expr.rs +++ b/src/librustc/middle/trans/expr.rs @@ -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; @@ -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); @@ -1552,8 +1552,8 @@ fn int_cast(bcx: block, lldsttype: Type, llsrctype: Type, llsrc: ValueRef, signed: bool) -> ValueRef { let _icx = bcx.insn_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 { @@ -1569,8 +1569,8 @@ fn int_cast(bcx: block, lldsttype: Type, llsrctype: Type, 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 srcsz = llsrctype.float_width(); + let dstsz = lldsttype.float_width(); return if dstsz > srcsz { FPExt(bcx, llsrc, lldsttype) } else if srcsz > dstsz { diff --git a/src/librustc/middle/trans/foreign.rs b/src/librustc/middle/trans/foreign.rs index 50d4709735c..5cad76e471e 100644 --- a/src/librustc/middle/trans/foreign.rs +++ b/src/librustc/middle/trans/foreign.rs @@ -44,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 { @@ -122,7 +123,7 @@ fn shim_types(ccx: @mut CrateContext, id: ast::node_id) -> ShimTypes { llsig: llsig, ret_def: ret_def, bundle_ty: bundle_ty, - shim_fn_ty: Type::func([bundle_ty.ptr_to()], Type::void()), + shim_fn_ty: Type::func([bundle_ty.ptr_to()], &Type::void()), fn_ty: fn_ty } } @@ -220,12 +221,9 @@ fn build_wrap_fn_(ccx: @mut CrateContext, 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 { + 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. @@ -233,9 +231,7 @@ fn build_wrap_fn_(ccx: @mut CrateContext, } else { // Cast if we have to... // XXX: This is ugly. - let llretptr = BitCast(return_context, - fcx.llretptr.get(), - llfunctionreturntype.ptr_to()); + let llretptr = BitCast(return_context, fcx.llretptr.get(), return_type.ptr_to()); Ret(return_context, Load(return_context, llretptr)); } } @@ -636,6 +632,9 @@ pub fn trans_intrinsic(ccx: @mut CrateContext, } } + build_return(bcx); + finish_fn(fcx, lltop); + return; } diff --git a/src/librustc/middle/trans/glue.rs b/src/librustc/middle/trans/glue.rs index 7396508fb8d..294d56dcd76 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, Type, 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; @@ -76,16 +78,6 @@ pub fn drop_ty(cx: block, v: ValueRef, t: ty::t) -> block { 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), type_of(bcx.ccx(), t).ptr_to()); - 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"); match ty::get(t).sty { @@ -436,8 +428,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 @@ -617,20 +609,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 @@ -640,20 +618,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 { @@ -661,7 +637,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, @@ -706,7 +681,11 @@ pub fn make_generic_glue_inner(ccx: @mut CrateContext, let llty = type_of(ccx, t); 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; } @@ -732,7 +711,7 @@ pub fn emit_tydescs(ccx: &mut CrateContext) { //let _icx = ccx.insn_ctxt("emit_tydescs"); // As of this point, allow no more tydescs to be created. ccx.finished_tydescs = true; - let glue_fn_ty = T_generic_glue_fn(ccx).ptr_to(); + let glue_fn_ty = Type::generic_glue_fn(ccx); let tyds = &mut ccx.tydescs; for tyds.each_value |&val| { let ti = val; @@ -747,7 +726,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()) } } }; @@ -757,7 +736,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 +746,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,16 +756,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(Type::i8p()); let shape_tables = C_null(Type::i8p()); - let tydesc = - C_named_struct(ccx.tydesc_type, + let tydesc = C_named_struct(ccx.tydesc_type, [ti.size, // size ti.align, // align take_glue, // take_glue @@ -802,18 +781,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 = ccx.tydesc_type.ptr_to(); - 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/machine.rs b/src/librustc/middle/trans/machine.rs index eb7240419ed..495d3bcae16 100644 --- a/src/librustc/middle/trans/machine.rs +++ b/src/librustc/middle/trans/machine.rs @@ -18,6 +18,8 @@ use middle::trans::type_of; use middle::ty; use util::ppaux::ty_to_str; +use middle::trans::type_::Type; + // ______________________________________________________________________ // compute sizeof / alignof @@ -140,7 +142,7 @@ 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), - cx.tn.type_to_str(T_struct(lltypes, false))); + cx.tn.type_to_str(Type::struct_(lltypes, false))); let this_size = llsize_of_real(cx, Type::struct_(lltypes, false)); if max_size < this_size { diff --git a/src/librustc/middle/trans/meth.rs b/src/librustc/middle/trans/meth.rs index ce240dc2484..055e1ebbd37 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}; @@ -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 = type_of_fn_from_ty(ccx, fn_ty).to_ptr(); + 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 @@ -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); diff --git a/src/librustc/middle/trans/reflect.rs b/src/librustc/middle/trans/reflect.rs index ebf2d888148..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::{Type, ValueRef, llvm}; +use lib::llvm::{ValueRef, llvm}; use middle::trans::adt; use middle::trans::base::*; use middle::trans::build::*; @@ -33,6 +33,8 @@ 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], diff --git a/src/librustc/middle/trans/shape.rs b/src/librustc/middle/trans/shape.rs index f3554b34806..82db5d405da 100644 --- a/src/librustc/middle/trans/shape.rs +++ b/src/librustc/middle/trans/shape.rs @@ -17,6 +17,8 @@ use lib::llvm::{True, ModuleRef, ValueRef}; use middle::trans::common::*; use middle::trans; +use middle::trans::type_::Type; + use core::str; pub struct Ctxt { @@ -32,7 +34,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); @@ -50,7 +52,7 @@ pub fn mk_ctxt(llmod: ModuleRef) -> Ctxt { unsafe { let llshapetablesty = Type::named_struct("shapes"); do "shapes".as_c_str |buf| { - llvm::LLVMAddGlobal(llmod, llshapetablesty, buf) + llvm::LLVMAddGlobal(llmod, llshapetablesty.to_ref(), buf) }; Ctxt { diff --git a/src/librustc/middle/trans/tvec.rs b/src/librustc/middle/trans/tvec.rs index 00933865012..014c46b06e4 100644 --- a/src/librustc/middle/trans/tvec.rs +++ b/src/librustc/middle/trans/tvec.rs @@ -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; diff --git a/src/librustc/middle/trans/type_.rs b/src/librustc/middle/trans/type_.rs index 851ff4511a0..14c4ac71d97 100644 --- a/src/librustc/middle/trans/type_.rs +++ b/src/librustc/middle/trans/type_.rs @@ -11,6 +11,7 @@ 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; @@ -26,6 +27,7 @@ use core::cast; use core::libc::{c_uint}; +#[deriving(Eq)] pub struct Type { priv rf: TypeRef } @@ -38,12 +40,14 @@ macro_rules! ty ( * 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 } @@ -136,7 +140,7 @@ impl Type { pub fn float_from_ty(ctx: &CrateContext, t: ast::float_ty) -> Type { match t { - ast::ty_f => ctx.float_ty, + ast::ty_f => ctx.float_type, ast::ty_f32 => Type::f32(), ast::ty_f64 => Type::f64() } @@ -147,7 +151,7 @@ impl Type { } pub fn func(args: &[Type], ret: &Type) -> Type { - let vec : &[TypeRef] = unsafe { cast::transmute() }; + let vec : &[TypeRef] = unsafe { cast::transmute(args) }; ty!(llvm::LLVMFunctionType(ret.to_ref(), vec::raw::to_ptr(vec), args.len() as c_uint, False)) } @@ -157,12 +161,13 @@ impl Type { } pub fn ptr(ty: Type) -> Type { - ty!(llvm::LLVMPointerType(ty, 0 as c_uint)) + 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::LLVMStructType(vec::raw::to_ptr(els), els.len() as c_uint, packed as Bool)) + 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 { @@ -175,7 +180,7 @@ impl Type { } pub fn vtable() -> Type { - Type::array(Type::i8().ptr_to(), 1) + Type::array(&Type::i8().ptr_to(), 1) } pub fn generic_glue_fn(cx: &mut CrateContext) -> Type { @@ -185,7 +190,7 @@ impl Type { } let ty = cx.tydesc_type.get_field(abi::tydesc_field_drop_glue); - cx.tn.associate_type("glue_fn", ty); + cx.tn.associate_type("glue_fn", &ty); return ty; } @@ -193,10 +198,9 @@ impl Type { pub fn tydesc(arch: Architecture) -> Type { let mut tydesc = Type::named_struct("tydesc"); let tydescpp = tydesc.ptr_to().ptr_to(); - let pvoid = Type::i8().ptr_to(); - let glue_fn_ty = Type::func( - [ Type::nil.ptr_to(), tydescpp, pvoid ], - Type::void()).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); @@ -226,7 +230,7 @@ impl Type { } pub fn opaque_vec(arch: Architecture) -> Type { - Type::vec(arch, Type::i8()) + Type::vec(arch, &Type::i8()) } #[inline] @@ -242,11 +246,11 @@ impl Type { } pub fn box(ctx: &CrateContext, ty: &Type) -> Type { - Type::struct_(Type::box_header_fields(ctx) + [ty], false) + Type::struct_(Type::box_header_fields(ctx) + [*ty], false) } pub fn opaque_box(ctx: &CrateContext) -> Type { - Type::box(ctx, Type::i8()) + Type::box(ctx, &Type::i8()) } pub fn unique(ctx: &CrateContext, ty: &Type) -> Type { @@ -254,7 +258,7 @@ impl Type { } pub fn opaque_cbox_ptr(cx: &CrateContext) -> Type { - Type::opaque_box().ptr_to() + Type::opaque_box(cx).ptr_to() } pub fn enum_discrim(cx: &CrateContext) -> Type { @@ -275,7 +279,7 @@ impl Type { } ty::UniqTraitStore => { Type::struct_( - [ tydesc_ptr, Type::unique(ctx, Type::i8()).ptr_to()], + [ tydesc_ptr, Type::unique(ctx, &Type::i8()).ptr_to()], false) } ty::RegionTraitStore(*) => { @@ -301,7 +305,7 @@ impl Type { } pub fn ptr_to(&self) -> Type { - ty!(llvm::LLVMPointerType(self.to_ref())) + ty!(llvm::LLVMPointerType(self.to_ref(), 0)) } pub fn get_field(&self, idx: uint) -> Type { @@ -335,14 +339,38 @@ impl Type { pub fn field_types(&self) -> ~[Type] { unsafe { - let n_elts = llvm::LLVMCountStructElementTypes(struct_ty) as uint; + 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(struct_ty, &mut elts[0]); + llvm::LLVMGetStructElementTypes(self.to_ref(), &mut elts[0]); cast::transmute(elts) } } + pub fn return_type(&self) -> Type { + unsafe { + 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 9ace4991f1b..0f4ffb04b28 100644 --- a/src/librustc/middle/trans/type_of.rs +++ b/src/librustc/middle/trans/type_of.rs @@ -18,6 +18,8 @@ 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 { @@ -58,10 +60,15 @@ pub fn type_of_fn(cx: &mut CrateContext, inputs: &[ty::t], output: ty::t) atys.push_all(type_of_explicit_args(cx, inputs)); // Use the output as the actual return value if it's immediate. +<<<<<<< HEAD if output_is_immediate && !ty::type_is_nil(output) { Type::func(atys, lloutputtype) +======= + if output_is_immediate { + Type::func(atys, &lloutputtype) +>>>>>>> Finish up Type refactoring } else { - Type::func(atys, Type::void()) + Type::func(atys, &Type::void()) } } } @@ -87,11 +94,11 @@ pub fn type_of_non_gc_box(cx: &mut CrateContext, t: ty::t) -> Type { match ty::get(t).sty { ty::ty_box(mt) => { let ty = type_of(cx, mt.ty); - Type::box(cx, ty).ptr_to() + Type::box(cx, &ty).ptr_to() } ty::ty_uniq(mt) => { let ty = type_of(cx, mt.ty); - Type::unique(cx, ty).ptr_to() + Type::unique(cx, &ty).ptr_to() } _ => { cx.sess.bug("non-box in type_of_non_gc_box"); @@ -146,14 +153,14 @@ pub fn sizing_type_of(cx: &mut CrateContext, t: ty::t) -> Type { 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)) => Type::array(Type::i8(), size), + ty::ty_estr(ty::vstore_fixed(size)) => Type::array(&Type::i8(), size as u64), ty::ty_evec(mt, ty::vstore_fixed(size)) => { - Type::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); - Type::vec(cx.sess.targ_cfg.arch, sz_ty) + Type::vec(cx.sess.targ_cfg.arch, &sz_ty) } ty::ty_tup(*) | ty::ty_enum(*) => { @@ -165,7 +172,7 @@ pub fn sizing_type_of(cx: &mut CrateContext, t: ty::t) -> Type { 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) + 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); @@ -205,14 +212,14 @@ pub fn type_of(cx: &mut CrateContext, t: ty::t) -> Type { return llty; } - let llty = match ty::get(t).sty { + 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) => { - Type::unique(cx, Type::vec(cx.sess.targ_cfg.arch, Type::i8())).ptr_to() + 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 @@ -223,30 +230,30 @@ pub fn type_of(cx: &mut CrateContext, t: ty::t) -> Type { Type::named_struct(llvm_type_name(cx, an_enum, did, substs.tps)) } ty::ty_estr(ty::vstore_box) => { - Type::box(cx, Type::vec(cx, Type::i8())).ptr_to() + 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 = Type::vec(cx.sess.targ_cfg.arch, e_ty); - Type::box(cx, v_ty).ptr_to() + 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); - Type::box(cx, ty).ptr_to() + Type::box(cx, &ty).ptr_to() } ty::ty_opaque_box => Type::opaque_box(cx).ptr_to(), ty::ty_uniq(ref mt) => { let ty = type_of(cx, mt.ty); - Type::unique(cx, ty).ptr_to() + Type::unique(cx, &ty).ptr_to() } ty::ty_evec(ref mt, ty::vstore_uniq) => { let ty = type_of(cx, mt.ty); - let ty = Type::vec(cx, ty); - Type::unique(cx, ty).ptr_to() + 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); - Type::vec(cx.sess.targ_cfg.arch, ty) + Type::vec(cx.sess.targ_cfg.arch, &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(), @@ -263,20 +270,20 @@ pub fn type_of(cx: &mut CrateContext, t: ty::t) -> Type { } ty::ty_estr(ty::vstore_fixed(n)) => { - Type::array(Type::i8(), n + 1u /* +1 for trailing null */) + Type::array(&Type::i8(), (n + 1u) as u64) } ty::ty_evec(ref mt, ty::vstore_fixed(n)) => { - Type::array(type_of(cx, mt.ty), n) + Type::array(&type_of(cx, mt.ty), n as u64) } 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); - Type::func_pair(cx, ty) + Type::func_pair(cx, &ty) } ty::ty_trait(_, _, store, _) => Type::opaque_trait(cx, store), - ty::ty_type => cx.tydesc_type.to_ptr(), + ty::ty_type => cx.tydesc_type.ptr_to(), ty::ty_tup(*) => { let repr = adt::represent_type(cx, t); Type::struct_(adt::fields_of(cx, repr), false) @@ -286,7 +293,7 @@ pub fn type_of(cx: &mut CrateContext, t: ty::t) -> Type { 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) + 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 @@ -306,16 +313,14 @@ pub fn type_of(cx: &mut CrateContext, t: ty::t) -> Type { 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); } } _ => () @@ -345,19 +350,5 @@ pub fn llvm_type_name(cx: &CrateContext, 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::viod()) -} - -/* -pub fn type_of_rooted(ccx: &mut CrateContext, t: ty::t) -> Type { - 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) -> Type { - let tydescpp = T_ptr(T_ptr(ccx.tydesc_type)); - return T_fn([T_ptr(T_nil()), tydescpp, T_ptr(T_i8())], T_void()); + Type::func([self_ty], Type::void()) } -*/ diff --git a/src/librustc/middle/trans/write_guard.rs b/src/librustc/middle/trans/write_guard.rs index 6b2c6801e58..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, diff --git a/src/libstd/unstable/intrinsics.rs b/src/libstd/unstable/intrinsics.rs index e1daf6c81b2..c38b013a75a 100644 --- a/src/libstd/unstable/intrinsics.rs +++ b/src/libstd/unstable/intrinsics.rs @@ -175,15 +175,15 @@ pub extern "rust-intrinsic" { pub fn atomic_umin_relaxed(dst: &mut int, src: int) -> int; #[cfg(not(stage0))] - pub fn atomic_umin(dst: &mut int, src: int) -> int; + pub fn atomic_umax(dst: &mut int, src: int) -> int; #[cfg(not(stage0))] - pub fn atomic_umin_acq(dst: &mut int, src: int) -> int; + pub fn atomic_umax_acq(dst: &mut int, src: int) -> int; #[cfg(not(stage0))] - pub fn atomic_umin_rel(dst: &mut int, src: int) -> int; + pub fn atomic_umax_rel(dst: &mut int, src: int) -> int; #[cfg(not(stage0))] - pub fn atomic_umin_acqrel(dst: &mut int, src: int) -> int; + pub fn atomic_umax_acqrel(dst: &mut int, src: int) -> int; #[cfg(not(stage0))] - pub fn atomic_umin_relaxed(dst: &mut int, src: int) -> int; + pub fn atomic_umax_relaxed(dst: &mut int, src: int) -> int; /// The size of a type in bytes. /// |
