mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-03 10:33:34 +00:00
Keep an explicit map of things that have to be spilled
This prevents us from spilling locals more than once. Closes #2040
This commit is contained in:
parent
1b81c5112a
commit
84019aa0dc
@ -169,7 +169,7 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg,
|
||||
let (copy_map, ref_map) =
|
||||
time(time_passes, "alias checking",
|
||||
bind middle::alias::check_crate(ty_cx, crate));
|
||||
let last_uses = time(time_passes, "last use finding",
|
||||
let (last_uses, spill_map) = time(time_passes, "last use finding",
|
||||
bind last_use::find_last_uses(crate, def_map, ref_map, ty_cx));
|
||||
time(time_passes, "kind checking",
|
||||
bind kind::check_crate(ty_cx, method_map, last_uses, crate));
|
||||
@ -181,7 +181,8 @@ fn compile_upto(sess: session, cfg: ast::crate_cfg,
|
||||
|
||||
let maps = {mutbl_map: mutbl_map, copy_map: copy_map,
|
||||
last_uses: last_uses, impl_map: impl_map,
|
||||
method_map: method_map, vtable_map: vtable_map};
|
||||
method_map: method_map, vtable_map: vtable_map,
|
||||
spill_map: spill_map};
|
||||
|
||||
let (llmod, link_meta) =
|
||||
time(time_passes, "translation",
|
||||
|
@ -512,7 +512,7 @@ impl of tr for method_origin {
|
||||
impl of tr for last_use::is_last_use {
|
||||
fn tr(xcx: extended_decode_ctxt) -> last_use::is_last_use {
|
||||
alt self {
|
||||
last_use::is_last_use | last_use::has_last_use { self }
|
||||
last_use::is_last_use { self }
|
||||
last_use::closes_over(ids) {
|
||||
last_use::closes_over(vec::map(ids, {|id| xcx.tr_id(id)}))
|
||||
}
|
||||
@ -780,6 +780,12 @@ fn encode_side_tables_for_id(ecx: @e::encode_ctxt,
|
||||
}
|
||||
}
|
||||
|
||||
option::may(ccx.maps.spill_map.find(id)) {|_m|
|
||||
ebml_w.tag(c::tag_table_spill) {||
|
||||
ebml_w.id(id);
|
||||
}
|
||||
}
|
||||
|
||||
option::may(ccx.maps.last_uses.find(id)) {|m|
|
||||
ebml_w.tag(c::tag_table_last_use) {||
|
||||
ebml_w.id(id);
|
||||
@ -869,6 +875,8 @@ fn decode_side_tables(xcx: extended_decode_ctxt,
|
||||
dcx.maps.mutbl_map.insert(id, ());
|
||||
} else if tag == (c::tag_table_copy as uint) {
|
||||
dcx.maps.copy_map.insert(id, ());
|
||||
} else if tag == (c::tag_table_spill as uint) {
|
||||
dcx.maps.spill_map.insert(id, ());
|
||||
} else {
|
||||
let val_doc = entry_doc[c::tag_table_val];
|
||||
let val_dsr = ebml::ebml_deserializer(val_doc);
|
||||
|
@ -100,6 +100,7 @@ enum astencode_tag { // Reserves 0x50 -- 0x6f
|
||||
tag_table_mutbl,
|
||||
tag_table_copy,
|
||||
tag_table_last_use,
|
||||
tag_table_spill,
|
||||
tag_table_method_map,
|
||||
tag_table_vtable_map
|
||||
}
|
||||
|
@ -28,10 +28,10 @@ import std::map::hashmap;
|
||||
#[auto_serialize]
|
||||
enum is_last_use {
|
||||
is_last_use,
|
||||
has_last_use,
|
||||
closes_over([node_id]),
|
||||
}
|
||||
type last_uses = std::map::hashmap<node_id, is_last_use>;
|
||||
type spill_map = std::map::hashmap<node_id, ()>;
|
||||
|
||||
enum seen { unset, seen(node_id), }
|
||||
enum block_type { func, lp, }
|
||||
@ -46,6 +46,7 @@ fn hash_use_id(id: use_id) -> uint {
|
||||
}
|
||||
|
||||
type ctx = {last_uses: std::map::hashmap<use_id, bool>,
|
||||
spill_map: std::map::hashmap<node_id, ()>,
|
||||
def_map: resolve::def_map,
|
||||
ref_map: alias::ref_map,
|
||||
tcx: ty::ctxt,
|
||||
@ -54,12 +55,14 @@ type ctx = {last_uses: std::map::hashmap<use_id, bool>,
|
||||
mutable blocks: list<bl>};
|
||||
|
||||
fn find_last_uses(c: @crate, def_map: resolve::def_map,
|
||||
ref_map: alias::ref_map, tcx: ty::ctxt) -> last_uses {
|
||||
ref_map: alias::ref_map, tcx: ty::ctxt)
|
||||
-> (last_uses, spill_map) {
|
||||
let v = visit::mk_vt(@{visit_expr: visit_expr,
|
||||
visit_stmt: visit_stmt,
|
||||
visit_fn: visit_fn
|
||||
with *visit::default_visitor()});
|
||||
let cx = {last_uses: std::map::hashmap(hash_use_id, {|a, b| a == b}),
|
||||
spill_map: std::map::int_hash(),
|
||||
def_map: def_map,
|
||||
ref_map: ref_map,
|
||||
tcx: tcx,
|
||||
@ -73,10 +76,10 @@ fn find_last_uses(c: @crate, def_map: resolve::def_map,
|
||||
path(id) {
|
||||
mini_table.insert(id, is_last_use);
|
||||
let def_node = ast_util::def_id_of_def(def_map.get(id)).node;
|
||||
mini_table.insert(def_node, has_last_use);
|
||||
cx.spill_map.insert(def_node, ());
|
||||
}
|
||||
close(fn_id, local_id) {
|
||||
mini_table.insert(local_id, has_last_use);
|
||||
cx.spill_map.insert(local_id, ());
|
||||
let known = alt check mini_table.find(fn_id) {
|
||||
some(closes_over(ids)) { ids }
|
||||
none { [] }
|
||||
@ -85,7 +88,7 @@ fn find_last_uses(c: @crate, def_map: resolve::def_map,
|
||||
}
|
||||
}
|
||||
}
|
||||
ret mini_table;
|
||||
ret (mini_table, cx.spill_map);
|
||||
}
|
||||
|
||||
fn visit_expr(ex: @expr, cx: ctx, v: visit::vt<ctx>) {
|
||||
@ -187,7 +190,11 @@ fn visit_expr(ex: @expr, cx: ctx, v: visit::vt<ctx>) {
|
||||
expr_path(_) {
|
||||
alt ty::arg_mode(cx.tcx, arg_t) {
|
||||
by_ref | by_val | by_mutbl_ref {
|
||||
clear_if_path(cx, arg, v, false);
|
||||
let def = cx.def_map.get(arg.id);
|
||||
option::may(def_is_owned_local(cx, def)) {|id|
|
||||
clear_in_current(cx, id, false);
|
||||
cx.spill_map.insert(id, ());
|
||||
}
|
||||
}
|
||||
_ {}
|
||||
}
|
||||
|
@ -3687,7 +3687,7 @@ fn alloc_local(cx: block, local: @ast::local) -> block {
|
||||
let ccx = cx.ccx();
|
||||
if option::is_some(simple_name) &&
|
||||
!ccx.maps.mutbl_map.contains_key(local.node.pat.id) &&
|
||||
!ccx.maps.last_uses.contains_key(local.node.pat.id) &&
|
||||
!ccx.maps.spill_map.contains_key(local.node.pat.id) &&
|
||||
ty::type_is_immediate(t) {
|
||||
alt local.node.init {
|
||||
some({op: ast::init_assign, _}) { ret cx; }
|
||||
|
@ -69,7 +69,8 @@ type maps = {
|
||||
last_uses: middle::last_use::last_uses,
|
||||
impl_map: middle::resolve::impl_map,
|
||||
method_map: middle::typeck::method_map,
|
||||
vtable_map: middle::typeck::vtable_map
|
||||
vtable_map: middle::typeck::vtable_map,
|
||||
spill_map: last_use::spill_map
|
||||
};
|
||||
|
||||
// Crate context. Every crate we compile has one of these.
|
||||
|
6
src/test/run-pass/stable-addr-of.rs
Normal file
6
src/test/run-pass/stable-addr-of.rs
Normal file
@ -0,0 +1,6 @@
|
||||
// Issue #2040
|
||||
|
||||
fn main() {
|
||||
let foo = 1;
|
||||
assert ptr::addr_of(foo) == ptr::addr_of(foo);
|
||||
}
|
Loading…
Reference in New Issue
Block a user