Skip to content

Commit

Permalink
Use concrete types in glue functions
Browse files Browse the repository at this point in the history
We used to have concrete types in glue functions, but the way we used
to implement that broke inlining of those functions. To fix that, we
converted all glue to just take an i8* and always casted to that type.

The problem with the old implementation was that we made a wrong
assumption about the glue functions, taking it for granted that they
always take an i8*, because that's the function type expected by the
TyDesc fields. Therefore, we always ended up with some kind of cast.

But actually, we can initially have the glue with concrete types and
only cast the functions to the generic type once we actually emit the
TyDesc data.

That means that for glue calls that can be statically resolved, we don't
need any casts, unless the glue uses a simplified type. In that case we
cast the argument. And for glue calls that are resolved at runtime, we
cast the argument to i8*, because that's what the glue function in the
TyDesc expects.

Since most of out glue calls are static, this saves a lot of bitcasts.
The size of the unoptimized librustc.ll goes down by 240k lines.
  • Loading branch information
dotdash committed Jul 13, 2013
1 parent 1d2e1a9 commit e56b369
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 8 deletions.
22 changes: 18 additions & 4 deletions src/librustc/middle/trans/glue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ pub fn lazily_emit_tydesc_glue(ccx: @mut CrateContext,
field: uint,
ti: @mut tydesc_info) {
let _icx = push_ctxt("lazily_emit_tydesc_glue");
let llfnty = Type::glue_fn();
let llfnty = Type::glue_fn(type_of::type_of(ccx, ti.ty).ptr_to());

if lazily_emit_simplified_tydesc_glue(ccx, field, ti) {
return;
Expand Down Expand Up @@ -323,7 +323,20 @@ pub fn call_tydesc_glue_full(bcx: block,
}
};

let llrawptr = PointerCast(bcx, v, Type::i8p());
// When static type info is available, avoid casting parameter unless the
// glue is using a simplified type, because the function already has the
// right type. Otherwise cast to generic pointer.
let llrawptr = if static_ti.is_none() || static_glue_fn.is_none() {
PointerCast(bcx, v, Type::i8p())
} else {
let ty = static_ti.get().ty;
let simpl = simplified_glue_type(ccx.tcx, field, ty);
if simpl != ty {
PointerCast(bcx, v, type_of(ccx, simpl).ptr_to())
} else {
v
}
};

let llfn = {
match static_glue_fn {
Expand Down Expand Up @@ -709,13 +722,14 @@ pub fn make_generic_glue_inner(ccx: @mut CrateContext,
// requirement since in many contexts glue is invoked indirectly and
// the caller has no idea if it's dealing with something that can be
// passed by value.
//
// llfn is expected be declared to take a parameter of the appropriate
// type, so we don't need to explicitly cast the function parameter.

let bcx = top_scope_block(fcx, None);
let lltop = bcx.llbb;
let rawptr0_arg = fcx.arg_pos(0u);
let llrawptr0 = unsafe { llvm::LLVMGetParam(llfn, rawptr0_arg as c_uint) };
let llty = type_of(ccx, t);
let llrawptr0 = PointerCast(bcx, llrawptr0, llty.ptr_to());
let bcx = helper(bcx, llrawptr0, t);

finish_fn(fcx, lltop, bcx);
Expand Down
8 changes: 4 additions & 4 deletions src/librustc/middle/trans/type_.rs
Original file line number Diff line number Diff line change
Expand Up @@ -187,20 +187,20 @@ impl Type {
None => ()
}

let ty = Type::glue_fn();
let ty = Type::glue_fn(Type::i8p());
cx.tn.associate_type("glue_fn", &ty);

return ty;
}

pub fn glue_fn() -> Type {
Type::func([ Type::nil().ptr_to(), Type::i8p() ],
pub fn glue_fn(t: Type) -> Type {
Type::func([ Type::nil().ptr_to(), t ],
&Type::void())
}

pub fn tydesc(arch: Architecture) -> Type {
let mut tydesc = Type::named_struct("tydesc");
let glue_fn_ty = Type::glue_fn().ptr_to();
let glue_fn_ty = Type::glue_fn(Type::i8p()).ptr_to();

let int_ty = Type::int(arch);

Expand Down

5 comments on commit e56b369

@bors
Copy link
Contributor

@bors bors commented on e56b369 Jul 14, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

saw approval from huonw
at dotdash@e56b369

@bors
Copy link
Contributor

@bors bors commented on e56b369 Jul 14, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

merging dotdash/rust/glue = e56b369 into auto

@bors
Copy link
Contributor

@bors bors commented on e56b369 Jul 14, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

dotdash/rust/glue = e56b369 merged ok, testing candidate = 66e2857

@bors
Copy link
Contributor

@bors bors commented on e56b369 Jul 14, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fast-forwarding master to auto = 66e2857

Please sign in to comment.