Auto merge of #38272 - michaelwoerister:incr-symbol-visibility, r=nikomatsakis

incr.comp.: Take symbol visibility into account for CGU hashes

r? @nikomatsakis
This commit is contained in:
bors 2016-12-11 18:20:52 +00:00
commit 6d5ec58912
5 changed files with 79 additions and 13 deletions

View File

@ -48,6 +48,7 @@ pub mod ich;
pub use assert_dep_graph::assert_dep_graph;
pub use calculate_svh::compute_incremental_hashes_map;
pub use calculate_svh::IncrementalHashesMap;
pub use calculate_svh::hasher::IchHasher;
pub use persist::load_dep_graph;
pub use persist::save_dep_graph;
pub use persist::save_trans_partition;

View File

@ -1610,7 +1610,7 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
let symbol_map = Rc::new(symbol_map);
let previous_work_products = trans_reuse_previous_work_products(tcx,
let previous_work_products = trans_reuse_previous_work_products(&shared_ccx,
&codegen_units,
&symbol_map);
@ -1630,7 +1630,9 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
ModuleTranslation {
name: String::from(ccx.codegen_unit().name()),
symbol_name_hash: ccx.codegen_unit().compute_symbol_name_hash(tcx, &symbol_map),
symbol_name_hash: ccx.codegen_unit()
.compute_symbol_name_hash(&shared_ccx,
&symbol_map),
source: source,
}
})
@ -1962,7 +1964,7 @@ fn gather_type_sizes<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>) {
/// For each CGU, identify if we can reuse an existing object file (or
/// maybe other context).
fn trans_reuse_previous_work_products(tcx: TyCtxt,
fn trans_reuse_previous_work_products(scx: &SharedCrateContext,
codegen_units: &[CodegenUnit],
symbol_map: &SymbolMap)
-> Vec<Option<WorkProduct>> {
@ -1972,16 +1974,16 @@ fn trans_reuse_previous_work_products(tcx: TyCtxt,
.map(|cgu| {
let id = cgu.work_product_id();
let hash = cgu.compute_symbol_name_hash(tcx, symbol_map);
let hash = cgu.compute_symbol_name_hash(scx, symbol_map);
debug!("trans_reuse_previous_work_products: id={:?} hash={}", id, hash);
if let Some(work_product) = tcx.dep_graph.previous_work_product(&id) {
if let Some(work_product) = scx.dep_graph().previous_work_product(&id) {
if work_product.input_hash == hash {
debug!("trans_reuse_previous_work_products: reusing {:?}", work_product);
return Some(work_product);
} else {
if tcx.sess.opts.debugging_opts.incremental_info {
if scx.sess().opts.debugging_opts.incremental_info {
println!("incremental: CGU `{}` invalidated because of \
changed partitioning hash.",
cgu.name());

View File

@ -10,7 +10,8 @@
use llvm;
use llvm::{ContextRef, ModuleRef, ValueRef, BuilderRef};
use rustc::dep_graph::{DepNode, DepTrackingMap, DepTrackingMapConfig, WorkProduct};
use rustc::dep_graph::{DepGraph, DepNode, DepTrackingMap, DepTrackingMapConfig,
WorkProduct};
use middle::cstore::LinkMeta;
use rustc::hir::def::ExportMap;
use rustc::hir::def_id::DefId;
@ -551,6 +552,10 @@ impl<'b, 'tcx> SharedCrateContext<'b, 'tcx> {
&self.tcx.sess
}
pub fn dep_graph<'a>(&'a self) -> &'a DepGraph {
&self.tcx.dep_graph
}
pub fn stats<'a>(&'a self) -> &'a Stats {
&self.stats
}

View File

@ -126,10 +126,10 @@ use rustc::hir::map::DefPathData;
use rustc::session::config::NUMBERED_CODEGEN_UNIT_MARKER;
use rustc::ty::TyCtxt;
use rustc::ty::item_path::characteristic_def_id_of_type;
use rustc_incremental::IchHasher;
use std::cmp::Ordering;
use std::hash::{Hash, Hasher};
use std::hash::Hash;
use std::sync::Arc;
use std::collections::hash_map::DefaultHasher;
use symbol_map::SymbolMap;
use syntax::ast::NodeId;
use syntax::symbol::{Symbol, InternedString};
@ -188,14 +188,30 @@ impl<'tcx> CodegenUnit<'tcx> {
DepNode::WorkProduct(self.work_product_id())
}
pub fn compute_symbol_name_hash(&self, tcx: TyCtxt, symbol_map: &SymbolMap) -> u64 {
let mut state = DefaultHasher::new();
let all_items = self.items_in_deterministic_order(tcx, symbol_map);
pub fn compute_symbol_name_hash(&self,
scx: &SharedCrateContext,
symbol_map: &SymbolMap) -> u64 {
let mut state = IchHasher::new();
let exported_symbols = scx.exported_symbols();
let all_items = self.items_in_deterministic_order(scx.tcx(), symbol_map);
for (item, _) in all_items {
let symbol_name = symbol_map.get(item).unwrap();
symbol_name.len().hash(&mut state);
symbol_name.hash(&mut state);
let exported = match item {
TransItem::Fn(ref instance) => {
let node_id = scx.tcx().map.as_local_node_id(instance.def);
node_id.map(|node_id| exported_symbols.contains(&node_id))
.unwrap_or(false)
}
TransItem::Static(node_id) => {
exported_symbols.contains(&node_id)
}
TransItem::DropGlue(..) => false,
};
exported.hash(&mut state);
}
state.finish()
state.finish().to_smaller_hash()
}
pub fn items_in_deterministic_order(&self,

View File

@ -0,0 +1,42 @@
// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// revisions: rpass1 rpass2
#![feature(rustc_attrs)]
#![allow(private_no_mangle_fns)]
#![rustc_partition_reused(module="change_symbol_export_status", cfg="rpass2")]
#![rustc_partition_translated(module="change_symbol_export_status-mod1", cfg="rpass2")]
// This test case makes sure that a change in symbol visibility is detected by
// our dependency tracking. We do this by changing a module's visibility to
// `private` in rpass2, causing the contained function to go from `default` to
// `hidden` visibility.
// The function is marked with #[no_mangle] so it is considered for exporting
// even from an executable. Plain Rust functions are only exported from Rust
// libraries, which our test infrastructure does not support.
#[cfg(rpass1)]
pub mod mod1 {
#[no_mangle]
pub fn foo() {}
}
#[cfg(rpass2)]
mod mod1 {
#[no_mangle]
pub fn foo() {}
}
fn main() {
mod1::foo();
}