diff options
Diffstat (limited to 'gcc/tree-ssa-operands.c')
-rw-r--r-- | gcc/tree-ssa-operands.c | 41 |
1 files changed, 27 insertions, 14 deletions
diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c index 94a83d0184b..f8d70156aba 100644 --- a/gcc/tree-ssa-operands.c +++ b/gcc/tree-ssa-operands.c @@ -893,20 +893,33 @@ build_ssa_operands (tree stmt, stmt_ann_t ann, stmt_operands_p old_ops, switch (code) { case MODIFY_EXPR: - get_expr_operands (stmt, &TREE_OPERAND (stmt, 1), opf_none); - if (TREE_CODE (TREE_OPERAND (stmt, 0)) == ARRAY_REF - || TREE_CODE (TREE_OPERAND (stmt, 0)) == ARRAY_RANGE_REF - || TREE_CODE (TREE_OPERAND (stmt, 0)) == COMPONENT_REF - || TREE_CODE (TREE_OPERAND (stmt, 0)) == REALPART_EXPR - || TREE_CODE (TREE_OPERAND (stmt, 0)) == IMAGPART_EXPR - /* Use a V_MAY_DEF if the RHS might throw, as the LHS won't be - modified in that case. FIXME we should represent somehow - that it is killed on the fallthrough path. */ - || tree_could_throw_p (TREE_OPERAND (stmt, 1))) - get_expr_operands (stmt, &TREE_OPERAND (stmt, 0), opf_is_def); - else - get_expr_operands (stmt, &TREE_OPERAND (stmt, 0), - opf_is_def | opf_kill_def); + /* First get operands from the RHS. For the LHS, we use a V_MAY_DEF if + either only part of LHS is modified or if the RHS might throw, + otherwise, use V_MUST_DEF. + + ??? If it might throw, we should represent somehow that it is killed + on the fallthrough path. */ + { + tree lhs = TREE_OPERAND (stmt, 0); + int lhs_flags = opf_is_def; + + get_expr_operands (stmt, &TREE_OPERAND (stmt, 1), opf_none); + + /* If the LHS is a VIEW_CONVERT_EXPR, it isn't changing whether + or not the entire LHS is modified; that depends on what's + inside the VIEW_CONVERT_EXPR. */ + if (TREE_CODE (lhs) == VIEW_CONVERT_EXPR) + lhs = TREE_OPERAND (lhs, 0); + + if (TREE_CODE (lhs) != ARRAY_REF && TREE_CODE (lhs) != ARRAY_RANGE_REF + && TREE_CODE (lhs) != COMPONENT_REF + && TREE_CODE (lhs) != BIT_FIELD_REF + && TREE_CODE (lhs) != REALPART_EXPR + && TREE_CODE (lhs) != IMAGPART_EXPR) + lhs_flags |= opf_kill_def; + + get_expr_operands (stmt, &TREE_OPERAND (stmt, 0), lhs_flags); + } break; case COND_EXPR: |