From 7f04d35cc6ca34e94a0635bde76a401f7f4a65da Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Thu, 21 Apr 2016 16:45:33 -0400 Subject: [PATCH] Add FixedUnitCount codegen unit partitioning strategy. --- src/librustc_trans/base.rs | 13 ++++++- src/librustc_trans/partitioning.rs | 39 ++++++++++++++++++- .../partitioning/extern-drop-glue.rs | 2 +- .../partitioning/extern-generic.rs | 2 +- .../inlining-from-extern-crate.rs | 2 +- .../partitioning/local-drop-glue.rs | 2 +- .../partitioning/local-generic.rs | 2 +- .../partitioning/local-inlining.rs | 2 +- .../partitioning/local-transitive-inlining.rs | 2 +- .../methods-are-with-self-type.rs | 2 +- .../partitioning/regular-modules.rs | 2 +- .../codegen-units/partitioning/statics.rs | 2 +- 12 files changed, 59 insertions(+), 13 deletions(-) diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 9190389b722b..ae097b823a6c 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -58,7 +58,7 @@ use attributes; use build::*; use builder::{Builder, noname}; use callee::{Callee, CallArgs, ArgExprs, ArgVals}; -use partitioning; +use partitioning::{self, PartitioningStrategy}; use cleanup::{self, CleanupMethods, DropHint}; use closure; use common::{Block, C_bool, C_bytes_in_context, C_i32, C_int, C_uint, C_integral}; @@ -2938,8 +2938,17 @@ fn collect_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>) { collector::collect_crate_translation_items(&ccx, collection_mode) }); + let strategy = if ccx.sess().opts.debugging_opts.incremental.is_some() { + PartitioningStrategy::PerModule + } else { + PartitioningStrategy::FixedUnitCount(ccx.sess().opts.cg.codegen_units) + }; + let codegen_units = time(time_passes, "codegen unit partitioning", || { - partitioning::partition(ccx.tcx(), items.iter().cloned(), &inlining_map) + partitioning::partition(ccx.tcx(), + items.iter().cloned(), + strategy, + &inlining_map) }); if ccx.sess().opts.debugging_opts.print_trans_items.is_some() { diff --git a/src/librustc_trans/partitioning.rs b/src/librustc_trans/partitioning.rs index d482814961fb..d98c377531a4 100644 --- a/src/librustc_trans/partitioning.rs +++ b/src/librustc_trans/partitioning.rs @@ -132,11 +132,17 @@ pub struct CodegenUnit<'tcx> { pub items: FnvHashMap, llvm::Linkage>, } +pub enum PartitioningStrategy { + PerModule, + FixedUnitCount(usize) +} + // Anything we can't find a proper codegen unit for goes into this. const FALLBACK_CODEGEN_UNIT: &'static str = "__rustc_fallback_codegen_unit"; pub fn partition<'tcx, I>(tcx: &TyCtxt<'tcx>, trans_items: I, + strategy: PartitioningStrategy, inlining_map: &InliningMap<'tcx>) -> Vec> where I: Iterator> @@ -144,7 +150,11 @@ pub fn partition<'tcx, I>(tcx: &TyCtxt<'tcx>, // In the first step, we place all regular translation items into their // respective 'home' codegen unit. Regular translation items are all // functions and statics defined in the local crate. - let initial_partitioning = place_root_translation_items(tcx, trans_items); + let mut initial_partitioning = place_root_translation_items(tcx, trans_items); + + if let PartitioningStrategy::FixedUnitCount(count) = strategy { + merge_codegen_units(&mut initial_partitioning, count, &tcx.crate_name[..]); + } // In the next step, we use the inlining map to determine which addtional // translation items have to go into each codegen unit. These additional @@ -217,6 +227,33 @@ fn place_root_translation_items<'tcx, I>(tcx: &TyCtxt<'tcx>, } } +fn merge_codegen_units<'tcx>(initial_partitioning: &mut InitialPartitioning<'tcx>, + target_cgu_count: usize, + crate_name: &str) { + if target_cgu_count >= initial_partitioning.codegen_units.len() { + return; + } + + assert!(target_cgu_count >= 1); + let codegen_units = &mut initial_partitioning.codegen_units; + + // Merge the two smallest codegen units until the target size is reached + while codegen_units.len() > target_cgu_count { + // Sort small cgus to the back + codegen_units.as_mut_slice().sort_by_key(|cgu| -(cgu.items.len() as i64)); + let smallest = codegen_units.pop().unwrap(); + let second_smallest = codegen_units.last_mut().unwrap(); + + for (k, v) in smallest.items.into_iter() { + second_smallest.items.insert(k, v); + } + } + + for (index, cgu) in codegen_units.iter_mut().enumerate() { + cgu.name = token::intern_and_get_ident(&format!("{}.{}", crate_name, index)[..]); + } +} + fn place_inlined_translation_items<'tcx>(initial_partitioning: InitialPartitioning<'tcx>, inlining_map: &InliningMap<'tcx>) -> Vec> { diff --git a/src/test/codegen-units/partitioning/extern-drop-glue.rs b/src/test/codegen-units/partitioning/extern-drop-glue.rs index bd57a09fadd3..78a051de6c78 100644 --- a/src/test/codegen-units/partitioning/extern-drop-glue.rs +++ b/src/test/codegen-units/partitioning/extern-drop-glue.rs @@ -9,7 +9,7 @@ // except according to those terms. // ignore-tidy-linelength -// compile-flags:-Zprint-trans-items=lazy +// compile-flags:-Zprint-trans-items=lazy -Zincremental="" #![allow(dead_code)] #![crate_type="lib"] diff --git a/src/test/codegen-units/partitioning/extern-generic.rs b/src/test/codegen-units/partitioning/extern-generic.rs index 71af676b0a97..c28dfb49de33 100644 --- a/src/test/codegen-units/partitioning/extern-generic.rs +++ b/src/test/codegen-units/partitioning/extern-generic.rs @@ -9,7 +9,7 @@ // except according to those terms. // ignore-tidy-linelength -// compile-flags:-Zprint-trans-items=eager +// compile-flags:-Zprint-trans-items=eager -Zincremental="" #![allow(dead_code)] #![crate_type="lib"] diff --git a/src/test/codegen-units/partitioning/inlining-from-extern-crate.rs b/src/test/codegen-units/partitioning/inlining-from-extern-crate.rs index 469f2c08c39c..9071050da114 100644 --- a/src/test/codegen-units/partitioning/inlining-from-extern-crate.rs +++ b/src/test/codegen-units/partitioning/inlining-from-extern-crate.rs @@ -9,7 +9,7 @@ // except according to those terms. // ignore-tidy-linelength -// compile-flags:-Zprint-trans-items=lazy +// compile-flags:-Zprint-trans-items=lazy -Zincremental="" #![crate_type="lib"] diff --git a/src/test/codegen-units/partitioning/local-drop-glue.rs b/src/test/codegen-units/partitioning/local-drop-glue.rs index a42a34a0766b..532eaef4659f 100644 --- a/src/test/codegen-units/partitioning/local-drop-glue.rs +++ b/src/test/codegen-units/partitioning/local-drop-glue.rs @@ -9,7 +9,7 @@ // except according to those terms. // ignore-tidy-linelength -// compile-flags:-Zprint-trans-items=lazy +// compile-flags:-Zprint-trans-items=lazy -Zincremental="" #![allow(dead_code)] #![crate_type="lib"] diff --git a/src/test/codegen-units/partitioning/local-generic.rs b/src/test/codegen-units/partitioning/local-generic.rs index 08c8ff0cb2f9..d2ccf36515c1 100644 --- a/src/test/codegen-units/partitioning/local-generic.rs +++ b/src/test/codegen-units/partitioning/local-generic.rs @@ -9,7 +9,7 @@ // except according to those terms. // ignore-tidy-linelength -// compile-flags:-Zprint-trans-items=eager +// compile-flags:-Zprint-trans-items=eager -Zincremental="" #![allow(dead_code)] #![crate_type="lib"] diff --git a/src/test/codegen-units/partitioning/local-inlining.rs b/src/test/codegen-units/partitioning/local-inlining.rs index d2bfa8383466..194e5763ac50 100644 --- a/src/test/codegen-units/partitioning/local-inlining.rs +++ b/src/test/codegen-units/partitioning/local-inlining.rs @@ -9,7 +9,7 @@ // except according to those terms. // ignore-tidy-linelength -// compile-flags:-Zprint-trans-items=lazy +// compile-flags:-Zprint-trans-items=lazy -Zincremental="" #![allow(dead_code)] #![crate_type="lib"] diff --git a/src/test/codegen-units/partitioning/local-transitive-inlining.rs b/src/test/codegen-units/partitioning/local-transitive-inlining.rs index 2e47dc5c9020..7b1b7e8cb0a8 100644 --- a/src/test/codegen-units/partitioning/local-transitive-inlining.rs +++ b/src/test/codegen-units/partitioning/local-transitive-inlining.rs @@ -9,7 +9,7 @@ // except according to those terms. // ignore-tidy-linelength -// compile-flags:-Zprint-trans-items=lazy +// compile-flags:-Zprint-trans-items=lazy -Zincremental="" #![allow(dead_code)] #![crate_type="lib"] diff --git a/src/test/codegen-units/partitioning/methods-are-with-self-type.rs b/src/test/codegen-units/partitioning/methods-are-with-self-type.rs index 51d2d53f24a8..3697b83927bd 100644 --- a/src/test/codegen-units/partitioning/methods-are-with-self-type.rs +++ b/src/test/codegen-units/partitioning/methods-are-with-self-type.rs @@ -9,7 +9,7 @@ // except according to those terms. // ignore-tidy-linelength -// compile-flags:-Zprint-trans-items=lazy +// compile-flags:-Zprint-trans-items=lazy -Zincremental="" #![allow(dead_code)] diff --git a/src/test/codegen-units/partitioning/regular-modules.rs b/src/test/codegen-units/partitioning/regular-modules.rs index a761cab2e44e..57f93d2b65bf 100644 --- a/src/test/codegen-units/partitioning/regular-modules.rs +++ b/src/test/codegen-units/partitioning/regular-modules.rs @@ -9,7 +9,7 @@ // except according to those terms. // ignore-tidy-linelength -// compile-flags:-Zprint-trans-items=eager +// compile-flags:-Zprint-trans-items=eager -Z incremental="" #![allow(dead_code)] #![crate_type="lib"] diff --git a/src/test/codegen-units/partitioning/statics.rs b/src/test/codegen-units/partitioning/statics.rs index ac6a0c55d4f6..7e4c0a4ca6a0 100644 --- a/src/test/codegen-units/partitioning/statics.rs +++ b/src/test/codegen-units/partitioning/statics.rs @@ -9,7 +9,7 @@ // except according to those terms. // ignore-tidy-linelength -// compile-flags:-Zprint-trans-items=lazy +// compile-flags:-Zprint-trans-items=lazy -Zincremental="" #![crate_type="lib"]