diff options
Diffstat (limited to 'gcc/tree-ssa-operands.c')
-rw-r--r-- | gcc/tree-ssa-operands.c | 37 |
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. */ |