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.c37
1 files changed, 31 insertions, 6 deletions
diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c
index 236db30..01bf7f2 100644
--- a/gcc/tree-ssa-operands.c
+++ b/gcc/tree-ssa-operands.c
@@ -1465,7 +1465,10 @@ get_indirect_ref_operands (tree stmt, tree expr, int flags)
static void
get_tmr_operands (tree stmt, tree expr, int flags)
{
- tree tag = TMR_TAG (expr);
+ tree tag = TMR_TAG (expr), ref;
+ HOST_WIDE_INT offset, size, maxsize;
+ subvar_t svars, sv;
+ stmt_ann_t s_ann = stmt_ann (stmt);
/* First record the real operands. */
get_expr_operands (stmt, &TMR_BASE (expr), opf_none);
@@ -1480,11 +1483,33 @@ get_tmr_operands (tree stmt, tree expr, int flags)
add_to_addressable_set (TMR_SYMBOL (expr), &ann->addresses_taken);
}
- if (tag)
- get_expr_operands (stmt, &tag, flags);
- else
- /* Something weird, so ensure that we will be careful. */
- stmt_ann (stmt)->has_volatile_ops = true;
+ if (!tag)
+ {
+ /* Something weird, so ensure that we will be careful. */
+ stmt_ann (stmt)->has_volatile_ops = true;
+ return;
+ }
+
+ if (DECL_P (tag))
+ {
+ get_expr_operands (stmt, &tag, flags);
+ return;
+ }
+
+ ref = get_ref_base_and_extent (tag, &offset, &size, &maxsize);
+ gcc_assert (ref != NULL_TREE);
+ svars = get_subvars_for_var (ref);
+ for (sv = svars; sv; sv = sv->next)
+ {
+ bool exact;
+ if (overlap_subvar (offset, maxsize, sv, &exact))
+ {
+ int subvar_flags = flags;
+ if (!exact || size != maxsize)
+ subvar_flags &= ~opf_kill_def;
+ add_stmt_operand (&sv->var, s_ann, subvar_flags);
+ }
+ }
}
/* A subroutine of get_expr_operands to handle CALL_EXPR. */