Returns newly created loop. */
struct loop *
-loopify (struct loops *loops, edge latch_edge, edge header_edge,
+loopify (struct loops *loops, edge latch_edge, edge header_edge,
basic_block switch_bb, edge true_edge, edge false_edge,
bool redirect_all_edges)
{
if (redirect_all_edges)
{
loop_redirect_edge (header_edge, switch_bb);
- loop_redirect_edge (false_edge, loop->header);
-
+ loop_redirect_edge (false_edge, loop->header);
+
/* Update dominators. */
set_immediate_dominator (CDI_DOMINATORS, switch_bb, pred_bb);
set_immediate_dominator (CDI_DOMINATORS, loop->header, switch_bb);
{
outer = loop->outer;
if (!fix_loop_placement (loop))
- break;
+ break;
/* Changing the placement of a loop in the loop tree may alter the
validity of condition 2) of the description of fix_bb_placement
edge snd;
gcc_assert (EDGE_COUNT (src->succs) > 1);
-
+
/* Cannot handle more than two exit edges. */
if (EDGE_COUNT (src->succs) > 2)
return false;
return false;
single_succ_edge (src)->flags &= ~EDGE_IRREDUCIBLE_LOOP;
single_succ_edge (src)->flags |= irr;
-
+
return true;
}
ret = can_copy_bbs_p (bbs, loop->num_nodes);
free (bbs);
-
+
return ret;
}
: prob_pass_thru;
/* Complete peeling is special as the probability of exit in last
- copy becomes 1. */
+ copy becomes 1. */
if (flags & DLTHE_FLAG_COMPLETTE_PEEL)
{
int wanted_freq = EDGE_FREQUENCY (e);
/* Now simulate the duplication adjustments and compute header
frequency of the last copy. */
for (i = 0; i < ndupl; i++)
- wanted_freq = RDIV (wanted_freq * scale_step[i], REG_BR_PROB_BASE);
+ wanted_freq = RDIV (wanted_freq * scale_step[i], REG_BR_PROB_BASE);
scale_main = RDIV (wanted_freq * REG_BR_PROB_BASE, freq_in);
}
else if (is_latch)
}
free (new_bbs);
free (orig_loops);
-
+
/* Update the original loop. */
if (!is_latch)
set_immediate_dominator (CDI_DOMINATORS, e->dest, e->src);
continue;
dom_bb = nearest_common_dominator (
CDI_DOMINATORS, first_active[i], first_active_latch);
- set_immediate_dominator (CDI_DOMINATORS, dominated, dom_bb);
+ set_immediate_dominator (CDI_DOMINATORS, dominated, dom_bb);
}
free (dom_bbs);
}
return new_bb;
}
-/* Uses the natural loop discovery to recreate loop notes. */
-void
-create_loop_notes (void)
-{
- rtx insn, head, end;
- struct loops loops;
- struct loop *loop;
- basic_block *first, *last, bb, pbb;
- struct loop **stack, **top;
-
-#ifdef ENABLE_CHECKING
- /* Verify that there really are no loop notes. */
- for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
- gcc_assert (!NOTE_P (insn) ||
- NOTE_LINE_NUMBER (insn) != NOTE_INSN_LOOP_BEG);
-#endif
-
- flow_loops_find (&loops);
- free_dominance_info (CDI_DOMINATORS);
- if (loops.num > 1)
- {
- last = XCNEWVEC (basic_block, loops.num);
-
- FOR_EACH_BB (bb)
- {
- for (loop = bb->loop_father; loop->outer; loop = loop->outer)
- last[loop->num] = bb;
- }
-
- first = XCNEWVEC (basic_block, loops.num);
- stack = XCNEWVEC (struct loop *, loops.num);
- top = stack;
-
- FOR_EACH_BB (bb)
- {
- for (loop = bb->loop_father; loop->outer; loop = loop->outer)
- {
- if (!first[loop->num])
- {
- *top++ = loop;
- first[loop->num] = bb;
- }
-
- if (bb == last[loop->num])
- {
- /* Prevent loops from overlapping. */
- while (*--top != loop)
- last[(*top)->num] = EXIT_BLOCK_PTR;
-
- /* If loop starts with jump into it, place the note in
- front of the jump. */
- insn = PREV_INSN (BB_HEAD (first[loop->num]));
- if (insn
- && BARRIER_P (insn))
- insn = PREV_INSN (insn);
-
- if (insn
- && JUMP_P (insn)
- && any_uncondjump_p (insn)
- && onlyjump_p (insn))
- {
- pbb = BLOCK_FOR_INSN (insn);
- gcc_assert (pbb && single_succ_p (pbb));
-
- if (!flow_bb_inside_loop_p (loop, single_succ (pbb)))
- insn = BB_HEAD (first[loop->num]);
- }
- else
- insn = BB_HEAD (first[loop->num]);
-
- head = BB_HEAD (first[loop->num]);
- emit_note_before (NOTE_INSN_LOOP_BEG, insn);
- BB_HEAD (first[loop->num]) = head;
-
- /* Position the note correctly wrto barrier. */
- insn = BB_END (last[loop->num]);
- if (NEXT_INSN (insn)
- && BARRIER_P (NEXT_INSN (insn)))
- insn = NEXT_INSN (insn);
-
- end = BB_END (last[loop->num]);
- emit_note_after (NOTE_INSN_LOOP_END, insn);
- BB_END (last[loop->num]) = end;
- }
- }
- }
-
- free (first);
- free (last);
- free (stack);
- }
- flow_loops_free (&loops);
-}
-
/* This function is called from loop_version. It splits the entry edge
of the loop we want to version, adds the versioning condition, and
adjust the edges to the two versions of the loop appropriately.
Split it and insert new conditional expression and adjust edges.
--- edge e ---> [cond expr] ---> [first_head]
- |
- +---------> [second_head]
+ |
+ +---------> [second_head]
*/
static basic_block
}
/* Main entry point for Loop Versioning transformation.
-
+
This transformation given a condition and a loop, creates
-if (condition) { loop_copy1 } else { loop_copy2 },
where loop_copy1 is the loop transformed in one way, and loop_copy2
instruction stream, otherwise it is placed before LOOP. */
struct loop *
-loop_version (struct loops *loops, struct loop * loop,
+loop_version (struct loops *loops, struct loop * loop,
void *cond_expr, basic_block *condition_bb,
bool place_after)
{
entry = loop_preheader_edge (loop);
irred_flag = entry->flags & EDGE_IRREDUCIBLE_LOOP;
entry->flags &= ~EDGE_IRREDUCIBLE_LOOP;
-
+
/* Note down head of loop as first_head. */
first_head = entry->dest;
/* Duplicate loop. */
if (!cfg_hook_duplicate_loop_to_header_edge (loop, entry, loops, 1,
- NULL, NULL, NULL, NULL, 0))
+ NULL, NULL, NULL, NULL, 0))
return NULL;
/* After duplication entry edge now points to new loop head block.
}
latch_edge = single_succ_edge (get_bb_copy (loop->latch));
-
+
extract_cond_bb_edges (cond_bb, &true_edge, &false_edge);
nloop = loopify (loops,
latch_edge,
if (exit)
nloop->single_exit = find_edge (get_bb_copy (exit->src), exit->dest);
- /* loopify redirected latch_edge. Update its PENDING_STMTS. */
+ /* loopify redirected latch_edge. Update its PENDING_STMTS. */
lv_flush_pending_stmts (latch_edge);
- /* loopify redirected condition_bb's succ edge. Update its PENDING_STMTS. */
+ /* loopify redirected condition_bb's succ edge. Update its PENDING_STMTS. */
extract_cond_bb_edges (cond_bb, &true_edge, &false_edge);
lv_flush_pending_stmts (false_edge);
/* Adjust irreducible flag. */
free (bbs);
}
- /* At this point condition_bb is loop predheader with two successors,
- first_head and second_head. Make sure that loop predheader has only
+ /* At this point condition_bb is loop predheader with two successors,
+ first_head and second_head. Make sure that loop predheader has only
one successor. */
loop_split_edge_with (loop_preheader_edge (loop), NULL);
loop_split_edge_with (loop_preheader_edge (nloop), NULL);
to be correct). But still for the remaining loops the header dominates
the latch, and loops did not get new subloobs (new loops might possibly
get created, but we are not interested in them). Fix up the mess.
-
+
If CHANGED_BBS is not NULL, basic blocks whose loop has changed are
marked in it. */
}
/* Remove the dead loops from structures. */
- loops->tree_root->num_nodes = n_basic_blocks;
+ loops->tree_root->num_nodes = n_basic_blocks;
for (i = 1; i < loops->num; i++)
{
loop = loops->parray[i];