From 5f3fefc77dcaeb0f2ca409a7087d0e04ae2e3554 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Fri, 13 May 2016 18:14:47 -0400 Subject: [PATCH] trans: Get rid of the last potential on-demand creation of non-closure functions. --- src/librustc_trans/base.rs | 69 +----------------------------- src/librustc_trans/glue.rs | 2 +- src/librustc_trans/monomorphize.rs | 31 ++++---------- 3 files changed, 11 insertions(+), 91 deletions(-) diff --git a/src/librustc_trans/base.rs b/src/librustc_trans/base.rs index 05ae347b534..fc45d73a7ae 100644 --- a/src/librustc_trans/base.rs +++ b/src/librustc_trans/base.rs @@ -25,8 +25,6 @@ #![allow(non_camel_case_types)] -pub use self::ValueOrigin::*; - use super::CrateTranslation; use super::ModuleTranslation; @@ -1918,37 +1916,6 @@ pub fn trans_closure<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fcx.finish(bcx, fn_cleanup_debug_loc.debug_loc()); } -/// Creates an LLVM function corresponding to a source language function. -pub fn trans_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, - decl: &hir::FnDecl, - body: &hir::Block, - llfndecl: ValueRef, - param_substs: &'tcx Substs<'tcx>, - id: ast::NodeId) { - let _s = StatRecorder::new(ccx, ccx.tcx().node_path_str(id)); - debug!("trans_fn(param_substs={:?})", param_substs); - let _icx = push_ctxt("trans_fn"); - let def_id = if let Some(&def_id) = ccx.external_srcs().borrow().get(&id) { - def_id - } else { - ccx.tcx().map.local_def_id(id) - }; - let fn_ty = ccx.tcx().lookup_item_type(def_id).ty; - let fn_ty = monomorphize::apply_param_substs(ccx.tcx(), param_substs, &fn_ty); - let sig = ccx.tcx().erase_late_bound_regions(fn_ty.fn_sig()); - let sig = ccx.tcx().normalize_associated_type(&sig); - let abi = fn_ty.fn_abi(); - trans_closure(ccx, - decl, - body, - llfndecl, - Instance::new(def_id, param_substs), - id, - &sig, - abi, - closure::ClosureEnv::NotClosure); -} - pub fn trans_instance<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, instance: Instance<'tcx>) { let instance = inline::maybe_inline_instance(ccx, instance); @@ -2215,46 +2182,14 @@ pub fn llvm_linkage_by_name(name: &str) -> Option { } } - -/// Enum describing the origin of an LLVM `Value`, for linkage purposes. -#[derive(Copy, Clone)] -pub enum ValueOrigin { - /// The LLVM `Value` is in this context because the corresponding item was - /// assigned to the current compilation unit. - OriginalTranslation, - /// The `Value`'s corresponding item was assigned to some other compilation - /// unit, but the `Value` was translated in this context anyway because the - /// item is marked `#[inline]`. - InlinedCopy, -} - /// Set the appropriate linkage for an LLVM `ValueRef` (function or global). /// If the `llval` is the direct translation of a specific Rust item, `id` /// should be set to the `NodeId` of that item. (This mapping should be /// 1-to-1, so monomorphizations and drop/visit glue should have `id` set to -/// `None`.) `llval_origin` indicates whether `llval` is the translation of an -/// item assigned to `ccx`'s compilation unit or an inlined copy of an item -/// assigned to a different compilation unit. +/// `None`.) pub fn update_linkage(ccx: &CrateContext, llval: ValueRef, - id: Option, - llval_origin: ValueOrigin) { - match llval_origin { - InlinedCopy => { - // `llval` is a translation of an item defined in a separate - // compilation unit. This only makes sense if there are at least - // two compilation units. - assert!(ccx.sess().opts.cg.codegen_units > 1 || - ccx.sess().opts.debugging_opts.incremental.is_some()); - // `llval` is a copy of something defined elsewhere, so use - // `AvailableExternallyLinkage` to avoid duplicating code in the - // output. - llvm::SetLinkage(llval, llvm::AvailableExternallyLinkage); - return; - }, - OriginalTranslation => {}, - } - + id: Option) { if let Some(id) = id { let item = ccx.tcx().map.get(id); if let hir_map::NodeItem(i) = item { diff --git a/src/librustc_trans/glue.rs b/src/librustc_trans/glue.rs index ac23d713d27..e4519ff82a0 100644 --- a/src/librustc_trans/glue.rs +++ b/src/librustc_trans/glue.rs @@ -285,7 +285,7 @@ fn get_drop_glue_core<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, let bcx = fcx.init(false, None); - update_linkage(ccx, llfn, None, OriginalTranslation); + update_linkage(ccx, llfn, None); ccx.stats().n_glues_created.set(ccx.stats().n_glues_created.get() + 1); // All glue functions take values passed *by alias*; this is a diff --git a/src/librustc_trans/monomorphize.rs b/src/librustc_trans/monomorphize.rs index 13d6d432422..832acfe14be 100644 --- a/src/librustc_trans/monomorphize.rs +++ b/src/librustc_trans/monomorphize.rs @@ -17,7 +17,6 @@ use rustc::ty::subst::{Subst, Substs}; use rustc::ty::{self, Ty, TypeFoldable, TyCtxt}; use attributes; use base::{push_ctxt}; -use base::trans_fn; use base; use common::*; use declare; @@ -27,17 +26,16 @@ use rustc::util::ppaux; use rustc::hir; -use syntax::attr; use errors; use std::fmt; +use trans_item::TransItem; pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, fn_id: DefId, psubsts: &'tcx subst::Substs<'tcx>) -> (ValueRef, Ty<'tcx>) { debug!("monomorphic_fn(fn_id={:?}, real_substs={:?})", fn_id, psubsts); - assert!(!psubsts.types.needs_infer() && !psubsts.types.has_param_types()); let _icx = push_ctxt("monomorphic_fn"); @@ -53,6 +51,8 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, if let Some(&val) = ccx.instances().borrow().get(&instance) { debug!("leaving monomorphic fn {:?}", instance); return (val, mono_ty); + } else { + assert!(!ccx.codegen_unit().items.contains_key(&TransItem::Fn(instance))); } debug!("monomorphic_fn({:?})", instance); @@ -96,6 +96,7 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, ccx.instances().borrow_mut().insert(instance, lldecl); + // we can only monomorphize things in this crate (or inlined into it) let fn_node_id = ccx.tcx().map.as_local_node_id(fn_id).unwrap(); let map_node = errors::expect( @@ -110,34 +111,18 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, match map_node { hir_map::NodeItem(&hir::Item { ref attrs, - node: hir::ItemFn(ref decl, _, _, _, _, ref body), .. + node: hir::ItemFn(..), .. }) | hir_map::NodeImplItem(&hir::ImplItem { ref attrs, node: hir::ImplItemKind::Method( - hir::MethodSig { ref decl, .. }, ref body), .. + hir::MethodSig { .. }, _), .. }) | hir_map::NodeTraitItem(&hir::TraitItem { ref attrs, node: hir::MethodTraitItem( - hir::MethodSig { ref decl, .. }, Some(ref body)), .. + hir::MethodSig { .. }, Some(_)), .. }) => { attributes::from_fn_attrs(ccx, attrs, lldecl); - - let is_first = !ccx.available_monomorphizations().borrow() - .contains(&symbol); - if is_first { - ccx.available_monomorphizations().borrow_mut().insert(symbol.clone()); - } - - let trans_everywhere = attr::requests_inline(attrs); - if trans_everywhere || is_first { - let origin = if is_first { base::OriginalTranslation } else { base::InlinedCopy }; - base::update_linkage(ccx, lldecl, None, origin); - trans_fn(ccx, decl, body, lldecl, psubsts, fn_node_id); - } else { - // We marked the value as using internal linkage earlier, but that is illegal for - // declarations, so switch back to external linkage. - llvm::SetLinkage(lldecl, llvm::ExternalLinkage); - } + llvm::SetLinkage(lldecl, llvm::ExternalLinkage); } hir_map::NodeVariant(_) | hir_map::NodeStructCtor(_) => {