use common::{type_is_zero_size, val_ty};
use common;
use consts;
-use context::{self, LocalCrateContext, SharedCrateContext};
+use context::{self, LocalCrateContext, SharedCrateContext, Stats};
use debuginfo;
use declare;
use machine;
let symbol_map = Rc::new(symbol_map);
+ let mut all_stats = Stats::default();
let modules: Vec<ModuleTranslation> = codegen_units
.into_iter()
.map(|cgu| {
let dep_node = cgu.work_product_dep_node();
- tcx.dep_graph.with_task(dep_node,
- AssertDepGraphSafe(&shared_ccx),
- AssertDepGraphSafe((cgu, symbol_map.clone())),
- module_translation)
+ let (stats, module) =
+ tcx.dep_graph.with_task(dep_node,
+ AssertDepGraphSafe(&shared_ccx),
+ AssertDepGraphSafe((cgu, symbol_map.clone())),
+ module_translation);
+ all_stats.extend(stats);
+ module
})
.collect();
fn module_translation<'a, 'tcx>(
scx: AssertDepGraphSafe<&SharedCrateContext<'a, 'tcx>>,
args: AssertDepGraphSafe<(CodegenUnit<'tcx>, Rc<SymbolMap<'tcx>>)>)
- -> ModuleTranslation
+ -> (Stats, ModuleTranslation)
{
// FIXME(#40304): We ought to be using the id as a key and some queries, I think.
let AssertDepGraphSafe(scx) = scx;
}
});
- let source = if let Some(buf) = previous_work_product {
+ if let Some(buf) = previous_work_product {
// Don't need to translate this module.
- ModuleSource::Preexisting(buf.clone())
- } else {
- // Instantiate translation items without filling out definitions yet...
- let lcx = LocalCrateContext::new(scx, cgu, symbol_map.clone());
+ let module = ModuleTranslation {
+ name: cgu_name,
+ symbol_name_hash,
+ source: ModuleSource::Preexisting(buf.clone())
+ };
+ return (Stats::default(), module);
+ }
+
+ // Instantiate translation items without filling out definitions yet...
+ let lcx = LocalCrateContext::new(scx, cgu, symbol_map.clone());
+ let module = {
let ccx = CrateContext::new(scx, &lcx);
let trans_items = ccx.codegen_unit()
.items_in_deterministic_order(ccx.tcx(), &symbol_map);
debuginfo::finalize(&ccx);
}
- ModuleSource::Translated(ModuleLlvm {
- llcx: ccx.llcx(),
- llmod: ccx.llmod(),
- })
+ ModuleTranslation {
+ name: cgu_name,
+ symbol_name_hash,
+ source: ModuleSource::Translated(ModuleLlvm {
+ llcx: ccx.llcx(),
+ llmod: ccx.llmod(),
+ })
+ }
};
- ModuleTranslation {
- name: cgu_name,
- symbol_name_hash,
- source,
- }
+ (lcx.into_stats(), module)
}
assert_module_sources::assert_module_sources(tcx, &modules);
symbol_names_test::report_symbol_names(&shared_ccx);
if shared_ccx.sess().trans_stats() {
- let stats = shared_ccx.stats();
println!("--- trans stats ---");
- println!("n_glues_created: {}", stats.n_glues_created.get());
- println!("n_null_glues: {}", stats.n_null_glues.get());
- println!("n_real_glues: {}", stats.n_real_glues.get());
+ println!("n_glues_created: {}", all_stats.n_glues_created.get());
+ println!("n_null_glues: {}", all_stats.n_null_glues.get());
+ println!("n_real_glues: {}", all_stats.n_real_glues.get());
- println!("n_fns: {}", stats.n_fns.get());
- println!("n_inlines: {}", stats.n_inlines.get());
- println!("n_closures: {}", stats.n_closures.get());
+ println!("n_fns: {}", all_stats.n_fns.get());
+ println!("n_inlines: {}", all_stats.n_inlines.get());
+ println!("n_closures: {}", all_stats.n_closures.get());
println!("fn stats:");
- stats.fn_stats.borrow_mut().sort_by(|&(_, insns_a), &(_, insns_b)| {
+ all_stats.fn_stats.borrow_mut().sort_by(|&(_, insns_a), &(_, insns_b)| {
insns_b.cmp(&insns_a)
});
- for tuple in stats.fn_stats.borrow().iter() {
+ for tuple in all_stats.fn_stats.borrow().iter() {
match *tuple {
(ref name, insns) => {
println!("{} insns, {}", insns, *name);
}
if shared_ccx.sess().count_llvm_insns() {
- for (k, v) in shared_ccx.stats().llvm_insns.borrow().iter() {
+ for (k, v) in all_stats.llvm_insns.borrow().iter() {
println!("{:7} {}", *v, *k);
}
}
use syntax_pos::DUMMY_SP;
use abi::Abi;
+#[derive(Clone, Default)]
pub struct Stats {
pub n_glues_created: Cell<usize>,
pub n_null_glues: Cell<usize>,
pub fn_stats: RefCell<Vec<(String, usize)> >,
}
+impl Stats {
+ pub fn extend(&mut self, stats: Stats) {
+ self.n_glues_created.set(self.n_glues_created.get() + stats.n_glues_created.get());
+ self.n_null_glues.set(self.n_null_glues.get() + stats.n_null_glues.get());
+ self.n_real_glues.set(self.n_real_glues.get() + stats.n_real_glues.get());
+ self.n_fns.set(self.n_fns.get() + stats.n_fns.get());
+ self.n_inlines.set(self.n_inlines.get() + stats.n_inlines.get());
+ self.n_closures.set(self.n_closures.get() + stats.n_closures.get());
+ self.n_llvm_insns.set(self.n_llvm_insns.get() + stats.n_llvm_insns.get());
+ self.llvm_insns.borrow_mut().extend(
+ stats.llvm_insns.borrow().iter()
+ .map(|(key, value)| (key.clone(), value.clone())));
+ self.fn_stats.borrow_mut().append(&mut *stats.fn_stats.borrow_mut());
+ }
+}
+
/// The shared portion of a `CrateContext`. There is one `SharedCrateContext`
/// per crate. The data here is shared between all compilation units of the
/// crate, so it must not contain references to any LLVM data structures
exported_symbols: NodeSet,
tcx: TyCtxt<'a, 'tcx, 'tcx>,
empty_param_env: ty::ParameterEnvironment<'tcx>,
- stats: Stats,
check_overflow: bool,
use_dll_storage_attrs: bool,
pub struct LocalCrateContext<'tcx> {
llmod: ModuleRef,
llcx: ContextRef,
+ stats: Stats,
codegen_unit: CodegenUnit<'tcx>,
needs_unwind_cleanup_cache: RefCell<FxHashMap<Ty<'tcx>, bool>>,
/// Cache instances of monomorphic and polymorphic items
exported_symbols: exported_symbols,
empty_param_env: tcx.empty_parameter_environment(),
tcx: tcx,
- stats: Stats {
- n_glues_created: Cell::new(0),
- n_null_glues: Cell::new(0),
- n_real_glues: Cell::new(0),
- n_fns: Cell::new(0),
- n_inlines: Cell::new(0),
- n_closures: Cell::new(0),
- n_llvm_insns: Cell::new(0),
- llvm_insns: RefCell::new(FxHashMap()),
- fn_stats: RefCell::new(Vec::new()),
- },
check_overflow: check_overflow,
use_dll_storage_attrs: use_dll_storage_attrs,
translation_items: RefCell::new(FxHashSet()),
&self.tcx.dep_graph
}
- pub fn stats<'a>(&'a self) -> &'a Stats {
- &self.stats
- }
-
pub fn use_dll_storage_attrs(&self) -> bool {
self.use_dll_storage_attrs
}
let local_ccx = LocalCrateContext {
llmod: llmod,
llcx: llcx,
+ stats: Stats::default(),
codegen_unit: codegen_unit,
needs_unwind_cleanup_cache: RefCell::new(FxHashMap()),
instances: RefCell::new(FxHashMap()),
local_ccx: &local_ccxs[0]
}
}
+
+ pub fn into_stats(self) -> Stats {
+ self.stats
+ }
}
impl<'b, 'tcx> CrateContext<'b, 'tcx> {
}
pub fn stats<'a>(&'a self) -> &'a Stats {
- &self.shared.stats
+ &self.local().stats
}
pub fn int_type(&self) -> Type {