Rollup merge of #56024 - oli-obk:const_fn_collect_inner, r=michaelwoerister

Don't auto-inline const functions

fixes #53451
This commit is contained in:
Pietro Albini 2018-11-25 17:04:57 +01:00 committed by GitHub
commit 1aa3ffaf99
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 52 additions and 33 deletions

View file

@ -173,10 +173,7 @@ impl<'tcx> InstanceDef<'tcx> {
// available to normal end-users.
return true
}
let codegen_fn_attrs = tcx.codegen_fn_attrs(self.def_id());
// need to use `is_const_fn_raw` since we don't really care if the user can use it as a
// const fn, just whether the function should be inlined
codegen_fn_attrs.requests_inline() || tcx.is_const_fn_raw(self.def_id())
tcx.codegen_fn_attrs(self.def_id()).requests_inline()
}
}

View file

@ -178,10 +178,6 @@
//! Some things are not yet fully implemented in the current version of this
//! module.
//!
//! ### Initializers of Constants and Statics
//! Since no MIR is constructed yet for initializer expressions of constants and
//! statics we cannot inspect these properly.
//!
//! ### Const Fns
//! Ideally, no mono item should be generated for const fns unless there
//! is a call to them that cannot be evaluated at compile time. At the moment
@ -191,7 +187,6 @@
use rustc::hir::{self, CodegenFnAttrFlags};
use rustc::hir::itemlikevisit::ItemLikeVisitor;
use rustc::hir::Node;
use rustc::hir::def_id::DefId;
use rustc::mir::interpret::{AllocId, ConstValue};
use rustc::middle::lang_items::{ExchangeMallocFnLangItem, StartFnLangItem};
@ -741,27 +736,27 @@ fn should_monomorphize_locally<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, instance:
ty::InstanceDef::CloneShim(..) => return true
};
return match tcx.hir.get_if_local(def_id) {
Some(Node::ForeignItem(..)) => {
false // foreign items are linked against, not codegened.
}
Some(_) => true,
None => {
if tcx.is_reachable_non_generic(def_id) ||
tcx.is_foreign_item(def_id) ||
is_available_upstream_generic(tcx, def_id, instance.substs)
{
// We can link to the item in question, no instance needed
// in this crate
false
} else {
if !tcx.is_mir_available(def_id) {
bug!("Cannot create local mono-item for {:?}", def_id)
}
true
}
}
};
if tcx.is_foreign_item(def_id) {
// We can always link to foreign items
return false;
}
if def_id.is_local() {
// local items cannot be referred to locally without monomorphizing them locally
return true;
}
if tcx.is_reachable_non_generic(def_id) ||
is_available_upstream_generic(tcx, def_id, instance.substs) {
// We can link to the item in question, no instance needed
// in this crate
return false;
}
if !tcx.is_mir_available(def_id) {
bug!("Cannot create local mono-item for {:?}", def_id)
}
return true;
fn is_available_upstream_generic<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
def_id: DefId,

View file

@ -11,11 +11,10 @@
// ignore-tidy-linelength
// compile-flags:-Zprint-mono-items=lazy
// NB: We do not expect *any* monomorphization to be generated here.
#![deny(dead_code)]
#![crate_type = "rlib"]
//~ MONO_ITEM fn unreferenced_const_fn::foo[0] @@ unreferenced_const_fn-cgu.0[External]
pub const fn foo(x: u32) -> u32 {
x + 0xf00
}

View file

@ -10,6 +10,24 @@
// Crate that exports a const fn. Used for testing cross-crate.
#![feature(const_fn)]
#![crate_type="rlib"]
pub const fn foo() -> usize { 22 } //~ ERROR const fn is unstable
pub const fn foo() -> usize { 22 }
pub const fn bar() -> fn() {
fn x() {}
x
}
#[inline]
pub const fn bar_inlined() -> fn() {
fn x() {}
x
}
#[inline(always)]
pub const fn bar_inlined_always() -> fn() {
fn x() {}
x
}

View file

@ -0,0 +1,10 @@
// compile-pass
// aux-build:const_fn_lib.rs
extern crate const_fn_lib;
fn main() {
const_fn_lib::bar()();
const_fn_lib::bar_inlined()();
const_fn_lib::bar_inlined_always()();
}