to the list of incoming edges associated with E. */
if (insert)
{
- struct el *el = XNEW (struct el);
+ struct el *el = XNEW (struct el);
el->next = elt->incoming_edges;
el->e = e;
elt->incoming_edges = el;
e2 = redirect_edge_and_branch (victim, path->last ()->e->dest);
e2->count = path->last ()->e->count;
/* If we redirected the edge, then we need to copy PHI arguments
- at the target. If the edge already existed (e2 != victim
+ at the target. If the edge already existed (e2 != victim
case), then the PHIs in the target already have the correct
arguments. */
if (e2 == victim)
- copy_phi_args (e2->dest, path->last ()->e, e2);
+ copy_phi_args (e2->dest, path->last ()->e, e2);
}
else
{
/* The second duplicated block in a jump threading path is specific
to the path. So it gets stored in RD rather than in LOCAL_DATA.
-
+
Each time we're called, we have to look through the path and see
if a second block needs to be duplicated.
}
/* Go ahead and clear E->aux. It's not needed anymore and failure
- to clear it will cause all kinds of unpleasant problems later. */
+ to clear it will cause all kinds of unpleasant problems later. */
delete_jump_thread_path (path);
e->aux = NULL;
/* Advance to the first executable statement. */
gsi = gsi_start_bb (bb);
while (!gsi_end_p (gsi)
- && (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
+ && (gimple_code (gsi_stmt (gsi)) == GIMPLE_LABEL
|| is_gimple_debug (gsi_stmt (gsi))
- || gimple_nop_p (gsi_stmt (gsi))))
+ || gimple_nop_p (gsi_stmt (gsi))))
gsi_next (&gsi);
/* Check if this is an empty block. */
/* Test that we've reached the terminating control statement. */
return gsi_stmt (gsi)
- && (gimple_code (gsi_stmt (gsi)) == GIMPLE_COND
- || gimple_code (gsi_stmt (gsi)) == GIMPLE_GOTO
- || gimple_code (gsi_stmt (gsi)) == GIMPLE_SWITCH);
+ && (gimple_code (gsi_stmt (gsi)) == GIMPLE_COND
+ || gimple_code (gsi_stmt (gsi)) == GIMPLE_GOTO
+ || gimple_code (gsi_stmt (gsi)) == GIMPLE_SWITCH);
}
/* BB is a block which ends with a COND_EXPR or SWITCH_EXPR and when BB
if (!e2 || noloop_only)
{
/* If NOLOOP_ONLY is true, we only allow threading through the
- header of a loop to exit edges.
-
- There are two cases to consider. The first when BB is the
- loop header. We will attempt to thread this elsewhere, so
- we can just continue here. */
-
- if (bb == bb->loop_father->header
- && (!loop_exit_edge_p (bb->loop_father, e2)
- || (*path)[1]->type == EDGE_COPY_SRC_JOINER_BLOCK))
- continue;
-
+ header of a loop to exit edges. */
- /* The second occurs when there was loop header buried in a jump
- threading path. We do not try and thread this elsewhere, so
- just cancel the jump threading request by clearing the AUX
- field now. */
+ /* One case occurs when there was loop header buried in a jump
+ threading path that crosses loop boundaries. We do not try
+ and thread this elsewhere, so just cancel the jump threading
+ request by clearing the AUX field now. */
if ((bb->loop_father != e2->src->loop_father
&& !loop_exit_edge_p (e2->src->loop_father, e2))
|| (e2->src->loop_father != e2->dest->loop_father
e->aux = NULL;
continue;
}
+
+ /* Another case occurs when trying to thread through our
+ own loop header, possibly from inside the loop.
+
+ If our loop header is buried in the path, then go ahead
+ and cancel the jump threading request here. This likely
+ will need updating for the FSA/FSM coremark case.
+
+ Other cases (BB is the loop header) are handled elsewhere. */
+ unsigned int i;
+ for (i = 1; i < path->length (); i++)
+ {
+ if ((*path)[i]->e->src == bb->loop_father->header
+ && (!loop_exit_edge_p (bb->loop_father, e2)
+ || (*path)[1]->type == EDGE_COPY_SRC_JOINER_BLOCK))
+ {
+ /* If i != 1, then it's a buried header that will not
+ be handled elsehwere. */
+ if (i != 1)
+ {
+ delete_jump_thread_path (path);
+ e->aux = NULL;
+ }
+ break;
+ }
+ }
+
+ if (i != path->length ())
+ continue;
}
if (e->dest == e2->src)
update_bb_profile_for_threading (e->dest, EDGE_FREQUENCY (e),
- e->count, (*THREAD_PATH (e))[1]->e);
+ e->count, (*THREAD_PATH (e))[1]->e);
/* Insert the outgoing edge into the hash table if it is not
already in the hash table. */
unsigned nblocks, i;
/* First handle the case latch edge is redirected. We are copying
- the loop header but not creating a multiple entry loop. Make the
+ the loop header but not creating a multiple entry loop. Make the
cfg manipulation code aware of that fact. */
set_loop_copy (loop, loop);
loop->latch = thread_single_edge (latch);