diff options
author | Jan Hubicka <hubicka@gcc.gnu.org> | 2004-06-19 15:33:06 +0000 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2004-06-19 15:33:06 +0000 |
commit | 242229bbdc6beacddb4ed263c759d3ca52dae927 (patch) | |
tree | 2ee8a7629143f7f2514ddf9a48376c6ac3d11bc0 /gcc/tree-cfg.c | |
parent | ff98621c682005e2a224f62c1aa5028353a5357e (diff) | |
download | gcc-242229bbdc6beacddb4ed263c759d3ca52dae927.zip gcc-242229bbdc6beacddb4ed263c759d3ca52dae927.tar.gz gcc-242229bbdc6beacddb4ed263c759d3ca52dae927.tar.bz2 |
CFG transparent RTL expansion:
* Makefile.in (cfgexpand.o): New object file.
(builtins.o): Add dependency on basic-block.h
* builtins.c: Include basic-block.h
(entry_of_function): New function.
(expand_builtin_apply_args, expand_builtin_saveargs): Use it.
* cfgexpand.c: New file.
* expr.c (execute_expand, pass_expand): Kill.
* pass.c (rest_of_compilation): Do not build CFG unless called from
coverage code.
* tree-cfg.c (delete_tree_cfg): Rename to..
(delete_tree_cfg_annotations): ... this one; Do not remove the CFG itself.
* tree-flow.h (delete_tree_cfg_annotations): Declare.
(dleete_tree_cfg): Kill.
* tree-optimize.c (execute_rebuild_bind, pass_rebuild_bind): Kill.
(execute_del_cfg): Rename to...
(execute_free_datastructures): This one...
(pass_del_cfg): Rename to...
(pass_free_datastructures): ... this one; Do not kill PROP_cfg.
(init_tree_optimization_passes): Make cfg build and profiling to happen
unconditionally.
* tree-mudflap.c (mf_decl_cache_locals): Skip labels before
inserting the cache variables.
* tree-mudflap.c: Include headers to make basic_block available.
Move functions around such that related functions are near each
other. Add prototypes for all static functions. Add comments
briefly explaining what IR the mudflap1 and mudflap2 work on and
what they do.
(mudflap_function_decls): Rename to execute_mudflap_function_decls.
(mudflap_function_ops): Rename to execute_mudflap_function_ops.
(pass_mudflap_1, pass_mudflap_2): Update.
(mf_decl_cache_locals): Make it work on the CFG instead of the saved
function tree.
(mf_build_check_statement_for): Make it work on the CFG.
(mf_xform_derefs_1): Likewise. Cleanup code style.
(mf_xform_derefs): Likewise.
* tree-cfg.c (label_to_block): Invent the label destination for
undefined labels.
(cleanup_dead_labels): Update table in the case label_to_block added
new label.
From-SVN: r83385
Diffstat (limited to 'gcc/tree-cfg.c')
-rw-r--r-- | gcc/tree-cfg.c | 68 |
1 files changed, 44 insertions, 24 deletions
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c index 1fad3da..243a654 100644 --- a/gcc/tree-cfg.c +++ b/gcc/tree-cfg.c @@ -619,7 +619,21 @@ make_switch_expr_edges (basic_block bb) basic_block label_to_block (tree dest) { - return VARRAY_BB (label_to_block_map, LABEL_DECL_UID (dest)); + int uid = LABEL_DECL_UID (dest); + + /* We would die hard when faced by undefined label. Emit label to + very first basic block. This will hopefully make even the dataflow + and undefined variable warnings quite right. */ + if ((errorcount || sorrycount) && uid < 0) + { + block_stmt_iterator bsi = bsi_start (BASIC_BLOCK (0)); + tree stmt; + + stmt = build1 (LABEL_EXPR, void_type_node, dest); + bsi_insert_before (&bsi, stmt, BSI_NEW_STMT); + uid = LABEL_DECL_UID (dest); + } + return VARRAY_BB (label_to_block_map, uid); } @@ -756,6 +770,18 @@ update_eh_label (struct eh_region *region) } } +/* Given LABEL return the first label in the same basic block. */ +static tree +main_block_label (tree label) +{ + basic_block bb = label_to_block (label); + + /* label_to_block possibly inserted undefined label into the chain. */ + if (!label_for_bb[bb->index]) + label_for_bb[bb->index] = label; + return label_for_bb[bb->index]; +} + /* Cleanup redundant labels. This is a three-steo process: 1) Find the leading label for each block. 2) Redirect all references to labels to the leading labels. @@ -815,15 +841,14 @@ cleanup_dead_labels (void) case COND_EXPR: { tree true_branch, false_branch; - basic_block true_bb, false_bb; true_branch = COND_EXPR_THEN (stmt); false_branch = COND_EXPR_ELSE (stmt); - true_bb = label_to_block (GOTO_DESTINATION (true_branch)); - false_bb = label_to_block (GOTO_DESTINATION (false_branch)); - GOTO_DESTINATION (true_branch) = label_for_bb[true_bb->index]; - GOTO_DESTINATION (false_branch) = label_for_bb[false_bb->index]; + GOTO_DESTINATION (true_branch) + = main_block_label (GOTO_DESTINATION (true_branch)); + GOTO_DESTINATION (false_branch) + = main_block_label (GOTO_DESTINATION (false_branch)); break; } @@ -836,12 +861,8 @@ cleanup_dead_labels (void) /* Replace all destination labels. */ for (i = 0; i < n; ++i) - { - tree label = CASE_LABEL (TREE_VEC_ELT (vec, i)); - - CASE_LABEL (TREE_VEC_ELT (vec, i)) = - label_for_bb[label_to_block (label)->index]; - } + CASE_LABEL (TREE_VEC_ELT (vec, i)) + = main_block_label (CASE_LABEL (TREE_VEC_ELT (vec, i))); break; } @@ -849,13 +870,12 @@ cleanup_dead_labels (void) /* We have to handle GOTO_EXPRs until they're removed, and we don't remove them until after we've created the CFG edges. */ case GOTO_EXPR: - { - tree label = GOTO_DESTINATION (stmt); - if (! computed_goto_p (stmt)) - GOTO_DESTINATION (stmt) = - label_for_bb[label_to_block (label)->index]; - break; - } + if (! computed_goto_p (stmt)) + { + GOTO_DESTINATION (stmt) + = main_block_label (GOTO_DESTINATION (stmt)); + break; + } default: break; @@ -2636,19 +2656,19 @@ disband_implicit_edges (void) } } - -/* Remove all the blocks and edges that make up the flowgraph. */ +/* Remove block annotations and other datastructures. */ void -delete_tree_cfg (void) +delete_tree_cfg_annotations (void) { + basic_block bb; if (n_basic_blocks > 0) free_blocks_annotations (); - free_basic_block_vars (); - basic_block_info = NULL; label_to_block_map = NULL; free_rbi_pool (); + FOR_EACH_BB (bb) + bb->rbi = NULL; } |