Tree specific functions for CFG manipulation
---------------------------------------------------------------------------*/
+/* Reinstall those PHI arguments queued in OLD_EDGE to NEW_EDGE. */
+
+static void
+reinstall_phi_args (edge new_edge, edge old_edge)
+{
+ tree var, phi;
+
+ if (!PENDING_STMT (old_edge))
+ return;
+
+ for (var = PENDING_STMT (old_edge), phi = phi_nodes (new_edge->dest);
+ var && phi;
+ var = TREE_CHAIN (var), phi = PHI_CHAIN (phi))
+ {
+ tree result = TREE_PURPOSE (var);
+ tree arg = TREE_VALUE (var);
+
+ gcc_assert (result == PHI_RESULT (phi));
+
+ add_phi_arg (&phi, arg, new_edge);
+ }
+
+ PENDING_STMT (old_edge) = NULL;
+}
+
/* Split a (typically critical) edge EDGE_IN. Return the new block.
Abort on abnormal edges. */
{
basic_block new_bb, after_bb, dest, src;
edge new_edge, e;
- tree phi;
- int i, num_elem;
edge_iterator ei;
/* Abnormal edges cannot be split. */
new_edge->probability = REG_BR_PROB_BASE;
new_edge->count = edge_in->count;
- /* Find all the PHI arguments on the original edge, and change them to
- the new edge. Do it before redirection, so that the argument does not
- get removed. */
- for (phi = phi_nodes (dest); phi; phi = PHI_CHAIN (phi))
- {
- num_elem = PHI_NUM_ARGS (phi);
- for (i = 0; i < num_elem; i++)
- if (PHI_ARG_EDGE (phi, i) == edge_in)
- {
- PHI_ARG_EDGE (phi, i) = new_edge;
- break;
- }
- }
-
e = redirect_edge_and_branch (edge_in, new_bb);
gcc_assert (e);
- gcc_assert (!PENDING_STMT (edge_in));
+ reinstall_phi_args (new_edge, e);
return new_bb;
}