------- Comment #10 from steven at gcc dot gnu dot org  2009-02-21 16:09 -------
OK, I checked what we're PREing here.  This is indeed partial-partial PRE.

I suppose something like the following is a good idea.  I'll admit it's
brute-force, but I'm not sure how else to stop GCSE-PRE from doing this (it's
baked into the LCM equations).

Jeff, what do you think about this PR?

Index: gcse.c
===================================================================
--- gcse.c      (revision 144303)
+++ gcse.c      (working copy)
@@ -3801,16 +3801,30 @@
       edge e;
       edge_iterator ei;

-      /* If the current block is the destination of an abnormal edge, we
-        kill all trapping expressions because we won't be able to properly
-        place the instruction on the edge.  So make them neither
-        anticipatable nor transparent.  This is fairly conservative.  */
-      FOR_EACH_EDGE (e, ei, bb->preds)
-       if (e->flags & EDGE_ABNORMAL)
-         {
-           sbitmap_difference (antloc[bb->index], antloc[bb->index],
trapping_expr);
-           sbitmap_difference (transp[bb->index], transp[bb->index],
trapping_expr);
-           break;
+      if (EDGE_COUNT (bb->preds) > 20) /* ??? Should be a PARAM */
+       {
+         /* If a block has a large number of incoming edges, then inserting
+            many expressions in the predecessors to make one/few expression
+            fully redundant is probably not a profitable transformation.
+            Make all expressions non-anticipatable and non-transparent.  */
+         sbitmap_zero (antloc[bb->index]);
+         sbitmap_zero (transp[bb->index]);
+       }
+      else
+       {
+         /* If the current block is the destination of an abnormal edge, we
+            kill all trapping expressions because we won't be able to properly
+            place the instruction on the edge.  So make them neither
+            anticipatable nor transparent.  This is fairly conservative.  */
+         FOR_EACH_EDGE (e, ei, bb->preds)
+           if (e->flags & EDGE_ABNORMAL)
+             {
+               sbitmap_difference (antloc[bb->index],
+                                   antloc[bb->index], trapping_expr);
+               sbitmap_difference (transp[bb->index],
+                                   transp[bb->index], trapping_expr);
+               break;
+             }
          }

       sbitmap_a_or_b (ae_kill[bb->index], transp[bb->index], comp[bb->index]);


-- 

steven at gcc dot gnu dot org changed:

           What    |Removed                     |Added
----------------------------------------------------------------------------
                 CC|                            |law at gcc dot gnu dot org


http://gcc.gnu.org/bugzilla/show_bug.cgi?id=39077

Reply via email to