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. */
/* 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;
}
{
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);
}
}
{
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)
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;
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. */