aboutsummaryrefslogtreecommitdiff
path: root/gcc/cfglayout.c
diff options
context:
space:
mode:
authorZdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>2003-07-04 01:50:05 +0200
committerZdenek Dvorak <rakdver@gcc.gnu.org>2003-07-03 23:50:05 +0000
commit8d28e87da7134b1ba6de7add4457a8b20687edd3 (patch)
treef71a6c934abe134dd6b13c539736910da43d4680 /gcc/cfglayout.c
parent694abeb6a7e64ba5aa18d9ae579585cb41dd53ee (diff)
downloadgcc-8d28e87da7134b1ba6de7add4457a8b20687edd3.zip
gcc-8d28e87da7134b1ba6de7add4457a8b20687edd3.tar.gz
gcc-8d28e87da7134b1ba6de7add4457a8b20687edd3.tar.bz2
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
Diffstat (limited to 'gcc/cfglayout.c')
-rw-r--r--gcc/cfglayout.c156
1 files changed, 142 insertions, 14 deletions
diff --git a/gcc/cfglayout.c b/gcc/cfglayout.c
index a576f0e..3a6b925 100644
--- a/gcc/cfglayout.c
+++ b/gcc/cfglayout.c
@@ -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"