// Copyright 2016 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Partitioning Codegen Units for Incremental Compilation
//! ======================================================
//!
//! The task of this module is to take the complete set of translation items of
//! a crate and produce a set of codegen units from it, where a codegen unit
//! is a named set of (translation-item, linkage) pairs. That is, this module
//! decides which translation item appears in which codegen units with which
//! linkage. The following paragraphs describe some of the background on the
//! partitioning scheme.
//!
//! The most important opportunity for saving on compilation time with
//! incremental compilation is to avoid re-translating and re-optimizing code.
//! Since the unit of translation and optimization for LLVM is "modules" or, how
//! we call them "codegen units", the particulars of how much time can be saved
//! by incremental compilation are tightly linked to how the output program is
//! partitioned into these codegen units prior to passing it to LLVM --
//! especially because we have to treat codegen units as opaque entities once
//! they are created: There is no way for us to incrementally update an existing
//! LLVM module and so we have to build any such module from scratch if it was
//! affected by some change in the source code.
//!
//! From that point of view it would make sense to maximize the number of
//! codegen units by, for example, putting each function into its own module.
//! That way only those modules would have to be re-compiled that were actually
//! affected by some change, minimizing the number of functions that could have
//! been re-used but just happened to be located in a module that is
//! re-compiled.
//!
//! However, since LLVM optimization does not work across module boundaries,
//! using such a highly granular partitioning would lead to very slow runtime
//! code since it would effectively prohibit inlining and other inter-procedure
//! optimizations. We want to avoid that as much as possible.
//!
//! Thus we end up with a trade-off: The bigger the codegen units, the better
//! LLVM's optimizer can do its work, but also the smaller the compilation time
//! reduction we get from incremental compilation.
//!
//! Ideally, we would create a partitioning such that there are few big codegen
//! units with few interdependencies between them. For now though, we use the
//! following heuristic to determine the partitioning:
//!
//! - There are two codegen units for every source-level module:
//! - One for "stable", that is non-generic, code
//! - One for more "volatile" code, i.e. monomorphized instances of functions
//!   defined in that module
//! - Code for monomorphized instances of functions from external crates gets
//!   placed into every codegen unit that uses that instance.
//!
//! In order to see why this heuristic makes sense, let's take a look at when a
//! codegen unit can get invalidated:
//!
//! 1. The most straightforward case is when the BODY of a function or global
//! changes. Then any codegen unit containing the code for that item has to be
//! re-compiled. Note that this includes all codegen units where the function
//! has been inlined.
//!
//! 2. The next case is when the SIGNATURE of a function or global changes. In
//! this case, all codegen units containing a REFERENCE to that item have to be
//! re-compiled. This is a superset of case 1.
//!
//! 3. The final and most subtle case is when a REFERENCE to a generic function
//! is added or removed somewhere. Even though the definition of the function
//! might be unchanged, a new REFERENCE might introduce a new monomorphized
//! instance of this function which has to be placed and compiled somewhere.
//! Conversely, when removing a REFERENCE, it might have been the last one with
//! that particular set of generic arguments and thus we have to remove it.
//!
//! From the above we see that just using one codegen unit per source-level
//! module is not such a good idea, since just adding a REFERENCE to some
//! generic item somewhere else would invalidate everything within the module
//! containing the generic item. The heuristic above reduces this detrimental
//! side-effect of references a little by at least not touching the non-generic
//! code of the module.
//!
//! As another optimization, monomorphized functions from external crates get
//! some special handling. Since we assume that the definition of such a
//! function changes rather infrequently compared to local items, we can just
//! instantiate external functions in every codegen unit where it is referenced
//! -- without having to fear that doing this will cause a lot of unnecessary
//! re-compilations. If such a reference is added or removed, the codegen unit
//! has to be re-translated anyway.
//! (Note that this only makes sense if external crates actually don't change
//! frequently. For certain multi-crate projects this might not be a valid
//! assumption).
//!
//! A Note on Inlining
//! ------------------
//! As briefly mentioned above, in order for LLVM to be able to inline a
//! function call, the body of the function has to be available in the LLVM
//! module where the call is made. This has a few consequences for partitioning:
//!
//! - The partitioning algorithm has to take care of placing functions into all
//!   codegen units where they should be available for inlining. It also has to
//!   decide on the correct linkage for these functions.
//!
//! - The partitioning algorithm has to know which functions are likely to get
//!   inlined, so it can distribute function instantiations accordingly. Since
//!   there is no way of knowing for sure which functions LLVM will decide to
//!   inline in the end, we apply a heuristic here: Only functions marked with
//!   #[inline] and (as stated above) functions from external crates are
//!   considered for inlining by the partitioner. The current implementation
//!   will not try to determine if a function is likely to be inlined by looking
//!   at the functions definition.
//!
//! Note though that as a side-effect of creating a codegen units per
//! source-level module, functions from the same module will be available for
//! inlining, even when they are not marked #[inline].

use collector::InliningMap;
use llvm;
use monomorphize;
use rustc::dep_graph::{DepNode, WorkProductId};
use rustc::hir::def_id::DefId;
use rustc::hir::map::DefPathData;
use rustc::session::config::NUMBERED_CODEGEN_UNIT_MARKER;
use rustc::ty::TyCtxt;
use rustc::ty::item_path::characteristic_def_id_of_type;
use std::cmp::Ordering;
use std::hash::{Hash, Hasher, SipHasher};
use std::sync::Arc;
use symbol_map::SymbolMap;
use syntax::ast::NodeId;
use syntax::parse::token::{self, InternedString};
use trans_item::TransItem;
use util::nodemap::{FnvHashMap, FnvHashSet, NodeSet};

pub enum PartitioningStrategy {
    /// Generate one codegen unit per source-level module.
    PerModule,

    /// Partition the whole crate into a fixed number of codegen units.
    FixedUnitCount(usize)
}

pub struct CodegenUnit<'tcx> {
    /// A name for this CGU. Incremental compilation requires that
    /// name be unique amongst **all** crates.  Therefore, it should
    /// contain something unique to this crate (e.g., a module path)
    /// as well as the crate name and disambiguator.
    name: InternedString,

    items: FnvHashMap<TransItem<'tcx>, llvm::Linkage>,
}

impl<'tcx> CodegenUnit<'tcx> {
    pub fn new(name: InternedString,
               items: FnvHashMap<TransItem<'tcx>, llvm::Linkage>)
               -> Self {
        CodegenUnit {
            name: name,
            items: items,
        }
    }

    pub fn empty(name: InternedString) -> Self {
        Self::new(name, FnvHashMap())
    }

    pub fn contains_item(&self, item: &TransItem<'tcx>) -> bool {
        self.items.contains_key(item)
    }

    pub fn name(&self) -> &str {
        &self.name
    }

    pub fn items(&self) -> &FnvHashMap<TransItem<'tcx>, llvm::Linkage> {
        &self.items
    }

    pub fn work_product_id(&self) -> Arc<WorkProductId> {
        Arc::new(WorkProductId(self.name().to_string()))
    }

    pub fn work_product_dep_node(&self) -> DepNode<DefId> {
        DepNode::WorkProduct(self.work_product_id())
    }

    pub fn compute_symbol_name_hash(&self, tcx: TyCtxt, symbol_map: &SymbolMap) -> u64 {
        let mut state = SipHasher::new();
        let all_items = self.items_in_deterministic_order(tcx, symbol_map);
        for (item, _) in all_items {
            let symbol_name = symbol_map.get(item).unwrap();
            symbol_name.hash(&mut state);
        }
        state.finish()
    }

    pub fn items_in_deterministic_order(&self,
                                        tcx: TyCtxt,
                                        symbol_map: &SymbolMap)
                                        -> Vec<(TransItem<'tcx>, llvm::Linkage)> {
        let mut items: Vec<(TransItem<'tcx>, llvm::Linkage)> =
            self.items.iter().map(|(item, linkage)| (*item, *linkage)).collect();

        // The codegen tests rely on items being process in the same order as
        // they appear in the file, so for local items, we sort by node_id first
        items.sort_by(|&(trans_item1, _), &(trans_item2, _)| {
            let node_id1 = local_node_id(tcx, trans_item1);
            let node_id2 = local_node_id(tcx, trans_item2);

            match (node_id1, node_id2) {
                (None, None) => {
                    let symbol_name1 = symbol_map.get(trans_item1).unwrap();
                    let symbol_name2 = symbol_map.get(trans_item2).unwrap();
                    symbol_name1.cmp(symbol_name2)
                }
                // In the following two cases we can avoid looking up the symbol
                (None, Some(_)) => Ordering::Less,
                (Some(_), None) => Ordering::Greater,
                (Some(node_id1), Some(node_id2)) => {
                    let ordering = node_id1.cmp(&node_id2);

                    if ordering != Ordering::Equal {
                        return ordering;
                    }

                    let symbol_name1 = symbol_map.get(trans_item1).unwrap();
                    let symbol_name2 = symbol_map.get(trans_item2).unwrap();
                    symbol_name1.cmp(symbol_name2)
                }
            }
        });

        return items;

        fn local_node_id(tcx: TyCtxt, trans_item: TransItem) -> Option<NodeId> {
            match trans_item {
                TransItem::Fn(instance) => {
                    tcx.map.as_local_node_id(instance.def)
                }
                TransItem::Static(node_id) => Some(node_id),
                TransItem::DropGlue(_) => None,
            }
        }
    }
}


// Anything we can't find a proper codegen unit for goes into this.
const FALLBACK_CODEGEN_UNIT: &'static str = "__rustc_fallback_codegen_unit";

pub fn partition<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                              trans_items: I,
                              strategy: PartitioningStrategy,
                              inlining_map: &InliningMap<'tcx>,
                              reachable: &NodeSet)
                              -> Vec<CodegenUnit<'tcx>>
    where I: Iterator<Item = TransItem<'tcx>>
{
    if let PartitioningStrategy::FixedUnitCount(1) = strategy {
        // If there is only a single codegen-unit, we can use a very simple
        // scheme and don't have to bother with doing much analysis.
        return vec![single_codegen_unit(tcx, trans_items, reachable)];
    }

    // In the first step, we place all regular translation items into their
    // respective 'home' codegen unit. Regular translation items are all
    // functions and statics defined in the local crate.
    let mut initial_partitioning = place_root_translation_items(tcx,
                                                                trans_items,
                                                                reachable);

    debug_dump(tcx, "INITIAL PARTITONING:", initial_partitioning.codegen_units.iter());

    // If the partitioning should produce a fixed count of codegen units, merge
    // until that count is reached.
    if let PartitioningStrategy::FixedUnitCount(count) = strategy {
        merge_codegen_units(&mut initial_partitioning, count, &tcx.crate_name[..]);

        debug_dump(tcx, "POST MERGING:", initial_partitioning.codegen_units.iter());
    }

    // In the next step, we use the inlining map to determine which addtional
    // translation items have to go into each codegen unit. These additional
    // translation items can be drop-glue, functions from external crates, and
    // local functions the definition of which is marked with #[inline].
    let post_inlining = place_inlined_translation_items(initial_partitioning,
                                                        inlining_map);

    debug_dump(tcx, "POST INLINING:", post_inlining.0.iter());

    // Finally, sort by codegen unit name, so that we get deterministic results
    let mut result = post_inlining.0;
    result.sort_by(|cgu1, cgu2| {
        (&cgu1.name[..]).cmp(&cgu2.name[..])
    });

    result
}

struct PreInliningPartitioning<'tcx> {
    codegen_units: Vec<CodegenUnit<'tcx>>,
    roots: FnvHashSet<TransItem<'tcx>>,
}

struct PostInliningPartitioning<'tcx>(Vec<CodegenUnit<'tcx>>);

fn place_root_translation_items<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                             trans_items: I,
                                             _reachable: &NodeSet)
                                             -> PreInliningPartitioning<'tcx>
    where I: Iterator<Item = TransItem<'tcx>>
{
    let mut roots = FnvHashSet();
    let mut codegen_units = FnvHashMap();

    for trans_item in trans_items {
        let is_root = !trans_item.is_instantiated_only_on_demand();

        if is_root {
            let characteristic_def_id = characteristic_def_id_of_trans_item(tcx, trans_item);
            let is_volatile = trans_item.is_generic_fn();

            let codegen_unit_name = match characteristic_def_id {
                Some(def_id) => compute_codegen_unit_name(tcx, def_id, is_volatile),
                None => InternedString::new(FALLBACK_CODEGEN_UNIT),
            };

            let make_codegen_unit = || {
                CodegenUnit::empty(codegen_unit_name.clone())
            };

            let mut codegen_unit = codegen_units.entry(codegen_unit_name.clone())
                                                .or_insert_with(make_codegen_unit);

            let linkage = match trans_item.explicit_linkage(tcx) {
                Some(explicit_linkage) => explicit_linkage,
                None => {
                    match trans_item {
                        TransItem::Static(..) => llvm::ExternalLinkage,
                        TransItem::DropGlue(..) => unreachable!(),
                        // Is there any benefit to using ExternalLinkage?:
                        TransItem::Fn(ref instance) => {
                            if instance.substs.types.is_empty() {
                                // This is a non-generic functions, we always
                                // make it visible externally on the chance that
                                // it might be used in another codegen unit.
                                llvm::ExternalLinkage
                            } else {
                                // In the current setup, generic functions cannot
                                // be roots.
                                unreachable!()
                            }
                        }
                    }
                }
            };

            codegen_unit.items.insert(trans_item, linkage);
            roots.insert(trans_item);
        }
    }

    // always ensure we have at least one CGU; otherwise, if we have a
    // crate with just types (for example), we could wind up with no CGU
    if codegen_units.is_empty() {
        let codegen_unit_name = InternedString::new(FALLBACK_CODEGEN_UNIT);
        codegen_units.entry(codegen_unit_name.clone())
                     .or_insert_with(|| CodegenUnit::empty(codegen_unit_name.clone()));
    }

    PreInliningPartitioning {
        codegen_units: codegen_units.into_iter()
                                    .map(|(_, codegen_unit)| codegen_unit)
                                    .collect(),
        roots: roots,
    }
}

fn merge_codegen_units<'tcx>(initial_partitioning: &mut PreInliningPartitioning<'tcx>,
                             target_cgu_count: usize,
                             crate_name: &str) {
    assert!(target_cgu_count >= 1);
    let codegen_units = &mut initial_partitioning.codegen_units;

    // Merge the two smallest codegen units until the target size is reached.
    // Note that "size" is estimated here rather inaccurately as the number of
    // translation items in a given unit. This could be improved on.
    while codegen_units.len() > target_cgu_count {
        // Sort small cgus to the back
        codegen_units.sort_by_key(|cgu| -(cgu.items.len() as i64));
        let smallest = codegen_units.pop().unwrap();
        let second_smallest = codegen_units.last_mut().unwrap();

        for (k, v) in smallest.items.into_iter() {
            second_smallest.items.insert(k, v);
        }
    }

    for (index, cgu) in codegen_units.iter_mut().enumerate() {
        cgu.name = numbered_codegen_unit_name(crate_name, index);
    }

    // If the initial partitioning contained less than target_cgu_count to begin
    // with, we won't have enough codegen units here, so add a empty units until
    // we reach the target count
    while codegen_units.len() < target_cgu_count {
        let index = codegen_units.len();
        codegen_units.push(
            CodegenUnit::empty(numbered_codegen_unit_name(crate_name, index)));
    }
}

fn place_inlined_translation_items<'tcx>(initial_partitioning: PreInliningPartitioning<'tcx>,
                                         inlining_map: &InliningMap<'tcx>)
                                         -> PostInliningPartitioning<'tcx> {
    let mut new_partitioning = Vec::new();

    for codegen_unit in &initial_partitioning.codegen_units[..] {
        // Collect all items that need to be available in this codegen unit
        let mut reachable = FnvHashSet();
        for root in codegen_unit.items.keys() {
            follow_inlining(*root, inlining_map, &mut reachable);
        }

        let mut new_codegen_unit =
            CodegenUnit::empty(codegen_unit.name.clone());

        // Add all translation items that are not already there
        for trans_item in reachable {
            if let Some(linkage) = codegen_unit.items.get(&trans_item) {
                // This is a root, just copy it over
                new_codegen_unit.items.insert(trans_item, *linkage);
            } else if initial_partitioning.roots.contains(&trans_item) {
                // This item will be instantiated in some other codegen unit,
                // so we just add it here with AvailableExternallyLinkage
                // FIXME(mw): I have not seen it happening yet but having
                //            available_externally here could potentially lead
                //            to the same problem with exception handling tables
                //            as in the case below.
                new_codegen_unit.items.insert(trans_item,
                                              llvm::AvailableExternallyLinkage);
            } else if trans_item.is_from_extern_crate() && !trans_item.is_generic_fn() {
                // FIXME(mw): It would be nice if we could mark these as
                // `AvailableExternallyLinkage`, since they should have
                // been instantiated in the extern crate. But this
                // sometimes leads to crashes on Windows because LLVM
                // does not handle exception handling table instantiation
                // reliably in that case.
                new_codegen_unit.items.insert(trans_item, llvm::InternalLinkage);
            } else {
                assert!(trans_item.is_instantiated_only_on_demand());
                // We can't be sure if this will also be instantiated
                // somewhere else, so we add an instance here with
                // InternalLinkage so we don't get any conflicts.
                new_codegen_unit.items.insert(trans_item,
                                              llvm::InternalLinkage);
            }
        }

        new_partitioning.push(new_codegen_unit);
    }

    return PostInliningPartitioning(new_partitioning);

    fn follow_inlining<'tcx>(trans_item: TransItem<'tcx>,
                             inlining_map: &InliningMap<'tcx>,
                             visited: &mut FnvHashSet<TransItem<'tcx>>) {
        if !visited.insert(trans_item) {
            return;
        }

        inlining_map.with_inlining_candidates(trans_item, |target| {
            follow_inlining(target, inlining_map, visited);
        });
    }
}

fn characteristic_def_id_of_trans_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                                 trans_item: TransItem<'tcx>)
                                                 -> Option<DefId> {
    match trans_item {
        TransItem::Fn(instance) => {
            // If this is a method, we want to put it into the same module as
            // its self-type. If the self-type does not provide a characteristic
            // DefId, we use the location of the impl after all.

            if let Some(self_ty) = instance.substs.self_ty() {
                // This is an implementation of a trait method.
                return characteristic_def_id_of_type(self_ty).or(Some(instance.def));
            }

            if let Some(impl_def_id) = tcx.impl_of_method(instance.def) {
                // This is a method within an inherent impl, find out what the
                // self-type is:
                let impl_self_ty = tcx.lookup_item_type(impl_def_id).ty;
                let impl_self_ty = tcx.erase_regions(&impl_self_ty);
                let impl_self_ty = monomorphize::apply_param_substs(tcx,
                                                                    instance.substs,
                                                                    &impl_self_ty);

                if let Some(def_id) = characteristic_def_id_of_type(impl_self_ty) {
                    return Some(def_id);
                }
            }

            Some(instance.def)
        }
        TransItem::DropGlue(dg) => characteristic_def_id_of_type(dg.ty()),
        TransItem::Static(node_id) => Some(tcx.map.local_def_id(node_id)),
    }
}

fn compute_codegen_unit_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                       def_id: DefId,
                                       volatile: bool)
                                       -> InternedString {
    // Unfortunately we cannot just use the `ty::item_path` infrastructure here
    // because we need paths to modules and the DefIds of those are not
    // available anymore for external items.
    let mut mod_path = String::with_capacity(64);

    let def_path = tcx.def_path(def_id);
    mod_path.push_str(&tcx.crate_name(def_path.krate));

    for part in tcx.def_path(def_id)
                   .data
                   .iter()
                   .take_while(|part| {
                        match part.data {
                            DefPathData::Module(..) => true,
                            _ => false,
                        }
                    }) {
        mod_path.push_str("-");
        mod_path.push_str(&part.data.as_interned_str());
    }

    if volatile {
        mod_path.push_str(".volatile");
    }

    return token::intern_and_get_ident(&mod_path[..]);
}

fn single_codegen_unit<'a, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                                    trans_items: I,
                                    reachable: &NodeSet)
                                    -> CodegenUnit<'tcx>
    where I: Iterator<Item = TransItem<'tcx>>
{
    let mut items = FnvHashMap();

    for trans_item in trans_items {
        let linkage = trans_item.explicit_linkage(tcx).unwrap_or_else(|| {
            match trans_item {
                TransItem::Static(node_id) => {
                    if reachable.contains(&node_id) {
                        llvm::ExternalLinkage
                    } else {
                        llvm::PrivateLinkage
                    }
                }
                TransItem::DropGlue(_) => {
                    llvm::InternalLinkage
                }
                TransItem::Fn(instance) => {
                    if trans_item.is_generic_fn() {
                        // FIXME(mw): Assigning internal linkage to all
                        // monomorphizations is potentially a waste of space
                        // since monomorphizations could be shared between
                        // crates. The main reason for making them internal is
                        // a limitation in MingW's binutils that cannot deal
                        // with COFF object that have more than 2^15 sections,
                        // which is something that can happen for large programs
                        // when every function gets put into its own COMDAT
                        // section.
                        llvm::InternalLinkage
                    } else if trans_item.is_from_extern_crate() {
                        // FIXME(mw): It would be nice if we could mark these as
                        // `AvailableExternallyLinkage`, since they should have
                        // been instantiated in the extern crate. But this
                        // sometimes leads to crashes on Windows because LLVM
                        // does not handle exception handling table instantiation
                        // reliably in that case.
                        llvm::InternalLinkage
                    } else if reachable.contains(&tcx.map
                                                     .as_local_node_id(instance.def)
                                                     .unwrap()) {
                        llvm::ExternalLinkage
                    } else {
                        // Functions that are not visible outside this crate can
                        // be marked as internal.
                        llvm::InternalLinkage
                    }
                }
            }
        });

        items.insert(trans_item, linkage);
    }

    CodegenUnit::new(
        numbered_codegen_unit_name(&tcx.crate_name[..], 0),
        items)
}

fn numbered_codegen_unit_name(crate_name: &str, index: usize) -> InternedString {
    token::intern_and_get_ident(&format!("{}{}{}",
        crate_name,
        NUMBERED_CODEGEN_UNIT_MARKER,
        index)[..])
}

fn debug_dump<'a, 'b, 'tcx, I>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
                               label: &str,
                               cgus: I)
    where I: Iterator<Item=&'b CodegenUnit<'tcx>>,
          'tcx: 'a + 'b
{
    if cfg!(debug_assertions) {
        debug!("{}", label);
        for cgu in cgus {
            debug!("CodegenUnit {}:", cgu.name);

            for (trans_item, linkage) in &cgu.items {
                debug!(" - {} [{:?}]", trans_item.to_string(tcx), linkage);
            }

            debug!("");
        }
    }
}
