diff options
author | Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz> | 2003-07-04 01:50:05 +0200 |
---|---|---|
committer | Zdenek Dvorak <rakdver@gcc.gnu.org> | 2003-07-03 23:50:05 +0000 |
commit | 8d28e87da7134b1ba6de7add4457a8b20687edd3 (patch) | |
tree | f71a6c934abe134dd6b13c539736910da43d4680 /gcc/cfglayout.c | |
parent | 694abeb6a7e64ba5aa18d9ae579585cb41dd53ee (diff) | |
download | gcc-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.c | 156 |
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" |