Commit 8d28e87d by Zdenek Dvorak Committed by Zdenek Dvorak

cfglayout.c (cfg_layout_duplicate_bb): Do not update frequencies at all if edge is not specified.

	* cfglayout.c (cfg_layout_duplicate_bb): Do not update frequencies
	at all if edge is not specified.
	(can_copy_bbs_p, copy_bbs): New.
	* cfglayout.h (can_copy_bbs_p, copy_bbs): Declare.
	* cfgloop.c (get_loop_body): Comment more precisely.
	* cfgloopmanip.c (copy_bbs, record_exit_edges): Removed.
	(scale_bbs_frequencies): Fix comment typo.
	(can_duplicate_loop_p): Use can_copy_bbs_p.
	(duplicate_loop_to_header_edge): Simplify by using copy_bbs.

From-SVN: r68906
parent 694abeb6
2003-07-03 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
* cfglayout.c (cfg_layout_duplicate_bb): Do not update frequencies
at all if edge is not specified.
(can_copy_bbs_p, copy_bbs): New.
* cfglayout.h (can_copy_bbs_p, copy_bbs): Declare.
* cfgloop.c (get_loop_body): Comment more precisely.
* cfgloopmanip.c (copy_bbs, record_exit_edges): Removed.
(scale_bbs_frequencies): Fix comment typo.
(can_duplicate_loop_p): Use can_copy_bbs_p.
(duplicate_loop_to_header_edge): Simplify by using copy_bbs.
2003-07-03 Devang Patel <dpatel@apple.com>
* c-opts.c (c_common_parse_file): Remove extra
......
......@@ -985,7 +985,9 @@ duplicate_insn_chain (rtx from, rtx to)
delete_insn (last);
return insn;
}
/* Create a duplicate of the basic block BB and redirect edge E into it. */
/* Create a duplicate of the basic block BB and redirect edge E into it.
If E is not specified, BB is just copied, but updating the frequencies
etc. is left to the caller. */
basic_block
cfg_layout_duplicate_bb (basic_block bb, edge e)
......@@ -1046,32 +1048,41 @@ cfg_layout_duplicate_bb (basic_block bb, edge e)
is no need to actually check for duplicated edges. */
n = unchecked_make_edge (new_bb, s->dest, s->flags);
n->probability = s->probability;
if (new_count)
/* Take care for overflows! */
n->count = s->count * (new_count * 10000 / bb->count) / 10000;
if (e && bb->count)
{
/* Take care for overflows! */
n->count = s->count * (new_count * 10000 / bb->count) / 10000;
s->count -= n->count;
}
else
n->count = 0;
s->count -= n->count;
n->count = s->count;
n->aux = s->aux;
}
new_bb->count = new_count;
bb->count -= new_count;
if (e)
{
new_bb->count = new_count;
bb->count -= new_count;
new_bb->frequency = EDGE_FREQUENCY (e);
bb->frequency -= EDGE_FREQUENCY (e);
redirect_edge_and_branch_force (e, new_bb);
}
if (bb->count < 0)
bb->count = 0;
if (bb->frequency < 0)
bb->frequency = 0;
if (bb->count < 0)
bb->count = 0;
if (bb->frequency < 0)
bb->frequency = 0;
}
else
{
new_bb->count = bb->count;
new_bb->frequency = bb->frequency;
}
new_bb->rbi->original = bb;
bb->rbi->copy = new_bb;
return new_bb;
}
......@@ -1167,4 +1178,121 @@ cfg_layout_finalize (void)
#endif
}
/* Checks whether all N blocks in BBS array can be copied. */
bool
can_copy_bbs_p (basic_block *bbs, unsigned n)
{
unsigned i;
edge e;
int ret = true;
for (i = 0; i < n; i++)
bbs[i]->rbi->duplicated = 1;
for (i = 0; i < n; i++)
{
/* In case we should redirect abnormal edge during duplication, fail. */
for (e = bbs[i]->succ; e; e = e->succ_next)
if ((e->flags & EDGE_ABNORMAL)
&& e->dest->rbi->duplicated)
{
ret = false;
goto end;
}
if (!cfg_layout_can_duplicate_bb_p (bbs[i]))
{
ret = false;
break;
}
}
end:
for (i = 0; i < n; i++)
bbs[i]->rbi->duplicated = 0;
return ret;
}
/* Duplicates N basic blocks stored in array BBS. Newly created basic blocks
are placed into array NEW_BBS in the same order. Edges from basic blocks
in BBS are also duplicated and copies of those of them
that lead into BBS are redirected to appropriate newly created block. The
function assigns bbs into loops (copy of basic block bb is assigned to
bb->loop_father->copy loop, so this must be set up correctly in advance)
and updates dominators locally (LOOPS structure that contains the information
about dominators is passed to enable this).
BASE is the superloop to that basic block belongs; if its header or latch
is copied, we do not set the new blocks as header or latch.
Created copies of N_EDGES edges in array EDGES are stored in array NEW_EDGES,
also in the same order. */
void
copy_bbs (basic_block *bbs, unsigned n, basic_block *new_bbs,
edge *edges, unsigned n_edges, edge *new_edges,
struct loop *base, struct loops *loops)
{
unsigned i, j;
basic_block bb, new_bb, dom_bb;
edge e;
/* Duplicate bbs, update dominators, assign bbs to loops. */
for (i = 0; i < n; i++)
{
/* Duplicate. */
bb = bbs[i];
new_bb = new_bbs[i] = cfg_layout_duplicate_bb (bb, NULL);
bb->rbi->duplicated = 1;
/* Add to loop. */
add_bb_to_loop (new_bb, bb->loop_father->copy);
add_to_dominance_info (loops->cfg.dom, new_bb);
/* Possibly set header. */
if (bb->loop_father->header == bb && bb->loop_father != base)
new_bb->loop_father->header = new_bb;
/* Or latch. */
if (bb->loop_father->latch == bb && bb->loop_father != base)
new_bb->loop_father->latch = new_bb;
}
/* Set dominators. */
for (i = 0; i < n; i++)
{
bb = bbs[i];
new_bb = new_bbs[i];
dom_bb = get_immediate_dominator (loops->cfg.dom, bb);
if (dom_bb->rbi->duplicated)
{
dom_bb = dom_bb->rbi->copy;
set_immediate_dominator (loops->cfg.dom, new_bb, dom_bb);
}
}
/* Redirect edges. */
for (j = 0; j < n_edges; j++)
new_edges[j] = NULL;
for (i = 0; i < n; i++)
{
new_bb = new_bbs[i];
bb = bbs[i];
for (e = new_bb->succ; e; e = e->succ_next)
{
for (j = 0; j < n_edges; j++)
if (edges[j] && edges[j]->src == bb && edges[j]->dest == e->dest)
new_edges[j] = e;
if (!e->dest->rbi->duplicated)
continue;
redirect_edge_and_branch_force (e, e->dest->rbi->copy);
}
}
/* Clear information about duplicates. */
for (i = 0; i < n; i++)
bbs[i]->rbi->duplicated = 0;
}
#include "gt-cfglayout.h"
......@@ -41,4 +41,7 @@ extern bool cfg_layout_can_duplicate_bb_p (basic_block);
extern basic_block cfg_layout_duplicate_bb (basic_block, edge);
extern void insn_locators_initialize (void);
extern void reemit_insn_block_notes (void);
extern bool can_copy_bbs_p (basic_block *, unsigned);
extern void copy_bbs (basic_block *, unsigned, basic_block *,
edge *, unsigned, edge *, struct loop *, struct loops *);
extern void cfg_layout_initialize_rbi (basic_block);
......@@ -960,7 +960,9 @@ glb_enum_p (basic_block bb, void *glb_header)
return bb != (basic_block) glb_header;
}
/* Gets basic blocks of a loop. */
/* Gets basic blocks of a LOOP. Header is the 0-th block, rest is in dfs
order against direction of edges from latch. Specially, if
header != latch, latch is the 1-st block. */
basic_block *
get_loop_body (const struct loop *loop)
{
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment