diff options
author | Richard Biener <rguenther@suse.de> | 2017-04-25 09:26:37 +0000 |
---|---|---|
committer | Richard Biener <rguenth@gcc.gnu.org> | 2017-04-25 09:26:37 +0000 |
commit | 2700fbd655f608e8e23dd3b113eb36d9d8d83bf7 (patch) | |
tree | c58d111a88734f85e5ee93cf424addf03cf59294 /gcc/tree-ssa-sink.c | |
parent | bfda9ccde6ae7aad1d259e6ebc29fc8f0af3f154 (diff) | |
download | gcc-2700fbd655f608e8e23dd3b113eb36d9d8d83bf7.zip gcc-2700fbd655f608e8e23dd3b113eb36d9d8d83bf7.tar.gz gcc-2700fbd655f608e8e23dd3b113eb36d9d8d83bf7.tar.bz2 |
re PR tree-optimization/79201 (missed optimization: sinking doesn't handle calls, swap PRE and sinking)
2017-04-25 Richard Biener <rguenther@suse.de>
PR tree-optimization/79201
* tree-ssa-sink.c (statement_sink_location): Handle calls.
* gcc.dg/tree-ssa/ssa-sink-16.c: New testcase.
* gcc.target/i386/pr22152.c: Disable sinking.
From-SVN: r247159
Diffstat (limited to 'gcc/tree-ssa-sink.c')
-rw-r--r-- | gcc/tree-ssa-sink.c | 16 |
1 files changed, 10 insertions, 6 deletions
diff --git a/gcc/tree-ssa-sink.c b/gcc/tree-ssa-sink.c index bb8d2ca..eb8b360 100644 --- a/gcc/tree-ssa-sink.c +++ b/gcc/tree-ssa-sink.c @@ -256,8 +256,12 @@ statement_sink_location (gimple *stmt, basic_block frombb, *zero_uses_p = false; - /* We only can sink assignments. */ - if (!is_gimple_assign (stmt)) + /* We only can sink assignments and non-looping const/pure calls. */ + int cf; + if (!is_gimple_assign (stmt) + && (!is_gimple_call (stmt) + || !((cf = gimple_call_flags (stmt)) & (ECF_CONST|ECF_PURE)) + || (cf & ECF_LOOPING_CONST_OR_PURE))) return false; /* We only can sink stmts with a single definition. */ @@ -291,7 +295,7 @@ statement_sink_location (gimple *stmt, basic_block frombb, if (stmt_ends_bb_p (stmt) || gimple_has_side_effects (stmt) || (cfun->has_local_explicit_reg_vars - && TYPE_MODE (TREE_TYPE (gimple_assign_lhs (stmt))) == BLKmode)) + && TYPE_MODE (TREE_TYPE (gimple_get_lhs (stmt))) == BLKmode)) return false; /* Return if there are no immediate uses of this stmt. */ @@ -323,15 +327,15 @@ statement_sink_location (gimple *stmt, basic_block frombb, /* A killing definition is not a use. */ if ((gimple_has_lhs (use_stmt) - && operand_equal_p (gimple_assign_lhs (stmt), + && operand_equal_p (gimple_get_lhs (stmt), gimple_get_lhs (use_stmt), 0)) - || stmt_kills_ref_p (use_stmt, gimple_assign_lhs (stmt))) + || stmt_kills_ref_p (use_stmt, gimple_get_lhs (stmt))) { /* If use_stmt is or might be a nop assignment then USE_STMT acts as a use as well as definition. */ if (stmt != use_stmt && ref_maybe_used_by_stmt_p (use_stmt, - gimple_assign_lhs (stmt))) + gimple_get_lhs (stmt))) return false; continue; } |