From d8db15c50d28073d3d32381ae0a99aafba54a1ef Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Sun, 19 Aug 2018 08:47:57 -0700 Subject: [PATCH] Make `codegen_fn_attrs` query cheap to clone This is an attempt to recover a perf loss observed in #52993 by making the result of the `codegen_fn_attrs` query cheap to clone as more and more parts of the compiler start to use this query. --- src/librustc/middle/reachable.rs | 8 ++++---- src/librustc/ty/query/mod.rs | 2 +- src/librustc_codegen_llvm/attributes.rs | 8 ++++++-- src/librustc_typeck/collect.rs | 5 +++-- 4 files changed, 14 insertions(+), 9 deletions(-) diff --git a/src/librustc/middle/reachable.rs b/src/librustc/middle/reachable.rs index a09942258e22d..9d8ee98e91bdf 100644 --- a/src/librustc/middle/reachable.rs +++ b/src/librustc/middle/reachable.rs @@ -51,7 +51,7 @@ fn generics_require_inlining(generics: &ty::Generics) -> bool { // true for functions. fn item_might_be_inlined(tcx: TyCtxt<'a, 'tcx, 'tcx>, item: &hir::Item, - attrs: CodegenFnAttrs) -> bool { + attrs: &CodegenFnAttrs) -> bool { if attrs.requests_inline() { return true } @@ -77,7 +77,7 @@ fn method_might_be_inlined<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, if let Some(impl_node_id) = tcx.hir.as_local_node_id(impl_src) { match tcx.hir.find(impl_node_id) { Some(hir_map::NodeItem(item)) => - item_might_be_inlined(tcx, &item, codegen_fn_attrs), + item_might_be_inlined(tcx, &item, &codegen_fn_attrs), Some(..) | None => span_bug!(impl_item.span, "impl did is not an item") } @@ -171,7 +171,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { Some(hir_map::NodeItem(item)) => { match item.node { hir::ItemKind::Fn(..) => - item_might_be_inlined(self.tcx, &item, self.tcx.codegen_fn_attrs(def_id)), + item_might_be_inlined(self.tcx, &item, &self.tcx.codegen_fn_attrs(def_id)), _ => false, } } @@ -264,7 +264,7 @@ impl<'a, 'tcx> ReachableContext<'a, 'tcx> { let def_id = self.tcx.hir.local_def_id(item.id); if item_might_be_inlined(self.tcx, &item, - self.tcx.codegen_fn_attrs(def_id)) { + &self.tcx.codegen_fn_attrs(def_id)) { self.visit_nested_body(body); } } diff --git a/src/librustc/ty/query/mod.rs b/src/librustc/ty/query/mod.rs index ef22ebef9d7d4..84410f587a70a 100644 --- a/src/librustc/ty/query/mod.rs +++ b/src/librustc/ty/query/mod.rs @@ -321,7 +321,7 @@ define_queries! { <'tcx> }, Codegen { - [] fn codegen_fn_attrs: codegen_fn_attrs(DefId) -> CodegenFnAttrs, + [] fn codegen_fn_attrs: codegen_fn_attrs(DefId) -> Lrc, }, Other { diff --git a/src/librustc_codegen_llvm/attributes.rs b/src/librustc_codegen_llvm/attributes.rs index 2b64642b766ab..f047673567cff 100644 --- a/src/librustc_codegen_llvm/attributes.rs +++ b/src/librustc_codegen_llvm/attributes.rs @@ -139,8 +139,12 @@ pub fn from_fn_attrs( llfn: &'ll Value, id: Option, ) { - let codegen_fn_attrs = id.map(|id| cx.tcx.codegen_fn_attrs(id)) - .unwrap_or(CodegenFnAttrs::new()); + let codegen_fn_attrs = id.map(|id| cx.tcx.codegen_fn_attrs(id)); + let default = CodegenFnAttrs::new(); + let codegen_fn_attrs = codegen_fn_attrs + .as_ref() + .map(|s| &**s) + .unwrap_or(&default); inline(llfn, codegen_fn_attrs.inline); diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 02f431dccca6b..eceb298d9cdd8 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -39,6 +39,7 @@ use rustc::ty::util::Discr; use rustc::util::captures::Captures; use rustc::util::nodemap::FxHashMap; use rustc_target::spec::abi; +use rustc_data_structures::sync::Lrc; use syntax::ast; use syntax::ast::MetaItemKind; @@ -1979,7 +1980,7 @@ fn linkage_by_name<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId, name: & } } -fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> CodegenFnAttrs { +fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Lrc { let attrs = tcx.get_attrs(id); let mut codegen_fn_attrs = CodegenFnAttrs::new(); @@ -2096,5 +2097,5 @@ fn codegen_fn_attrs<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> Codegen } } - codegen_fn_attrs + Lrc::new(codegen_fn_attrs) }