librustc: De-@mut the reachable map

This commit is contained in:
Patrick Walton 2013-12-20 20:14:51 -08:00
parent 417378554c
commit fbb70d916f
6 changed files with 80 additions and 36 deletions

View file

@ -212,7 +212,7 @@ pub struct CrateAnalysis {
exported_items: middle::privacy::ExportedItems,
ty_cx: ty::ctxt,
maps: astencode::Maps,
reachable: @mut HashSet<ast::NodeId>
reachable: @RefCell<HashSet<ast::NodeId>>
}
/// Run the resolution, typechecking, region checking and other
@ -309,9 +309,16 @@ pub fn phase_3_run_analysis_passes(sess: Session,
time(time_passes, "reachability checking", (), |_|
reachable::find_reachable(ty_cx, method_map, &exported_items));
time(time_passes, "death checking", (), |_|
middle::dead::check_crate(ty_cx, method_map,
&exported_items, reachable_map, crate));
{
let reachable_map = reachable_map.borrow();
time(time_passes, "death checking", (), |_| {
middle::dead::check_crate(ty_cx,
method_map,
&exported_items,
reachable_map.get(),
crate)
});
}
time(time_passes, "lint checking", (), |_|
lint::check_crate(ty_cx, method_map, &exported_items, crate));

View file

@ -65,7 +65,7 @@ pub struct EncodeParams<'a> {
link_meta: &'a LinkMeta,
cstore: @cstore::CStore,
encode_inlined_item: encode_inlined_item<'a>,
reachable: @mut HashSet<ast::NodeId>,
reachable: @RefCell<HashSet<ast::NodeId>>,
}
struct Stats {
@ -95,11 +95,12 @@ pub struct EncodeContext<'a> {
cstore: &'a cstore::CStore,
encode_inlined_item: encode_inlined_item<'a>,
type_abbrevs: abbrev_map,
reachable: @mut HashSet<ast::NodeId>,
reachable: @RefCell<HashSet<ast::NodeId>>,
}
pub fn reachable(ecx: &EncodeContext, id: NodeId) -> bool {
ecx.reachable.contains(&id)
let reachable = ecx.reachable.borrow();
reachable.get().contains(&id)
}
fn encode_name(ecx: &EncodeContext,

View file

@ -19,6 +19,7 @@ use middle::ty;
use middle::typeck;
use middle::privacy;
use std::cell::RefCell;
use std::hashmap::HashSet;
use syntax::ast;
use syntax::ast_map;
@ -84,7 +85,7 @@ struct ReachableContext {
// methods they've been resolved to.
method_map: typeck::method_map,
// The set of items which must be exported in the linkage sense.
reachable_symbols: @mut HashSet<ast::NodeId>,
reachable_symbols: @RefCell<HashSet<ast::NodeId>>,
// A worklist of item IDs. Each item ID in this worklist will be inlined
// and will be scanned for further references.
worklist: @mut ~[ast::NodeId],
@ -94,7 +95,7 @@ struct MarkSymbolVisitor {
worklist: @mut ~[ast::NodeId],
method_map: typeck::method_map,
tcx: ty::ctxt,
reachable_symbols: @mut HashSet<ast::NodeId>,
reachable_symbols: @RefCell<HashSet<ast::NodeId>>,
}
impl Visitor<()> for MarkSymbolVisitor {
@ -129,7 +130,9 @@ impl Visitor<()> for MarkSymbolVisitor {
// If this wasn't a static, then this destination is
// surely reachable.
_ => {
self.reachable_symbols.insert(def_id.node);
let mut reachable_symbols =
self.reachable_symbols.borrow_mut();
reachable_symbols.get().insert(def_id.node);
}
}
}
@ -146,9 +149,13 @@ impl Visitor<()> for MarkSymbolVisitor {
def_id_represents_local_inlined_item(
self.tcx,
def_id) {
self.worklist.push(def_id.node)
}
self.reachable_symbols.insert(def_id.node);
self.worklist.push(def_id.node)
}
{
let mut reachable_symbols =
self.reachable_symbols.borrow_mut();
reachable_symbols.get().insert(def_id.node);
}
}
}
Some(_) => {}
@ -177,7 +184,7 @@ impl ReachableContext {
ReachableContext {
tcx: tcx,
method_map: method_map,
reachable_symbols: @mut HashSet::new(),
reachable_symbols: @RefCell::new(HashSet::new()),
worklist: @mut ~[],
}
}
@ -289,7 +296,9 @@ impl ReachableContext {
ast_map::node_item(item, _) => {
match item.node {
ast::item_fn(_, ast::extern_fn, _, _, _) => {
self.reachable_symbols.insert(search_item);
let mut reachable_symbols =
self.reachable_symbols.borrow_mut();
reachable_symbols.get().insert(search_item);
}
_ => {}
}
@ -301,7 +310,8 @@ impl ReachableContext {
// continue to participate in linkage after this product is
// produced. In this case, we traverse the ast node, recursing on
// all reachable nodes from this one.
self.reachable_symbols.insert(search_item);
let mut reachable_symbols = self.reachable_symbols.borrow_mut();
reachable_symbols.get().insert(search_item);
}
match *node {
@ -318,7 +328,9 @@ impl ReachableContext {
ast::item_static(..) => {
if attr::contains_name(item.attrs,
"address_insignificant") {
self.reachable_symbols.remove(&search_item);
let mut reachable_symbols =
self.reachable_symbols.borrow_mut();
reachable_symbols.get().remove(&search_item);
}
}
@ -377,7 +389,9 @@ impl ReachableContext {
let destructor_for_type = self.tcx.destructor_for_type.borrow();
for (_, destructor_def_id) in destructor_for_type.get().iter() {
if destructor_def_id.crate == ast::LOCAL_CRATE {
self.reachable_symbols.insert(destructor_def_id.node);
let mut reachable_symbols = self.reachable_symbols
.borrow_mut();
reachable_symbols.get().insert(destructor_def_id.node);
}
}
}
@ -386,7 +400,7 @@ impl ReachableContext {
pub fn find_reachable(tcx: ty::ctxt,
method_map: typeck::method_map,
exported_items: &privacy::ExportedItems)
-> @mut HashSet<ast::NodeId> {
-> @RefCell<HashSet<ast::NodeId>> {
let reachable_context = ReachableContext::new(tcx, method_map);
// Step 1: Seed the worklist with all nodes which were found to be public as

View file

@ -2318,8 +2318,11 @@ fn finish_register_fn(ccx: @CrateContext, sp: Span, sym: ~str, node_id: ast::Nod
item_symbols.get().insert(node_id, sym);
}
if !ccx.reachable.contains(&node_id) {
lib::llvm::SetLinkage(llfn, lib::llvm::InternalLinkage);
{
let reachable = ccx.reachable.borrow();
if !reachable.get().contains(&node_id) {
lib::llvm::SetLinkage(llfn, lib::llvm::InternalLinkage);
}
}
if is_entry_fn(&ccx.sess, node_id) && !*ccx.sess.building_library {
@ -2531,18 +2534,27 @@ pub fn get_item_val(ccx: @CrateContext, id: ast::NodeId) -> ValueRef {
llvm::LLVMAddGlobal(ccx.llmod, llty, buf)
});
if !ccx.reachable.contains(&id) {
lib::llvm::SetLinkage(g, lib::llvm::InternalLinkage);
{
let reachable = ccx.reachable.borrow();
if !reachable.get().contains(&id) {
lib::llvm::SetLinkage(
g,
lib::llvm::InternalLinkage);
}
}
// Apply the `unnamed_addr` attribute if
// requested
if attr::contains_name(i.attrs,
"address_insignificant"){
if ccx.reachable.contains(&id) {
ccx.sess.span_bug(i.span,
"insignificant static is \
reachable");
{
let reachable =
ccx.reachable.borrow();
if reachable.get().contains(&id) {
ccx.sess.span_bug(i.span,
"insignificant static is \
reachable");
}
}
lib::llvm::SetUnnamedAddr(g, true);
@ -2731,8 +2743,11 @@ pub fn get_item_val(ccx: @CrateContext, id: ast::NodeId) -> ValueRef {
// foreign items (extern fns and extern statics) don't have internal
// linkage b/c that doesn't quite make sense. Otherwise items can
// have internal linkage if they're not reachable.
if !foreign && !ccx.reachable.contains(&id) {
lib::llvm::SetLinkage(val, lib::llvm::InternalLinkage);
{
let reachable = ccx.reachable.borrow();
if !foreign && !reachable.get().contains(&id) {
lib::llvm::SetLinkage(val, lib::llvm::InternalLinkage);
}
}
let mut item_vals = ccx.item_vals.borrow_mut();
@ -3245,10 +3260,14 @@ pub fn trans_crate(sess: session::Session,
let llcx = ccx.llcx;
let link_meta = ccx.link_meta.clone();
let llmod = ccx.llmod;
let mut reachable = ccx.reachable.iter().filter_map(|id| {
let item_symbols = ccx.item_symbols.borrow();
item_symbols.get().find(id).map(|s| s.to_owned())
}).to_owned_vec();
let mut reachable = {
let reachable_map = ccx.reachable.borrow();
reachable_map.get().iter().filter_map(|id| {
let item_symbols = ccx.item_symbols.borrow();
item_symbols.get().find(id).map(|s| s.to_owned())
}).to_owned_vec()
};
// Make sure that some other crucial symbols are not eliminated from the
// module. This includes the main function, the crate map (used for debug

View file

@ -49,7 +49,7 @@ pub struct CrateContext {
intrinsics: HashMap<&'static str, ValueRef>,
item_vals: RefCell<HashMap<ast::NodeId, ValueRef>>,
exp_map2: resolve::ExportMap2,
reachable: @mut HashSet<ast::NodeId>,
reachable: @RefCell<HashSet<ast::NodeId>>,
item_symbols: RefCell<HashMap<ast::NodeId, ~str>>,
link_meta: LinkMeta,
tydescs: RefCell<HashMap<ty::t, @mut tydesc_info>>,
@ -123,7 +123,7 @@ impl CrateContext {
maps: astencode::Maps,
symbol_hasher: Sha256,
link_meta: LinkMeta,
reachable: @mut HashSet<ast::NodeId>)
reachable: @RefCell<HashSet<ast::NodeId>>)
-> CrateContext {
unsafe {
let llcx = llvm::LLVMContextCreate();

View file

@ -732,7 +732,10 @@ pub fn create_function_debug_context(cx: &CrateContext,
// (by being externally visible or by being inlined into something externally visible). It might
// better to use the `exported_items` set from `driver::CrateAnalysis` in the future, but (atm)
// this set is not available in the translation pass.
let is_local_to_unit = !cx.reachable.contains(&fn_ast_id);
let is_local_to_unit = {
let reachable = cx.reachable.borrow();
!reachable.get().contains(&fn_ast_id)
};
let fn_metadata = function_name.with_c_str(|function_name| {
linkage_name.with_c_str(|linkage_name| {