rustc: Run all intrinsics through the monomorphiser
Intrinsics always want to be inlined.
This commit is contained in:
parent
bb348ccab1
commit
5aedabf1a3
@ -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 {
|
||||
|
@ -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(*) => {
|
||||
|
@ -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;}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user