diff options
Diffstat (limited to 'gcc/tree-ssa-operands.c')
-rw-r--r-- | gcc/tree-ssa-operands.c | 64 |
1 files changed, 38 insertions, 26 deletions
diff --git a/gcc/tree-ssa-operands.c b/gcc/tree-ssa-operands.c index 71fb883..0aeea9f 100644 --- a/gcc/tree-ssa-operands.c +++ b/gcc/tree-ssa-operands.c @@ -1660,7 +1660,10 @@ add_call_clobber_ops (tree stmt, tree callee) bitmap_iterator bi; stmt_ann_t s_ann = stmt_ann (stmt); bitmap not_read_b, not_written_b; - + tree call = get_call_expr_in (stmt); + + gcc_assert (!(call_expr_flags (call) & (ECF_PURE | ECF_CONST))); + /* If we created .GLOBAL_VAR earlier, just use it. */ if (gimple_global_var (cfun)) { @@ -1674,12 +1677,10 @@ add_call_clobber_ops (tree stmt, tree callee) or write that variable. */ not_read_b = callee ? ipa_reference_get_not_read_global (callee) : NULL; not_written_b = callee ? ipa_reference_get_not_written_global (callee) : NULL; - /* Add a VDEF operand for every call clobbered variable. */ EXECUTE_IF_SET_IN_BITMAP (gimple_call_clobbered_vars (cfun), 0, u, bi) { tree var = referenced_var_lookup (u); - unsigned int escape_mask = var_ann (var)->escape_mask; tree real_var = var; bool not_read; bool not_written; @@ -1697,24 +1698,6 @@ add_call_clobber_ops (tree stmt, tree callee) /* See if this variable is really clobbered by this function. */ - /* Trivial case: Things escaping only to pure/const are not - clobbered by non-pure-const, and only read by pure/const. */ - if ((escape_mask & ~(ESCAPE_TO_PURE_CONST)) == 0) - { - tree call = get_call_expr_in (stmt); - if (call_expr_flags (call) & (ECF_CONST | ECF_PURE)) - { - add_virtual_operand (var, s_ann, opf_use, NULL, 0, -1, true); - clobber_stats.unescapable_clobbers_avoided++; - continue; - } - else - { - clobber_stats.unescapable_clobbers_avoided++; - continue; - } - } - if (not_written) { clobber_stats.static_write_clobbers_avoided++; @@ -1739,18 +1722,47 @@ add_call_read_ops (tree stmt, tree callee) bitmap_iterator bi; stmt_ann_t s_ann = stmt_ann (stmt); bitmap not_read_b; + tree call = get_call_expr_in (stmt); + + /* Const functions do not reference memory. */ + if (call_expr_flags (call) & ECF_CONST) + return; - /* if the function is not pure, it may reference memory. Add - a VUSE for .GLOBAL_VAR if it has been created. See add_referenced_var - for the heuristic used to decide whether to create .GLOBAL_VAR. */ + not_read_b = callee ? ipa_reference_get_not_read_global (callee) : NULL; + + /* For pure functions we compute non-escaped uses separately. */ + if (call_expr_flags (call) & ECF_PURE) + EXECUTE_IF_SET_IN_BITMAP (gimple_call_used_vars (cfun), 0, u, bi) + { + tree var = referenced_var_lookup (u); + tree real_var = var; + bool not_read; + + if (unmodifiable_var_p (var)) + continue; + + not_read = not_read_b + ? bitmap_bit_p (not_read_b, DECL_UID (real_var)) + : false; + + clobber_stats.readonly_clobbers++; + + /* See if this variable is really used by this function. */ + if (!not_read) + add_virtual_operand (var, s_ann, opf_use, NULL, 0, -1, true); + else + clobber_stats.static_readonly_clobbers_avoided++; + } + + /* Add a VUSE for .GLOBAL_VAR if it has been created. See + add_referenced_var for the heuristic used to decide whether to + create .GLOBAL_VAR. */ if (gimple_global_var (cfun)) { tree var = gimple_global_var (cfun); add_virtual_operand (var, s_ann, opf_use, NULL, 0, -1, true); return; } - - not_read_b = callee ? ipa_reference_get_not_read_global (callee) : NULL; /* Add a VUSE for each call-clobbered variable. */ EXECUTE_IF_SET_IN_BITMAP (gimple_call_clobbered_vars (cfun), 0, u, bi) |