mirror of
https://github.com/rust-lang/rust.git
synced 2025-02-13 15:33:53 +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) =
|
let (copy_map, ref_map) =
|
||||||
time(time_passes, "alias checking",
|
time(time_passes, "alias checking",
|
||||||
bind middle::alias::check_crate(ty_cx, crate));
|
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));
|
bind last_use::find_last_uses(crate, def_map, ref_map, ty_cx));
|
||||||
time(time_passes, "kind checking",
|
time(time_passes, "kind checking",
|
||||||
bind kind::check_crate(ty_cx, method_map, last_uses, crate));
|
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,
|
let maps = {mutbl_map: mutbl_map, copy_map: copy_map,
|
||||||
last_uses: last_uses, impl_map: impl_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) =
|
let (llmod, link_meta) =
|
||||||
time(time_passes, "translation",
|
time(time_passes, "translation",
|
||||||
|
@ -512,7 +512,7 @@ impl of tr for method_origin {
|
|||||||
impl of tr for last_use::is_last_use {
|
impl of tr for last_use::is_last_use {
|
||||||
fn tr(xcx: extended_decode_ctxt) -> last_use::is_last_use {
|
fn tr(xcx: extended_decode_ctxt) -> last_use::is_last_use {
|
||||||
alt self {
|
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(ids) {
|
||||||
last_use::closes_over(vec::map(ids, {|id| xcx.tr_id(id)}))
|
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|
|
option::may(ccx.maps.last_uses.find(id)) {|m|
|
||||||
ebml_w.tag(c::tag_table_last_use) {||
|
ebml_w.tag(c::tag_table_last_use) {||
|
||||||
ebml_w.id(id);
|
ebml_w.id(id);
|
||||||
@ -869,6 +875,8 @@ fn decode_side_tables(xcx: extended_decode_ctxt,
|
|||||||
dcx.maps.mutbl_map.insert(id, ());
|
dcx.maps.mutbl_map.insert(id, ());
|
||||||
} else if tag == (c::tag_table_copy as uint) {
|
} else if tag == (c::tag_table_copy as uint) {
|
||||||
dcx.maps.copy_map.insert(id, ());
|
dcx.maps.copy_map.insert(id, ());
|
||||||
|
} else if tag == (c::tag_table_spill as uint) {
|
||||||
|
dcx.maps.spill_map.insert(id, ());
|
||||||
} else {
|
} else {
|
||||||
let val_doc = entry_doc[c::tag_table_val];
|
let val_doc = entry_doc[c::tag_table_val];
|
||||||
let val_dsr = ebml::ebml_deserializer(val_doc);
|
let val_dsr = ebml::ebml_deserializer(val_doc);
|
||||||
|
@ -100,6 +100,7 @@ enum astencode_tag { // Reserves 0x50 -- 0x6f
|
|||||||
tag_table_mutbl,
|
tag_table_mutbl,
|
||||||
tag_table_copy,
|
tag_table_copy,
|
||||||
tag_table_last_use,
|
tag_table_last_use,
|
||||||
|
tag_table_spill,
|
||||||
tag_table_method_map,
|
tag_table_method_map,
|
||||||
tag_table_vtable_map
|
tag_table_vtable_map
|
||||||
}
|
}
|
||||||
|
@ -28,10 +28,10 @@ import std::map::hashmap;
|
|||||||
#[auto_serialize]
|
#[auto_serialize]
|
||||||
enum is_last_use {
|
enum is_last_use {
|
||||||
is_last_use,
|
is_last_use,
|
||||||
has_last_use,
|
|
||||||
closes_over([node_id]),
|
closes_over([node_id]),
|
||||||
}
|
}
|
||||||
type last_uses = std::map::hashmap<node_id, is_last_use>;
|
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 seen { unset, seen(node_id), }
|
||||||
enum block_type { func, lp, }
|
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>,
|
type ctx = {last_uses: std::map::hashmap<use_id, bool>,
|
||||||
|
spill_map: std::map::hashmap<node_id, ()>,
|
||||||
def_map: resolve::def_map,
|
def_map: resolve::def_map,
|
||||||
ref_map: alias::ref_map,
|
ref_map: alias::ref_map,
|
||||||
tcx: ty::ctxt,
|
tcx: ty::ctxt,
|
||||||
@ -54,12 +55,14 @@ type ctx = {last_uses: std::map::hashmap<use_id, bool>,
|
|||||||
mutable blocks: list<bl>};
|
mutable blocks: list<bl>};
|
||||||
|
|
||||||
fn find_last_uses(c: @crate, def_map: resolve::def_map,
|
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,
|
let v = visit::mk_vt(@{visit_expr: visit_expr,
|
||||||
visit_stmt: visit_stmt,
|
visit_stmt: visit_stmt,
|
||||||
visit_fn: visit_fn
|
visit_fn: visit_fn
|
||||||
with *visit::default_visitor()});
|
with *visit::default_visitor()});
|
||||||
let cx = {last_uses: std::map::hashmap(hash_use_id, {|a, b| a == b}),
|
let cx = {last_uses: std::map::hashmap(hash_use_id, {|a, b| a == b}),
|
||||||
|
spill_map: std::map::int_hash(),
|
||||||
def_map: def_map,
|
def_map: def_map,
|
||||||
ref_map: ref_map,
|
ref_map: ref_map,
|
||||||
tcx: tcx,
|
tcx: tcx,
|
||||||
@ -73,10 +76,10 @@ fn find_last_uses(c: @crate, def_map: resolve::def_map,
|
|||||||
path(id) {
|
path(id) {
|
||||||
mini_table.insert(id, is_last_use);
|
mini_table.insert(id, is_last_use);
|
||||||
let def_node = ast_util::def_id_of_def(def_map.get(id)).node;
|
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) {
|
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) {
|
let known = alt check mini_table.find(fn_id) {
|
||||||
some(closes_over(ids)) { ids }
|
some(closes_over(ids)) { ids }
|
||||||
none { [] }
|
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>) {
|
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(_) {
|
expr_path(_) {
|
||||||
alt ty::arg_mode(cx.tcx, arg_t) {
|
alt ty::arg_mode(cx.tcx, arg_t) {
|
||||||
by_ref | by_val | by_mutbl_ref {
|
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();
|
let ccx = cx.ccx();
|
||||||
if option::is_some(simple_name) &&
|
if option::is_some(simple_name) &&
|
||||||
!ccx.maps.mutbl_map.contains_key(local.node.pat.id) &&
|
!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) {
|
ty::type_is_immediate(t) {
|
||||||
alt local.node.init {
|
alt local.node.init {
|
||||||
some({op: ast::init_assign, _}) { ret cx; }
|
some({op: ast::init_assign, _}) { ret cx; }
|
||||||
|
@ -69,7 +69,8 @@ type maps = {
|
|||||||
last_uses: middle::last_use::last_uses,
|
last_uses: middle::last_use::last_uses,
|
||||||
impl_map: middle::resolve::impl_map,
|
impl_map: middle::resolve::impl_map,
|
||||||
method_map: middle::typeck::method_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.
|
// 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