@@ -68,7 +68,7 @@ use common::{node_id_type, fulfill_obligation};
6868use common:: { type_is_immediate, type_is_zero_size, val_ty} ;
6969use common;
7070use consts;
71- use context:: SharedCrateContext ;
71+ use context:: { SharedCrateContext , CrateContextList } ;
7272use controlflow;
7373use datum;
7474use debuginfo:: { self , DebugLoc , ToDebugLoc } ;
@@ -81,7 +81,7 @@ use machine::{llalign_of_min, llsize_of, llsize_of_real};
8181use meth;
8282use mir;
8383use monomorphize:: { self , Instance } ;
84- use partitioning:: { self , PartitioningStrategy , InstantiationMode } ;
84+ use partitioning:: { self , PartitioningStrategy , InstantiationMode , CodegenUnit } ;
8585use symbol_names_test;
8686use tvec;
8787use type_:: Type ;
@@ -664,7 +664,7 @@ pub fn coerce_unsized_into<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
664664 }
665665}
666666
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 > ,
668668 source_ty : Ty < ' tcx > ,
669669 target_ty : Ty < ' tcx > )
670670 -> CustomCoerceUnsized {
@@ -674,13 +674,13 @@ pub fn custom_coerce_unsize_info<'ccx, 'tcx>(ccx: &CrateContext<'ccx, 'tcx>,
674674 subst:: VecPerParamSpace :: empty ( ) ) ;
675675
676676 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)
679679 } ) ;
680680
681- match fulfill_obligation ( ccx , DUMMY_SP , trait_ref) {
681+ match fulfill_obligation ( scx , DUMMY_SP , trait_ref) {
682682 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)
684684 }
685685 vtable => {
686686 bug ! ( "invalid CoerceUnsized vtable: {:?}" , vtable) ;
@@ -1824,7 +1824,7 @@ pub fn trans_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
18241824 closure_env : closure:: ClosureEnv ) {
18251825 ccx. stats ( ) . n_closures . set ( ccx. stats ( ) . n_closures . get ( ) + 1 ) ;
18261826
1827- if collector:: collecting_debug_information ( ccx) {
1827+ if collector:: collecting_debug_information ( ccx. shared ( ) ) {
18281828 ccx. record_translation_item_as_generated ( TransItem :: Fn ( instance) ) ;
18291829 }
18301830
@@ -2188,7 +2188,8 @@ pub fn update_linkage(ccx: &CrateContext,
21882188 // `llval` is a translation of an item defined in a separate
21892189 // compilation unit. This only makes sense if there are at least
21902190 // 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( ) ) ;
21922193 // `llval` is a copy of something defined elsewhere, so use
21932194 // `AvailableExternallyLinkage` to avoid duplicating code in the
21942195 // output.
@@ -2524,7 +2525,7 @@ pub fn write_metadata<'a, 'tcx>(cx: &SharedCrateContext<'a, 'tcx>,
25242525
25252526/// Find any symbols that are defined in one compilation unit, but not declared
25262527/// 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 > ) {
25282529 unsafe {
25292530 let mut declared = HashSet :: new ( ) ;
25302531
@@ -2579,12 +2580,12 @@ fn internalize_symbols(cx: &SharedCrateContext, reachable: &HashSet<&str>) {
25792580// when using MSVC linker. We do this only for data, as linker can fix up
25802581// code references on its own.
25812582// See #26591, #27438
2582- fn create_imps ( cx : & SharedCrateContext ) {
2583+ fn create_imps ( cx : & CrateContextList ) {
25832584 // The x86 ABI seems to require that leading underscores are added to symbol
25842585 // names, so we need an extra underscore on 32-bit. There's also a leading
25852586 // '\x01' here which disables LLVM's symbol mangling (e.g. no extra
25862587 // 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" {
25882589 "\x01 __imp__"
25892590 } else {
25902591 "\x01 __imp_"
@@ -2661,10 +2662,10 @@ fn iter_functions(llmod: llvm::ModuleRef) -> ValueIter {
26612662///
26622663/// This list is later used by linkers to determine the set of symbols needed to
26632664/// 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| {
26662667 // 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)
26682669 } ) . filter ( |& id| {
26692670 // Next, we want to ignore some FFI functions that are not exposed from
26702671 // this crate. Reachable FFI functions can be lumped into two
@@ -2679,9 +2680,9 @@ pub fn filter_reachable_ids(ccx: &SharedCrateContext) -> NodeSet {
26792680 //
26802681 // As a result, if this id is an FFI item (foreign item) then we only
26812682 // let it through if it's included statically.
2682- match ccx . tcx ( ) . map . get ( id) {
2683+ match scx . tcx ( ) . map . get ( id) {
26832684 hir_map:: NodeForeignItem ( ..) => {
2684- ccx . sess ( ) . cstore . is_statically_included_foreign_item ( id)
2685+ scx . sess ( ) . cstore . is_statically_included_foreign_item ( id)
26852686 }
26862687 _ => true ,
26872688 }
@@ -2716,10 +2717,7 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>,
27162717
27172718 let link_meta = link:: build_link_meta ( & tcx, name) ;
27182719
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,
27232721 & mir_map,
27242722 export_map,
27252723 Sha256 :: new ( ) ,
@@ -2728,9 +2726,15 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>,
27282726 check_overflow,
27292727 check_dropflag) ;
27302728
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+
27312736 {
2732- let ccx = shared_ccx. get_ccx ( 0 ) ;
2733- collect_translation_items ( & ccx) ;
2737+ let ccx = crate_context_list. get_ccx ( 0 ) ;
27342738
27352739 // Translate all items. See `TransModVisitor` for
27362740 // details on why we walk in this particular way.
@@ -2740,12 +2744,12 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>,
27402744 krate. visit_all_items ( & mut TransModVisitor { ccx : & ccx } ) ;
27412745 }
27422746
2743- collector:: print_collection_results ( & ccx) ;
2747+ collector:: print_collection_results ( ccx. shared ( ) ) ;
27442748
27452749 symbol_names_test:: report_symbol_names ( & ccx) ;
27462750 }
27472751
2748- for ccx in shared_ccx . iter ( ) {
2752+ for ccx in crate_context_list . iter ( ) {
27492753 if ccx. sess ( ) . opts . debuginfo != NoDebugInfo {
27502754 debuginfo:: finalize ( & ccx) ;
27512755 }
@@ -2794,7 +2798,7 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>,
27942798 }
27952799 }
27962800
2797- let modules = shared_ccx . iter ( )
2801+ let modules = crate_context_list . iter ( )
27982802 . map ( |ccx| ModuleTranslation { llcx : ccx. llcx ( ) , llmod : ccx. llmod ( ) } )
27992803 . collect ( ) ;
28002804
@@ -2820,14 +2824,14 @@ pub fn trans_crate<'tcx>(tcx: &TyCtxt<'tcx>,
28202824 }
28212825 }
28222826
2823- if codegen_units > 1 {
2824- internalize_symbols ( & shared_ccx ,
2827+ if codegen_unit_count > 1 {
2828+ internalize_symbols ( & crate_context_list ,
28252829 & reachable_symbols. iter ( ) . map ( |x| & x[ ..] ) . collect ( ) ) ;
28262830 }
28272831
28282832 if sess. target . target . options . is_like_msvc &&
28292833 sess. crate_types . borrow ( ) . iter ( ) . any ( |ct| * ct == config:: CrateTypeRlib ) {
2830- create_imps ( & shared_ccx ) ;
2834+ create_imps ( & crate_context_list ) ;
28312835 }
28322836
28332837 let metadata_module = ModuleTranslation {
@@ -2912,10 +2916,11 @@ impl<'a, 'tcx, 'v> Visitor<'v> for TransItemsWithinModVisitor<'a, 'tcx> {
29122916 }
29132917}
29142918
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 ( ) ;
29172922
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 {
29192924 Some ( ref s) => {
29202925 let mode_string = s. to_lowercase ( ) ;
29212926 let mode_string = mode_string. trim ( ) ;
@@ -2926,7 +2931,7 @@ fn collect_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>) {
29262931 let message = format ! ( "Unknown codegen-item collection mode '{}'. \
29272932 Falling back to 'lazy' mode.",
29282933 mode_string) ;
2929- ccx . sess ( ) . warn ( & message) ;
2934+ scx . sess ( ) . warn ( & message) ;
29302935 }
29312936
29322937 TransItemCollectionMode :: Lazy
@@ -2936,27 +2941,27 @@ fn collect_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>) {
29362941 } ;
29372942
29382943 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)
29402945 } ) ;
29412946
2942- let strategy = if ccx . sess ( ) . opts . debugging_opts . incremental . is_some ( ) {
2947+ let strategy = if scx . sess ( ) . opts . debugging_opts . incremental . is_some ( ) {
29432948 PartitioningStrategy :: PerModule
29442949 } else {
2945- PartitioningStrategy :: FixedUnitCount ( ccx . sess ( ) . opts . cg . codegen_units )
2950+ PartitioningStrategy :: FixedUnitCount ( scx . sess ( ) . opts . cg . codegen_units )
29462951 } ;
29472952
29482953 let codegen_units = time ( time_passes, "codegen unit partitioning" , || {
2949- partitioning:: partition ( ccx . tcx ( ) ,
2954+ partitioning:: partition ( scx . tcx ( ) ,
29502955 items. iter ( ) . cloned ( ) ,
29512956 strategy,
29522957 & reference_map)
29532958 } ) ;
29542959
2955- if ccx . sess ( ) . opts . debugging_opts . print_trans_items . is_some ( ) {
2960+ if scx . sess ( ) . opts . debugging_opts . print_trans_items . is_some ( ) {
29562961 let mut item_to_cgus = HashMap :: new ( ) ;
29572962
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 {
29602965 item_to_cgus. entry ( trans_item)
29612966 . or_insert ( Vec :: new ( ) )
29622967 . push ( ( cgu. name . clone ( ) , linkage) ) ;
@@ -2966,7 +2971,7 @@ fn collect_translation_items<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>) {
29662971 let mut item_keys: Vec < _ > = items
29672972 . iter ( )
29682973 . map ( |i| {
2969- let mut output = i. to_string ( ccx ) ;
2974+ let mut output = i. to_string ( scx . tcx ( ) ) ;
29702975 output. push_str ( " @@" ) ;
29712976 let mut empty = Vec :: new ( ) ;
29722977 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>) {
30053010 println ! ( "TRANS_ITEM {}" , item) ;
30063011 }
30073012
3008- let mut ccx_map = ccx . translation_items ( ) . borrow_mut ( ) ;
3013+ let mut ccx_map = scx . translation_items ( ) . borrow_mut ( ) ;
30093014
30103015 for cgi in items {
30113016 ccx_map. insert ( cgi, TransItemState :: PredictedButNotGenerated ) ;
30123017 }
30133018 }
3019+
3020+ codegen_units
30143021}
0 commit comments