attr-alwaysinline.c: New.

2002-02-21  Aldy Hernandez  <aldyh@redhat.com>

        * gcc.dg/attr-alwaysinline.c: New.

        * c-common.c (c_common_post_options): Set inline trees by
        default.

        * doc/extend.texi (Function Attributes): Document always_inline
        attribute.
        Update documentation about inlining when not optimizing.

        * cp/decl.c (duplicate_decls): Merge always_inline attribute.

        * cp/tree.c (cp_cannot_inline_tree_fn): Do not inline at -O0
        unless DECL_ALWAYS_INLINE.

        * c-objc-common.c (c_cannot_inline_tree_fn): Do not inline at -O0
        unless DECL_ALWAYS_INLINE.
        (c_disregard_inline_limits): Disregard if always_inline set.

        * langhooks.c (lhd_tree_inlining_disregard_inline_limits):
        Disregard if always_inline set.
        (lhd_tree_inlining_cannot_inline_tree_fn): Do not inline at -O0
        unless DECL_ALWAYS_INLINE.

        * attribs.c (handle_always_inline_attribute): New.
        (c_common_attribute_table): Add always_inline.

        * config/rs6000/altivec.h: Add prototypes for builtins
        requiring the always_inline attribute.

From-SVN: r49947
This commit is contained in:
Aldy Hernandez 2002-02-22 00:09:04 +00:00 committed by Aldy Hernandez
parent c410d49e43
commit 6aa77e6c39
10 changed files with 151 additions and 11 deletions

View File

@ -1,3 +1,34 @@
2002-02-21 Aldy Hernandez <aldyh@redhat.com>
* testsuite/gcc.dg/attr-alwaysinline.c: New.
* c-common.c (c_common_post_options): Set inline trees by
default.
* doc/extend.texi (Function Attributes): Document always_inline
attribute.
Update documentation about inlining when not optimizing.
* cp/decl.c (duplicate_decls): Merge always_inline attribute.
* cp/tree.c (cp_cannot_inline_tree_fn): Do not inline at -O0
unless DECL_ALWAYS_INLINE.
* c-objc-common.c (c_cannot_inline_tree_fn): Do not inline at -O0
unless DECL_ALWAYS_INLINE.
(c_disregard_inline_limits): Disregard if always_inline set.
* langhooks.c (lhd_tree_inlining_disregard_inline_limits):
Disregard if always_inline set.
(lhd_tree_inlining_cannot_inline_tree_fn): Do not inline at -O0
unless DECL_ALWAYS_INLINE.
* attribs.c (handle_always_inline_attribute): New.
(c_common_attribute_table): Add always_inline.
* config/rs6000/altivec.h: Add prototypes for builtins
requiring the always_inline attribute.
2002-02-21 Eric Christopher <echristo@redhat.com>
* expmed.c (store_bit_field): Try to simplify the subreg

View File

@ -51,6 +51,8 @@ static tree handle_noreturn_attribute PARAMS ((tree *, tree, tree, int,
bool *));
static tree handle_noinline_attribute PARAMS ((tree *, tree, tree, int,
bool *));
static tree handle_always_inline_attribute PARAMS ((tree *, tree, tree, int,
bool *));
static tree handle_used_attribute PARAMS ((tree *, tree, tree, int,
bool *));
static tree handle_unused_attribute PARAMS ((tree *, tree, tree, int,
@ -109,6 +111,8 @@ static const struct attribute_spec c_common_attribute_table[] =
handle_noreturn_attribute },
{ "noinline", 0, 0, true, false, false,
handle_noinline_attribute },
{ "always_inline", 0, 0, true, false, false,
handle_always_inline_attribute },
{ "used", 0, 0, true, false, false,
handle_used_attribute },
{ "unused", 0, 0, false, false, false,
@ -563,6 +567,31 @@ handle_noinline_attribute (node, name, args, flags, no_add_attrs)
return NULL_TREE;
}
/* Handle a "always_inline" attribute; arguments as in
struct attribute_spec.handler. */
static tree
handle_always_inline_attribute (node, name, args, flags, no_add_attrs)
tree *node;
tree name;
tree args ATTRIBUTE_UNUSED;
int flags ATTRIBUTE_UNUSED;
bool *no_add_attrs;
{
if (TREE_CODE (*node) == FUNCTION_DECL)
{
/* Do nothing else, just set the attribute. We'll get at
it later with lookup_attribute. */
}
else
{
warning ("`%s' attribute ignored", IDENTIFIER_POINTER (name));
*no_add_attrs = true;
}
return NULL_TREE;
}
/* Handle a "used" attribute; arguments as in
struct attribute_spec.handler. */
@ -1431,3 +1460,4 @@ strip_attrs (specs_attrs)
return specs;
}

View File

@ -4109,15 +4109,14 @@ c_common_post_options ()
{
cpp_post_options (parse_in);
flag_inline_trees = 1;
/* Use tree inlining if possible. Function instrumentation is only
done in the RTL level, so we disable tree inlining. */
if (! flag_instrument_function_entry_exit)
{
if (!flag_no_inline)
{
flag_inline_trees = 1;
flag_no_inline = 1;
}
flag_no_inline = 1;
if (flag_inline_functions)
{
flag_inline_trees = 2;

View File

@ -59,6 +59,9 @@ int
c_disregard_inline_limits (fn)
tree fn;
{
if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) != NULL)
return 1;
return DECL_DECLARED_INLINE_P (fn) && DECL_EXTERNAL (fn);
}
@ -142,6 +145,10 @@ c_cannot_inline_tree_fn (fnp)
tree fn = *fnp;
tree t;
if (optimize == 0
&& lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL)
return 1;
if (! function_attribute_inlinable_p (fn))
{
DECL_UNINLINABLE (fn) = 1;

View File

@ -70,6 +70,38 @@ extern int __altivec_link_error_invalid_argument ();
#ifdef __cplusplus
/* Prototypes for builtins that take literals and must always be
inlined. */
inline vector float vec_ctf (vector unsigned int, const char) __attribute__ ((always_inline));
inline vector float vec_ctf (vector signed int, const char) __attribute__ ((always_inline));
inline vector signed int vec_cts (vector float, const char) __attribute__ ((always_inline));
inline vector unsigned int vec_ctu (vector float, const char) __attribute__ ((always_inline));
inline void vec_dss (const char) __attribute__ ((always_inline));
inline void vec_dst (void *, int, const char) __attribute__ ((always_inline));
inline void vec_dstst (void *, int, const char) __attribute__ ((always_inline));
inline void vec_dststt (void *, int, const char) __attribute__ ((always_inline));
inline void vec_dstt (void *, int, const char) __attribute__ ((always_inline));
inline vector float vec_sld (vector float, vector float, const char) __attribute__ ((always_inline));
inline vector signed int vec_sld (vector signed int, vector signed int, const char) __attribute__ ((always_inline));
inline vector unsigned int vec_sld (vector unsigned int, vector unsigned int, const char) __attribute__ ((always_inline));
inline vector signed short vec_sld (vector signed short, vector signed short, const char) __attribute__ ((always_inline));
inline vector unsigned short vec_sld (vector unsigned short, vector unsigned short, const char) __attribute__ ((always_inline));
inline vector signed char vec_sld (vector signed char, vector signed char, const char) __attribute__ ((always_inline));
inline vector unsigned char vec_sld (vector unsigned char, vector unsigned char, const char) __attribute__ ((always_inline));
inline vector signed char vec_splat (vector signed char, const char) __attribute__ ((always_inline));
inline vector unsigned char vec_splat (vector unsigned char, const char) __attribute__ ((always_inline));
inline vector signed short vec_splat (vector signed short, const char) __attribute__ ((always_inline));
inline vector unsigned short vec_splat (vector unsigned short, const char) __attribute__ ((always_inline));
inline vector float vec_splat (vector float, const char) __attribute__ ((always_inline));
inline vector signed int vec_splat (vector signed int, const char) __attribute__ ((always_inline));
inline vector unsigned int vec_splat (vector unsigned int, const char) __attribute__ ((always_inline));
inline vector signed char vec_splat_s8 (const char) __attribute__ ((always_inline));
inline vector signed short vec_splat_s16 (const char) __attribute__ ((always_inline));
inline vector signed int vec_splat_s32 (const char) __attribute__ ((always_inline));
inline vector unsigned char vec_splat_u8 (const char) __attribute__ ((always_inline));
inline vector unsigned short vec_splat_u16 (const char) __attribute__ ((always_inline));
inline vector unsigned int vec_splat_u32 (const char) __attribute__ ((always_inline));
/* vec_abs */
inline vector signed char

View File

@ -3482,6 +3482,7 @@ duplicate_decls (newdecl, olddecl)
except for any that we copy here from the old type. */
DECL_ATTRIBUTES (newdecl)
= (*targetm.merge_decl_attributes) (olddecl, newdecl);
decl_attributes (&newdecl, DECL_ATTRIBUTES (newdecl), 0);
if (TREE_CODE (newdecl) == TEMPLATE_DECL)
{

View File

@ -2099,6 +2099,10 @@ cp_cannot_inline_tree_fn (fnp)
{
tree fn = *fnp;
if (optimize == 0
&& lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) == NULL)
return 1;
/* We can inline a template instantiation only if it's fully
instantiated. */
if (DECL_TEMPLATE_INFO (fn)

View File

@ -1880,7 +1880,8 @@ The keyword @code{__attribute__} allows you to specify special
attributes when making a declaration. This keyword is followed by an
attribute specification inside double parentheses. The following
attributes are currently defined for functions on all targets:
@code{noreturn}, @code{noinline}, @code{pure}, @code{const},
@code{noreturn}, @code{noinline}, @code{always_inline},
@code{pure}, @code{const},
@code{format}, @code{format_arg}, @code{no_instrument_function},
@code{section}, @code{constructor}, @code{destructor}, @code{used},
@code{unused}, @code{deprecated}, @code{weak}, @code{malloc}, and
@ -1946,6 +1947,12 @@ volatile voidfn fatal;
This function attribute prevents a function from being considered for
inlining.
@cindex @code{always_inline} function attribute
@item always_inline
Generally, functions are not inlined unless optimization is specified.
For functions declared inline, this attribute inlines the function even
if no optimization level was specified.
@cindex @code{pure} function attribute
@item pure
Many functions have no effects except the return value and their
@ -3388,10 +3395,13 @@ existing semantics will remain available when @option{-std=gnu89} is
specified, but eventually the default will be @option{-std=gnu99} and
that will implement the C99 semantics, though it does not do so yet.)
GCC does not inline any functions when not optimizing. It is not
clear whether it is better to inline or not, in this case, but we found
that a correct implementation when not optimizing was difficult. So we
did the easy thing, and turned it off.
GCC does not inline any functions when not optimizing unless you specify
the @samp{always_inline} attribute for the function, like this:
@example
/* Prototype. */
inline void foo (const char) __attribute__((always_inline));
@end example
@node Extended Asm
@section Assembler Instructions with C Expression Operands

View File

@ -153,8 +153,12 @@ lhd_tree_inlining_walk_subtrees (tp,subtrees,func,data,htab)
int
lhd_tree_inlining_cannot_inline_tree_fn (fnp)
tree *fnp ATTRIBUTE_UNUSED;
tree *fnp;
{
if (optimize == 0
&& lookup_attribute ("always_inline", DECL_ATTRIBUTES (*fnp)) == NULL)
return 1;
return 0;
}
@ -164,8 +168,11 @@ lhd_tree_inlining_cannot_inline_tree_fn (fnp)
int
lhd_tree_inlining_disregard_inline_limits (fn)
tree fn ATTRIBUTE_UNUSED;
tree fn;
{
if (lookup_attribute ("always_inline", DECL_ATTRIBUTES (fn)) != NULL)
return 1;
return 0;
}

View File

@ -0,0 +1,19 @@
/* Test always_inline attribute, which forces inlining of functions
even at no optimization. */
/* Origin: Aldy Hernandez <aldyh@redhat.com>. */
/* { dg-do compile } */
/* { dg-options "-O0" } */
static inline int sabrina (void) __attribute__((always_inline));
static inline int sabrina (void)
{
return 13;
}
int bar (void)
{
return sabrina () + 68;
}
/* { dg-final { scan-assembler-not "sabrina" } } */