diff --git a/src/rustc/front/attr.rs b/src/rustc/front/attr.rs index 9a2aea625704..0a539759f72e 100644 --- a/src/rustc/front/attr.rs +++ b/src/rustc/front/attr.rs @@ -7,6 +7,7 @@ import driver::session::session; export attr_meta; export attr_metas; export find_linkage_metas; +export should_inline; export find_attrs_by_name; export attrs_contains_name; export find_meta_items_by_name; @@ -43,6 +44,11 @@ fn find_linkage_metas(attrs: [ast::attribute]) -> [@ast::meta_item] { ret metas; } +// True if something like #[inline] is found in the list of attrs. +fn should_inline(attrs: [ast::attribute]) -> bool { + attr::attrs_contains_name(attrs, "inline") +} + // Search a list of attributes and return only those with a specific name fn find_attrs_by_name(attrs: [ast::attribute], name: ast::ident) -> [ast::attribute] { diff --git a/src/rustc/metadata/encoder.rs b/src/rustc/metadata/encoder.rs index a8173d51f061..b5a10a0db486 100644 --- a/src/rustc/metadata/encoder.rs +++ b/src/rustc/metadata/encoder.rs @@ -29,10 +29,6 @@ type abbrev_map = map::hashmap; type encode_ctxt = {ccx: crate_ctxt, type_abbrevs: abbrev_map}; -fn should_inline(_path: ast_map::path, attrs: [attribute]) -> bool { - attr::attrs_contains_name(attrs, "inline") -} - // Path table encoding fn encode_name(ebml_w: ebml::writer, name: str) { ebml_w.wr_tagged_str(tag_paths_data_name, name); @@ -343,7 +339,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item, encode_type(ecx, ebml_w, node_id_to_type(tcx, item.id)); encode_symbol(ecx, ebml_w, item.id); encode_path(ebml_w, path, ast_map::path_name(item.ident)); - if should_inline(path, item.attrs) { + if attr::should_inline(item.attrs) { astencode::encode_inlined_item(ecx, ebml_w, path, ii_item(item)); } ebml_w.end_tag(); @@ -446,7 +442,7 @@ fn encode_info_for_item(ecx: @encode_ctxt, ebml_w: ebml::writer, item: @item, encode_name(ebml_w, m.ident); encode_symbol(ecx, ebml_w, m.id); encode_path(ebml_w, impl_path, ast_map::path_name(m.ident)); - if should_inline(path, m.attrs) { + if attr::should_inline(m.attrs) { astencode::encode_inlined_item( ecx, ebml_w, impl_path, ii_method(local_def(item.id), m)); diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs index d97e70172461..08a33e348f2d 100644 --- a/src/rustc/middle/trans/base.rs +++ b/src/rustc/middle/trans/base.rs @@ -646,6 +646,19 @@ fn set_uwtable(f: ValueRef) { 0u as c_uint); } +fn set_inline_hint(f: ValueRef) { + llvm::LLVMAddFunctionAttr(f, lib::llvm::InlineHintAttribute as c_uint, + 0u as c_uint); +} + +fn set_inline_hint_if_appr(ccx: crate_ctxt, + attrs: [ast::attribute], + id: ast::node_id) { + if attr::should_inline(attrs) { + set_inline_hint(ccx.item_ids.get(id)); + } +} + fn set_always_inline(f: ValueRef) { llvm::LLVMAddFunctionAttr(f, lib::llvm::AlwaysInlineAttribute as c_uint, 0u as c_uint); @@ -4696,6 +4709,8 @@ fn collect_item(ccx: crate_ctxt, abi: @mutable option, } else { native::register_crust_fn(ccx, i.span, my_path, i.id); } + + set_inline_hint_if_appr(ccx, i.attrs, i.id); } ast::item_impl(tps, _, _, methods) { let path = my_path + [path_name(int::str(i.id))]; @@ -4703,6 +4718,8 @@ fn collect_item(ccx: crate_ctxt, abi: @mutable option, register_fn(ccx, i.span, path + [path_name(m.ident)], "impl_method", tps + m.tps, m.id); + + set_inline_hint_if_appr(ccx, m.attrs, m.id); } } ast::item_res(_, tps, _, dtor_id, ctor_id) { @@ -4749,12 +4766,6 @@ fn collect_inlined_items(ccx: crate_ctxt, inline_map: inline::inline_map) { alt ii { ast::ii_item(item) { collect_item(ccx, abi, item); - alt item.node { - ast::item_fn(_, _, _) { - set_always_inline(ccx.item_ids.get(item.id)); - } - _ { /* fallthrough */ } - } } ast::ii_method(impl_did, m) { @@ -4763,6 +4774,7 @@ fn collect_inlined_items(ccx: crate_ctxt, inline_map: inline::inline_map) { let mthd_ty = ty::node_id_to_type(ccx.tcx, m.id); register_fn_full(ccx, m.span, m_path, "impl_method", m_bounds, m.id, mthd_ty); + set_inline_hint_if_appr(ccx, m.attrs, m.id); } } }