librustc: De-@mut the reachable map
This commit is contained in:
parent
417378554c
commit
fbb70d916f
6 changed files with 80 additions and 36 deletions
|
|
@ -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));
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
|
|
|
|||
|
|
@ -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| {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue