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