Skip to content
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

use available_externally linkage for cross-crate inlined functions #16270

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
9 changes: 5 additions & 4 deletions src/librustc/metadata/encoder.rs
Original file line number Diff line number Diff line change
Expand Up @@ -810,7 +810,8 @@ fn encode_info_for_method(ecx: &EncodeContext,
encode_inlined_item(ecx, rbml_w,
IIMethodRef(local_def(parent_id), false,
&*ast_method));
} else {
}
if !any_types {
encode_symbol(ecx, rbml_w, m.def_id.node);
}
encode_method_argument_names(rbml_w, &*ast_method.pe_fn_decl());
Expand Down Expand Up @@ -965,7 +966,8 @@ fn encode_info_for_item(ecx: &EncodeContext,
encode_attributes(rbml_w, item.attrs.as_slice());
if tps_len > 0u || should_inline(item.attrs.as_slice()) {
encode_inlined_item(ecx, rbml_w, IIItemRef(item));
} else {
}
if tps_len == 0 {
encode_symbol(ecx, rbml_w, item.id);
}
encode_visibility(rbml_w, vis);
Expand Down Expand Up @@ -1291,9 +1293,8 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext,
encode_name(rbml_w, nitem.ident.name);
if abi == abi::RustIntrinsic {
encode_inlined_item(ecx, rbml_w, IIForeignRef(nitem));
} else {
encode_symbol(ecx, rbml_w, nitem.id);
}
encode_symbol(ecx, rbml_w, nitem.id);
}
ForeignItemStatic(_, mutbl) => {
if mutbl {
Expand Down
19 changes: 9 additions & 10 deletions src/librustc/middle/trans/base.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2311,6 +2311,14 @@ pub fn create_entry_wrapper(ccx: &CrateContext,

fn exported_name(ccx: &CrateContext, id: ast::NodeId,
ty: ty::t, attrs: &[ast::Attribute]) -> String {
match ccx.external_srcs.borrow().find(&id) {
Some(&did) => {
debug!("found item in other crate...");
return csearch::get_symbol(&ccx.sess().cstore, did)
}
None => {}
}

match attr::first_attr_value_str_by_name(attrs, "export_name") {
// Use provided name
Some(name) => name.get().to_string(),
Expand Down Expand Up @@ -2354,16 +2362,7 @@ pub fn get_item_val(ccx: &CrateContext, id: ast::NodeId) -> ValueRef {
// using the current crate's name/version
// information in the hash of the symbol
debug!("making {}", sym);
let (sym, is_local) = {
match ccx.external_srcs.borrow().find(&i.id) {
Some(&did) => {
debug!("but found in other crate...");
(csearch::get_symbol(&ccx.sess().cstore,
did), false)
}
None => (sym, true)
}
};
let is_local = !ccx.external_srcs.borrow().contains_key(&id);

// We need the translated value here, because for enums the
// LLVM type is not fully determined by the Rust type.
Expand Down
65 changes: 42 additions & 23 deletions src/librustc/middle/trans/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use llvm::{AvailableExternallyLinkage, SetLinkage};
use llvm::{AvailableExternallyLinkage, InternalLinkage, SetLinkage};
use metadata::csearch;
use middle::astencode;
use middle::trans::base::{push_ctxt, trans_item, get_item_val, trans_fn};
Expand Down Expand Up @@ -53,26 +53,44 @@ pub fn maybe_instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
ccx.stats.n_inlines.set(ccx.stats.n_inlines.get() + 1);
trans_item(ccx, &*item);

// We're bringing an external global into this crate, but we don't
// want to create two copies of the global. If we do this, then if
// you take the address of the global in two separate crates you get
// two different addresses. This is bad for things like conditions,
// but it could possibly have other adverse side effects. We still
// want to achieve the optimizations related to this global,
// however, so we use the available_externally linkage which llvm
// provides
match item.node {
let linkage = match item.node {
ast::ItemFn(_, _, _, ref generics, _) => {
if generics.is_type_parameterized() {
// Generics have no symbol, so they can't be given any
// linkage.
None
} else {
// Use available_externally when possible. This allows
// LLVM to inline the function into its callers, but
// doesn't produce duplicate code if LLVM chooses not
// to inline at some call sites.
Some(AvailableExternallyLinkage)
}
}
ast::ItemStatic(_, mutbl, _) => {
let g = get_item_val(ccx, item.id);
// see the comment in get_item_val() as to why this check is
// performed here.
if ast_util::static_has_significant_address(
mutbl,
item.attrs.as_slice()) {
SetLinkage(g, AvailableExternallyLinkage);
if !ast_util::static_has_significant_address(mutbl, item.attrs.as_slice()) {
// Inlined static items use internal linkage when
// possible, so that LLVM will coalesce globals with
// identical initializers. (It only does this for
// globals with unnamed_addr and either internal or
// private linkage.)
Some(InternalLinkage)
} else {
// The address is significant, so we can't create an
// internal copy of the static. (The copy would have a
// different address from the original.)
Some(AvailableExternallyLinkage)
}
}
_ => {}
_ => unreachable!(),
};

match linkage {
Some(linkage) => {
let g = get_item_val(ccx, item.id);
SetLinkage(g, linkage);
}
None => {}
}

local_def(item.id)
Expand Down Expand Up @@ -130,12 +148,13 @@ pub fn maybe_instantiate_inline(ccx: &CrateContext, fn_id: ast::DefId)
impl_tpt.generics.types.is_empty() &&
mth.pe_generics().ty_params.is_empty();

if unparameterized {
let llfn = get_item_val(ccx, mth.id);
if unparameterized {
let llfn = get_item_val(ccx, mth.id);
trans_fn(ccx, &*mth.pe_fn_decl(), &*mth.pe_body(), llfn,
&param_substs::empty(), mth.id, [], TranslateItems);
}
local_def(mth.id)
&param_substs::empty(), mth.id, [], TranslateItems);
SetLinkage(llfn, AvailableExternallyLinkage);
}
local_def(mth.id)
}
};
}