]> git.lizzy.rs Git - rust.git/blob - src/librustc_mir/monomorphize/partitioning.rs
rustc: collapse relevant DefPathData variants into TypeNs.
[rust.git] / src / librustc_mir / monomorphize / partitioning.rs
1 //! Partitioning Codegen Units for Incremental Compilation
2 //! ======================================================
3 //!
4 //! The task of this module is to take the complete set of monomorphizations of
5 //! a crate and produce a set of codegen units from it, where a codegen unit
6 //! is a named set of (mono-item, linkage) pairs. That is, this module
7 //! decides which monomorphization appears in which codegen units with which
8 //! linkage. The following paragraphs describe some of the background on the
9 //! partitioning scheme.
10 //!
11 //! The most important opportunity for saving on compilation time with
12 //! incremental compilation is to avoid re-codegenning and re-optimizing code.
13 //! Since the unit of codegen and optimization for LLVM is "modules" or, how
14 //! we call them "codegen units", the particulars of how much time can be saved
15 //! by incremental compilation are tightly linked to how the output program is
16 //! partitioned into these codegen units prior to passing it to LLVM --
17 //! especially because we have to treat codegen units as opaque entities once
18 //! they are created: There is no way for us to incrementally update an existing
19 //! LLVM module and so we have to build any such module from scratch if it was
20 //! affected by some change in the source code.
21 //!
22 //! From that point of view it would make sense to maximize the number of
23 //! codegen units by, for example, putting each function into its own module.
24 //! That way only those modules would have to be re-compiled that were actually
25 //! affected by some change, minimizing the number of functions that could have
26 //! been re-used but just happened to be located in a module that is
27 //! re-compiled.
28 //!
29 //! However, since LLVM optimization does not work across module boundaries,
30 //! using such a highly granular partitioning would lead to very slow runtime
31 //! code since it would effectively prohibit inlining and other inter-procedure
32 //! optimizations. We want to avoid that as much as possible.
33 //!
34 //! Thus we end up with a trade-off: The bigger the codegen units, the better
35 //! LLVM's optimizer can do its work, but also the smaller the compilation time
36 //! reduction we get from incremental compilation.
37 //!
38 //! Ideally, we would create a partitioning such that there are few big codegen
39 //! units with few interdependencies between them. For now though, we use the
40 //! following heuristic to determine the partitioning:
41 //!
42 //! - There are two codegen units for every source-level module:
43 //! - One for "stable", that is non-generic, code
44 //! - One for more "volatile" code, i.e., monomorphized instances of functions
45 //!   defined in that module
46 //!
47 //! In order to see why this heuristic makes sense, let's take a look at when a
48 //! codegen unit can get invalidated:
49 //!
50 //! 1. The most straightforward case is when the BODY of a function or global
51 //! changes. Then any codegen unit containing the code for that item has to be
52 //! re-compiled. Note that this includes all codegen units where the function
53 //! has been inlined.
54 //!
55 //! 2. The next case is when the SIGNATURE of a function or global changes. In
56 //! this case, all codegen units containing a REFERENCE to that item have to be
57 //! re-compiled. This is a superset of case 1.
58 //!
59 //! 3. The final and most subtle case is when a REFERENCE to a generic function
60 //! is added or removed somewhere. Even though the definition of the function
61 //! might be unchanged, a new REFERENCE might introduce a new monomorphized
62 //! instance of this function which has to be placed and compiled somewhere.
63 //! Conversely, when removing a REFERENCE, it might have been the last one with
64 //! that particular set of generic arguments and thus we have to remove it.
65 //!
66 //! From the above we see that just using one codegen unit per source-level
67 //! module is not such a good idea, since just adding a REFERENCE to some
68 //! generic item somewhere else would invalidate everything within the module
69 //! containing the generic item. The heuristic above reduces this detrimental
70 //! side-effect of references a little by at least not touching the non-generic
71 //! code of the module.
72 //!
73 //! A Note on Inlining
74 //! ------------------
75 //! As briefly mentioned above, in order for LLVM to be able to inline a
76 //! function call, the body of the function has to be available in the LLVM
77 //! module where the call is made. This has a few consequences for partitioning:
78 //!
79 //! - The partitioning algorithm has to take care of placing functions into all
80 //!   codegen units where they should be available for inlining. It also has to
81 //!   decide on the correct linkage for these functions.
82 //!
83 //! - The partitioning algorithm has to know which functions are likely to get
84 //!   inlined, so it can distribute function instantiations accordingly. Since
85 //!   there is no way of knowing for sure which functions LLVM will decide to
86 //!   inline in the end, we apply a heuristic here: Only functions marked with
87 //!   `#[inline]` are considered for inlining by the partitioner. The current
88 //!   implementation will not try to determine if a function is likely to be
89 //!   inlined by looking at the functions definition.
90 //!
91 //! Note though that as a side-effect of creating a codegen units per
92 //! source-level module, functions from the same module will be available for
93 //! inlining, even when they are not marked #[inline].
94
95 use std::collections::hash_map::Entry;
96 use std::cmp;
97 use std::sync::Arc;
98
99 use syntax::symbol::InternedString;
100 use rustc::dep_graph::{WorkProductId, WorkProduct, DepNode, DepConstructor};
101 use rustc::hir::{CodegenFnAttrFlags, HirId};
102 use rustc::hir::def::DefKind;
103 use rustc::hir::def_id::{CrateNum, DefId, LOCAL_CRATE, CRATE_DEF_INDEX};
104 use rustc::mir::mono::{Linkage, Visibility, CodegenUnitNameBuilder};
105 use rustc::middle::exported_symbols::SymbolExportLevel;
106 use rustc::ty::{self, DefIdTree, TyCtxt, InstanceDef};
107 use rustc::ty::print::characteristic_def_id_of_type;
108 use rustc::ty::query::Providers;
109 use rustc::util::common::time;
110 use rustc::util::nodemap::{DefIdSet, FxHashMap, FxHashSet};
111 use rustc::mir::mono::MonoItem;
112
113 use crate::monomorphize::collector::InliningMap;
114 use crate::monomorphize::collector::{self, MonoItemCollectionMode};
115 use crate::monomorphize::item::{MonoItemExt, InstantiationMode};
116
117 pub use rustc::mir::mono::CodegenUnit;
118
119 pub enum PartitioningStrategy {
120     /// Generates one codegen unit per source-level module.
121     PerModule,
122
123     /// Partition the whole crate into a fixed number of codegen units.
124     FixedUnitCount(usize)
125 }
126
127 pub trait CodegenUnitExt<'tcx> {
128     fn as_codegen_unit(&self) -> &CodegenUnit<'tcx>;
129
130     fn contains_item(&self, item: &MonoItem<'tcx>) -> bool {
131         self.items().contains_key(item)
132     }
133
134     fn name<'a>(&'a self) -> &'a InternedString
135         where 'tcx: 'a,
136     {
137         &self.as_codegen_unit().name()
138     }
139
140     fn items(&self) -> &FxHashMap<MonoItem<'tcx>, (Linkage, Visibility)> {
141         &self.as_codegen_unit().items()
142     }
143
144     fn work_product_id(&self) -> WorkProductId {
145         WorkProductId::from_cgu_name(&self.name().as_str())
146     }
147
148     fn work_product(&self, tcx: TyCtxt<'_, '_, '_>) -> WorkProduct {
149         let work_product_id = self.work_product_id();
150         tcx.dep_graph
151            .previous_work_product(&work_product_id)
152            .unwrap_or_else(|| {
153                 panic!("Could not find work-product for CGU `{}`", self.name())
154             })
155     }
156
157     fn items_in_deterministic_order<'a>(&self,
158                                         tcx: TyCtxt<'a, 'tcx, 'tcx>)
159                                         -> Vec<(MonoItem<'tcx>,
160                                                 (Linkage, Visibility))> {
161         // The codegen tests rely on items being process in the same order as
162         // they appear in the file, so for local items, we sort by node_id first
163         #[derive(PartialEq, Eq, PartialOrd, Ord)]
164         pub struct ItemSortKey(Option<HirId>, ty::SymbolName);
165
166         fn item_sort_key<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
167                                    item: MonoItem<'tcx>) -> ItemSortKey {
168             ItemSortKey(match item {
169                 MonoItem::Fn(ref instance) => {
170                     match instance.def {
171                         // We only want to take HirIds of user-defined
172                         // instances into account. The others don't matter for
173                         // the codegen tests and can even make item order
174                         // unstable.
175                         InstanceDef::Item(def_id) => {
176                             tcx.hir().as_local_hir_id(def_id)
177                         }
178                         InstanceDef::VtableShim(..) |
179                         InstanceDef::Intrinsic(..) |
180                         InstanceDef::FnPtrShim(..) |
181                         InstanceDef::Virtual(..) |
182                         InstanceDef::ClosureOnceShim { .. } |
183                         InstanceDef::DropGlue(..) |
184                         InstanceDef::CloneShim(..) => {
185                             None
186                         }
187                     }
188                 }
189                 MonoItem::Static(def_id) => {
190                     tcx.hir().as_local_hir_id(def_id)
191                 }
192                 MonoItem::GlobalAsm(hir_id) => {
193                     Some(hir_id)
194                 }
195             }, item.symbol_name(tcx))
196         }
197
198         let mut items: Vec<_> = self.items().iter().map(|(&i, &l)| (i, l)).collect();
199         items.sort_by_cached_key(|&(i, _)| item_sort_key(tcx, i));
200         items
201     }
202
203     fn codegen_dep_node(&self, tcx: TyCtxt<'_, 'tcx, 'tcx>) -> DepNode {
204         DepNode::new(tcx, DepConstructor::CompileCodegenUnit(self.name().clone()))
205     }
206 }
207
208 impl<'tcx> CodegenUnitExt<'tcx> for CodegenUnit<'tcx> {
209     fn as_codegen_unit(&self) -> &CodegenUnit<'tcx> {
210         self
211     }
212 }
213
214 // Anything we can't find a proper codegen unit for goes into this.
215 fn fallback_cgu_name(name_builder: &mut CodegenUnitNameBuilder<'_, '_, '_>) -> InternedString {
216     name_builder.build_cgu_name(LOCAL_CRATE, &["fallback"], Some("cgu"))
217 }
218
219 pub fn partition<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
220                               mono_items: I,
221                               strategy: PartitioningStrategy,
222                               inlining_map: &InliningMap<'tcx>)
223                               -> Vec<CodegenUnit<'tcx>>
224     where I: Iterator<Item = MonoItem<'tcx>>
225 {
226     // In the first step, we place all regular monomorphizations into their
227     // respective 'home' codegen unit. Regular monomorphizations are all
228     // functions and statics defined in the local crate.
229     let mut initial_partitioning = place_root_mono_items(tcx, mono_items);
230
231     initial_partitioning.codegen_units.iter_mut().for_each(|cgu| cgu.estimate_size(tcx));
232
233     debug_dump(tcx, "INITIAL PARTITIONING:", initial_partitioning.codegen_units.iter());
234
235     // If the partitioning should produce a fixed count of codegen units, merge
236     // until that count is reached.
237     if let PartitioningStrategy::FixedUnitCount(count) = strategy {
238         merge_codegen_units(tcx, &mut initial_partitioning, count);
239
240         debug_dump(tcx, "POST MERGING:", initial_partitioning.codegen_units.iter());
241     }
242
243     // In the next step, we use the inlining map to determine which additional
244     // monomorphizations have to go into each codegen unit. These additional
245     // monomorphizations can be drop-glue, functions from external crates, and
246     // local functions the definition of which is marked with #[inline].
247     let mut post_inlining = place_inlined_mono_items(initial_partitioning,
248                                                             inlining_map);
249
250     post_inlining.codegen_units.iter_mut().for_each(|cgu| cgu.estimate_size(tcx));
251
252     debug_dump(tcx, "POST INLINING:", post_inlining.codegen_units.iter());
253
254     // Next we try to make as many symbols "internal" as possible, so LLVM has
255     // more freedom to optimize.
256     if !tcx.sess.opts.cg.link_dead_code {
257         internalize_symbols(tcx, &mut post_inlining, inlining_map);
258     }
259
260     // Finally, sort by codegen unit name, so that we get deterministic results
261     let PostInliningPartitioning {
262         codegen_units: mut result,
263         mono_item_placements: _,
264         internalization_candidates: _,
265     } = post_inlining;
266
267     result.sort_by(|cgu1, cgu2| {
268         cgu1.name().cmp(cgu2.name())
269     });
270
271     result
272 }
273
274 struct PreInliningPartitioning<'tcx> {
275     codegen_units: Vec<CodegenUnit<'tcx>>,
276     roots: FxHashSet<MonoItem<'tcx>>,
277     internalization_candidates: FxHashSet<MonoItem<'tcx>>,
278 }
279
280 /// For symbol internalization, we need to know whether a symbol/mono-item is
281 /// accessed from outside the codegen unit it is defined in. This type is used
282 /// to keep track of that.
283 #[derive(Clone, PartialEq, Eq, Debug)]
284 enum MonoItemPlacement {
285     SingleCgu { cgu_name: InternedString },
286     MultipleCgus,
287 }
288
289 struct PostInliningPartitioning<'tcx> {
290     codegen_units: Vec<CodegenUnit<'tcx>>,
291     mono_item_placements: FxHashMap<MonoItem<'tcx>, MonoItemPlacement>,
292     internalization_candidates: FxHashSet<MonoItem<'tcx>>,
293 }
294
295 fn place_root_mono_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
296                                              mono_items: I)
297                                              -> PreInliningPartitioning<'tcx>
298     where I: Iterator<Item = MonoItem<'tcx>>
299 {
300     let mut roots = FxHashSet::default();
301     let mut codegen_units = FxHashMap::default();
302     let is_incremental_build = tcx.sess.opts.incremental.is_some();
303     let mut internalization_candidates = FxHashSet::default();
304
305     // Determine if monomorphizations instantiated in this crate will be made
306     // available to downstream crates. This depends on whether we are in
307     // share-generics mode and whether the current crate can even have
308     // downstream crates.
309     let export_generics = tcx.sess.opts.share_generics() &&
310                           tcx.local_crate_exports_generics();
311
312     let cgu_name_builder = &mut CodegenUnitNameBuilder::new(tcx);
313     let cgu_name_cache = &mut FxHashMap::default();
314
315     for mono_item in mono_items {
316         match mono_item.instantiation_mode(tcx) {
317             InstantiationMode::GloballyShared { .. } => {}
318             InstantiationMode::LocalCopy => continue,
319         }
320
321         let characteristic_def_id = characteristic_def_id_of_mono_item(tcx, mono_item);
322         let is_volatile = is_incremental_build &&
323                           mono_item.is_generic_fn();
324
325         let codegen_unit_name = match characteristic_def_id {
326             Some(def_id) => compute_codegen_unit_name(tcx,
327                                                       cgu_name_builder,
328                                                       def_id,
329                                                       is_volatile,
330                                                       cgu_name_cache),
331             None => fallback_cgu_name(cgu_name_builder),
332         };
333
334         let codegen_unit = codegen_units.entry(codegen_unit_name.clone())
335             .or_insert_with(|| CodegenUnit::new(codegen_unit_name.clone()));
336
337         let mut can_be_internalized = true;
338         let (linkage, visibility) = mono_item_linkage_and_visibility(
339             tcx,
340             &mono_item,
341             &mut can_be_internalized,
342             export_generics,
343         );
344         if visibility == Visibility::Hidden && can_be_internalized {
345             internalization_candidates.insert(mono_item);
346         }
347
348         codegen_unit.items_mut().insert(mono_item, (linkage, visibility));
349         roots.insert(mono_item);
350     }
351
352     // always ensure we have at least one CGU; otherwise, if we have a
353     // crate with just types (for example), we could wind up with no CGU
354     if codegen_units.is_empty() {
355         let codegen_unit_name = fallback_cgu_name(cgu_name_builder);
356         codegen_units.insert(codegen_unit_name.clone(),
357                              CodegenUnit::new(codegen_unit_name.clone()));
358     }
359
360     PreInliningPartitioning {
361         codegen_units: codegen_units.into_iter()
362                                     .map(|(_, codegen_unit)| codegen_unit)
363                                     .collect(),
364         roots,
365         internalization_candidates,
366     }
367 }
368
369 fn mono_item_linkage_and_visibility(
370     tcx: TyCtxt<'a, 'tcx, 'tcx>,
371     mono_item: &MonoItem<'tcx>,
372     can_be_internalized: &mut bool,
373     export_generics: bool,
374 ) -> (Linkage, Visibility) {
375     if let Some(explicit_linkage) = mono_item.explicit_linkage(tcx) {
376         return (explicit_linkage, Visibility::Default)
377     }
378     let vis = mono_item_visibility(
379         tcx,
380         mono_item,
381         can_be_internalized,
382         export_generics,
383     );
384     (Linkage::External, vis)
385 }
386
387 fn mono_item_visibility(
388     tcx: TyCtxt<'a, 'tcx, 'tcx>,
389     mono_item: &MonoItem<'tcx>,
390     can_be_internalized: &mut bool,
391     export_generics: bool,
392 ) -> Visibility {
393     let instance = match mono_item {
394         // This is pretty complicated, go below
395         MonoItem::Fn(instance) => instance,
396
397         // Misc handling for generics and such, but otherwise
398         MonoItem::Static(def_id) => {
399             return if tcx.is_reachable_non_generic(*def_id) {
400                 *can_be_internalized = false;
401                 default_visibility(tcx, *def_id, false)
402             } else {
403                 Visibility::Hidden
404             };
405         }
406         MonoItem::GlobalAsm(hir_id) => {
407             let def_id = tcx.hir().local_def_id_from_hir_id(*hir_id);
408             return if tcx.is_reachable_non_generic(def_id) {
409                 *can_be_internalized = false;
410                 default_visibility(tcx, def_id, false)
411             } else {
412                 Visibility::Hidden
413             };
414         }
415     };
416
417     let def_id = match instance.def {
418         InstanceDef::Item(def_id) => def_id,
419
420         // These are all compiler glue and such, never exported, always hidden.
421         InstanceDef::VtableShim(..) |
422         InstanceDef::FnPtrShim(..) |
423         InstanceDef::Virtual(..) |
424         InstanceDef::Intrinsic(..) |
425         InstanceDef::ClosureOnceShim { .. } |
426         InstanceDef::DropGlue(..) |
427         InstanceDef::CloneShim(..) => {
428             return Visibility::Hidden
429         }
430     };
431
432     // The `start_fn` lang item is actually a monomorphized instance of a
433     // function in the standard library, used for the `main` function. We don't
434     // want to export it so we tag it with `Hidden` visibility but this symbol
435     // is only referenced from the actual `main` symbol which we unfortunately
436     // don't know anything about during partitioning/collection. As a result we
437     // forcibly keep this symbol out of the `internalization_candidates` set.
438     //
439     // FIXME: eventually we don't want to always force this symbol to have
440     //        hidden visibility, it should indeed be a candidate for
441     //        internalization, but we have to understand that it's referenced
442     //        from the `main` symbol we'll generate later.
443     //
444     //        This may be fixable with a new `InstanceDef` perhaps? Unsure!
445     if tcx.lang_items().start_fn() == Some(def_id) {
446         *can_be_internalized = false;
447         return Visibility::Hidden
448     }
449
450     let is_generic = instance.substs.non_erasable_generics().next().is_some();
451
452     // Upstream `DefId` instances get different handling than local ones
453     if !def_id.is_local() {
454         return if export_generics && is_generic {
455             // If it is a upstream monomorphization
456             // and we export generics, we must make
457             // it available to downstream crates.
458             *can_be_internalized = false;
459             default_visibility(tcx, def_id, true)
460         } else {
461             Visibility::Hidden
462         }
463     }
464
465     if is_generic {
466         if export_generics {
467             if tcx.is_unreachable_local_definition(def_id) {
468                 // This instance cannot be used
469                 // from another crate.
470                 Visibility::Hidden
471             } else {
472                 // This instance might be useful in
473                 // a downstream crate.
474                 *can_be_internalized = false;
475                 default_visibility(tcx, def_id, true)
476             }
477         } else {
478             // We are not exporting generics or
479             // the definition is not reachable
480             // for downstream crates, we can
481             // internalize its instantiations.
482             Visibility::Hidden
483         }
484     } else {
485
486         // If this isn't a generic function then we mark this a `Default` if
487         // this is a reachable item, meaning that it's a symbol other crates may
488         // access when they link to us.
489         if tcx.is_reachable_non_generic(def_id) {
490             *can_be_internalized = false;
491             debug_assert!(!is_generic);
492             return default_visibility(tcx, def_id, false)
493         }
494
495         // If this isn't reachable then we're gonna tag this with `Hidden`
496         // visibility. In some situations though we'll want to prevent this
497         // symbol from being internalized.
498         //
499         // There's two categories of items here:
500         //
501         // * First is weak lang items. These are basically mechanisms for
502         //   libcore to forward-reference symbols defined later in crates like
503         //   the standard library or `#[panic_handler]` definitions. The
504         //   definition of these weak lang items needs to be referenceable by
505         //   libcore, so we're no longer a candidate for internalization.
506         //   Removal of these functions can't be done by LLVM but rather must be
507         //   done by the linker as it's a non-local decision.
508         //
509         // * Second is "std internal symbols". Currently this is primarily used
510         //   for allocator symbols. Allocators are a little weird in their
511         //   implementation, but the idea is that the compiler, at the last
512         //   minute, defines an allocator with an injected object file. The
513         //   `alloc` crate references these symbols (`__rust_alloc`) and the
514         //   definition doesn't get hooked up until a linked crate artifact is
515         //   generated.
516         //
517         //   The symbols synthesized by the compiler (`__rust_alloc`) are thin
518         //   veneers around the actual implementation, some other symbol which
519         //   implements the same ABI. These symbols (things like `__rg_alloc`,
520         //   `__rdl_alloc`, `__rde_alloc`, etc), are all tagged with "std
521         //   internal symbols".
522         //
523         //   The std-internal symbols here **should not show up in a dll as an
524         //   exported interface**, so they return `false` from
525         //   `is_reachable_non_generic` above and we'll give them `Hidden`
526         //   visibility below. Like the weak lang items, though, we can't let
527         //   LLVM internalize them as this decision is left up to the linker to
528         //   omit them, so prevent them from being internalized.
529         let attrs = tcx.codegen_fn_attrs(def_id);
530         if attrs.flags.contains(CodegenFnAttrFlags::RUSTC_STD_INTERNAL_SYMBOL) {
531             *can_be_internalized = false;
532         }
533
534         Visibility::Hidden
535     }
536 }
537
538 fn default_visibility(tcx: TyCtxt<'_, '_, '_>, id: DefId, is_generic: bool) -> Visibility {
539     if !tcx.sess.target.target.options.default_hidden_visibility {
540         return Visibility::Default
541     }
542
543     // Generic functions never have export level C
544     if is_generic {
545         return Visibility::Hidden
546     }
547
548     // Things with export level C don't get instantiated in
549     // downstream crates
550     if !id.is_local() {
551         return Visibility::Hidden
552     }
553
554     // C-export level items remain at `Default`, all other internal
555     // items become `Hidden`
556     match tcx.reachable_non_generics(id.krate).get(&id) {
557         Some(SymbolExportLevel::C) => Visibility::Default,
558         _ => Visibility::Hidden,
559     }
560 }
561
562 fn merge_codegen_units<'tcx>(tcx: TyCtxt<'_, 'tcx, 'tcx>,
563                              initial_partitioning: &mut PreInliningPartitioning<'tcx>,
564                              target_cgu_count: usize) {
565     assert!(target_cgu_count >= 1);
566     let codegen_units = &mut initial_partitioning.codegen_units;
567
568     // Note that at this point in time the `codegen_units` here may not be in a
569     // deterministic order (but we know they're deterministically the same set).
570     // We want this merging to produce a deterministic ordering of codegen units
571     // from the input.
572     //
573     // Due to basically how we've implemented the merging below (merge the two
574     // smallest into each other) we're sure to start off with a deterministic
575     // order (sorted by name). This'll mean that if two cgus have the same size
576     // the stable sort below will keep everything nice and deterministic.
577     codegen_units.sort_by_key(|cgu| *cgu.name());
578
579     // Merge the two smallest codegen units until the target size is reached.
580     while codegen_units.len() > target_cgu_count {
581         // Sort small cgus to the back
582         codegen_units.sort_by_cached_key(|cgu| cmp::Reverse(cgu.size_estimate()));
583         let mut smallest = codegen_units.pop().unwrap();
584         let second_smallest = codegen_units.last_mut().unwrap();
585
586         second_smallest.modify_size_estimate(smallest.size_estimate());
587         for (k, v) in smallest.items_mut().drain() {
588             second_smallest.items_mut().insert(k, v);
589         }
590     }
591
592     let cgu_name_builder = &mut CodegenUnitNameBuilder::new(tcx);
593     for (index, cgu) in codegen_units.iter_mut().enumerate() {
594         cgu.set_name(numbered_codegen_unit_name(cgu_name_builder, index));
595     }
596 }
597
598 fn place_inlined_mono_items<'tcx>(initial_partitioning: PreInliningPartitioning<'tcx>,
599                                   inlining_map: &InliningMap<'tcx>)
600                                   -> PostInliningPartitioning<'tcx> {
601     let mut new_partitioning = Vec::new();
602     let mut mono_item_placements = FxHashMap::default();
603
604     let PreInliningPartitioning {
605         codegen_units: initial_cgus,
606         roots,
607         internalization_candidates,
608     } = initial_partitioning;
609
610     let single_codegen_unit = initial_cgus.len() == 1;
611
612     for old_codegen_unit in initial_cgus {
613         // Collect all items that need to be available in this codegen unit
614         let mut reachable = FxHashSet::default();
615         for root in old_codegen_unit.items().keys() {
616             follow_inlining(*root, inlining_map, &mut reachable);
617         }
618
619         let mut new_codegen_unit = CodegenUnit::new(old_codegen_unit.name().clone());
620
621         // Add all monomorphizations that are not already there
622         for mono_item in reachable {
623             if let Some(linkage) = old_codegen_unit.items().get(&mono_item) {
624                 // This is a root, just copy it over
625                 new_codegen_unit.items_mut().insert(mono_item, *linkage);
626             } else {
627                 if roots.contains(&mono_item) {
628                     bug!("GloballyShared mono-item inlined into other CGU: \
629                           {:?}", mono_item);
630                 }
631
632                 // This is a cgu-private copy
633                 new_codegen_unit.items_mut().insert(
634                     mono_item,
635                     (Linkage::Internal, Visibility::Default),
636                 );
637             }
638
639             if !single_codegen_unit {
640                 // If there is more than one codegen unit, we need to keep track
641                 // in which codegen units each monomorphization is placed:
642                 match mono_item_placements.entry(mono_item) {
643                     Entry::Occupied(e) => {
644                         let placement = e.into_mut();
645                         debug_assert!(match *placement {
646                             MonoItemPlacement::SingleCgu { ref cgu_name } => {
647                                 *cgu_name != *new_codegen_unit.name()
648                             }
649                             MonoItemPlacement::MultipleCgus => true,
650                         });
651                         *placement = MonoItemPlacement::MultipleCgus;
652                     }
653                     Entry::Vacant(e) => {
654                         e.insert(MonoItemPlacement::SingleCgu {
655                             cgu_name: new_codegen_unit.name().clone()
656                         });
657                     }
658                 }
659             }
660         }
661
662         new_partitioning.push(new_codegen_unit);
663     }
664
665     return PostInliningPartitioning {
666         codegen_units: new_partitioning,
667         mono_item_placements,
668         internalization_candidates,
669     };
670
671     fn follow_inlining<'tcx>(mono_item: MonoItem<'tcx>,
672                              inlining_map: &InliningMap<'tcx>,
673                              visited: &mut FxHashSet<MonoItem<'tcx>>) {
674         if !visited.insert(mono_item) {
675             return;
676         }
677
678         inlining_map.with_inlining_candidates(mono_item, |target| {
679             follow_inlining(target, inlining_map, visited);
680         });
681     }
682 }
683
684 fn internalize_symbols<'a, 'tcx>(_tcx: TyCtxt<'a, 'tcx, 'tcx>,
685                                  partitioning: &mut PostInliningPartitioning<'tcx>,
686                                  inlining_map: &InliningMap<'tcx>) {
687     if partitioning.codegen_units.len() == 1 {
688         // Fast path for when there is only one codegen unit. In this case we
689         // can internalize all candidates, since there is nowhere else they
690         // could be accessed from.
691         for cgu in &mut partitioning.codegen_units {
692             for candidate in &partitioning.internalization_candidates {
693                 cgu.items_mut().insert(*candidate,
694                                        (Linkage::Internal, Visibility::Default));
695             }
696         }
697
698         return;
699     }
700
701     // Build a map from every monomorphization to all the monomorphizations that
702     // reference it.
703     let mut accessor_map: FxHashMap<MonoItem<'tcx>, Vec<MonoItem<'tcx>>> = Default::default();
704     inlining_map.iter_accesses(|accessor, accessees| {
705         for accessee in accessees {
706             accessor_map.entry(*accessee)
707                         .or_default()
708                         .push(accessor);
709         }
710     });
711
712     let mono_item_placements = &partitioning.mono_item_placements;
713
714     // For each internalization candidates in each codegen unit, check if it is
715     // accessed from outside its defining codegen unit.
716     for cgu in &mut partitioning.codegen_units {
717         let home_cgu = MonoItemPlacement::SingleCgu {
718             cgu_name: cgu.name().clone()
719         };
720
721         for (accessee, linkage_and_visibility) in cgu.items_mut() {
722             if !partitioning.internalization_candidates.contains(accessee) {
723                 // This item is no candidate for internalizing, so skip it.
724                 continue
725             }
726             debug_assert_eq!(mono_item_placements[accessee], home_cgu);
727
728             if let Some(accessors) = accessor_map.get(accessee) {
729                 if accessors.iter()
730                             .filter_map(|accessor| {
731                                 // Some accessors might not have been
732                                 // instantiated. We can safely ignore those.
733                                 mono_item_placements.get(accessor)
734                             })
735                             .any(|placement| *placement != home_cgu) {
736                     // Found an accessor from another CGU, so skip to the next
737                     // item without marking this one as internal.
738                     continue
739                 }
740             }
741
742             // If we got here, we did not find any accesses from other CGUs,
743             // so it's fine to make this monomorphization internal.
744             *linkage_and_visibility = (Linkage::Internal, Visibility::Default);
745         }
746     }
747 }
748
749 fn characteristic_def_id_of_mono_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
750                                                  mono_item: MonoItem<'tcx>)
751                                                  -> Option<DefId> {
752     match mono_item {
753         MonoItem::Fn(instance) => {
754             let def_id = match instance.def {
755                 ty::InstanceDef::Item(def_id) => def_id,
756                 ty::InstanceDef::VtableShim(..) |
757                 ty::InstanceDef::FnPtrShim(..) |
758                 ty::InstanceDef::ClosureOnceShim { .. } |
759                 ty::InstanceDef::Intrinsic(..) |
760                 ty::InstanceDef::DropGlue(..) |
761                 ty::InstanceDef::Virtual(..) |
762                 ty::InstanceDef::CloneShim(..) => return None
763             };
764
765             // If this is a method, we want to put it into the same module as
766             // its self-type. If the self-type does not provide a characteristic
767             // DefId, we use the location of the impl after all.
768
769             if tcx.trait_of_item(def_id).is_some() {
770                 let self_ty = instance.substs.type_at(0);
771                 // This is an implementation of a trait method.
772                 return characteristic_def_id_of_type(self_ty).or(Some(def_id));
773             }
774
775             if let Some(impl_def_id) = tcx.impl_of_method(def_id) {
776                 // This is a method within an inherent impl, find out what the
777                 // self-type is:
778                 let impl_self_ty = tcx.subst_and_normalize_erasing_regions(
779                     instance.substs,
780                     ty::ParamEnv::reveal_all(),
781                     &tcx.type_of(impl_def_id),
782                 );
783                 if let Some(def_id) = characteristic_def_id_of_type(impl_self_ty) {
784                     return Some(def_id);
785                 }
786             }
787
788             Some(def_id)
789         }
790         MonoItem::Static(def_id) => Some(def_id),
791         MonoItem::GlobalAsm(hir_id) => Some(tcx.hir().local_def_id_from_hir_id(hir_id)),
792     }
793 }
794
795 type CguNameCache = FxHashMap<(DefId, bool), InternedString>;
796
797 fn compute_codegen_unit_name(tcx: TyCtxt<'_, '_, '_>,
798                              name_builder: &mut CodegenUnitNameBuilder<'_, '_, '_>,
799                              def_id: DefId,
800                              volatile: bool,
801                              cache: &mut CguNameCache)
802                              -> InternedString {
803     // Find the innermost module that is not nested within a function
804     let mut current_def_id = def_id;
805     let mut cgu_def_id = None;
806     // Walk backwards from the item we want to find the module for:
807     loop {
808         if current_def_id.index == CRATE_DEF_INDEX {
809             if cgu_def_id.is_none() {
810                 // If we have not found a module yet, take the crate root.
811                 cgu_def_id = Some(DefId {
812                     krate: def_id.krate,
813                     index: CRATE_DEF_INDEX,
814                 });
815             }
816             break
817         } else if tcx.def_kind(current_def_id) == Some(DefKind::Mod) {
818             if cgu_def_id.is_none() {
819                 cgu_def_id = Some(current_def_id);
820             }
821         } else {
822             // If we encounter something that is not a module, throw away
823             // any module that we've found so far because we now know that
824             // it is nested within something else.
825             cgu_def_id = None;
826         }
827
828         current_def_id = tcx.parent(current_def_id).unwrap();
829     }
830
831     let cgu_def_id = cgu_def_id.unwrap();
832
833     cache.entry((cgu_def_id, volatile)).or_insert_with(|| {
834         let def_path = tcx.def_path(cgu_def_id);
835
836         let components = def_path
837             .data
838             .iter()
839             .map(|part| part.data.as_interned_str());
840
841         let volatile_suffix = if volatile {
842             Some("volatile")
843         } else {
844             None
845         };
846
847         name_builder.build_cgu_name(def_path.krate, components, volatile_suffix)
848     }).clone()
849 }
850
851 fn numbered_codegen_unit_name(name_builder: &mut CodegenUnitNameBuilder<'_, '_, '_>,
852                               index: usize)
853                               -> InternedString {
854     name_builder.build_cgu_name_no_mangle(LOCAL_CRATE, &["cgu"], Some(index))
855 }
856
857 fn debug_dump<'a, 'b, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
858                                label: &str,
859                                cgus: I)
860     where I: Iterator<Item=&'b CodegenUnit<'tcx>>,
861           'tcx: 'a + 'b
862 {
863     if cfg!(debug_assertions) {
864         debug!("{}", label);
865         for cgu in cgus {
866             debug!("CodegenUnit {}:", cgu.name());
867
868             for (mono_item, linkage) in cgu.items() {
869                 let symbol_name = mono_item.symbol_name(tcx).as_str();
870                 let symbol_hash_start = symbol_name.rfind('h');
871                 let symbol_hash = symbol_hash_start.map(|i| &symbol_name[i ..])
872                                                    .unwrap_or("<no hash>");
873
874                 debug!(" - {} [{:?}] [{}]",
875                        mono_item.to_string(tcx, true),
876                        linkage,
877                        symbol_hash);
878             }
879
880             debug!("");
881         }
882     }
883 }
884
885 fn collect_and_partition_mono_items<'a, 'tcx>(
886     tcx: TyCtxt<'a, 'tcx, 'tcx>,
887     cnum: CrateNum,
888 ) -> (Arc<DefIdSet>, Arc<Vec<Arc<CodegenUnit<'tcx>>>>)
889 {
890     assert_eq!(cnum, LOCAL_CRATE);
891
892     let collection_mode = match tcx.sess.opts.debugging_opts.print_mono_items {
893         Some(ref s) => {
894             let mode_string = s.to_lowercase();
895             let mode_string = mode_string.trim();
896             if mode_string == "eager" {
897                 MonoItemCollectionMode::Eager
898             } else {
899                 if mode_string != "lazy" {
900                     let message = format!("Unknown codegen-item collection mode '{}'. \
901                                            Falling back to 'lazy' mode.",
902                                           mode_string);
903                     tcx.sess.warn(&message);
904                 }
905
906                 MonoItemCollectionMode::Lazy
907             }
908         }
909         None => {
910             if tcx.sess.opts.cg.link_dead_code {
911                 MonoItemCollectionMode::Eager
912             } else {
913                 MonoItemCollectionMode::Lazy
914             }
915         }
916     };
917
918     let (items, inlining_map) =
919         time(tcx.sess, "monomorphization collection", || {
920             collector::collect_crate_mono_items(tcx, collection_mode)
921     });
922
923     tcx.sess.abort_if_errors();
924
925     crate::monomorphize::assert_symbols_are_distinct(tcx, items.iter());
926
927     let strategy = if tcx.sess.opts.incremental.is_some() {
928         PartitioningStrategy::PerModule
929     } else {
930         PartitioningStrategy::FixedUnitCount(tcx.sess.codegen_units())
931     };
932
933     let codegen_units = time(tcx.sess, "codegen unit partitioning", || {
934         partition(
935             tcx,
936             items.iter().cloned(),
937             strategy,
938             &inlining_map
939         )
940             .into_iter()
941             .map(Arc::new)
942             .collect::<Vec<_>>()
943     });
944
945     let mono_items: DefIdSet = items.iter().filter_map(|mono_item| {
946         match *mono_item {
947             MonoItem::Fn(ref instance) => Some(instance.def_id()),
948             MonoItem::Static(def_id) => Some(def_id),
949             _ => None,
950         }
951     }).collect();
952
953     if tcx.sess.opts.debugging_opts.print_mono_items.is_some() {
954         let mut item_to_cgus: FxHashMap<_, Vec<_>> = Default::default();
955
956         for cgu in &codegen_units {
957             for (&mono_item, &linkage) in cgu.items() {
958                 item_to_cgus.entry(mono_item)
959                             .or_default()
960                             .push((cgu.name().clone(), linkage));
961             }
962         }
963
964         let mut item_keys: Vec<_> = items
965             .iter()
966             .map(|i| {
967                 let mut output = i.to_string(tcx, false);
968                 output.push_str(" @@");
969                 let mut empty = Vec::new();
970                 let cgus = item_to_cgus.get_mut(i).unwrap_or(&mut empty);
971                 cgus.sort_by_key(|(name, _)| *name);
972                 cgus.dedup();
973                 for &(ref cgu_name, (linkage, _)) in cgus.iter() {
974                     output.push_str(" ");
975                     output.push_str(&cgu_name.as_str());
976
977                     let linkage_abbrev = match linkage {
978                         Linkage::External => "External",
979                         Linkage::AvailableExternally => "Available",
980                         Linkage::LinkOnceAny => "OnceAny",
981                         Linkage::LinkOnceODR => "OnceODR",
982                         Linkage::WeakAny => "WeakAny",
983                         Linkage::WeakODR => "WeakODR",
984                         Linkage::Appending => "Appending",
985                         Linkage::Internal => "Internal",
986                         Linkage::Private => "Private",
987                         Linkage::ExternalWeak => "ExternalWeak",
988                         Linkage::Common => "Common",
989                     };
990
991                     output.push_str("[");
992                     output.push_str(linkage_abbrev);
993                     output.push_str("]");
994                 }
995                 output
996             })
997             .collect();
998
999         item_keys.sort();
1000
1001         for item in item_keys {
1002             println!("MONO_ITEM {}", item);
1003         }
1004     }
1005
1006     (Arc::new(mono_items), Arc::new(codegen_units))
1007 }
1008
1009 pub fn provide(providers: &mut Providers<'_>) {
1010     providers.collect_and_partition_mono_items =
1011         collect_and_partition_mono_items;
1012
1013     providers.is_codegened_item = |tcx, def_id| {
1014         let (all_mono_items, _) =
1015             tcx.collect_and_partition_mono_items(LOCAL_CRATE);
1016         all_mono_items.contains(&def_id)
1017     };
1018
1019     providers.codegen_unit = |tcx, name| {
1020         let (_, all) = tcx.collect_and_partition_mono_items(LOCAL_CRATE);
1021         all.iter()
1022             .find(|cgu| *cgu.name() == name)
1023             .cloned()
1024             .unwrap_or_else(|| panic!("failed to find cgu with name {:?}", name))
1025     };
1026 }