@@ -68,7 +68,7 @@ use common::{node_id_type, fulfill_obligation};
68
68
use common:: { type_is_immediate, type_is_zero_size, val_ty} ;
69
69
use common;
70
70
use consts;
71
- use context:: SharedCrateContext ;
71
+ use context:: { SharedCrateContext , CrateContextList } ;
72
72
use controlflow;
73
73
use datum;
74
74
use debuginfo:: { self , DebugLoc , ToDebugLoc } ;
@@ -81,7 +81,7 @@ use machine::{llalign_of_min, llsize_of, llsize_of_real};
81
81
use meth;
82
82
use mir;
83
83
use monomorphize:: { self , Instance } ;
84
- use partitioning:: { self , PartitioningStrategy , InstantiationMode } ;
84
+ use partitioning:: { self , PartitioningStrategy , InstantiationMode , CodegenUnit } ;
85
85
use symbol_names_test;
86
86
use tvec;
87
87
use type_:: Type ;
@@ -664,7 +664,7 @@ pub fn coerce_unsized_into<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
664
664
}
665
665
}
666
666
667
- pub fn custom_coerce_unsize_info < ' ccx , ' tcx > ( ccx : & CrateContext < ' ccx , ' tcx > ,
667
+ pub fn custom_coerce_unsize_info < ' scx , ' tcx > ( scx : & SharedCrateContext < ' scx , ' tcx > ,
668
668
source_ty : Ty < ' tcx > ,
669
669
target_ty : Ty < ' tcx > )
670
670
-> CustomCoerceUnsized {
@@ -674,13 +674,13 @@ pub fn custom_coerce_unsize_info<'ccx, 'tcx>(ccx: &CrateContext<'ccx, 'tcx>,
674
674
subst:: VecPerParamSpace :: empty ( ) ) ;
675
675
676
676
let trait_ref = ty:: Binder ( ty:: TraitRef {
677
- def_id : ccx . tcx ( ) . lang_items . coerce_unsized_trait ( ) . unwrap ( ) ,
678
- substs : ccx . tcx ( ) . mk_substs ( trait_substs)
677
+ def_id : scx . tcx ( ) . lang_items . coerce_unsized_trait ( ) . unwrap ( ) ,
678
+ substs : scx . tcx ( ) . mk_substs ( trait_substs)
679
679
} ) ;
680
680
681
- match fulfill_obligation ( ccx , DUMMY_SP , trait_ref) {
681
+ match fulfill_obligation ( scx , DUMMY_SP , trait_ref) {
682
682
traits:: VtableImpl ( traits:: VtableImplData { impl_def_id, .. } ) => {
683
- ccx . tcx ( ) . custom_coerce_unsized_kind ( impl_def_id)
683
+ scx . tcx ( ) . custom_coerce_unsized_kind ( impl_def_id)
684
684
}
685
685
vtable => {
686
686
bug ! ( "invalid CoerceUnsized vtable: {:?}" , vtable) ;
@@ -1824,7 +1824,7 @@ pub fn trans_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
1824
1824
closure_env : closure:: ClosureEnv ) {
1825
1825
ccx. stats ( ) . n_closures . set ( ccx. stats ( ) . n_closures . get ( ) + 1 ) ;
1826
1826
1827
- if collector:: collecting_debug_information ( ccx) {
1827
+ if collector:: collecting_debug_information ( ccx. shared ( ) ) {
1828
1828
ccx. record_translation_item_as_generated ( TransItem :: Fn ( instance) ) ;
1829
1829
}
1830
1830
@@ -2188,7 +2188,8 @@ pub fn update_linkage(ccx: &CrateContext,
2188
2188
// `llval` is a translation of an item defined in a separate
2189
2189
// compilation unit. This only makes sense if there are at least
2190
2190
// two compilation units.
2191
- assert ! ( ccx. sess( ) . opts. cg. codegen_units > 1 ) ;
2191
+ assert ! ( ccx. sess( ) . opts. cg. codegen_units > 1 ||
2192
+ ccx. sess( ) . opts. debugging_opts. incremental. is_some( ) ) ;
2192
2193
// `llval` is a copy of something defined elsewhere, so use
2193
2194
// `AvailableExternallyLinkage` to avoid duplicating code in the
2194
2195
// output.
@@ -2524,7 +2525,7 @@ pub fn write_metadata<'a, 'tcx>(cx: &SharedCrateContext<'a, 'tcx>,
2524
2525
2525
2526
/// Find any symbols that are defined in one compilation unit, but not declared
2526
2527
/// in any other compilation unit. Give these symbols internal linkage.
2527
- fn internalize_symbols ( cx : & SharedCrateContext , reachable : & HashSet < & str > ) {
2528
+ fn internalize_symbols ( cx : & CrateContextList , reachable : & HashSet < & str > ) {
2528
2529
unsafe {
2529
2530
let mut declared = HashSet :: new ( ) ;
2530
2531
@@ -2579,12 +2580,12 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet<&str>) {
2579
2580
// when using MSVC linker. We do this only for data, as linker can fix up
2580
2581
// code references on its own.
2581
2582
// See #26591, #27438
2582
- fn create_imps ( cx : & SharedCrateContext ) {
2583
+ fn create_imps ( cx : & CrateContextList ) {
2583
2584
// The x86 ABI seems to require that leading underscores are added to symbol
2584
2585
// names, so we need an extra underscore on 32-bit. There's also a leading
2585
2586
// '\x01' here which disables LLVM's symbol mangling (e.g. no extra
2586
2587
// underscores added in front).
2587
- let prefix = if cx. sess ( ) . target . target . target_pointer_width == "32" {
2588
+ let prefix = if cx. shared ( ) . sess ( ) . target . target . target_pointer_width == "32" {
2588
2589
"\x01 __imp__"
2589
2590
} else {
2590
2591
"\x01 __imp_"
@@ -2661,10 +2662,10 @@ fn iter_functions(llmod: llvm::ModuleRef) -> ValueIter {
2661
2662
///
2662
2663
/// This list is later used by linkers to determine the set of symbols needed to
2663
2664
/// be exposed from a dynamic library and it's also encoded into the metadata.
2664
- pub fn filter_reachable_ids ( ccx : & SharedCrateContext ) -> NodeSet {
2665
- ccx . reachable ( ) . iter ( ) . map ( |x| * x) . filter ( |id| {
2665
+ pub fn filter_reachable_ids ( scx : & SharedCrateContext ) -> NodeSet {
2666
+ scx . reachable ( ) . iter ( ) . map ( |x| * x) . filter ( |id| {
2666
2667
// First, only worry about nodes which have a symbol name
2667
- ccx . item_symbols ( ) . borrow ( ) . contains_key ( id)
2668
+ scx . item_symbols ( ) . borrow ( ) . contains_key ( id)
2668
2669
} ) . filter ( |& id| {
2669
2670
// Next, we want to ignore some FFI functions that are not exposed from
2670
2671
// this crate. Reachable FFI functions can be lumped into two
@@ -2679,9 +2680,9 @@ pub fn filter_reachable_ids(ccx: &SharedCrateContext) -> NodeSet {
2679
2680
//
2680
2681
// As a result, if this id is an FFI item (foreign item) then we only
2681
2682
// let it through if it's included statically.
2682
- match ccx . tcx ( ) . map . get ( id) {
2683
+ match scx . tcx ( ) . map . get ( id) {
2683
2684
hir_map:: NodeForeignItem ( ..) => {
2684
- ccx . sess ( ) . cstore . is_statically_included_foreign_item ( id)
2685
+ scx . sess ( ) . cstore . is_statically_included_foreign_item ( id)
2685
2686
}
2686
2687
_ => true ,
2687
2688
}
@@ -2716,10 +2717,7 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>,
2716
2717
2717
2718
let link_meta = link:: build_link_meta ( & tcx, name) ;
2718
2719
2719
- let codegen_units = tcx. sess . opts . cg . codegen_units ;
2720
- let shared_ccx = SharedCrateContext :: new ( & link_meta. crate_name ,
2721
- codegen_units,
2722
- tcx,
2720
+ let shared_ccx = SharedCrateContext :: new ( tcx,
2723
2721
& mir_map,
2724
2722
export_map,
2725
2723
Sha256 :: new ( ) ,
@@ -2728,9 +2726,15 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>,
2728
2726
check_overflow,
2729
2727
check_dropflag) ;
2730
2728
2729
+ let codegen_units = collect_and_partition_translation_items ( & shared_ccx) ;
2730
+ let codegen_unit_count = codegen_units. len ( ) ;
2731
+ assert ! ( tcx. sess. opts. cg. codegen_units == codegen_unit_count ||
2732
+ tcx. sess. opts. debugging_opts. incremental. is_some( ) ) ;
2733
+
2734
+ let crate_context_list = CrateContextList :: new ( & shared_ccx, codegen_units) ;
2735
+
2731
2736
{
2732
- let ccx = shared_ccx. get_ccx ( 0 ) ;
2733
- collect_translation_items ( & ccx) ;
2737
+ let ccx = crate_context_list. get_ccx ( 0 ) ;
2734
2738
2735
2739
// Translate all items. See `TransModVisitor` for
2736
2740
// details on why we walk in this particular way.
@@ -2740,12 +2744,12 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>,
2740
2744
krate. visit_all_items ( & mut TransModVisitor { ccx : & ccx } ) ;
2741
2745
}
2742
2746
2743
- collector:: print_collection_results ( & ccx) ;
2747
+ collector:: print_collection_results ( ccx. shared ( ) ) ;
2744
2748
2745
2749
symbol_names_test:: report_symbol_names ( & ccx) ;
2746
2750
}
2747
2751
2748
- for ccx in shared_ccx . iter ( ) {
2752
+ for ccx in crate_context_list . iter ( ) {
2749
2753
if ccx. sess ( ) . opts . debuginfo != NoDebugInfo {
2750
2754
debuginfo:: finalize ( & ccx) ;
2751
2755
}
@@ -2794,7 +2798,7 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>,
2794
2798
}
2795
2799
}
2796
2800
2797
- let modules = shared_ccx . iter ( )
2801
+ let modules = crate_context_list . iter ( )
2798
2802
. map ( |ccx| ModuleTranslation { llcx : ccx. llcx ( ) , llmod : ccx. llmod ( ) } )
2799
2803
. collect ( ) ;
2800
2804
@@ -2820,14 +2824,14 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>,
2820
2824
}
2821
2825
}
2822
2826
2823
- if codegen_units > 1 {
2824
- internalize_symbols ( & shared_ccx ,
2827
+ if codegen_unit_count > 1 {
2828
+ internalize_symbols ( & crate_context_list ,
2825
2829
& reachable_symbols. iter ( ) . map ( |x| & x[ ..] ) . collect ( ) ) ;
2826
2830
}
2827
2831
2828
2832
if sess. target . target . options . is_like_msvc &&
2829
2833
sess. crate_types . borrow ( ) . iter ( ) . any ( |ct| * ct == config:: CrateTypeRlib ) {
2830
- create_imps ( & shared_ccx ) ;
2834
+ create_imps ( & crate_context_list ) ;
2831
2835
}
2832
2836
2833
2837
let metadata_module = ModuleTranslation {
@@ -2912,10 +2916,11 @@ impl<'a, 'tcx, 'v> Visitor<'v> for TransItemsWithinModVisitor<'a, 'tcx> {
2912
2916
}
2913
2917
}
2914
2918
2915
- fn collect_translation_items < ' a , ' tcx > ( ccx : & CrateContext < ' a , ' tcx > ) {
2916
- let time_passes = ccx. sess ( ) . time_passes ( ) ;
2919
+ fn collect_and_partition_translation_items < ' a , ' tcx > ( scx : & SharedCrateContext < ' a , ' tcx > )
2920
+ -> Vec < CodegenUnit < ' tcx > > {
2921
+ let time_passes = scx. sess ( ) . time_passes ( ) ;
2917
2922
2918
- let collection_mode = match ccx . sess ( ) . opts . debugging_opts . print_trans_items {
2923
+ let collection_mode = match scx . sess ( ) . opts . debugging_opts . print_trans_items {
2919
2924
Some ( ref s) => {
2920
2925
let mode_string = s. to_lowercase ( ) ;
2921
2926
let mode_string = mode_string. trim ( ) ;
@@ -2926,7 +2931,7 @@ fn collect_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>) {
2926
2931
let message = format ! ( "Unknown codegen-item collection mode '{}'. \
2927
2932
Falling back to 'lazy' mode.",
2928
2933
mode_string) ;
2929
- ccx . sess ( ) . warn ( & message) ;
2934
+ scx . sess ( ) . warn ( & message) ;
2930
2935
}
2931
2936
2932
2937
TransItemCollectionMode :: Lazy
@@ -2936,27 +2941,27 @@ fn collect_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>) {
2936
2941
} ;
2937
2942
2938
2943
let ( items, reference_map) = time ( time_passes, "translation item collection" , || {
2939
- collector:: collect_crate_translation_items ( & ccx , collection_mode)
2944
+ collector:: collect_crate_translation_items ( scx , collection_mode)
2940
2945
} ) ;
2941
2946
2942
- let strategy = if ccx . sess ( ) . opts . debugging_opts . incremental . is_some ( ) {
2947
+ let strategy = if scx . sess ( ) . opts . debugging_opts . incremental . is_some ( ) {
2943
2948
PartitioningStrategy :: PerModule
2944
2949
} else {
2945
- PartitioningStrategy :: FixedUnitCount ( ccx . sess ( ) . opts . cg . codegen_units )
2950
+ PartitioningStrategy :: FixedUnitCount ( scx . sess ( ) . opts . cg . codegen_units )
2946
2951
} ;
2947
2952
2948
2953
let codegen_units = time ( time_passes, "codegen unit partitioning" , || {
2949
- partitioning:: partition ( ccx . tcx ( ) ,
2954
+ partitioning:: partition ( scx . tcx ( ) ,
2950
2955
items. iter ( ) . cloned ( ) ,
2951
2956
strategy,
2952
2957
& reference_map)
2953
2958
} ) ;
2954
2959
2955
- if ccx . sess ( ) . opts . debugging_opts . print_trans_items . is_some ( ) {
2960
+ if scx . sess ( ) . opts . debugging_opts . print_trans_items . is_some ( ) {
2956
2961
let mut item_to_cgus = HashMap :: new ( ) ;
2957
2962
2958
- for cgu in codegen_units {
2959
- for ( trans_item, linkage) in cgu. items {
2963
+ for cgu in & codegen_units {
2964
+ for ( & trans_item, & linkage) in & cgu. items {
2960
2965
item_to_cgus. entry ( trans_item)
2961
2966
. or_insert ( Vec :: new ( ) )
2962
2967
. push ( ( cgu. name . clone ( ) , linkage) ) ;
@@ -2966,7 +2971,7 @@ fn collect_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>) {
2966
2971
let mut item_keys: Vec < _ > = items
2967
2972
. iter ( )
2968
2973
. map ( |i| {
2969
- let mut output = i. to_string ( ccx ) ;
2974
+ let mut output = i. to_string ( scx . tcx ( ) ) ;
2970
2975
output. push_str ( " @@" ) ;
2971
2976
let mut empty = Vec :: new ( ) ;
2972
2977
let mut cgus = item_to_cgus. get_mut ( i) . unwrap_or ( & mut empty) ;
@@ -3005,10 +3010,12 @@ fn collect_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>) {
3005
3010
println ! ( "TRANS_ITEM {}" , item) ;
3006
3011
}
3007
3012
3008
- let mut ccx_map = ccx . translation_items ( ) . borrow_mut ( ) ;
3013
+ let mut ccx_map = scx . translation_items ( ) . borrow_mut ( ) ;
3009
3014
3010
3015
for cgi in items {
3011
3016
ccx_map. insert ( cgi, TransItemState :: PredictedButNotGenerated ) ;
3012
3017
}
3013
3018
}
3019
+
3020
+ codegen_units
3014
3021
}
0 commit comments