diff options
author | steven <steven@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-06-17 21:08:39 +0000 |
---|---|---|
committer | steven <steven@138bc75d-0d04-0410-961f-82ee72b054a4> | 2012-06-17 21:08:39 +0000 |
commit | 23a070f3288838226d6b9fa688ccce70de8d4d9a (patch) | |
tree | 1716ec5f5eb641fe82e493441959f78d3212142b /gcc/cfghooks.c | |
parent | aedb7bf8a9ee16ca0326af295b8888a85c367ccf (diff) | |
download | gcc-23a070f3288838226d6b9fa688ccce70de8d4d9a.tar.gz |
2012-06-17 Steven Bosscher <steven@gcc.gnu.org>
* cfglayout.h: Remove.
* cfglayout.c: Remove.
* function.h (struct function): Remove x_last_location field.
* function.c: Do not include cfglayout.h.
(expand_function_start): Do not call no-op force_next_line_note.
(expand_function_end): Likewise.
* cfgrtl.c: Do not include cfglayout.h. Include gt-cfgrtl.h.
(unlink_insn_chain): Moved here from cfglayout.c.
(skip_insns_after_block, label_for_bb, record_effective_endpoints,
into_cfg_layout_mode, outof_cfg_layout_mode,
pass_into_cfg_layout_mode, pass_outof_cfg_layout_mode,
relink_block_chain, fixup_reorder_chain, verify_insn_chain,
fixup_fallthru_exit_predecessor, force_one_exit_fallthru,
cfg_layout_can_duplicate_bb_p, duplicate_insn_chain,
cfg_layout_duplicate_bb, cfg_layout_initialize, break_superblocks,
cfg_layout_finalize): Likewise.
(rtl_can_remove_branch_p): Likewise.
* rtl.h (insn_scope): Move prototype from cfglayout.h here.
(duplicate_insn_chain): Likewise.
(force_next_line_note): Remove prototype.
* emit-rtl.c: Do not include tree-flow.h, egad. Include vecprim.h.
(last_location): Remove #define to emit.x_last_location.
(force_next_line_note): Remove no-op function.
(init_emit): Don't set x_last_location.
(block_locators_locs, block_locators_blocks, locations_locators_locs,
locations_locators_vals, prologue_locator, epilogue_locator,
curr_location, last_location, curr_block, last_block, curr_rtl_loc):
Move POD to here from cfglayout.c.
(insn_locators_alloc, insn_locators_finalize, insn_locators_free,
set_curr_insn_source_location, get_curr_insn_source_location,
set_curr_insn_block, get_curr_insn_block, curr_insn_locator,
locator_scope, insn_scope, locator_location, locator_line, insn_line,
locator_file, insn_file, locator_eq): Move to here from cfglayout.c.
* cfghooks.h: Remove double-include protection.
(can_copy_bbs_p, copy_bbs): Move prototypes from cfglayout.h to here.
* cfghooks.c (can_copy_bbs_p, copy_bbs): Move to here from cfglayout.c.
* final.c: Do not include cfglayout.h.
(choose_inner_scope, change_scope): Move to here from cfglayout.c.
(reemit_insn_block_notes): Likewise. Make static.
* tree-flow.h (tree_could_trap_p, operation_could_trap_helper_p,
operation_could_trap_p, tree_could_throw_p): Move from here...
* tree.h: ... to here.
* gengtype.c (open_base_files): Remove cfglayout.h from the list.
* profile.c: Do not include cfghooks.h.
* cfgloopmanip.c: Do not include cfglayout.h and cfghooks.h.
* modulo-sched.c: Likewise.
* loop-unswitch.c: Do not include cfglayout.h.
* sched-ebb.c: Likewise.
* tracer.c: Likewise.
* ddg.c: Likewise.
* tree-vect-loop-manip.c: Likewise.
* loop-init.c: Likewise.
* dwarf2out.c: Likewise.
* hw-doloop.c: Likewise.
* loop-unroll.c: Likewise.
* cfgcleanup.c: Likewise.
* bb-reorder.c: Likewise.
* sched-rgn.c: Likewise.
* tree-cfg.c: Likewise.
* config/alpha/alpha.c: Likewise.
* config/spu/spu.c: Likewise.
* config/sparc/sparc.c: Likewise.
* config/sh/sh.c: Likewise.
* config/c6x/c6x.c: Likewise.
* config/ia64/ia64.c: Likewise.
* config/rs6000/rs6000.c: Likewise.
* config/score/score.c: Likewise.
* config/mips/mips.c: Likewise.
* config/bfin/bfin.c: Likewise.
* Makefile.in (CFGAYOUT_H): Remove, and fixup users.
* config/rs6000/t-rs6000 (rs6000.o): Do not depend on cfglayout.h.
* config/spu/t-spu-elf (spu.o: $): Likewise.
* config/sparc/t-sparc (sparc.o): Do not depend on CFGLAYOUT_H.
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@188712 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/cfghooks.c')
-rw-r--r-- | gcc/cfghooks.c | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/gcc/cfghooks.c b/gcc/cfghooks.c index bc1b7a2f582..5b49d64f090 100644 --- a/gcc/cfghooks.c +++ b/gcc/cfghooks.c @@ -1161,3 +1161,124 @@ lv_add_condition_to_bb (basic_block first, basic_block second, gcc_assert (cfg_hooks->lv_add_condition_to_bb); cfg_hooks->lv_add_condition_to_bb (first, second, new_block, cond); } + +/* 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]->flags |= BB_DUPLICATED; + + for (i = 0; i < n; i++) + { + /* In case we should redirect abnormal edge during duplication, fail. */ + edge_iterator ei; + FOR_EACH_EDGE (e, ei, bbs[i]->succs) + if ((e->flags & EDGE_ABNORMAL) + && (e->dest->flags & BB_DUPLICATED)) + { + ret = false; + goto end; + } + + if (!can_duplicate_block_p (bbs[i])) + { + ret = false; + break; + } + } + +end: + for (i = 0; i < n; i++) + bbs[i]->flags &= ~BB_DUPLICATED; + + 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. + + Newly created basic blocks are put after the basic block AFTER in the + instruction stream, and the order of the blocks in BBS array is preserved. */ + +void +copy_bbs (basic_block *bbs, unsigned n, basic_block *new_bbs, + edge *edges, unsigned num_edges, edge *new_edges, + struct loop *base, basic_block after) +{ + 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] = duplicate_block (bb, NULL, after); + after = new_bb; + bb->flags |= BB_DUPLICATED; + /* Possibly set loop 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 (CDI_DOMINATORS, bb); + if (dom_bb->flags & BB_DUPLICATED) + { + dom_bb = get_bb_copy (dom_bb); + set_immediate_dominator (CDI_DOMINATORS, new_bb, dom_bb); + } + } + + /* Redirect edges. */ + for (j = 0; j < num_edges; j++) + new_edges[j] = NULL; + for (i = 0; i < n; i++) + { + edge_iterator ei; + new_bb = new_bbs[i]; + bb = bbs[i]; + + FOR_EACH_EDGE (e, ei, new_bb->succs) + { + for (j = 0; j < num_edges; j++) + if (edges[j] && edges[j]->src == bb && edges[j]->dest == e->dest) + new_edges[j] = e; + + if (!(e->dest->flags & BB_DUPLICATED)) + continue; + redirect_edge_and_branch_force (e, get_bb_copy (e->dest)); + } + } + + /* Clear information about duplicates. */ + for (i = 0; i < n; i++) + bbs[i]->flags &= ~BB_DUPLICATED; +} + |