]> git.lizzy.rs Git - rust.git/commitdiff
pull stats out of `SharedCrateContext`
authorNiko Matsakis <niko@alum.mit.edu>
Thu, 13 Apr 2017 21:11:54 +0000 (17:11 -0400)
committerNiko Matsakis <niko@alum.mit.edu>
Thu, 13 Apr 2017 22:37:47 +0000 (18:37 -0400)
shared mutable state is bad

src/librustc_trans/base.rs
src/librustc_trans/context.rs

index cec599e28484baf2d6246f01a706a480e9fe5c2d..3fd966eb73ee6bd32a1dfac023c996463599b3a0 100644 (file)
@@ -57,7 +57,7 @@
 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;
@@ -1115,21 +1115,25 @@ pub fn trans_crate<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 
     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;
@@ -1161,12 +1165,19 @@ fn module_translation<'a, 'tcx>(
                 }
             });
 
-        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);
@@ -1214,17 +1225,17 @@ fn module_translation<'a, 'tcx>(
                 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);
@@ -1232,20 +1243,19 @@ fn module_translation<'a, 'tcx>(
     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);
@@ -1255,7 +1265,7 @@ fn module_translation<'a, 'tcx>(
     }
 
     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);
         }
     }
index 9d18b4574bcc42612c05a85f36ebb4229bf3248b..7e49dee498d003047ae4a72446ffda5b3a2978be 100644 (file)
@@ -45,6 +45,7 @@
 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>,
@@ -58,6 +59,22 @@ pub struct Stats {
     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
@@ -66,7 +83,6 @@ pub struct SharedCrateContext<'a, 'tcx: 'a> {
     exported_symbols: NodeSet,
     tcx: TyCtxt<'a, 'tcx, 'tcx>,
     empty_param_env: ty::ParameterEnvironment<'tcx>,
-    stats: Stats,
     check_overflow: bool,
 
     use_dll_storage_attrs: bool,
@@ -83,6 +99,7 @@ pub struct SharedCrateContext<'a, 'tcx: 'a> {
 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
@@ -366,17 +383,6 @@ pub fn new(tcx: TyCtxt<'b, 'tcx, 'tcx>,
             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()),
@@ -417,10 +423,6 @@ pub fn dep_graph<'a>(&'a self) -> &'a DepGraph {
         &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
     }
@@ -466,6 +468,7 @@ pub fn new<'a>(shared: &SharedCrateContext<'a, 'tcx>,
             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()),
@@ -537,6 +540,10 @@ fn dummy_ccx<'a>(shared: &'a SharedCrateContext<'a, 'tcx>,
             local_ccx: &local_ccxs[0]
         }
     }
+
+    pub fn into_stats(self) -> Stats {
+        self.stats
+    }
 }
 
 impl<'b, 'tcx> CrateContext<'b, 'tcx> {
@@ -651,7 +658,7 @@ pub fn type_hashcodes<'a>(&'a self) -> &'a RefCell<FxHashMap<Ty<'tcx>, String>>
     }
 
     pub fn stats<'a>(&'a self) -> &'a Stats {
-        &self.shared.stats
+        &self.local().stats
     }
 
     pub fn int_type(&self) -> Type {