Commit dcd6de6d by Zdenek Dvorak Committed by Zdenek Dvorak

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
parent 0e8c2b0d
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> 2005-03-14 Uros Bizjak <uros@kss-loka.si>
PR target/17688 PR target/17688
......
...@@ -83,17 +83,22 @@ DEF_ATTR_IDENT (ATTR_GCC_DIAG, "gcc_diag") ...@@ -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_CDIAG, "gcc_cdiag")
DEF_ATTR_IDENT (ATTR_GCC_CXXDIAG, "gcc_cxxdiag") DEF_ATTR_IDENT (ATTR_GCC_CXXDIAG, "gcc_cxxdiag")
DEF_ATTR_IDENT (ATTR_PURE, "pure") DEF_ATTR_IDENT (ATTR_PURE, "pure")
DEF_ATTR_IDENT (ATTR_NOVOPS, "no vops")
DEF_ATTR_IDENT (ATTR_SCANF, "scanf") DEF_ATTR_IDENT (ATTR_SCANF, "scanf")
DEF_ATTR_IDENT (ATTR_SENTINEL, "sentinel") DEF_ATTR_IDENT (ATTR_SENTINEL, "sentinel")
DEF_ATTR_IDENT (ATTR_STRFMON, "strfmon") DEF_ATTR_IDENT (ATTR_STRFMON, "strfmon")
DEF_ATTR_IDENT (ATTR_STRFTIME, "strftime") 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_NOTHROW_LIST, ATTR_NOTHROW, ATTR_NULL, ATTR_NULL)
DEF_ATTR_TREE_LIST (ATTR_CONST_NOTHROW_LIST, ATTR_CONST, \ DEF_ATTR_TREE_LIST (ATTR_CONST_NOTHROW_LIST, ATTR_CONST, \
ATTR_NULL, ATTR_NOTHROW_LIST) ATTR_NULL, ATTR_NOTHROW_LIST)
DEF_ATTR_TREE_LIST (ATTR_PURE_NOTHROW_LIST, ATTR_PURE, \ DEF_ATTR_TREE_LIST (ATTR_PURE_NOTHROW_LIST, ATTR_PURE, \
ATTR_NULL, ATTR_NOTHROW_LIST) 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, \ DEF_ATTR_TREE_LIST (ATTR_NORETURN_NOTHROW_LIST, ATTR_NORETURN, \
ATTR_NULL, ATTR_NOTHROW_LIST) ATTR_NULL, ATTR_NOTHROW_LIST)
DEF_ATTR_TREE_LIST (ATTR_MALLOC_NOTHROW_LIST, ATTR_MALLOC, \ DEF_ATTR_TREE_LIST (ATTR_MALLOC_NOTHROW_LIST, ATTR_MALLOC, \
......
...@@ -134,7 +134,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA ...@@ -134,7 +134,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
global memory. In "unsafe" mode we can be less careful. */ global memory. In "unsafe" mode we can be less careful. */
#undef ATTR_MATHFN_FPROUNDING #undef ATTR_MATHFN_FPROUNDING
#define ATTR_MATHFN_FPROUNDING (flag_unsafe_math_optimizations ? \ #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 /* Define an attribute list for math functions that are normally
"impure" because some of them may write into global memory for "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 ...@@ -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_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_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_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, "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_RETURN_ADDRESS, "return_address", BT_FN_PTR_UINT, ATTR_NULL)
DEF_GCC_BUILTIN (BUILT_IN_SAVEREGS, "saveregs", BT_FN_PTR_VAR, 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 *); ...@@ -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, static tree handle_no_limit_stack_attribute (tree *, tree, tree, int,
bool *); bool *);
static tree handle_pure_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, static tree handle_deprecated_attribute (tree *, tree, tree, int,
bool *); bool *);
static tree handle_vector_size_attribute (tree *, tree, tree, int, static tree handle_vector_size_attribute (tree *, tree, tree, int,
...@@ -614,6 +615,10 @@ const struct attribute_spec c_common_attribute_table[] = ...@@ -614,6 +615,10 @@ const struct attribute_spec c_common_attribute_table[] =
handle_no_limit_stack_attribute }, handle_no_limit_stack_attribute },
{ "pure", 0, 0, true, false, false, { "pure", 0, 0, true, false, false,
handle_pure_attribute }, 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, { "deprecated", 0, 0, false, false, false,
handle_deprecated_attribute }, handle_deprecated_attribute },
{ "vector_size", 1, 1, false, true, false, { "vector_size", 1, 1, false, true, false,
...@@ -4854,6 +4859,19 @@ handle_pure_attribute (tree *node, tree name, tree ARG_UNUSED (args), ...@@ -4854,6 +4859,19 @@ handle_pure_attribute (tree *node, tree name, tree ARG_UNUSED (args),
return NULL_TREE; 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 /* Handle a "deprecated" attribute; arguments as in
struct attribute_spec.handler. */ struct attribute_spec.handler. */
......
...@@ -1689,6 +1689,7 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype) ...@@ -1689,6 +1689,7 @@ merge_decls (tree newdecl, tree olddecl, tree newtype, tree oldtype)
TREE_READONLY (newdecl) |= TREE_READONLY (olddecl); TREE_READONLY (newdecl) |= TREE_READONLY (olddecl);
DECL_IS_MALLOC (newdecl) |= DECL_IS_MALLOC (olddecl); DECL_IS_MALLOC (newdecl) |= DECL_IS_MALLOC (olddecl);
DECL_IS_PURE (newdecl) |= DECL_IS_PURE (olddecl); DECL_IS_PURE (newdecl) |= DECL_IS_PURE (olddecl);
DECL_IS_NOVOPS (newdecl) |= DECL_IS_NOVOPS (olddecl);
} }
/* Merge the storage class information. */ /* Merge the storage class information. */
......
...@@ -593,6 +593,9 @@ flags_from_decl_or_type (tree exp) ...@@ -593,6 +593,9 @@ flags_from_decl_or_type (tree exp)
if (DECL_IS_PURE (exp)) if (DECL_IS_PURE (exp))
flags |= ECF_PURE | ECF_LIBCALL_BLOCK; flags |= ECF_PURE | ECF_LIBCALL_BLOCK;
if (DECL_IS_NOVOPS (exp))
flags |= ECF_NOVOPS;
if (TREE_NOTHROW (exp)) if (TREE_NOTHROW (exp))
flags |= ECF_NOTHROW; flags |= ECF_NOTHROW;
......
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> 2005-03-14 Kriang Lerdsuwanakij <lerdsuwa@users.sourceforge.net>
PR c++/4403 PR c++/4403
......
/* { 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) ...@@ -1529,7 +1529,9 @@ get_call_expr_operands (tree stmt, tree expr)
computed. By not bothering with virtual operands for CALL_EXPRs computed. By not bothering with virtual operands for CALL_EXPRs
we avoid adding superfluous virtual operands, which can be a we avoid adding superfluous virtual operands, which can be a
significant compile time sink (See PR 15855). */ 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 'pure' or a 'const' functions never call clobber anything.
A 'noreturn' function might, but since we don't return anyway A 'noreturn' function might, but since we don't return anyway
......
...@@ -2185,6 +2185,11 @@ struct tree_binfo GTY (()) ...@@ -2185,6 +2185,11 @@ struct tree_binfo GTY (())
as "pure" function (like const function, but may read global memory). */ as "pure" function (like const function, but may read global memory). */
#define DECL_IS_PURE(NODE) (FUNCTION_DECL_CHECK (NODE)->decl.pure_flag) #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 /* Nonzero in a FIELD_DECL means it is a bit field, and must be accessed
specially. */ specially. */
#define DECL_BIT_FIELD(NODE) (FIELD_DECL_CHECK (NODE)->decl.bit_field_flag) #define DECL_BIT_FIELD(NODE) (FIELD_DECL_CHECK (NODE)->decl.bit_field_flag)
...@@ -2365,7 +2370,6 @@ struct tree_decl GTY(()) ...@@ -2365,7 +2370,6 @@ struct tree_decl GTY(())
unsigned uninlinable : 1; unsigned uninlinable : 1;
unsigned thread_local_flag : 1; unsigned thread_local_flag : 1;
unsigned declared_inline_flag : 1; unsigned declared_inline_flag : 1;
unsigned seen_in_bind_expr : 1;
ENUM_BITFIELD(symbol_visibility) visibility : 2; ENUM_BITFIELD(symbol_visibility) visibility : 2;
unsigned visibility_specified : 1; unsigned visibility_specified : 1;
...@@ -2383,7 +2387,9 @@ struct tree_decl GTY(()) ...@@ -2383,7 +2387,9 @@ struct tree_decl GTY(())
unsigned gimple_formal_temp : 1; unsigned gimple_formal_temp : 1;
unsigned debug_expr_is_from : 1; unsigned debug_expr_is_from : 1;
unsigned returns_twice_flag : 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 { union tree_decl_u1 {
/* In a FUNCTION_DECL for which DECL_BUILT_IN holds, this is /* In a FUNCTION_DECL for which DECL_BUILT_IN holds, this is
...@@ -3688,6 +3694,9 @@ extern rtx emit_line_note (location_t); ...@@ -3688,6 +3694,9 @@ extern rtx emit_line_note (location_t);
#define ECF_SP_DEPRESSED 256 #define ECF_SP_DEPRESSED 256
/* Create libcall block around the call. */ /* Create libcall block around the call. */
#define ECF_LIBCALL_BLOCK 512 #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 flags_from_decl_or_type (tree);
extern int call_expr_flags (tree); extern int call_expr_flags (tree);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment