This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix remainder of PR58742
- From: Richard Biener <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Date: Wed, 29 Jan 2014 15:42:08 +0100 (CET)
- Subject: [PATCH] Fix remainder of PR58742
- Authentication-results: sourceware.org; auth=none
This fixes the rest, adding p + (q - p) pattern matching and
(p + o1) + o2 associating (similar to the fold-const code).
And it adds testcases for the whole series.
Bootstrapped and tested on x86_64-unknown-linux-gnu and applied.
Richard.
2014-01-29 Richard Biener <rguenther@suse.de>
PR tree-optimization/58742
* tree-ssa-forwprop.c (associate_pointerplus): Rename to
associate_pointerplus_align.
(associate_pointerplus_diff): New function.
(associate_pointerplus): Likewise. Call associate_pointerplus_align
and associate_pointerplus_diff.
* gcc.dg/pr58742-1.c: New testcase.
* gcc.dg/pr58742-2.c: Likewise.
* gcc.dg/pr58742-3.c: Likewise.
Index: gcc/tree-ssa-forwprop.c
===================================================================
*** gcc/tree-ssa-forwprop.c (revision 207234)
--- gcc/tree-ssa-forwprop.c (working copy)
*************** out:
*** 2802,2808 ****
true if anything changed, false otherwise. */
static bool
! associate_pointerplus (gimple_stmt_iterator *gsi)
{
gimple stmt = gsi_stmt (*gsi);
gimple def_stmt;
--- 2802,2808 ----
true if anything changed, false otherwise. */
static bool
! associate_pointerplus_align (gimple_stmt_iterator *gsi)
{
gimple stmt = gsi_stmt (*gsi);
gimple def_stmt;
*************** associate_pointerplus (gimple_stmt_itera
*** 2848,2853 ****
--- 2848,2950 ----
update_stmt (stmt);
return true;
+ }
+
+ /* Associate operands of a POINTER_PLUS_EXPR assignmen at *GSI. Returns
+ true if anything changed, false otherwise. */
+
+ static bool
+ associate_pointerplus_diff (gimple_stmt_iterator *gsi)
+ {
+ gimple stmt = gsi_stmt (*gsi);
+ gimple def_stmt;
+ tree ptr1, rhs;
+
+ /* Pattern match
+ tem1 = (long) ptr1;
+ tem2 = (long) ptr2;
+ tem3 = tem2 - tem1;
+ tem4 = (unsigned long) tem3;
+ tem5 = ptr1 + tem4;
+ and produce
+ tem5 = ptr2; */
+ ptr1 = gimple_assign_rhs1 (stmt);
+ rhs = gimple_assign_rhs2 (stmt);
+ if (TREE_CODE (rhs) != SSA_NAME)
+ return false;
+ gimple minus = SSA_NAME_DEF_STMT (rhs);
+ /* Conditionally look through a sign-changing conversion. */
+ if (is_gimple_assign (minus)
+ && CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (minus))
+ && (TYPE_PRECISION (TREE_TYPE (gimple_assign_rhs1 (minus)))
+ == TYPE_PRECISION (TREE_TYPE (rhs)))
+ && TREE_CODE (gimple_assign_rhs1 (minus)) == SSA_NAME)
+ minus = SSA_NAME_DEF_STMT (gimple_assign_rhs1 (minus));
+ if (!is_gimple_assign (minus))
+ return false;
+ if (gimple_assign_rhs_code (minus) != MINUS_EXPR)
+ return false;
+ rhs = gimple_assign_rhs2 (minus);
+ if (TREE_CODE (rhs) != SSA_NAME)
+ return false;
+ def_stmt = SSA_NAME_DEF_STMT (rhs);
+ if (!is_gimple_assign (def_stmt)
+ || ! CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt))
+ || gimple_assign_rhs1 (def_stmt) != ptr1)
+ return false;
+ rhs = gimple_assign_rhs1 (minus);
+ if (TREE_CODE (rhs) != SSA_NAME)
+ return false;
+ def_stmt = SSA_NAME_DEF_STMT (rhs);
+ if (!is_gimple_assign (def_stmt)
+ || ! CONVERT_EXPR_CODE_P (gimple_assign_rhs_code (def_stmt)))
+ return false;
+ rhs = gimple_assign_rhs1 (def_stmt);
+ if (! useless_type_conversion_p (TREE_TYPE (ptr1), TREE_TYPE (rhs)))
+ return false;
+
+ gimple_assign_set_rhs_with_ops (gsi, TREE_CODE (rhs), rhs, NULL_TREE);
+ update_stmt (stmt);
+
+ return true;
+ }
+
+ /* Associate operands of a POINTER_PLUS_EXPR assignmen at *GSI. Returns
+ true if anything changed, false otherwise. */
+
+ static bool
+ associate_pointerplus (gimple_stmt_iterator *gsi)
+ {
+ gimple stmt = gsi_stmt (*gsi);
+ gimple def_stmt;
+ tree ptr, off1, off2;
+
+ if (associate_pointerplus_align (gsi)
+ || associate_pointerplus_diff (gsi))
+ return true;
+
+ /* Associate (p +p off1) +p off2 as (p +p (off1 + off2)). */
+ ptr = gimple_assign_rhs1 (stmt);
+ off1 = gimple_assign_rhs2 (stmt);
+ if (TREE_CODE (ptr) != SSA_NAME)
+ return false;
+ def_stmt = SSA_NAME_DEF_STMT (ptr);
+ if (!is_gimple_assign (def_stmt)
+ || gimple_assign_rhs_code (def_stmt) != POINTER_PLUS_EXPR)
+ return false;
+ ptr = gimple_assign_rhs1 (def_stmt);
+ off2 = gimple_assign_rhs2 (def_stmt);
+ if (!types_compatible_p (TREE_TYPE (off1), TREE_TYPE (off2)))
+ return false;
+
+ tree off = make_ssa_name (TREE_TYPE (off1), NULL);
+ gimple ostmt = gimple_build_assign_with_ops (PLUS_EXPR, off, off1, off2);
+ gsi_insert_before (gsi, ostmt, GSI_SAME_STMT);
+
+ gimple_assign_set_rhs_with_ops (gsi, POINTER_PLUS_EXPR, ptr, off);
+ update_stmt (stmt);
+
+ return true;
}
/* Combine two conversions in a row for the second conversion at *GSI.
Index: gcc/testsuite/gcc.dg/pr58742-1.c
===================================================================
*** gcc/testsuite/gcc.dg/pr58742-1.c (revision 0)
--- gcc/testsuite/gcc.dg/pr58742-1.c (working copy)
***************
*** 0 ****
--- 1,13 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O -fdump-tree-cddce1" } */
+
+ int *
+ fx (int *b, int *e)
+ {
+ __SIZE_TYPE__ p = e - b;
+ /* The first forwprop pass should optimize this to return e; */
+ return b + p;
+ }
+
+ /* { dg-final { scan-tree-dump "return e" "cddce1" } } */
+ /* { dg-final { cleanup-tree-dump "cddce1" } } */
Index: gcc/testsuite/gcc.dg/pr58742-2.c
===================================================================
*** gcc/testsuite/gcc.dg/pr58742-2.c (revision 0)
--- gcc/testsuite/gcc.dg/pr58742-2.c (working copy)
***************
*** 0 ****
--- 1,13 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O -fdump-tree-cddce1" } */
+
+ __SIZE_TYPE__
+ fx (char *a, __SIZE_TYPE__ sz)
+ {
+ char *b = a + sz;
+ /* The first forwprop pass should optimize this to return sz; */
+ return b - a;
+ }
+
+ /* { dg-final { scan-tree-dump "return sz" "cddce1" } } */
+ /* { dg-final { cleanup-tree-dump "cddce1" } } */
Index: gcc/testsuite/gcc.dg/pr58742-3.c
===================================================================
*** gcc/testsuite/gcc.dg/pr58742-3.c (revision 0)
--- gcc/testsuite/gcc.dg/pr58742-3.c (working copy)
***************
*** 0 ****
--- 1,14 ----
+ /* { dg-do compile } */
+ /* { dg-options "-O -fdump-tree-cddce1" } */
+
+ int *
+ fx (int *a, int sz)
+ {
+ int *b = a + sz;
+ b = b - sz;
+ /* forwprop together with FRE should optimize this to return a; */
+ return b;
+ }
+
+ /* { dg-final { scan-tree-dump "return a" "cddce1" } } */
+ /* { dg-final { cleanup-tree-dump "cddce1" } } */