This fixes PR50213 by adding a heuristic to tree forwprop to not
propagate simple IV counter increments (similar as how to DOM
avoids to CSE them).

Bootstrapped and tested on x86_64-unknown-linux-gnu, applied.

Richard.

2011-09-07  Richard Guenther  <rguent...@suse.de>

        PR tree-optimization/50213
        * tree-flow.h (simple_iv_increment_p): Declare.
        * tree-ssa-dom.c (simple_iv_increment_p): Export.  Also handle
        POINTER_PLUS_EXPR.
        * tree-ssa-forwprop.c (ssa_forward_propagate_and_combine): Do
        not propagate simple IV counter increments.

Index: gcc/tree-flow.h
===================================================================
*** gcc/tree-flow.h     (revision 178628)
--- gcc/tree-flow.h     (working copy)
*************** extern void dump_dominator_optimization_
*** 597,602 ****
--- 597,603 ----
  extern void debug_dominator_optimization_stats (void);
  int loop_depth_of_name (tree);
  tree degenerate_phi_result (gimple);
+ bool simple_iv_increment_p (gimple);
  
  /* In tree-ssa-copy.c  */
  extern void propagate_value (use_operand_p, tree);
Index: gcc/tree-ssa-dom.c
===================================================================
*** gcc/tree-ssa-dom.c  (revision 178628)
--- gcc/tree-ssa-dom.c  (working copy)
*************** record_equality (tree x, tree y)
*** 1409,1417 ****
     i_1 = phi (..., i_2)
     i_2 = i_1 +/- ...  */
  
! static bool
  simple_iv_increment_p (gimple stmt)
  {
    tree lhs, preinc;
    gimple phi;
    size_t i;
--- 1409,1418 ----
     i_1 = phi (..., i_2)
     i_2 = i_1 +/- ...  */
  
! bool
  simple_iv_increment_p (gimple stmt)
  {
+   enum tree_code code;
    tree lhs, preinc;
    gimple phi;
    size_t i;
*************** simple_iv_increment_p (gimple stmt)
*** 1423,1434 ****
    if (TREE_CODE (lhs) != SSA_NAME)
      return false;
  
!   if (gimple_assign_rhs_code (stmt) != PLUS_EXPR
!       && gimple_assign_rhs_code (stmt) != MINUS_EXPR)
      return false;
  
    preinc = gimple_assign_rhs1 (stmt);
- 
    if (TREE_CODE (preinc) != SSA_NAME)
      return false;
  
--- 1424,1436 ----
    if (TREE_CODE (lhs) != SSA_NAME)
      return false;
  
!   code = gimple_assign_rhs_code (stmt);
!   if (code != PLUS_EXPR
!       && code != MINUS_EXPR
!       && code != POINTER_PLUS_EXPR)
      return false;
  
    preinc = gimple_assign_rhs1 (stmt);
    if (TREE_CODE (preinc) != SSA_NAME)
      return false;
  
Index: gcc/tree-ssa-forwprop.c
===================================================================
*** gcc/tree-ssa-forwprop.c     (revision 178628)
--- gcc/tree-ssa-forwprop.c     (working copy)
*************** ssa_forward_propagate_and_combine (void)
*** 2377,2397 ****
              else
                gsi_next (&gsi);
            }
!         else if (code == POINTER_PLUS_EXPR && can_propagate_from (stmt))
            {
!             if (TREE_CODE (gimple_assign_rhs2 (stmt)) == INTEGER_CST
                  /* ???  Better adjust the interface to that function
                     instead of building new trees here.  */
                  && forward_propagate_addr_expr
!                 (lhs,
!                  build1 (ADDR_EXPR,
!                          TREE_TYPE (rhs),
!                          fold_build2 (MEM_REF,
!                                       TREE_TYPE (TREE_TYPE (rhs)),
!                                       rhs,
!                                       fold_convert
!                                       (ptr_type_node,
!                                        gimple_assign_rhs2 (stmt))))))
                {
                  release_defs (stmt);
                  todoflags |= TODO_remove_unused_locals;
--- 2377,2399 ----
              else
                gsi_next (&gsi);
            }
!         else if (code == POINTER_PLUS_EXPR)
            {
!             tree off = gimple_assign_rhs2 (stmt);
!             if (TREE_CODE (off) == INTEGER_CST
!                 && can_propagate_from (stmt)
!                 && !simple_iv_increment_p (stmt)
                  /* ???  Better adjust the interface to that function
                     instead of building new trees here.  */
                  && forward_propagate_addr_expr
!                      (lhs,
!                       build1_loc (gimple_location (stmt),
!                                   ADDR_EXPR, TREE_TYPE (rhs),
!                                   fold_build2 (MEM_REF,
!                                                TREE_TYPE (TREE_TYPE (rhs)),
!                                                rhs,
!                                                fold_convert (ptr_type_node,
!                                                              off)))))
                {
                  release_defs (stmt);
                  todoflags |= TODO_remove_unused_locals;

Reply via email to