OSDN Git Service

* testsuite/lib/libgomp-dg.exp (libgomp_init): Compute multilib-related
[pf3gnuchains/gcc-fork.git] / gcc / tree-cfgcleanup.c
index 7e719c1..4619d1d 100644 (file)
@@ -117,7 +117,7 @@ cleanup_control_expr_graph (basic_block bb, block_stmt_iterator bsi)
   else
     taken_edge = single_succ_edge (bb);
 
-  bsi_remove (&bsi);
+  bsi_remove (&bsi, true);
   taken_edge->flags = EDGE_FALLTHRU;
 
   /* We removed some paths from the cfg.  */
@@ -207,7 +207,7 @@ cleanup_control_flow (void)
 
          /* Remove the GOTO_EXPR as it is not needed.  The CFG has all the
             relevant information we need.  */
-         bsi_remove (&bsi);
+         bsi_remove (&bsi, true);
          retval = true;
        }
 
@@ -433,7 +433,7 @@ remove_forwarder_block (basic_block bb, basic_block **worklist)
        {
          label = bsi_stmt (bsi);
          gcc_assert (TREE_CODE (label) == LABEL_EXPR);
-         bsi_remove (&bsi);
+         bsi_remove (&bsi, false);
          bsi_insert_before (&bsi_to, label, BSI_CONTINUE_LINKING);
        }
     }
@@ -470,7 +470,7 @@ cleanup_forwarder_blocks (void)
 {
   basic_block bb;
   bool changed = false;
-  basic_block *worklist = xmalloc (sizeof (basic_block) * n_basic_blocks);
+  basic_block *worklist = XNEWVEC (basic_block, n_basic_blocks);
   basic_block *current = worklist;
 
   FOR_EACH_BB (bb)
@@ -711,7 +711,7 @@ remove_forwarder_block_with_phi (basic_block bb)
 static void
 merge_phi_nodes (void)
 {
-  basic_block *worklist = xmalloc (sizeof (basic_block) * n_basic_blocks);
+  basic_block *worklist = XNEWVEC (basic_block, n_basic_blocks);
   basic_block *current = worklist;
   basic_block bb;
 
@@ -743,6 +743,41 @@ merge_phi_nodes (void)
             nodes at BB.  */
          *current++ = bb;
        }
+      else
+       {
+         tree phi;
+         unsigned int dest_idx = single_succ_edge (bb)->dest_idx;
+
+         /* BB dominates DEST.  There may be many users of the PHI
+            nodes in BB.  However, there is still a trivial case we
+            can handle.  If the result of every PHI in BB is used
+            only by a PHI in DEST, then we can trivially merge the
+            PHI nodes from BB into DEST.  */
+         for (phi = phi_nodes (bb); phi; phi = PHI_CHAIN (phi))
+           {
+             tree result = PHI_RESULT (phi);
+             int num_uses = num_imm_uses (result);
+             use_operand_p imm_use;
+             tree use_stmt;
+
+             /* If the PHI's result is never used, then we can just
+                ignore it.  */
+             if (num_uses == 0)
+               continue;
+
+             /* Get the single use of the result of this PHI node.  */
+             if (!single_imm_use (result, &imm_use, &use_stmt)
+                 || TREE_CODE (use_stmt) != PHI_NODE
+                 || bb_for_stmt (use_stmt) != dest
+                 || PHI_ARG_DEF (use_stmt, dest_idx) != result)
+               break;
+           }
+
+         /* If the loop above iterated thorugh all the PHI nodes
+            in BB, then we can merge the PHIs from BB into DEST.  */
+         if (!phi)
+           *current++ = bb;
+       }
     }
 
   /* Now let's drain WORKLIST.  */