switch (TREE_CODE (expr))
{
case COND_EXPR:
- val = COND_EXPR_COND (expr);
+ val = fold (COND_EXPR_COND (expr));
break;
case SWITCH_EXPR:
- val = SWITCH_COND (expr);
+ val = fold (SWITCH_COND (expr));
if (TREE_CODE (val) != INTEGER_CST)
return false;
break;
}
-/* Remove unreachable blocks and other miscellaneous clean up work. */
+/* Remove unreachable blocks and other miscellaneous clean up work.
+ Return true if the flowgraph was modified, false otherwise. */
bool
cleanup_tree_cfg (void)
{
- bool retval;
- int i;
+ bool retval, changed;
timevar_push (TV_TREE_CLEANUP_CFG);
- for (retval = true, i = 0; i < 5 && retval; i++)
- retval = cleanup_tree_cfg_1 ();
-
-#ifdef ENABLE_CHECKING
- if (retval)
+ /* Iterate until there are no more cleanups left to do. If any
+ iteration changed the flowgraph, set CHANGED to true. */
+ changed = false;
+ do
{
- gcc_assert (!cleanup_control_flow ());
- gcc_assert (!delete_unreachable_blocks ());
- if (optimize > 0)
- gcc_assert (!cleanup_forwarder_blocks ());
+ retval = cleanup_tree_cfg_1 ();
+ changed |= retval;
}
-#endif
+ while (retval);
compact_blocks ();
timevar_pop (TV_TREE_CLEANUP_CFG);
- return retval;
+ return changed;
}
/* Cleanup cfg and repair loop structures. */
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. */