Skip to content

Commit 998e41a

Browse files
committed
auto merge of #7154 : dotdash/rust/glue, r=graydon
Currently, when calling glue functions, we cast the function to match the argument type. This interacts very badly with LLVM and breaks inlining of the glue code. It's more efficient to use a unified function type for the glue functions and always cast the function argument instead of the function. The resulting code for rustc is about 13% faster (measured up to and including the "trans" pass) and the resulting librustc is about 5% smaller.
2 parents eac0200 + a08d768 commit 998e41a

File tree

2 files changed

+10
-43
lines changed

2 files changed

+10
-43
lines changed

src/librustc/middle/trans/glue.rs

Lines changed: 8 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -218,14 +218,6 @@ pub fn simplified_glue_type(tcx: ty::ctxt, field: uint, t: ty::t) -> ty::t {
218218
return t;
219219
}
220220

221-
pub fn cast_glue(ccx: @CrateContext, ti: @mut tydesc_info, v: ValueRef)
222-
-> ValueRef {
223-
unsafe {
224-
let llfnty = type_of_glue_fn(ccx, ti.ty);
225-
llvm::LLVMConstPointerCast(v, T_ptr(llfnty))
226-
}
227-
}
228-
229221
pub fn lazily_emit_simplified_tydesc_glue(ccx: @CrateContext,
230222
field: uint,
231223
ti: @mut tydesc_info) -> bool {
@@ -235,19 +227,14 @@ pub fn lazily_emit_simplified_tydesc_glue(ccx: @CrateContext,
235227
let simpl_ti = get_tydesc(ccx, simpl);
236228
lazily_emit_tydesc_glue(ccx, field, simpl_ti);
237229
{
238-
let simpl_ti = &mut *simpl_ti;
239230
if field == abi::tydesc_field_take_glue {
240-
ti.take_glue =
241-
simpl_ti.take_glue.map(|v| cast_glue(ccx, ti, *v));
231+
ti.take_glue = simpl_ti.take_glue;
242232
} else if field == abi::tydesc_field_drop_glue {
243-
ti.drop_glue =
244-
simpl_ti.drop_glue.map(|v| cast_glue(ccx, ti, *v));
233+
ti.drop_glue = simpl_ti.drop_glue;
245234
} else if field == abi::tydesc_field_free_glue {
246-
ti.free_glue =
247-
simpl_ti.free_glue.map(|v| cast_glue(ccx, ti, *v));
235+
ti.free_glue = simpl_ti.free_glue;
248236
} else if field == abi::tydesc_field_visit_glue {
249-
ti.visit_glue =
250-
simpl_ti.visit_glue.map(|v| cast_glue(ccx, ti, *v));
237+
ti.visit_glue = simpl_ti.visit_glue;
251238
}
252239
}
253240
return true;
@@ -260,7 +247,7 @@ pub fn lazily_emit_tydesc_glue(ccx: @CrateContext,
260247
field: uint,
261248
ti: @mut tydesc_info) {
262249
let _icx = ccx.insn_ctxt("lazily_emit_tydesc_glue");
263-
let llfnty = type_of_glue_fn(ccx, ti.ty);
250+
let llfnty = type_of_glue_fn(ccx);
264251

265252
if lazily_emit_simplified_tydesc_glue(ccx, field, ti) {
266253
return;
@@ -353,25 +340,7 @@ pub fn call_tydesc_glue_full(bcx: block,
353340
}
354341
};
355342

356-
// When available, use static type info to give glue the right type.
357-
let static_glue_fn = match static_ti {
358-
None => None,
359-
Some(sti) => {
360-
match static_glue_fn {
361-
None => None,
362-
Some(sgf) => Some(
363-
PointerCast(bcx, sgf, T_ptr(type_of_glue_fn(ccx, sti.ty))))
364-
}
365-
}
366-
};
367-
368-
// When static type info is available, avoid casting parameter because the
369-
// function already has the right type. Otherwise cast to generic pointer.
370-
let llrawptr = if static_ti.is_none() || static_glue_fn.is_none() {
371-
PointerCast(bcx, v, T_ptr(T_i8()))
372-
} else {
373-
v
374-
};
343+
let llrawptr = PointerCast(bcx, v, T_ptr(T_i8()));
375344

376345
let llfn = {
377346
match static_glue_fn {
@@ -736,14 +705,13 @@ pub fn make_generic_glue_inner(ccx: @CrateContext,
736705
// requirement since in many contexts glue is invoked indirectly and
737706
// the caller has no idea if it's dealing with something that can be
738707
// passed by value.
739-
//
740-
// llfn is expected be declared to take a parameter of the appropriate
741-
// type, so we don't need to explicitly cast the function parameter.
742708

743709
let bcx = top_scope_block(fcx, None);
744710
let lltop = bcx.llbb;
745711
let rawptr0_arg = fcx.arg_pos(1u);
746712
let llrawptr0 = unsafe { llvm::LLVMGetParam(llfn, rawptr0_arg as c_uint) };
713+
let llty = type_of(ccx, t);
714+
let llrawptr0 = PointerCast(bcx, llrawptr0, T_ptr(llty));
747715
helper(bcx, llrawptr0, t);
748716
finish_fn(fcx, lltop);
749717
return llfn;

src/librustc/middle/trans/type_of.rs

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -341,8 +341,7 @@ pub fn type_of_rooted(ccx: @CrateContext, t: ty::t) -> TypeRef {
341341
return T_root(type_of(ccx, t), addrspace);
342342
}
343343

344-
pub fn type_of_glue_fn(ccx: @CrateContext, t: ty::t) -> TypeRef {
344+
pub fn type_of_glue_fn(ccx: @CrateContext) -> TypeRef {
345345
let tydescpp = T_ptr(T_ptr(ccx.tydesc_type));
346-
let llty = T_ptr(type_of(ccx, t));
347-
return T_fn([T_ptr(T_nil()), tydescpp, llty], T_nil());
346+
return T_fn([T_ptr(T_nil()), tydescpp, T_ptr(T_i8())], T_nil());
348347
}

0 commit comments

Comments
 (0)