OSDN Git Service

2010-01-03 Richard Guenther <rguenther@suse.de>
authorrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 3 Jan 2010 12:06:02 +0000 (12:06 +0000)
committerrguenth <rguenth@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 3 Jan 2010 12:06:02 +0000 (12:06 +0000)
PR tree-optimization/42438
* tree-ssa-pre.c (struct bb_bitmap_sets): Add
contains_may_not_return_call flag.
(BB_MAY_NOTRETURN): New.
(valid_in_sets): Trapping nary operations are not valid
in blocks that may not return.
(insert_into_preds_of_block): Remove check for trapping
expressions.
(compute_avail): Compute also BB_MAY_NOTRETURN.

* gcc.dg/tree-ssa/ssa-pre-27.c: New testcase.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@155584 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-27.c [new file with mode: 0644]
gcc/tree-ssa-pre.c

index c133aac..8065b24 100644 (file)
@@ -1,3 +1,15 @@
+2010-01-03  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/42438
+       * tree-ssa-pre.c (struct bb_bitmap_sets): Add
+       contains_may_not_return_call flag.
+       (BB_MAY_NOTRETURN): New.
+       (valid_in_sets): Trapping nary operations are not valid
+       in blocks that may not return.
+       (insert_into_preds_of_block): Remove check for trapping
+       expressions.
+       (compute_avail): Compute also BB_MAY_NOTRETURN.
+
 2010-01-03  Gerald Pfeifer  <gerald@pfeifer.com>
 
        * doc/invoke.texi: Add 2010 to copyright years.
index d1580fa..609589c 100644 (file)
@@ -1,3 +1,8 @@
+2010-01-03  Richard Guenther  <rguenther@suse.de>
+
+       PR tree-optimization/42438
+       * gcc.dg/tree-ssa/ssa-pre-27.c: New testcase.
+
 2010-01-02  Richard Guenther  <rguenther@suse.de>
 
        PR testsuite/41651
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-27.c b/gcc/testsuite/gcc.dg/tree-ssa/ssa-pre-27.c
new file mode 100644 (file)
index 0000000..1d60a30
--- /dev/null
@@ -0,0 +1,29 @@
+/* { dg-do compile } */
+/* { dg-options "-O2 -fdump-tree-pre" } */
+
+int foo (int i, int j, int b)
+{
+  int res = 0;
+  if (b)
+    res = i/j;
+  /* We should insert the possibly trapping i/j.  */
+  res += i/j;
+  return res;
+}
+
+extern void bar (void);
+int foo2 (int i, int j, int b)
+{
+  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" } } */
index 52e973f..7d9b9bf 100644 (file)
@@ -382,11 +382,14 @@ typedef struct bb_bitmap_sets
   bitmap expr_dies;
 
   /* True if we have visited this block during ANTIC calculation.  */
-  unsigned int visited:1;
+  unsigned int visited : 1;
 
   /* True we have deferred processing this block during ANTIC
      calculation until its successor is processed.  */
   unsigned int deferred : 1;
+
+  /* True when the block contains a call that might not return.  */
+  unsigned int contains_may_not_return_call : 1;
 } *bb_value_sets_t;
 
 #define EXP_GEN(BB)    ((bb_value_sets_t) ((BB)->aux))->exp_gen
@@ -399,6 +402,7 @@ typedef struct bb_bitmap_sets
 #define EXPR_DIES(BB)  ((bb_value_sets_t) ((BB)->aux))->expr_dies
 #define BB_VISITED(BB) ((bb_value_sets_t) ((BB)->aux))->visited
 #define BB_DEFERRED(BB) ((bb_value_sets_t) ((BB)->aux))->deferred
+#define BB_MAY_NOTRETURN(BB) ((bb_value_sets_t) ((BB)->aux))->contains_may_not_return_call
 
 
 /* Basic block list in postorder.  */
@@ -2032,6 +2036,13 @@ valid_in_sets (bitmap_set_t set1, bitmap_set_t set2, pre_expr expr,
                  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;
@@ -2469,6 +2480,7 @@ compute_antic (void)
 
       BB_VISITED (block) = 0;
       BB_DEFERRED (block) = 0;
+
       /* While we are here, give empty ANTIC_IN sets to each block.  */
       ANTIC_IN (block) = bitmap_set_new ();
       PA_IN (block) = bitmap_set_new ();
@@ -3187,16 +3199,6 @@ insert_into_preds_of_block (basic_block block, unsigned int exprnum,
        }
     }
 
-  /* Make sure we are not inserting trapping expressions.  */
-  FOR_EACH_EDGE (pred, ei, block->preds)
-    {
-      bprime = pred->src;
-      eprime = avail[bprime->index];
-      if (eprime->kind == NARY
-         && vn_nary_may_trap (PRE_EXPR_NARY (eprime)))
-       return false;
-    }
-
   /* Make the necessary insertions.  */
   FOR_EACH_EDGE (pred, ei, block->preds)
     {
@@ -3804,6 +3806,8 @@ compute_avail (void)
       for (gsi = gsi_start_phis (block); !gsi_end_p (gsi); gsi_next (&gsi))
        make_values_for_phi (gsi_stmt (gsi), block);
 
+      BB_MAY_NOTRETURN (block) = 0;
+
       /* Now compute value numbers and populate value sets with all
         the expressions computed in BLOCK.  */
       for (gsi = gsi_start_bb (block); !gsi_end_p (gsi); gsi_next (&gsi))
@@ -3814,6 +3818,23 @@ compute_avail (void)
          stmt = gsi_stmt (gsi);
          gimple_set_uid (stmt, stmt_uid++);
 
+         /* Cache whether the basic-block has any non-visible side-effect
+            or control flow.
+            If this isn't a call or it is the last stmt in the
+            basic-block then the CFG represents things correctly.  */
+         if (is_gimple_call (stmt)
+             && !stmt_ends_bb_p (stmt))
+           {
+             /* Non-looping const functions always return normally.
+                Otherwise the call might not return or have side-effects
+                that forbids hoisting possibly trapping expressions
+                before it.  */
+             int flags = gimple_call_flags (stmt);
+             if (!(flags & ECF_CONST)
+                 || (flags & ECF_LOOPING_CONST_OR_PURE))
+               BB_MAY_NOTRETURN (block) = 1;
+           }
+
          FOR_EACH_SSA_TREE_OPERAND (op, stmt, iter, SSA_OP_DEF)
            {
              pre_expr e = get_or_alloc_expr_for_name (op);