builtin-attrs.def (ATTR_NOVOPS, [...]): New.

* builtin-attrs.def (ATTR_NOVOPS, ATTR_NOVOPS_LIST,
	ATTR_PURE_NOTHROW_NOVOPS_LIST): New.
	* builtins.def (ATTR_MATHFN_FPROUNDING): Use NOVOPS.
	(BUILT_IN_PREFETCH): Set the NOVOPS attribute.
	* c-common.c (handle_novops_attribute): New function.
	(c_common_attribute_table): Add "no vops" entry.
	* c-decl.c (merge_decls): Copy DECL_IS_NOVOPS.
	* calls.c (flags_from_decl_or_type): Set ECF_NOVOPS.
	* tree-ssa-operands.c (get_call_expr_operands): Do not
	create virtual operands for calls with ECF_NOVOPS flag.
	* tree.h (DECL_IS_NOVOPS): New macro.
	(struct tree_decl): Add novops_flag.
	(ECF_NOVOPS): New constant.

From-SVN: r96438
This commit is contained in:
Zdenek Dvorak 2005-03-14 17:21:16 +01:00 committed by Zdenek Dvorak
parent 0e8c2b0d43
commit dcd6de6d69
10 changed files with 84 additions and 5 deletions

View File

@ -1,3 +1,19 @@
2005-03-14 Zdenek Dvorak <dvorakz@suse.cz>
* builtin-attrs.def (ATTR_NOVOPS, ATTR_NOVOPS_LIST,
ATTR_PURE_NOTHROW_NOVOPS_LIST): New.
* builtins.def (ATTR_MATHFN_FPROUNDING): Use NOVOPS.
(BUILT_IN_PREFETCH): Set the NOVOPS attribute.
* c-common.c (handle_novops_attribute): New function.
(c_common_attribute_table): Add "no vops" entry.
* c-decl.c (merge_decls): Copy DECL_IS_NOVOPS.
* calls.c (flags_from_decl_or_type): Set ECF_NOVOPS.
* tree-ssa-operands.c (get_call_expr_operands): Do not
create virtual operands for calls with ECF_NOVOPS flag.
* tree.h (DECL_IS_NOVOPS): New macro.
(struct tree_decl): Add novops_flag.
(ECF_NOVOPS): New constant.
2005-03-14 Uros Bizjak <uros@kss-loka.si>
PR target/17688

View File

@ -83,17 +83,22 @@ DEF_ATTR_IDENT (ATTR_GCC_DIAG, "gcc_diag")
DEF_ATTR_IDENT (ATTR_GCC_CDIAG, "gcc_cdiag")
DEF_ATTR_IDENT (ATTR_GCC_CXXDIAG, "gcc_cxxdiag")
DEF_ATTR_IDENT (ATTR_PURE, "pure")
DEF_ATTR_IDENT (ATTR_NOVOPS, "no vops")
DEF_ATTR_IDENT (ATTR_SCANF, "scanf")
DEF_ATTR_IDENT (ATTR_SENTINEL, "sentinel")
DEF_ATTR_IDENT (ATTR_STRFMON, "strfmon")
DEF_ATTR_IDENT (ATTR_STRFTIME, "strftime")
DEF_ATTR_TREE_LIST (ATTR_NOVOPS_LIST, ATTR_NOVOPS, ATTR_NULL, ATTR_NULL)
DEF_ATTR_TREE_LIST (ATTR_NOTHROW_LIST, ATTR_NOTHROW, ATTR_NULL, ATTR_NULL)
DEF_ATTR_TREE_LIST (ATTR_CONST_NOTHROW_LIST, ATTR_CONST, \
ATTR_NULL, ATTR_NOTHROW_LIST)
DEF_ATTR_TREE_LIST (ATTR_PURE_NOTHROW_LIST, ATTR_PURE, \
ATTR_NULL, ATTR_NOTHROW_LIST)
DEF_ATTR_TREE_LIST (ATTR_PURE_NOTHROW_NOVOPS_LIST, ATTR_NOVOPS, \
ATTR_NULL, ATTR_PURE_NOTHROW_LIST)
DEF_ATTR_TREE_LIST (ATTR_NORETURN_NOTHROW_LIST, ATTR_NORETURN, \
ATTR_NULL, ATTR_NOTHROW_LIST)
DEF_ATTR_TREE_LIST (ATTR_MALLOC_NOTHROW_LIST, ATTR_MALLOC, \

View File

@ -134,7 +134,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
global memory. In "unsafe" mode we can be less careful. */
#undef ATTR_MATHFN_FPROUNDING
#define ATTR_MATHFN_FPROUNDING (flag_unsafe_math_optimizations ? \
ATTR_CONST_NOTHROW_LIST : ATTR_PURE_NOTHROW_LIST)
ATTR_CONST_NOTHROW_LIST : ATTR_PURE_NOTHROW_NOVOPS_LIST)
/* Define an attribute list for math functions that are normally
"impure" because some of them may write into global memory for
@ -612,7 +612,7 @@ DEF_GCC_BUILTIN (BUILT_IN_POPCOUNT, "popcount", BT_FN_INT_UINT, ATTR_CONS
DEF_GCC_BUILTIN (BUILT_IN_POPCOUNTIMAX, "popcountimax", BT_FN_INT_UINTMAX, ATTR_CONST_NOTHROW_LIST)
DEF_GCC_BUILTIN (BUILT_IN_POPCOUNTL, "popcountl", BT_FN_INT_ULONG, ATTR_CONST_NOTHROW_LIST)
DEF_GCC_BUILTIN (BUILT_IN_POPCOUNTLL, "popcountll", BT_FN_INT_ULONGLONG, ATTR_CONST_NOTHROW_LIST)
DEF_GCC_BUILTIN (BUILT_IN_PREFETCH, "prefetch", BT_FN_VOID_CONST_PTR_VAR, ATTR_NULL)
DEF_GCC_BUILTIN (BUILT_IN_PREFETCH, "prefetch", BT_FN_VOID_CONST_PTR_VAR, ATTR_NOVOPS_LIST)
DEF_GCC_BUILTIN (BUILT_IN_RETURN, "return", BT_FN_VOID_PTR, ATTR_NORETURN_NOTHROW_LIST)
DEF_GCC_BUILTIN (BUILT_IN_RETURN_ADDRESS, "return_address", BT_FN_PTR_UINT, ATTR_NULL)
DEF_GCC_BUILTIN (BUILT_IN_SAVEREGS, "saveregs", BT_FN_PTR_VAR, ATTR_NULL)

View File

@ -541,6 +541,7 @@ static tree handle_returns_twice_attribute (tree *, tree, tree, int, bool *);
static tree handle_no_limit_stack_attribute (tree *, tree, tree, int,
bool *);
static tree handle_pure_attribute (tree *, tree, tree, int, bool *);
static tree handle_novops_attribute (tree *, tree, tree, int, bool *);
static tree handle_deprecated_attribute (tree *, tree, tree, int,
bool *);
static tree handle_vector_size_attribute (tree *, tree, tree, int,
@ -614,6 +615,10 @@ const struct attribute_spec c_common_attribute_table[] =
handle_no_limit_stack_attribute },
{ "pure", 0, 0, true, false, false,
handle_pure_attribute },
/* For internal use (marking of builtins) only. The name contains space
to prevent its usage in source code. */
{ "no vops", 0, 0, true, false, false,
handle_novops_attribute },
{ "deprecated", 0, 0, false, false, false,
handle_deprecated_attribute },
{ "vector_size", 1, 1, false, true, false,
@ -4854,6 +4859,19 @@ handle_pure_attribute (tree *node, tree name, tree ARG_UNUSED (args),
return NULL_TREE;
}
/* Handle a "no vops" attribute; arguments as in
struct attribute_spec.handler. */
static tree
handle_novops_attribute (tree *node, tree ARG_UNUSED (name),
tree ARG_UNUSED (args), int ARG_UNUSED (flags),
bool *ARG_UNUSED (no_add_attrs))
{
gcc_assert (TREE_CODE (*node) == FUNCTION_DECL);
DECL_IS_NOVOPS (*node) = 1;
return NULL_TREE;
}
/* Handle a "deprecated" attribute; arguments as in
struct attribute_spec.handler. */

View File

@ -1689,6 +1689,7 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
TREE_READONLY (newdecl) |= TREE_READONLY (olddecl);
DECL_IS_MALLOC (newdecl) |= DECL_IS_MALLOC (olddecl);
DECL_IS_PURE (newdecl) |= DECL_IS_PURE (olddecl);
DECL_IS_NOVOPS (newdecl) |= DECL_IS_NOVOPS (olddecl);
}
/* Merge the storage class information. */

View File

@ -593,6 +593,9 @@ flags_from_decl_or_type (tree exp)
if (DECL_IS_PURE (exp))
flags |= ECF_PURE | ECF_LIBCALL_BLOCK;
if (DECL_IS_NOVOPS (exp))
flags |= ECF_NOVOPS;
if (TREE_NOTHROW (exp))
flags |= ECF_NOTHROW;

View File

@ -1,3 +1,7 @@
2005-03-14 Zdenek Dvorak <dvorakz@suse.cz>
* gcc.dg/tree-ssa/20050314-1.c: New test.
2005-03-14 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
PR c++/4403

View File

@ -0,0 +1,21 @@
/* { dg-do compile } */
/* { dg-options "-O1 -fdump-tree-lim-details" } */
float a[100];
int foo(void);
float sinf (float);
void xxx (void)
{
int i, k = foo ();
for (i = 0; i < 100; i++)
a[k] += sinf (i);
}
/* Store motion may be applied to the assignment to a[k], since sinf
cannot read nor write the memory. */
/* { dg-final { scan-tree-dump-times "Moving statement" 1 "lim" } } */

View File

@ -1529,7 +1529,9 @@ get_call_expr_operands (tree stmt, tree expr)
computed. By not bothering with virtual operands for CALL_EXPRs
we avoid adding superfluous virtual operands, which can be a
significant compile time sink (See PR 15855). */
if (aliases_computed_p && !bitmap_empty_p (call_clobbered_vars))
if (aliases_computed_p
&& !bitmap_empty_p (call_clobbered_vars)
&& !(call_flags & ECF_NOVOPS))
{
/* A 'pure' or a 'const' functions never call clobber anything.
A 'noreturn' function might, but since we don't return anyway

View File

@ -2185,6 +2185,11 @@ struct tree_binfo GTY (())
as "pure" function (like const function, but may read global memory). */
#define DECL_IS_PURE(NODE) (FUNCTION_DECL_CHECK (NODE)->decl.pure_flag)
/* Nonzero in a FUNCTION_DECL means this function should be treated
as "novops" function (function that does not read global memory,
but may have arbitrary side effects). */
#define DECL_IS_NOVOPS(NODE) (FUNCTION_DECL_CHECK (NODE)->decl.novops_flag)
/* Nonzero in a FIELD_DECL means it is a bit field, and must be accessed
specially. */
#define DECL_BIT_FIELD(NODE) (FIELD_DECL_CHECK (NODE)->decl.bit_field_flag)
@ -2365,7 +2370,6 @@ struct tree_decl GTY(())
unsigned uninlinable : 1;
unsigned thread_local_flag : 1;
unsigned declared_inline_flag : 1;
unsigned seen_in_bind_expr : 1;
ENUM_BITFIELD(symbol_visibility) visibility : 2;
unsigned visibility_specified : 1;
@ -2383,7 +2387,9 @@ struct tree_decl GTY(())
unsigned gimple_formal_temp : 1;
unsigned debug_expr_is_from : 1;
unsigned returns_twice_flag : 1;
/* 11 unused bits. */
unsigned seen_in_bind_expr : 1;
unsigned novops_flag : 1;
/* 9 unused bits. */
union tree_decl_u1 {
/* In a FUNCTION_DECL for which DECL_BUILT_IN holds, this is
@ -3688,6 +3694,9 @@ extern rtx emit_line_note (location_t);
#define ECF_SP_DEPRESSED 256
/* Create libcall block around the call. */
#define ECF_LIBCALL_BLOCK 512
/* Function does not read or write memory (but may have side effects, so
it does not necessarily fit ECF_CONST). */
#define ECF_NOVOPS 1024
extern int flags_from_decl_or_type (tree);
extern int call_expr_flags (tree);