X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Fcfghooks.c;h=ad5fb6b6c4cb2f37744c91b73a6a28f2e1b4d797;hb=c8665f5923cd8c92e6c46a20d60b0d974f33d0f5;hp=921bf6fe291e4836320ed5a9ded7c94ecc61ed70;hpb=5493cb9ab6c5e787f31e54d400c418b3becba440;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/cfghooks.c b/gcc/cfghooks.c index 921bf6fe291..ad5fb6b6c4c 100644 --- a/gcc/cfghooks.c +++ b/gcc/cfghooks.c @@ -1,5 +1,6 @@ /* Hooks for cfg representation specific functions. - Copyright (C) 2003, 2004, 2005, 2007 Free Software Foundation, Inc. + Copyright (C) 2003, 2004, 2005, 2007, 2008 Free Software Foundation, + Inc. Contributed by Sebastian Pop This file is part of GCC. @@ -50,9 +51,21 @@ cfg_layout_rtl_register_cfg_hooks (void) /* Initialization of functions specific to the tree IR. */ void -tree_register_cfg_hooks (void) +gimple_register_cfg_hooks (void) { - cfg_hooks = &tree_cfg_hooks; + cfg_hooks = &gimple_cfg_hooks; +} + +struct cfg_hooks +get_cfg_hooks (void) +{ + return *cfg_hooks; +} + +void +set_cfg_hooks (struct cfg_hooks new_cfg_hooks) +{ + *cfg_hooks = new_cfg_hooks; } /* Returns current ir type. */ @@ -60,7 +73,7 @@ tree_register_cfg_hooks (void) enum ir_type current_ir_type (void) { - if (cfg_hooks == &tree_cfg_hooks) + if (cfg_hooks == &gimple_cfg_hooks) return IR_GIMPLE; else if (cfg_hooks == &rtl_cfg_hooks) return IR_RTL_CFGRTL; @@ -290,7 +303,7 @@ dump_bb (basic_block bb, FILE *outf, int indent) putc ('\n', outf); if (cfg_hooks->dump_bb) - cfg_hooks->dump_bb (bb, outf, indent); + cfg_hooks->dump_bb (bb, outf, indent, 0); } /* Redirect edge E to the given basic block DEST and update underlying program @@ -412,6 +425,7 @@ edge split_block (basic_block bb, void *i) { basic_block new_bb; + edge res; if (!cfg_hooks->split_block) internal_error ("%s does not support split_block", cfg_hooks->name); @@ -423,6 +437,7 @@ split_block (basic_block bb, void *i) new_bb->count = bb->count; new_bb->frequency = bb->frequency; new_bb->loop_depth = bb->loop_depth; + new_bb->discriminator = bb->discriminator; if (dom_info_available_p (CDI_DOMINATORS)) { @@ -437,7 +452,15 @@ split_block (basic_block bb, void *i) bb->loop_father->latch = new_bb; } - return make_single_succ_edge (bb, new_bb, EDGE_FALLTHRU); + res = make_single_succ_edge (bb, new_bb, EDGE_FALLTHRU); + + if (bb->flags & BB_IRREDUCIBLE_LOOP) + { + new_bb->flags |= BB_IRREDUCIBLE_LOOP; + res->flags |= EDGE_IRREDUCIBLE_LOOP; + } + + return res; } /* Splits block BB just after labels. The newly created edge is returned. */ @@ -616,7 +639,7 @@ create_empty_bb (basic_block after) /* Checks whether we may merge blocks BB1 and BB2. */ bool -can_merge_blocks_p (const_basic_block bb1, const_basic_block bb2) +can_merge_blocks_p (basic_block bb1, basic_block bb2) { bool ret; @@ -718,6 +741,8 @@ make_forwarder_block (basic_block bb, bool (*redirect_edge_p) (edge), /* Redirect back edges we want to keep. */ for (ei = ei_start (dummy->preds); (e = ei_safe_edge (ei)); ) { + basic_block e_src; + if (redirect_edge_p (e)) { ei_next (&ei); @@ -734,10 +759,21 @@ make_forwarder_block (basic_block bb, bool (*redirect_edge_p) (edge), if (fallthru->count < 0) fallthru->count = 0; + e_src = e->src; jump = redirect_edge_and_branch_force (e, bb); - if (jump != NULL - && new_bb_cbk != NULL) - new_bb_cbk (jump); + if (jump != NULL) + { + /* If we redirected the loop latch edge, the JUMP block now acts like + the new latch of the loop. */ + if (current_loops != NULL + && dummy->loop_father != NULL + && dummy->loop_father->header == dummy + && dummy->loop_father->latch == e_src) + dummy->loop_father->latch = jump; + + if (new_bb_cbk != NULL) + new_bb_cbk (jump); + } } if (dom_info_available_p (CDI_DOMINATORS)) @@ -794,7 +830,7 @@ tidy_fallthru_edge (edge e) /* Fix up edges that now fall through, or rather should now fall through but previously required a jump around now deleted blocks. Simplify the search by only examining blocks numerically adjacent, since this - is how find_basic_blocks created them. */ + is how they were created. */ void tidy_fallthru_edges (void) @@ -817,9 +853,9 @@ tidy_fallthru_edges (void) a single successor. If we had a conditional branch to the next instruction when - find_basic_blocks was called, then there will only be one - out edge for the block which ended with the conditional - branch (since we do not create duplicate edges). + CFG was built, then there will only be one out edge for the + block which ended with the conditional branch (since we do + not create duplicate edges). Furthermore, the edge will be marked as a fallthru because we merge the flags for the duplicate edges. So we do not want to @@ -938,7 +974,7 @@ duplicate_block (basic_block bb, edge e, basic_block after) instructions that must stay with the call, 0 otherwise. */ bool -block_ends_with_call_p (const_basic_block bb) +block_ends_with_call_p (basic_block bb) { if (!cfg_hooks->block_ends_with_call_p) internal_error ("%s does not support block_ends_with_call_p", cfg_hooks->name); @@ -1029,7 +1065,7 @@ cfg_hook_duplicate_loop_to_header_edge (struct loop *loop, edge e, /* Conditional jumps are represented differently in trees and RTL, this hook takes a basic block that is known to have a cond jump - at its end and extracts the taken and not taken eges out of it + at its end and extracts the taken and not taken edges out of it and store it in E1 and E2 respectively. */ void extract_cond_bb_edges (basic_block b, edge *e1, edge *e2)