Commit d47cc544 by Steven Bosscher

backport: et-forest.h (et_forest_create, [...]): Declarations removed.

	Backport from tree-ssa (relevant changes only):
	2003-12-18  Zdenek Dvorak  <rakdver@atrey.karlin.mff.cuni.cz>

	* et-forest.h (et_forest_create, et_forest_delete,
	et_forest_add_node, et_forest_add_edge, et_forest_remove_node,
	et_forest_remove_edge, et_forest_parent,
	et_forest_common_ancestor, et_forest_node_value,
	et_forest_enumerate_sons): Declarations removed.
	(struct et_node): New.
	(et_new_tree, et_free_tree, et_set_father, et_split, et_nca,
	et_below): Declare.
	* et-forest.c (struct et_forest_occurrence, struct et_forest,
	struct et_forest_node): Removed.
	(et_forest_create, et_forest_delete,
	et_forest_add_node, et_forest_add_edge, et_forest_remove_node,
	et_forest_remove_edge, et_forest_parent,
	et_forest_common_ancestor, et_forest_node_value,
	et_forest_enumerate_sons, splay, remove_all_occurrences,
	find_leftmost_node, find_rightmost_node, calculate_value): Removed.
	(struct et_occ): New.
	(et_nodes, et_occurences): New.
	(set_depth, set_depth_add, set_prev, set_next, et_recomp_min,
	et_check_occ_sanity, et_check_sanity, et_check_tree_sanity,
	record_path_before_1, record_path_before, check_path_after_1,
	check_path_after, et_splay, et_new_occ, et_new_tree,
	et_free_tree, et_set_father, et_split, et_nca, et_below): New.
	* basic-block.h (struct basic_block_def): New field dom.
	(struct dominance_info): Type removed.
	(calculate_dominance_info, free_dominance_info,
	nearest_common_dominator, set_immediate_dominator,
	get_immediate_dominator, dominated_by_p, get_dominated_by,
	add_to_dominance_info, delete_from_dominance_info,
	recount_dominator, redirect_immediate_dominators,
	iterate_fix_dominators, verify_dominators): Declarations
	changed.
	(enum dom_state): New.
	(dom_computed): New variable.
	(first_dom_son, next_dom_son): Declare.
	* dominance.c (struct dominance_info): Removed.
	(BB_NODE, SET_BB_NODE): Removed.
	(calculate_dominance_info, free_dominance_info,
	nearest_common_dominator, set_immediate_dominator,
	get_immediate_dominator, dominated_by_p, get_dominated_by,
	add_to_dominance_info, delete_from_dominance_info,
	recount_dominator, redirect_immediate_dominators,
	iterate_fix_dominators, verify_dominators,
	debug_dominance_info): Work over new datastructure.  Access
	dominance datastructures through CFG.
	(assign_dfs_numbers, compute_dom_fast_query, first_dom_son,
	next_dom_son): New.
	* bt-load.c (dom): Variable removed.
	(augment_live_range, combine_btr_defs, migrate_btr_def,
	migrate_btr_defs, branch_target_load_optimize): Updated for the
	new interface for dominance information.
	* cfg.c {exit_entry_blocks): Update initializer.
	* cfglayout.c (copy_bbs): Removed loops argument. Updated for
	the new interface for dominance information.
	* cfglayout.h (copy_bbs): Declaration changed.
	* cfgloop.c (flow_loop_pre_header_find, flow_loops_cfg_dump,
	flow_loop_scan, canonicalize_loop_headers, flow_loops_find): Updated
	for the new interface for dominance information.
	(flow_loop_scan): Loops argument removed.
	(flow_loops_free): Don't release dominators.
	* cfgloop.h (struct cfg): Dom field removed.
	(flow_loop_scan, loop_split_edge_with, simple_loop_p,
	just_once_each_iteration_p, split_loop_bb): Declaration changed.
	* cfgloopanal.c (simple_loop_exit_p, simple_increment,
	just_once_each_iteration_p, simple_loop_p): Remove loops argument.
	Updated for the new interface for dominance information.
	* cfgloopmanip.c (remove_bbs, find_path, create_preheader,
	split_loop_bb, loopify, duplicate_loop_to_header_edge,
	force_single_succ_latches, loop_split_edge_with): Ditto.
	* gcse.c (dominators): Variable removed.
	(free_code_hoist_mem, compute_code_hoist_data, hoist_code):
	Updated for the new interface for dominance information.
	* ifcvt.c (post_dominators): Variable removed.
	(mark_loop_exit_edges, merge_if_block, find_if_header,
	find_cond_trap, find_if_case_1, find_if_case_2, if_convert):
	Updated for the new interface for dominance information.
	* loop-init.c (rtl_loop_optimizer_init,
	rtl_loop_optimizer_finalize): Ditto.
	* loop-unroll.c (decide_peel_simple, decide_peel_once_rolling,
	decide_peel_completely, decide_unroll_stupid,
	decide_unroll_constant_iterations,
	decide_unroll_runtime_iterations): Loops argument removed.
	Updated for the new interface for dominance information.
	(unroll_and_peel_loops, peel_loops_completely,
	unroll_loop_runtime_iterations): Updated for the new interface for
	dominance information.
	* loop-unswitch.c (may_unswitch_on_p, unswitch_loops,
	unswitch_single_loop, unswitch_loop): Updated for the new
	interface for dominance information.
	* predict.c (process_note_predictions, process_note_prediction,
	estimate_probability, note_prediction_to_br_prob): Ditto.
	* sched-rgn.c (find_rgns, init_regions): Ditto.
	* toplev.c (rest_of_handle_branch_prob): Free the dominators.

From-SVN: r75226
parent 58496de1
2003-12-30 Steven Bosscher <steven@gcc.gnu.org>
Backport from tree-ssa (relevant changes only):
2003-12-18 Zdenek Dvorak <rakdver@atrey.karlin.mff.cuni.cz>
* et-forest.h (et_forest_create, et_forest_delete,
et_forest_add_node, et_forest_add_edge, et_forest_remove_node,
et_forest_remove_edge, et_forest_parent,
et_forest_common_ancestor, et_forest_node_value,
et_forest_enumerate_sons): Declarations removed.
(struct et_node): New.
(et_new_tree, et_free_tree, et_set_father, et_split, et_nca,
et_below): Declare.
* et-forest.c (struct et_forest_occurrence, struct et_forest,
struct et_forest_node): Removed.
(et_forest_create, et_forest_delete,
et_forest_add_node, et_forest_add_edge, et_forest_remove_node,
et_forest_remove_edge, et_forest_parent,
et_forest_common_ancestor, et_forest_node_value,
et_forest_enumerate_sons, splay, remove_all_occurrences,
find_leftmost_node, find_rightmost_node, calculate_value): Removed.
(struct et_occ): New.
(et_nodes, et_occurences): New.
(set_depth, set_depth_add, set_prev, set_next, et_recomp_min,
et_check_occ_sanity, et_check_sanity, et_check_tree_sanity,
record_path_before_1, record_path_before, check_path_after_1,
check_path_after, et_splay, et_new_occ, et_new_tree,
et_free_tree, et_set_father, et_split, et_nca, et_below): New.
* basic-block.h (struct basic_block_def): New field dom.
(struct dominance_info): Type removed.
(calculate_dominance_info, free_dominance_info,
nearest_common_dominator, set_immediate_dominator,
get_immediate_dominator, dominated_by_p, get_dominated_by,
add_to_dominance_info, delete_from_dominance_info,
recount_dominator, redirect_immediate_dominators,
iterate_fix_dominators, verify_dominators): Declarations
changed.
(enum dom_state): New.
(dom_computed): New variable.
(first_dom_son, next_dom_son): Declare.
* dominance.c (struct dominance_info): Removed.
(BB_NODE, SET_BB_NODE): Removed.
(calculate_dominance_info, free_dominance_info,
nearest_common_dominator, set_immediate_dominator,
get_immediate_dominator, dominated_by_p, get_dominated_by,
add_to_dominance_info, delete_from_dominance_info,
recount_dominator, redirect_immediate_dominators,
iterate_fix_dominators, verify_dominators,
debug_dominance_info): Work over new datastructure. Access
dominance datastructures through CFG.
(assign_dfs_numbers, compute_dom_fast_query, first_dom_son,
next_dom_son): New.
* bt-load.c (dom): Variable removed.
(augment_live_range, combine_btr_defs, migrate_btr_def,
migrate_btr_defs, branch_target_load_optimize): Updated for the
new interface for dominance information.
* cfg.c {exit_entry_blocks): Update initializer.
* cfglayout.c (copy_bbs): Removed loops argument. Updated for
the new interface for dominance information.
* cfglayout.h (copy_bbs): Declaration changed.
* cfgloop.c (flow_loop_pre_header_find, flow_loops_cfg_dump,
flow_loop_scan, canonicalize_loop_headers, flow_loops_find): Updated
for the new interface for dominance information.
(flow_loop_scan): Loops argument removed.
(flow_loops_free): Don't release dominators.
* cfgloop.h (struct cfg): Dom field removed.
(flow_loop_scan, loop_split_edge_with, simple_loop_p,
just_once_each_iteration_p, split_loop_bb): Declaration changed.
* cfgloopanal.c (simple_loop_exit_p, simple_increment,
just_once_each_iteration_p, simple_loop_p): Remove loops argument.
Updated for the new interface for dominance information.
* cfgloopmanip.c (remove_bbs, find_path, create_preheader,
split_loop_bb, loopify, duplicate_loop_to_header_edge,
force_single_succ_latches, loop_split_edge_with): Ditto.
* gcse.c (dominators): Variable removed.
(free_code_hoist_mem, compute_code_hoist_data, hoist_code):
Updated for the new interface for dominance information.
* ifcvt.c (post_dominators): Variable removed.
(mark_loop_exit_edges, merge_if_block, find_if_header,
find_cond_trap, find_if_case_1, find_if_case_2, if_convert):
Updated for the new interface for dominance information.
* loop-init.c (rtl_loop_optimizer_init,
rtl_loop_optimizer_finalize): Ditto.
* loop-unroll.c (decide_peel_simple, decide_peel_once_rolling,
decide_peel_completely, decide_unroll_stupid,
decide_unroll_constant_iterations,
decide_unroll_runtime_iterations): Loops argument removed.
Updated for the new interface for dominance information.
(unroll_and_peel_loops, peel_loops_completely,
unroll_loop_runtime_iterations): Updated for the new interface for
dominance information.
* loop-unswitch.c (may_unswitch_on_p, unswitch_loops,
unswitch_single_loop, unswitch_loop): Updated for the new
interface for dominance information.
* predict.c (process_note_predictions, process_note_prediction,
estimate_probability, note_prediction_to_br_prob): Ditto.
* sched-rgn.c (find_rgns, init_regions): Ditto.
* toplev.c (rest_of_handle_branch_prob): Free the dominators.
2003-12-30 Jan Hubicka <jh@suse.cz> 2003-12-30 Jan Hubicka <jh@suse.cz>
PR target/13456 PR target/13456
......
...@@ -1322,7 +1322,7 @@ c-convert.o : c-convert.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) ...@@ -1322,7 +1322,7 @@ c-convert.o : c-convert.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H)
c-pragma.o: c-pragma.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \ c-pragma.o: c-pragma.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(TREE_H) \
function.h c-pragma.h toplev.h output.h $(GGC_H) $(TM_P_H) $(C_COMMON_H) gt-c-pragma.h function.h c-pragma.h toplev.h output.h $(GGC_H) $(TM_P_H) $(C_COMMON_H) gt-c-pragma.h
graph.o: graph.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) toplev.h flags.h output.h \ graph.o: graph.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) toplev.h flags.h output.h \
$(RTL_H) function.h hard-reg-set.h $(BASIC_BLOCK_H) graph.h $(RTL_H) function.h langhooks.h hard-reg-set.h $(BASIC_BLOCK_H) graph.h $(TREE_H)
sbitmap.o: sbitmap.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) flags.h \ sbitmap.o: sbitmap.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) flags.h \
hard-reg-set.h $(BASIC_BLOCK_H) hard-reg-set.h $(BASIC_BLOCK_H)
...@@ -1651,7 +1651,7 @@ web.o : web.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(REGS_H) \ ...@@ -1651,7 +1651,7 @@ web.o : web.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(REGS_H) \
hard-reg-set.h flags.h $(BASIC_BLOCK_H) function.h output.h toplev.h df.h hard-reg-set.h flags.h $(BASIC_BLOCK_H) function.h output.h toplev.h df.h
gcse.o : gcse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(REGS_H) \ gcse.o : gcse.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(REGS_H) \
hard-reg-set.h flags.h real.h insn-config.h $(GGC_H) $(RECOG_H) $(EXPR_H) \ hard-reg-set.h flags.h real.h insn-config.h $(GGC_H) $(RECOG_H) $(EXPR_H) \
$(BASIC_BLOCK_H) function.h output.h toplev.h $(TM_P_H) $(PARAMS_H) \ $(BASIC_BLOCK_H) function.h langhooks.h output.h toplev.h $(TM_P_H) $(PARAMS_H) \
except.h gt-gcse.h $(TREE_H) except.h gt-gcse.h $(TREE_H)
sibcall.o : sibcall.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(REGS_H) \ sibcall.o : sibcall.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(RTL_H) $(REGS_H) \
function.h hard-reg-set.h flags.h insn-config.h $(RECOG_H) $(BASIC_BLOCK_H) function.h hard-reg-set.h flags.h insn-config.h $(RECOG_H) $(BASIC_BLOCK_H)
......
...@@ -234,6 +234,9 @@ typedef struct basic_block_def { ...@@ -234,6 +234,9 @@ typedef struct basic_block_def {
/* Outermost loop containing the block. */ /* Outermost loop containing the block. */
struct loop *loop_father; struct loop *loop_father;
/* The dominance and postdominance information node. */
struct et_node *dom[2];
/* Expected number of executions: calculated in profile.c. */ /* Expected number of executions: calculated in profile.c. */
gcov_type count; gcov_type count;
...@@ -373,10 +376,6 @@ extern void clear_edges (void); ...@@ -373,10 +376,6 @@ extern void clear_edges (void);
extern void mark_critical_edges (void); extern void mark_critical_edges (void);
extern rtx first_insn_after_basic_block_note (basic_block); extern rtx first_insn_after_basic_block_note (basic_block);
/* Dominator information for basic blocks. */
typedef struct dominance_info *dominance_info;
/* Structure to group all of the information to process IF-THEN and /* Structure to group all of the information to process IF-THEN and
IF-THEN-ELSE blocks for the conditional execution support. This IF-THEN-ELSE blocks for the conditional execution support. This
needs to be in a public file in case the IFCVT macros call needs to be in a public file in case the IFCVT macros call
...@@ -612,22 +611,35 @@ enum cdi_direction ...@@ -612,22 +611,35 @@ enum cdi_direction
CDI_POST_DOMINATORS CDI_POST_DOMINATORS
}; };
extern dominance_info calculate_dominance_info (enum cdi_direction); enum dom_state
extern void free_dominance_info (dominance_info); {
extern basic_block nearest_common_dominator (dominance_info, DOM_NONE, /* Not computed at all. */
DOM_CONS_OK, /* The data is conservatively OK, i.e. if it says you that A dominates B,
it indeed does. */
DOM_NO_FAST_QUERY, /* The data is OK, but the fast query data are not usable. */
DOM_OK /* Everything is ok. */
};
extern enum dom_state dom_computed[2];
extern void calculate_dominance_info (enum cdi_direction);
extern void free_dominance_info (enum cdi_direction);
extern basic_block nearest_common_dominator (enum cdi_direction,
basic_block, basic_block); basic_block, basic_block);
extern void set_immediate_dominator (dominance_info, basic_block, extern void set_immediate_dominator (enum cdi_direction, basic_block,
basic_block); basic_block);
extern basic_block get_immediate_dominator (dominance_info, basic_block); extern basic_block get_immediate_dominator (enum cdi_direction, basic_block);
extern bool dominated_by_p (dominance_info, basic_block, basic_block); extern bool dominated_by_p (enum cdi_direction, basic_block, basic_block);
extern int get_dominated_by (dominance_info, basic_block, basic_block **); extern int get_dominated_by (enum cdi_direction, basic_block, basic_block **);
extern void add_to_dominance_info (dominance_info, basic_block); extern void add_to_dominance_info (enum cdi_direction, basic_block);
extern void delete_from_dominance_info (dominance_info, basic_block); extern void delete_from_dominance_info (enum cdi_direction, basic_block);
basic_block recount_dominator (dominance_info, basic_block); basic_block recount_dominator (enum cdi_direction, basic_block);
extern void redirect_immediate_dominators (dominance_info, basic_block, extern void redirect_immediate_dominators (enum cdi_direction, basic_block,
basic_block); basic_block);
void iterate_fix_dominators (dominance_info, basic_block *, int); extern void iterate_fix_dominators (enum cdi_direction, basic_block *, int);
extern void verify_dominators (dominance_info); extern void verify_dominators (enum cdi_direction);
extern basic_block first_dom_son (enum cdi_direction, basic_block);
extern basic_block next_dom_son (enum cdi_direction, basic_block);
#include "cfghooks.h" #include "cfghooks.h"
......
...@@ -155,9 +155,6 @@ static void note_btr_set (rtx, rtx, void *); ...@@ -155,9 +155,6 @@ static void note_btr_set (rtx, rtx, void *);
migrating branch target load instructions. */ migrating branch target load instructions. */
static struct obstack migrate_btrl_obstack; static struct obstack migrate_btrl_obstack;
/* Basic block dominator information used when migrating PT instructions. */
static dominance_info dom;
/* Array indexed by basic block number, giving the set of registers /* Array indexed by basic block number, giving the set of registers
live in that block. */ live in that block. */
static HARD_REG_SET *btrs_live; static HARD_REG_SET *btrs_live;
...@@ -840,9 +837,9 @@ augment_live_range (bitmap live_range, HARD_REG_SET *btrs_live_in_range, ...@@ -840,9 +837,9 @@ augment_live_range (bitmap live_range, HARD_REG_SET *btrs_live_in_range,
tos = worklist = xmalloc (sizeof (basic_block) * (n_basic_blocks + 1)); tos = worklist = xmalloc (sizeof (basic_block) * (n_basic_blocks + 1));
if (dominated_by_p (dom, new_bb, head_bb)) if (dominated_by_p (CDI_DOMINATORS, new_bb, head_bb))
*tos++ = new_bb; *tos++ = new_bb;
else if (dominated_by_p (dom, head_bb, new_bb)) else if (dominated_by_p (CDI_DOMINATORS, head_bb, new_bb))
{ {
edge e; edge e;
int new_block = new_bb->index; int new_block = new_bb->index;
...@@ -974,7 +971,7 @@ combine_btr_defs (btr_def def, HARD_REG_SET *btrs_live_in_range) ...@@ -974,7 +971,7 @@ combine_btr_defs (btr_def def, HARD_REG_SET *btrs_live_in_range)
if (other_def != def if (other_def != def
&& other_def->uses != NULL && other_def->uses != NULL
&& ! other_def->has_ambiguous_use && ! other_def->has_ambiguous_use
&& dominated_by_p (dom, other_def->bb, def->bb)) && dominated_by_p (CDI_DOMINATORS, other_def->bb, def->bb))
{ {
/* def->bb dominates the other def, so def and other_def could /* def->bb dominates the other def, so def and other_def could
be combined. */ be combined. */
...@@ -1226,9 +1223,9 @@ migrate_btr_def (btr_def def, int min_cost) ...@@ -1226,9 +1223,9 @@ migrate_btr_def (btr_def def, int min_cost)
def_basic_block_freq = basic_block_freq (def->bb); def_basic_block_freq = basic_block_freq (def->bb);
for (try = get_immediate_dominator (dom, def->bb); for (try = get_immediate_dominator (CDI_DOMINATORS, def->bb);
!give_up && try && try != ENTRY_BLOCK_PTR && def->cost >= min_cost; !give_up && try && try != ENTRY_BLOCK_PTR && def->cost >= min_cost;
try = get_immediate_dominator (dom, try)) try = get_immediate_dominator (CDI_DOMINATORS, try))
{ {
/* Try to move the instruction that sets the target register into /* Try to move the instruction that sets the target register into
basic block TRY. */ basic block TRY. */
...@@ -1299,7 +1296,7 @@ migrate_btr_defs (enum reg_class btr_class, int allow_callee_save) ...@@ -1299,7 +1296,7 @@ migrate_btr_defs (enum reg_class btr_class, int allow_callee_save)
"Basic block %d: count = " HOST_WIDEST_INT_PRINT_DEC "Basic block %d: count = " HOST_WIDEST_INT_PRINT_DEC
" loop-depth = %d idom = %d\n", " loop-depth = %d idom = %d\n",
i, (HOST_WIDEST_INT) bb->count, bb->loop_depth, i, (HOST_WIDEST_INT) bb->count, bb->loop_depth,
get_immediate_dominator (dom, bb)->index); get_immediate_dominator (CDI_DOMINATORS, bb)->index);
} }
} }
...@@ -1367,12 +1364,12 @@ branch_target_load_optimize (rtx insns, bool after_prologue_epilogue_gen) ...@@ -1367,12 +1364,12 @@ branch_target_load_optimize (rtx insns, bool after_prologue_epilogue_gen)
life_analysis (insns, NULL, 0); life_analysis (insns, NULL, 0);
/* Dominator info is also needed for migrate_btr_def. */ /* Dominator info is also needed for migrate_btr_def. */
dom = calculate_dominance_info (CDI_DOMINATORS); calculate_dominance_info (CDI_DOMINATORS);
migrate_btr_defs (class, migrate_btr_defs (class,
((*targetm.branch_target_register_callee_saved) ((*targetm.branch_target_register_callee_saved)
(after_prologue_epilogue_gen))); (after_prologue_epilogue_gen)));
free_dominance_info (dom); free_dominance_info (CDI_DOMINATORS);
update_life_info (NULL, UPDATE_LIFE_GLOBAL_RM_NOTES, update_life_info (NULL, UPDATE_LIFE_GLOBAL_RM_NOTES,
PROP_DEATH_NOTES | PROP_REG_INFO); PROP_DEATH_NOTES | PROP_REG_INFO);
......
...@@ -111,6 +111,7 @@ struct basic_block_def entry_exit_blocks[2] ...@@ -111,6 +111,7 @@ struct basic_block_def entry_exit_blocks[2]
EXIT_BLOCK_PTR, /* next_bb */ EXIT_BLOCK_PTR, /* next_bb */
0, /* loop_depth */ 0, /* loop_depth */
NULL, /* loop_father */ NULL, /* loop_father */
{ NULL, NULL }, /* dom */
0, /* count */ 0, /* count */
0, /* frequency */ 0, /* frequency */
0, /* flags */ 0, /* flags */
...@@ -133,6 +134,7 @@ struct basic_block_def entry_exit_blocks[2] ...@@ -133,6 +134,7 @@ struct basic_block_def entry_exit_blocks[2]
NULL, /* next_bb */ NULL, /* next_bb */
0, /* loop_depth */ 0, /* loop_depth */
NULL, /* loop_father */ NULL, /* loop_father */
{ NULL, NULL }, /* dom */
0, /* count */ 0, /* count */
0, /* frequency */ 0, /* frequency */
0, /* flags */ 0, /* flags */
......
...@@ -1253,7 +1253,7 @@ end: ...@@ -1253,7 +1253,7 @@ end:
void void
copy_bbs (basic_block *bbs, unsigned n, basic_block *new_bbs, copy_bbs (basic_block *bbs, unsigned n, basic_block *new_bbs,
edge *edges, unsigned n_edges, edge *new_edges, edge *edges, unsigned n_edges, edge *new_edges,
struct loop *base, struct loops *loops) struct loop *base)
{ {
unsigned i, j; unsigned i, j;
basic_block bb, new_bb, dom_bb; basic_block bb, new_bb, dom_bb;
...@@ -1268,7 +1268,7 @@ copy_bbs (basic_block *bbs, unsigned n, basic_block *new_bbs, ...@@ -1268,7 +1268,7 @@ copy_bbs (basic_block *bbs, unsigned n, basic_block *new_bbs,
bb->rbi->duplicated = 1; bb->rbi->duplicated = 1;
/* Add to loop. */ /* Add to loop. */
add_bb_to_loop (new_bb, bb->loop_father->copy); add_bb_to_loop (new_bb, bb->loop_father->copy);
add_to_dominance_info (loops->cfg.dom, new_bb); add_to_dominance_info (CDI_DOMINATORS, new_bb);
/* Possibly set header. */ /* Possibly set header. */
if (bb->loop_father->header == bb && bb->loop_father != base) if (bb->loop_father->header == bb && bb->loop_father != base)
new_bb->loop_father->header = new_bb; new_bb->loop_father->header = new_bb;
...@@ -1283,11 +1283,11 @@ copy_bbs (basic_block *bbs, unsigned n, basic_block *new_bbs, ...@@ -1283,11 +1283,11 @@ copy_bbs (basic_block *bbs, unsigned n, basic_block *new_bbs,
bb = bbs[i]; bb = bbs[i];
new_bb = new_bbs[i]; new_bb = new_bbs[i];
dom_bb = get_immediate_dominator (loops->cfg.dom, bb); dom_bb = get_immediate_dominator (CDI_DOMINATORS, bb);
if (dom_bb->rbi->duplicated) if (dom_bb->rbi->duplicated)
{ {
dom_bb = dom_bb->rbi->copy; dom_bb = dom_bb->rbi->copy;
set_immediate_dominator (loops->cfg.dom, new_bb, dom_bb); set_immediate_dominator (CDI_DOMINATORS, new_bb, dom_bb);
} }
} }
......
...@@ -43,5 +43,5 @@ extern void insn_locators_initialize (void); ...@@ -43,5 +43,5 @@ extern void insn_locators_initialize (void);
extern void reemit_insn_block_notes (void); extern void reemit_insn_block_notes (void);
extern bool can_copy_bbs_p (basic_block *, unsigned); extern bool can_copy_bbs_p (basic_block *, unsigned);
extern void copy_bbs (basic_block *, unsigned, basic_block *, extern void copy_bbs (basic_block *, unsigned, basic_block *,
edge *, unsigned, edge *, struct loop *, struct loops *); edge *, unsigned, edge *, struct loop *);
extern void cfg_layout_initialize_rbi (basic_block); extern void cfg_layout_initialize_rbi (basic_block);
...@@ -38,7 +38,7 @@ static void flow_loop_entry_edges_find (struct loop *); ...@@ -38,7 +38,7 @@ static void flow_loop_entry_edges_find (struct loop *);
static void flow_loop_exit_edges_find (struct loop *); static void flow_loop_exit_edges_find (struct loop *);
static int flow_loop_nodes_find (basic_block, struct loop *); static int flow_loop_nodes_find (basic_block, struct loop *);
static void flow_loop_pre_header_scan (struct loop *); static void flow_loop_pre_header_scan (struct loop *);
static basic_block flow_loop_pre_header_find (basic_block, dominance_info); static basic_block flow_loop_pre_header_find (basic_block);
static int flow_loop_level_compute (struct loop *); static int flow_loop_level_compute (struct loop *);
static int flow_loops_level_compute (struct loops *); static int flow_loops_level_compute (struct loops *);
static void establish_preds (struct loop *); static void establish_preds (struct loop *);
...@@ -55,7 +55,7 @@ flow_loops_cfg_dump (const struct loops *loops, FILE *file) ...@@ -55,7 +55,7 @@ flow_loops_cfg_dump (const struct loops *loops, FILE *file)
int i; int i;
basic_block bb; basic_block bb;
if (! loops->num || ! file || ! loops->cfg.dom) if (! loops->num || ! file)
return; return;
FOR_EACH_BB (bb) FOR_EACH_BB (bb)
...@@ -212,9 +212,6 @@ flow_loops_free (struct loops *loops) ...@@ -212,9 +212,6 @@ flow_loops_free (struct loops *loops)
free (loops->parray); free (loops->parray);
loops->parray = NULL; loops->parray = NULL;
if (loops->cfg.dom)
free_dominance_info (loops->cfg.dom);
if (loops->cfg.dfs_order) if (loops->cfg.dfs_order)
free (loops->cfg.dfs_order); free (loops->cfg.dfs_order);
if (loops->cfg.rc_order) if (loops->cfg.rc_order)
...@@ -391,11 +388,10 @@ flow_loop_pre_header_scan (struct loop *loop) ...@@ -391,11 +388,10 @@ flow_loop_pre_header_scan (struct loop *loop)
} }
/* Return the block for the pre-header of the loop with header /* Return the block for the pre-header of the loop with header
HEADER where DOM specifies the dominator information. Return NULL if HEADER. Return NULL if there is no pre-header. */
there is no pre-header. */
static basic_block static basic_block
flow_loop_pre_header_find (basic_block header, dominance_info dom) flow_loop_pre_header_find (basic_block header)
{ {
basic_block pre_header; basic_block pre_header;
edge e; edge e;
...@@ -408,7 +404,7 @@ flow_loop_pre_header_find (basic_block header, dominance_info dom) ...@@ -408,7 +404,7 @@ flow_loop_pre_header_find (basic_block header, dominance_info dom)
basic_block node = e->src; basic_block node = e->src;
if (node != ENTRY_BLOCK_PTR if (node != ENTRY_BLOCK_PTR
&& ! dominated_by_p (dom, node, header)) && ! dominated_by_p (CDI_DOMINATORS, node, header))
{ {
if (pre_header == NULL) if (pre_header == NULL)
pre_header = node; pre_header = node;
...@@ -522,7 +518,7 @@ flow_loops_level_compute (struct loops *loops) ...@@ -522,7 +518,7 @@ flow_loops_level_compute (struct loops *loops)
about it specified by FLAGS. */ about it specified by FLAGS. */
int int
flow_loop_scan (struct loops *loops, struct loop *loop, int flags) flow_loop_scan (struct loop *loop, int flags)
{ {
if (flags & LOOP_ENTRY_EDGES) if (flags & LOOP_ENTRY_EDGES)
{ {
...@@ -541,8 +537,7 @@ flow_loop_scan (struct loops *loops, struct loop *loop, int flags) ...@@ -541,8 +537,7 @@ flow_loop_scan (struct loops *loops, struct loop *loop, int flags)
if (flags & LOOP_PRE_HEADER) if (flags & LOOP_PRE_HEADER)
{ {
/* Look to see if the loop has a pre-header node. */ /* Look to see if the loop has a pre-header node. */
loop->pre_header loop->pre_header = flow_loop_pre_header_find (loop->header);
= flow_loop_pre_header_find (loop->header, loops->cfg.dom);
/* Find the blocks within the extended basic block of /* Find the blocks within the extended basic block of
the loop pre-header. */ the loop pre-header. */
...@@ -627,12 +622,11 @@ make_forwarder_block (basic_block bb, int redirect_latch, int redirect_nonlatch, ...@@ -627,12 +622,11 @@ make_forwarder_block (basic_block bb, int redirect_latch, int redirect_nonlatch,
static void static void
canonicalize_loop_headers (void) canonicalize_loop_headers (void)
{ {
dominance_info dom;
basic_block header; basic_block header;
edge e; edge e;
/* Compute the dominators. */ /* Compute the dominators. */
dom = calculate_dominance_info (CDI_DOMINATORS); calculate_dominance_info (CDI_DOMINATORS);
alloc_aux_for_blocks (sizeof (int)); alloc_aux_for_blocks (sizeof (int));
alloc_aux_for_edges (sizeof (int)); alloc_aux_for_edges (sizeof (int));
...@@ -651,7 +645,7 @@ canonicalize_loop_headers (void) ...@@ -651,7 +645,7 @@ canonicalize_loop_headers (void)
have_abnormal_edge = 1; have_abnormal_edge = 1;
if (latch != ENTRY_BLOCK_PTR if (latch != ENTRY_BLOCK_PTR
&& dominated_by_p (dom, latch, header)) && dominated_by_p (CDI_DOMINATORS, latch, header))
{ {
num_latches++; num_latches++;
LATCH_EDGE (e) = 1; LATCH_EDGE (e) = 1;
...@@ -663,6 +657,8 @@ canonicalize_loop_headers (void) ...@@ -663,6 +657,8 @@ canonicalize_loop_headers (void)
HEADER_BLOCK (header) = num_latches; HEADER_BLOCK (header) = num_latches;
} }
free_dominance_info (CDI_DOMINATORS);
if (HEADER_BLOCK (ENTRY_BLOCK_PTR->succ->dest)) if (HEADER_BLOCK (ENTRY_BLOCK_PTR->succ->dest))
{ {
basic_block bb; basic_block bb;
...@@ -728,7 +724,6 @@ canonicalize_loop_headers (void) ...@@ -728,7 +724,6 @@ canonicalize_loop_headers (void)
free_aux_for_blocks (); free_aux_for_blocks ();
free_aux_for_edges (); free_aux_for_edges ();
free_dominance_info (dom);
} }
/* Find all the natural loops in the function and save in LOOPS structure and /* Find all the natural loops in the function and save in LOOPS structure and
...@@ -744,7 +739,6 @@ flow_loops_find (struct loops *loops, int flags) ...@@ -744,7 +739,6 @@ flow_loops_find (struct loops *loops, int flags)
int num_loops; int num_loops;
edge e; edge e;
sbitmap headers; sbitmap headers;
dominance_info dom;
int *dfs_order; int *dfs_order;
int *rc_order; int *rc_order;
basic_block header; basic_block header;
...@@ -770,7 +764,7 @@ flow_loops_find (struct loops *loops, int flags) ...@@ -770,7 +764,7 @@ flow_loops_find (struct loops *loops, int flags)
canonicalize_loop_headers (); canonicalize_loop_headers ();
/* Compute the dominators. */ /* Compute the dominators. */
dom = loops->cfg.dom = calculate_dominance_info (CDI_DOMINATORS); calculate_dominance_info (CDI_DOMINATORS);
/* Count the number of loop headers. This should be the /* Count the number of loop headers. This should be the
same as the number of natural loops. */ same as the number of natural loops. */
...@@ -804,7 +798,8 @@ flow_loops_find (struct loops *loops, int flags) ...@@ -804,7 +798,8 @@ flow_loops_find (struct loops *loops, int flags)
node (header) that dominates all the nodes in the node (header) that dominates all the nodes in the
loop. It also has single back edge to the header loop. It also has single back edge to the header
from a latch node. */ from a latch node. */
if (latch != ENTRY_BLOCK_PTR && dominated_by_p (dom, latch, header)) if (latch != ENTRY_BLOCK_PTR
&& dominated_by_p (CDI_DOMINATORS, latch, header))
{ {
/* Shared headers should be eliminated by now. */ /* Shared headers should be eliminated by now. */
if (more_latches) if (more_latches)
...@@ -849,7 +844,6 @@ flow_loops_find (struct loops *loops, int flags) ...@@ -849,7 +844,6 @@ flow_loops_find (struct loops *loops, int flags)
flow_depth_first_order_compute (dfs_order, rc_order); flow_depth_first_order_compute (dfs_order, rc_order);
/* Save CFG derived information to avoid recomputing it. */ /* Save CFG derived information to avoid recomputing it. */
loops->cfg.dom = dom;
loops->cfg.dfs_order = dfs_order; loops->cfg.dfs_order = dfs_order;
loops->cfg.rc_order = rc_order; loops->cfg.rc_order = rc_order;
...@@ -878,7 +872,7 @@ flow_loops_find (struct loops *loops, int flags) ...@@ -878,7 +872,7 @@ flow_loops_find (struct loops *loops, int flags)
basic_block latch = e->src; basic_block latch = e->src;
if (latch != ENTRY_BLOCK_PTR if (latch != ENTRY_BLOCK_PTR
&& dominated_by_p (dom, latch, header)) && dominated_by_p (CDI_DOMINATORS, latch, header))
{ {
loop->latch = latch; loop->latch = latch;
break; break;
...@@ -897,14 +891,13 @@ flow_loops_find (struct loops *loops, int flags) ...@@ -897,14 +891,13 @@ flow_loops_find (struct loops *loops, int flags)
/* Scan the loops. */ /* Scan the loops. */
for (i = 1; i < num_loops; i++) for (i = 1; i < num_loops; i++)
flow_loop_scan (loops, loops->parray[i], flags); flow_loop_scan (loops->parray[i], flags);
loops->num = num_loops; loops->num = num_loops;
} }
else else
{ {
loops->cfg.dom = NULL; free_dominance_info (CDI_DOMINATORS);
free_dominance_info (dom);
} }
loops->state = 0; loops->state = 0;
......
...@@ -230,9 +230,6 @@ struct loops ...@@ -230,9 +230,6 @@ struct loops
/* Information derived from the CFG. */ /* Information derived from the CFG. */
struct cfg struct cfg
{ {
/* The bitmap vector of dominators or NULL if not computed. */
dominance_info dom;
/* The ordering of the basic blocks in a depth first search. */ /* The ordering of the basic blocks in a depth first search. */
int *dfs_order; int *dfs_order;
...@@ -265,7 +262,7 @@ extern void flow_loops_dump (const struct loops *, FILE *, ...@@ -265,7 +262,7 @@ extern void flow_loops_dump (const struct loops *, FILE *,
void (*)(const struct loop *, FILE *, int), int); void (*)(const struct loop *, FILE *, int), int);
extern void flow_loop_dump (const struct loop *, FILE *, extern void flow_loop_dump (const struct loop *, FILE *,
void (*)(const struct loop *, FILE *, int), int); void (*)(const struct loop *, FILE *, int), int);
extern int flow_loop_scan (struct loops *, struct loop *, int); extern int flow_loop_scan (struct loop *, int);
extern void flow_loop_free (struct loop *); extern void flow_loop_free (struct loop *);
void mark_irreducible_loops (struct loops *); void mark_irreducible_loops (struct loops *);
...@@ -292,7 +289,7 @@ extern void remove_bb_from_loops (basic_block); ...@@ -292,7 +289,7 @@ extern void remove_bb_from_loops (basic_block);
extern void cancel_loop (struct loops *, struct loop *); extern void cancel_loop (struct loops *, struct loop *);
extern void cancel_loop_tree (struct loops *, struct loop *); extern void cancel_loop_tree (struct loops *, struct loop *);
extern basic_block loop_split_edge_with (edge, rtx, struct loops *); extern basic_block loop_split_edge_with (edge, rtx);
extern int fix_loop_placement (struct loop *); extern int fix_loop_placement (struct loop *);
enum enum
...@@ -306,10 +303,9 @@ extern void force_single_succ_latches (struct loops *); ...@@ -306,10 +303,9 @@ extern void force_single_succ_latches (struct loops *);
extern void verify_loop_structure (struct loops *); extern void verify_loop_structure (struct loops *);
/* Loop analysis. */ /* Loop analysis. */
extern bool simple_loop_p (struct loops *, struct loop *, struct loop_desc *); extern bool simple_loop_p (struct loop *, struct loop_desc *);
extern rtx count_loop_iterations (struct loop_desc *, rtx, rtx); extern rtx count_loop_iterations (struct loop_desc *, rtx, rtx);
extern bool just_once_each_iteration_p (struct loops *,struct loop *, extern bool just_once_each_iteration_p (struct loop *, basic_block);
basic_block);
extern unsigned expected_loop_iterations (const struct loop *); extern unsigned expected_loop_iterations (const struct loop *);
/* Loop manipulation. */ /* Loop manipulation. */
...@@ -324,7 +320,7 @@ extern int duplicate_loop_to_header_edge (struct loop *, edge, struct loops *, ...@@ -324,7 +320,7 @@ extern int duplicate_loop_to_header_edge (struct loop *, edge, struct loops *,
extern struct loop *loopify (struct loops *, edge, edge, basic_block); extern struct loop *loopify (struct loops *, edge, edge, basic_block);
extern void unloop (struct loops *, struct loop *); extern void unloop (struct loops *, struct loop *);
extern bool remove_path (struct loops *, edge); extern bool remove_path (struct loops *, edge);
extern edge split_loop_bb (struct loops *, basic_block, rtx); extern edge split_loop_bb (basic_block, rtx);
/* Loop optimizer initialization. */ /* Loop optimizer initialization. */
extern struct loops *loop_optimizer_init (FILE *); extern struct loops *loop_optimizer_init (FILE *);
......
...@@ -39,14 +39,13 @@ static bool invariant_rtx_wrto_regs_p (rtx, regset); ...@@ -39,14 +39,13 @@ static bool invariant_rtx_wrto_regs_p (rtx, regset);
static rtx test_for_iteration (struct loop_desc *desc, unsigned HOST_WIDE_INT); static rtx test_for_iteration (struct loop_desc *desc, unsigned HOST_WIDE_INT);
static bool constant_iterations (struct loop_desc *, unsigned HOST_WIDE_INT *, static bool constant_iterations (struct loop_desc *, unsigned HOST_WIDE_INT *,
bool *); bool *);
static bool simple_loop_exit_p (struct loops *, struct loop *, edge, regset, static bool simple_loop_exit_p (struct loop *, edge, regset,
rtx *, struct loop_desc *); rtx *, struct loop_desc *);
static rtx variable_initial_value (rtx, regset, rtx, rtx *, enum machine_mode); static rtx variable_initial_value (rtx, regset, rtx, rtx *, enum machine_mode);
static rtx variable_initial_values (edge, rtx, enum machine_mode); static rtx variable_initial_values (edge, rtx, enum machine_mode);
static bool simple_condition_p (struct loop *, rtx, regset, static bool simple_condition_p (struct loop *, rtx, regset,
struct loop_desc *); struct loop_desc *);
static basic_block simple_increment (struct loops *, struct loop *, rtx *, static basic_block simple_increment (struct loop *, rtx *, struct loop_desc *);
struct loop_desc *);
static rtx count_strange_loop_iterations (rtx, rtx, enum rtx_code, static rtx count_strange_loop_iterations (rtx, rtx, enum rtx_code,
int, rtx, enum machine_mode, int, rtx, enum machine_mode,
enum machine_mode); enum machine_mode);
...@@ -73,10 +72,10 @@ inverse (unsigned HOST_WIDEST_INT x, int mod) ...@@ -73,10 +72,10 @@ inverse (unsigned HOST_WIDEST_INT x, int mod)
/* Checks whether BB is executed exactly once in each LOOP iteration. */ /* Checks whether BB is executed exactly once in each LOOP iteration. */
bool bool
just_once_each_iteration_p (struct loops *loops, struct loop *loop, basic_block bb) just_once_each_iteration_p (struct loop *loop, basic_block bb)
{ {
/* It must be executed at least once each iteration. */ /* It must be executed at least once each iteration. */
if (!dominated_by_p (loops->cfg.dom, loop->latch, bb)) if (!dominated_by_p (CDI_DOMINATORS, loop->latch, bb))
return false; return false;
/* And just once. */ /* And just once. */
...@@ -295,8 +294,8 @@ simple_condition_p (struct loop *loop ATTRIBUTE_UNUSED, rtx condition, ...@@ -295,8 +294,8 @@ simple_condition_p (struct loop *loop ATTRIBUTE_UNUSED, rtx condition,
iteration. Fills in DESC->stride and returns block in that DESC->var is iteration. Fills in DESC->stride and returns block in that DESC->var is
modified. */ modified. */
static basic_block static basic_block
simple_increment (struct loops *loops, struct loop *loop, simple_increment (struct loop *loop, rtx *simple_increment_regs,
rtx *simple_increment_regs, struct loop_desc *desc) struct loop_desc *desc)
{ {
rtx mod_insn, mod_insn1, set, set_src, set_add; rtx mod_insn, mod_insn1, set, set_src, set_add;
basic_block mod_bb, mod_bb1; basic_block mod_bb, mod_bb1;
...@@ -308,7 +307,7 @@ simple_increment (struct loops *loops, struct loop *loop, ...@@ -308,7 +307,7 @@ simple_increment (struct loops *loops, struct loop *loop,
mod_bb = BLOCK_FOR_INSN (mod_insn); mod_bb = BLOCK_FOR_INSN (mod_insn);
/* Check that it is executed exactly once each iteration. */ /* Check that it is executed exactly once each iteration. */
if (!just_once_each_iteration_p (loops, loop, mod_bb)) if (!just_once_each_iteration_p (loop, mod_bb))
return NULL; return NULL;
/* mod_insn must be a simple increment/decrement. */ /* mod_insn must be a simple increment/decrement. */
...@@ -355,7 +354,7 @@ simple_increment (struct loops *loops, struct loop *loop, ...@@ -355,7 +354,7 @@ simple_increment (struct loops *loops, struct loop *loop,
return NULL; return NULL;
mod_bb1 = BLOCK_FOR_INSN (mod_insn1); mod_bb1 = BLOCK_FOR_INSN (mod_insn1);
if (!dominated_by_p (loops->cfg.dom, mod_bb, mod_bb1)) if (!dominated_by_p (CDI_DOMINATORS, mod_bb, mod_bb1))
return NULL; return NULL;
if (mod_bb1 == mod_bb) if (mod_bb1 == mod_bb)
{ {
...@@ -962,7 +961,7 @@ test_for_iteration (struct loop_desc *desc, unsigned HOST_WIDE_INT iter) ...@@ -962,7 +961,7 @@ test_for_iteration (struct loop_desc *desc, unsigned HOST_WIDE_INT iter)
description joined to it in in DESC. INVARIANT_REGS and SINGLE_SET_REGS description joined to it in in DESC. INVARIANT_REGS and SINGLE_SET_REGS
are results of blocks_{invariant,single_set}_regs over BODY. */ are results of blocks_{invariant,single_set}_regs over BODY. */
static bool static bool
simple_loop_exit_p (struct loops *loops, struct loop *loop, edge exit_edge, simple_loop_exit_p (struct loop *loop, edge exit_edge,
regset invariant_regs, rtx *single_set_regs, regset invariant_regs, rtx *single_set_regs,
struct loop_desc *desc) struct loop_desc *desc)
{ {
...@@ -979,7 +978,7 @@ simple_loop_exit_p (struct loops *loops, struct loop *loop, edge exit_edge, ...@@ -979,7 +978,7 @@ simple_loop_exit_p (struct loops *loops, struct loop *loop, edge exit_edge,
return false; return false;
/* It must be tested (at least) once during any iteration. */ /* It must be tested (at least) once during any iteration. */
if (!dominated_by_p (loops->cfg.dom, loop->latch, exit_bb)) if (!dominated_by_p (CDI_DOMINATORS, loop->latch, exit_bb))
return false; return false;
/* It must end in a simple conditional jump. */ /* It must end in a simple conditional jump. */
...@@ -1003,11 +1002,11 @@ simple_loop_exit_p (struct loops *loops, struct loop *loop, edge exit_edge, ...@@ -1003,11 +1002,11 @@ simple_loop_exit_p (struct loops *loops, struct loop *loop, edge exit_edge,
/* Var must be simply incremented or decremented in exactly one insn that /* Var must be simply incremented or decremented in exactly one insn that
is executed just once every iteration. */ is executed just once every iteration. */
if (!(mod_bb = simple_increment (loops, loop, single_set_regs, desc))) if (!(mod_bb = simple_increment (loop, single_set_regs, desc)))
return false; return false;
/* OK, it is simple loop. Now just fill in remaining info. */ /* OK, it is simple loop. Now just fill in remaining info. */
desc->postincr = !dominated_by_p (loops->cfg.dom, exit_bb, mod_bb); desc->postincr = !dominated_by_p (CDI_DOMINATORS, exit_bb, mod_bb);
desc->neg = !fallthru_out; desc->neg = !fallthru_out;
/* Find initial value of var and alternative values for lim. */ /* Find initial value of var and alternative values for lim. */
...@@ -1026,7 +1025,7 @@ simple_loop_exit_p (struct loops *loops, struct loop *loop, edge exit_edge, ...@@ -1026,7 +1025,7 @@ simple_loop_exit_p (struct loops *loops, struct loop *loop, edge exit_edge,
/* Tests whether LOOP is simple for loop. Returns simple loop description /* Tests whether LOOP is simple for loop. Returns simple loop description
in DESC. */ in DESC. */
bool bool
simple_loop_p (struct loops *loops, struct loop *loop, struct loop_desc *desc) simple_loop_p (struct loop *loop, struct loop_desc *desc)
{ {
unsigned i; unsigned i;
basic_block *body; basic_block *body;
...@@ -1051,7 +1050,7 @@ simple_loop_p (struct loops *loops, struct loop *loop, struct loop_desc *desc) ...@@ -1051,7 +1050,7 @@ simple_loop_p (struct loops *loops, struct loop *loop, struct loop_desc *desc)
{ {
for (e = body[i]->succ; e; e = e->succ_next) for (e = body[i]->succ; e; e = e->succ_next)
if (!flow_bb_inside_loop_p (loop, e->dest) if (!flow_bb_inside_loop_p (loop, e->dest)
&& simple_loop_exit_p (loops, loop, e, && simple_loop_exit_p (loop, e,
invariant_regs, single_set_regs, &act)) invariant_regs, single_set_regs, &act))
{ {
/* Prefer constant iterations; the less the better. */ /* Prefer constant iterations; the less the better. */
......
...@@ -36,9 +36,9 @@ static void copy_loops_to (struct loops *, struct loop **, int, ...@@ -36,9 +36,9 @@ static void copy_loops_to (struct loops *, struct loop **, int,
struct loop *); struct loop *);
static void loop_redirect_edge (edge, basic_block); static void loop_redirect_edge (edge, basic_block);
static bool loop_delete_branch_edge (edge, int); static bool loop_delete_branch_edge (edge, int);
static void remove_bbs (dominance_info, basic_block *, int); static void remove_bbs (basic_block *, int);
static bool rpe_enum_p (basic_block, void *); static bool rpe_enum_p (basic_block, void *);
static int find_path (edge, dominance_info, basic_block **); static int find_path (edge, basic_block **);
static bool alp_enum_p (basic_block, void *); static bool alp_enum_p (basic_block, void *);
static void add_loop (struct loops *, struct loop *); static void add_loop (struct loops *, struct loop *);
static void fix_loop_placements (struct loop *); static void fix_loop_placements (struct loop *);
...@@ -47,17 +47,15 @@ static void fix_bb_placements (struct loops *, basic_block); ...@@ -47,17 +47,15 @@ static void fix_bb_placements (struct loops *, basic_block);
static void place_new_loop (struct loops *, struct loop *); static void place_new_loop (struct loops *, struct loop *);
static void scale_loop_frequencies (struct loop *, int, int); static void scale_loop_frequencies (struct loop *, int, int);
static void scale_bbs_frequencies (basic_block *, int, int, int); static void scale_bbs_frequencies (basic_block *, int, int, int);
static basic_block create_preheader (struct loop *, dominance_info, int); static basic_block create_preheader (struct loop *, int);
static void fix_irreducible_loops (basic_block); static void fix_irreducible_loops (basic_block);
/* Splits basic block BB after INSN, returns created edge. Updates loops /* Splits basic block BB after INSN, returns created edge. Updates loops
and dominators. */ and dominators. */
edge edge
split_loop_bb (struct loops *loops, basic_block bb, rtx insn) split_loop_bb (basic_block bb, rtx insn)
{ {
edge e; edge e;
basic_block *dom_bbs;
int n_dom_bbs, i;
/* Split the block. */ /* Split the block. */
e = split_block (bb, insn); e = split_block (bb, insn);
...@@ -66,42 +64,31 @@ split_loop_bb (struct loops *loops, basic_block bb, rtx insn) ...@@ -66,42 +64,31 @@ split_loop_bb (struct loops *loops, basic_block bb, rtx insn)
add_bb_to_loop (e->dest, e->src->loop_father); add_bb_to_loop (e->dest, e->src->loop_father);
/* Fix dominators. */ /* Fix dominators. */
add_to_dominance_info (loops->cfg.dom, e->dest); add_to_dominance_info (CDI_DOMINATORS, e->dest);
n_dom_bbs = get_dominated_by (loops->cfg.dom, e->src, &dom_bbs); redirect_immediate_dominators (CDI_DOMINATORS, e->src, e->dest);
for (i = 0; i < n_dom_bbs; i++) set_immediate_dominator (CDI_DOMINATORS, e->dest, e->src);
set_immediate_dominator (loops->cfg.dom, dom_bbs[i], e->dest);
free (dom_bbs);
set_immediate_dominator (loops->cfg.dom, e->dest, e->src);
return e; return e;
} }
/* Checks whether basic block BB is dominated by RPE->DOM, where /* Checks whether basic block BB is dominated by DATA. */
RPE is passed through DATA. */
struct rpe_data
{
basic_block dom;
dominance_info doms;
};
static bool static bool
rpe_enum_p (basic_block bb, void *data) rpe_enum_p (basic_block bb, void *data)
{ {
struct rpe_data *rpe = data; return dominated_by_p (CDI_DOMINATORS, bb, data);
return dominated_by_p (rpe->doms, bb, rpe->dom);
} }
/* Remove basic blocks BBS from loop structure and dominance info, /* Remove basic blocks BBS from loop structure and dominance info,
and delete them afterwards. */ and delete them afterwards. */
static void static void
remove_bbs (dominance_info dom, basic_block *bbs, int nbbs) remove_bbs (basic_block *bbs, int nbbs)
{ {
int i; int i;
for (i = 0; i < nbbs; i++) for (i = 0; i < nbbs; i++)
{ {
remove_bb_from_loops (bbs[i]); remove_bb_from_loops (bbs[i]);
delete_from_dominance_info (dom, bbs[i]); delete_from_dominance_info (CDI_DOMINATORS, bbs[i]);
delete_block (bbs[i]); delete_block (bbs[i]);
} }
} }
...@@ -113,19 +100,15 @@ remove_bbs (dominance_info dom, basic_block *bbs, int nbbs) ...@@ -113,19 +100,15 @@ remove_bbs (dominance_info dom, basic_block *bbs, int nbbs)
alter anything by this function). The number of basic blocks in the alter anything by this function). The number of basic blocks in the
path is returned. */ path is returned. */
static int static int
find_path (edge e, dominance_info doms, basic_block **bbs) find_path (edge e, basic_block **bbs)
{ {
struct rpe_data rpe;
if (e->dest->pred->pred_next) if (e->dest->pred->pred_next)
abort (); abort ();
/* Find bbs in the path. */ /* Find bbs in the path. */
rpe.dom = e->dest;
rpe.doms = doms;
*bbs = xcalloc (n_basic_blocks, sizeof (basic_block)); *bbs = xcalloc (n_basic_blocks, sizeof (basic_block));
return dfs_enumerate_from (e->dest, 0, rpe_enum_p, *bbs, return dfs_enumerate_from (e->dest, 0, rpe_enum_p, *bbs,
n_basic_blocks, &rpe); n_basic_blocks, e->dest);
} }
/* Fix placement of basic block BB inside loop hierarchy stored in LOOPS -- /* Fix placement of basic block BB inside loop hierarchy stored in LOOPS --
...@@ -353,19 +336,19 @@ remove_path (struct loops *loops, edge e) ...@@ -353,19 +336,19 @@ remove_path (struct loops *loops, edge e)
fix -- when e->dest has exactly one predecessor, this corresponds fix -- when e->dest has exactly one predecessor, this corresponds
to blocks dominated by e->dest, if not, split the edge. */ to blocks dominated by e->dest, if not, split the edge. */
if (e->dest->pred->pred_next) if (e->dest->pred->pred_next)
e = loop_split_edge_with (e, NULL_RTX, loops)->pred; e = loop_split_edge_with (e, NULL_RTX)->pred;
/* It may happen that by removing path we remove one or more loops /* It may happen that by removing path we remove one or more loops
we belong to. In this case first unloop the loops, then proceed we belong to. In this case first unloop the loops, then proceed
normally. We may assume that e->dest is not a header of any loop, normally. We may assume that e->dest is not a header of any loop,
as it now has exactly one predecessor. */ as it now has exactly one predecessor. */
while (e->src->loop_father->outer while (e->src->loop_father->outer
&& dominated_by_p (loops->cfg.dom, && dominated_by_p (CDI_DOMINATORS,
e->src->loop_father->latch, e->dest)) e->src->loop_father->latch, e->dest))
unloop (loops, e->src->loop_father); unloop (loops, e->src->loop_father);
/* Identify the path. */ /* Identify the path. */
nrem = find_path (e, loops->cfg.dom, &rem_bbs); nrem = find_path (e, &rem_bbs);
n_bord_bbs = 0; n_bord_bbs = 0;
bord_bbs = xcalloc (n_basic_blocks, sizeof (basic_block)); bord_bbs = xcalloc (n_basic_blocks, sizeof (basic_block));
...@@ -397,7 +380,7 @@ remove_path (struct loops *loops, edge e) ...@@ -397,7 +380,7 @@ remove_path (struct loops *loops, edge e)
if (rem_bbs[i]->loop_father->header == rem_bbs[i]) if (rem_bbs[i]->loop_father->header == rem_bbs[i])
cancel_loop_tree (loops, rem_bbs[i]->loop_father); cancel_loop_tree (loops, rem_bbs[i]->loop_father);
remove_bbs (loops->cfg.dom, rem_bbs, nrem); remove_bbs (rem_bbs, nrem);
free (rem_bbs); free (rem_bbs);
/* Find blocks whose dominators may be affected. */ /* Find blocks whose dominators may be affected. */
...@@ -405,25 +388,24 @@ remove_path (struct loops *loops, edge e) ...@@ -405,25 +388,24 @@ remove_path (struct loops *loops, edge e)
sbitmap_zero (seen); sbitmap_zero (seen);
for (i = 0; i < n_bord_bbs; i++) for (i = 0; i < n_bord_bbs; i++)
{ {
int j, nldom; basic_block ldom;
basic_block *ldom;
bb = get_immediate_dominator (loops->cfg.dom, bord_bbs[i]); bb = get_immediate_dominator (CDI_DOMINATORS, bord_bbs[i]);
if (TEST_BIT (seen, bb->index)) if (TEST_BIT (seen, bb->index))
continue; continue;
SET_BIT (seen, bb->index); SET_BIT (seen, bb->index);
nldom = get_dominated_by (loops->cfg.dom, bb, &ldom); for (ldom = first_dom_son (CDI_DOMINATORS, bb);
for (j = 0; j < nldom; j++) ldom;
if (!dominated_by_p (loops->cfg.dom, from, ldom[j])) ldom = next_dom_son (CDI_DOMINATORS, ldom))
dom_bbs[n_dom_bbs++] = ldom[j]; if (!dominated_by_p (CDI_DOMINATORS, from, ldom))
free(ldom); dom_bbs[n_dom_bbs++] = ldom;
} }
free (seen); free (seen);
/* Recount dominators. */ /* Recount dominators. */
iterate_fix_dominators (loops->cfg.dom, dom_bbs, n_dom_bbs); iterate_fix_dominators (CDI_DOMINATORS, dom_bbs, n_dom_bbs);
free (dom_bbs); free (dom_bbs);
/* These blocks have lost some predecessor(s), thus their irreducible /* These blocks have lost some predecessor(s), thus their irreducible
...@@ -513,7 +495,7 @@ loopify (struct loops *loops, edge latch_edge, edge header_edge, basic_block swi ...@@ -513,7 +495,7 @@ loopify (struct loops *loops, edge latch_edge, edge header_edge, basic_block swi
basic_block succ_bb = latch_edge->dest; basic_block succ_bb = latch_edge->dest;
basic_block pred_bb = header_edge->src; basic_block pred_bb = header_edge->src;
basic_block *dom_bbs, *body; basic_block *dom_bbs, *body;
unsigned n_dom_bbs, i, j; unsigned n_dom_bbs, i;
sbitmap seen; sbitmap seen;
struct loop *loop = xcalloc (1, sizeof (struct loop)); struct loop *loop = xcalloc (1, sizeof (struct loop));
struct loop *outer = succ_bb->loop_father->outer; struct loop *outer = succ_bb->loop_father->outer;
...@@ -538,9 +520,9 @@ loopify (struct loops *loops, edge latch_edge, edge header_edge, basic_block swi ...@@ -538,9 +520,9 @@ loopify (struct loops *loops, edge latch_edge, edge header_edge, basic_block swi
loop_redirect_edge (switch_bb->succ, succ_bb); loop_redirect_edge (switch_bb->succ, succ_bb);
/* Update dominators. */ /* Update dominators. */
set_immediate_dominator (loops->cfg.dom, switch_bb, pred_bb); set_immediate_dominator (CDI_DOMINATORS, switch_bb, pred_bb);
set_immediate_dominator (loops->cfg.dom, loop->header, switch_bb); set_immediate_dominator (CDI_DOMINATORS, loop->header, switch_bb);
set_immediate_dominator (loops->cfg.dom, succ_bb, switch_bb); set_immediate_dominator (CDI_DOMINATORS, succ_bb, switch_bb);
/* Compute new loop. */ /* Compute new loop. */
add_loop (loops, loop); add_loop (loops, loop);
...@@ -569,20 +551,19 @@ loopify (struct loops *loops, edge latch_edge, edge header_edge, basic_block swi ...@@ -569,20 +551,19 @@ loopify (struct loops *loops, edge latch_edge, edge header_edge, basic_block swi
for (i = 0; i < loop->num_nodes; i++) for (i = 0; i < loop->num_nodes; i++)
{ {
unsigned nldom; basic_block ldom;
basic_block *ldom;
nldom = get_dominated_by (loops->cfg.dom, body[i], &ldom); for (ldom = first_dom_son (CDI_DOMINATORS, body[i]);
for (j = 0; j < nldom; j++) ldom;
if (!TEST_BIT (seen, ldom[j]->index)) ldom = next_dom_son (CDI_DOMINATORS, ldom))
if (!TEST_BIT (seen, ldom->index))
{ {
SET_BIT (seen, ldom[j]->index); SET_BIT (seen, ldom->index);
dom_bbs[n_dom_bbs++] = ldom[j]; dom_bbs[n_dom_bbs++] = ldom;
} }
free (ldom);
} }
iterate_fix_dominators (loops->cfg.dom, dom_bbs, n_dom_bbs); iterate_fix_dominators (CDI_DOMINATORS, dom_bbs, n_dom_bbs);
free (body); free (body);
free (seen); free (seen);
...@@ -990,7 +971,7 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e, struct loops *loops, ...@@ -990,7 +971,7 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e, struct loops *loops,
copy_loops_to (loops, orig_loops, n_orig_loops, target); copy_loops_to (loops, orig_loops, n_orig_loops, target);
/* Copy bbs. */ /* Copy bbs. */
copy_bbs (bbs, n, new_bbs, spec_edges, 2, new_spec_edges, loop, loops); copy_bbs (bbs, n, new_bbs, spec_edges, 2, new_spec_edges, loop);
/* Note whether the blocks and edges belong to an irreducible loop. */ /* Note whether the blocks and edges belong to an irreducible loop. */
if (add_irreducible_flag) if (add_irreducible_flag)
...@@ -1019,7 +1000,7 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e, struct loops *loops, ...@@ -1019,7 +1000,7 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e, struct loops *loops,
redirect_edge_and_branch_force (latch_edge, new_bbs[0]); redirect_edge_and_branch_force (latch_edge, new_bbs[0]);
redirect_edge_and_branch_force (new_spec_edges[SE_LATCH], redirect_edge_and_branch_force (new_spec_edges[SE_LATCH],
loop->header); loop->header);
set_immediate_dominator (loops->cfg.dom, new_bbs[0], latch); set_immediate_dominator (CDI_DOMINATORS, new_bbs[0], latch);
latch = loop->latch = new_bbs[1]; latch = loop->latch = new_bbs[1];
e = latch_edge = new_spec_edges[SE_LATCH]; e = latch_edge = new_spec_edges[SE_LATCH];
} }
...@@ -1028,7 +1009,7 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e, struct loops *loops, ...@@ -1028,7 +1009,7 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e, struct loops *loops,
redirect_edge_and_branch_force (new_spec_edges[SE_LATCH], redirect_edge_and_branch_force (new_spec_edges[SE_LATCH],
loop->header); loop->header);
redirect_edge_and_branch_force (e, new_bbs[0]); redirect_edge_and_branch_force (e, new_bbs[0]);
set_immediate_dominator (loops->cfg.dom, new_bbs[0], e->src); set_immediate_dominator (CDI_DOMINATORS, new_bbs[0], e->src);
e = new_spec_edges[SE_LATCH]; e = new_spec_edges[SE_LATCH];
} }
...@@ -1056,7 +1037,7 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e, struct loops *loops, ...@@ -1056,7 +1037,7 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e, struct loops *loops,
/* Update the original loop. */ /* Update the original loop. */
if (!is_latch) if (!is_latch)
set_immediate_dominator (loops->cfg.dom, e->dest, e->src); set_immediate_dominator (CDI_DOMINATORS, e->dest, e->src);
if (flags & DLTHE_FLAG_UPDATE_FREQ) if (flags & DLTHE_FLAG_UPDATE_FREQ)
{ {
scale_bbs_frequencies (bbs, n, scale_main, REG_BR_PROB_BASE); scale_bbs_frequencies (bbs, n, scale_main, REG_BR_PROB_BASE);
...@@ -1070,15 +1051,15 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e, struct loops *loops, ...@@ -1070,15 +1051,15 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e, struct loops *loops,
int n_dom_bbs,j; int n_dom_bbs,j;
bb = bbs[i]; bb = bbs[i];
n_dom_bbs = get_dominated_by (loops->cfg.dom, bb, &dom_bbs); n_dom_bbs = get_dominated_by (CDI_DOMINATORS, bb, &dom_bbs);
for (j = 0; j < n_dom_bbs; j++) for (j = 0; j < n_dom_bbs; j++)
{ {
dominated = dom_bbs[j]; dominated = dom_bbs[j];
if (flow_bb_inside_loop_p (loop, dominated)) if (flow_bb_inside_loop_p (loop, dominated))
continue; continue;
dom_bb = nearest_common_dominator ( dom_bb = nearest_common_dominator (
loops->cfg.dom, first_active[i], first_active_latch); CDI_DOMINATORS, first_active[i], first_active_latch);
set_immediate_dominator (loops->cfg.dom, dominated, dom_bb); set_immediate_dominator (CDI_DOMINATORS, dominated, dom_bb);
} }
free (dom_bbs); free (dom_bbs);
} }
...@@ -1094,7 +1075,7 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e, struct loops *loops, ...@@ -1094,7 +1075,7 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e, struct loops *loops,
entry; otherwise we also force preheader block to have only one successor. entry; otherwise we also force preheader block to have only one successor.
The function also updates dominators stored in DOM. */ The function also updates dominators stored in DOM. */
static basic_block static basic_block
create_preheader (struct loop *loop, dominance_info dom, int flags) create_preheader (struct loop *loop, int flags)
{ {
edge e, fallthru; edge e, fallthru;
basic_block dummy; basic_block dummy;
...@@ -1141,7 +1122,7 @@ create_preheader (struct loop *loop, dominance_info dom, int flags) ...@@ -1141,7 +1122,7 @@ create_preheader (struct loop *loop, dominance_info dom, int flags)
if (ploop->latch == dummy) if (ploop->latch == dummy)
ploop->latch = fallthru->dest; ploop->latch = fallthru->dest;
add_to_dominance_info (dom, fallthru->dest); add_to_dominance_info (CDI_DOMINATORS, fallthru->dest);
/* Redirect edges. */ /* Redirect edges. */
for (e = dummy->pred; e; e = e->pred_next) for (e = dummy->pred; e; e = e->pred_next)
...@@ -1159,15 +1140,15 @@ create_preheader (struct loop *loop, dominance_info dom, int flags) ...@@ -1159,15 +1140,15 @@ create_preheader (struct loop *loop, dominance_info dom, int flags)
jump = redirect_edge_and_branch_force (e, loop->header); jump = redirect_edge_and_branch_force (e, loop->header);
if (jump) if (jump)
{ {
add_to_dominance_info (dom, jump); add_to_dominance_info (CDI_DOMINATORS, jump);
set_immediate_dominator (dom, jump, src); set_immediate_dominator (CDI_DOMINATORS, jump, src);
add_bb_to_loop (jump, loop); add_bb_to_loop (jump, loop);
loop->latch = jump; loop->latch = jump;
} }
/* Update structures. */ /* Update structures. */
redirect_immediate_dominators (dom, dummy, loop->header); redirect_immediate_dominators (CDI_DOMINATORS, dummy, loop->header);
set_immediate_dominator (dom, loop->header, dummy); set_immediate_dominator (CDI_DOMINATORS, loop->header, dummy);
loop->header->loop_father = loop; loop->header->loop_father = loop;
add_bb_to_loop (dummy, cloop); add_bb_to_loop (dummy, cloop);
if (rtl_dump_file) if (rtl_dump_file)
...@@ -1184,7 +1165,7 @@ create_preheaders (struct loops *loops, int flags) ...@@ -1184,7 +1165,7 @@ create_preheaders (struct loops *loops, int flags)
{ {
unsigned i; unsigned i;
for (i = 1; i < loops->num; i++) for (i = 1; i < loops->num; i++)
create_preheader (loops->parray[i], loops->cfg.dom, flags); create_preheader (loops->parray[i], flags);
loops->state |= LOOPS_HAVE_PREHEADERS; loops->state |= LOOPS_HAVE_PREHEADERS;
} }
...@@ -1207,7 +1188,7 @@ force_single_succ_latches (struct loops *loops) ...@@ -1207,7 +1188,7 @@ force_single_succ_latches (struct loops *loops)
for (e = loop->header->pred; e->src != loop->latch; e = e->pred_next) for (e = loop->header->pred; e->src != loop->latch; e = e->pred_next)
continue; continue;
loop_split_edge_with (e, NULL_RTX, loops); loop_split_edge_with (e, NULL_RTX);
} }
loops->state |= LOOPS_HAVE_SIMPLE_LATCHES; loops->state |= LOOPS_HAVE_SIMPLE_LATCHES;
} }
...@@ -1217,7 +1198,7 @@ force_single_succ_latches (struct loops *loops) ...@@ -1217,7 +1198,7 @@ force_single_succ_latches (struct loops *loops)
be ok after this function. The created block is placed on correct place be ok after this function. The created block is placed on correct place
in LOOPS structure and its dominator is set. */ in LOOPS structure and its dominator is set. */
basic_block basic_block
loop_split_edge_with (edge e, rtx insns, struct loops *loops) loop_split_edge_with (edge e, rtx insns)
{ {
basic_block src, dest, new_bb; basic_block src, dest, new_bb;
struct loop *loop_c; struct loop *loop_c;
...@@ -1231,7 +1212,7 @@ loop_split_edge_with (edge e, rtx insns, struct loops *loops) ...@@ -1231,7 +1212,7 @@ loop_split_edge_with (edge e, rtx insns, struct loops *loops)
/* Create basic block for it. */ /* Create basic block for it. */
new_bb = split_edge (e); new_bb = split_edge (e);
add_to_dominance_info (loops->cfg.dom, new_bb); add_to_dominance_info (CDI_DOMINATORS, new_bb);
add_bb_to_loop (new_bb, loop_c); add_bb_to_loop (new_bb, loop_c);
new_bb->flags = insns ? BB_SUPERBLOCK : 0; new_bb->flags = insns ? BB_SUPERBLOCK : 0;
...@@ -1245,9 +1226,9 @@ loop_split_edge_with (edge e, rtx insns, struct loops *loops) ...@@ -1245,9 +1226,9 @@ loop_split_edge_with (edge e, rtx insns, struct loops *loops)
if (insns) if (insns)
emit_insn_after (insns, BB_END (new_bb)); emit_insn_after (insns, BB_END (new_bb));
set_immediate_dominator (loops->cfg.dom, new_bb, src); set_immediate_dominator (CDI_DOMINATORS, new_bb, src);
set_immediate_dominator (loops->cfg.dom, dest, set_immediate_dominator (CDI_DOMINATORS, dest,
recount_dominator (loops->cfg.dom, dest)); recount_dominator (CDI_DOMINATORS, dest));
if (dest->loop_father->latch == src) if (dest->loop_father->latch == src)
dest->loop_father->latch = new_bb; dest->loop_father->latch = new_bb;
......
...@@ -43,16 +43,8 @@ ...@@ -43,16 +43,8 @@
#include "errors.h" #include "errors.h"
#include "et-forest.h" #include "et-forest.h"
struct dominance_info /* Whether the dominators and the postdominators are available. */
{ enum dom_state dom_computed[2];
et_forest_t forest;
varray_type varray;
};
#define BB_NODE(info, bb) \
((et_forest_node_t)VARRAY_GENERIC_PTR ((info)->varray, (bb)->index + 2))
#define SET_BB_NODE(info, bb, node) \
(VARRAY_GENERIC_PTR ((info)->varray, (bb)->index + 2) = (node))
/* We name our nodes with integers, beginning with 1. Zero is reserved for /* We name our nodes with integers, beginning with 1. Zero is reserved for
'undefined' or 'end of list'. The name of each node is given by the dfs 'undefined' or 'end of list'. The name of each node is given by the dfs
...@@ -124,7 +116,7 @@ static void compress (struct dom_info *, TBB); ...@@ -124,7 +116,7 @@ static void compress (struct dom_info *, TBB);
static TBB eval (struct dom_info *, TBB); static TBB eval (struct dom_info *, TBB);
static void link_roots (struct dom_info *, TBB, TBB); static void link_roots (struct dom_info *, TBB, TBB);
static void calc_idoms (struct dom_info *, enum cdi_direction); static void calc_idoms (struct dom_info *, enum cdi_direction);
void debug_dominance_info (dominance_info); void debug_dominance_info (enum cdi_direction);
/* Helper macro for allocating and initializing an array, /* Helper macro for allocating and initializing an array,
for aesthetic reasons. */ for aesthetic reasons. */
...@@ -526,172 +518,250 @@ calc_idoms (struct dom_info *di, enum cdi_direction reverse) ...@@ -526,172 +518,250 @@ calc_idoms (struct dom_info *di, enum cdi_direction reverse)
di->dom[v] = di->dom[di->dom[v]]; di->dom[v] = di->dom[di->dom[v]];
} }
/* The main entry point into this module. IDOM is an integer array with room /* Assign dfs numbers starting from NUM to NODE and its sons. */
for last_basic_block integers, DOMS is a preallocated sbitmap array having
room for last_basic_block^2 bits, and POST is true if the caller wants to static void
know post-dominators. assign_dfs_numbers (struct et_node *node, int *num)
{
struct et_node *son;
node->dfs_num_in = (*num)++;
if (node->son)
{
assign_dfs_numbers (node->son, num);
for (son = node->son->right; son != node->son; son = son->right)
assign_dfs_numbers (son, num);
}
On return IDOM[i] will be the BB->index of the immediate (post) dominator node->dfs_num_out = (*num)++;
of basic block i, and DOMS[i] will have set bit j if basic block j is a }
(post)dominator for block i.
Either IDOM or DOMS may be NULL (meaning the caller is not interested in /* Compute the data neccesary for fast resolving of dominator queries in a
immediate resp. all dominators). */ static dominator tree. */
dominance_info static void
calculate_dominance_info (enum cdi_direction reverse) compute_dom_fast_query (enum cdi_direction dir)
{
int num = 0;
basic_block bb;
if (dom_computed[dir] < DOM_NO_FAST_QUERY)
abort ();
if (dom_computed[dir] == DOM_OK)
return;
FOR_ALL_BB (bb)
{
if (!bb->dom[dir]->father)
assign_dfs_numbers (bb->dom[dir], &num);
}
dom_computed[dir] = DOM_OK;
}
/* The main entry point into this module. DIR is set depending on whether
we want to compute dominators or postdominators. */
void
calculate_dominance_info (enum cdi_direction dir)
{ {
struct dom_info di; struct dom_info di;
dominance_info info;
basic_block b; basic_block b;
/* Allocate structure for dominance information. */ if (dom_computed[dir] == DOM_OK)
info = xmalloc (sizeof (struct dominance_info)); return;
info->forest = et_forest_create ();
VARRAY_GENERIC_PTR_INIT (info->varray, last_basic_block + 3, "dominance info");
/* Add the two well-known basic blocks. */ if (dom_computed[dir] != DOM_NO_FAST_QUERY)
SET_BB_NODE (info, ENTRY_BLOCK_PTR, et_forest_add_node (info->forest, {
ENTRY_BLOCK_PTR)); if (dom_computed[dir] != DOM_NONE)
SET_BB_NODE (info, EXIT_BLOCK_PTR, et_forest_add_node (info->forest, free_dominance_info (dir);
EXIT_BLOCK_PTR));
FOR_EACH_BB (b)
SET_BB_NODE (info, b, et_forest_add_node (info->forest, b));
init_dom_info (&di); FOR_ALL_BB (b)
calc_dfs_tree (&di, reverse); {
calc_idoms (&di, reverse); b->dom[dir] = et_new_tree (b);
}
init_dom_info (&di);
calc_dfs_tree (&di, dir);
calc_idoms (&di, dir);
FOR_EACH_BB (b) FOR_EACH_BB (b)
{ {
TBB d = di.dom[di.dfs_order[b->index]]; TBB d = di.dom[di.dfs_order[b->index]];
if (di.dfs_to_bb[d]) if (di.dfs_to_bb[d])
et_forest_add_edge (info->forest, BB_NODE (info, di.dfs_to_bb[d]), BB_NODE (info, b)); et_set_father (b->dom[dir], di.dfs_to_bb[d]->dom[dir]);
} }
free_dom_info (&di); free_dom_info (&di);
return info; dom_computed[dir] = DOM_NO_FAST_QUERY;
}
compute_dom_fast_query (dir);
} }
/* Free dominance information. */ /* Free dominance information for direction DIR. */
void void
free_dominance_info (dominance_info info) free_dominance_info (enum cdi_direction dir)
{ {
basic_block bb; basic_block bb;
/* Allow users to create new basic block without setting up the dominance if (!dom_computed[dir])
information for them. */ return;
FOR_EACH_BB (bb)
if (bb->index < (int)(info->varray->num_elements - 2) FOR_ALL_BB (bb)
&& BB_NODE (info, bb)) {
delete_from_dominance_info (info, bb); delete_from_dominance_info (dir, bb);
delete_from_dominance_info (info, ENTRY_BLOCK_PTR); }
delete_from_dominance_info (info, EXIT_BLOCK_PTR);
et_forest_delete (info->forest); dom_computed[dir] = DOM_NONE;
VARRAY_GROW (info->varray, 0);
free (info);
} }
/* Return the immediate dominator of basic block BB. */ /* Return the immediate dominator of basic block BB. */
basic_block basic_block
get_immediate_dominator (dominance_info dom, basic_block bb) get_immediate_dominator (enum cdi_direction dir, basic_block bb)
{ {
return et_forest_node_value (dom->forest, struct et_node *node = bb->dom[dir];
et_forest_parent (dom->forest,
BB_NODE (dom, bb))); if (!dom_computed[dir])
abort ();
if (!node->father)
return NULL;
return node->father->data;
} }
/* Set the immediate dominator of the block possibly removing /* Set the immediate dominator of the block possibly removing
existing edge. NULL can be used to remove any edge. */ existing edge. NULL can be used to remove any edge. */
inline void inline void
set_immediate_dominator (dominance_info dom, basic_block bb, basic_block dominated_by) set_immediate_dominator (enum cdi_direction dir, basic_block bb,
basic_block dominated_by)
{ {
void *aux_bb_node; struct et_node *node = bb->dom[dir];
et_forest_node_t bb_node = BB_NODE (dom, bb);
aux_bb_node = et_forest_parent (dom->forest, bb_node); if (!dom_computed[dir])
if (aux_bb_node)
et_forest_remove_edge (dom->forest, aux_bb_node, bb_node);
if (dominated_by != NULL)
{
if (bb == dominated_by)
abort ();
if (!et_forest_add_edge (dom->forest, BB_NODE (dom, dominated_by), bb_node))
abort (); abort ();
if (node->father)
{
if (node->father->data == dominated_by)
return;
et_split (node);
} }
if (dominated_by)
et_set_father (node, dominated_by->dom[dir]);
if (dom_computed[dir] == DOM_OK)
dom_computed[dir] = DOM_NO_FAST_QUERY;
} }
/* Store all basic blocks dominated by BB into BBS and return their number. */ /* Store all basic blocks immediatelly dominated by BB into BBS and return
their number. */
int int
get_dominated_by (dominance_info dom, basic_block bb, basic_block **bbs) get_dominated_by (enum cdi_direction dir, basic_block bb, basic_block **bbs)
{ {
int n, i; int n;
struct et_node *node = bb->dom[dir], *son = node->son, *ason;
if (!dom_computed[dir])
abort ();
if (!son)
{
*bbs = NULL;
return 0;
}
for (ason = son->right, n = 1; ason != son; ason = ason->right)
n++;
*bbs = xmalloc (n * sizeof (basic_block));
(*bbs)[0] = son->data;
for (ason = son->right, n = 1; ason != son; ason = ason->right)
(*bbs)[n++] = ason->data;
*bbs = xmalloc (n_basic_blocks * sizeof (basic_block));
n = et_forest_enumerate_sons (dom->forest, BB_NODE (dom, bb), (et_forest_node_t *)*bbs);
for (i = 0; i < n; i++)
(*bbs)[i] = et_forest_node_value (dom->forest, (et_forest_node_t)(*bbs)[i]);
return n; return n;
} }
/* Redirect all edges pointing to BB to TO. */ /* Redirect all edges pointing to BB to TO. */
void void
redirect_immediate_dominators (dominance_info dom, basic_block bb, basic_block to) redirect_immediate_dominators (enum cdi_direction dir, basic_block bb,
basic_block to)
{ {
et_forest_node_t *bbs = xmalloc (n_basic_blocks * sizeof (basic_block)); struct et_node *bb_node = bb->dom[dir], *to_node = to->dom[dir], *son;
et_forest_node_t node = BB_NODE (dom, bb);
et_forest_node_t node2 = BB_NODE (dom, to);
int n = et_forest_enumerate_sons (dom->forest, node, bbs);
int i;
for (i = 0; i < n; i++) if (!dom_computed[dir])
abort ();
if (!bb_node->son)
return;
while (bb_node->son)
{ {
et_forest_remove_edge (dom->forest, node, bbs[i]); son = bb_node->son;
et_forest_add_edge (dom->forest, node2, bbs[i]);
et_split (son);
et_set_father (son, to_node);
} }
free (bbs);
if (dom_computed[dir] == DOM_OK)
dom_computed[dir] = DOM_NO_FAST_QUERY;
} }
/* Find first basic block in the tree dominating both BB1 and BB2. */ /* Find first basic block in the tree dominating both BB1 and BB2. */
basic_block basic_block
nearest_common_dominator (dominance_info dom, basic_block bb1, basic_block bb2) nearest_common_dominator (enum cdi_direction dir, basic_block bb1, basic_block bb2)
{ {
if (!dom_computed[dir])
abort ();
if (!bb1) if (!bb1)
return bb2; return bb2;
if (!bb2) if (!bb2)
return bb1; return bb1;
return et_forest_node_value (dom->forest,
et_forest_common_ancestor (dom->forest, return et_nca (bb1->dom[dir], bb2->dom[dir])->data;
BB_NODE (dom, bb1),
BB_NODE (dom,
bb2)));
} }
/* Return TRUE in case BB1 is dominated by BB2. */ /* Return TRUE in case BB1 is dominated by BB2. */
bool bool
dominated_by_p (dominance_info dom, basic_block bb1, basic_block bb2) dominated_by_p (enum cdi_direction dir, basic_block bb1, basic_block bb2)
{ {
return nearest_common_dominator (dom, bb1, bb2) == bb2; struct et_node *n1 = bb1->dom[dir], *n2 = bb2->dom[dir];
if (!dom_computed[dir])
abort ();
if (dom_computed[dir] == DOM_OK)
return (n1->dfs_num_in >= n2->dfs_num_in
&& n1->dfs_num_out <= n2->dfs_num_out);
return et_below (n1, n2);
} }
/* Verify invariants of dominator structure. */ /* Verify invariants of dominator structure. */
void void
verify_dominators (dominance_info dom) verify_dominators (enum cdi_direction dir)
{ {
int err = 0; int err = 0;
basic_block bb; basic_block bb;
if (!dom_computed[dir])
abort ();
FOR_EACH_BB (bb) FOR_EACH_BB (bb)
{ {
basic_block dom_bb; basic_block dom_bb;
dom_bb = recount_dominator (dom, bb); dom_bb = recount_dominator (dir, bb);
if (dom_bb != get_immediate_dominator (dom, bb)) if (dom_bb != get_immediate_dominator (dir, bb))
{ {
error ("dominator of %d should be %d, not %d", error ("dominator of %d should be %d, not %d",
bb->index, dom_bb->index, get_immediate_dominator(dom, bb)->index); bb->index, dom_bb->index, get_immediate_dominator(dir, bb)->index);
err = 1; err = 1;
} }
} }
...@@ -701,15 +771,18 @@ verify_dominators (dominance_info dom) ...@@ -701,15 +771,18 @@ verify_dominators (dominance_info dom)
/* Recount dominator of BB. */ /* Recount dominator of BB. */
basic_block basic_block
recount_dominator (dominance_info dom, basic_block bb) recount_dominator (enum cdi_direction dir, basic_block bb)
{ {
basic_block dom_bb = NULL; basic_block dom_bb = NULL;
edge e; edge e;
if (!dom_computed[dir])
abort ();
for (e = bb->pred; e; e = e->pred_next) for (e = bb->pred; e; e = e->pred_next)
{ {
if (!dominated_by_p (dom, e->src, bb)) if (!dominated_by_p (dir, e->src, bb))
dom_bb = nearest_common_dominator (dom, dom_bb, e->src); dom_bb = nearest_common_dominator (dir, dom_bb, e->src);
} }
return dom_bb; return dom_bb;
...@@ -718,50 +791,85 @@ recount_dominator (dominance_info dom, basic_block bb) ...@@ -718,50 +791,85 @@ recount_dominator (dominance_info dom, basic_block bb)
/* Iteratively recount dominators of BBS. The change is supposed to be local /* Iteratively recount dominators of BBS. The change is supposed to be local
and not to grow further. */ and not to grow further. */
void void
iterate_fix_dominators (dominance_info dom, basic_block *bbs, int n) iterate_fix_dominators (enum cdi_direction dir, basic_block *bbs, int n)
{ {
int i, changed = 1; int i, changed = 1;
basic_block old_dom, new_dom; basic_block old_dom, new_dom;
if (!dom_computed[dir])
abort ();
while (changed) while (changed)
{ {
changed = 0; changed = 0;
for (i = 0; i < n; i++) for (i = 0; i < n; i++)
{ {
old_dom = get_immediate_dominator (dom, bbs[i]); old_dom = get_immediate_dominator (dir, bbs[i]);
new_dom = recount_dominator (dom, bbs[i]); new_dom = recount_dominator (dir, bbs[i]);
if (old_dom != new_dom) if (old_dom != new_dom)
{ {
changed = 1; changed = 1;
set_immediate_dominator (dom, bbs[i], new_dom); set_immediate_dominator (dir, bbs[i], new_dom);
} }
} }
} }
} }
void void
add_to_dominance_info (dominance_info dom, basic_block bb) add_to_dominance_info (enum cdi_direction dir, basic_block bb)
{ {
VARRAY_GROW (dom->varray, last_basic_block + 3); if (!dom_computed[dir])
#ifdef ENABLE_CHECKING abort ();
if (BB_NODE (dom, bb))
if (bb->dom[dir])
abort (); abort ();
#endif
SET_BB_NODE (dom, bb, et_forest_add_node (dom->forest, bb)); bb->dom[dir] = et_new_tree (bb);
if (dom_computed[dir] == DOM_OK)
dom_computed[dir] = DOM_NO_FAST_QUERY;
} }
void void
delete_from_dominance_info (dominance_info dom, basic_block bb) delete_from_dominance_info (enum cdi_direction dir, basic_block bb)
{ {
et_forest_remove_node (dom->forest, BB_NODE (dom, bb)); if (!dom_computed[dir])
SET_BB_NODE (dom, bb, NULL); abort ();
et_free_tree (bb->dom[dir]);
bb->dom[dir] = NULL;
if (dom_computed[dir] == DOM_OK)
dom_computed[dir] = DOM_NO_FAST_QUERY;
}
/* Returns the first son of BB in the dominator or postdominator tree
as determined by DIR. */
basic_block
first_dom_son (enum cdi_direction dir, basic_block bb)
{
struct et_node *son = bb->dom[dir]->son;
return son ? son->data : NULL;
}
/* Returns the next dominance son after BB in the dominator or postdominator
tree as determined by DIR, or NULL if it was the last one. */
basic_block
next_dom_son (enum cdi_direction dir, basic_block bb)
{
struct et_node *next = bb->dom[dir]->right;
return next->father->son == next ? NULL : next->data;
} }
void void
debug_dominance_info (dominance_info dom) debug_dominance_info (enum cdi_direction dir)
{ {
basic_block bb, bb2; basic_block bb, bb2;
FOR_EACH_BB (bb) FOR_EACH_BB (bb)
if ((bb2 = get_immediate_dominator (dom, bb))) if ((bb2 = get_immediate_dominator (dir, bb)))
fprintf (stderr, "%i %i\n", bb->index, bb2->index); fprintf (stderr, "%i %i\n", bb->index, bb2->index);
} }
...@@ -30,638 +30,714 @@ Boston, MA 02111-1307, USA. ...@@ -30,638 +30,714 @@ Boston, MA 02111-1307, USA.
#include "et-forest.h" #include "et-forest.h"
#include "alloc-pool.h" #include "alloc-pool.h"
struct et_forest_occurrence; /* We do not enable this with ENABLE_CHECKING, since it is awfully slow. */
typedef struct et_forest_occurrence* et_forest_occurrence_t; #undef DEBUG_ET
/* The ET-forest type. */ #ifdef DEBUG_ET
struct et_forest #include "basic-block.h"
{ #endif
/* Linked list of nodes is used to destroy the structure. */
int nnodes;
alloc_pool node_pool;
alloc_pool occur_pool;
};
/* Single occurrence of node in ET-forest. /* The occurence of a node in the et tree. */
A single node may have multiple occurrences. struct et_occ
*/
struct et_forest_occurrence
{ {
/* Parent in the splay-tree. */ struct et_node *of; /* The node. */
et_forest_occurrence_t parent;
struct et_occ *parent; /* Parent in the splay-tree. */
/* Children in the splay-tree. */ struct et_occ *prev; /* Left son in the splay-tree. */
et_forest_occurrence_t left, right; struct et_occ *next; /* Right son in the splay-tree. */
/* Counts of vertices in the two splay-subtrees. */ int depth; /* The depth of the node is the sum of depth
int count_left, count_right; fields on the path to the root. */
int min; /* The minimum value of the depth in the subtree
/* Next occurrence of this node in the sequence. */ is obtained by adding sum of depth fields
et_forest_occurrence_t next; on the path to the root. */
struct et_occ *min_occ; /* The occurence in the subtree with the minimal
/* The node, which this occurrence is of. */ depth. */
et_forest_node_t node;
}; };
static alloc_pool et_nodes;
static alloc_pool et_occurences;
/* ET-forest node. */ /* Changes depth of OCC to D. */
struct et_forest_node
{
et_forest_t forest;
void *value;
/* First and last occurrence of this node in the sequence. */ static inline void
et_forest_occurrence_t first, last; set_depth (struct et_occ *occ, int d)
}; {
if (!occ)
return;
occ->min += d - occ->depth;
occ->depth = d;
}
static et_forest_occurrence_t splay (et_forest_occurrence_t); /* Adds D to the depth of OCC. */
static void remove_all_occurrences (et_forest_t, et_forest_node_t);
static inline et_forest_occurrence_t find_leftmost_node
(et_forest_occurrence_t);
static inline et_forest_occurrence_t find_rightmost_node
(et_forest_occurrence_t);
static int calculate_value (et_forest_occurrence_t);
/* Return leftmost node present in the tree roted by OCC. */ static inline void
static inline et_forest_occurrence_t set_depth_add (struct et_occ *occ, int d)
find_leftmost_node (et_forest_occurrence_t occ)
{ {
while (occ->left) if (!occ)
occ = occ->left; return;
return occ; occ->min += d;
occ->depth += d;
} }
/* Return rightmost node present in the tree roted by OCC. */ /* Sets prev field of OCC to P. */
static inline et_forest_occurrence_t
find_rightmost_node (et_forest_occurrence_t occ) static inline void
set_prev (struct et_occ *occ, struct et_occ *t)
{ {
while (occ->right) #ifdef DEBUG_ET
occ = occ->right; if (occ == t)
return occ; abort ();
#endif
occ->prev = t;
if (t)
t->parent = occ;
} }
/* Sets next field of OCC to P. */
/* Operation splay for splay tree structure representing occurrences. */ static inline void
static et_forest_occurrence_t set_next (struct et_occ *occ, struct et_occ *t)
splay (et_forest_occurrence_t node)
{ {
et_forest_occurrence_t parent; #ifdef DEBUG_ET
et_forest_occurrence_t grandparent; if (occ == t)
abort ();
while (1) #endif
{
parent = node->parent;
if (! parent) occ->next = t;
return node; /* node == root. */ if (t)
t->parent = occ;
}
grandparent = parent->parent; /* Recompute minimum for occurence OCC. */
if (! grandparent) static inline void
break; et_recomp_min (struct et_occ *occ)
{
struct et_occ *mson = occ->prev;
/* Now there are four possible combinations: */ if (!mson
|| (occ->next
&& mson->min > occ->next->min))
mson = occ->next;
if (node == parent->left) if (mson && mson->min < 0)
{
if (parent == grandparent->left)
{ {
et_forest_occurrence_t node1, node2; occ->min = mson->min + occ->depth;
int count1, count2; occ->min_occ = mson->min_occ;
node1 = node->right;
count1 = node->count_right;
node2 = parent->right;
count2 = parent->count_right;
grandparent->left = node2;
grandparent->count_left = count2;
if (node2)
node2->parent = grandparent;
parent->left = node1;
parent->count_left = count1;
if (node1)
node1->parent = parent;
parent->right = grandparent;
parent->count_right = count2 + grandparent->count_right + 1;
node->right = parent;
node->count_right = count1 + parent->count_right + 1;
node->parent = grandparent->parent;
parent->parent = node;
grandparent->parent = parent;
if (node->parent)
{
if (node->parent->left == grandparent)
node->parent->left = node;
else
node->parent->right = node;
}
} }
else else
{ {
/* parent == grandparent->right && node == parent->left*/ occ->min = occ->depth;
et_forest_occurrence_t node1, node2; occ->min_occ = occ;
int count1, count2;
node1 = node->left;
count1 = node->count_left;
node2 = node->right;
count2 = node->count_right;
grandparent->right = node1;
grandparent->count_right = count1;
if (node1)
node1->parent = grandparent;
parent->left = node2;
parent->count_left = count2;
if (node2)
node2->parent = parent;
node->left = grandparent;
node->count_left = grandparent->count_left + count1 + 1;
node->right = parent;
node->count_right = parent->count_right + count2 + 1;
node->parent = grandparent->parent;
parent->parent = node;
grandparent->parent = node;
if (node->parent)
{
if (node->parent->left == grandparent)
node->parent->left = node;
else
node->parent->right = node;
}
} }
} }
else
{ #ifdef DEBUG_ET
/* node == parent->right. */ /* Checks whether neighbourhood of OCC seems sane. */
if (parent == grandparent->left)
{ static void
et_forest_occurrence_t node1, node2; et_check_occ_sanity (struct et_occ *occ)
int count1, count2; {
if (!occ)
node1 = node->left; return;
count1 = node->count_left;
node2 = node->right; if (occ->parent == occ)
count2 = node->count_right; abort ();
parent->right = node1; if (occ->prev == occ)
parent->count_right = count1; abort ();
if (node1)
node1->parent = parent; if (occ->next == occ)
grandparent->left = node2; abort ();
grandparent->count_left = count2;
if (node2) if (occ->next && occ->next == occ->prev)
node2->parent = grandparent; abort ();
node->left = parent;
node->count_left = parent->count_left + count1 + 1; if (occ->next)
node->right = grandparent;
node->count_right = grandparent->count_right + count2 + 1;
node->parent = grandparent->parent;
parent->parent = node;
grandparent->parent = node;
if (node->parent)
{ {
if (node->parent->left == grandparent) if (occ->next == occ->parent)
node->parent->left = node; abort ();
else
node->parent->right = node; if (occ->next->parent != occ)
} abort ();
} }
else
{ if (occ->prev)
/* parent == grandparent->right && node == parent->right*/
et_forest_occurrence_t node1, node2;
int count1, count2;
node1 = node->left;
count1 = node->count_left;
node2 = parent->left;
count2 = parent->count_left;
grandparent->right = node2;
grandparent->count_right = count2;
if (node2)
node2->parent = grandparent;
parent->right = node1;
parent->count_right = count1;
if (node1)
node1->parent = parent;
parent->left = grandparent;
parent->count_left = count2 + grandparent->count_left + 1;
node->left = parent;
node->count_left = count1 + parent->count_left + 1;
node->parent = grandparent->parent;
parent->parent = node;
grandparent->parent = parent;
if (node->parent)
{ {
if (node->parent->left == grandparent) if (occ->prev == occ->parent)
node->parent->left = node; abort ();
else
node->parent->right = node;
}
}
}
if (occ->prev->parent != occ)
abort ();
} }
/* parent == root. */ if (occ->parent
/* There are two possible combinations: */ && occ->parent->prev != occ
&& occ->parent->next != occ)
abort ();
}
/* Checks whether tree rooted at OCC is sane. */
if (node == parent->left) static void
{ et_check_sanity (struct et_occ *occ)
et_forest_occurrence_t node1; {
int count1; et_check_occ_sanity (occ);
if (occ->prev)
node1 = node->right; et_check_sanity (occ->prev);
count1 = node->count_right; if (occ->next)
et_check_sanity (occ->next);
parent->left = node1; }
parent->count_left = count1;
if (node1) /* Checks whether tree containing OCC is sane. */
node1->parent = parent;
node->right = parent; static void
node->count_right = parent->count_right + 1 + count1; et_check_tree_sanity (struct et_occ *occ)
node->parent = parent->parent; /* the same as = 0; */ {
parent->parent = node; while (occ->parent)
occ = occ->parent;
if (node->parent)
et_check_sanity (occ);
}
/* For recording the paths. */
static int len;
static void *datas[100000];
static int depths[100000];
/* Records the path represented by OCC, with depth incremented by DEPTH. */
static int
record_path_before_1 (struct et_occ *occ, int depth)
{
int mn, m;
depth += occ->depth;
mn = depth;
if (occ->prev)
{ {
if (node->parent->left == parent) m = record_path_before_1 (occ->prev, depth);
node->parent->left = node; if (m < mn)
else mn = m;
node->parent->right = node;
}
} }
else
{ fprintf (stderr, "%d (%d); ", ((basic_block) occ->of->data)->index, depth);
/* node == parent->right. */ depths[len] = depth;
et_forest_occurrence_t node1; datas[len] = occ->of;
int count1; len++;
node1 = node->left; if (occ->next)
count1 = node->count_left;
parent->right = node1;
parent->count_right = count1;
if (node1)
node1->parent = parent;
node->left = parent;
node->count_left = parent->count_left + 1 + count1;
node->parent = parent->parent; /* the same as = 0; */
parent->parent = node;
if (node->parent)
{ {
if (node->parent->left == parent) m = record_path_before_1 (occ->next, depth);
node->parent->left = node; if (m < mn)
else mn = m;
node->parent->right = node;
}
} }
return node; if (mn != occ->min + depth - occ->depth)
abort ();
return mn;
} }
/* Remove all occurrences of the given node before destroying the node. */ /* Records the path represented by a tree containing OCC. */
static void static void
remove_all_occurrences (et_forest_t forest, et_forest_node_t forest_node) record_path_before (struct et_occ *occ)
{ {
et_forest_occurrence_t first = forest_node->first; while (occ->parent)
et_forest_occurrence_t last = forest_node->last; occ = occ->parent;
et_forest_occurrence_t node;
len = 0;
record_path_before_1 (occ, 0);
fprintf (stderr, "\n");
}
splay (first); /* Checks whether the path represented by OCC, with depth incremented by DEPTH,
was not changed since the last recording. */
if (first->left) static int
first->left->parent = 0; check_path_after_1 (struct et_occ *occ, int depth)
if (first->right) {
first->right->parent = 0; int mn, m;
if (last != first) depth += occ->depth;
{ mn = depth;
splay (last);
if (last->left) if (occ->next)
last->left->parent = 0; {
if (last->right) m = check_path_after_1 (occ->next, depth);
last->right->parent = 0; if (m < mn)
mn = m;
} }
if (last->right && first->left) /* actually, first->left would suffice. */ len--;
if (depths[len] != depth
|| datas[len] != occ->of)
abort ();
if (occ->prev)
{ {
/* Need to join them. */ m = check_path_after_1 (occ->prev, depth);
et_forest_occurrence_t prev_node, next_node; if (m < mn)
mn = m;
prev_node = splay (find_rightmost_node (first->left)); }
next_node = splay (find_leftmost_node (last->right));
/* prev_node and next_node are consecutive occurrences if (mn != occ->min + depth - occ->depth)
of the same node. */ abort ();
if (prev_node->next != next_node)
return mn;
}
/* Checks whether the path represented by a tree containing OCC was
not changed since the last recording. */
static void
check_path_after (struct et_occ *occ)
{
while (occ->parent)
occ = occ->parent;
check_path_after_1 (occ, 0);
if (len != 0)
abort (); abort ();
}
prev_node->right = next_node->right; #endif
prev_node->count_right = next_node->count_right;
prev_node->next = next_node->next;
if (prev_node->right)
prev_node->right->parent = prev_node;
if (prev_node->node->last == next_node) /* Splay the occurence OCC to the root of the tree. */
prev_node->node->last = prev_node;
pool_free (forest->occur_pool, next_node); static inline void
} et_splay (struct et_occ *occ)
{
struct et_occ *f, *gf, *ggf;
int occ_depth, f_depth, gf_depth;
if (first != last) #ifdef DEBUG_ET
{ record_path_before (occ);
node = first->next; et_check_tree_sanity (occ);
#endif
while (node != last) while (occ->parent)
{ {
et_forest_occurrence_t next_node; occ_depth = occ->depth;
f = occ->parent;
f_depth = f->depth;
splay (node); gf = f->parent;
if (node->left) if (!gf)
node->left->parent = 0; {
if (node->right) set_depth_add (occ, f_depth);
node->right->parent = 0; occ->min_occ = f->min_occ;
occ->min = f->min;
next_node = node->next; if (f->prev == occ)
pool_free (forest->occur_pool, node); {
node = next_node; /* zig */
set_prev (f, occ->next);
set_next (occ, f);
set_depth_add (f->prev, occ_depth);
}
else
{
/* zag */
set_next (f, occ->prev);
set_prev (occ, f);
set_depth_add (f->next, occ_depth);
} }
set_depth (f, -occ_depth);
occ->parent = NULL;
et_recomp_min (f);
#ifdef DEBUG_ET
et_check_tree_sanity (occ);
check_path_after (occ);
#endif
return;
} }
pool_free (forest->occur_pool, first); gf_depth = gf->depth;
if (first != last)
pool_free (forest->occur_pool, last);
}
/* Calculate ET value of the given node. */ set_depth_add (occ, f_depth + gf_depth);
static inline int occ->min_occ = gf->min_occ;
calculate_value (et_forest_occurrence_t node) occ->min = gf->min;
{
int value = node->count_left;
while (node->parent) ggf = gf->parent;
{
if (node == node->parent->right)
value += node->parent->count_left + 1;
node = node->parent; if (gf->prev == f)
{
if (f->prev == occ)
{
/* zig zig */
set_prev (gf, f->next);
set_prev (f, occ->next);
set_next (occ, f);
set_next (f, gf);
set_depth (f, -occ_depth);
set_depth_add (f->prev, occ_depth);
set_depth (gf, -f_depth);
set_depth_add (gf->prev, f_depth);
}
else
{
/* zag zig */
set_prev (gf, occ->next);
set_next (f, occ->prev);
set_prev (occ, f);
set_next (occ, gf);
set_depth (f, -occ_depth);
set_depth_add (f->next, occ_depth);
set_depth (gf, -occ_depth - f_depth);
set_depth_add (gf->prev, occ_depth + f_depth);
}
}
else
{
if (f->prev == occ)
{
/* zig zag */
set_next (gf, occ->prev);
set_prev (f, occ->next);
set_prev (occ, gf);
set_next (occ, f);
set_depth (f, -occ_depth);
set_depth_add (f->prev, occ_depth);
set_depth (gf, -occ_depth - f_depth);
set_depth_add (gf->next, occ_depth + f_depth);
}
else
{
/* zag zag */
set_next (gf, f->prev);
set_next (f, occ->prev);
set_prev (occ, f);
set_prev (f, gf);
set_depth (f, -occ_depth);
set_depth_add (f->next, occ_depth);
set_depth (gf, -f_depth);
set_depth_add (gf->next, f_depth);
}
} }
return value; occ->parent = ggf;
} if (ggf)
{
if (ggf->prev == gf)
ggf->prev = occ;
else
ggf->next = occ;
}
et_recomp_min (gf);
et_recomp_min (f);
#ifdef DEBUG_ET
et_check_tree_sanity (occ);
#endif
}
#ifdef DEBUG_ET
et_check_sanity (occ);
check_path_after (occ);
#endif
}
/* Create a new et tree occurence of NODE. */
/* Create ET-forest structure. */ static struct et_occ *
et_forest_t et_new_occ (struct et_node *node)
et_forest_create (void)
{ {
et_forest_t forest = xmalloc (sizeof (struct et_forest)); struct et_occ *nw;
forest->nnodes = 0; if (!et_occurences)
forest->occur_pool = create_alloc_pool ("et_forest_occurrence pool", sizeof (struct et_forest_occurrence), 300); et_occurences = create_alloc_pool ("et_occ pool", sizeof (struct et_occ), 300);
forest->node_pool = create_alloc_pool ("et_forest_node pool", sizeof (struct et_forest_node), 300); nw = pool_alloc (et_occurences);
return forest;
}
nw->of = node;
nw->parent = NULL;
nw->prev = NULL;
nw->next = NULL;
nw->depth = 0;
nw->min_occ = nw;
nw->min = 0;
/* Deallocate the structure. */ return nw;
void
et_forest_delete (et_forest_t forest)
{
if (forest->nnodes)
abort ();
free_alloc_pool (forest->occur_pool);
free_alloc_pool (forest->node_pool);
free (forest);
} }
/* Create new node with VALUE and return the edge. /* Create a new et tree containing DATA. */
Return NULL when memory allocation failed. */
et_forest_node_t
et_forest_add_node (et_forest_t forest, void *value)
{
/* Create node with one occurrence. */
et_forest_node_t node;
et_forest_occurrence_t occ;
node = pool_alloc (forest->node_pool);
occ = pool_alloc (forest->occur_pool);
node->first = node->last = occ;
node->value = value;
forest->nnodes++;
occ->node = node;
occ->left = occ->right = occ->parent = 0;
occ->next = 0;
occ->count_left = occ->count_right = 0;
return node;
}
/* Add new edge to the tree, return 1 if successful. struct et_node *
0 indicates that creation of the edge will close the cycle in graph. */ et_new_tree (void *data)
int
et_forest_add_edge (et_forest_t forest ATTRIBUTE_UNUSED,
et_forest_node_t parent_node, et_forest_node_t child_node)
{ {
et_forest_occurrence_t new_occ, parent_occ, child_occ; struct et_node *nw;
if (! parent_node || ! child_node) if (!et_nodes)
abort (); et_nodes = create_alloc_pool ("et_node pool", sizeof (struct et_node), 300);
nw = pool_alloc (et_nodes);
nw->data = data;
nw->father = NULL;
nw->left = NULL;
nw->right = NULL;
nw->son = NULL;
nw->rightmost_occ = et_new_occ (nw);
nw->parent_occ = NULL;
parent_occ = parent_node->first; return nw;
child_occ = child_node->first;
splay (parent_occ);
splay (child_occ);
if (parent_occ->parent)
return 0; /* Both child and parent are in the same tree. */
if (child_occ->left)
abort (); /* child must be root of its containing tree. */
new_occ = pool_alloc (forest->occur_pool);
new_occ->node = parent_node;
new_occ->left = child_occ;
new_occ->count_left = child_occ->count_right + 1; /* count_left is 0. */
new_occ->right = parent_occ->right;
new_occ->count_right = parent_occ->count_right;
new_occ->parent = parent_occ;
new_occ->next = parent_occ->next;
child_occ->parent = new_occ;
parent_occ->right = new_occ;
parent_occ->count_right = new_occ->count_left + new_occ->count_right + 1;
parent_occ->next = new_occ;
if (new_occ->right)
new_occ->right->parent = new_occ;
if (parent_node->last == parent_occ)
parent_node->last = new_occ;
return 1;
} }
/* Remove NODE from the tree and all connected edges. */ /* Releases et tree T. */
void void
et_forest_remove_node (et_forest_t forest, et_forest_node_t node) et_free_tree (struct et_node *t)
{ {
remove_all_occurrences (forest, node); while (t->son)
forest->nnodes--; et_split (t->son);
if (t->father)
et_split (t);
pool_free (forest->node_pool, node); pool_free (et_occurences, t->rightmost_occ);
pool_free (et_nodes, t);
} }
/* Remove edge from the tree, return 1 if successful, /* Sets father of et tree T to FATHER. */
0 indicates nonexisting edge. */
int void
et_forest_remove_edge (et_forest_t forest ATTRIBUTE_UNUSED, et_set_father (struct et_node *t, struct et_node *father)
et_forest_node_t parent_node,
et_forest_node_t child_node)
{ {
et_forest_occurrence_t parent_pre_occ, parent_post_occ; struct et_node *left, *right;
struct et_occ *rmost, *left_part, *new_f_occ, *p;
splay (child_node->first); /* Update the path represented in the splay tree. */
new_f_occ = et_new_occ (father);
if (! child_node->first->left) rmost = father->rightmost_occ;
return 0; et_splay (rmost);
parent_pre_occ = find_rightmost_node (child_node->first->left); left_part = rmost->prev;
if (parent_pre_occ->node != parent_node)
abort ();
splay (parent_pre_occ); p = t->rightmost_occ;
parent_pre_occ->right->parent = 0; et_splay (p);
parent_post_occ = parent_pre_occ->next; set_prev (new_f_occ, left_part);
splay (parent_post_occ); set_next (new_f_occ, p);
parent_post_occ->left->parent = 0; p->depth++;
p->min++;
et_recomp_min (new_f_occ);
parent_pre_occ->right = parent_post_occ->right; set_prev (rmost, new_f_occ);
parent_pre_occ->count_right = parent_post_occ->count_right;
if (parent_post_occ->right)
parent_post_occ->right->parent = parent_pre_occ;
parent_pre_occ->next = parent_post_occ->next; if (new_f_occ->min + rmost->depth < rmost->min)
{
rmost->min = new_f_occ->min + rmost->depth;
rmost->min_occ = new_f_occ->min_occ;
}
if (parent_post_occ == parent_node->last) t->parent_occ = new_f_occ;
parent_node->last = parent_pre_occ;
pool_free (forest->occur_pool, parent_post_occ); /* Update the tree. */
return 1; t->father = father;
} right = father->son;
if (right)
left = right->left;
else
left = right = t;
/* Return the parent of the NODE if any, NULL otherwise. */ left->right = t;
et_forest_node_t right->left = t;
et_forest_parent (et_forest_t forest ATTRIBUTE_UNUSED, et_forest_node_t node) t->left = left;
{ t->right = right;
splay (node->first);
if (node->first->left) father->son = t;
return find_rightmost_node (node->first->left)->node;
else #ifdef DEBUG_ET
return 0; et_check_tree_sanity (rmost);
record_path_before (rmost);
#endif
} }
/* Splits the edge from T to its father. */
/* Return nearest common ancestor of NODE1 and NODE2. void
Return NULL of they are in different trees. */ et_split (struct et_node *t)
et_forest_node_t
et_forest_common_ancestor (et_forest_t forest ATTRIBUTE_UNUSED,
et_forest_node_t node1, et_forest_node_t node2)
{ {
int value1, value2, max_value; struct et_node *father = t->father;
et_forest_node_t ancestor; struct et_occ *r, *l, *rmost, *p_occ;
if (node1 == node2) /* Update the path represented by the splay tree. */
return node1; rmost = t->rightmost_occ;
et_splay (rmost);
if (! node1 || ! node2) for (r = rmost->next; r->prev; r = r->prev)
abort (); continue;
et_splay (r);
r->prev->parent = NULL;
p_occ = t->parent_occ;
et_splay (p_occ);
t->parent_occ = NULL;
l = p_occ->prev;
p_occ->next->parent = NULL;
splay (node1->first); set_prev (r, l);
splay (node2->first);
if (! node1->first->parent) /* The two vertices are in different trees. */ et_recomp_min (r);
return 0;
value2 = calculate_value (node2->first); et_splay (rmost);
value1 = calculate_value (node1->first); rmost->depth = 0;
rmost->min = 0;
if (value1 < value2) pool_free (et_occurences, p_occ);
/* Update the tree. */
if (father->son == t)
father->son = t->right;
if (father->son == t)
father->son = NULL;
else
{ {
ancestor = node1; t->left->right = t->right;
max_value = value2; t->right->left = t->left;
}
t->left = t->right = NULL;
t->father = NULL;
#ifdef DEBUG_ET
et_check_tree_sanity (rmost);
record_path_before (rmost);
et_check_tree_sanity (r);
record_path_before (r);
#endif
}
/* Finds the nearest common ancestor of the nodes N1 and N2. */
struct et_node *
et_nca (struct et_node *n1, struct et_node *n2)
{
struct et_occ *o1 = n1->rightmost_occ, *o2 = n2->rightmost_occ, *om;
struct et_occ *l, *r, *ret;
int mn;
if (n1 == n2)
return n1;
et_splay (o1);
l = o1->prev;
r = o1->next;
if (l)
l->parent = NULL;
if (r)
r->parent = NULL;
et_splay (o2);
if (l == o2 || (l && l->parent != NULL))
{
ret = o2->next;
set_prev (o1, o2);
if (r)
r->parent = o1;
} }
else else
{ {
ancestor = node2; ret = o2->prev;
max_value = value1;
set_next (o1, o2);
if (l)
l->parent = o1;
} }
while (calculate_value (ancestor->last) < max_value) if (0 < o2->depth)
{
om = o1;
mn = o1->depth;
}
else
{ {
/* Find parent node. */ om = o2;
splay (ancestor->first); mn = o2->depth + o1->depth;
ancestor = find_rightmost_node (ancestor->first->left) ->node;
} }
return ancestor; #ifdef DEBUG_ET
} et_check_tree_sanity (o2);
#endif
/* Return the value pointer of node set during it's creation. */ if (ret && ret->min + o1->depth + o2->depth < mn)
void * return ret->min_occ->of;
et_forest_node_value (et_forest_t forest ATTRIBUTE_UNUSED, else
et_forest_node_t node) return om->of;
{
/* Alloc threading NULL as a special node of the forest. */
if (!node)
return NULL;
return node->value;
} }
/* Find all sons of NODE and store them into ARRAY allocated by the caller. /* Checks whether the node UP is an ancestor of the node DOWN. */
Return number of nodes found. */
int bool
et_forest_enumerate_sons (et_forest_t forest ATTRIBUTE_UNUSED, et_below (struct et_node *down, struct et_node *up)
et_forest_node_t node, et_forest_node_t *array)
{ {
int n = 0; struct et_occ *u = up->rightmost_occ, *d = down->rightmost_occ;
et_forest_occurrence_t occ = node->first, stop = node->last, occ1; struct et_occ *l, *r;
/* Parent is the rightmost node of the left successor. if (up == down)
Look for all occurrences having no right successor return true;
and lookup the sons. */
while (occ != stop) et_splay (u);
{ l = u->prev;
splay (occ); r = u->next;
if (occ->right)
if (!l)
return false;
l->parent = NULL;
if (r)
r->parent = NULL;
et_splay (d);
if (l == d || l->parent != NULL)
{ {
occ1 = find_leftmost_node (occ->right); if (r)
if (occ1->node->first == occ1) r->parent = u;
array[n++] = occ1->node; set_prev (u, d);
#ifdef DEBUG_ET
et_check_tree_sanity (u);
#endif
} }
occ = occ->next; else
{
l->parent = u;
/* In case O1 and O2 are in two different trees, we must just restore the
original state. */
if (r && r->parent != NULL)
set_next (u, d);
else
set_next (u, r);
#ifdef DEBUG_ET
et_check_tree_sanity (u);
#endif
return false;
} }
return n;
if (0 >= d->depth)
return false;
return !d->next || d->next->min + d->depth >= 0;
} }
...@@ -55,26 +55,28 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ ...@@ -55,26 +55,28 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */
extern "C" { extern "C" {
#endif /* __cplusplus */ #endif /* __cplusplus */
typedef struct et_forest *et_forest_t; /* The node representing the node in an et tree. */
typedef struct et_forest_node *et_forest_node_t; struct et_node
{
extern et_forest_t et_forest_create (void); void *data; /* The data represented by the node. */
extern void et_forest_delete (et_forest_t); int dfs_num_in, dfs_num_out; /* Number of the node in the dfs ordering. */
extern et_forest_node_t et_forest_add_node (et_forest_t, void *); struct et_node *father; /* Father of the node. */
extern int et_forest_add_edge (et_forest_t, et_forest_node_t, struct et_node *son; /* The first of the sons of the node. */
et_forest_node_t); struct et_node *left;
extern void et_forest_remove_node (et_forest_t, et_forest_node_t); struct et_node *right; /* The brothers of the node. */
extern int et_forest_remove_edge (et_forest_t, et_forest_node_t,
et_forest_node_t); struct et_occ *rightmost_occ; /* The rightmost occurence. */
extern et_forest_node_t et_forest_parent (et_forest_t, et_forest_node_t); struct et_occ *parent_occ; /* The occurence of the parent node. */
extern et_forest_node_t et_forest_common_ancestor (et_forest_t, };
et_forest_node_t,
et_forest_node_t); struct et_node *et_new_tree (void *data);
extern void * et_forest_node_value (et_forest_t, et_forest_node_t); void et_free_tree (struct et_node *);
extern int et_forest_enumerate_sons (et_forest_t, et_forest_node_t, void et_set_father (struct et_node *, struct et_node *);
et_forest_node_t *); void et_split (struct et_node *);
struct et_node *et_nca (struct et_node *, struct et_node *);
bool et_below (struct et_node *, struct et_node *);
#ifdef __cplusplus #ifdef __cplusplus
} }
......
...@@ -6408,8 +6408,6 @@ allocate_struct_function (tree fndecl) ...@@ -6408,8 +6408,6 @@ allocate_struct_function (tree fndecl)
DECL_SAVED_INSNS (fndecl) = cfun; DECL_SAVED_INSNS (fndecl) = cfun;
cfun->decl = fndecl; cfun->decl = fndecl;
current_function_name = (*lang_hooks.decl_printable_name) (fndecl, 2);
result = DECL_RESULT (fndecl); result = DECL_RESULT (fndecl);
if (aggregate_value_p (result, fndecl)) if (aggregate_value_p (result, fndecl))
{ {
......
...@@ -183,9 +183,6 @@ struct function GTY(()) ...@@ -183,9 +183,6 @@ struct function GTY(())
/* For function.c. */ /* For function.c. */
/* Name of this function. */
const char *name;
/* Points to the FUNCTION_DECL of this function. */ /* Points to the FUNCTION_DECL of this function. */
tree decl; tree decl;
...@@ -534,7 +531,6 @@ extern int virtuals_instantiated; ...@@ -534,7 +531,6 @@ extern int virtuals_instantiated;
extern int trampolines_created; extern int trampolines_created;
/* For backward compatibility... eventually these should all go away. */ /* For backward compatibility... eventually these should all go away. */
#define current_function_name (cfun->name)
#define current_function_pops_args (cfun->pops_args) #define current_function_pops_args (cfun->pops_args)
#define current_function_returns_struct (cfun->returns_struct) #define current_function_returns_struct (cfun->returns_struct)
#define current_function_returns_pcc_struct (cfun->returns_pcc_struct) #define current_function_returns_pcc_struct (cfun->returns_pcc_struct)
......
...@@ -161,6 +161,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA ...@@ -161,6 +161,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "basic-block.h" #include "basic-block.h"
#include "output.h" #include "output.h"
#include "function.h" #include "function.h"
#include "langhooks.h"
#include "expr.h" #include "expr.h"
#include "except.h" #include "except.h"
#include "ggc.h" #include "ggc.h"
...@@ -855,7 +856,8 @@ gcse_main (rtx f, FILE *file) ...@@ -855,7 +856,8 @@ gcse_main (rtx f, FILE *file)
if (file) if (file)
{ {
fprintf (file, "GCSE of %s: %d basic blocks, ", fprintf (file, "GCSE of %s: %d basic blocks, ",
current_function_name, n_basic_blocks); (*lang_hooks.decl_printable_name) (current_function_decl, 2),
n_basic_blocks);
fprintf (file, "%d pass%s, %d bytes\n\n", fprintf (file, "%d pass%s, %d bytes\n\n",
pass, pass > 1 ? "es" : "", max_pass_bytes); pass, pass > 1 ? "es" : "", max_pass_bytes);
} }
...@@ -3614,7 +3616,8 @@ one_classic_gcse_pass (int pass) ...@@ -3614,7 +3616,8 @@ one_classic_gcse_pass (int pass)
{ {
fprintf (gcse_file, "\n"); fprintf (gcse_file, "\n");
fprintf (gcse_file, "GCSE of %s, pass %d: %d bytes needed, %d substs,", fprintf (gcse_file, "GCSE of %s, pass %d: %d bytes needed, %d substs,",
current_function_name, pass, bytes_used, gcse_subst_count); (*lang_hooks.decl_printable_name) (current_function_decl, 2),
pass, bytes_used, gcse_subst_count);
fprintf (gcse_file, "%d insns created\n", gcse_create_count); fprintf (gcse_file, "%d insns created\n", gcse_create_count);
} }
...@@ -4686,7 +4689,8 @@ one_cprop_pass (int pass, int cprop_jumps, int bypass_jumps) ...@@ -4686,7 +4689,8 @@ one_cprop_pass (int pass, int cprop_jumps, int bypass_jumps)
if (gcse_file) if (gcse_file)
{ {
fprintf (gcse_file, "CPROP of %s, pass %d: %d bytes needed, ", fprintf (gcse_file, "CPROP of %s, pass %d: %d bytes needed, ",
current_function_name, pass, bytes_used); (*lang_hooks.decl_printable_name) (current_function_decl, 2),
pass, bytes_used);
fprintf (gcse_file, "%d const props, %d copy props\n\n", fprintf (gcse_file, "%d const props, %d copy props\n\n",
const_prop_count, copy_prop_count); const_prop_count, copy_prop_count);
} }
...@@ -5788,7 +5792,8 @@ one_pre_gcse_pass (int pass) ...@@ -5788,7 +5792,8 @@ one_pre_gcse_pass (int pass)
if (gcse_file) if (gcse_file)
{ {
fprintf (gcse_file, "\nPRE GCSE of %s, pass %d: %d bytes needed, ", fprintf (gcse_file, "\nPRE GCSE of %s, pass %d: %d bytes needed, ",
current_function_name, pass, bytes_used); (*lang_hooks.decl_printable_name) (current_function_decl, 2),
pass, bytes_used);
fprintf (gcse_file, "%d substs, %d insns created\n", fprintf (gcse_file, "%d substs, %d insns created\n",
gcse_subst_count, gcse_create_count); gcse_subst_count, gcse_create_count);
} }
...@@ -6182,9 +6187,6 @@ static sbitmap *hoist_vbeout; ...@@ -6182,9 +6187,6 @@ static sbitmap *hoist_vbeout;
/* Hoistable expressions. */ /* Hoistable expressions. */
static sbitmap *hoist_exprs; static sbitmap *hoist_exprs;
/* Dominator bitmaps. */
dominance_info dominators;
/* ??? We could compute post dominators and run this algorithm in /* ??? We could compute post dominators and run this algorithm in
reverse to perform tail merging, doing so would probably be reverse to perform tail merging, doing so would probably be
more effective than the tail merging code in jump.c. more effective than the tail merging code in jump.c.
...@@ -6221,7 +6223,7 @@ free_code_hoist_mem (void) ...@@ -6221,7 +6223,7 @@ free_code_hoist_mem (void)
sbitmap_vector_free (hoist_exprs); sbitmap_vector_free (hoist_exprs);
sbitmap_vector_free (transpout); sbitmap_vector_free (transpout);
free_dominance_info (dominators); free_dominance_info (CDI_DOMINATORS);
} }
/* Compute the very busy expressions at entry/exit from each block. /* Compute the very busy expressions at entry/exit from each block.
...@@ -6270,7 +6272,7 @@ compute_code_hoist_data (void) ...@@ -6270,7 +6272,7 @@ compute_code_hoist_data (void)
compute_local_properties (transp, comp, antloc, &expr_hash_table); compute_local_properties (transp, comp, antloc, &expr_hash_table);
compute_transpout (); compute_transpout ();
compute_code_hoist_vbeinout (); compute_code_hoist_vbeinout ();
dominators = calculate_dominance_info (CDI_DOMINATORS); calculate_dominance_info (CDI_DOMINATORS);
if (gcse_file) if (gcse_file)
fprintf (gcse_file, "\n"); fprintf (gcse_file, "\n");
} }
...@@ -6362,7 +6364,7 @@ hoist_code (void) ...@@ -6362,7 +6364,7 @@ hoist_code (void)
int found = 0; int found = 0;
int insn_inserted_p; int insn_inserted_p;
domby_len = get_dominated_by (dominators, bb, &domby); domby_len = get_dominated_by (CDI_DOMINATORS, bb, &domby);
/* Examine each expression that is very busy at the exit of this /* Examine each expression that is very busy at the exit of this
block. These are the potentially hoistable expressions. */ block. These are the potentially hoistable expressions. */
for (i = 0; i < hoist_vbeout[bb->index]->n_bits; i++) for (i = 0; i < hoist_vbeout[bb->index]->n_bits; i++)
...@@ -8020,7 +8022,8 @@ bypass_jumps (FILE *file) ...@@ -8020,7 +8022,8 @@ bypass_jumps (FILE *file)
if (file) if (file)
{ {
fprintf (file, "BYPASS of %s: %d basic blocks, ", fprintf (file, "BYPASS of %s: %d basic blocks, ",
current_function_name, n_basic_blocks); (*lang_hooks.decl_printable_name) (current_function_decl, 2),
n_basic_blocks);
fprintf (file, "%d bytes\n\n", bytes_used); fprintf (file, "%d bytes\n\n", bytes_used);
} }
......
...@@ -25,9 +25,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA ...@@ -25,9 +25,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
#include "tm.h" #include "tm.h"
#include "rtl.h" #include "rtl.h"
#include "tree.h"
#include "flags.h" #include "flags.h"
#include "output.h" #include "output.h"
#include "function.h" #include "function.h"
#include "langhooks.h"
#include "hard-reg-set.h" #include "hard-reg-set.h"
#include "basic-block.h" #include "basic-block.h"
#include "toplev.h" #include "toplev.h"
...@@ -55,7 +57,8 @@ start_fct (FILE *fp) ...@@ -55,7 +57,8 @@ start_fct (FILE *fp)
case vcg: case vcg:
fprintf (fp, "\ fprintf (fp, "\
graph: { title: \"%s\"\nfolding: 1\nhidden: 2\nnode: { title: \"%s.0\" }\n", graph: { title: \"%s\"\nfolding: 1\nhidden: 2\nnode: { title: \"%s.0\" }\n",
current_function_name, current_function_name); (*lang_hooks.decl_printable_name) (current_function_decl, 2),
(*lang_hooks.decl_printable_name) (current_function_decl, 2));
break; break;
case no_graph: case no_graph:
break; break;
...@@ -71,7 +74,8 @@ start_bb (FILE *fp, int bb) ...@@ -71,7 +74,8 @@ start_bb (FILE *fp, int bb)
fprintf (fp, "\ fprintf (fp, "\
graph: {\ntitle: \"%s.BB%d\"\nfolding: 1\ncolor: lightblue\n\ graph: {\ntitle: \"%s.BB%d\"\nfolding: 1\ncolor: lightblue\n\
label: \"basic block %d", label: \"basic block %d",
current_function_name, bb, bb); (*lang_hooks.decl_printable_name) (current_function_decl, 2),
bb, bb);
break; break;
case no_graph: case no_graph:
break; break;
...@@ -113,8 +117,9 @@ node_data (FILE *fp, rtx tmp_rtx) ...@@ -113,8 +117,9 @@ node_data (FILE *fp, rtx tmp_rtx)
case vcg: case vcg:
fprintf (fp, "\ fprintf (fp, "\
edge: { sourcename: \"%s.0\" targetname: \"%s.%d\" }\n", edge: { sourcename: \"%s.0\" targetname: \"%s.%d\" }\n",
current_function_name, (*lang_hooks.decl_printable_name) (current_function_decl, 2),
current_function_name, XINT (tmp_rtx, 0)); (*lang_hooks.decl_printable_name) (current_function_decl, 2),
XINT (tmp_rtx, 0));
break; break;
case no_graph: case no_graph:
break; break;
...@@ -126,7 +131,8 @@ edge: { sourcename: \"%s.0\" targetname: \"%s.%d\" }\n", ...@@ -126,7 +131,8 @@ edge: { sourcename: \"%s.0\" targetname: \"%s.%d\" }\n",
case vcg: case vcg:
fprintf (fp, "node: {\n title: \"%s.%d\"\n color: %s\n \ fprintf (fp, "node: {\n title: \"%s.%d\"\n color: %s\n \
label: \"%s %d\n", label: \"%s %d\n",
current_function_name, XINT (tmp_rtx, 0), (*lang_hooks.decl_printable_name) (current_function_decl, 2),
XINT (tmp_rtx, 0),
GET_CODE (tmp_rtx) == NOTE ? "lightgrey" GET_CODE (tmp_rtx) == NOTE ? "lightgrey"
: GET_CODE (tmp_rtx) == INSN ? "green" : GET_CODE (tmp_rtx) == INSN ? "green"
: GET_CODE (tmp_rtx) == JUMP_INSN ? "darkgreen" : GET_CODE (tmp_rtx) == JUMP_INSN ? "darkgreen"
...@@ -178,8 +184,11 @@ draw_edge (FILE *fp, int from, int to, int bb_edge, int class) ...@@ -178,8 +184,11 @@ draw_edge (FILE *fp, int from, int to, int bb_edge, int class)
color = "color: green "; color = "color: green ";
fprintf (fp, fprintf (fp,
"edge: { sourcename: \"%s.%d\" targetname: \"%s.%d\" %s", "edge: { sourcename: \"%s.%d\" targetname: \"%s.%d\" %s",
current_function_name, from, (*lang_hooks.decl_printable_name) (current_function_decl, 2),
current_function_name, to, color); from,
(*lang_hooks.decl_printable_name) (current_function_decl, 2),
to,
color);
if (class) if (class)
fprintf (fp, "class: %d ", class); fprintf (fp, "class: %d ", class);
fputs ("}\n", fp); fputs ("}\n", fp);
...@@ -209,7 +218,7 @@ end_fct (FILE *fp) ...@@ -209,7 +218,7 @@ end_fct (FILE *fp)
{ {
case vcg: case vcg:
fprintf (fp, "node: { title: \"%s.999999\" label: \"END\" }\n}\n", fprintf (fp, "node: { title: \"%s.999999\" label: \"END\" }\n}\n",
current_function_name); (*lang_hooks.decl_printable_name) (current_function_decl, 2));
break; break;
case no_graph: case no_graph:
break; break;
......
...@@ -84,9 +84,6 @@ static int cond_exec_changed_p; ...@@ -84,9 +84,6 @@ static int cond_exec_changed_p;
/* True if life data ok at present. */ /* True if life data ok at present. */
static bool life_data_ok; static bool life_data_ok;
/* The post-dominator relation on the original block numbers. */
static dominance_info post_dominators;
/* Forward references. */ /* Forward references. */
static int count_bb_insns (basic_block); static int count_bb_insns (basic_block);
static rtx first_active_insn (basic_block); static rtx first_active_insn (basic_block);
...@@ -123,6 +120,7 @@ mark_loop_exit_edges (void) ...@@ -123,6 +120,7 @@ mark_loop_exit_edges (void)
edge e; edge e;
flow_loops_find (&loops, LOOP_TREE); flow_loops_find (&loops, LOOP_TREE);
free_dominance_info (CDI_DOMINATORS);
if (loops.num > 1) if (loops.num > 1)
{ {
...@@ -2105,8 +2103,8 @@ merge_if_block (struct ce_if_block * ce_info) ...@@ -2105,8 +2103,8 @@ merge_if_block (struct ce_if_block * ce_info)
{ {
bb = fallthru; bb = fallthru;
fallthru = block_fallthru (bb); fallthru = block_fallthru (bb);
if (post_dominators) if (dom_computed[CDI_POST_DOMINATORS] >= DOM_NO_FAST_QUERY)
delete_from_dominance_info (post_dominators, bb); delete_from_dominance_info (CDI_POST_DOMINATORS, bb);
merge_blocks (combo_bb, bb); merge_blocks (combo_bb, bb);
num_true_changes++; num_true_changes++;
} }
...@@ -2122,8 +2120,8 @@ merge_if_block (struct ce_if_block * ce_info) ...@@ -2122,8 +2120,8 @@ merge_if_block (struct ce_if_block * ce_info)
if (combo_bb->global_live_at_end) if (combo_bb->global_live_at_end)
COPY_REG_SET (combo_bb->global_live_at_end, COPY_REG_SET (combo_bb->global_live_at_end,
then_bb->global_live_at_end); then_bb->global_live_at_end);
if (post_dominators) if (dom_computed[CDI_POST_DOMINATORS] >= DOM_NO_FAST_QUERY)
delete_from_dominance_info (post_dominators, then_bb); delete_from_dominance_info (CDI_POST_DOMINATORS, then_bb);
merge_blocks (combo_bb, then_bb); merge_blocks (combo_bb, then_bb);
num_true_changes++; num_true_changes++;
} }
...@@ -2133,8 +2131,8 @@ merge_if_block (struct ce_if_block * ce_info) ...@@ -2133,8 +2131,8 @@ merge_if_block (struct ce_if_block * ce_info)
get their addresses taken. */ get their addresses taken. */
if (else_bb) if (else_bb)
{ {
if (post_dominators) if (dom_computed[CDI_POST_DOMINATORS] >= DOM_NO_FAST_QUERY)
delete_from_dominance_info (post_dominators, else_bb); delete_from_dominance_info (CDI_POST_DOMINATORS, else_bb);
merge_blocks (combo_bb, else_bb); merge_blocks (combo_bb, else_bb);
num_true_changes++; num_true_changes++;
} }
...@@ -2190,8 +2188,8 @@ merge_if_block (struct ce_if_block * ce_info) ...@@ -2190,8 +2188,8 @@ merge_if_block (struct ce_if_block * ce_info)
COPY_REG_SET (combo_bb->global_live_at_end, COPY_REG_SET (combo_bb->global_live_at_end,
join_bb->global_live_at_end); join_bb->global_live_at_end);
if (post_dominators) if (dom_computed[CDI_POST_DOMINATORS] >= DOM_NO_FAST_QUERY)
delete_from_dominance_info (post_dominators, join_bb); delete_from_dominance_info (CDI_POST_DOMINATORS, join_bb);
merge_blocks (combo_bb, join_bb); merge_blocks (combo_bb, join_bb);
num_true_changes++; num_true_changes++;
} }
...@@ -2271,7 +2269,7 @@ find_if_header (basic_block test_bb, int pass) ...@@ -2271,7 +2269,7 @@ find_if_header (basic_block test_bb, int pass)
&& find_cond_trap (test_bb, then_edge, else_edge)) && find_cond_trap (test_bb, then_edge, else_edge))
goto success; goto success;
if (post_dominators if (dom_computed[CDI_POST_DOMINATORS] >= DOM_NO_FAST_QUERY
&& (! HAVE_conditional_execution || reload_completed)) && (! HAVE_conditional_execution || reload_completed))
{ {
if (find_if_case_1 (test_bb, then_edge, else_edge)) if (find_if_case_1 (test_bb, then_edge, else_edge))
...@@ -2646,8 +2644,8 @@ find_cond_trap (basic_block test_bb, edge then_edge, edge else_edge) ...@@ -2646,8 +2644,8 @@ find_cond_trap (basic_block test_bb, edge then_edge, edge else_edge)
remove_edge (trap_bb == then_bb ? then_edge : else_edge); remove_edge (trap_bb == then_bb ? then_edge : else_edge);
if (trap_bb->pred == NULL) if (trap_bb->pred == NULL)
{ {
if (post_dominators) if (dom_computed[CDI_POST_DOMINATORS] >= DOM_NO_FAST_QUERY)
delete_from_dominance_info (post_dominators, trap_bb); delete_from_dominance_info (CDI_POST_DOMINATORS, trap_bb);
delete_block (trap_bb); delete_block (trap_bb);
} }
...@@ -2831,8 +2829,8 @@ find_if_case_1 (basic_block test_bb, edge then_edge, edge else_edge) ...@@ -2831,8 +2829,8 @@ find_if_case_1 (basic_block test_bb, edge then_edge, edge else_edge)
new_bb = redirect_edge_and_branch_force (FALLTHRU_EDGE (test_bb), else_bb); new_bb = redirect_edge_and_branch_force (FALLTHRU_EDGE (test_bb), else_bb);
then_bb_index = then_bb->index; then_bb_index = then_bb->index;
if (post_dominators) if (dom_computed[CDI_POST_DOMINATORS] >= DOM_NO_FAST_QUERY)
delete_from_dominance_info (post_dominators, then_bb); delete_from_dominance_info (CDI_POST_DOMINATORS, then_bb);
delete_block (then_bb); delete_block (then_bb);
/* Make rest of code believe that the newly created block is the THEN_BB /* Make rest of code believe that the newly created block is the THEN_BB
...@@ -2841,8 +2839,8 @@ find_if_case_1 (basic_block test_bb, edge then_edge, edge else_edge) ...@@ -2841,8 +2839,8 @@ find_if_case_1 (basic_block test_bb, edge then_edge, edge else_edge)
{ {
new_bb->index = then_bb_index; new_bb->index = then_bb_index;
BASIC_BLOCK (then_bb_index) = new_bb; BASIC_BLOCK (then_bb_index) = new_bb;
if (post_dominators) if (dom_computed[CDI_POST_DOMINATORS] >= DOM_NO_FAST_QUERY)
add_to_dominance_info (post_dominators, new_bb); add_to_dominance_info (CDI_POST_DOMINATORS, new_bb);
} }
/* We've possibly created jump to next insn, cleanup_cfg will solve that /* We've possibly created jump to next insn, cleanup_cfg will solve that
later. */ later. */
...@@ -2884,7 +2882,7 @@ find_if_case_2 (basic_block test_bb, edge then_edge, edge else_edge) ...@@ -2884,7 +2882,7 @@ find_if_case_2 (basic_block test_bb, edge then_edge, edge else_edge)
if (note && INTVAL (XEXP (note, 0)) >= REG_BR_PROB_BASE / 2) if (note && INTVAL (XEXP (note, 0)) >= REG_BR_PROB_BASE / 2)
; ;
else if (else_succ->dest->index < 0 else if (else_succ->dest->index < 0
|| dominated_by_p (post_dominators, then_bb, || dominated_by_p (CDI_POST_DOMINATORS, then_bb,
else_succ->dest)) else_succ->dest))
; ;
else else
...@@ -2911,8 +2909,8 @@ find_if_case_2 (basic_block test_bb, edge then_edge, edge else_edge) ...@@ -2911,8 +2909,8 @@ find_if_case_2 (basic_block test_bb, edge then_edge, edge else_edge)
then_bb->global_live_at_start, then_bb->global_live_at_start,
else_bb->global_live_at_end, BITMAP_IOR); else_bb->global_live_at_end, BITMAP_IOR);
if (post_dominators) if (dom_computed[CDI_POST_DOMINATORS] >= DOM_NO_FAST_QUERY)
delete_from_dominance_info (post_dominators, else_bb); delete_from_dominance_info (CDI_POST_DOMINATORS, else_bb);
delete_block (else_bb); delete_block (else_bb);
num_true_changes++; num_true_changes++;
...@@ -3217,11 +3215,9 @@ if_convert (int x_life_data_ok) ...@@ -3217,11 +3215,9 @@ if_convert (int x_life_data_ok)
free_basic_block_vars (1); free_basic_block_vars (1);
/* Compute postdominators if we think we'll use them. */ /* Compute postdominators if we think we'll use them. */
post_dominators = NULL;
if (HAVE_conditional_execution || life_data_ok) if (HAVE_conditional_execution || life_data_ok)
{ calculate_dominance_info (CDI_POST_DOMINATORS);
post_dominators = calculate_dominance_info (CDI_POST_DOMINATORS);
}
if (life_data_ok) if (life_data_ok)
clear_bb_flags (); clear_bb_flags ();
...@@ -3258,8 +3254,7 @@ if_convert (int x_life_data_ok) ...@@ -3258,8 +3254,7 @@ if_convert (int x_life_data_ok)
fprintf (rtl_dump_file, "\n\n========== no more changes\n"); fprintf (rtl_dump_file, "\n\n========== no more changes\n");
#endif #endif
if (post_dominators) free_dominance_info (CDI_POST_DOMINATORS);
free_dominance_info (post_dominators);
if (rtl_dump_file) if (rtl_dump_file)
fflush (rtl_dump_file); fflush (rtl_dump_file);
......
...@@ -53,7 +53,9 @@ loop_optimizer_init (FILE *dumpfile) ...@@ -53,7 +53,9 @@ loop_optimizer_init (FILE *dumpfile)
/* No loops. */ /* No loops. */
flow_loops_free (loops); flow_loops_free (loops);
free_dominance_info (CDI_DOMINATORS);
free (loops); free (loops);
/* Make chain. */ /* Make chain. */
FOR_EACH_BB (bb) FOR_EACH_BB (bb)
if (bb->next_bb != EXIT_BLOCK_PTR) if (bb->next_bb != EXIT_BLOCK_PTR)
...@@ -81,7 +83,7 @@ loop_optimizer_init (FILE *dumpfile) ...@@ -81,7 +83,7 @@ loop_optimizer_init (FILE *dumpfile)
flow_loops_dump (loops, dumpfile, NULL, 1); flow_loops_dump (loops, dumpfile, NULL, 1);
#ifdef ENABLE_CHECKING #ifdef ENABLE_CHECKING
verify_dominators (loops->cfg.dom); verify_dominators (CDI_DOMINATORS);
verify_loop_structure (loops); verify_loop_structure (loops);
#endif #endif
...@@ -105,6 +107,7 @@ loop_optimizer_finalize (struct loops *loops, FILE *dumpfile) ...@@ -105,6 +107,7 @@ loop_optimizer_finalize (struct loops *loops, FILE *dumpfile)
/* Clean up. */ /* Clean up. */
flow_loops_free (loops); flow_loops_free (loops);
free_dominance_info (CDI_DOMINATORS);
free (loops); free (loops);
/* Finalize changes. */ /* Finalize changes. */
......
...@@ -68,14 +68,12 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA ...@@ -68,14 +68,12 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
static void decide_unrolling_and_peeling (struct loops *, int); static void decide_unrolling_and_peeling (struct loops *, int);
static void peel_loops_completely (struct loops *, int); static void peel_loops_completely (struct loops *, int);
static void decide_peel_simple (struct loops *, struct loop *, int); static void decide_peel_simple (struct loop *, int);
static void decide_peel_once_rolling (struct loops *, struct loop *, int); static void decide_peel_once_rolling (struct loop *, int);
static void decide_peel_completely (struct loops *, struct loop *, int); static void decide_peel_completely (struct loop *, int);
static void decide_unroll_stupid (struct loops *, struct loop *, int); static void decide_unroll_stupid (struct loop *, int);
static void decide_unroll_constant_iterations (struct loops *, static void decide_unroll_constant_iterations (struct loop *, int);
struct loop *, int); static void decide_unroll_runtime_iterations (struct loop *, int);
static void decide_unroll_runtime_iterations (struct loops *, struct loop *,
int);
static void peel_loop_simple (struct loops *, struct loop *); static void peel_loop_simple (struct loops *, struct loop *);
static void peel_loop_completely (struct loops *, struct loop *); static void peel_loop_completely (struct loops *, struct loop *);
static void unroll_loop_stupid (struct loops *, struct loop *); static void unroll_loop_stupid (struct loops *, struct loop *);
...@@ -140,7 +138,7 @@ unroll_and_peel_loops (struct loops *loops, int flags) ...@@ -140,7 +138,7 @@ unroll_and_peel_loops (struct loops *loops, int flags)
if (check) if (check)
{ {
#ifdef ENABLE_CHECKING #ifdef ENABLE_CHECKING
verify_dominators (loops->cfg.dom); verify_dominators (CDI_DOMINATORS);
verify_loop_structure (loops); verify_loop_structure (loops);
#endif #endif
} }
...@@ -178,15 +176,15 @@ peel_loops_completely (struct loops *loops, int flags) ...@@ -178,15 +176,15 @@ peel_loops_completely (struct loops *loops, int flags)
loop->ninsns = num_loop_insns (loop); loop->ninsns = num_loop_insns (loop);
decide_peel_once_rolling (loops, loop, flags); decide_peel_once_rolling (loop, flags);
if (loop->lpt_decision.decision == LPT_NONE) if (loop->lpt_decision.decision == LPT_NONE)
decide_peel_completely (loops, loop, flags); decide_peel_completely (loop, flags);
if (loop->lpt_decision.decision == LPT_PEEL_COMPLETELY) if (loop->lpt_decision.decision == LPT_PEEL_COMPLETELY)
{ {
peel_loop_completely (loops, loop); peel_loop_completely (loops, loop);
#ifdef ENABLE_CHECKING #ifdef ENABLE_CHECKING
verify_dominators (loops->cfg.dom); verify_dominators (CDI_DOMINATORS);
verify_loop_structure (loops); verify_loop_structure (loops);
#endif #endif
} }
...@@ -254,13 +252,13 @@ decide_unrolling_and_peeling (struct loops *loops, int flags) ...@@ -254,13 +252,13 @@ decide_unrolling_and_peeling (struct loops *loops, int flags)
/* Try transformations one by one in decreasing order of /* Try transformations one by one in decreasing order of
priority. */ priority. */
decide_unroll_constant_iterations (loops, loop, flags); decide_unroll_constant_iterations (loop, flags);
if (loop->lpt_decision.decision == LPT_NONE) if (loop->lpt_decision.decision == LPT_NONE)
decide_unroll_runtime_iterations (loops, loop, flags); decide_unroll_runtime_iterations (loop, flags);
if (loop->lpt_decision.decision == LPT_NONE) if (loop->lpt_decision.decision == LPT_NONE)
decide_unroll_stupid (loops, loop, flags); decide_unroll_stupid (loop, flags);
if (loop->lpt_decision.decision == LPT_NONE) if (loop->lpt_decision.decision == LPT_NONE)
decide_peel_simple (loops, loop, flags); decide_peel_simple (loop, flags);
loop = next; loop = next;
} }
...@@ -269,8 +267,7 @@ decide_unrolling_and_peeling (struct loops *loops, int flags) ...@@ -269,8 +267,7 @@ decide_unrolling_and_peeling (struct loops *loops, int flags)
/* Decide whether the LOOP is once rolling and suitable for complete /* Decide whether the LOOP is once rolling and suitable for complete
peeling. */ peeling. */
static void static void
decide_peel_once_rolling (struct loops *loops, struct loop *loop, decide_peel_once_rolling (struct loop *loop, int flags ATTRIBUTE_UNUSED)
int flags ATTRIBUTE_UNUSED)
{ {
if (rtl_dump_file) if (rtl_dump_file)
fprintf (rtl_dump_file, ";; Considering peeling once rolling loop\n"); fprintf (rtl_dump_file, ";; Considering peeling once rolling loop\n");
...@@ -284,7 +281,7 @@ decide_peel_once_rolling (struct loops *loops, struct loop *loop, ...@@ -284,7 +281,7 @@ decide_peel_once_rolling (struct loops *loops, struct loop *loop,
} }
/* Check for simple loops. */ /* Check for simple loops. */
loop->simple = simple_loop_p (loops, loop, &loop->desc); loop->simple = simple_loop_p (loop, &loop->desc);
loop->has_desc = 1; loop->has_desc = 1;
/* Check number of iterations. */ /* Check number of iterations. */
...@@ -303,8 +300,7 @@ decide_peel_once_rolling (struct loops *loops, struct loop *loop, ...@@ -303,8 +300,7 @@ decide_peel_once_rolling (struct loops *loops, struct loop *loop,
/* Decide whether the LOOP is suitable for complete peeling. */ /* Decide whether the LOOP is suitable for complete peeling. */
static void static void
decide_peel_completely (struct loops *loops, struct loop *loop, decide_peel_completely (struct loop *loop, int flags ATTRIBUTE_UNUSED)
int flags ATTRIBUTE_UNUSED)
{ {
unsigned npeel; unsigned npeel;
...@@ -352,7 +348,7 @@ decide_peel_completely (struct loops *loops, struct loop *loop, ...@@ -352,7 +348,7 @@ decide_peel_completely (struct loops *loops, struct loop *loop,
/* Check for simple loops. */ /* Check for simple loops. */
if (!loop->has_desc) if (!loop->has_desc)
{ {
loop->simple = simple_loop_p (loops, loop, &loop->desc); loop->simple = simple_loop_p (loop, &loop->desc);
loop->has_desc = 1; loop->has_desc = 1;
} }
...@@ -441,8 +437,7 @@ peel_loop_completely (struct loops *loops, struct loop *loop) ...@@ -441,8 +437,7 @@ peel_loop_completely (struct loops *loops, struct loop *loop)
/* Decide whether to unroll LOOP iterating constant number of times and how much. */ /* Decide whether to unroll LOOP iterating constant number of times and how much. */
static void static void
decide_unroll_constant_iterations (struct loops *loops, struct loop *loop, decide_unroll_constant_iterations (struct loop *loop, int flags)
int flags)
{ {
unsigned nunroll, nunroll_by_av, best_copies, best_unroll = -1, n_copies, i; unsigned nunroll, nunroll_by_av, best_copies, best_unroll = -1, n_copies, i;
...@@ -475,7 +470,7 @@ decide_unroll_constant_iterations (struct loops *loops, struct loop *loop, ...@@ -475,7 +470,7 @@ decide_unroll_constant_iterations (struct loops *loops, struct loop *loop,
/* Check for simple loops. */ /* Check for simple loops. */
if (!loop->has_desc) if (!loop->has_desc)
{ {
loop->simple = simple_loop_p (loops, loop, &loop->desc); loop->simple = simple_loop_p (loop, &loop->desc);
loop->has_desc = 1; loop->has_desc = 1;
} }
...@@ -649,8 +644,7 @@ unroll_loop_constant_iterations (struct loops *loops, struct loop *loop) ...@@ -649,8 +644,7 @@ unroll_loop_constant_iterations (struct loops *loops, struct loop *loop)
/* Decide whether to unroll LOOP iterating runtime computable number of times /* Decide whether to unroll LOOP iterating runtime computable number of times
and how much. */ and how much. */
static void static void
decide_unroll_runtime_iterations (struct loops *loops, struct loop *loop, decide_unroll_runtime_iterations (struct loop *loop, int flags)
int flags)
{ {
unsigned nunroll, nunroll_by_av, i; unsigned nunroll, nunroll_by_av, i;
...@@ -683,7 +677,7 @@ decide_unroll_runtime_iterations (struct loops *loops, struct loop *loop, ...@@ -683,7 +677,7 @@ decide_unroll_runtime_iterations (struct loops *loops, struct loop *loop,
/* Check for simple loops. */ /* Check for simple loops. */
if (!loop->has_desc) if (!loop->has_desc)
{ {
loop->simple = simple_loop_p (loops, loop, &loop->desc); loop->simple = simple_loop_p (loop, &loop->desc);
loop->has_desc = 1; loop->has_desc = 1;
} }
...@@ -774,7 +768,7 @@ unroll_loop_runtime_iterations (struct loops *loops, struct loop *loop) ...@@ -774,7 +768,7 @@ unroll_loop_runtime_iterations (struct loops *loops, struct loop *loop)
unsigned nldom; unsigned nldom;
basic_block *ldom; basic_block *ldom;
nldom = get_dominated_by (loops->cfg.dom, body[i], &ldom); nldom = get_dominated_by (CDI_DOMINATORS, body[i], &ldom);
for (j = 0; j < nldom; j++) for (j = 0; j < nldom; j++)
if (!flow_bb_inside_loop_p (loop, ldom[j])) if (!flow_bb_inside_loop_p (loop, ldom[j]))
dom_bbs[n_dom_bbs++] = ldom[j]; dom_bbs[n_dom_bbs++] = ldom[j];
...@@ -821,7 +815,7 @@ unroll_loop_runtime_iterations (struct loops *loops, struct loop *loop) ...@@ -821,7 +815,7 @@ unroll_loop_runtime_iterations (struct loops *loops, struct loop *loop)
end_sequence (); end_sequence ();
/* Precondition the loop. */ /* Precondition the loop. */
loop_split_edge_with (loop_preheader_edge (loop), init_code, loops); loop_split_edge_with (loop_preheader_edge (loop), init_code);
remove_edges = xcalloc (max_unroll + n_peel + 1, sizeof (edge)); remove_edges = xcalloc (max_unroll + n_peel + 1, sizeof (edge));
n_remove_edges = 0; n_remove_edges = 0;
...@@ -844,7 +838,7 @@ unroll_loop_runtime_iterations (struct loops *loops, struct loop *loop) ...@@ -844,7 +838,7 @@ unroll_loop_runtime_iterations (struct loops *loops, struct loop *loop)
/* Record the place where switch will be built for preconditioning. */ /* Record the place where switch will be built for preconditioning. */
swtch = loop_split_edge_with (loop_preheader_edge (loop), swtch = loop_split_edge_with (loop_preheader_edge (loop),
NULL_RTX, loops); NULL_RTX);
for (i = 0; i < n_peel; i++) for (i = 0; i < n_peel; i++)
{ {
...@@ -862,8 +856,7 @@ unroll_loop_runtime_iterations (struct loops *loops, struct loop *loop) ...@@ -862,8 +856,7 @@ unroll_loop_runtime_iterations (struct loops *loops, struct loop *loop)
j = n_peel - i - (extra_zero_check ? 0 : 1); j = n_peel - i - (extra_zero_check ? 0 : 1);
p = REG_BR_PROB_BASE / (i + 2); p = REG_BR_PROB_BASE / (i + 2);
preheader = loop_split_edge_with (loop_preheader_edge (loop), preheader = loop_split_edge_with (loop_preheader_edge (loop), NULL_RTX);
NULL_RTX, loops);
label = block_label (preheader); label = block_label (preheader);
start_sequence (); start_sequence ();
do_compare_rtx_and_jump (copy_rtx (niter), GEN_INT (j), EQ, 0, do_compare_rtx_and_jump (copy_rtx (niter), GEN_INT (j), EQ, 0,
...@@ -879,8 +872,8 @@ unroll_loop_runtime_iterations (struct loops *loops, struct loop *loop) ...@@ -879,8 +872,8 @@ unroll_loop_runtime_iterations (struct loops *loops, struct loop *loop)
branch_code = get_insns (); branch_code = get_insns ();
end_sequence (); end_sequence ();
swtch = loop_split_edge_with (swtch->pred, branch_code, loops); swtch = loop_split_edge_with (swtch->pred, branch_code);
set_immediate_dominator (loops->cfg.dom, preheader, swtch); set_immediate_dominator (CDI_DOMINATORS, preheader, swtch);
swtch->succ->probability = REG_BR_PROB_BASE - p; swtch->succ->probability = REG_BR_PROB_BASE - p;
e = make_edge (swtch, preheader, e = make_edge (swtch, preheader,
swtch->succ->flags & EDGE_IRREDUCIBLE_LOOP); swtch->succ->flags & EDGE_IRREDUCIBLE_LOOP);
...@@ -892,8 +885,7 @@ unroll_loop_runtime_iterations (struct loops *loops, struct loop *loop) ...@@ -892,8 +885,7 @@ unroll_loop_runtime_iterations (struct loops *loops, struct loop *loop)
/* Add branch for zero iterations. */ /* Add branch for zero iterations. */
p = REG_BR_PROB_BASE / (max_unroll + 1); p = REG_BR_PROB_BASE / (max_unroll + 1);
swtch = ezc_swtch; swtch = ezc_swtch;
preheader = loop_split_edge_with (loop_preheader_edge (loop), preheader = loop_split_edge_with (loop_preheader_edge (loop), NULL_RTX);
NULL_RTX, loops);
label = block_label (preheader); label = block_label (preheader);
start_sequence (); start_sequence ();
do_compare_rtx_and_jump (copy_rtx (niter), const0_rtx, EQ, 0, do_compare_rtx_and_jump (copy_rtx (niter), const0_rtx, EQ, 0,
...@@ -909,8 +901,8 @@ unroll_loop_runtime_iterations (struct loops *loops, struct loop *loop) ...@@ -909,8 +901,8 @@ unroll_loop_runtime_iterations (struct loops *loops, struct loop *loop)
branch_code = get_insns (); branch_code = get_insns ();
end_sequence (); end_sequence ();
swtch = loop_split_edge_with (swtch->succ, branch_code, loops); swtch = loop_split_edge_with (swtch->succ, branch_code);
set_immediate_dominator (loops->cfg.dom, preheader, swtch); set_immediate_dominator (CDI_DOMINATORS, preheader, swtch);
swtch->succ->probability = REG_BR_PROB_BASE - p; swtch->succ->probability = REG_BR_PROB_BASE - p;
e = make_edge (swtch, preheader, e = make_edge (swtch, preheader,
swtch->succ->flags & EDGE_IRREDUCIBLE_LOOP); swtch->succ->flags & EDGE_IRREDUCIBLE_LOOP);
...@@ -918,7 +910,7 @@ unroll_loop_runtime_iterations (struct loops *loops, struct loop *loop) ...@@ -918,7 +910,7 @@ unroll_loop_runtime_iterations (struct loops *loops, struct loop *loop)
} }
/* Recount dominators for outer blocks. */ /* Recount dominators for outer blocks. */
iterate_fix_dominators (loops->cfg.dom, dom_bbs, n_dom_bbs); iterate_fix_dominators (CDI_DOMINATORS, dom_bbs, n_dom_bbs);
/* And unroll loop. */ /* And unroll loop. */
...@@ -946,7 +938,7 @@ unroll_loop_runtime_iterations (struct loops *loops, struct loop *loop) ...@@ -946,7 +938,7 @@ unroll_loop_runtime_iterations (struct loops *loops, struct loop *loop)
/* Decide whether to simply peel LOOP and how much. */ /* Decide whether to simply peel LOOP and how much. */
static void static void
decide_peel_simple (struct loops *loops, struct loop *loop, int flags) decide_peel_simple (struct loop *loop, int flags)
{ {
unsigned npeel; unsigned npeel;
...@@ -975,7 +967,7 @@ decide_peel_simple (struct loops *loops, struct loop *loop, int flags) ...@@ -975,7 +967,7 @@ decide_peel_simple (struct loops *loops, struct loop *loop, int flags)
/* Check for simple loops. */ /* Check for simple loops. */
if (!loop->has_desc) if (!loop->has_desc)
{ {
loop->simple = simple_loop_p (loops, loop, &loop->desc); loop->simple = simple_loop_p (loop, &loop->desc);
loop->has_desc = 1; loop->has_desc = 1;
} }
...@@ -1062,7 +1054,7 @@ peel_loop_simple (struct loops *loops, struct loop *loop) ...@@ -1062,7 +1054,7 @@ peel_loop_simple (struct loops *loops, struct loop *loop)
/* Decide whether to unroll LOOP stupidly and how much. */ /* Decide whether to unroll LOOP stupidly and how much. */
static void static void
decide_unroll_stupid (struct loops *loops, struct loop *loop, int flags) decide_unroll_stupid (struct loop *loop, int flags)
{ {
unsigned nunroll, nunroll_by_av, i; unsigned nunroll, nunroll_by_av, i;
...@@ -1095,7 +1087,7 @@ decide_unroll_stupid (struct loops *loops, struct loop *loop, int flags) ...@@ -1095,7 +1087,7 @@ decide_unroll_stupid (struct loops *loops, struct loop *loop, int flags)
/* Check for simple loops. */ /* Check for simple loops. */
if (!loop->has_desc) if (!loop->has_desc)
{ {
loop->simple = simple_loop_p (loops, loop, &loop->desc); loop->simple = simple_loop_p (loop, &loop->desc);
loop->has_desc = 1; loop->has_desc = 1;
} }
......
...@@ -81,7 +81,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA ...@@ -81,7 +81,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
static struct loop *unswitch_loop (struct loops *, struct loop *, static struct loop *unswitch_loop (struct loops *, struct loop *,
basic_block); basic_block);
static void unswitch_single_loop (struct loops *, struct loop *, rtx, int); static void unswitch_single_loop (struct loops *, struct loop *, rtx, int);
static bool may_unswitch_on_p (struct loops *, basic_block, struct loop *, static bool may_unswitch_on_p (basic_block, struct loop *,
basic_block *); basic_block *);
static rtx reversed_condition (rtx); static rtx reversed_condition (rtx);
...@@ -107,7 +107,7 @@ unswitch_loops (struct loops *loops) ...@@ -107,7 +107,7 @@ unswitch_loops (struct loops *loops)
unswitch_single_loop (loops, loop, NULL_RTX, 0); unswitch_single_loop (loops, loop, NULL_RTX, 0);
#ifdef ENABLE_CHECKING #ifdef ENABLE_CHECKING
verify_dominators (loops->cfg.dom); verify_dominators (CDI_DOMINATORS);
verify_loop_structure (loops); verify_loop_structure (loops);
#endif #endif
} }
...@@ -117,8 +117,7 @@ unswitch_loops (struct loops *loops) ...@@ -117,8 +117,7 @@ unswitch_loops (struct loops *loops)
basic blocks (for what it means see comments below). List of basic blocks basic blocks (for what it means see comments below). List of basic blocks
inside LOOP is provided in BODY to save time. */ inside LOOP is provided in BODY to save time. */
static bool static bool
may_unswitch_on_p (struct loops *loops, basic_block bb, struct loop *loop, may_unswitch_on_p (basic_block bb, struct loop *loop, basic_block *body)
basic_block *body)
{ {
rtx test; rtx test;
unsigned i; unsigned i;
...@@ -136,7 +135,7 @@ may_unswitch_on_p (struct loops *loops, basic_block bb, struct loop *loop, ...@@ -136,7 +135,7 @@ may_unswitch_on_p (struct loops *loops, basic_block bb, struct loop *loop,
/* It must be executed just once each iteration (because otherwise we /* It must be executed just once each iteration (because otherwise we
are unable to update dominator/irreducible loop information correctly). */ are unable to update dominator/irreducible loop information correctly). */
if (!just_once_each_iteration_p (loops, loop, bb)) if (!just_once_each_iteration_p (loop, bb))
return false; return false;
/* Condition must be invariant. We use just a stupid test of invariantness /* Condition must be invariant. We use just a stupid test of invariantness
...@@ -239,7 +238,7 @@ unswitch_single_loop (struct loops *loops, struct loop *loop, ...@@ -239,7 +238,7 @@ unswitch_single_loop (struct loops *loops, struct loop *loop,
/* Find a bb to unswitch on. */ /* Find a bb to unswitch on. */
bbs = get_loop_body (loop); bbs = get_loop_body (loop);
for (i = 0; i < loop->num_nodes; i++) for (i = 0; i < loop->num_nodes; i++)
if (may_unswitch_on_p (loops, bbs[i], loop, bbs)) if (may_unswitch_on_p (bbs[i], loop, bbs))
break; break;
if (i == loop->num_nodes) if (i == loop->num_nodes)
...@@ -295,7 +294,7 @@ unswitch_single_loop (struct loops *loops, struct loop *loop, ...@@ -295,7 +294,7 @@ unswitch_single_loop (struct loops *loops, struct loop *loop,
rconds = cond_checked; rconds = cond_checked;
/* Separate condition in a single basic block. */ /* Separate condition in a single basic block. */
bb = split_loop_bb (loops, bbs[i], PREV_INSN (split_before))->dest; bb = split_loop_bb (bbs[i], PREV_INSN (split_before))->dest;
free (bbs); free (bbs);
true_first = !(bb->succ->flags & EDGE_FALLTHRU); true_first = !(bb->succ->flags & EDGE_FALLTHRU);
if (rtl_dump_file) if (rtl_dump_file)
...@@ -335,7 +334,7 @@ unswitch_loop (struct loops *loops, struct loop *loop, basic_block unswitch_on) ...@@ -335,7 +334,7 @@ unswitch_loop (struct loops *loops, struct loop *loop, basic_block unswitch_on)
if (!unswitch_on->succ || !unswitch_on->succ->succ_next || if (!unswitch_on->succ || !unswitch_on->succ->succ_next ||
unswitch_on->succ->succ_next->succ_next) unswitch_on->succ->succ_next->succ_next)
abort (); abort ();
if (!just_once_each_iteration_p (loops, loop, unswitch_on)) if (!just_once_each_iteration_p (loop, unswitch_on))
abort (); abort ();
if (loop->inner) if (loop->inner)
abort (); abort ();
...@@ -382,7 +381,7 @@ unswitch_loop (struct loops *loops, struct loop *loop, basic_block unswitch_on) ...@@ -382,7 +381,7 @@ unswitch_loop (struct loops *loops, struct loop *loop, basic_block unswitch_on)
switch_bb->succ->flags &= ~EDGE_IRREDUCIBLE_LOOP; switch_bb->succ->flags &= ~EDGE_IRREDUCIBLE_LOOP;
switch_bb->succ->succ_next->flags &= ~EDGE_IRREDUCIBLE_LOOP; switch_bb->succ->succ_next->flags &= ~EDGE_IRREDUCIBLE_LOOP;
} }
add_to_dominance_info (loops->cfg.dom, switch_bb); add_to_dominance_info (CDI_DOMINATORS, switch_bb);
unswitch_on->rbi->copy = unswitch_on_alt; unswitch_on->rbi->copy = unswitch_on_alt;
/* Loopify from the copy of LOOP body, constructing the new loop. */ /* Loopify from the copy of LOOP body, constructing the new loop. */
...@@ -403,8 +402,8 @@ unswitch_loop (struct loops *loops, struct loop *loop, basic_block unswitch_on) ...@@ -403,8 +402,8 @@ unswitch_loop (struct loops *loops, struct loop *loop, basic_block unswitch_on)
fix_loop_placement (nloop); fix_loop_placement (nloop);
/* Preserve the simple loop preheaders. */ /* Preserve the simple loop preheaders. */
loop_split_edge_with (loop_preheader_edge (loop), NULL_RTX, loops); loop_split_edge_with (loop_preheader_edge (loop), NULL_RTX);
loop_split_edge_with (loop_preheader_edge (nloop), NULL_RTX, loops); loop_split_edge_with (loop_preheader_edge (nloop), NULL_RTX);
return nloop; return nloop;
} }
...@@ -72,10 +72,8 @@ static void estimate_loops_at_level (struct loop *loop); ...@@ -72,10 +72,8 @@ static void estimate_loops_at_level (struct loop *loop);
static void propagate_freq (struct loop *); static void propagate_freq (struct loop *);
static void estimate_bb_frequencies (struct loops *); static void estimate_bb_frequencies (struct loops *);
static void counts_to_freqs (void); static void counts_to_freqs (void);
static void process_note_predictions (basic_block, int *, dominance_info, static void process_note_predictions (basic_block, int *);
dominance_info); static void process_note_prediction (basic_block, int *, int, int);
static void process_note_prediction (basic_block, int *, dominance_info,
dominance_info, int, int);
static bool last_basic_block_p (basic_block); static bool last_basic_block_p (basic_block);
static void compute_function_frequency (void); static void compute_function_frequency (void);
static void choose_function_section (void); static void choose_function_section (void);
...@@ -393,13 +391,12 @@ combine_predictions_for_insn (rtx insn, basic_block bb) ...@@ -393,13 +391,12 @@ combine_predictions_for_insn (rtx insn, basic_block bb)
void void
estimate_probability (struct loops *loops_info) estimate_probability (struct loops *loops_info)
{ {
dominance_info dominators, post_dominators;
basic_block bb; basic_block bb;
unsigned i; unsigned i;
connect_infinite_loops_to_exit (); connect_infinite_loops_to_exit ();
dominators = calculate_dominance_info (CDI_DOMINATORS); calculate_dominance_info (CDI_DOMINATORS);
post_dominators = calculate_dominance_info (CDI_POST_DOMINATORS); calculate_dominance_info (CDI_POST_DOMINATORS);
/* Try to predict out blocks in a loop that are not part of a /* Try to predict out blocks in a loop that are not part of a
natural loop. */ natural loop. */
...@@ -412,11 +409,10 @@ estimate_probability (struct loops *loops_info) ...@@ -412,11 +409,10 @@ estimate_probability (struct loops *loops_info)
struct loop_desc desc; struct loop_desc desc;
unsigned HOST_WIDE_INT niter; unsigned HOST_WIDE_INT niter;
flow_loop_scan (loops_info, loop, LOOP_EXIT_EDGES); flow_loop_scan (loop, LOOP_EXIT_EDGES);
exits = loop->num_exits; exits = loop->num_exits;
if (simple_loop_p (loops_info, loop, &desc) if (simple_loop_p (loop, &desc) && desc.const_iter)
&& desc.const_iter)
{ {
int prob; int prob;
niter = desc.niter + 1; niter = desc.niter + 1;
...@@ -500,8 +496,8 @@ estimate_probability (struct loops *loops_info) ...@@ -500,8 +496,8 @@ estimate_probability (struct loops *loops_info)
/* Look for block we are guarding (ie we dominate it, /* Look for block we are guarding (ie we dominate it,
but it doesn't postdominate us). */ but it doesn't postdominate us). */
if (e->dest != EXIT_BLOCK_PTR && e->dest != bb if (e->dest != EXIT_BLOCK_PTR && e->dest != bb
&& dominated_by_p (dominators, e->dest, e->src) && dominated_by_p (CDI_DOMINATORS, e->dest, e->src)
&& !dominated_by_p (post_dominators, e->src, e->dest)) && !dominated_by_p (CDI_POST_DOMINATORS, e->src, e->dest))
{ {
rtx insn; rtx insn;
...@@ -618,8 +614,7 @@ estimate_probability (struct loops *loops_info) ...@@ -618,8 +614,7 @@ estimate_probability (struct loops *loops_info)
&& bb->succ->succ_next != NULL) && bb->succ->succ_next != NULL)
combine_predictions_for_insn (BB_END (bb), bb); combine_predictions_for_insn (BB_END (bb), bb);
free_dominance_info (post_dominators); free_dominance_info (CDI_POST_DOMINATORS);
free_dominance_info (dominators);
remove_fake_edges (); remove_fake_edges ();
estimate_bb_frequencies (loops_info); estimate_bb_frequencies (loops_info);
...@@ -719,10 +714,7 @@ last_basic_block_p (basic_block bb) ...@@ -719,10 +714,7 @@ last_basic_block_p (basic_block bb)
on demand, so -1 may be there in case this was not needed yet). */ on demand, so -1 may be there in case this was not needed yet). */
static void static void
process_note_prediction (basic_block bb, int *heads, process_note_prediction (basic_block bb, int *heads, int pred, int flags)
dominance_info dominators,
dominance_info post_dominators, int pred,
int flags)
{ {
edge e; edge e;
int y; int y;
...@@ -736,18 +728,18 @@ process_note_prediction (basic_block bb, int *heads, ...@@ -736,18 +728,18 @@ process_note_prediction (basic_block bb, int *heads,
find first dominator that we do not post-dominate (we are find first dominator that we do not post-dominate (we are
using already known members of heads array). */ using already known members of heads array). */
basic_block ai = bb; basic_block ai = bb;
basic_block next_ai = get_immediate_dominator (dominators, bb); basic_block next_ai = get_immediate_dominator (CDI_DOMINATORS, bb);
int head; int head;
while (heads[next_ai->index] < 0) while (heads[next_ai->index] < 0)
{ {
if (!dominated_by_p (post_dominators, next_ai, bb)) if (!dominated_by_p (CDI_POST_DOMINATORS, next_ai, bb))
break; break;
heads[next_ai->index] = ai->index; heads[next_ai->index] = ai->index;
ai = next_ai; ai = next_ai;
next_ai = get_immediate_dominator (dominators, next_ai); next_ai = get_immediate_dominator (CDI_DOMINATORS, next_ai);
} }
if (!dominated_by_p (post_dominators, next_ai, bb)) if (!dominated_by_p (CDI_POST_DOMINATORS, next_ai, bb))
head = next_ai->index; head = next_ai->index;
else else
head = heads[next_ai->index]; head = heads[next_ai->index];
...@@ -769,7 +761,7 @@ process_note_prediction (basic_block bb, int *heads, ...@@ -769,7 +761,7 @@ process_note_prediction (basic_block bb, int *heads,
return; return;
for (e = BASIC_BLOCK (y)->succ; e; e = e->succ_next) for (e = BASIC_BLOCK (y)->succ; e; e = e->succ_next)
if (e->dest->index >= 0 if (e->dest->index >= 0
&& dominated_by_p (post_dominators, e->dest, bb)) && dominated_by_p (CDI_POST_DOMINATORS, e->dest, bb))
predict_edge_def (e, pred, taken); predict_edge_def (e, pred, taken);
} }
...@@ -778,9 +770,7 @@ process_note_prediction (basic_block bb, int *heads, ...@@ -778,9 +770,7 @@ process_note_prediction (basic_block bb, int *heads,
process_note_prediction. */ process_note_prediction. */
static void static void
process_note_predictions (basic_block bb, int *heads, process_note_predictions (basic_block bb, int *heads)
dominance_info dominators,
dominance_info post_dominators)
{ {
rtx insn; rtx insn;
edge e; edge e;
...@@ -813,8 +803,6 @@ process_note_predictions (basic_block bb, int *heads, ...@@ -813,8 +803,6 @@ process_note_predictions (basic_block bb, int *heads,
/* Process single prediction note. */ /* Process single prediction note. */
process_note_prediction (bb, process_note_prediction (bb,
heads, heads,
dominators,
post_dominators,
alg, (int) NOTE_PREDICTION_FLAGS (insn)); alg, (int) NOTE_PREDICTION_FLAGS (insn));
delete_insn (insn); delete_insn (insn);
} }
...@@ -827,10 +815,7 @@ process_note_predictions (basic_block bb, int *heads, ...@@ -827,10 +815,7 @@ process_note_predictions (basic_block bb, int *heads,
/* This block ended from other reasons than because of return. /* This block ended from other reasons than because of return.
If it is because of noreturn call, this should certainly not If it is because of noreturn call, this should certainly not
be taken. Otherwise it is probably some error recovery. */ be taken. Otherwise it is probably some error recovery. */
process_note_prediction (bb, process_note_prediction (bb, heads, PRED_NORETURN, NOT_TAKEN);
heads,
dominators,
post_dominators, PRED_NORETURN, NOT_TAKEN);
} }
} }
...@@ -841,15 +826,14 @@ void ...@@ -841,15 +826,14 @@ void
note_prediction_to_br_prob (void) note_prediction_to_br_prob (void)
{ {
basic_block bb; basic_block bb;
dominance_info post_dominators, dominators;
int *heads; int *heads;
/* To enable handling of noreturn blocks. */ /* To enable handling of noreturn blocks. */
add_noreturn_fake_exit_edges (); add_noreturn_fake_exit_edges ();
connect_infinite_loops_to_exit (); connect_infinite_loops_to_exit ();
post_dominators = calculate_dominance_info (CDI_POST_DOMINATORS); calculate_dominance_info (CDI_POST_DOMINATORS);
dominators = calculate_dominance_info (CDI_DOMINATORS); calculate_dominance_info (CDI_DOMINATORS);
heads = xmalloc (sizeof (int) * last_basic_block); heads = xmalloc (sizeof (int) * last_basic_block);
memset (heads, -1, sizeof (int) * last_basic_block); memset (heads, -1, sizeof (int) * last_basic_block);
...@@ -858,10 +842,10 @@ note_prediction_to_br_prob (void) ...@@ -858,10 +842,10 @@ note_prediction_to_br_prob (void)
/* Process all prediction notes. */ /* Process all prediction notes. */
FOR_EACH_BB (bb) FOR_EACH_BB (bb)
process_note_predictions (bb, heads, dominators, post_dominators); process_note_predictions (bb, heads);
free_dominance_info (post_dominators); free_dominance_info (CDI_POST_DOMINATORS);
free_dominance_info (dominators); free_dominance_info (CDI_DOMINATORS);
free (heads); free (heads);
remove_fake_edges (); remove_fake_edges ();
......
...@@ -155,7 +155,7 @@ static int *containing_rgn; ...@@ -155,7 +155,7 @@ static int *containing_rgn;
void debug_regions (void); void debug_regions (void);
static void find_single_block_region (void); static void find_single_block_region (void);
static void find_rgns (struct edge_list *, dominance_info); static void find_rgns (struct edge_list *);
static int too_large (int, int *, int *); static int too_large (int, int *, int *);
extern void debug_live (int, int); extern void debug_live (int, int);
...@@ -613,7 +613,7 @@ too_large (int block, int *num_bbs, int *num_insns) ...@@ -613,7 +613,7 @@ too_large (int block, int *num_bbs, int *num_insns)
of edge tables. That would simplify it somewhat. */ of edge tables. That would simplify it somewhat. */
static void static void
find_rgns (struct edge_list *edge_list, dominance_info dom) find_rgns (struct edge_list *edge_list)
{ {
int *max_hdr, *dfs_nr, *stack, *degree; int *max_hdr, *dfs_nr, *stack, *degree;
char no_loops = 1; char no_loops = 1;
...@@ -827,7 +827,7 @@ find_rgns (struct edge_list *edge_list, dominance_info dom) ...@@ -827,7 +827,7 @@ find_rgns (struct edge_list *edge_list, dominance_info dom)
{ {
/* Now verify that the block is dominated by the loop /* Now verify that the block is dominated by the loop
header. */ header. */
if (!dominated_by_p (dom, jbb, bb)) if (!dominated_by_p (CDI_DOMINATORS, jbb, bb))
break; break;
} }
} }
...@@ -2597,7 +2597,6 @@ init_regions (void) ...@@ -2597,7 +2597,6 @@ init_regions (void)
} }
else else
{ {
dominance_info dom;
struct edge_list *edge_list; struct edge_list *edge_list;
/* The scheduler runs after estimate_probabilities; therefore, we /* The scheduler runs after estimate_probabilities; therefore, we
...@@ -2607,7 +2606,7 @@ init_regions (void) ...@@ -2607,7 +2606,7 @@ init_regions (void)
edge_list = create_edge_list (); edge_list = create_edge_list ();
/* Compute the dominators and post dominators. */ /* Compute the dominators and post dominators. */
dom = calculate_dominance_info (CDI_DOMINATORS); calculate_dominance_info (CDI_DOMINATORS);
/* build_control_flow will return nonzero if it detects unreachable /* build_control_flow will return nonzero if it detects unreachable
blocks or any other irregularity with the cfg which prevents blocks or any other irregularity with the cfg which prevents
...@@ -2615,7 +2614,7 @@ init_regions (void) ...@@ -2615,7 +2614,7 @@ init_regions (void)
if (build_control_flow (edge_list) != 0) if (build_control_flow (edge_list) != 0)
find_single_block_region (); find_single_block_region ();
else else
find_rgns (edge_list, dom); find_rgns (edge_list);
if (sched_verbose >= 3) if (sched_verbose >= 3)
debug_regions (); debug_regions ();
...@@ -2625,7 +2624,7 @@ init_regions (void) ...@@ -2625,7 +2624,7 @@ init_regions (void)
/* For now. This will move as more and more of haifa is converted /* For now. This will move as more and more of haifa is converted
to using the cfg code in flow.c. */ to using the cfg code in flow.c. */
free_dominance_info (dom); free_dominance_info (CDI_DOMINATORS);
} }
} }
......
...@@ -2477,6 +2477,7 @@ rest_of_handle_branch_prob (tree decl, rtx insns) ...@@ -2477,6 +2477,7 @@ rest_of_handle_branch_prob (tree decl, rtx insns)
estimate_probability (&loops); estimate_probability (&loops);
flow_loops_free (&loops); flow_loops_free (&loops);
free_dominance_info (CDI_DOMINATORS);
close_dump_file (DFI_bp, print_rtl_with_bb, insns); close_dump_file (DFI_bp, print_rtl_with_bb, insns);
timevar_pop (TV_BRANCH_PROB); timevar_pop (TV_BRANCH_PROB);
} }
...@@ -3014,8 +3015,9 @@ rest_of_handle_loop_optimize (tree decl, rtx insns) ...@@ -3014,8 +3015,9 @@ rest_of_handle_loop_optimize (tree decl, rtx insns)
sooner, but we want the profile feedback to work more sooner, but we want the profile feedback to work more
efficiently. */ efficiently. */
static void static void
rest_of_handle_loop2 (tree decl, rtx insns) rest_of_handle_loop2 (tree decl ATTRIBUTE_UNUSED, rtx insns ATTRIBUTE_UNUSED)
{ {
#if 0
struct loops *loops; struct loops *loops;
timevar_push (TV_LOOP); timevar_push (TV_LOOP);
open_dump_file (DFI_loop2, decl); open_dump_file (DFI_loop2, decl);
...@@ -3047,6 +3049,7 @@ rest_of_handle_loop2 (tree decl, rtx insns) ...@@ -3047,6 +3049,7 @@ rest_of_handle_loop2 (tree decl, rtx insns)
close_dump_file (DFI_loop2, print_rtl_with_bb, get_insns ()); close_dump_file (DFI_loop2, print_rtl_with_bb, get_insns ());
timevar_pop (TV_LOOP); timevar_pop (TV_LOOP);
ggc_collect (); ggc_collect ();
#endif
} }
/* This is called from finish_function (within langhooks.parse_file) /* This is called from finish_function (within langhooks.parse_file)
......
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