Skip to content

librustc: Stop exporting all cross-crate inlined functions. Shaves 800K ... #4918

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
95 changes: 75 additions & 20 deletions src/librustc/middle/trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1139,7 +1139,9 @@ pub fn trans_stmt(cx: block, s: ast::stmt) -> block {
}
}
}
ast::decl_item(i) => trans_item(cx.fcx.ccx, *i)
ast::decl_item(i) => {
trans_item(cx.fcx.ccx, *i, DontForceInternal)
}
}
}
ast::stmt_mac(*) => cx.tcx().sess.bug(~"unexpanded macro")
Expand Down Expand Up @@ -1972,26 +1974,36 @@ pub fn trans_struct_dtor(ccx: @crate_ctxt,
lldecl
}

pub fn trans_enum_def(ccx: @crate_ctxt, enum_definition: ast::enum_def,
id: ast::node_id, degen: bool,
path: @ast_map::path, vi: @~[ty::VariantInfo],
i: &mut uint) {
pub fn trans_enum_def(ccx: @crate_ctxt,
enum_definition: ast::enum_def,
id: ast::node_id,
degen: bool,
path: @ast_map::path,
vi: @~[ty::VariantInfo],
i: &mut uint,
force_internal: ForceInternalFlag) {
for vec::each(enum_definition.variants) |variant| {
let disr_val = vi[*i].disr_val;
*i += 1;

match variant.node.kind {
ast::tuple_variant_kind(ref args) if args.len() > 0 => {
let llfn = get_item_val(ccx, variant.node.id);
if force_internal == ForceInternal {
internalize_item(llfn);
}
trans_enum_variant(ccx, id, *variant, /*bad*/copy *args,
disr_val, degen, None, llfn);
}
ast::tuple_variant_kind(_) => {
// Nothing to do.
}
ast::struct_variant_kind(struct_def) => {
trans_struct_def(ccx, struct_def, path,
variant.node.id);
trans_struct_def(ccx,
struct_def,
path,
variant.node.id,
force_internal);
}
ast::enum_variant_kind(ref enum_definition) => {
trans_enum_def(ccx,
Expand All @@ -2000,13 +2012,28 @@ pub fn trans_enum_def(ccx: @crate_ctxt, enum_definition: ast::enum_def,
degen,
path,
vi,
&mut *i);
&mut *i,
force_internal);
}
}
}
}

pub fn trans_item(ccx: @crate_ctxt, item: ast::item) {
#[deriving_eq]
pub enum ForceInternalFlag {
DontForceInternal,
ForceInternal,
}

// Marks the LLVM ValueRef corresponding to the given item as internal, so
// that if it gets inlined away LLVM won't bother translating it.
pub fn internalize_item(llval: ValueRef) {
lib::llvm::SetLinkage(llval, lib::llvm::InternalLinkage);
}

pub fn trans_item(ccx: @crate_ctxt,
item: ast::item,
force_internal: ForceInternalFlag) {
let _icx = ccx.insn_ctxt("trans_item");
let path = match ccx.tcx.items.get(&item.id) {
ast_map::node_item(_, p) => p,
Expand All @@ -2017,13 +2044,19 @@ pub fn trans_item(ccx: @crate_ctxt, item: ast::item) {
ast::item_fn(ref decl, purity, ref tps, ref body) => {
if purity == ast::extern_fn {
let llfndecl = get_item_val(ccx, item.id);
if force_internal == ForceInternal {
internalize_item(llfndecl);
}
foreign::trans_foreign_fn(ccx,
vec::append(
/*bad*/copy *path,
~[path_name(item.ident)]),
decl, body, llfndecl, item.id);
} else if tps.is_empty() {
let llfndecl = get_item_val(ccx, item.id);
if force_internal == ForceInternal {
internalize_item(llfndecl);
}
trans_fn(ccx,
vec::append(/*bad*/copy *path, ~[path_name(item.ident)]),
decl, body, llfndecl, no_self, None, item.id, None);
Expand All @@ -2032,16 +2065,22 @@ pub fn trans_item(ccx: @crate_ctxt, item: ast::item) {
match stmt.node {
ast::stmt_decl(@codemap::spanned { node: ast::decl_item(i),
_ }, _) => {
trans_item(ccx, *i);
trans_item(ccx, *i, DontForceInternal);
}
_ => ()
}
}
}
}
ast::item_impl(tps, _, _, ms) => {
meth::trans_impl(ccx, /*bad*/copy *path, item.ident, ms, tps, None,
item.id);
meth::trans_impl(ccx,
/*bad*/copy *path,
item.ident,
ms,
tps,
None,
item.id,
force_internal);
}
ast::item_mod(m) => {
trans_mod(ccx, m);
Expand All @@ -2051,8 +2090,14 @@ pub fn trans_item(ccx: @crate_ctxt, item: ast::item) {
let degen = (*enum_definition).variants.len() == 1u;
let vi = ty::enum_variants(ccx.tcx, local_def(item.id));
let mut i = 0;
trans_enum_def(ccx, (*enum_definition), item.id,
degen, path, vi, &mut i);
trans_enum_def(ccx,
*enum_definition,
item.id,
degen,
path,
vi,
&mut i,
force_internal);
}
}
ast::item_const(_, expr) => consts::trans_const(ccx, expr, item.id),
Expand All @@ -2066,16 +2111,22 @@ pub fn trans_item(ccx: @crate_ctxt, item: ast::item) {
}
ast::item_struct(struct_def, tps) => {
if tps.is_empty() {
trans_struct_def(ccx, struct_def, path, item.id);
trans_struct_def(ccx,
struct_def,
path,
item.id,
DontForceInternal);
}
}
_ => {/* fall through */ }
}
}

pub fn trans_struct_def(ccx: @crate_ctxt, struct_def: @ast::struct_def,
pub fn trans_struct_def(ccx: @crate_ctxt,
struct_def: @ast::struct_def,
path: @ast_map::path,
id: ast::node_id) {
id: ast::node_id,
force_internal: ForceInternalFlag) {
// Translate the destructor.
do option::iter(&struct_def.dtor) |dtor| {
trans_struct_dtor(ccx, /*bad*/copy *path, &dtor.node.body,
Expand All @@ -2088,6 +2139,9 @@ pub fn trans_struct_def(ccx: @crate_ctxt, struct_def: @ast::struct_def,
// otherwise this is a unit-like struct.
Some(ctor_id) if struct_def.fields.len() > 0 => {
let llfndecl = get_item_val(ccx, ctor_id);
if force_internal == ForceInternal {
internalize_item(llfndecl);
}
trans_tuple_struct(ccx, /*bad*/copy struct_def.fields,
ctor_id, None, llfndecl);
}
Expand All @@ -2103,7 +2157,7 @@ pub fn trans_struct_def(ccx: @crate_ctxt, struct_def: @ast::struct_def,
pub fn trans_mod(ccx: @crate_ctxt, m: ast::_mod) {
let _icx = ccx.insn_ctxt("trans_mod");
for vec::each(m.items) |item| {
trans_item(ccx, **item);
trans_item(ccx, **item, DontForceInternal);
}
}

Expand Down Expand Up @@ -2477,8 +2531,9 @@ pub fn get_item_val(ccx: @crate_ctxt, id: ast::node_id) -> ValueRef {
ccx.sess.bug(~"get_item_val(): unexpected variant")
}
};
if !(exprt || ccx.reachable.contains_key(&id)) {
lib::llvm::SetLinkage(val, lib::llvm::InternalLinkage);
if !*ccx.sess.building_library ||
(!exprt && !ccx.reachable.contains_key(&id)) {
internalize_item(val);
}
ccx.item_vals.insert(id, val);
val
Expand Down
12 changes: 7 additions & 5 deletions src/librustc/middle/trans/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
use core::prelude::*;

use middle::astencode;
use middle::trans::base::{get_insn_ctxt};
use middle::trans::base::{ForceInternal, get_insn_ctxt, internalize_item};
use middle::trans::base::{impl_owned_self, impl_self, no_self};
use middle::trans::base::{trans_item, get_item_val, self_arg, trans_fn};
use middle::trans::common::*;
Expand Down Expand Up @@ -54,7 +54,7 @@ pub fn maybe_instantiate_inline(ccx: @crate_ctxt, fn_id: ast::def_id,
csearch::found(ast::ii_item(item)) => {
ccx.external.insert(fn_id, Some(item.id));
ccx.stats.n_inlines += 1;
if translate { trans_item(ccx, *item); }
if translate { trans_item(ccx, *item, ForceInternal); }
local_def(item.id)
}
csearch::found(ast::ii_foreign(item)) => {
Expand All @@ -64,9 +64,10 @@ pub fn maybe_instantiate_inline(ccx: @crate_ctxt, fn_id: ast::def_id,
csearch::found_parent(parent_id, ast::ii_item(item)) => {
ccx.external.insert(parent_id, Some(item.id));
let mut my_id = 0;
let vs_here;
match item.node {
ast::item_enum(_, _) => {
let vs_here = ty::enum_variants(ccx.tcx, local_def(item.id));
vs_here = ty::enum_variants(ccx.tcx, local_def(item.id));
let vs_there = ty::enum_variants(ccx.tcx, parent_id);
for vec::each2(*vs_here, *vs_there) |here, there| {
if there.id == fn_id { my_id = here.id.node; }
Expand All @@ -76,7 +77,7 @@ pub fn maybe_instantiate_inline(ccx: @crate_ctxt, fn_id: ast::def_id,
_ => ccx.sess.bug(~"maybe_instantiate_inline: item has a \
non-enum parent")
}
if translate { trans_item(ccx, *item); }
if translate { trans_item(ccx, *item, ForceInternal); }
local_def(my_id)
}
csearch::found_parent(_, _) => {
Expand All @@ -90,6 +91,7 @@ pub fn maybe_instantiate_inline(ccx: @crate_ctxt, fn_id: ast::def_id,
ty::lookup_item_type(ccx.tcx, impl_did);
if translate && (*impl_bnds).len() + mth.tps.len() == 0u {
let llfn = get_item_val(ccx, mth.id);
internalize_item(llfn);
let path = vec::append(
ty::item_path(ccx.tcx, impl_did),
~[path_name(mth.ident)]);
Expand Down Expand Up @@ -119,7 +121,7 @@ pub fn maybe_instantiate_inline(ccx: @crate_ctxt, fn_id: ast::def_id,
local_def(mth.id)
}
csearch::found(ast::ii_dtor(ref dtor, _, _, _)) => {
ccx.external.insert(fn_id, Some((*dtor).node.id));
ccx.external.insert(fn_id, Some(dtor.node.id));
local_def((*dtor).node.id)
}
}
Expand Down
14 changes: 11 additions & 3 deletions src/librustc/middle/trans/meth.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,15 +50,23 @@ for non-monomorphized methods only. Other methods will
be generated once they are invoked with specific type parameters,
see `trans::base::lval_static_fn()` or `trans::base::monomorphic_fn()`.
*/
pub fn trans_impl(ccx: @crate_ctxt, +path: path, name: ast::ident,
methods: ~[@ast::method], tps: ~[ast::ty_param],
self_ty: Option<ty::t>, id: ast::node_id) {
pub fn trans_impl(ccx: @crate_ctxt,
+path: path,
name: ast::ident,
methods: ~[@ast::method],
tps: ~[ast::ty_param],
self_ty: Option<ty::t>,
id: ast::node_id,
force_internal: ForceInternalFlag) {
let _icx = ccx.insn_ctxt("impl::trans_impl");
if tps.len() > 0u { return; }
let sub_path = vec::append_one(path, path_name(name));
for vec::each(methods) |method| {
if method.tps.len() == 0u {
let llfn = get_item_val(ccx, method.id);
if force_internal == ForceInternal {
internalize_item(llfn);
}
let path = vec::append_one(/*bad*/copy sub_path,
path_name(method.ident));

Expand Down