tree-cfg.c File Reference

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "tm.h"
#include "tree.h"
#include "rtl.h"
#include "tm_p.h"
#include "hard-reg-set.h"
#include "basic-block.h"
#include "output.h"
#include "flags.h"
#include "function.h"
#include "expr.h"
#include "ggc.h"
#include "langhooks.h"
#include "diagnostic.h"
#include "tree-flow.h"
#include "timevar.h"
#include "tree-dump.h"
#include "tree-pass.h"
#include "toplev.h"
#include "except.h"
#include "cfgloop.h"
#include "cfglayout.h"
#include "hashtab.h"
#include "tree-ssa-propagate.h"

Include dependency graph for tree-cfg.c:

Go to the source code of this file.

Data Structures

struct  edge_to_cases_elt
struct  cfg_stats_d
struct  rus_data
struct  move_stmt_d

Defines

#define CHECK_OP(N, MSG)

Functions

static basic_block create_bb (void *, void *, basic_block)
static void make_blocks (tree)
static void factor_computed_gotos (void)
static void make_edges (void)
static void make_cond_expr_edges (basic_block)
static void make_switch_expr_edges (basic_block)
static void make_goto_expr_edges (basic_block)
static edge tree_redirect_edge_and_branch (edge, basic_block)
static edge tree_try_redirect_by_replacing_jump (edge, basic_block)
static unsigned int split_critical_edges (void)
static bool stmt_starts_bb_p (tree, tree)
static int tree_verify_flow_info (void)
static void tree_make_forwarder_block (edge)
static void tree_cfg2vcg (FILE *)
static void change_bb_for_stmt (tree t, basic_block bb)
static void tree_merge_blocks (basic_block, basic_block)
static bool tree_can_merge_blocks_p (basic_block, basic_block)
static void remove_bb (basic_block)
static edge find_taken_edge_computed_goto (basic_block, tree)
static edge find_taken_edge_cond_expr (basic_block, tree)
static edge find_taken_edge_switch_expr (basic_block, tree)
static tree find_case_label_for_value (tree, tree)
void init_empty_tree_cfg ()
static void build_tree_cfg ()
static unsigned int execute_build_cfg ()
static void make_blocks ()
static basic_block create_bb ()
void fold_cond_expr_cond ()
static void make_cond_expr_edges ()
static hashval_t edge_to_cases_hash ()
static int edge_to_cases_eq ()
static void edge_to_cases_cleanup ()
void start_recording_case_labels ()
static bool recording_case_labels_p ()
void end_recording_case_labels ()
static void record_switch_edge ()
static tree get_cases_for_edge ()
static void make_switch_expr_edges ()
basic_block label_to_block_fn ()
static void make_goto_expr_edges ()
static void update_eh_label ()
static tree main_block_label ()
void cleanup_dead_labels ()
void group_case_labels ()
static bool tree_can_merge_blocks_p ()
void replace_uses_by ()
static void tree_merge_blocks ()
basic_block single_noncomplex_succ ()
static void remove_useless_stmts_1 (tree *, struct rus_data *)
static bool remove_useless_stmts_warn_notreached ()
static void remove_useless_stmts_cond ()
static void remove_useless_stmts_tf ()
static void remove_useless_stmts_tc ()
static void remove_useless_stmts_bind ()
static void remove_useless_stmts_goto ()
static void remove_useless_stmts_label ()
static void update_call_expr_flags ()
void notice_special_calls ()
void clear_special_calls ()
static void remove_useless_stmts_1 ()
static unsigned int remove_useless_stmts ()
static void remove_phi_nodes_and_edges_for_unreachable_block ()
static void remove_bb ()
edge find_taken_edge ()
static edge find_taken_edge_computed_goto ()
static edge find_taken_edge_cond_expr ()
static edge find_taken_edge_switch_expr ()
static tree find_case_label_for_value ()
void tree_dump_bb ()
void debug_tree_bb ()
basic_block debug_tree_bb_n ()
void debug_tree_cfg ()
void dump_tree_cfg ()
void dump_cfg_stats ()
void debug_cfg_stats ()
static void tree_cfg2vcg ()
bool is_ctrl_stmt ()
bool is_ctrl_altering_stmt ()
bool computed_goto_p ()
bool simple_goto_p ()
static bool stmt_starts_bb_p ()
bool stmt_ends_bb_p ()
void disband_implicit_edges ()
void delete_tree_cfg_annotations ()
tree first_stmt ()
tree last_stmt ()
tree * last_stmt_ptr ()
tree last_and_only_stmt ()
void set_bb_for_stmt ()
static void change_bb_for_stmt ()
block_stmt_iterator bsi_for_stmt ()
static void update_modified_stmts ()
void bsi_insert_before ()
void bsi_insert_after ()
void bsi_remove ()
void bsi_move_after ()
void bsi_move_before ()
void bsi_move_to_bb_end ()
void bsi_replace ()
static bool tree_find_edge_insert_loc (edge e, block_stmt_iterator *bsi, basic_block *new_bb)
void bsi_commit_edge_inserts ()
void bsi_commit_one_edge_insert ()
void bsi_insert_on_edge ()
basic_block bsi_insert_on_edge_immediate ()
static void reinstall_phi_args ()
static basic_block split_edge_bb_loc ()
static basic_block tree_split_edge ()
static bool has_label_p ()
static tree verify_expr ()
static bool verify_stmt ()
static bool tree_node_can_be_shared ()
static tree verify_node_sharing ()
void verify_stmts ()
static void tree_make_forwarder_block ()
tree tree_block_label ()
static edge tree_try_redirect_by_replacing_jump ()
static edge tree_redirect_edge_and_branch ()
static basic_block tree_redirect_edge_and_branch_force ()
static basic_block tree_split_block ()
static bool tree_move_block_after ()
static bool tree_can_duplicate_bb_p ()
static basic_block tree_duplicate_bb ()
void add_phi_args_after_copy_bb ()
void add_phi_args_after_copy ()
bool tree_duplicate_sese_region (edge entry, edge exit, basic_block *region, unsigned n_region, basic_block *region_copy)
static void gather_blocks_in_sese_region (basic_block entry, basic_block exit, VEC(basic_block, heap)**bbs_p)
static tree move_stmt_r ()
static void move_block_to_fn (struct function *dest_cfun, basic_block bb, basic_block after, bool update_edge_count_p, bitmap vars_to_remove, htab_t new_label_map, int eh_offset)
static int find_outermost_region_in_block (struct function *src_cfun, basic_block bb, int region)
static tree new_label_mapper ()
basic_block move_sese_region_to_fn (struct function *dest_cfun, basic_block entry_bb, basic_block exit_bb)
void dump_function_to_file ()
void debug_function ()
static void print_loop (FILE *, struct loop *, int)
static void print_pred_bbs (FILE *, basic_block bb)
static void print_succ_bbs (FILE *, basic_block bb)
static void print_pred_bbs ()
static void print_succ_bbs ()
static void print_loop ()
void print_loop_ir ()
void debug_loop_ir ()
static bool tree_block_ends_with_call_p ()
static bool tree_block_ends_with_condjump_p ()
static bool need_fake_edge_p ()
static int tree_flow_call_edges_add ()
bool tree_purge_dead_eh_edges ()
bool tree_purge_all_dead_eh_edges ()
static void tree_execute_on_growing_pred ()
static void tree_execute_on_shrinking_pred ()
static void tree_lv_adjust_loop_header_phi (basic_block first, basic_block second, basic_block new_head, edge e)
static void tree_lv_add_condition_to_bb (basic_block first_head, basic_block second_head, basic_block cond_bb, void *cond_e)
tree gimplify_val ()
tree gimplify_build3 (block_stmt_iterator *bsi, enum tree_code code, tree type, tree a, tree b, tree c)
tree gimplify_build2 (block_stmt_iterator *bsi, enum tree_code code, tree type, tree a, tree b)
tree gimplify_build1 (block_stmt_iterator *bsi, enum tree_code code, tree type, tree a)
static unsigned int execute_warn_function_return ()
void extract_true_false_edges_from_block (basic_block b, edge *true_edge, edge *false_edge)
static unsigned int execute_warn_function_noreturn ()

Variables

static const int initial_cfg_capacity = 20
static htab_t edge_to_cases
static struct cfg_stats_d cfg_stats
static bool found_computed_goto
tree_opt_pass pass_build_cfg
static tree * label_for_bb
tree_opt_pass pass_remove_useless_stmts
cfg_hooks tree_cfg_hooks
tree_opt_pass pass_split_crit_edges
tree_opt_pass pass_warn_function_return
tree_opt_pass pass_warn_function_noreturn


Define Documentation

#define CHECK_OP N,
MSG   ) 
 

Value:

do { if (!is_gimple_val (TREE_OPERAND (t, N)))          \
       { error (MSG); return TREE_OPERAND (t, N); }} while (0)

Referenced by verify_expr().


Function Documentation

void add_phi_args_after_copy  ) 
 

Blocks in REGION_COPY array of length N_REGION were created by
   duplication of basic blocks.  Add phi node arguments for edges
   going from these blocks.   

Definition at line 4360 of file tree-cfg.c.

References add_phi_args_after_copy_bb().

04361 {
04362   unsigned i;
04363 
04364   for (i = 0; i < n_region; i++)
04365     region_copy[i]->flags |= BB_DUPLICATED;
04366 
04367   for (i = 0; i < n_region; i++)
04368     add_phi_args_after_copy_bb (region_copy[i]);
04369 
04370   for (i = 0; i < n_region; i++)
04371     region_copy[i]->flags &= ~BB_DUPLICATED;
04372 }

void add_phi_args_after_copy_bb  ) 
 

Basic block BB_COPY was created by code duplication.  Add phi node
   arguments for edges going out of BB_COPY.  The blocks that were
   duplicated have BB_DUPLICATED set.   

Definition at line 4311 of file tree-cfg.c.

References add_phi_arg(), PHI_ARG_DEF_FROM_EDGE, PHI_CHAIN, and phi_nodes().

Referenced by add_phi_args_after_copy(), and copy_phi_node_args().

04312 {
04313   basic_block bb, dest;
04314   edge e, e_copy;
04315   edge_iterator ei;
04316   tree phi, phi_copy, phi_next, def;
04317 
04318   bb = get_bb_original (bb_copy);
04319 
04320   FOR_EACH_EDGE (e_copy, ei, bb_copy->succs)
04321     {
04322       if (!phi_nodes (e_copy->dest))
04323         continue;
04324 
04325       if (e_copy->dest->flags & BB_DUPLICATED)
04326         dest = get_bb_original (e_copy->dest);
04327       else
04328         dest = e_copy->dest;
04329 
04330       e = find_edge (bb, dest);
04331       if (!e)
04332         {
04333           /* During loop unrolling the target of the latch edge is copied.
04334              In this case we are not looking for edge to dest, but to
04335              duplicated block whose original was dest.  */
04336           FOR_EACH_EDGE (e, ei, bb->succs)
04337             if ((e->dest->flags & BB_DUPLICATED)
04338                 && get_bb_original (e->dest) == dest)
04339               break;
04340 
04341           gcc_assert (e != NULL);
04342         }
04343 
04344       for (phi = phi_nodes (e->dest), phi_copy = phi_nodes (e_copy->dest);
04345            phi;
04346            phi = phi_next, phi_copy = PHI_CHAIN (phi_copy))
04347         {
04348           phi_next = PHI_CHAIN (phi);
04349           def = PHI_ARG_DEF_FROM_EDGE (phi, e);
04350           add_phi_arg (phi_copy, def, e_copy);
04351         }
04352     }
04353 }

void bsi_commit_edge_inserts void   ) 
 

This routine will commit all pending edge insertions, creating any new
   basic blocks which are necessary.   

Definition at line 3045 of file tree-cfg.c.

References bsi_commit_one_edge_insert().

Referenced by execute_pre(), loop_commit_inserts(), mf_decl_cache_locals(), process_assert_insertions(), scalarize_function(), tree_flow_call_edges_add(), and tree_lower_complex().

03046 {
03047   basic_block bb;
03048   edge e;
03049   edge_iterator ei;
03050 
03051   bsi_commit_one_edge_insert (single_succ_edge (ENTRY_BLOCK_PTR), NULL);
03052 
03053   FOR_EACH_BB (bb)
03054     FOR_EACH_EDGE (e, ei, bb->succs)
03055       bsi_commit_one_edge_insert (e, NULL);
03056 }

void bsi_commit_one_edge_insert  ) 
 

Commit insertions pending at edge E. If a new block is created, set NEW_BB
   to this block, otherwise set it to NULL.   

Definition at line 3063 of file tree-cfg.c.

References bsi_insert_after(), bsi_insert_before(), BSI_NEW_STMT, NULL_TREE, PENDING_STMT, and tree_find_edge_insert_loc().

Referenced by analyze_edges_for_bb(), and bsi_commit_edge_inserts().

03064 {
03065   if (new_bb)
03066     *new_bb = NULL;
03067   if (PENDING_STMT (e))
03068     {
03069       block_stmt_iterator bsi;
03070       tree stmt = PENDING_STMT (e);
03071 
03072       PENDING_STMT (e) = NULL_TREE;
03073 
03074       if (tree_find_edge_insert_loc (e, &bsi, new_bb))
03075         bsi_insert_after (&bsi, stmt, BSI_NEW_STMT);
03076       else
03077         bsi_insert_before (&bsi, stmt, BSI_NEW_STMT);
03078     }
03079 }

block_stmt_iterator bsi_for_stmt  ) 
 

Finds iterator for STMT.   

Definition at line 2799 of file tree-cfg.c.

References bb_for_stmt(), bsi_end_p(), bsi_next(), bsi_start, and bsi_stmt().

02800 {
02801   block_stmt_iterator bsi;
02802 
02803   for (bsi = bsi_start (bb_for_stmt (stmt)); !bsi_end_p (bsi); bsi_next (&bsi))
02804     if (bsi_stmt (bsi) == stmt)
02805       return bsi;
02806 
02807   gcc_unreachable ();
02808 }

void bsi_insert_after  ) 
 

Insert statement (or statement list) T after the statement
   pointed-to by iterator I.  M specifies how to update iterator I
   after insertion (see enum bsi_iterator_update).   

Definition at line 2846 of file tree-cfg.c.

References block_stmt_iterator::bb, set_bb_for_stmt(), block_stmt_iterator::tsi, tsi_link_after(), and update_modified_stmts().

Referenced by abs_replacement(), adjust_accumulator_values(), adjust_return_value(), bsi_commit_one_edge_insert(), bsi_insert_on_edge_immediate(), bsi_move_after(), copy_bb(), create_iv(), determine_invariantness_stmt(), disband_implicit_edges(), expand_call_inline(), expand_complex_div_wide(), factor_computed_gotos(), insert_backedge_copies(), insert_fake_stores(), insert_reciprocals(), mf_build_check_statement_for(), process_assert_insertions_for(), rewrite_use_nonlinear_expr(), slpeel_add_loop_guard(), sra_insert_after(), tree_lv_add_condition_to_bb(), tree_merge_blocks(), tree_unroll_loop(), update_complex_components(), and vect_create_epilog_for_reduction().

02847 {
02848   set_bb_for_stmt (t, i->bb);
02849   update_modified_stmts (t);
02850   tsi_link_after (&i->tsi, t, m);
02851 }

void bsi_insert_before  ) 
 

Insert statement (or statement list) T before the statement
   pointed-to by iterator I.  M specifies how to update iterator I
   after insertion (see enum bsi_iterator_update).   

Definition at line 2833 of file tree-cfg.c.

References block_stmt_iterator::bb, set_bb_for_stmt(), block_stmt_iterator::tsi, tsi_link_before(), and update_modified_stmts().

Referenced by abs_replacement(), add_to_dst_predicate_list(), adjust_return_value(), bsi_commit_one_edge_insert(), bsi_insert_on_edge_immediate(), bsi_move_before(), convert_to_gimple_builtin(), create_iv(), expand_complex_div_wide(), expand_complex_move(), factor_computed_gotos(), find_phi_replacement_condition(), force_gimple_operand_bsi(), gimplify_val(), insert_backedge_copies(), insert_reciprocals(), issue_prefetch_ref(), label_to_block_fn(), minmax_replacement(), realify_fake_stores(), remove_bb(), replace_phi_with_cond_modify_expr(), rewrite_use_compare(), rewrite_use_nonlinear_expr(), slpeel_make_loop_iterate_ntimes(), sra_insert_before(), tree_find_edge_insert_loc(), tree_gen_interval_profiler(), tree_gen_one_value_profiler(), tree_gen_pow2_profiler(), vect_finish_stmt_generation(), vect_pattern_recog_1(), vect_transform_loop(), and vect_update_ivs_after_vectorizer().

02834 {
02835   set_bb_for_stmt (t, i->bb);
02836   update_modified_stmts (t);
02837   tsi_link_before (&i->tsi, t, m);
02838 }

void bsi_insert_on_edge  ) 
 

Add STMT to the pending list of edge E.  No actual insertion is
   made until a call to bsi_commit_edge_inserts () is made.   

Definition at line 3086 of file tree-cfg.c.

References append_to_statement_list(), and PENDING_STMT.

Referenced by insert_copy_on_edge(), insert_edge_copies(), insert_into_preds_of_block(), move_computations_stmt(), process_assert_insertions_for(), schedule_sm(), tree_flow_call_edges_add(), tree_gen_edge_profiler(), and update_complex_components_on_edge().

03087 {
03088   append_to_statement_list (stmt, &PENDING_STMT (e));
03089 }

basic_block bsi_insert_on_edge_immediate  ) 
 

Similar to bsi_insert_on_edge+bsi_commit_edge_inserts.  If a new
   block has to be created, it is returned.   

Definition at line 3095 of file tree-cfg.c.

References bsi_insert_after(), bsi_insert_before(), BSI_NEW_STMT, PENDING_STMT, and tree_find_edge_insert_loc().

Referenced by bsi_insert_on_edge_immediate_loop(), vect_build_loop_niters(), vect_create_data_ref_ptr(), vect_gen_niters_for_prolog_loop(), vect_generate_tmps_on_preheader(), vect_init_vector(), and vectorizable_load().

03096 {
03097   block_stmt_iterator bsi;
03098   basic_block new_bb = NULL;
03099 
03100   gcc_assert (!PENDING_STMT (e));
03101 
03102   if (tree_find_edge_insert_loc (e, &bsi, &new_bb))
03103     bsi_insert_after (&bsi, stmt, BSI_NEW_STMT);
03104   else
03105     bsi_insert_before (&bsi, stmt, BSI_NEW_STMT);
03106 
03107   return new_bb;
03108 }

void bsi_move_after  ) 
 

Move the statement at FROM so it comes right after the statement at TO.   

Definition at line 2880 of file tree-cfg.c.

References bsi_insert_after(), bsi_remove(), BSI_SAME_STMT, and bsi_stmt().

Referenced by bsi_move_to_bb_end().

02881 {
02882   tree stmt = bsi_stmt (*from);
02883   bsi_remove (from, false);
02884   bsi_insert_after (to, stmt, BSI_SAME_STMT);
02885 }

void bsi_move_before  ) 
 

Move the statement at FROM so it comes right before the statement at TO.   

Definition at line 2891 of file tree-cfg.c.

References bsi_insert_before(), bsi_remove(), BSI_SAME_STMT, and bsi_stmt().

Referenced by bsi_move_to_bb_end(), expand_call_inline(), linearize_expr(), linearize_expr_tree(), minmax_replacement(), sink_code_in_bb(), and tree_block_label().

02892 {
02893   tree stmt = bsi_stmt (*from);
02894   bsi_remove (from, false);
02895   bsi_insert_before (to, stmt, BSI_SAME_STMT);
02896 }

void bsi_move_to_bb_end  ) 
 

Move the statement at FROM to the end of basic block BB.   

Definition at line 2902 of file tree-cfg.c.

References bsi_end_p(), bsi_last, bsi_move_after(), bsi_move_before(), bsi_stmt(), and is_ctrl_stmt().

Referenced by sink_code_in_bb().

02903 {
02904   block_stmt_iterator last = bsi_last (bb);
02905 
02906   /* Have to check bsi_end_p because it could be an empty block.  */
02907   if (!bsi_end_p (last) && is_ctrl_stmt (bsi_stmt (last)))
02908     bsi_move_before (from, &last);
02909   else
02910     bsi_move_after (from, &last);
02911 }

void bsi_remove  ) 
 

Remove the statement pointed to by iterator I.  The iterator is updated
   to the next statement.

   When REMOVE_EH_INFO is true we remove the statement pointed to by
   iterator I from the EH tables.  Otherwise we do not modify the EH
   tables.

   Generally, REMOVE_EH_INFO should be true when the statement is going to
   be removed from the IL and not reinserted elsewhere.   

Definition at line 2865 of file tree-cfg.c.

References bsi_stmt(), delink_stmt_imm_use(), mark_stmt_modified(), remove_stmt_from_eh_region(), set_bb_for_stmt(), block_stmt_iterator::tsi, and tsi_delink().

Referenced by bsi_move_after(), bsi_move_before(), disband_implicit_edges(), dse_optimize_stmt(), eliminate_tail_call(), expand_call_inline(), expand_complex_div_wide(), forward_propagate_into_cond(), make_goto_expr_edges(), move_computations_stmt(), propagate_rhs_into_lhs(), realify_fake_stores(), remove_bb(), remove_ctrl_stmt_and_useless_edges(), remove_dead_stmt(), remove_range_assertions(), remove_statement(), remove_stmt_or_phi(), replace_phi_edge_with_variable(), slpeel_make_loop_iterate_ntimes(), sra_replace(), tree_if_convert_cond_expr(), tree_redirect_edge_and_branch(), tree_ssa_forward_propagate_single_use_vars(), tree_try_redirect_by_replacing_jump(), and VEC().

02866 {
02867   tree t = bsi_stmt (*i);
02868   set_bb_for_stmt (t, NULL);
02869   delink_stmt_imm_use (t);
02870   tsi_delink (&i->tsi);
02871   mark_stmt_modified (t);
02872   if (remove_eh_info)
02873     remove_stmt_from_eh_region (t);
02874 }

void bsi_replace  ) 
 

Replace the contents of the statement pointed to by iterator BSI
   with STMT.  If UPDATE_EH_INFO is true, the exception handling
   information of the original statement is moved to the new statement.   

Definition at line 2919 of file tree-cfg.c.

References add_stmt_to_eh_region(), block_stmt_iterator::bb, bsi_stmt(), bsi_stmt_ptr(), delink_stmt_imm_use(), EXPR_LOCUS, lookup_stmt_eh_region(), mark_stmt_modified(), remove_stmt_from_eh_region(), set_bb_for_stmt(), SET_EXPR_LOCUS, and update_modified_stmts().

Referenced by adjust_return_value(), determine_invariantness_stmt(), and scalarize_ldst().

02920 {
02921   int eh_region;
02922   tree orig_stmt = bsi_stmt (*bsi);
02923 
02924   SET_EXPR_LOCUS (stmt, EXPR_LOCUS (orig_stmt));
02925   set_bb_for_stmt (stmt, bsi->bb);
02926 
02927   /* Preserve EH region information from the original statement, if
02928      requested by the caller.  */
02929   if (update_eh_info)
02930     {
02931       eh_region = lookup_stmt_eh_region (orig_stmt);
02932       if (eh_region >= 0)
02933         {
02934           remove_stmt_from_eh_region (orig_stmt);
02935           add_stmt_to_eh_region (stmt, eh_region);
02936         }
02937     }
02938 
02939   delink_stmt_imm_use (orig_stmt);
02940   *bsi_stmt_ptr (*bsi) = stmt;
02941   mark_stmt_modified (stmt);
02942   update_modified_stmts (stmt);
02943 }

static void build_tree_cfg  )  [static]
 

Entry point to the CFG builder for trees.  TP points to the list of
   statements to be added to the flowgraph.   

Definition at line 159 of file tree-cfg.c.

References cfg_stats, cleanup_dead_labels(), dump_begin(), dump_end(), dump_file, dump_flags, dump_tree_cfg(), factor_computed_gotos(), found_computed_goto, group_case_labels(), init_empty_tree_cfg(), make_blocks(), make_edges(), TDI_vcg, tree_cfg2vcg(), and verify_stmts().

Referenced by execute_build_cfg().

00160 {
00161   /* Register specific tree functions.  */
00162   tree_register_cfg_hooks ();
00163 
00164   memset ((void *) &cfg_stats, 0, sizeof (cfg_stats));
00165 
00166   init_empty_tree_cfg ();
00167 
00168   found_computed_goto = 0;
00169   make_blocks (*tp);
00170 
00171   /* Computed gotos are hell to deal with, especially if there are
00172      lots of them with a large number of destinations.  So we factor
00173      them to a common computed goto location before we build the
00174      edge list.  After we convert back to normal form, we will un-factor
00175      the computed gotos since factoring introduces an unwanted jump.  */
00176   if (found_computed_goto)
00177     factor_computed_gotos ();
00178 
00179   /* Make sure there is always at least one block, even if it's empty.  */
00180   if (n_basic_blocks == NUM_FIXED_BLOCKS)
00181     create_empty_bb (ENTRY_BLOCK_PTR);
00182 
00183   /* Adjust the size of the array.  */
00184   if (VEC_length (basic_block, basic_block_info) < (size_t) n_basic_blocks)
00185     {
00186       size_t old_size = VEC_length (basic_block, basic_block_info);
00187       basic_block *p;
00188       VEC_safe_grow (basic_block, gc, basic_block_info, n_basic_blocks);
00189       p = VEC_address (basic_block, basic_block_info);
00190       memset (&p[old_size], 0,
00191               sizeof (basic_block) * (n_basic_blocks - old_size));
00192     }
00193 
00194   /* To speed up statement iterator walks, we first purge dead labels.  */
00195   cleanup_dead_labels ();
00196 
00197   /* Group case nodes to reduce the number of edges.
00198      We do this after cleaning up dead labels because otherwise we miss
00199      a lot of obvious case merging opportunities.  */
00200   group_case_labels ();
00201 
00202   /* Create the edges of the flowgraph.  */
00203   make_edges ();
00204 
00205   /* Debugging dumps.  */
00206 
00207   /* Write the flowgraph to a VCG file.  */
00208   {
00209     int local_dump_flags;
00210     FILE *vcg_file = dump_begin (TDI_vcg, &local_dump_flags);
00211     if (vcg_file)
00212       {
00213         tree_cfg2vcg (vcg_file);
00214         dump_end (TDI_vcg, vcg_file);
00215       }
00216   }
00217 
00218 #ifdef ENABLE_CHECKING
00219   verify_stmts ();
00220 #endif
00221 
00222   /* Dump a textual representation of the flowgraph.  */
00223   if (dump_file)
00224     dump_tree_cfg (dump_file, dump_flags);
00225 }

static void change_bb_for_stmt  )  [inline, static]
 

Faster version of set_bb_for_stmt that assume that statement is being moved
   from one basic block to another.  
   For BB splitting we can run into quadratic case, so performance is quite
   important and knowing that the tables are big enough, change_bb_for_stmt
   can inline as leaf function.   

Definition at line 2788 of file tree-cfg.c.

References stmt_ann_d::bb, get_stmt_ann, LABEL_DECL_UID, LABEL_EXPR_LABEL, and TREE_CODE.

02789 {
02790   get_stmt_ann (t)->bb = bb;
02791   if (TREE_CODE (t) == LABEL_EXPR)
02792     VEC_replace (basic_block, label_to_block_map,
02793                  LABEL_DECL_UID (LABEL_EXPR_LABEL (t)), bb);
02794 }

static void change_bb_for_stmt tree  t,
basic_block  bb
[inline, static]
 

void cleanup_dead_labels void   ) 
 

Cleanup redundant labels.  This is a three-step process:
     1) Find the leading label for each block.
     2) Redirect all references to labels to the leading labels.
     3) Cleanup all useless labels.   

Definition at line 965 of file tree-cfg.c.

References bsi_end_p(), bsi_next(), bsi_start, bsi_stmt(), DECL_ARTIFICIAL, LABEL_EXPR_LABEL, label_for_bb, and TREE_CODE.

Referenced by build_tree_cfg(), and execute_cleanup_cfg_post_optimizing().

00966 {
00967   basic_block bb;
00968   label_for_bb = XCNEWVEC (tree, last_basic_block);
00969 
00970   /* Find a suitable label for each block.  We use the first user-defined
00971      label if there is one, or otherwise just the first label we see.  */
00972   FOR_EACH_BB (bb)
00973     {
00974       block_stmt_iterator i;
00975 
00976       for (i = bsi_start (bb); !bsi_end_p (i); bsi_next (&i))
00977         {
00978           tree label, stmt = bsi_stmt (i);
00979 
00980           if (TREE_CODE (stmt) != LABEL_EXPR)
00981             break;
00982 
00983           label = LABEL_EXPR_LABEL (stmt);
00984 
00985           /* If we have not yet seen a label for the current block,
00986              remember this one and see if there are more labels.  */
00987           if (! label_for_bb[bb->index])
00988             {
00989               label_for_bb[bb->index] = label;
00990               continue;
00991             }
00992 
00993           /* If we did see a label for the current block already, but it
00994              is an artificially created label, replace it if the current
00995              label is a user defined label.  */
00996           if (! DECL_ARTIFICIAL (label)
00997               && DECL_ARTIFICIAL (label_for_bb[bb->index]))
00998             {
00999               label_for_bb[bb->index] = label;
01000               break;
01001             }
01002         }
01003     }
01004 
01005   /* Now redirect all jumps/branches to the selected label.
01006      First do so for each block ending in a control statement.  */
01007   FOR_EACH_BB (bb)
01008     {
01009       tree stmt = last_stmt (bb);
01010       if (!stmt)
01011         continue;
01012 
01013       switch (TREE_CODE (stmt))
01014         {
01015         case COND_EXPR:
01016           {
01017             tree true_branch, false_branch;
01018 
01019             true_branch = COND_EXPR_THEN (stmt);
01020             false_branch = COND_EXPR_ELSE (stmt);
01021 
01022             GOTO_DESTINATION (true_branch)
01023               = main_block_label (GOTO_DESTINATION (true_branch));
01024             GOTO_DESTINATION (false_branch)
01025               = main_block_label (GOTO_DESTINATION (false_branch));
01026 
01027             break;
01028           }
01029 
01030         case SWITCH_EXPR:
01031           {
01032             size_t i;
01033             tree vec = SWITCH_LABELS (stmt);
01034             size_t n = TREE_VEC_LENGTH (vec);
01035 
01036             /* Replace all destination labels.  */
01037             for (i = 0; i < n; ++i)
01038               {
01039                 tree elt = TREE_VEC_ELT (vec, i);
01040                 tree label = main_block_label (CASE_LABEL (elt));
01041                 CASE_LABEL (elt) = label;
01042               }
01043             break;
01044           }
01045 
01046         /* We have to handle GOTO_EXPRs until they're removed, and we don't
01047            remove them until after we've created the CFG edges.  */
01048         case GOTO_EXPR:
01049           if (! computed_goto_p (stmt))
01050             {
01051               GOTO_DESTINATION (stmt)
01052                 = main_block_label (GOTO_DESTINATION (stmt));
01053               break;
01054             }
01055 
01056         default:
01057           break;
01058       }
01059     }
01060 
01061   for_each_eh_region (update_eh_label);
01062 
01063   /* Finally, purge dead labels.  All user-defined labels and labels that
01064      can be the target of non-local gotos and labels which have their
01065      address taken are preserved.  */
01066   FOR_EACH_BB (bb)
01067     {
01068       block_stmt_iterator i;
01069       tree label_for_this_bb = label_for_bb[bb->index];
01070 
01071       if (! label_for_this_bb)
01072         continue;
01073 
01074       for (i = bsi_start (bb); !bsi_end_p (i); )
01075         {
01076           tree label, stmt = bsi_stmt (i);
01077 
01078           if (TREE_CODE (stmt) != LABEL_EXPR)
01079             break;
01080 
01081           label = LABEL_EXPR_LABEL (stmt);
01082 
01083           if (label == label_for_this_bb
01084               || ! DECL_ARTIFICIAL (label)
01085               || DECL_NONLOCAL (label)
01086               || FORCED_LABEL (label))
01087             bsi_next (&i);
01088           else
01089             bsi_remove (&i, true);
01090         }
01091     }
01092 
01093   free (label_for_bb);
01094 }

void clear_special_calls void   ) 
 

Clear flags set by notice_special_calls.  Used by dead code removal
   to update the flags.   

Definition at line 1838 of file tree-cfg.c.

Referenced by eliminate_unnecessary_stmts(), and remove_useless_stmts().

01839 {
01840   current_function_calls_alloca = false;
01841   current_function_calls_setjmp = false;
01842 }

bool computed_goto_p  ) 
 

Return true if T is a computed goto.   

Definition at line 2513 of file tree-cfg.c.

References GOTO_DESTINATION, and TREE_CODE.

Referenced by factor_computed_gotos(), find_taken_edge(), and make_blocks().

02514 {
02515   return (TREE_CODE (t) == GOTO_EXPR
02516           && TREE_CODE (GOTO_DESTINATION (t)) != LABEL_DECL);
02517 }

static basic_block create_bb  )  [static]
 

Create and return a new empty basic block after bb AFTER.   

Definition at line 378 of file tree-cfg.c.

References alloc_stmt_list().

00379 {
00380   basic_block bb;
00381 
00382   gcc_assert (!e);
00383 
00384   /* Create and initialize a new basic block.  Since alloc_block uses
00385      ggc_alloc_cleared to allocate a basic block, we do not have to
00386      clear the newly allocated basic block here.  */
00387   bb = alloc_block ();
00388 
00389   bb->index = last_basic_block;
00390   bb->flags = BB_NEW;
00391   bb->stmt_list = h ? (tree) h : alloc_stmt_list ();
00392 
00393   /* Add the new block to the linked list of blocks.  */
00394   link_block (bb, after);
00395 
00396   /* Grow the basic block array if needed.  */
00397   if ((size_t) last_basic_block == VEC_length (basic_block, basic_block_info))
00398     {
00399       size_t old_size = VEC_length (basic_block, basic_block_info);
00400       size_t new_size = last_basic_block + (last_basic_block + 3) / 4;
00401       basic_block *p;
00402       VEC_safe_grow (basic_block, gc, basic_block_info, new_size);
00403       p = VEC_address (basic_block, basic_block_info);
00404       memset (&p[old_size], 0, sizeof (basic_block) * (new_size - old_size));
00405     }
00406 
00407   /* Add the newly created block to the array.  */
00408   SET_BASIC_BLOCK (last_basic_block, bb);
0040