Skip to content

Commit 66e2857

Browse files
committed
auto merge of #7781 : dotdash/rust/glue, r=huonw
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.
2 parents 51cb984 + e56b369 commit 66e2857

File tree

2 files changed

+22
-8
lines changed

2 files changed

+22
-8
lines changed

src/librustc/middle/trans/glue.rs

+18-4
Original file line numberDiff line numberDiff line change
@@ -230,7 +230,7 @@ pub fn lazily_emit_tydesc_glue(ccx: @mut CrateContext,
230230
field: uint,
231231
ti: @mut tydesc_info) {
232232
let _icx = push_ctxt("lazily_emit_tydesc_glue");
233-
let llfnty = Type::glue_fn();
233+
let llfnty = Type::glue_fn(type_of::type_of(ccx, ti.ty).ptr_to());
234234

235235
if lazily_emit_simplified_tydesc_glue(ccx, field, ti) {
236236
return;
@@ -323,7 +323,20 @@ pub fn call_tydesc_glue_full(bcx: block,
323323
}
324324
};
325325

326-
let llrawptr = PointerCast(bcx, v, Type::i8p());
326+
// When static type info is available, avoid casting parameter unless the
327+
// glue is using a simplified type, because the function already has the
328+
// right type. Otherwise cast to generic pointer.
329+
let llrawptr = if static_ti.is_none() || static_glue_fn.is_none() {
330+
PointerCast(bcx, v, Type::i8p())
331+
} else {
332+
let ty = static_ti.get().ty;
333+
let simpl = simplified_glue_type(ccx.tcx, field, ty);
334+
if simpl != ty {
335+
PointerCast(bcx, v, type_of(ccx, simpl).ptr_to())
336+
} else {
337+
v
338+
}
339+
};
327340

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

713729
let bcx = top_scope_block(fcx, None);
714730
let lltop = bcx.llbb;
715731
let rawptr0_arg = fcx.arg_pos(0u);
716732
let llrawptr0 = unsafe { llvm::LLVMGetParam(llfn, rawptr0_arg as c_uint) };
717-
let llty = type_of(ccx, t);
718-
let llrawptr0 = PointerCast(bcx, llrawptr0, llty.ptr_to());
719733
let bcx = helper(bcx, llrawptr0, t);
720734

721735
finish_fn(fcx, lltop, bcx);

src/librustc/middle/trans/type_.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -187,20 +187,20 @@ impl Type {
187187
None => ()
188188
}
189189

190-
let ty = Type::glue_fn();
190+
let ty = Type::glue_fn(Type::i8p());
191191
cx.tn.associate_type("glue_fn", &ty);
192192

193193
return ty;
194194
}
195195

196-
pub fn glue_fn() -> Type {
197-
Type::func([ Type::nil().ptr_to(), Type::i8p() ],
196+
pub fn glue_fn(t: Type) -> Type {
197+
Type::func([ Type::nil().ptr_to(), t ],
198198
&Type::void())
199199
}
200200

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

205205
let int_ty = Type::int(arch);
206206

0 commit comments

Comments
 (0)