From 3aee39a6ec910bde6ae9a5423b11aaaad4a1b089 Mon Sep 17 00:00:00 2001 From: Eric Holk Date: Wed, 25 Jul 2012 17:29:34 -0700 Subject: [PATCH] Add #[inline(never)], and also fixed inlining on vec::push --- src/libcore/dvec.rs | 5 +++++ src/libcore/vec.rs | 20 ++++++++++++++------ src/libstd/smallintmap.rs | 4 +++- src/libsyntax/attr.rs | 6 +++++- src/rustc/metadata/encoder.rs | 4 ++-- src/rustc/middle/trans/base.rs | 1 + 6 files changed, 30 insertions(+), 10 deletions(-) diff --git a/src/libcore/dvec.rs b/src/libcore/dvec.rs index bdbdb6cef16b..60cb1b51be68 100644 --- a/src/libcore/dvec.rs +++ b/src/libcore/dvec.rs @@ -108,6 +108,11 @@ impl private_methods for dvec { // almost nothing works without the copy bound due to limitations // around closures. impl extensions for dvec { + /// Reserves space for N elements + fn reserve(count: uint) { + vec::reserve(self.data, count) + } + /** * Swaps out the current vector and hands it off to a user-provided * function `f`. The function should transform it however is desired diff --git a/src/libcore/vec.rs b/src/libcore/vec.rs index 5aa2f35029ab..c07dd9b8224c 100644 --- a/src/libcore/vec.rs +++ b/src/libcore/vec.rs @@ -509,10 +509,7 @@ fn push(&v: ~[const T], +initval: T) { let repr: **unsafe::vec_repr = ::unsafe::reinterpret_cast(addr_of(v)); let fill = (**repr).fill; if (**repr).alloc > fill { - (**repr).fill += sys::size_of::(); - let p = ptr::addr_of((**repr).data); - let p = ptr::offset(p, fill) as *mut T; - rusti::move_val_init(*p, initval); + push_fast(v, initval); } else { push_slow(v, initval); @@ -520,9 +517,21 @@ fn push(&v: ~[const T], +initval: T) { } } +// This doesn't bother to make sure we have space. +#[inline(always)] // really pretty please +unsafe fn push_fast(&v: ~[const T], +initval: T) { + let repr: **unsafe::vec_repr = ::unsafe::reinterpret_cast(addr_of(v)); + let fill = (**repr).fill; + (**repr).fill += sys::size_of::(); + let p = ptr::addr_of((**repr).data); + let p = ptr::offset(p, fill) as *mut T; + rusti::move_val_init(*p, initval); +} + +#[inline(never)] fn push_slow(&v: ~[const T], +initval: T) { reserve_at_least(v, v.len() + 1u); - push(v, initval); + unsafe { push_fast(v, initval) } } // Unchecked vector indexing @@ -644,7 +653,6 @@ fn grow_fn(&v: ~[const T], n: uint, op: init_op) { * of the vector, expands the vector by replicating `initval` to fill the * intervening space. */ -#[inline(always)] fn grow_set(&v: ~[mut T], index: uint, initval: T, val: T) { if index >= len(v) { grow(v, index - len(v) + 1u, initval); } v[index] = val; diff --git a/src/libstd/smallintmap.rs b/src/libstd/smallintmap.rs index 112a55ab67d8..09f14f4f63e6 100644 --- a/src/libstd/smallintmap.rs +++ b/src/libstd/smallintmap.rs @@ -17,7 +17,8 @@ enum smallintmap { /// Create a smallintmap fn mk() -> smallintmap { - ret smallintmap_(@{v: dvec()}); + let v = dvec(); + ret smallintmap_(@{v: v}); } /** @@ -26,6 +27,7 @@ fn mk() -> smallintmap { */ #[inline(always)] fn insert(self: smallintmap, key: uint, val: T) { + //#error("inserting key %?", key); self.v.grow_set_elt(key, none, some(val)); } diff --git a/src/libsyntax/attr.rs b/src/libsyntax/attr.rs index 859bc70bfd64..4587a5b8b297 100644 --- a/src/libsyntax/attr.rs +++ b/src/libsyntax/attr.rs @@ -364,7 +364,8 @@ fn foreign_abi(attrs: ~[ast::attribute]) -> either<~str, ast::foreign_abi> { enum inline_attr { ia_none, ia_hint, - ia_always + ia_always, + ia_never, } /// True if something like #[inline] is found in the list of attrs. @@ -376,6 +377,9 @@ fn find_inline_attr(attrs: ~[ast::attribute]) -> inline_attr { ast::meta_list(@~"inline", items) { if !vec::is_empty(find_meta_items_by_name(items, ~"always")) { ia_always + } else if !vec::is_empty( + find_meta_items_by_name(items, ~"never")) { + ia_never } else { ia_hint } diff --git a/src/rustc/metadata/encoder.rs b/src/rustc/metadata/encoder.rs index 69e97f7e9db6..b2847b3acc53 100644 --- a/src/rustc/metadata/encoder.rs +++ b/src/rustc/metadata/encoder.rs @@ -545,8 +545,8 @@ fn purity_fn_family(p: purity) -> char { fn should_inline(attrs: ~[attribute]) -> bool { alt attr::find_inline_attr(attrs) { - attr::ia_none { false } - attr::ia_hint | attr::ia_always { true } + attr::ia_none | attr::ia_never { false } + attr::ia_hint | attr::ia_always { true } } } diff --git a/src/rustc/middle/trans/base.rs b/src/rustc/middle/trans/base.rs index 209bb6ee7c2c..94a4a30021db 100644 --- a/src/rustc/middle/trans/base.rs +++ b/src/rustc/middle/trans/base.rs @@ -456,6 +456,7 @@ fn set_inline_hint_if_appr(attrs: ~[ast::attribute], alt attr::find_inline_attr(attrs) { attr::ia_hint { set_inline_hint(llfn); } attr::ia_always { set_always_inline(llfn); } + attr::ia_never { set_no_inline(llfn); } attr::ia_none { /* fallthrough */ } } }