From: Eric Botcazou Date: Thu, 7 Apr 2011 21:11:51 +0000 (+0000) Subject: basic-block.h (force_nonfallthru): Move to... X-Git-Url: https://git.libre-soc.org/?a=commitdiff_plain;h=cf103ca449e8f5e38f42b107b3271b18c73c59a5;p=gcc.git basic-block.h (force_nonfallthru): Move to... * basic-block.h (force_nonfallthru): Move to... * cfghooks.h (struct cfg_hooks): Add force_nonfallthru hook. (force_nonfallthru): ...here. * cfghooks.c (force_nonfallthru): New function. * cfgrtl.c (force_nonfallthru): Rename into... (rtl_force_nonfallthru): ...this. (commit_one_edge_insertion): Do not set AUX field. (commit_edge_insertions): Do not discover new basic blocks. (rtl_cfg_hooks): Add rtl_force_nonfallthru. (cfg_layout_rtl_cfg_hooks): Likewise. * function.c (thread_prologue_and_epilogue_insns): Remove bogus ATTRIBUTE_UNUSED. Discover new basic blocks in the prologue insns. * tree-cfg.c (gimple_cfg_hooks): Add NULL for force_nonfallthru. From-SVN: r172128 --- diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f55348589b8..2c180856c1c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,19 @@ +2011-04-07 Eric Botcazou + + * basic-block.h (force_nonfallthru): Move to... + * cfghooks.h (struct cfg_hooks): Add force_nonfallthru hook. + (force_nonfallthru): ...here. + * cfghooks.c (force_nonfallthru): New function. + * cfgrtl.c (force_nonfallthru): Rename into... + (rtl_force_nonfallthru): ...this. + (commit_one_edge_insertion): Do not set AUX field. + (commit_edge_insertions): Do not discover new basic blocks. + (rtl_cfg_hooks): Add rtl_force_nonfallthru. + (cfg_layout_rtl_cfg_hooks): Likewise. + * function.c (thread_prologue_and_epilogue_insns): Remove bogus + ATTRIBUTE_UNUSED. Discover new basic blocks in the prologue insns. + * tree-cfg.c (gimple_cfg_hooks): Add NULL for force_nonfallthru. + 2011-04-07 Anatoly Sokolov * config/mips/mips.h (REG_MODE_OK_FOR_BASE_P, REG_OK_FOR_INDEX_P): diff --git a/gcc/basic-block.h b/gcc/basic-block.h index 2791fbc4184..946fe9d2ba1 100644 --- a/gcc/basic-block.h +++ b/gcc/basic-block.h @@ -794,7 +794,6 @@ extern void flow_nodes_print (const char *, const_sbitmap, FILE *); extern void flow_edge_list_print (const char *, const edge *, int, FILE *); /* In cfgrtl.c */ -extern basic_block force_nonfallthru (edge); extern rtx block_label (basic_block); extern bool purge_all_dead_edges (void); extern bool purge_dead_edges (basic_block); diff --git a/gcc/cfghooks.c b/gcc/cfghooks.c index fb991a76171..34685f4444a 100644 --- a/gcc/cfghooks.c +++ b/gcc/cfghooks.c @@ -398,8 +398,7 @@ redirect_edge_and_branch_force (edge e, basic_block dest) rescan_loop_exit (e, false, true); ret = cfg_hooks->redirect_edge_and_branch_force (e, dest); - if (ret != NULL - && dom_info_available_p (CDI_DOMINATORS)) + if (ret != NULL && dom_info_available_p (CDI_DOMINATORS)) set_immediate_dominator (CDI_DOMINATORS, ret, src); if (current_loops != NULL) @@ -820,6 +819,8 @@ make_forwarder_block (basic_block bb, bool (*redirect_edge_p) (edge), return fallthru; } +/* Try to make the edge fallthru. */ + void tidy_fallthru_edge (edge e) { @@ -874,6 +875,42 @@ tidy_fallthru_edges (void) } } +/* Edge E is assumed to be fallthru edge. Emit needed jump instruction + (and possibly create new basic block) to make edge non-fallthru. + Return newly created BB or NULL if none. */ + +basic_block +force_nonfallthru (edge e) +{ + basic_block ret, src = e->src, dest = e->dest; + struct loop *loop; + + if (!cfg_hooks->force_nonfallthru) + internal_error ("%s does not support force_nonfallthru", + cfg_hooks->name); + + if (current_loops != NULL) + rescan_loop_exit (e, false, true); + + ret = cfg_hooks->force_nonfallthru (e); + if (ret != NULL && dom_info_available_p (CDI_DOMINATORS)) + set_immediate_dominator (CDI_DOMINATORS, ret, src); + + if (current_loops != NULL) + { + if (ret != NULL) + { + loop = find_common_loop (single_pred (ret)->loop_father, + single_succ (ret)->loop_father); + add_bb_to_loop (ret, loop); + } + else if (find_edge (src, dest) == e) + rescan_loop_exit (e, true, false); + } + + return ret; +} + /* Returns true if we can duplicate basic block BB. */ bool diff --git a/gcc/cfghooks.h b/gcc/cfghooks.h index 574176805e2..9fd81acb0d3 100644 --- a/gcc/cfghooks.h +++ b/gcc/cfghooks.h @@ -85,9 +85,12 @@ struct cfg_hooks basic_block (*split_edge) (edge); void (*make_forwarder_block) (edge); - /* Tries to make the edge fallthru. */ + /* Try to make the edge fallthru. */ void (*tidy_fallthru_edge) (edge); + /* Make the edge non-fallthru. */ + basic_block (*force_nonfallthru) (edge); + /* Say whether a block ends with a call, possibly followed by some other code that must stay with the call. */ bool (*block_ends_with_call_p) (basic_block); @@ -156,6 +159,7 @@ extern bool can_merge_blocks_p (basic_block, basic_block); extern void merge_blocks (basic_block, basic_block); extern edge make_forwarder_block (basic_block, bool (*)(edge), void (*) (basic_block)); +extern basic_block force_nonfallthru (edge); extern void tidy_fallthru_edge (edge); extern void tidy_fallthru_edges (void); extern void predict_edge (edge e, enum br_predictor predictor, int probability); diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c index 9031886fb16..c450ca005a0 100644 --- a/gcc/cfgrtl.c +++ b/gcc/cfgrtl.c @@ -1279,8 +1279,8 @@ force_nonfallthru_and_redirect (edge e, basic_block target) (and possibly create new basic block) to make edge non-fallthru. Return newly created BB or NULL if none. */ -basic_block -force_nonfallthru (edge e) +static basic_block +rtl_force_nonfallthru (edge e) { return force_nonfallthru_and_redirect (e, e->dest); } @@ -1566,10 +1566,6 @@ commit_one_edge_insertion (edge e) } else gcc_assert (!JUMP_P (last)); - - /* Mark the basic block for find_many_sub_basic_blocks. */ - if (current_ir_type () != IR_RTL_CFGLAYOUT) - bb->aux = &bb->aux; } /* Update the CFG for all queued instructions. */ @@ -1578,8 +1574,6 @@ void commit_edge_insertions (void) { basic_block bb; - sbitmap blocks; - bool changed = false; #ifdef ENABLE_CHECKING verify_flow_info (); @@ -1592,35 +1586,8 @@ commit_edge_insertions (void) FOR_EACH_EDGE (e, ei, bb->succs) if (e->insns.r) - { - changed = true; - commit_one_edge_insertion (e); - } + commit_one_edge_insertion (e); } - - if (!changed) - return; - - /* In the old rtl CFG API, it was OK to insert control flow on an - edge, apparently? In cfglayout mode, this will *not* work, and - the caller is responsible for making sure that control flow is - valid at all times. */ - if (current_ir_type () == IR_RTL_CFGLAYOUT) - return; - - blocks = sbitmap_alloc (last_basic_block); - sbitmap_zero (blocks); - FOR_EACH_BB (bb) - if (bb->aux) - { - SET_BIT (blocks, bb->index); - /* Check for forgotten bb->aux values before commit_edge_insertions - call. */ - gcc_assert (bb->aux == &bb->aux); - bb->aux = NULL; - } - find_many_sub_basic_blocks (blocks); - sbitmap_free (blocks); } @@ -3233,6 +3200,7 @@ struct cfg_hooks rtl_cfg_hooks = { rtl_split_edge, rtl_make_forwarder_block, rtl_tidy_fallthru_edge, + rtl_force_nonfallthru, rtl_block_ends_with_call_p, rtl_block_ends_with_condjump_p, rtl_flow_call_edges_add, @@ -3276,7 +3244,8 @@ struct cfg_hooks cfg_layout_rtl_cfg_hooks = { cfg_layout_duplicate_bb, cfg_layout_split_edge, rtl_make_forwarder_block, - NULL, + NULL, /* tidy_fallthru_edge */ + rtl_force_nonfallthru, rtl_block_ends_with_call_p, rtl_block_ends_with_condjump_p, rtl_flow_call_edges_add, diff --git a/gcc/function.c b/gcc/function.c index 63ecd7c378d..14d21c97a42 100644 --- a/gcc/function.c +++ b/gcc/function.c @@ -5295,8 +5295,7 @@ thread_prologue_and_epilogue_insns (void) { bool inserted; rtx seq ATTRIBUTE_UNUSED, epilogue_end ATTRIBUTE_UNUSED; - edge entry_edge ATTRIBUTE_UNUSED; - edge e; + edge entry_edge, e; edge_iterator ei; rtl_profile_for_bb (ENTRY_BLOCK_PTR); @@ -5328,10 +5327,6 @@ thread_prologue_and_epilogue_insns (void) record_insns (seq, NULL, &prologue_insn_hash); set_insn_locators (seq, prologue_locator); - /* This relies on the fact that committing the edge insertion - will look for basic blocks within the inserted instructions, - which in turn relies on the fact that we are not in CFG - layout mode here. */ insert_insn_on_edge (seq, entry_edge); inserted = true; #endif @@ -5566,13 +5561,23 @@ thread_prologue_and_epilogue_insns (void) cur_bb->aux = cur_bb->next_bb; cfg_layout_finalize (); } + epilogue_done: default_rtl_profile (); if (inserted) { + sbitmap blocks; + commit_edge_insertions (); + /* Look for basic blocks within the prologue insns. */ + blocks = sbitmap_alloc (last_basic_block); + sbitmap_zero (blocks); + SET_BIT (blocks, entry_edge->dest->index); + find_many_sub_basic_blocks (blocks); + sbitmap_free (blocks); + /* The epilogue insns we inserted may cause the exit edge to no longer be fallthru. */ FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds) diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 8a47e2ff728..e6dac6fa0e2 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -7135,6 +7135,7 @@ struct cfg_hooks gimple_cfg_hooks = { gimple_split_edge, /* split_edge */ gimple_make_forwarder_block, /* make_forward_block */ NULL, /* tidy_fallthru_edge */ + NULL, /* force_nonfallthru */ gimple_block_ends_with_call_p,/* block_ends_with_call_p */ gimple_block_ends_with_condjump_p, /* block_ends_with_condjump_p */ gimple_flow_call_edges_add, /* flow_call_edges_add */