summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorrakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4>2005-03-14 16:21:16 +0000
committerrakdver <rakdver@138bc75d-0d04-0410-961f-82ee72b054a4>2005-03-14 16:21:16 +0000
commitfc09b2000b21b17f7c6ea3c27cd9e0a05912f703 (patch)
tree5260f74234c5264de982dff0fa79d5c8f864f9e6 /gcc
parent2c5d3eb17dd92800cd7cf57f329aa561f8d073cd (diff)
downloadgcc-fc09b2000b21b17f7c6ea3c27cd9e0a05912f703.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@96438 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog16
-rw-r--r--gcc/builtin-attrs.def5
-rw-r--r--gcc/builtins.def4
-rw-r--r--gcc/c-common.c18
-rw-r--r--gcc/c-decl.c1
-rw-r--r--gcc/calls.c3
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/20050314-1.c21
-rw-r--r--gcc/tree-ssa-operands.c4
-rw-r--r--gcc/tree.h13
10 files changed, 84 insertions, 5 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 04024683b7a..0d01767f7dd 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/builtin-attrs.def b/gcc/builtin-attrs.def
index bfb70521bf2..971723de695 100644
--- a/gcc/builtin-attrs.def
+++ b/gcc/builtin-attrs.def
@@ -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, \
diff --git a/gcc/builtins.def b/gcc/builtins.def
index 33617c493b6..d324e01a584 100644
--- a/gcc/builtins.def
+++ b/gcc/builtins.def
@@ -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)
diff --git a/gcc/c-common.c b/gcc/c-common.c
index d26c8b1452d..313b554249d 100644
--- a/gcc/c-common.c
+++ b/gcc/c-common.c
@@ -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. */
diff --git a/gcc/c-decl.c b/gcc/c-decl.c
index 400c6cf293b..eee7b66a7b5 100644
--- a/gcc/c-decl.c
+++ b/gcc/c-decl.c
@@ -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. */
diff --git a/gcc/calls.c b/gcc/calls.c
index d6032fc78bc..4b9e051298d 100644
--- a/gcc/calls.c
+++ b/gcc/calls.c
@@ -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;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 841c7330a6c..24dc38a4acc 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -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
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/20050314-1.c b/gcc/testsuite/gcc.dg/tree-ssa/20050314-1.c
new file mode 100644
index 00000000000..3f8cfb3f662
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/20050314-1.c
@@ -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" } } */
+
diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c
index 8db74e1fadb..2a63d0874a6 100644
--- a/gcc/tree-ssa-operands.c
+++ b/gcc/tree-ssa-operands.c
@@ -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
diff --git a/gcc/tree.h b/gcc/tree.h
index 3857ff909cc..8854b7df8fd 100644
--- a/gcc/tree.h
+++ b/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);