Skip to content

Commit

Permalink
More Type refactorings
Browse files Browse the repository at this point in the history
  • Loading branch information
James Miller committed Jun 22, 2013
1 parent 1968622 commit fd83b92
Show file tree
Hide file tree
Showing 13 changed files with 470 additions and 578 deletions.
61 changes: 28 additions & 33 deletions src/librustc/back/upcall.rs
Expand Up @@ -11,8 +11,8 @@

use driver::session;
use middle::trans::base;
use middle::trans::common::{T_fn, T_i8, T_i32, T_int, T_ptr, T_void};
use lib::llvm::{ModuleRef, ValueRef, TypeRef};
use middle::trans::type_::Type;
use lib::llvm::{ModuleRef, ValueRef};

pub struct Upcalls {
trace: ValueRef,
Expand All @@ -22,40 +22,35 @@ pub struct Upcalls {
reset_stack_limit: ValueRef
}

pub fn declare_upcalls(targ_cfg: @session::config,
llmod: ModuleRef) -> @Upcalls {
fn decl(llmod: ModuleRef, prefix: ~str, name: ~str,
tys: ~[TypeRef], rv: TypeRef) ->
ValueRef {
let arg_tys = tys.map(|t| *t);
let fn_ty = T_fn(arg_tys, rv);
return base::decl_cdecl_fn(llmod, prefix + name, fn_ty);
}
fn nothrow(f: ValueRef) -> ValueRef {
base::set_no_unwind(f); f
}
let d: &fn(a: ~str, b: ~[TypeRef], c: TypeRef) -> ValueRef =
|a,b,c| decl(llmod, ~"upcall_", a, b, c);
let dv: &fn(a: ~str, b: ~[TypeRef]) -> ValueRef =
|a,b| decl(llmod, ~"upcall_", a, b, T_void());
macro_rules! upcall (
(fn $name:ident($($arg:expr),+) -> $ret:expr) => ({
let fn_ty = Type::func([ $($arg),* ], $ret);
base::decl_cdecl_fn(llmod, ~"upcall_" + stringify!($name), fn_ty)
});
(nothrow fn $name:ident($($arg:expr),+) -> $ret:expr) => ({
let fn_ty = Type::func([ $($arg),* ], $ret);
let decl = base::decl_cdecl_fn(llmod, ~"upcall_" + stringify!($name), fn_ty);
base::set_no_unwind(decl);
decl
});
(nothrow fn $name:ident -> $ret:expr) => ({
let fn_ty = Type::func([], $ret);
let decl = base::decl_cdecl_fn(llmod, ~"upcall_" + stringify!($name), fn_ty);
base::set_no_unwind(decl);
decl
})
)

let int_t = T_int(targ_cfg);
pub fn declare_upcalls(targ_cfg: @session::config, llmod: ModuleRef) -> @Upcalls {
let opaque_ptr = Type::i8().to_ptr();
let int_ty = Type::int(targ_cfg.arch);

@Upcalls {
trace: dv(~"trace", ~[T_ptr(T_i8()),
T_ptr(T_i8()),
int_t]),
call_shim_on_c_stack:
d(~"call_shim_on_c_stack",
// arguments: void *args, void *fn_ptr
~[T_ptr(T_i8()), T_ptr(T_i8())],
int_t),
trace: upcall!(fn trace(opaque_ptr, opaque_ptr, int_ty) -> Type::void()),
call_shim_on_c_stack: upcall!(fn call_shim_on_c_stack(opaque_ptr, opaque_ptr) -> int_ty),
call_shim_on_rust_stack:
d(~"call_shim_on_rust_stack",
~[T_ptr(T_i8()), T_ptr(T_i8())], int_t),
rust_personality:
nothrow(d(~"rust_personality", ~[], T_i32())),
reset_stack_limit:
nothrow(dv(~"reset_stack_limit", ~[]))
upcall!(fn call_shim_on_rust_stack(opaque_ptr, opaque_ptr) -> int_ty),
rust_personality: upcall!(nothrow fn rust_personality -> Type::i32()),
reset_stack_limit: upcall!(nothrow fn reset_stack_limit -> Type::void())
}
}
12 changes: 0 additions & 12 deletions src/librustc/lib/llvm.rs
Expand Up @@ -2233,18 +2233,6 @@ pub fn fn_ty_param_tys(fn_ty: TypeRef) -> ~[TypeRef] {
}
}

pub fn struct_tys(struct_ty: TypeRef) -> ~[TypeRef] {
unsafe {
let n_elts = llvm::LLVMCountStructElementTypes(struct_ty) as uint;
if n_elts == 0 {
return ~[];
}
let mut elts = vec::from_elem(n_elts, ptr::null());
llvm::LLVMGetStructElementTypes(struct_ty, &mut elts[0]);
return elts;
}
}


/* Memory-managed interface to target data. */

Expand Down
2 changes: 1 addition & 1 deletion src/librustc/middle/trans/_match.rs
Expand Up @@ -1644,7 +1644,7 @@ fn create_bindings_map(bcx: block, pat: @ast::pat) -> BindingsMap {
// but during matching we need to store a *T as explained
// above
let is_move = ccx.maps.moves_map.contains(&p_id);
llmatch = alloca(bcx, T_ptr(llvariable_ty));
llmatch = alloca(bcx, llvariable_ty.ptr_to());
trmode = TrByValue(is_move, alloca(bcx, llvariable_ty));
}
ast::bind_by_ref(_) => {
Expand Down
32 changes: 16 additions & 16 deletions src/librustc/middle/trans/adt.rs
Expand Up @@ -49,7 +49,7 @@ use core::libc::c_ulonglong;
use core::option::{Option, Some, None};
use core::vec;

use lib::llvm::{ValueRef, TypeRef, True, IntEQ, IntNE};
use lib::llvm::{ValueRef, True, IntEQ, IntNE};
use middle::trans::_match;
use middle::trans::build::*;
use middle::trans::common::*;
Expand Down Expand Up @@ -212,7 +212,7 @@ fn represent_type_uncached(cx: &mut CrateContext, t: ty::t) -> Repr {

fn mk_struct(cx: &mut CrateContext, tys: &[ty::t], packed: bool) -> Struct {
let lltys = tys.map(|&ty| type_of::sizing_type_of(cx, ty));
let llty_rec = T_struct(lltys, packed);
let llty_rec = Type::struct_(lltys, packed);
Struct {
size: machine::llsize_of_alloc(cx, llty_rec) /*bad*/as u64,
align: machine::llalign_of_min(cx, llty_rec) /*bad*/as u64,
Expand All @@ -226,17 +226,16 @@ fn mk_struct(cx: &mut CrateContext, tys: &[ty::t], packed: bool) -> Struct {
* All nominal types are LLVM structs, in order to be able to use
* forward-declared opaque types to prevent circularity in `type_of`.
*/
pub fn fields_of(cx: &mut CrateContext, r: &Repr) -> ~[TypeRef] {
pub fn fields_of(cx: &mut CrateContext, r: &Repr) -> ~[Type] {
generic_fields_of(cx, r, false)
}
/// Like `fields_of`, but for `type_of::sizing_type_of` (q.v.).
pub fn sizing_fields_of(cx: &mut CrateContext, r: &Repr) -> ~[TypeRef] {
pub fn sizing_fields_of(cx: &mut CrateContext, r: &Repr) -> ~[Type] {
generic_fields_of(cx, r, true)
}
fn generic_fields_of(cx: &mut CrateContext, r: &Repr, sizing: bool)
-> ~[TypeRef] {
fn generic_fields_of(cx: &mut CrateContext, r: &Repr, sizing: bool) -> ~[Type] {
match *r {
CEnum(*) => ~[T_enum_discrim(cx)],
CEnum(*) => ~[Type::enum_discrim(cx)],
Univariant(ref st, _dtor) => struct_llfields(cx, st, sizing),
NullablePointer{ nonnull: ref st, _ } => struct_llfields(cx, st, sizing),
General(ref sts) => {
Expand All @@ -261,14 +260,15 @@ fn generic_fields_of(cx: &mut CrateContext, r: &Repr, sizing: bool)
let most_aligned = most_aligned.get();
let padding = largest_size - most_aligned.size;

assert!(padding >= 0);

struct_llfields(cx, most_aligned, sizing)
+ [T_array(T_i8(), padding /*bad*/as uint)]
+ [Type::array(Type::i8(), padding /*bad*/as uint)]
}
}
}

fn struct_llfields(cx: &mut CrateContext, st: &Struct, sizing: bool)
-> ~[TypeRef] {
fn struct_llfields(cx: &mut CrateContext, st: &Struct, sizing: bool) -> ~[Type] {
if sizing {
st.fields.map(|&ty| type_of::sizing_type_of(cx, ty))
} else {
Expand Down Expand Up @@ -309,7 +309,7 @@ pub fn trans_get_discr(bcx: block, r: &Repr, scrutinee: ValueRef)
(cases.len() - 1) as int),
NullablePointer{ nonnull: ref nonnull, nndiscr, ptrfield, _ } => {
ZExt(bcx, nullable_bitdiscr(bcx, nonnull, nndiscr, ptrfield, scrutinee),
T_enum_discrim(bcx.ccx()))
Type::enum_discrim(bcx.ccx()))
}
}
}
Expand Down Expand Up @@ -438,11 +438,11 @@ pub fn trans_field_ptr(bcx: block, r: &Repr, val: ValueRef, discr: int,
} else {
// The unit-like case might have a nonzero number of unit-like fields.
// (e.g., Result or Either with () as one side.)
let llty = type_of::type_of(bcx.ccx(), nullfields[ix]);
let ty = type_of::type_of(bcx.ccx(), nullfields[ix]);
assert_eq!(machine::llsize_of_alloc(bcx.ccx(), llty), 0);
// The contents of memory at this pointer can't matter, but use
// the value that's "reasonable" in case of pointer comparison.
PointerCast(bcx, val, T_ptr(llty))
PointerCast(bcx, val, ty.ptr_to())
}
}
}
Expand All @@ -456,8 +456,8 @@ fn struct_field_ptr(bcx: block, st: &Struct, val: ValueRef, ix: uint,
let fields = do st.fields.map |&ty| {
type_of::type_of(ccx, ty)
};
let real_llty = T_struct(fields, st.packed);
PointerCast(bcx, val, T_ptr(real_llty))
let real_ty = Type::struct_(fields, st.packed);
PointerCast(bcx, val, real_llty.to_ptr().to_ref())
} else {
val
};
Expand Down Expand Up @@ -572,7 +572,7 @@ fn build_const_struct(ccx: &mut CrateContext, st: &Struct, vals: &[ValueRef])
}

fn padding(size: u64) -> ValueRef {
C_undef(T_array(T_i8(), size /*bad*/as uint))
C_undef(Type::array(Type::i8(), size).to_ref())
}

// XXX this utility routine should be somewhere more general
Expand Down
8 changes: 4 additions & 4 deletions src/librustc/middle/trans/asm.rs
Expand Up @@ -110,11 +110,11 @@ pub fn trans_inline_asm(bcx: block, ia: &ast::inline_asm) -> block {

// Depending on how many outputs we have, the return type is different
let output = if numOutputs == 0 {
T_void()
Type::void()
} else if numOutputs == 1 {
val_ty(outputs[0])
} else {
T_struct(outputs.map(|o| val_ty(*o)), false)
Type::struct_(outputs.map(|o| val_ty(*o)), false)
};

let dialect = match ia.dialect {
Expand All @@ -130,12 +130,12 @@ pub fn trans_inline_asm(bcx: block, ia: &ast::inline_asm) -> block {

// Again, based on how many outputs we have
if numOutputs == 1 {
let op = PointerCast(bcx, aoutputs[0], T_ptr(val_ty(outputs[0])));
let op = PointerCast(bcx, aoutputs[0], val_ty(outputs[0]).ptr_to());
Store(bcx, r, op);
} else {
for aoutputs.iter().enumerate().advance |(i, o)| {
let v = ExtractValue(bcx, r, i);
let op = PointerCast(bcx, *o, T_ptr(val_ty(outputs[i])));
let op = PointerCast(bcx, *o, val_ty(outputs[i]).ptr_to());
Store(bcx, v, op);
}
}
Expand Down

0 comments on commit fd83b92

Please sign in to comment.