From 2700fbd655f608e8e23dd3b113eb36d9d8d83bf7 Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Tue, 25 Apr 2017 09:26:37 +0000 Subject: [PATCH] re PR tree-optimization/79201 (missed optimization: sinking doesn't handle calls, swap PRE and sinking) 2017-04-25 Richard Biener 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 --- gcc/ChangeLog | 5 +++++ gcc/testsuite/ChangeLog | 6 ++++++ gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-16.c | 14 ++++++++++++++ gcc/testsuite/gcc.target/i386/pr22152.c | 2 +- gcc/tree-ssa-sink.c | 16 ++++++++++------ 5 files changed, 36 insertions(+), 7 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-16.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 05d38bdd077..e1c79a8116a 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,8 @@ +2017-04-25 Richard Biener + + PR tree-optimization/79201 + * tree-ssa-sink.c (statement_sink_location): Handle calls. + 2017-04-25 Andreas Krebbel PR target/80464 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 1f347f44101..409725c46bf 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,9 @@ +2017-04-25 Richard Biener + + PR tree-optimization/79201 + * gcc.dg/tree-ssa/ssa-sink-16.c: New testcase. + * gcc.target/i386/pr22152.c: Disable sinking. + 2017-04-25 Andreas Krebbel PR target/80464 diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-16.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-16.c new file mode 100644 index 00000000000..1b94c336806 --- /dev/null +++ b/gcc/testsuite/gcc.dg/tree-ssa/ssa-sink-16.c @@ -0,0 +1,14 @@ +/* { dg-do compile } */ +/* Note PRE rotates the loop and blocks the sinking opportunity. */ +/* { dg-options "-O2 -fno-tree-pre -fdump-tree-sink -fdump-tree-optimized" } */ + +int f(int n) +{ + int i,j=0; + for (i = 0; i < 31; i++) + j = __builtin_ffs(i); + return j; +} + +/* { dg-final { scan-tree-dump "Sinking j_. = __builtin_ffs" "sink" } } */ +/* { dg-final { scan-tree-dump "return 2;" "optimized" } } */ diff --git a/gcc/testsuite/gcc.target/i386/pr22152.c b/gcc/testsuite/gcc.target/i386/pr22152.c index 5e2d4ac731b..8603b09fe4a 100644 --- a/gcc/testsuite/gcc.target/i386/pr22152.c +++ b/gcc/testsuite/gcc.target/i386/pr22152.c @@ -1,5 +1,5 @@ /* { dg-do compile } */ -/* { dg-options "-O2 -msse2 -mtune=core2" } */ +/* { dg-options "-O2 -fno-tree-sink -msse2 -mtune=core2" } */ /* { dg-additional-options "-mno-vect8-ret-in-mem" { target *-*-vxworks* } } */ /* { dg-additional-options "-mabi=sysv" { target x86_64-*-mingw* } } */ diff --git a/gcc/tree-ssa-sink.c b/gcc/tree-ssa-sink.c index bb8d2ca9732..eb8b36095d8 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; }