@@ -69,7 +69,7 @@ use common::{node_id_type, fulfill_obligation};
6969use common:: { type_is_immediate, type_is_zero_size, val_ty} ;
7070use common;
7171use consts;
72- use context:: SharedCrateContext ;
72+ use context:: { SharedCrateContext , CrateContextList } ;
7373use controlflow;
7474use datum;
7575use debuginfo:: { self , DebugLoc , ToDebugLoc } ;
@@ -82,7 +82,7 @@ use machine::{llalign_of_min, llsize_of, llsize_of_real};
8282use meth;
8383use mir;
8484use monomorphize:: { self , Instance } ;
85- use partitioning:: { self , PartitioningStrategy , InstantiationMode } ;
85+ use partitioning:: { self , PartitioningStrategy , InstantiationMode , CodegenUnit } ;
8686use symbol_names_test;
8787use tvec;
8888use type_:: Type ;
@@ -665,7 +665,7 @@ pub fn coerce_unsized_into<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
665665 }
666666}
667667
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 > ,
669669 source_ty : Ty < ' tcx > ,
670670 target_ty : Ty < ' tcx > )
671671 -> CustomCoerceUnsized {
@@ -675,13 +675,13 @@ pub fn custom_coerce_unsize_info<'ccx, 'tcx>(ccx: &CrateContext<'ccx, 'tcx>,
675675 subst:: VecPerParamSpace :: empty ( ) ) ;
676676
677677 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)
680680 } ) ;
681681
682- match fulfill_obligation ( ccx , DUMMY_SP , trait_ref) {
682+ match fulfill_obligation ( scx , DUMMY_SP , trait_ref) {
683683 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)
685685 }
686686 vtable => {
687687 bug ! ( "invalid CoerceUnsized vtable: {:?}" , vtable) ;
@@ -1825,7 +1825,7 @@ pub fn trans_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
18251825 closure_env : closure:: ClosureEnv ) {
18261826 ccx. stats ( ) . n_closures . set ( ccx. stats ( ) . n_closures . get ( ) + 1 ) ;
18271827
1828- if collector:: collecting_debug_information ( ccx) {
1828+ if collector:: collecting_debug_information ( ccx. shared ( ) ) {
18291829 ccx. record_translation_item_as_generated ( TransItem :: Fn ( instance) ) ;
18301830 }
18311831
@@ -2187,7 +2187,8 @@ pub fn update_linkage(ccx: &CrateContext,
21872187 // `llval` is a translation of an item defined in a separate
21882188 // compilation unit. This only makes sense if there are at least
21892189 // 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( ) ) ;
21912192 // `llval` is a copy of something defined elsewhere, so use
21922193 // `AvailableExternallyLinkage` to avoid duplicating code in the
21932194 // output.
@@ -2523,7 +2524,7 @@ pub fn write_metadata<'a, 'tcx>(cx: &SharedCrateContext<'a, 'tcx>,
25232524
25242525/// Find any symbols that are defined in one compilation unit, but not declared
25252526/// 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 > ) {
25272528 unsafe {
25282529 let mut declared = HashSet :: new ( ) ;
25292530
@@ -2578,12 +2579,12 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet<&str>) {
25782579// when using MSVC linker. We do this only for data, as linker can fix up
25792580// code references on its own.
25802581// See #26591, #27438
2581- fn create_imps ( cx : & SharedCrateContext ) {
2582+ fn create_imps ( cx : & CrateContextList ) {
25822583 // The x86 ABI seems to require that leading underscores are added to symbol
25832584 // names, so we need an extra underscore on 32-bit. There's also a leading
25842585 // '\x01' here which disables LLVM's symbol mangling (e.g. no extra
25852586 // 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" {
25872588 "\x01 __imp__"
25882589 } else {
25892590 "\x01 __imp_"
@@ -2660,10 +2661,10 @@ fn iter_functions(llmod: llvm::ModuleRef) -> ValueIter {
26602661///
26612662/// This list is later used by linkers to determine the set of symbols needed to
26622663/// 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| {
26652666 // 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)
26672668 } ) . filter ( |& id| {
26682669 // Next, we want to ignore some FFI functions that are not exposed from
26692670 // this crate. Reachable FFI functions can be lumped into two
@@ -2678,9 +2679,9 @@ pub fn filter_reachable_ids(ccx: &SharedCrateContext) -> NodeSet {
26782679 //
26792680 // As a result, if this id is an FFI item (foreign item) then we only
26802681 // let it through if it's included statically.
2681- match ccx . tcx ( ) . map . get ( id) {
2682+ match scx . tcx ( ) . map . get ( id) {
26822683 hir_map:: NodeForeignItem ( ..) => {
2683- ccx . sess ( ) . cstore . is_statically_included_foreign_item ( id)
2684+ scx . sess ( ) . cstore . is_statically_included_foreign_item ( id)
26842685 }
26852686 _ => true ,
26862687 }
@@ -2715,10 +2716,7 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>,
27152716
27162717 let link_meta = link:: build_link_meta ( & tcx, name) ;
27172718
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,
27222720 & mir_map,
27232721 export_map,
27242722 Sha256 :: new ( ) ,
@@ -2727,9 +2725,15 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>,
27272725 check_overflow,
27282726 check_dropflag) ;
27292727
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+
27302735 {
2731- let ccx = shared_ccx. get_ccx ( 0 ) ;
2732- collect_translation_items ( & ccx) ;
2736+ let ccx = crate_context_list. get_ccx ( 0 ) ;
27332737
27342738 // Translate all items. See `TransModVisitor` for
27352739 // details on why we walk in this particular way.
@@ -2739,12 +2743,12 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>,
27392743 krate. visit_all_items ( & mut TransModVisitor { ccx : & ccx } ) ;
27402744 }
27412745
2742- collector:: print_collection_results ( & ccx) ;
2746+ collector:: print_collection_results ( ccx. shared ( ) ) ;
27432747
27442748 symbol_names_test:: report_symbol_names ( & ccx) ;
27452749 }
27462750
2747- for ccx in shared_ccx . iter ( ) {
2751+ for ccx in crate_context_list . iter ( ) {
27482752 if ccx. sess ( ) . opts . debuginfo != NoDebugInfo {
27492753 debuginfo:: finalize ( & ccx) ;
27502754 }
@@ -2793,7 +2797,7 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>,
27932797 }
27942798 }
27952799
2796- let modules = shared_ccx . iter ( )
2800+ let modules = crate_context_list . iter ( )
27972801 . map ( |ccx| ModuleTranslation { llcx : ccx. llcx ( ) , llmod : ccx. llmod ( ) } )
27982802 . collect ( ) ;
27992803
@@ -2819,14 +2823,14 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>,
28192823 }
28202824 }
28212825
2822- if codegen_units > 1 {
2823- internalize_symbols ( & shared_ccx ,
2826+ if codegen_unit_count > 1 {
2827+ internalize_symbols ( & crate_context_list ,
28242828 & reachable_symbols. iter ( ) . map ( |x| & x[ ..] ) . collect ( ) ) ;
28252829 }
28262830
28272831 if sess. target . target . options . is_like_msvc &&
28282832 sess. crate_types . borrow ( ) . iter ( ) . any ( |ct| * ct == config:: CrateTypeRlib ) {
2829- create_imps ( & shared_ccx ) ;
2833+ create_imps ( & crate_context_list ) ;
28302834 }
28312835
28322836 let metadata_module = ModuleTranslation {
@@ -2911,10 +2915,11 @@ impl<'a, 'tcx, 'v> Visitor<'v> for TransItemsWithinModVisitor<'a, 'tcx> {
29112915 }
29122916}
29132917
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 ( ) ;
29162921
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 {
29182923 Some ( ref s) => {
29192924 let mode_string = s. to_lowercase ( ) ;
29202925 let mode_string = mode_string. trim ( ) ;
@@ -2925,7 +2930,7 @@ fn collect_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>) {
29252930 let message = format ! ( "Unknown codegen-item collection mode '{}'. \
29262931 Falling back to 'lazy' mode.",
29272932 mode_string) ;
2928- ccx . sess ( ) . warn ( & message) ;
2933+ scx . sess ( ) . warn ( & message) ;
29292934 }
29302935
29312936 TransItemCollectionMode :: Lazy
@@ -2935,27 +2940,27 @@ fn collect_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>) {
29352940 } ;
29362941
29372942 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)
29392944 } ) ;
29402945
2941- let strategy = if ccx . sess ( ) . opts . debugging_opts . incremental . is_some ( ) {
2946+ let strategy = if scx . sess ( ) . opts . debugging_opts . incremental . is_some ( ) {
29422947 PartitioningStrategy :: PerModule
29432948 } else {
2944- PartitioningStrategy :: FixedUnitCount ( ccx . sess ( ) . opts . cg . codegen_units )
2949+ PartitioningStrategy :: FixedUnitCount ( scx . sess ( ) . opts . cg . codegen_units )
29452950 } ;
29462951
29472952 let codegen_units = time ( time_passes, "codegen unit partitioning" , || {
2948- partitioning:: partition ( ccx . tcx ( ) ,
2953+ partitioning:: partition ( scx . tcx ( ) ,
29492954 items. iter ( ) . cloned ( ) ,
29502955 strategy,
29512956 & reference_map)
29522957 } ) ;
29532958
2954- if ccx . sess ( ) . opts . debugging_opts . print_trans_items . is_some ( ) {
2959+ if scx . sess ( ) . opts . debugging_opts . print_trans_items . is_some ( ) {
29552960 let mut item_to_cgus = HashMap :: new ( ) ;
29562961
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 {
29592964 item_to_cgus. entry ( trans_item)
29602965 . or_insert ( Vec :: new ( ) )
29612966 . push ( ( cgu. name . clone ( ) , linkage) ) ;
@@ -2965,7 +2970,7 @@ fn collect_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>) {
29652970 let mut item_keys: Vec < _ > = items
29662971 . iter ( )
29672972 . map ( |i| {
2968- let mut output = i. to_string ( ccx ) ;
2973+ let mut output = i. to_string ( scx . tcx ( ) ) ;
29692974 output. push_str ( " @@" ) ;
29702975 let mut empty = Vec :: new ( ) ;
29712976 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>) {
30043009 println ! ( "TRANS_ITEM {}" , item) ;
30053010 }
30063011
3007- let mut ccx_map = ccx . translation_items ( ) . borrow_mut ( ) ;
3012+ let mut ccx_map = scx . translation_items ( ) . borrow_mut ( ) ;
30083013
30093014 for cgi in items {
30103015 ccx_map. insert ( cgi, TransItemState :: PredictedButNotGenerated ) ;
30113016 }
30123017 }
3018+
3019+ codegen_units
30133020}
0 commit comments