rustc: Run all intrinsics through the monomorphiser

Intrinsics always want to be inlined.
This commit is contained in:
Brian Anderson 2012-09-03 16:44:54 -07:00
parent bb348ccab1
commit 5aedabf1a3
3 changed files with 22 additions and 39 deletions

View File

@ -2504,7 +2504,6 @@ fn lval_static_fn_inner(bcx: block, fn_id: ast::def_id, id: ast::node_id,
// Check whether this fn has an inlined copy and, if so, redirect fn_id to
// the local id of the inlined copy.
let original_crate = fn_id.crate;
let fn_id = if fn_id.crate != ast::local_crate {
maybe_instantiate_inline(ccx, fn_id)
} else { fn_id };
@ -2513,27 +2512,27 @@ fn lval_static_fn_inner(bcx: block, fn_id: ast::def_id, id: ast::node_id,
let local_with_type_params =
fn_id.crate == ast::local_crate && tys.len() > 0u;
// Rust intrinsic functions should always be monomorphised
let inlined_rust_intrinsic = {
if fn_id.crate == ast::local_crate
&& original_crate != ast::local_crate {
// Intrinsic functions should always be monomorphised. In particular,
// if we see an intrinsic that is inlined from a different crate, we
// want to reemit the intrinsic instead of trying to call it in the
// other crate.
let rust_intrinsic = if fn_id.crate == ast::local_crate {
let map_node = session::expect(
ccx.sess,
ccx.tcx.items.find(fn_id.node),
|| fmt!("inlined item should be in ast map"));
let map_node = session::expect(
ccx.sess,
ccx.tcx.items.find(fn_id.node),
|| fmt!("local item should be in ast map"));
match map_node {
ast_map::node_foreign_item(
_, ast::foreign_abi_rust_intrinsic, _) => true,
_ => false
}
} else {
false
match map_node {
ast_map::node_foreign_item(
_, ast::foreign_abi_rust_intrinsic, _) => true,
_ => false
}
} else {
false
};
local_with_type_params || inlined_rust_intrinsic
local_with_type_params || rust_intrinsic
};
if must_monomorphise {

View File

@ -759,7 +759,7 @@ fn trans_foreign_mod(ccx: @crate_ctxt,
for vec::each(foreign_mod.items) |foreign_item| {
match foreign_item.node {
ast::foreign_item_fn(_, _, typarams) => {
ast::foreign_item_fn(*) => {
let id = foreign_item.id;
if abi != ast::foreign_abi_rust_intrinsic {
let llwrapfn = get_item_val(ccx, id);
@ -772,25 +772,7 @@ fn trans_foreign_mod(ccx: @crate_ctxt,
build_wrap_fn(ccx, tys, llshimfn, llwrapfn);
}
} else {
// Intrinsics with type parameters are emitted by
// monomorphic_fn, but ones without are emitted here
if typarams.is_empty() {
let llwrapfn = get_item_val(ccx, id);
let path = match ccx.tcx.items.find(id) {
Some(ast_map::node_foreign_item(_, _, pt)) => pt,
_ => {
ccx.sess.span_bug(foreign_item.span,
~"can't find intrinsic path")
}
};
let psubsts = {
tys: ~[],
vtables: None,
bounds: @~[]
};
trans_intrinsic(ccx, llwrapfn, foreign_item,
*path, psubsts, None);
}
// Intrinsics are emitted by monomorphic fn
}
}
ast::foreign_item_const(*) => {

View File

@ -94,11 +94,13 @@ fn type_uses_for(ccx: @crate_ctxt, fn_id: def_id, n_tps: uint)
~"atomic_xchg_acq" | ~"atomic_xadd_acq" | ~"atomic_xsub_acq" |
~"atomic_xchg_rel" | ~"atomic_xadd_rel" | ~"atomic_xsub_rel" =>
{ 0u }
~"visit_tydesc" | ~"forget" | ~"addr_of" => {
~"visit_tydesc" | ~"forget" | ~"addr_of" |
~"frame_address" | ~"morestack_addr" => {
0u
}
// would be cool to make these an enum instead of strings!
_ => fail ~"unknown intrinsic in type_use"
_ => fail fmt!("unknown intrinsic in type_use %?",
cx.ccx.sess.str_of(i.ident))
};
for uint::range(0u, n_tps) |n| { cx.uses[n] |= flags;}
}