From 2521cda1ec5e24cce81e25fcf64281584fcfdb5d Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Fri, 14 Oct 2011 17:00:17 -0700 Subject: [PATCH] work on making the size of ints depend on the target arch --- src/comp/middle/trans.rs | 98 +++++++++++++++++++++------------ src/comp/middle/trans_build.rs | 6 +- src/comp/middle/trans_common.rs | 48 ++++++++-------- 3 files changed, 92 insertions(+), 60 deletions(-) diff --git a/src/comp/middle/trans.rs b/src/comp/middle/trans.rs index 4c49634e68b2..138d3a3bbd55 100644 --- a/src/comp/middle/trans.rs +++ b/src/comp/middle/trans.rs @@ -134,9 +134,9 @@ fn type_of_inner(cx: @crate_ctxt, sp: span, t: ty::t) T_nil() /* ...I guess? */ } ty::ty_bool. { T_bool() } - ty::ty_int. { T_int(cx) } - ty::ty_float. { T_float(cx) } - ty::ty_uint. { T_int(cx) } + ty::ty_int. { cx.int_type } + ty::ty_float. { cx.float_type } + ty::ty_uint. { cx.int_type } ty::ty_machine(tm) { alt tm { ast::ty_i8. | ast::ty_u8. { T_i8() } @@ -345,8 +345,8 @@ fn get_simple_extern_fn(cx: @block_ctxt, llmod: ModuleRef, name: str, n_args: int) -> ValueRef { let ccx = cx.fcx.lcx.ccx; - let inputs = std::vec::init_elt::(T_int(ccx), n_args as uint); - let output = T_int(ccx); + let inputs = std::vec::init_elt::(ccx.int_type, n_args as uint); + let output = ccx.int_type; let t = T_fn(inputs, output); ret get_extern_fn(externs, llmod, name, lib::llvm::LLVMCCallConv, t); } @@ -405,12 +405,12 @@ fn llalign_of_real(cx: @crate_ctxt, t: TypeRef) -> uint { } fn llsize_of(cx: @crate_ctxt, t: TypeRef) -> ValueRef { - ret llvm::LLVMConstIntCast(lib::llvm::llvm::LLVMSizeOf(t), T_int(cx), + ret llvm::LLVMConstIntCast(lib::llvm::llvm::LLVMSizeOf(t), cx.int_type, False); } fn llalign_of(cx: @crate_ctxt, t: TypeRef) -> ValueRef { - ret llvm::LLVMConstIntCast(lib::llvm::llvm::LLVMAlignOf(t), T_int(cx), + ret llvm::LLVMConstIntCast(lib::llvm::llvm::LLVMAlignOf(t), cx.int_type, False); } @@ -597,7 +597,7 @@ fn dynamic_size_of(cx: @block_ctxt, t: ty::t, mode: align_mode) -> result { let ccx = bcx_ccx(bcx); // Compute max(variant sizes). - let max_size: ValueRef = alloca(bcx, T_int(ccx)); + let max_size: ValueRef = alloca(bcx, ccx.int_type); Store(bcx, C_int(ccx, 0), max_size); let variants = ty::tag_variants(bcx_tcx(bcx), tid); for variant: ty::variant_info in variants { @@ -618,7 +618,7 @@ fn dynamic_size_of(cx: @block_ctxt, t: ty::t, mode: align_mode) -> result { let max_size_val = Load(bcx, max_size); let total_size = if std::vec::len(variants) != 1u { - Add(bcx, max_size_val, llsize_of(ccx, T_int(ccx))) + Add(bcx, max_size_val, llsize_of(ccx, ccx.int_type)) } else { max_size_val }; ret rslt(bcx, total_size); } @@ -2161,7 +2161,7 @@ fn trans_crate_lit(cx: @crate_ctxt, lit: ast::lit) -> ValueRef { // if target int width is larger than host, at the moment; // re-do the mach-int types using 'big' when that works. - let t = T_int(cx); + let t = cx.int_type; let s = True; alt tm { ast::ty_u8. { t = T_i8(); s = False; } @@ -2177,7 +2177,7 @@ fn trans_crate_lit(cx: @crate_ctxt, lit: ast::lit) -> ValueRef { } ast::lit_float(fs) { ret C_float(cx, fs); } ast::lit_mach_float(tm, s) { - let t = T_float(cx); + let t = cx.float_type; alt tm { ast::ty_f32. { t = T_f32(); } ast::ty_f64. { t = T_f64(); } } ret C_floating(s, t); } @@ -2961,7 +2961,7 @@ fn lookup_discriminant(lcx: @local_ctxt, vid: ast::def_id) -> ValueRef { let gvar = str::as_buf(sym, {|buf| - llvm::LLVMAddGlobal(ccx.llmod, T_int(ccx), buf) + llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type, buf) }); llvm::LLVMSetLinkage(gvar, lib::llvm::LLVMExternalLinkage as llvm::Linkage); @@ -3120,11 +3120,11 @@ fn trans_index(cx: @block_ctxt, sp: span, base: @ast::expr, idx: @ast::expr, // Cast to an LLVM integer. Rust is less strict than LLVM in this regard. let ix_val; let ix_size = llsize_of_real(bcx_ccx(cx), val_ty(ix.val)); - let int_size = llsize_of_real(bcx_ccx(cx), T_int(ccx)); + let int_size = llsize_of_real(bcx_ccx(cx), ccx.int_type); if ix_size < int_size { - ix_val = ZExt(bcx, ix.val, T_int(ccx)); + ix_val = ZExt(bcx, ix.val, ccx.int_type); } else if ix_size > int_size { - ix_val = Trunc(bcx, ix.val, T_int(ccx)); + ix_val = Trunc(bcx, ix.val, ccx.int_type); } else { ix_val = ix.val; } let unit_ty = node_id_type(bcx_ccx(cx), id); @@ -4420,10 +4420,10 @@ fn trans_log(lvl: int, cx: @block_ctxt, e: @ast::expr) -> @block_ctxt { let s = link::mangle_internal_name_by_path_and_seq( lcx.ccx, lcx.module_path, "loglevel"); let global = str::as_buf(s, {|buf| - llvm::LLVMAddGlobal(lcx.ccx.llmod, T_int(ccx), buf) + llvm::LLVMAddGlobal(lcx.ccx.llmod, ccx.int_type, buf) }); llvm::LLVMSetGlobalConstant(global, False); - llvm::LLVMSetInitializer(global, C_null(T_int(ccx))); + llvm::LLVMSetInitializer(global, C_null(ccx.int_type)); llvm::LLVMSetLinkage(global, lib::llvm::LLVMInternalLinkage as llvm::Linkage); lcx.ccx.module_data.insert(modname, global); @@ -5651,14 +5651,14 @@ fn register_native_fn(ccx: @crate_ctxt, sp: span, path: [str], name: str, cast_to_i32 = true; } ast::native_abi_c_stack_cdecl. { - let llfn = decl_cdecl_fn(ccx.llmod, name, T_fn([], T_int())); + let llfn = decl_cdecl_fn(ccx.llmod, name, T_fn([], ccx.int_type)); ccx.item_ids.insert(id, llfn); ccx.item_symbols.insert(id, name); ret; } ast::native_abi_c_stack_stdcall. { let llfn = decl_fn(ccx.llmod, name, lib::llvm::LLVMX86StdcallCallConv, - T_fn([], T_int())); + T_fn([], ccx.int_type)); ccx.item_ids.insert(id, llfn); ccx.item_symbols.insert(id, name); ret; @@ -5706,21 +5706,23 @@ fn register_native_fn(ccx: @crate_ctxt, sp: span, path: [str], name: str, fn convert_arg_to_i32(cx: @block_ctxt, v: ValueRef, t: ty::t, mode: ty::mode) -> ValueRef { if mode == ast::by_ref || mode == ast::by_val { + let ccx = bcx_ccx(cx); if ty::type_is_integral(bcx_tcx(cx), t) { // FIXME: would be nice to have a postcondition that says // if a type is integral, then it has static size (#586) - let lldsttype = T_int(); - let ccx = bcx_ccx(cx); + let lldsttype = ccx.int_type; let sp = cx.sp; check (type_has_static_size(ccx, t)); let llsrctype = type_of(ccx, sp, t); if llvm::LLVMGetIntTypeWidth(lldsttype) > llvm::LLVMGetIntTypeWidth(llsrctype) { - ret ZExtOrBitCast(cx, v, T_int()); + ret ZExtOrBitCast(cx, v, ccx.int_type); } - ret TruncOrBitCast(cx, v, T_int()); + ret TruncOrBitCast(cx, v, ccx.int_type); + } + if ty::type_is_fp(bcx_tcx(cx), t) { + ret FPToSI(cx, v, ccx.int_type); } - if ty::type_is_fp(bcx_tcx(cx), t) { ret FPToSI(cx, v, T_int()); } } ret vp2i(cx, v); } @@ -5927,11 +5929,10 @@ fn trans_constant(ccx: @crate_ctxt, it: @ast::item, &&pt: [str], let p = new_pt + [it.ident, variant.node.name, "discrim"]; let s = mangle_exported_name(ccx, p, ty::mk_int(ccx.tcx)); let discrim_gvar = - str::as_buf(s, - {|buf| - llvm::LLVMAddGlobal(ccx.llmod, T_int(), buf) - }); - llvm::LLVMSetInitializer(discrim_gvar, C_int(i as int)); + str::as_buf(s, {|buf| + llvm::LLVMAddGlobal(ccx.llmod, ccx.int_type, buf) + }); + llvm::LLVMSetInitializer(discrim_gvar, C_int(ccx, i as int)); llvm::LLVMSetGlobalConstant(discrim_gvar, True); ccx.discrims.insert( ast_util::local_def(variant.node.id), discrim_gvar); @@ -5951,10 +5952,13 @@ fn trans_constants(ccx: @crate_ctxt, crate: @ast::crate) { } fn vp2i(cx: @block_ctxt, v: ValueRef) -> ValueRef { - ret PtrToInt(cx, v, T_int()); + let ccx = bcx_ccx(cx); + ret PtrToInt(cx, v, ccx.int_type); } -fn p2i(v: ValueRef) -> ValueRef { ret llvm::LLVMConstPtrToInt(v, T_int()); } +fn p2i(ccx: @crate_ctxt, v: ValueRef) -> ValueRef { + ret llvm::LLVMConstPtrToInt(v, ccx.int_type); +} fn declare_intrinsics(llmod: ModuleRef) -> hashmap { let T_memmove32_args: [TypeRef] = @@ -6005,7 +6009,7 @@ fn trap(bcx: @block_ctxt) { } fn create_module_map(ccx: @crate_ctxt) -> ValueRef { - let elttype = T_struct([T_int(), T_int()]); + let elttype = T_struct([ccx.int_type, ccx.int_type]); let maptype = T_array(elttype, ccx.module_data.size() + 1u); let map = str::as_buf("_rust_mod_map", @@ -6057,6 +6061,24 @@ fn fill_crate_map(ccx: @crate_ctxt, map: ValueRef) { subcrates += [C_int(0)]; llvm::LLVMSetInitializer(map, C_struct([p2i(create_module_map(ccx)), C_array(T_int(), subcrates)])); + subcrates += [C_int(ccx, 0)]; + let mapname; + if ccx.sess.get_opts().library { + mapname = ccx.link_meta.name; + } else { mapname = "toplevel"; } + let sym_name = "_rust_crate_map_" + mapname; + let arrtype = T_array(ccx.int_type, std::vec::len::(subcrates)); + let maptype = T_struct([ccx.int_type, arrtype]); + let map = + str::as_buf(sym_name, + {|buf| llvm::LLVMAddGlobal(ccx.llmod, maptype, buf) }); + llvm::LLVMSetLinkage(map, + lib::llvm::LLVMExternalLinkage as llvm::Linkage); + llvm::LLVMSetInitializer(map, + C_struct([p2i(create_module_map(ccx)), + C_array(ccx.int_type, subcrates)])); + ret map; +>>>>>>> work on making the size of ints depend on the target arch } fn write_metadata(cx: @crate_ctxt, crate: @ast::crate) { @@ -6090,7 +6112,7 @@ fn write_metadata(cx: @crate_ctxt, crate: @ast::crate) { // Writes the current ABI version into the crate. fn write_abi_version(ccx: @crate_ctxt) { - shape::mk_global(ccx, "rust_abi_version", C_uint(abi::abi_version), + shape::mk_global(ccx, "rust_abi_version", C_uint(ccx, abi::abi_version), false); } @@ -6110,8 +6132,12 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt, let td = mk_target_data(sess.get_targ_cfg().target_strs.data_layout); let tn = mk_type_names(); let intrinsics = declare_intrinsics(llmod); - let task_type = T_task(); - let tydesc_type = T_tydesc(); + let int_type = T_int(sess.get_targ_cfg().arch); + let float_type = T_float(sess.get_targ_cfg().arch); + let task_type = T_task(sess.get_targ_cfg().arch); + let taskptr_type = T_ptr(task_type); + tn.associate("taskptr", taskptr_type); + let tydesc_type = T_tydesc(taskptr_type); tn.associate("tydesc", tydesc_type); let hasher = ty::hash_ty; let eqer = ty::eq_ty; @@ -6161,6 +6187,8 @@ fn trans_crate(sess: session::session, crate: @ast::crate, tcx: ty::ctxt, upcall::declare_upcalls(tn, tydesc_type, llmod), rust_object_type: T_rust_object(), tydesc_type: tydesc_type, + int_type: int_type, + float_type: float_type, task_type: task_type, builder: BuilderRef_res(llvm::LLVMCreateBuilder()), shape_cx: shape::mk_ctxt(llmod), diff --git a/src/comp/middle/trans_build.rs b/src/comp/middle/trans_build.rs index 290e81e754eb..68cf33398ed2 100644 --- a/src/comp/middle/trans_build.rs +++ b/src/comp/middle/trans_build.rs @@ -306,7 +306,7 @@ fn Load(cx: @block_ctxt, PointerVal: ValueRef) -> ValueRef { if cx.unreachable { let ty = val_ty(PointerVal); let eltty = if llvm::LLVMGetTypeKind(ty) == 11 { - llvm::LLVMGetElementType(ty) } else { T_int(ccx) }; + llvm::LLVMGetElementType(ty) } else { ccx.int_type }; ret llvm::LLVMGetUndef(eltty); } ret llvm::LLVMBuildLoad(B(cx), PointerVal, noname()); @@ -492,7 +492,7 @@ fn _UndefReturn(cx: @block_ctxt, Fn: ValueRef) -> ValueRef { let ccx = cx.fcx.lcx.ccx; let ty = val_ty(Fn); let retty = if llvm::LLVMGetTypeKind(ty) == 8 { - llvm::LLVMGetReturnType(ty) } else { T_int(ccx) }; + llvm::LLVMGetReturnType(ty) } else { ccx.int_type }; ret llvm::LLVMGetUndef(retty); } @@ -577,7 +577,7 @@ fn IsNotNull(cx: @block_ctxt, Val: ValueRef) -> ValueRef { fn PtrDiff(cx: @block_ctxt, LHS: ValueRef, RHS: ValueRef) -> ValueRef { let ccx = cx.fcx.lcx.ccx; - if cx.unreachable { ret llvm::LLVMGetUndef(T_int(ccx)); } + if cx.unreachable { ret llvm::LLVMGetUndef(ccx.int_type); } ret llvm::LLVMBuildPtrDiff(B(cx), LHS, RHS, noname()); } diff --git a/src/comp/middle/trans_common.rs b/src/comp/middle/trans_common.rs index 9a303ba88fa2..0121b848a4c6 100644 --- a/src/comp/middle/trans_common.rs +++ b/src/comp/middle/trans_common.rs @@ -120,6 +120,8 @@ type crate_ctxt = upcalls: @upcall::upcalls, rust_object_type: TypeRef, tydesc_type: TypeRef, + int_type: TypeRef, + float_type: TypeRef, task_type: TypeRef, builder: BuilderRef_res, shape_cx: shape::ctxt, @@ -488,16 +490,16 @@ fn T_f64() -> TypeRef { ret llvm::LLVMDoubleType(); } fn T_bool() -> TypeRef { ret T_i1(); } -fn T_int(cx: @crate_ctxt) -> TypeRef { - ret alt cx.sess.get_targ_cfg().arch { +fn T_int(arch: session::arch) -> TypeRef { + ret alt arch { arch_x86 { T_i32() } arch_x86_64 { T_i64() } arch_arm { T_i32() } }; } -fn T_float(cx: @crate_ctxt) -> TypeRef { - ret alt cx.sess.get_targ_cfg().arch { +fn T_float(arch: session::arch) -> TypeRef { + ret alt arch { arch_x86 { T_f64() } arch_x86_64 { T_f64() } arch_arm { T_f64() } @@ -507,7 +509,7 @@ fn T_float(cx: @crate_ctxt) -> TypeRef { fn T_char() -> TypeRef { ret T_i32(); } fn T_size_t(cx: @crate_ctxt) -> TypeRef { - ret T_int(cx); + ret cx.int_type; } fn T_fn(inputs: [TypeRef], output: TypeRef) -> TypeRef { @@ -551,7 +553,7 @@ fn T_rust_object() -> TypeRef { ret t; } -fn T_task(cx: @crate_ctxt) -> TypeRef { +fn T_task(arch: session::arch) -> TypeRef { let t = T_named_struct("task"); // Refcount @@ -565,9 +567,10 @@ fn T_task(cx: @crate_ctxt) -> TypeRef { // Domain pointer // Crate cache pointer + let t_int = T_int(arch); let elems = - [T_int(cx), T_int(cx), T_int(cx), T_int(cx), - T_int(cx), T_int(cx), T_int(cx), T_int(cx)]; + [t_int, t_int, t_int, t_int, + t_int, t_int, t_int, t_int]; set_struct_body(t, elems); ret t; } @@ -612,9 +615,10 @@ fn T_tydesc(cx: @crate_ctxt) -> TypeRef { pvoid, pvoid, T_i8()], T_void())); let elems = - [tydescpp, T_int(cx), T_int(cx), glue_fn_ty, glue_fn_ty, glue_fn_ty, + [tydescpp, cx.int_type, cx.int_type, + glue_fn_ty, glue_fn_ty, glue_fn_ty, T_ptr(T_i8()), glue_fn_ty, glue_fn_ty, glue_fn_ty, cmp_glue_fn_ty, - T_ptr(T_i8()), T_ptr(T_i8()), T_int(cx), T_int(cx)]; + T_ptr(T_i8()), T_ptr(T_i8()), cx.int_type, cx.int_type]; set_struct_body(tydesc, elems); ret tydesc; } @@ -626,8 +630,8 @@ fn T_array(t: TypeRef, n: uint) -> TypeRef { ret llvm::LLVMArrayType(t, n); } // // TODO: Support user-defined vector sizes. fn T_vec(cx: @crate_ctxt, t: TypeRef) -> TypeRef { - ret T_struct([T_int(cx), // fill - T_int(cx), // alloc + ret T_struct([cx.int_type, // fill + cx.int_type, // alloc T_array(t, 0u)]); // elements } @@ -635,16 +639,16 @@ fn T_vec(cx: @crate_ctxt, t: TypeRef) -> TypeRef { fn T_opaque_vec(cx: @crate_ctxt) -> TypeRef { ret T_vec(cx, T_i8()); } fn T_box(cx: @crate_ctxt, t: TypeRef) -> TypeRef { - ret T_struct([T_int(cx), t]); + ret T_struct([cx.int_type, t]); } fn T_port(cx: @crate_ctxt, _t: TypeRef) -> TypeRef { - ret T_struct([T_int(cx)]); // Refcount + ret T_struct([cx.int_type]); // Refcount } fn T_chan(cx: @crate_ctxt, _t: TypeRef) -> TypeRef { - ret T_struct([T_int(cx)]); // Refcount + ret T_struct([cx.int_type]); // Refcount } @@ -684,8 +688,8 @@ fn T_tag(cx: @crate_ctxt, size: uint) -> TypeRef { if cx.tn.name_has_type(s) { ret cx.tn.get_type(s); } let t = if size == 0u { - T_struct([T_int(cx)]) - } else { T_struct([T_int(cx), T_array(T_i8(), size)]) }; + T_struct([cx.int_type]) + } else { T_struct([cx.int_type, T_array(T_i8(), size)]) }; cx.tn.associate(s, t); ret t; } @@ -693,7 +697,7 @@ fn T_tag(cx: @crate_ctxt, size: uint) -> TypeRef { fn T_opaque_tag(cx: @crate_ctxt) -> TypeRef { let s = "opaque_tag"; if cx.tn.name_has_type(s) { ret cx.tn.get_type(s); } - let t = T_struct([T_int(cx), T_i8()]); + let t = T_struct([cx.int_type, T_i8()]); cx.tn.associate(s, t); ret t; } @@ -731,7 +735,7 @@ fn C_integral(t: TypeRef, u: uint, sign_extend: Bool) -> ValueRef { // FIXME: We can't use LLVM::ULongLong with our existing minimal native // API, which only knows word-sized args. // - // ret llvm::LLVMConstInt(T_int(), t as LLVM::ULongLong, False); + // ret llvm::LLVMConstInt(.int_type, t as LLVM::ULongLong, False); // ret llvm::LLVMRustConstSmallInt(t, u, sign_extend); @@ -739,7 +743,7 @@ fn C_integral(t: TypeRef, u: uint, sign_extend: Bool) -> ValueRef { fn C_float(cx: @crate_ctxt, s: str) -> ValueRef { ret str::as_buf(s, {|buf| - llvm::LLVMConstRealOfString(T_float(cx), buf) + llvm::LLVMConstRealOfString(cx.float_type, buf) }); } @@ -760,11 +764,11 @@ fn C_bool(b: bool) -> ValueRef { } fn C_int(cx: @crate_ctxt, i: int) -> ValueRef { - ret C_integral(T_int(cx), i as uint, True); + ret C_integral(cx.int_type, i as uint, True); } fn C_uint(cx: @crate_ctxt, i: uint) -> ValueRef { - ret C_integral(T_int(cx), i, False); + ret C_integral(cx.int_type, i, False); } fn C_u8(i: uint) -> ValueRef { ret C_integral(T_i8(), i, False); }