This moves handling of trapping ops to prune_clobbered_mems and
compute_avail, similar to how I moved handling of clobbered mems
earlier.  It fixes one existing testcase even.

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

Richard.

2012-05-03  Richard Guenther  <rguent...@suse.de>

        * tree-ssa-pre.c (valid_in_sets): Remove checking of trapping
        operations.
        (prune_clobbered_mems): Do it here.  Do not uselessly sort
        expressions.
        (compute_avail): Do not add possibly trapping operations to
        EXP_GEN if they might not be executed in the block.

        * gcc.dg/tree-ssa/ssa-pre-27.c: Remove XFAIL.

Index: gcc/tree-ssa-pre.c
===================================================================
*** gcc/tree-ssa-pre.c  (revision 187092)
--- gcc/tree-ssa-pre.c  (working copy)
*************** valid_in_sets (bitmap_set_t set1, bitmap
*** 2069,2081 ****
        for (i = 0; i < nary->length; i++)
          if (!op_valid_in_sets (set1, set2, nary->op[i]))
            return false;
-       /* If the NARY may trap make sure the block does not contain
-          a possible exit point.
-          ???  This is overly conservative if we translate AVAIL_OUT
-          as the available expression might be after the exit point.  */
-       if (BB_MAY_NOTRETURN (block)
-           && vn_nary_may_trap (nary))
-         return false;
        return true;
        }
        break;
--- 2069,2074 ----
*************** clean (bitmap_set_t set, basic_block blo
*** 2140,2174 ****
  }
  
  /* Clean the set of expressions that are no longer valid in SET because
!    they are clobbered in BLOCK.  */
  
  static void
  prune_clobbered_mems (bitmap_set_t set, basic_block block)
  {
!   VEC (pre_expr, heap) *exprs = sorted_array_from_bitmap_set (set);
!   pre_expr expr;
!   int i;
  
!   FOR_EACH_VEC_ELT (pre_expr, exprs, i, expr)
      {
!       vn_reference_t ref;
!       if (expr->kind != REFERENCE)
!       continue;
! 
!       ref = PRE_EXPR_REFERENCE (expr);
!       if (ref->vuse)
        {
!         gimple def_stmt = SSA_NAME_DEF_STMT (ref->vuse);
!         if (!gimple_nop_p (def_stmt)
!             && ((gimple_bb (def_stmt) != block
!                  && !dominated_by_p (CDI_DOMINATORS,
!                                      block, gimple_bb (def_stmt)))
!                 || (gimple_bb (def_stmt) == block
!                     && value_dies_in_block_x (expr, block))))
            bitmap_remove_from_set (set, expr);
        }
      }
-   VEC_free (pre_expr, heap, exprs);
  }
  
  static sbitmap has_abnormal_preds;
--- 2133,2176 ----
  }
  
  /* Clean the set of expressions that are no longer valid in SET because
!    they are clobbered in BLOCK or because they trap and may not be executed.  
*/
  
  static void
  prune_clobbered_mems (bitmap_set_t set, basic_block block)
  {
!   bitmap_iterator bi;
!   unsigned i;
  
!   FOR_EACH_EXPR_ID_IN_SET (set, i, bi)
      {
!       pre_expr expr = expression_for_id (i);
!       if (expr->kind == REFERENCE)
!       {
!         vn_reference_t ref = PRE_EXPR_REFERENCE (expr);
!         if (ref->vuse)
!           {
!             gimple def_stmt = SSA_NAME_DEF_STMT (ref->vuse);
!             if (!gimple_nop_p (def_stmt)
!                 && ((gimple_bb (def_stmt) != block
!                      && !dominated_by_p (CDI_DOMINATORS,
!                                          block, gimple_bb (def_stmt)))
!                     || (gimple_bb (def_stmt) == block
!                         && value_dies_in_block_x (expr, block))))
!               bitmap_remove_from_set (set, expr);
!           }
!       }
!       else if (expr->kind == NARY)
        {
!         vn_nary_op_t nary = PRE_EXPR_NARY (expr);
!         /* If the NARY may trap make sure the block does not contain
!            a possible exit point.
!            ???  This is overly conservative if we translate AVAIL_OUT
!            as the available expression might be after the exit point.  */
!         if (BB_MAY_NOTRETURN (block)
!             && vn_nary_may_trap (nary))
            bitmap_remove_from_set (set, expr);
        }
      }
  }
  
  static sbitmap has_abnormal_preds;
*************** compute_avail (void)
*** 4119,4124 ****
--- 4121,4133 ----
                        if (TREE_CODE (nary->op[i]) == SSA_NAME)
                          add_to_exp_gen (block, nary->op[i]);
  
+                     /* If the NARY traps and there was a preceeding
+                        point in the block that might not return avoid
+                        adding the nary to EXP_GEN.  */
+                     if (BB_MAY_NOTRETURN (block)
+                         && vn_nary_may_trap (nary))
+                       continue;
+ 
                      result = (pre_expr) pool_alloc (pre_expr_pool);
                      result->kind = NARY;
                      result->id = 0;
Index: gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-27.c
===================================================================
*** gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-27.c  (revision 187091)
--- gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-27.c  (working copy)
*************** int foo2 (int i, int j, int b)
*** 17,29 ****
    int res = 0;
    if (b)
      res = i/j;
!   /* But we fail so here because of the possibly not returning
!      call in the same basic-block.  */
    res += i/j;
    bar ();
    return res;
  }
  
! /* { dg-final { scan-tree-dump-times "# prephitmp" 1 "pre" } } */
! /* { dg-final { scan-tree-dump-times "# prephitmp" 2 "pre" { xfail *-*-* } } 
} */
  /* { dg-final { cleanup-tree-dump "pre" } } */
--- 17,28 ----
    int res = 0;
    if (b)
      res = i/j;
!   /* And here, the possibly not returning call in the same basic-block
!      comes after the trapping i/j.  */
    res += i/j;
    bar ();
    return res;
  }
  
! /* { dg-final { scan-tree-dump-times "# prephitmp" 2 "pre" } } */
  /* { dg-final { cleanup-tree-dump "pre" } } */

Reply via email to