Commit 242229bb by Jan Hubicka

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
parent ff98621c
2004-06-19 Jan Hubicka <jh@suse.cz>
Steven Bosscher <stevenb@suse.de>
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.
2004-06-19 Steven Bosscher <stevenb@suse.de>
* 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.
2004-06-19 Jan Hubicka <jh@suse.cz>
* 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.
2004-06-18 Richard Henderson <rth@redhat.com> 2004-06-18 Richard Henderson <rth@redhat.com>
PR c++/16036 PR c++/16036
......
...@@ -916,7 +916,7 @@ OBJS-common = \ ...@@ -916,7 +916,7 @@ OBJS-common = \
targhooks.o timevar.o toplev.o tracer.o tree.o tree-dump.o unroll.o \ targhooks.o timevar.o toplev.o tracer.o tree.o tree-dump.o unroll.o \
varasm.o varray.o version.o vmsdbgout.o xcoffout.o alloc-pool.o \ varasm.o varray.o version.o vmsdbgout.o xcoffout.o alloc-pool.o \
et-forest.o cfghooks.o bt-load.o pretty-print.o $(GGC) web.o passes.o \ et-forest.o cfghooks.o bt-load.o pretty-print.o $(GGC) web.o passes.o \
rtl-profile.o tree-profile.o rtlhooks.o rtl-profile.o tree-profile.o rtlhooks.o cfgexpand.o
OBJS-md = $(out_object_file) OBJS-md = $(out_object_file)
OBJS-archive = $(EXTRA_OBJS) $(host_hook_obj) tree-inline.o \ OBJS-archive = $(EXTRA_OBJS) $(host_hook_obj) tree-inline.o \
...@@ -1793,7 +1793,7 @@ dojump.o : dojump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_ ...@@ -1793,7 +1793,7 @@ dojump.o : dojump.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_
builtins.o : builtins.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H)\ builtins.o : builtins.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H)\
$(TREE_GIMPLE_H) $(FLAGS_H) $(TARGET_H) function.h $(REGS_H) $(EXPR_H) $(OPTABS_H) \ $(TREE_GIMPLE_H) $(FLAGS_H) $(TARGET_H) function.h $(REGS_H) $(EXPR_H) $(OPTABS_H) \
insn-config.h $(RECOG_H) output.h typeclass.h hard-reg-set.h toplev.h hard-reg-set.h \ insn-config.h $(RECOG_H) output.h typeclass.h hard-reg-set.h toplev.h hard-reg-set.h \
except.h $(TM_P_H) $(PREDICT_H) libfuncs.h real.h langhooks.h except.h $(TM_P_H) $(PREDICT_H) libfuncs.h real.h langhooks.h basic-block.h
calls.o : calls.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) $(FLAGS_H) \ calls.o : calls.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) $(FLAGS_H) \
$(EXPR_H) $(OPTABS_H) langhooks.h $(TARGET_H) \ $(EXPR_H) $(OPTABS_H) langhooks.h $(TARGET_H) \
libfuncs.h $(REGS_H) toplev.h output.h function.h $(TIMEVAR_H) $(TM_P_H) cgraph.h except.h libfuncs.h $(REGS_H) toplev.h output.h function.h $(TIMEVAR_H) $(TM_P_H) cgraph.h except.h
...@@ -1930,6 +1930,9 @@ cfg.o : cfg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(FLAGS_H) in ...@@ -1930,6 +1930,9 @@ cfg.o : cfg.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(FLAGS_H) in
function.h except.h $(GGC_H) $(TM_P_H) alloc-pool.h $(TIMEVAR_H) function.h except.h $(GGC_H) $(TM_P_H) alloc-pool.h $(TIMEVAR_H)
cfghooks.o: cfghooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \ cfghooks.o: cfghooks.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
$(BASIC_BLOCK_H) $(CFGLAYOUT_H) $(TREE_FLOW_H) $(TIMEVAR_H) toplev.h $(BASIC_BLOCK_H) $(CFGLAYOUT_H) $(TREE_FLOW_H) $(TIMEVAR_H) toplev.h
cfgexpand.o : cfgexpand.c $(TREE_FLOW_H) $(CONFIG_H) $(SYSTEM_H) \
$(RTL_H) $(TREE_H) $(TM_P_H) $(EXPR_H) function.h $(TIMEVAR_H) $(TM_H) coretypes.h \
$(TREE_DUMP_H) except.h langhooks.h cfgloop.h gt-tree-cfg.h tree-pass.h $(RTL_H)
cfgrtl.o : cfgrtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(FLAGS_H) \ cfgrtl.o : cfgrtl.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(FLAGS_H) \
insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h $(RECOG_H) \ insn-config.h $(BASIC_BLOCK_H) $(REGS_H) hard-reg-set.h output.h toplev.h $(RECOG_H) \
function.h except.h $(GGC_H) $(TM_P_H) insn-config.h $(EXPR_H) function.h except.h $(GGC_H) $(TM_P_H) insn-config.h $(EXPR_H)
......
...@@ -45,6 +45,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA ...@@ -45,6 +45,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "tm_p.h" #include "tm_p.h"
#include "target.h" #include "target.h"
#include "langhooks.h" #include "langhooks.h"
#include "basic-block.h"
#define CALLED_AS_BUILT_IN(NODE) \ #define CALLED_AS_BUILT_IN(NODE) \
(!strncmp (IDENTIFIER_POINTER (DECL_NAME (NODE)), "__builtin_", 10)) (!strncmp (IDENTIFIER_POINTER (DECL_NAME (NODE)), "__builtin_", 10))
...@@ -1206,6 +1207,13 @@ expand_builtin_apply_args_1 (void) ...@@ -1206,6 +1207,13 @@ expand_builtin_apply_args_1 (void)
return copy_addr_to_reg (XEXP (registers, 0)); return copy_addr_to_reg (XEXP (registers, 0));
} }
/* Return RTX to emit after when we want to emit code on the entry of function. */
static rtx
entry_of_function (void)
{
return (n_basic_blocks ? BB_HEAD (ENTRY_BLOCK_PTR->next_bb) : get_insns ());
}
/* __builtin_apply_args returns block of memory allocated on /* __builtin_apply_args returns block of memory allocated on
the stack into which is stored the arg pointer, structure the stack into which is stored the arg pointer, structure
value address, static chain, and all the registers that might value address, static chain, and all the registers that might
...@@ -1239,7 +1247,7 @@ expand_builtin_apply_args (void) ...@@ -1239,7 +1247,7 @@ expand_builtin_apply_args (void)
chain current, so the code is placed at the start of the chain current, so the code is placed at the start of the
function. */ function. */
push_topmost_sequence (); push_topmost_sequence ();
emit_insn_before (seq, NEXT_INSN (get_insns ())); emit_insn_before (seq, NEXT_INSN (entry_of_function ()));
pop_topmost_sequence (); pop_topmost_sequence ();
return temp; return temp;
} }
...@@ -4010,7 +4018,7 @@ expand_builtin_saveregs (void) ...@@ -4010,7 +4018,7 @@ expand_builtin_saveregs (void)
is inside a start_sequence, make the outer-level insn chain current, so is inside a start_sequence, make the outer-level insn chain current, so
the code is placed at the start of the function. */ the code is placed at the start of the function. */
push_topmost_sequence (); push_topmost_sequence ();
emit_insn_after (seq, get_insns ()); emit_insn_after (seq, entry_of_function ());
pop_topmost_sequence (); pop_topmost_sequence ();
return val; return val;
......
This diff is collapsed. Click to expand it.
...@@ -168,7 +168,6 @@ static void emit_single_push_insn (enum machine_mode, rtx, tree); ...@@ -168,7 +168,6 @@ static void emit_single_push_insn (enum machine_mode, rtx, tree);
#endif #endif
static void do_tablejump (rtx, enum machine_mode, rtx, rtx, rtx); static void do_tablejump (rtx, enum machine_mode, rtx, rtx, rtx);
static rtx const_vector_from_tree (tree); static rtx const_vector_from_tree (tree);
static void execute_expand (void);
/* Record for each mode whether we can move a register directly to or /* Record for each mode whether we can move a register directly to or
from an object of that mode in memory. If we can't, we won't try from an object of that mode in memory. If we can't, we won't try
...@@ -10213,92 +10212,4 @@ const_vector_from_tree (tree exp) ...@@ -10213,92 +10212,4 @@ const_vector_from_tree (tree exp)
return gen_rtx_raw_CONST_VECTOR (mode, v); return gen_rtx_raw_CONST_VECTOR (mode, v);
} }
/* Called to move the SAVE_EXPRs for parameter declarations in a
nested function into the nested function. DATA is really the
nested FUNCTION_DECL. */
static tree
set_save_expr_context (tree *tp,
int *walk_subtrees,
void *data)
{
if (TREE_CODE (*tp) == SAVE_EXPR && !SAVE_EXPR_CONTEXT (*tp))
SAVE_EXPR_CONTEXT (*tp) = (tree) data;
/* Do not walk back into the SAVE_EXPR_CONTEXT; that will cause
circularity. */
else if (DECL_P (*tp))
*walk_subtrees = 0;
return NULL;
}
static void
execute_expand (void)
{
/* If the function has a variably modified type, there may be
SAVE_EXPRs in the parameter types. Their context must be set to
refer to this function; they cannot be expanded in the containing
function. */
if (decl_function_context (current_function_decl) == current_function_decl
&& variably_modified_type_p (TREE_TYPE (current_function_decl)))
walk_tree (&TREE_TYPE (current_function_decl), set_save_expr_context,
current_function_decl, NULL);
/* Expand the variables recorded during gimple lowering. This must
occur before the call to expand_function_start to ensure that
all used variables are expanded before we expand anything on the
PENDING_SIZES list. */
expand_used_vars ();
/* Set up parameters and prepare for return, for the function. */
expand_function_start (current_function_decl, 0);
/* If this function is `main', emit a call to `__main'
to run global initializers, etc. */
if (DECL_NAME (current_function_decl)
&& MAIN_NAME_P (DECL_NAME (current_function_decl))
&& DECL_FILE_SCOPE_P (current_function_decl))
expand_main_function ();
/* Generate the RTL for this function. */
expand_expr_stmt_value (DECL_SAVED_TREE (current_function_decl), 0, 0);
/* We hard-wired immediate_size_expand to zero above.
expand_function_end will decrement this variable. So, we set the
variable to one here, so that after the decrement it will remain
zero. */
immediate_size_expand = 1;
/* Make sure the locus is set to the end of the function, so that
epilogue line numbers and warnings are set properly. */
if (cfun->function_end_locus.file)
input_location = cfun->function_end_locus;
/* The following insns belong to the top scope. */
record_block_change (DECL_INITIAL (current_function_decl));
/* Generate rtl for function exit. */
expand_function_end ();
}
struct tree_opt_pass pass_expand =
{
"expand", /* name */
NULL, /* gate */
execute_expand, /* execute */
NULL, /* sub */
NULL, /* next */
0, /* static_pass_number */
TV_EXPAND, /* tv_id */
/* ??? If TER is enabled, we actually receive GENERIC. */
PROP_gimple_leh, /* properties_required */
PROP_rtl, /* properties_provided */
PROP_cfg | PROP_gimple_leh, /* properties_destroyed */
0, /* todo_flags_start */
0 /* todo_flags_finish */
};
#include "gt-expr.h" #include "gt-expr.h"
...@@ -1385,8 +1385,6 @@ rest_of_compilation (void) ...@@ -1385,8 +1385,6 @@ rest_of_compilation (void)
else else
finalize_block_changes (); finalize_block_changes ();
init_flow ();
/* Dump the rtl code if we are dumping rtl. */ /* Dump the rtl code if we are dumping rtl. */
if (open_dump_file (DFI_rtl, current_function_decl)) if (open_dump_file (DFI_rtl, current_function_decl))
close_dump_file (DFI_rtl, print_rtl, get_insns ()); close_dump_file (DFI_rtl, print_rtl, get_insns ());
...@@ -1443,11 +1441,21 @@ rest_of_compilation (void) ...@@ -1443,11 +1441,21 @@ rest_of_compilation (void)
timevar_push (TV_JUMP); timevar_push (TV_JUMP);
open_dump_file (DFI_sibling, current_function_decl); open_dump_file (DFI_sibling, current_function_decl);
rebuild_jump_labels (get_insns ());
find_exception_handler_labels ();
find_basic_blocks (get_insns (), max_reg_num (), dump_file);
/* ??? We may get called either via tree_rest_of_compilation when the CFG
is already built or directly (for instance from coverage code).
The direct callers shall be updated. */
if (!basic_block_info)
{
init_flow ();
rebuild_jump_labels (get_insns ());
find_exception_handler_labels ();
find_basic_blocks (get_insns (), max_reg_num (), dump_file);
}
delete_unreachable_blocks (); delete_unreachable_blocks ();
#ifdef ENABLE_CHECKING
verify_flow_info();
#endif
/* Turn NOTE_INSN_PREDICTIONs into branch predictions. */ /* Turn NOTE_INSN_PREDICTIONs into branch predictions. */
if (flag_guess_branch_prob) if (flag_guess_branch_prob)
...@@ -1515,10 +1523,8 @@ rest_of_compilation (void) ...@@ -1515,10 +1523,8 @@ rest_of_compilation (void)
if (flag_guess_branch_prob) if (flag_guess_branch_prob)
expected_value_to_br_prob (); expected_value_to_br_prob ();
reg_scan (get_insns (), max_reg_num (), 0);
rebuild_jump_labels (get_insns ());
find_basic_blocks (get_insns (), max_reg_num (), dump_file);
delete_trivially_dead_insns (get_insns (), max_reg_num ()); delete_trivially_dead_insns (get_insns (), max_reg_num ());
reg_scan (get_insns(), max_reg_num (), 0);
if (dump_file) if (dump_file)
dump_flow_info (dump_file); dump_flow_info (dump_file);
cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0) | CLEANUP_PRE_LOOP cleanup_cfg ((optimize ? CLEANUP_EXPENSIVE : 0) | CLEANUP_PRE_LOOP
......
...@@ -116,3 +116,6 @@ DEF_PREDICTOR (PRED_NEGATIVE_RETURN, "negative return", HITRATE (96), 0) ...@@ -116,3 +116,6 @@ DEF_PREDICTOR (PRED_NEGATIVE_RETURN, "negative return", HITRATE (96), 0)
/* Branch ending with return; is probably not taken */ /* Branch ending with return; is probably not taken */
DEF_PREDICTOR (PRED_NULL_RETURN, "null return", HITRATE (90), 0) DEF_PREDICTOR (PRED_NULL_RETURN, "null return", HITRATE (90), 0)
/* Branches to a mudflap bounds check are extremely unlikely. */
DEF_PREDICTOR (PRED_MUDFLAP, "mudflap check", HITRATE (99), 0)
...@@ -619,7 +619,21 @@ make_switch_expr_edges (basic_block bb) ...@@ -619,7 +619,21 @@ make_switch_expr_edges (basic_block bb)
basic_block basic_block
label_to_block (tree dest) 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) ...@@ -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: /* Cleanup redundant labels. This is a three-steo process:
1) Find the leading label for each block. 1) Find the leading label for each block.
2) Redirect all references to labels to the leading labels. 2) Redirect all references to labels to the leading labels.
...@@ -815,15 +841,14 @@ cleanup_dead_labels (void) ...@@ -815,15 +841,14 @@ cleanup_dead_labels (void)
case COND_EXPR: case COND_EXPR:
{ {
tree true_branch, false_branch; tree true_branch, false_branch;
basic_block true_bb, false_bb;
true_branch = COND_EXPR_THEN (stmt); true_branch = COND_EXPR_THEN (stmt);
false_branch = COND_EXPR_ELSE (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 (true_branch)
GOTO_DESTINATION (false_branch) = label_for_bb[false_bb->index]; = main_block_label (GOTO_DESTINATION (true_branch));
GOTO_DESTINATION (false_branch)
= main_block_label (GOTO_DESTINATION (false_branch));
break; break;
} }
...@@ -836,12 +861,8 @@ cleanup_dead_labels (void) ...@@ -836,12 +861,8 @@ cleanup_dead_labels (void)
/* Replace all destination labels. */ /* Replace all destination labels. */
for (i = 0; i < n; ++i) for (i = 0; i < n; ++i)
{ CASE_LABEL (TREE_VEC_ELT (vec, i))
tree label = CASE_LABEL (TREE_VEC_ELT (vec, i)); = main_block_label (CASE_LABEL (TREE_VEC_ELT (vec, i)));
CASE_LABEL (TREE_VEC_ELT (vec, i)) =
label_for_bb[label_to_block (label)->index];
}
break; break;
} }
...@@ -849,13 +870,12 @@ cleanup_dead_labels (void) ...@@ -849,13 +870,12 @@ cleanup_dead_labels (void)
/* We have to handle GOTO_EXPRs until they're removed, and we don't /* We have to handle GOTO_EXPRs until they're removed, and we don't
remove them until after we've created the CFG edges. */ remove them until after we've created the CFG edges. */
case GOTO_EXPR: case GOTO_EXPR:
{ if (! computed_goto_p (stmt))
tree label = GOTO_DESTINATION (stmt); {
if (! computed_goto_p (stmt)) GOTO_DESTINATION (stmt)
GOTO_DESTINATION (stmt) = = main_block_label (GOTO_DESTINATION (stmt));
label_for_bb[label_to_block (label)->index]; break;
break; }
}
default: default:
break; break;
...@@ -2636,19 +2656,19 @@ disband_implicit_edges (void) ...@@ -2636,19 +2656,19 @@ disband_implicit_edges (void)
} }
} }
/* Remove block annotations and other datastructures. */
/* Remove all the blocks and edges that make up the flowgraph. */
void void
delete_tree_cfg (void) delete_tree_cfg_annotations (void)
{ {
basic_block bb;
if (n_basic_blocks > 0) if (n_basic_blocks > 0)
free_blocks_annotations (); free_blocks_annotations ();
free_basic_block_vars ();
basic_block_info = NULL;
label_to_block_map = NULL; label_to_block_map = NULL;
free_rbi_pool (); free_rbi_pool ();
FOR_EACH_BB (bb)
bb->rbi = NULL;
} }
......
...@@ -434,7 +434,7 @@ extern void bsi_replace (const block_stmt_iterator *, tree, bool); ...@@ -434,7 +434,7 @@ extern void bsi_replace (const block_stmt_iterator *, tree, bool);
/* Location to track pending stmt for edge insertion. */ /* Location to track pending stmt for edge insertion. */
#define PENDING_STMT(e) ((e)->insns.t) #define PENDING_STMT(e) ((e)->insns.t)
extern void delete_tree_cfg (void); extern void delete_tree_cfg_annotations (void);
extern void disband_implicit_edges (void); extern void disband_implicit_edges (void);
extern bool stmt_ends_bb_p (tree); extern bool stmt_ends_bb_p (tree);
extern bool is_ctrl_stmt (tree); extern bool is_ctrl_stmt (tree);
...@@ -582,6 +582,9 @@ void set_value_handle (tree, tree); ...@@ -582,6 +582,9 @@ void set_value_handle (tree, tree);
void debug_value_expressions (tree); void debug_value_expressions (tree);
void print_value_expressions (FILE *, tree); void print_value_expressions (FILE *, tree);
/* In tree-sra.c */
void insert_edge_copies (tree stmt, basic_block bb);
#include "tree-flow-inline.h" #include "tree-flow-inline.h"
#endif /* _TREE_FLOW_H */ #endif /* _TREE_FLOW_H */
...@@ -84,33 +84,6 @@ static struct tree_opt_pass pass_gimple = ...@@ -84,33 +84,6 @@ static struct tree_opt_pass pass_gimple =
TODO_dump_func /* todo_flags_finish */ TODO_dump_func /* todo_flags_finish */
}; };
/* Pass: replace the outermost BIND_EXPR. We removed all of them while
optimizing, but the tree->rtl expander requires it. */
static void
execute_rebuild_bind (void)
{
DECL_SAVED_TREE (current_function_decl)
= build (BIND_EXPR, void_type_node, NULL_TREE,
DECL_SAVED_TREE (current_function_decl), NULL_TREE);
}
static struct tree_opt_pass pass_rebuild_bind =
{
NULL, /* name */
NULL, /* gate */
execute_rebuild_bind, /* execute */
NULL, /* sub */
NULL, /* next */
0, /* static_pass_number */
0, /* tv_id */
0, /* properties_required */
0, /* properties_provided */
0, /* properties_destroyed */
0, /* todo_flags_start */
0 /* todo_flags_finish */
};
/* Gate: execute, or not, all of the non-trivial optimizations. */ /* Gate: execute, or not, all of the non-trivial optimizations. */
static bool static bool
...@@ -141,9 +114,8 @@ static struct tree_opt_pass pass_all_optimizations = ...@@ -141,9 +114,8 @@ static struct tree_opt_pass pass_all_optimizations =
passes. */ passes. */
static void static void
execute_del_cfg (void) execute_free_datastructures (void)
{ {
basic_block bb;
tree *chain; tree *chain;
/* ??? This isn't the right place for this. Worse, it got computed /* ??? This isn't the right place for this. Worse, it got computed
...@@ -160,27 +132,23 @@ execute_del_cfg (void) ...@@ -160,27 +132,23 @@ execute_del_cfg (void)
/* Re-chain the statements from the blocks. */ /* Re-chain the statements from the blocks. */
chain = &DECL_SAVED_TREE (current_function_decl); chain = &DECL_SAVED_TREE (current_function_decl);
*chain = alloc_stmt_list (); *chain = alloc_stmt_list ();
FOR_EACH_BB (bb)
{
append_to_statement_list_force (bb->stmt_list, chain);
}
/* And get rid of the cfg. */ /* And get rid of annotations we no longer need. */
delete_tree_cfg (); delete_tree_cfg_annotations ();
} }
static struct tree_opt_pass pass_del_cfg = static struct tree_opt_pass pass_free_datastructures =
{ {
NULL, /* name */ NULL, /* name */
NULL, /* gate */ NULL, /* gate */
execute_del_cfg, /* execute */ execute_free_datastructures, /* execute */
NULL, /* sub */ NULL, /* sub */
NULL, /* next */ NULL, /* next */
0, /* static_pass_number */ 0, /* static_pass_number */
0, /* tv_id */ 0, /* tv_id */
PROP_cfg, /* properties_required */ PROP_cfg, /* properties_required */
0, /* properties_provided */ 0, /* properties_provided */
PROP_cfg, /* properties_destroyed */ 0, /* properties_destroyed */
0, /* todo_flags_start */ 0, /* todo_flags_start */
0 /* todo_flags_finish */ 0 /* todo_flags_finish */
}; };
...@@ -283,16 +251,16 @@ init_tree_optimization_passes (void) ...@@ -283,16 +251,16 @@ init_tree_optimization_passes (void)
NEXT_PASS (pass_mudflap_1); NEXT_PASS (pass_mudflap_1);
NEXT_PASS (pass_lower_cf); NEXT_PASS (pass_lower_cf);
NEXT_PASS (pass_lower_eh); NEXT_PASS (pass_lower_eh);
NEXT_PASS (pass_build_cfg);
NEXT_PASS (pass_tree_profile);
NEXT_PASS (pass_all_optimizations); NEXT_PASS (pass_all_optimizations);
NEXT_PASS (pass_mudflap_2); NEXT_PASS (pass_mudflap_2);
NEXT_PASS (pass_rebuild_bind); NEXT_PASS (pass_free_datastructures);
NEXT_PASS (pass_expand); NEXT_PASS (pass_expand);
NEXT_PASS (pass_rest_of_compilation); NEXT_PASS (pass_rest_of_compilation);
*p = NULL; *p = NULL;
p = &pass_all_optimizations.sub; p = &pass_all_optimizations.sub;
NEXT_PASS (pass_build_cfg);
NEXT_PASS (pass_tree_profile);
NEXT_PASS (pass_referenced_vars); NEXT_PASS (pass_referenced_vars);
NEXT_PASS (pass_build_pta); NEXT_PASS (pass_build_pta);
NEXT_PASS (pass_build_ssa); NEXT_PASS (pass_build_ssa);
...@@ -335,7 +303,6 @@ init_tree_optimization_passes (void) ...@@ -335,7 +303,6 @@ init_tree_optimization_passes (void)
NEXT_PASS (pass_del_ssa); NEXT_PASS (pass_del_ssa);
NEXT_PASS (pass_nrv); NEXT_PASS (pass_nrv);
NEXT_PASS (pass_remove_useless_vars); NEXT_PASS (pass_remove_useless_vars);
NEXT_PASS (pass_del_cfg);
*p = NULL; *p = NULL;
#undef NEXT_PASS #undef NEXT_PASS
......
...@@ -56,7 +56,6 @@ enum sra_copy_mode { SCALAR_SCALAR, FIELD_SCALAR, SCALAR_FIELD }; ...@@ -56,7 +56,6 @@ enum sra_copy_mode { SCALAR_SCALAR, FIELD_SCALAR, SCALAR_FIELD };
/* Local functions. */ /* Local functions. */
static inline bool can_be_scalarized_p (tree); static inline bool can_be_scalarized_p (tree);
static inline void insert_edge_copies (tree stmt, basic_block bb);
static tree create_scalar_copies (tree lhs, tree rhs, enum sra_copy_mode mode); static tree create_scalar_copies (tree lhs, tree rhs, enum sra_copy_mode mode);
static inline void scalarize_component_ref (tree, tree *tp); static inline void scalarize_component_ref (tree, tree *tp);
static void scalarize_structures (void); static void scalarize_structures (void);
...@@ -556,7 +555,7 @@ find_candidates_for_sra (void) ...@@ -556,7 +555,7 @@ find_candidates_for_sra (void)
has more than one edge, STMT will be replicated for each edge. Also, has more than one edge, STMT will be replicated for each edge. Also,
abnormal edges will be ignored. */ abnormal edges will be ignored. */
static inline void void
insert_edge_copies (tree stmt, basic_block bb) insert_edge_copies (tree stmt, basic_block bb)
{ {
edge e; edge e;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment