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:
parent
0e8c2b0d43
commit
dcd6de6d69
@ -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
|
||||
|
@ -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, \
|
||||
|
@ -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)
|
||||
|
@ -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. */
|
||||
|
||||
|
@ -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. */
|
||||
|
@ -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;
|
||||
|
||||
|
@ -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
|
||||
|
21
gcc/testsuite/gcc.dg/tree-ssa/20050314-1.c
Normal file
21
gcc/testsuite/gcc.dg/tree-ssa/20050314-1.c
Normal 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" } } */
|
||||
|
@ -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
|
||||
|
13
gcc/tree.h
13
gcc/tree.h
@ -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);
|
||||
|
Loading…
Reference in New Issue
Block a user