aboutsummaryrefslogtreecommitdiff
path: root/gcc/tree-ssa-operands.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/tree-ssa-operands.c')
-rw-r--r--gcc/tree-ssa-operands.c48
1 files changed, 42 insertions, 6 deletions
diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c
index 5d5f6ba..62bb8c9 100644
--- a/gcc/tree-ssa-operands.c
+++ b/gcc/tree-ssa-operands.c
@@ -1452,6 +1452,7 @@ get_expr_operands (tree stmt, tree *expr_p, int flags)
case TRUTH_XOR_EXPR:
case COMPOUND_EXPR:
case OBJ_TYPE_REF:
+ case ASSERT_EXPR:
do_binary:
{
tree op0 = TREE_OPERAND (expr, 0);
@@ -1735,7 +1736,7 @@ get_call_expr_operands (tree stmt, tree expr)
&& !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' function never call-clobbers anything.
A 'noreturn' function might, but since we don't return anyway
there is no point in recording that. */
if (TREE_SIDE_EFFECTS (expr)
@@ -1798,6 +1799,24 @@ add_stmt_operand (tree *var_p, stmt_ann_t s_ann, int flags)
if (TREE_THIS_VOLATILE (sym) && s_ann)
s_ann->has_volatile_ops = true;
+ /* If the variable cannot be modified and this is a V_MAY_DEF change
+ it into a VUSE. This happens when read-only variables are marked
+ call-clobbered and/or aliased to writeable variables. So we only
+ check that this only happens on stores, and not writes to GIMPLE
+ registers.
+
+ FIXME: The C++ FE is emitting assignments in the IL stream for
+ read-only globals. This is wrong, but for the time being disable
+ this transformation on V_MUST_DEF operands (otherwise, we
+ mis-optimize SPEC2000's eon). */
+ if ((flags & opf_is_def)
+ && !(flags & opf_kill_def)
+ && unmodifiable_var_p (var))
+ {
+ gcc_assert (!is_real_op);
+ flags &= ~opf_is_def;
+ }
+
if (is_real_op)
{
/* The variable is a GIMPLE register. Add it to real operands. */
@@ -1858,17 +1877,35 @@ add_stmt_operand (tree *var_p, stmt_ann_t s_ann, int flags)
if (flags & opf_is_def)
{
+ bool added_may_defs_p = false;
+
/* If the variable is also an alias tag, add a virtual
operand for it, otherwise we will miss representing
references to the members of the variable's alias set.
This fixes the bug in gcc.c-torture/execute/20020503-1.c. */
if (v_ann->is_alias_tag)
- append_v_may_def (var);
+ {
+ added_may_defs_p = true;
+ append_v_may_def (var);
+ }
for (i = 0; i < VARRAY_ACTIVE_SIZE (aliases); i++)
- append_v_may_def (VARRAY_TREE (aliases, i));
+ {
+ /* While VAR may be modifiable, some of its aliases
+ may not be. If that's the case, we don't really
+ need to add them a V_MAY_DEF for them. */
+ tree alias = VARRAY_TREE (aliases, i);
+
+ if (unmodifiable_var_p (alias))
+ append_vuse (alias);
+ else
+ {
+ append_v_may_def (alias);
+ added_may_defs_p = true;
+ }
+ }
- if (s_ann)
+ if (s_ann && added_may_defs_p)
s_ann->makes_aliased_stores = 1;
}
else
@@ -2000,8 +2037,7 @@ add_call_clobber_ops (tree stmt)
EXECUTE_IF_SET_IN_BITMAP (call_clobbered_vars, 0, i, bi)
{
tree var = referenced_var (i);
- if (TREE_READONLY (var)
- && (TREE_STATIC (var) || DECL_EXTERNAL (var)))
+ if (unmodifiable_var_p (var))
add_stmt_operand (&var, &empty_ann, opf_none);
else
add_stmt_operand (&var, &empty_ann, opf_is_def);