Backport from tree-ssa (relevant changes only):
authorsteven <steven@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 30 Dec 2003 10:40:56 +0000 (10:40 +0000)
committersteven <steven@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 30 Dec 2003 10:40:56 +0000 (10:40 +0000)
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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@75226 138bc75d-0d04-0410-961f-82ee72b054a4

25 files changed:
gcc/ChangeLog
gcc/Makefile.in
gcc/basic-block.h
gcc/bt-load.c
gcc/cfg.c
gcc/cfglayout.c
gcc/cfglayout.h
gcc/cfgloop.c
gcc/cfgloop.h
gcc/cfgloopanal.c
gcc/cfgloopmanip.c
gcc/dominance.c
gcc/et-forest.c
gcc/et-forest.h
gcc/function.c
gcc/function.h
gcc/gcse.c
gcc/graph.c
gcc/ifcvt.c
gcc/loop-init.c
gcc/loop-unroll.c
gcc/loop-unswitch.c
gcc/predict.c
gcc/sched-rgn.c
gcc/toplev.c

index a6c5491..4b5b073 100644 (file)
@@ -1,3 +1,102 @@
+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>
 
        PR target/13456
index 1390141..bd65e0b 100644 (file)
@@ -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) \
     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 \
-    $(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 \
     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) \
    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) \
    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)
 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)
index 9b664a1..2e8f578 100644 (file)
@@ -234,6 +234,9 @@ typedef struct basic_block_def {
   /* Outermost loop containing the block.  */
   struct loop *loop_father;
 
+  /* The dominance and postdominance information node.  */
+  struct et_node *dom[2];
+
   /* Expected number of executions: calculated in profile.c.  */
   gcov_type count;
 
@@ -373,10 +376,6 @@ extern void clear_edges (void);
 extern void mark_critical_edges (void);
 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
    IF-THEN-ELSE blocks for the conditional execution support.  This
    needs to be in a public file in case the IFCVT macros call
@@ -612,22 +611,35 @@ enum cdi_direction
   CDI_POST_DOMINATORS
 };
 
-extern dominance_info calculate_dominance_info (enum cdi_direction);
-extern void free_dominance_info (dominance_info);
-extern basic_block nearest_common_dominator (dominance_info,
+enum dom_state
+{
+  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);
-extern void set_immediate_dominator (dominance_info, basic_block,
+extern void set_immediate_dominator (enum cdi_direction, basic_block,
                                     basic_block);
-extern basic_block get_immediate_dominator (dominance_info, basic_block);
-extern bool dominated_by_p (dominance_info, basic_block, basic_block);
-extern int get_dominated_by (dominance_info, basic_block, basic_block **);
-extern void add_to_dominance_info (dominance_info, basic_block);
-extern void delete_from_dominance_info (dominance_info, basic_block);
-basic_block recount_dominator (dominance_info, basic_block);
-extern void redirect_immediate_dominators (dominance_info, basic_block,
+extern basic_block get_immediate_dominator (enum cdi_direction, basic_block);
+extern bool dominated_by_p (enum cdi_direction, basic_block, basic_block);
+extern int get_dominated_by (enum cdi_direction, basic_block, basic_block **);
+extern void add_to_dominance_info (enum cdi_direction, basic_block);
+extern void delete_from_dominance_info (enum cdi_direction, basic_block);
+basic_block recount_dominator (enum cdi_direction, basic_block);
+extern void redirect_immediate_dominators (enum cdi_direction, basic_block,
                                           basic_block);
-void iterate_fix_dominators (dominance_info, basic_block *, int);
-extern void verify_dominators (dominance_info);
+extern void iterate_fix_dominators (enum cdi_direction, basic_block *, int);
+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"
 
index 6f77a20..2a68cd7 100644 (file)
@@ -155,9 +155,6 @@ static void note_btr_set (rtx, rtx, void *);
    migrating branch target load instructions.  */
 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
    live in that block.  */
 static HARD_REG_SET *btrs_live;
@@ -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));
 
-  if (dominated_by_p (dom, new_bb, head_bb))
+  if (dominated_by_p (CDI_DOMINATORS, new_bb, head_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;
       int new_block = new_bb->index;
@@ -974,7 +971,7 @@ combine_btr_defs (btr_def def, HARD_REG_SET *btrs_live_in_range)
       if (other_def != def
          && other_def->uses != NULL
          && ! 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
             be combined.  */
@@ -1226,9 +1223,9 @@ migrate_btr_def (btr_def def, int min_cost)
 
   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;
-       try = get_immediate_dominator (dom, try))
+       try = get_immediate_dominator (CDI_DOMINATORS, try))
     {
       /* Try to move the instruction that sets the target register into
         basic block TRY.  */
@@ -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
            " loop-depth = %d idom = %d\n",
            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)
       life_analysis (insns, NULL, 0);
 
       /* Dominator info is also needed for migrate_btr_def.  */
-      dom = calculate_dominance_info (CDI_DOMINATORS);
+      calculate_dominance_info (CDI_DOMINATORS);
       migrate_btr_defs (class,
                       ((*targetm.branch_target_register_callee_saved)
                        (after_prologue_epilogue_gen)));
 
-      free_dominance_info (dom);
+      free_dominance_info (CDI_DOMINATORS);
 
       update_life_info (NULL, UPDATE_LIFE_GLOBAL_RM_NOTES,
                        PROP_DEATH_NOTES | PROP_REG_INFO);
index 32da973..96dac25 100644 (file)
--- a/gcc/cfg.c
+++ b/gcc/cfg.c
@@ -111,6 +111,7 @@ struct basic_block_def entry_exit_blocks[2]
     EXIT_BLOCK_PTR,            /* next_bb */
     0,                         /* loop_depth */
     NULL,                       /* loop_father */
+    { NULL, NULL },            /* dom */
     0,                         /* count */
     0,                         /* frequency */
     0,                         /* flags */
@@ -133,6 +134,7 @@ struct basic_block_def entry_exit_blocks[2]
     NULL,                      /* next_bb */
     0,                         /* loop_depth */
     NULL,                       /* loop_father */
+    { NULL, NULL },            /* dom */
     0,                         /* count */
     0,                         /* frequency */
     0,                         /* flags */
index 14138a7..15ec054 100644 (file)
@@ -1253,7 +1253,7 @@ end:
 void
 copy_bbs (basic_block *bbs, unsigned n, basic_block *new_bbs,
          edge *edges, unsigned n_edges, edge *new_edges,
-         struct loop *base, struct loops *loops)
+         struct loop *base)
 {
   unsigned i, j;
   basic_block bb, new_bb, dom_bb;
@@ -1268,7 +1268,7 @@ copy_bbs (basic_block *bbs, unsigned n, basic_block *new_bbs,
       bb->rbi->duplicated = 1;
       /* Add to loop.  */
       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.  */
       if (bb->loop_father->header == bb && bb->loop_father != base)
        new_bb->loop_father->header = new_bb;
@@ -1283,11 +1283,11 @@ copy_bbs (basic_block *bbs, unsigned n, basic_block *new_bbs,
       bb = 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)
        {
          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);
        }
     }
 
index 3258fe8..ca79e26 100644 (file)
@@ -43,5 +43,5 @@ extern void insn_locators_initialize (void);
 extern void reemit_insn_block_notes (void);
 extern bool can_copy_bbs_p (basic_block *, unsigned);
 extern void copy_bbs (basic_block *, unsigned, basic_block *,
-                     edge *, unsigned, edge *, struct loop *, struct loops *);
-extern void cfg_layout_initialize_rbi  (basic_block);
+                     edge *, unsigned, edge *, struct loop *);
+extern void cfg_layout_initialize_rbi (basic_block);
index 413b606..43c52f2 100644 (file)
@@ -38,7 +38,7 @@ static void flow_loop_entry_edges_find (struct loop *);
 static void flow_loop_exit_edges_find (struct loop *);
 static int flow_loop_nodes_find (basic_block, 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_loops_level_compute (struct loops *);
 static void establish_preds (struct loop *);
@@ -55,7 +55,7 @@ flow_loops_cfg_dump (const struct loops *loops, FILE *file)
   int i;
   basic_block bb;
 
-  if (! loops->num || ! file || ! loops->cfg.dom)
+  if (! loops->num || ! file)
     return;
 
   FOR_EACH_BB (bb)
@@ -212,9 +212,6 @@ flow_loops_free (struct loops *loops)
       free (loops->parray);
       loops->parray = NULL;
 
-      if (loops->cfg.dom)
-       free_dominance_info (loops->cfg.dom);
-
       if (loops->cfg.dfs_order)
        free (loops->cfg.dfs_order);
       if (loops->cfg.rc_order)
@@ -391,11 +388,10 @@ flow_loop_pre_header_scan (struct loop *loop)
 }
 
 /* Return the block for the pre-header of the loop with header
-   HEADER where DOM specifies the dominator information.  Return NULL if
-   there is no pre-header.  */
+   HEADER.  Return NULL if there is no pre-header.  */
 
 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;
   edge e;
@@ -408,7 +404,7 @@ flow_loop_pre_header_find (basic_block header, dominance_info dom)
       basic_block node = e->src;
 
       if (node != ENTRY_BLOCK_PTR
-         && ! dominated_by_p (dom, node, header))
+         && ! dominated_by_p (CDI_DOMINATORS, node, header))
        {
          if (pre_header == NULL)
            pre_header = node;
@@ -522,7 +518,7 @@ flow_loops_level_compute (struct loops *loops)
    about it specified by FLAGS.  */
 
 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)
     {
@@ -541,8 +537,7 @@ flow_loop_scan (struct loops *loops, struct loop *loop, int flags)
   if (flags & LOOP_PRE_HEADER)
     {
       /* Look to see if the loop has a pre-header node.  */
-      loop->pre_header
-       = flow_loop_pre_header_find (loop->header, loops->cfg.dom);
+      loop->pre_header = flow_loop_pre_header_find (loop->header);
 
       /* Find the blocks within the extended basic block of
         the loop pre-header.  */
@@ -627,12 +622,11 @@ make_forwarder_block (basic_block bb, int redirect_latch, int redirect_nonlatch,
 static void
 canonicalize_loop_headers (void)
 {
-  dominance_info dom;
   basic_block header;
   edge e;
 
   /* Compute the dominators.  */
-  dom = calculate_dominance_info (CDI_DOMINATORS);
+  calculate_dominance_info (CDI_DOMINATORS);
 
   alloc_aux_for_blocks (sizeof (int));
   alloc_aux_for_edges (sizeof (int));
@@ -651,7 +645,7 @@ canonicalize_loop_headers (void)
            have_abnormal_edge = 1;
 
          if (latch != ENTRY_BLOCK_PTR
-             && dominated_by_p (dom, latch, header))
+             && dominated_by_p (CDI_DOMINATORS, latch, header))
            {
              num_latches++;
              LATCH_EDGE (e) = 1;
@@ -663,6 +657,8 @@ canonicalize_loop_headers (void)
        HEADER_BLOCK (header) = num_latches;
     }
 
+  free_dominance_info (CDI_DOMINATORS);
+
   if (HEADER_BLOCK (ENTRY_BLOCK_PTR->succ->dest))
     {
       basic_block bb;
@@ -728,7 +724,6 @@ canonicalize_loop_headers (void)
 
   free_aux_for_blocks ();
   free_aux_for_edges ();
-  free_dominance_info (dom);
 }
 
 /* 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)
   int num_loops;
   edge e;
   sbitmap headers;
-  dominance_info dom;
   int *dfs_order;
   int *rc_order;
   basic_block header;
@@ -770,7 +764,7 @@ flow_loops_find (struct loops *loops, int flags)
   canonicalize_loop_headers ();
 
   /* 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
      same as the number of natural loops.  */
@@ -804,7 +798,8 @@ flow_loops_find (struct loops *loops, int flags)
             node (header) that dominates all the nodes in the
             loop.  It also has single back edge to the header
             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.  */
              if (more_latches)
@@ -849,7 +844,6 @@ flow_loops_find (struct loops *loops, int flags)
       flow_depth_first_order_compute (dfs_order, rc_order);
 
       /* Save CFG derived information to avoid recomputing it.  */
-      loops->cfg.dom = dom;
       loops->cfg.dfs_order = dfs_order;
       loops->cfg.rc_order = rc_order;
 
@@ -878,7 +872,7 @@ flow_loops_find (struct loops *loops, int flags)
              basic_block latch = e->src;
 
              if (latch != ENTRY_BLOCK_PTR
-                 && dominated_by_p (dom, latch, header))
+                 && dominated_by_p (CDI_DOMINATORS, latch, header))
                {
                  loop->latch = latch;
                  break;
@@ -897,14 +891,13 @@ flow_loops_find (struct loops *loops, int flags)
 
       /* Scan the loops.  */
       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;
     }
   else
     {
-      loops->cfg.dom = NULL;
-      free_dominance_info (dom);
+      free_dominance_info (CDI_DOMINATORS);
     }
 
   loops->state = 0;
index 0ab1590..4d8c67d 100644 (file)
@@ -230,9 +230,6 @@ struct loops
   /* Information derived from the 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.  */
     int *dfs_order;
 
@@ -265,7 +262,7 @@ extern void flow_loops_dump (const struct loops *, FILE *,
                             void (*)(const struct loop *, FILE *, int), int);
 extern void flow_loop_dump (const struct loop *, FILE *,
                            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 *);
 void mark_irreducible_loops (struct loops *);
 
@@ -292,7 +289,7 @@ extern void remove_bb_from_loops (basic_block);
 extern void cancel_loop (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 *);
 
 enum
@@ -306,10 +303,9 @@ extern void force_single_succ_latches (struct loops *);
 extern void verify_loop_structure (struct loops *);
 
 /* 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 bool just_once_each_iteration_p (struct loops *,struct loop *,
-                                       basic_block);
+extern bool just_once_each_iteration_p (struct loop *, basic_block);
 extern unsigned expected_loop_iterations (const struct loop *);
 
 /* Loop manipulation.  */
@@ -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 void unloop (struct loops *, struct loop *);
 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.  */
 extern struct loops *loop_optimizer_init (FILE *);
index 74cebe0..fb5f8ae 100644 (file)
@@ -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 bool constant_iterations (struct loop_desc *, unsigned HOST_WIDE_INT *,
                                 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 *);
 static rtx variable_initial_value (rtx, regset, rtx, rtx *, enum machine_mode);
 static rtx variable_initial_values (edge, rtx, enum machine_mode);
 static bool simple_condition_p (struct loop *, rtx, regset,
                                struct loop_desc *);
-static basic_block simple_increment (struct loops *, struct loop *, rtx *,
-                                    struct loop_desc *);
+static basic_block simple_increment (struct loop *, rtx *, struct loop_desc *);
 static rtx count_strange_loop_iterations (rtx, rtx, enum rtx_code,
                                          int, rtx, enum machine_mode,
                                          enum machine_mode);
@@ -73,10 +72,10 @@ inverse (unsigned HOST_WIDEST_INT x, int mod)
 
 /* Checks whether BB is executed exactly once in each LOOP iteration.  */
 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.  */
-  if (!dominated_by_p (loops->cfg.dom, loop->latch, bb))
+  if (!dominated_by_p (CDI_DOMINATORS, loop->latch, bb))
     return false;
 
   /* And just once.  */
@@ -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
    modified.  */
 static basic_block
-simple_increment (struct loops *loops, struct loop *loop,
-                 rtx *simple_increment_regs, struct loop_desc *desc)
+simple_increment (struct loop *loop, rtx *simple_increment_regs,
+                 struct loop_desc *desc)
 {
   rtx mod_insn, mod_insn1, set, set_src, set_add;
   basic_block mod_bb, mod_bb1;
@@ -308,7 +307,7 @@ simple_increment (struct loops *loops, struct loop *loop,
   mod_bb = BLOCK_FOR_INSN (mod_insn);
 
   /* 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;
 
   /* mod_insn must be a simple increment/decrement.  */
@@ -355,7 +354,7 @@ simple_increment (struct loops *loops, struct loop *loop,
        return NULL;
 
       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;
       if (mod_bb1 == mod_bb)
        {
@@ -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
    are results of blocks_{invariant,single_set}_regs over BODY.  */
 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,
                    struct loop_desc *desc)
 {
@@ -979,7 +978,7 @@ simple_loop_exit_p (struct loops *loops, struct loop *loop, edge exit_edge,
     return false;
 
   /* 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;
 
   /* 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,
 
   /*  Var must be simply incremented or decremented in exactly one insn that
      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;
 
   /* 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;
 
   /* 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,
 /* Tests whether LOOP is simple for loop.  Returns simple loop description
    in DESC.  */
 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;
   basic_block *body;
@@ -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)
        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))
          {
            /* Prefer constant iterations; the less the better.  */
index 6fa80c7..86af4a2 100644 (file)
@@ -36,9 +36,9 @@ static void copy_loops_to (struct loops *, struct loop **, int,
                           struct loop *);
 static void loop_redirect_edge (edge, basic_block);
 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 int find_path (edge, dominance_info, basic_block **);
+static int find_path (edge, basic_block **);
 static bool alp_enum_p (basic_block, void *);
 static void add_loop (struct loops *, struct loop *);
 static void fix_loop_placements (struct loop *);
@@ -47,17 +47,15 @@ static void fix_bb_placements (struct loops *, basic_block);
 static void place_new_loop (struct loops *, struct loop *);
 static void scale_loop_frequencies (struct loop *, 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);
 
 /* Splits basic block BB after INSN, returns created edge.  Updates loops
    and dominators.  */
 edge
-split_loop_bb (struct loops *loops, basic_block bb, rtx insn)
+split_loop_bb (basic_block bb, rtx insn)
 {
   edge e;
-  basic_block *dom_bbs;
-  int n_dom_bbs, i;
 
   /* Split the block.  */
   e = split_block (bb, 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);
 
   /* Fix dominators.  */
-  add_to_dominance_info (loops->cfg.dom, e->dest);
-  n_dom_bbs = get_dominated_by (loops->cfg.dom, e->src, &dom_bbs);
-  for (i = 0; i < n_dom_bbs; i++)
-    set_immediate_dominator (loops->cfg.dom, dom_bbs[i], e->dest);
-  free (dom_bbs);
-  set_immediate_dominator (loops->cfg.dom, e->dest, e->src);
+  add_to_dominance_info (CDI_DOMINATORS, e->dest);
+  redirect_immediate_dominators (CDI_DOMINATORS, e->src, e->dest);
+  set_immediate_dominator (CDI_DOMINATORS, e->dest, e->src);
 
   return e;
 }
 
-/* Checks whether basic block BB is dominated by RPE->DOM, where
-   RPE is passed through DATA.  */
-struct rpe_data
- {
-   basic_block dom;
-   dominance_info doms;
- };
-
+/* Checks whether basic block BB is dominated by DATA.  */
 static bool
 rpe_enum_p (basic_block bb, void *data)
 {
-  struct rpe_data *rpe = data;
-  return dominated_by_p (rpe->doms, bb, rpe->dom);
+  return dominated_by_p (CDI_DOMINATORS, bb, data);
 }
 
 /* Remove basic blocks BBS from loop structure and dominance info,
    and delete them afterwards.  */
 static void
-remove_bbs (dominance_info dom, basic_block *bbs, int nbbs)
+remove_bbs (basic_block *bbs, int nbbs)
 {
   int i;
 
   for (i = 0; i < nbbs; 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]);
     }
 }
@@ -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
    path is returned.  */
 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)
     abort ();
 
   /* Find bbs in the path.  */
-  rpe.dom = e->dest;
-  rpe.doms = doms;
   *bbs = xcalloc (n_basic_blocks, sizeof (basic_block));
   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 --
@@ -353,19 +336,19 @@ remove_path (struct loops *loops, edge e)
      fix -- when e->dest has exactly one predecessor, this corresponds
      to blocks dominated by e->dest, if not, split the edge.  */
   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
      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,
      as it now has exactly one predecessor.  */
   while (e->src->loop_father->outer
-        && dominated_by_p (loops->cfg.dom,
+        && dominated_by_p (CDI_DOMINATORS,
                            e->src->loop_father->latch, e->dest))
     unloop (loops, e->src->loop_father);
 
   /* Identify the path.  */
-  nrem = find_path (e, loops->cfg.dom, &rem_bbs);
+  nrem = find_path (e, &rem_bbs);
 
   n_bord_bbs = 0;
   bord_bbs = xcalloc (n_basic_blocks, sizeof (basic_block));
@@ -397,7 +380,7 @@ remove_path (struct loops *loops, edge e)
     if (rem_bbs[i]->loop_father->header == rem_bbs[i])
       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);
 
   /* Find blocks whose dominators may be affected.  */
@@ -405,25 +388,24 @@ remove_path (struct loops *loops, edge e)
   sbitmap_zero (seen);
   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))
        continue;
       SET_BIT (seen, bb->index);
 
-      nldom = get_dominated_by (loops->cfg.dom, bb, &ldom);
-      for (j = 0; j < nldom; j++)
-       if (!dominated_by_p (loops->cfg.dom, from, ldom[j]))
-         dom_bbs[n_dom_bbs++] = ldom[j];
-      free(ldom);
+      for (ldom = first_dom_son (CDI_DOMINATORS, bb);
+          ldom;
+          ldom = next_dom_son (CDI_DOMINATORS, ldom))
+       if (!dominated_by_p (CDI_DOMINATORS, from, ldom))
+         dom_bbs[n_dom_bbs++] = ldom;
     }
 
   free (seen);
 
   /* 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);
 
   /* 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
   basic_block succ_bb = latch_edge->dest;
   basic_block pred_bb = header_edge->src;
   basic_block *dom_bbs, *body;
-  unsigned n_dom_bbs, i, j;
+  unsigned n_dom_bbs, i;
   sbitmap seen;
   struct loop *loop = xcalloc (1, sizeof (struct loop));
   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
   loop_redirect_edge (switch_bb->succ, succ_bb);
 
   /* Update dominators.  */
-  set_immediate_dominator (loops->cfg.dom, switch_bb, pred_bb);
-  set_immediate_dominator (loops->cfg.dom, loop->header, switch_bb);
-  set_immediate_dominator (loops->cfg.dom, succ_bb, switch_bb);
+  set_immediate_dominator (CDI_DOMINATORS, switch_bb, pred_bb);
+  set_immediate_dominator (CDI_DOMINATORS, loop->header, switch_bb);
+  set_immediate_dominator (CDI_DOMINATORS, succ_bb, switch_bb);
 
   /* Compute new loop.  */
   add_loop (loops, loop);
@@ -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++)
     {
-      unsigned nldom;
-      basic_block *ldom;
+      basic_block ldom;
 
-      nldom = get_dominated_by (loops->cfg.dom, body[i], &ldom);
-      for (j = 0; j < nldom; j++)
-       if (!TEST_BIT (seen, ldom[j]->index))
+      for (ldom = first_dom_son (CDI_DOMINATORS, body[i]);
+          ldom;
+          ldom = next_dom_son (CDI_DOMINATORS, ldom))
+       if (!TEST_BIT (seen, ldom->index))
          {
-           SET_BIT (seen, ldom[j]->index);
-           dom_bbs[n_dom_bbs++] = ldom[j];
+           SET_BIT (seen, ldom->index);
+           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 (seen);
@@ -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 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.  */
       if (add_irreducible_flag)
@@ -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 (new_spec_edges[SE_LATCH],
                                          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];
          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,
          redirect_edge_and_branch_force (new_spec_edges[SE_LATCH],
                                          loop->header);
          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];
        }
 
@@ -1056,7 +1037,7 @@ duplicate_loop_to_header_edge (struct loop *loop, edge e, struct loops *loops,
   
   /* Update the original loop.  */
   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)
     {
       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,
       int n_dom_bbs,j;
 
       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++)
        {
          dominated = dom_bbs[j];
          if (flow_bb_inside_loop_p (loop, dominated))
            continue;
          dom_bb = nearest_common_dominator (
-                       loops->cfg.dom, first_active[i], first_active_latch);
-          set_immediate_dominator (loops->cfg.dom, dominated, dom_bb);
+                       CDI_DOMINATORS, first_active[i], first_active_latch);
+          set_immediate_dominator (CDI_DOMINATORS, dominated, dom_bb);
        }
       free (dom_bbs);
     }
@@ -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.
    The function also updates dominators stored in DOM.  */
 static basic_block
-create_preheader (struct loop *loop, dominance_info dom, int flags)
+create_preheader (struct loop *loop, int flags)
 {
   edge e, fallthru;
   basic_block dummy;
@@ -1141,7 +1122,7 @@ create_preheader (struct loop *loop, dominance_info dom, int flags)
     if (ploop->latch == dummy)
       ploop->latch = fallthru->dest;
 
-  add_to_dominance_info (dom, fallthru->dest);
+  add_to_dominance_info (CDI_DOMINATORS, fallthru->dest);
 
   /* Redirect edges.  */
   for (e = dummy->pred; e; e = e->pred_next)
@@ -1159,15 +1140,15 @@ create_preheader (struct loop *loop, dominance_info dom, int flags)
   jump = redirect_edge_and_branch_force (e, loop->header);
   if (jump)
     {
-      add_to_dominance_info (dom, jump);
-      set_immediate_dominator (dom, jump, src);
+      add_to_dominance_info (CDI_DOMINATORS, jump);
+      set_immediate_dominator (CDI_DOMINATORS, jump, src);
       add_bb_to_loop (jump, loop);
       loop->latch = jump;
     }
 
   /* Update structures.  */
-  redirect_immediate_dominators (dom, dummy, loop->header);
-  set_immediate_dominator (dom, loop->header, dummy);
+  redirect_immediate_dominators (CDI_DOMINATORS, dummy, loop->header);
+  set_immediate_dominator (CDI_DOMINATORS, loop->header, dummy);
   loop->header->loop_father = loop;
   add_bb_to_loop (dummy, cloop);
   if (rtl_dump_file)
@@ -1184,7 +1165,7 @@ create_preheaders (struct loops *loops, int flags)
 {
   unsigned 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;
 }
 
@@ -1207,7 +1188,7 @@ force_single_succ_latches (struct loops *loops)
       for (e = loop->header->pred; e->src != loop->latch; e = e->pred_next)
        continue;
 
-      loop_split_edge_with (e, NULL_RTX, loops);
+      loop_split_edge_with (e, NULL_RTX);
     }
   loops->state |= LOOPS_HAVE_SIMPLE_LATCHES;
 }
@@ -1217,7 +1198,7 @@ force_single_succ_latches (struct loops *loops)
    be ok after this function.  The created block is placed on correct place
    in LOOPS structure and its dominator is set.  */
 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;
   struct loop *loop_c;
@@ -1231,7 +1212,7 @@ loop_split_edge_with (edge e, rtx insns, struct loops *loops)
   /* Create basic block for it.  */
 
   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);
   new_bb->flags = insns ? BB_SUPERBLOCK : 0;
 
@@ -1245,9 +1226,9 @@ loop_split_edge_with (edge e, rtx insns, struct loops *loops)
   if (insns)
     emit_insn_after (insns, BB_END (new_bb));
 
-  set_immediate_dominator (loops->cfg.dom, new_bb, src);
-  set_immediate_dominator (loops->cfg.dom, dest,
-    recount_dominator (loops->cfg.dom, dest));
+  set_immediate_dominator (CDI_DOMINATORS, new_bb, src);
+  set_immediate_dominator (CDI_DOMINATORS, dest,
+                          recount_dominator (CDI_DOMINATORS, dest));
 
   if (dest->loop_father->latch == src)
     dest->loop_father->latch = new_bb;
index 38182ef..1b6c9fd 100644 (file)
 #include "errors.h"
 #include "et-forest.h"
 
-struct dominance_info
-{
-  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))
+/* Whether the dominators and the postdominators are available.  */
+enum dom_state dom_computed[2];
 
 /* 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
@@ -124,7 +116,7 @@ static void compress (struct dom_info *, TBB);
 static TBB eval (struct dom_info *, TBB);
 static void link_roots (struct dom_info *, TBB, TBB);
 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,
    for aesthetic reasons.  */
@@ -526,172 +518,250 @@ calc_idoms (struct dom_info *di, enum cdi_direction reverse)
       di->dom[v] = di->dom[di->dom[v]];
 }
 
-/* The main entry point into this module.  IDOM is an integer array with room
-   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
-   know post-dominators.
+/* Assign dfs numbers starting from NUM to NODE and its sons.  */
+
+static void
+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
-   of basic block i, and DOMS[i] will have set bit j if basic block j is a
-   (post)dominator for block i.
+  node->dfs_num_out = (*num)++;
+}
 
-   Either IDOM or DOMS may be NULL (meaning the caller is not interested in
-   immediate resp. all dominators).  */
+/* Compute the data neccesary for fast resolving of dominator queries in a
+   static dominator tree.  */
 
-dominance_info
-calculate_dominance_info (enum cdi_direction reverse)
+static void
+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;
-  dominance_info info;
   basic_block b;
 
-  /* Allocate structure for dominance information.  */
-  info = xmalloc (sizeof (struct dominance_info));
-  info->forest = et_forest_create ();
-  VARRAY_GENERIC_PTR_INIT (info->varray, last_basic_block + 3, "dominance info");
+  if (dom_computed[dir] == DOM_OK)
+    return;
 
-  /* Add the two well-known basic blocks.  */
-  SET_BB_NODE (info, ENTRY_BLOCK_PTR, et_forest_add_node (info->forest,
-                                                         ENTRY_BLOCK_PTR));
-  SET_BB_NODE (info, EXIT_BLOCK_PTR, et_forest_add_node (info->forest,
-                                                        EXIT_BLOCK_PTR));
-  FOR_EACH_BB (b)
-    SET_BB_NODE (info, b, et_forest_add_node (info->forest, b));
+  if (dom_computed[dir] != DOM_NO_FAST_QUERY)
+    {
+      if (dom_computed[dir] != DOM_NONE)
+      free_dominance_info (dir);
 
-  init_dom_info (&di);
-  calc_dfs_tree (&di, reverse);
-  calc_idoms (&di, reverse);
+      FOR_ALL_BB (b)
+       {
+         b->dom[dir] = et_new_tree (b);
+       }
 
+      init_dom_info (&di);
+      calc_dfs_tree (&di, dir);
+      calc_idoms (&di, dir);
 
-  FOR_EACH_BB (b)
-    {
-      TBB d = di.dom[di.dfs_order[b->index]];
+      FOR_EACH_BB (b)
+       {
+         TBB d = di.dom[di.dfs_order[b->index]];
+
+         if (di.dfs_to_bb[d])
+           et_set_father (b->dom[dir], di.dfs_to_bb[d]->dom[dir]);
+       }
 
-      if (di.dfs_to_bb[d])
-        et_forest_add_edge (info->forest, BB_NODE (info, di.dfs_to_bb[d]), BB_NODE (info, b));
+      free_dom_info (&di);
+      dom_computed[dir] = DOM_NO_FAST_QUERY;
     }
 
-  free_dom_info (&di);
-  return info;
+  compute_dom_fast_query (dir);
 }
 
-/* Free dominance information.  */
+/* Free dominance information for direction DIR.  */
 void
-free_dominance_info (dominance_info info)
+free_dominance_info (enum cdi_direction dir)
 {
   basic_block bb;
 
-  /* Allow users to create new basic block without setting up the dominance
-     information for them.  */
-  FOR_EACH_BB (bb)
-    if (bb->index < (int)(info->varray->num_elements - 2)
-       && BB_NODE (info, bb))
-      delete_from_dominance_info (info, bb);
-  delete_from_dominance_info (info, ENTRY_BLOCK_PTR);
-  delete_from_dominance_info (info, EXIT_BLOCK_PTR);
-  et_forest_delete (info->forest);
-  VARRAY_GROW (info->varray, 0);
-  free (info);
+  if (!dom_computed[dir])
+    return;
+
+  FOR_ALL_BB (bb)
+    {
+      delete_from_dominance_info (dir, bb);
+    }
+
+  dom_computed[dir] = DOM_NONE;
 }
 
 /* Return the immediate dominator of basic block BB.  */
 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,
-                              et_forest_parent (dom->forest,
-                                                BB_NODE (dom, bb)));
+  struct et_node *node = bb->dom[dir];
+
+  if (!dom_computed[dir])
+    abort ();
+
+  if (!node->father)
+    return NULL;
+
+  return node->father->data; 
 }
 
 /* Set the immediate dominator of the block possibly removing
    existing edge.  NULL can be used to remove any edge.  */
 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;
-  et_forest_node_t bb_node = BB_NODE (dom, bb);
+  struct et_node *node = bb->dom[dir];
+
+  if (!dom_computed[dir])
+    abort ();
 
-  aux_bb_node = et_forest_parent (dom->forest, bb_node);
-  if (aux_bb_node)
-    et_forest_remove_edge (dom->forest, aux_bb_node, bb_node);
-  if (dominated_by != NULL)
+  if (node->father)
     {
-      if (bb == dominated_by)
-       abort ();
-      if (!et_forest_add_edge (dom->forest, BB_NODE (dom, dominated_by), bb_node))
-       abort ();
+      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
-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;
 }
 
 /* Redirect all edges pointing to BB to TO.  */
 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));
-  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;
+  struct et_node *bb_node = bb->dom[dir], *to_node = to->dom[dir], *son;
+
+  if (!dom_computed[dir])
+    abort ();
 
-  for (i = 0; i < n; i++)
+  if (!bb_node->son)
+    return;
+
+  while (bb_node->son)
     {
-      et_forest_remove_edge (dom->forest, node, bbs[i]);
-      et_forest_add_edge (dom->forest, node2, bbs[i]);
+      son = bb_node->son;
+
+      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.  */
 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)
     return bb2;
   if (!bb2)
     return bb1;
-  return et_forest_node_value (dom->forest,
-                              et_forest_common_ancestor (dom->forest,
-                                                         BB_NODE (dom, bb1),
-                                                         BB_NODE (dom,
-                                                                  bb2)));
+
+  return et_nca (bb1->dom[dir], bb2->dom[dir])->data;
 }
 
 /* Return TRUE in case BB1 is dominated by BB2.  */
 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.  */
 void
-verify_dominators (dominance_info dom)
+verify_dominators (enum cdi_direction dir)
 {
   int err = 0;
   basic_block bb;
 
+  if (!dom_computed[dir])
+    abort ();
+
   FOR_EACH_BB (bb)
     {
       basic_block dom_bb;
 
-      dom_bb = recount_dominator (dom, bb);
-      if (dom_bb != get_immediate_dominator (dom, bb))
+      dom_bb = recount_dominator (dir, bb);
+      if (dom_bb != get_immediate_dominator (dir, bb))
        {
          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;
        }
     }
@@ -701,15 +771,18 @@ verify_dominators (dominance_info dom)
 
 /* Recount dominator of BB.  */
 basic_block
-recount_dominator (dominance_info dom, basic_block bb)
+recount_dominator (enum cdi_direction dir, basic_block bb)
 {
    basic_block dom_bb = NULL;
    edge e;
 
+  if (!dom_computed[dir])
+    abort ();
+
    for (e = bb->pred; e; e = e->pred_next)
      {
-       if (!dominated_by_p (dom, e->src, bb))
-         dom_bb = nearest_common_dominator (dom, dom_bb, e->src);
+       if (!dominated_by_p (dir, e->src, bb))
+         dom_bb = nearest_common_dominator (dir, dom_bb, e->src);
      }
 
    return dom_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
    and not to grow further.  */
 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;
   basic_block old_dom, new_dom;
 
+  if (!dom_computed[dir])
+    abort ();
+
   while (changed)
     {
       changed = 0;
       for (i = 0; i < n; i++)
        {
-         old_dom = get_immediate_dominator (dom, bbs[i]);
-         new_dom = recount_dominator (dom, bbs[i]);
+         old_dom = get_immediate_dominator (dir, bbs[i]);
+         new_dom = recount_dominator (dir, bbs[i]);
          if (old_dom != new_dom)
            {
              changed = 1;
-             set_immediate_dominator (dom, bbs[i], new_dom);
+             set_immediate_dominator (dir, bbs[i], new_dom);
            }
        }
     }
 }
 
 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);
-#ifdef ENABLE_CHECKING
-  if (BB_NODE (dom, bb))
+  if (!dom_computed[dir])
     abort ();
-#endif
-  SET_BB_NODE (dom, bb, et_forest_add_node (dom->forest, bb));
+
+  if (bb->dom[dir])
+    abort ();
+
+  bb->dom[dir] = et_new_tree (bb);
+
+  if (dom_computed[dir] == DOM_OK)
+    dom_computed[dir] = DOM_NO_FAST_QUERY;
 }
 
 void
-delete_from_dominance_info (dominance_info dom, basic_block bb)
+delete_from_dominance_info (enum cdi_direction dir, basic_block bb)
+{
+  if (!dom_computed[dir])
+    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)
 {
-  et_forest_remove_node (dom->forest, BB_NODE (dom, bb));
-  SET_BB_NODE (dom, bb, NULL);
+  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
-debug_dominance_info (dominance_info dom)
+debug_dominance_info (enum cdi_direction dir)
 {
   basic_block bb, bb2;
   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);
 }
index ffdce1d..ea7793f 100644 (file)
@@ -30,638 +30,714 @@ Boston, MA 02111-1307, USA.
 #include "et-forest.h"
 #include "alloc-pool.h"
 
-struct et_forest_occurrence;
-typedef struct et_forest_occurrence* et_forest_occurrence_t;
+/* We do not enable this with ENABLE_CHECKING, since it is awfully slow.  */
+#undef DEBUG_ET
 
-/* The ET-forest type.  */
-struct et_forest
-{
-  /* Linked list of nodes is used to destroy the structure.  */
-  int nnodes;
-  alloc_pool node_pool;
-  alloc_pool occur_pool;
-};
+#ifdef DEBUG_ET
+#include "basic-block.h"
+#endif
 
-/* Single occurrence of node in ET-forest.
-   A single node may have multiple occurrences.
- */
-struct et_forest_occurrence
+/* The occurence of a node in the et tree.  */
+struct et_occ
 {
-  /* Parent in the splay-tree.  */
-  et_forest_occurrence_t parent;
+  struct et_node *of;          /* The node.  */
+
+  struct et_occ *parent;       /* Parent in the splay-tree.  */
+  struct et_occ *prev;         /* Left son in the splay-tree.  */
+  struct et_occ *next;         /* Right son in the splay-tree.  */
+
+  int depth;                   /* The depth of the node is the sum of depth
+                                  fields on the path to the root.  */
+  int min;                     /* The minimum value of the depth in the subtree
+                                  is obtained by adding sum of depth fields
+                                  on the path to the root.  */
+  struct et_occ *min_occ;      /* The occurence in the subtree with the minimal
+                                  depth.  */
+};
 
-  /* Children in the splay-tree.  */
-  et_forest_occurrence_t left, right;
+static alloc_pool et_nodes;
+static alloc_pool et_occurences;
 
-  /* Counts of vertices in the two splay-subtrees.  */
-  int count_left, count_right;
+/* Changes depth of OCC to D.  */
 
-  /* Next occurrence of this node in the sequence.  */
-  et_forest_occurrence_t next;
+static inline void
+set_depth (struct et_occ *occ, int d)
+{
+  if (!occ)
+    return;
 
-  /* The node, which this occurrence is of.  */
-  et_forest_node_t node;
-};
+  occ->min += d - occ->depth;
+  occ->depth = d;
+}
 
+/* Adds D to the depth of OCC.  */
 
-/* ET-forest node.  */
-struct et_forest_node
+static inline void
+set_depth_add (struct et_occ *occ, int d)
 {
-  et_forest_t forest;
-  void *value;
-
-  /* First and last occurrence of this node in the sequence.  */
-  et_forest_occurrence_t first, last;
-};
+  if (!occ)
+    return;
 
+  occ->min += d;
+  occ->depth += d;
+}
 
-static et_forest_occurrence_t splay (et_forest_occurrence_t);
-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);
+/* Sets prev field of OCC to P.  */
 
-/* Return leftmost node present in the tree roted by OCC.  */
-static inline et_forest_occurrence_t
-find_leftmost_node (et_forest_occurrence_t occ)
+static inline void
+set_prev (struct et_occ *occ, struct et_occ *t)
 {
-  while (occ->left)
-    occ = occ->left;
+#ifdef DEBUG_ET
+  if (occ == t)
+    abort ();
+#endif
 
-  return occ;
+  occ->prev = t;
+  if (t)
+    t->parent = occ;
 }
 
-/* Return rightmost node present in the tree roted by OCC.  */
-static inline et_forest_occurrence_t
-find_rightmost_node (et_forest_occurrence_t occ)
+/* Sets next field of OCC to P.  */
+
+static inline void
+set_next (struct et_occ *occ, struct et_occ *t)
 {
-  while (occ->right)
-    occ = occ->right;
-  return occ;
+#ifdef DEBUG_ET
+  if (occ == t)
+    abort ();
+#endif
+
+  occ->next = t;
+  if (t)
+    t->parent = occ;
 }
 
+/* Recompute minimum for occurence OCC.  */
 
-/* Operation splay for splay tree structure representing occurrences.  */
-static et_forest_occurrence_t
-splay (et_forest_occurrence_t node)
+static inline void
+et_recomp_min (struct et_occ *occ)
 {
-  et_forest_occurrence_t parent;
-  et_forest_occurrence_t grandparent;
+  struct et_occ *mson = occ->prev;
 
-  while (1)
-    {
-      parent = node->parent;
+  if (!mson
+      || (occ->next
+         && mson->min > occ->next->min))
+      mson = occ->next;
 
-      if (! parent)
-       return node;  /* node == root.  */
+  if (mson && mson->min < 0)
+    {
+      occ->min = mson->min + occ->depth;
+      occ->min_occ = mson->min_occ;
+    }
+  else
+    {
+      occ->min = occ->depth;
+      occ->min_occ = occ;
+    }
+}
 
-      grandparent = parent->parent;
+#ifdef DEBUG_ET
+/* Checks whether neighbourhood of OCC seems sane.  */
 
-      if (! grandparent)
-       break;
+static void
+et_check_occ_sanity (struct et_occ *occ)
+{
+  if (!occ)
+    return;
 
-      /* Now there are four possible combinations:  */
+  if (occ->parent == occ)
+    abort ();
 
-      if (node == parent->left)
-       {
-         if (parent == grandparent->left)
-           {
-             et_forest_occurrence_t node1, node2;
-             int count1, count2;
-
-             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
-           {
-             /* parent == grandparent->right && node == parent->left*/
-             et_forest_occurrence_t node1, node2;
-             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
-       {
-         /* node == parent->right.  */
-         if (parent == grandparent->left)
-           {
-             et_forest_occurrence_t node1, node2;
-             int count1, count2;
-
-             node1 = node->left;
-             count1 = node->count_left;
-             node2 = node->right;
-             count2 = node->count_right;
-
-             parent->right = node1;
-             parent->count_right = count1;
-             if (node1)
-               node1->parent = parent;
-             grandparent->left = node2;
-             grandparent->count_left = count2;
-             if (node2)
-               node2->parent = grandparent;
-             node->left = parent;
-             node->count_left = parent->count_left + count1 + 1;
-             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)
-                   node->parent->left = node;
-                 else
-                   node->parent->right = node;
-               }
-           }
-         else
-           {
-             /* 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)
-                   node->parent->left = node;
-                 else
-                   node->parent->right = node;
-               }
-           }
-       }
+  if (occ->prev == occ)
+    abort ();
 
-    }
+  if (occ->next == occ)
+    abort ();
 
-  /* parent == root.  */
-  /* There are two possible combinations:  */
+  if (occ->next && occ->next == occ->prev)
+    abort ();
 
-  if (node == parent->left)
+  if (occ->next)
     {
-      et_forest_occurrence_t node1;
-      int count1;
-
-      node1 = node->right;
-      count1 = node->count_right;
-
-      parent->left = node1;
-      parent->count_left = count1;
-      if (node1)
-       node1->parent = parent;
-      node->right = parent;
-      node->count_right = parent->count_right + 1 + count1;
-      node->parent = parent->parent;  /* the same as = 0;  */
-      parent->parent = node;
-
-      if (node->parent)
-       {
-         if (node->parent->left == parent)
-           node->parent->left = node;
-         else
-           node->parent->right = node;
-       }
+      if (occ->next == occ->parent)
+       abort ();
+
+      if (occ->next->parent != occ)
+       abort ();
     }
-  else
+
+  if (occ->prev)
     {
-      /* node == parent->right.  */
-      et_forest_occurrence_t node1;
-      int count1;
-
-      node1 = node->left;
-      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)
-           node->parent->left = node;
-         else
-           node->parent->right = node;
-       }
+      if (occ->prev == occ->parent)
+       abort ();
+
+      if (occ->prev->parent != occ)
+       abort ();
     }
 
-  return node;
+  if (occ->parent
+      && occ->parent->prev != occ
+      && occ->parent->next != occ)
+    abort ();
 }
 
-/* Remove all occurrences of the given node before destroying the node.  */
+/* Checks whether tree rooted at OCC is sane.  */
+
 static void
-remove_all_occurrences (et_forest_t forest, et_forest_node_t forest_node)
+et_check_sanity (struct et_occ *occ)
 {
-  et_forest_occurrence_t first = forest_node->first;
-  et_forest_occurrence_t last = forest_node->last;
-  et_forest_occurrence_t node;
+  et_check_occ_sanity (occ);
+  if (occ->prev)
+    et_check_sanity (occ->prev);
+  if (occ->next)
+    et_check_sanity (occ->next);
+}
 
-  splay (first);
+/* Checks whether tree containing OCC is sane.  */
 
-  if (first->left)
-    first->left->parent = 0;
-  if (first->right)
-    first->right->parent = 0;
+static void
+et_check_tree_sanity (struct et_occ *occ)
+{
+  while (occ->parent)
+    occ = occ->parent;
 
-  if (last != first)
-    {
-      splay (last);
+  et_check_sanity (occ);
+}
 
-      if (last->left)
-       last->left->parent = 0;
-      if (last->right)
-       last->right->parent = 0;
-    }
+/* For recording the paths.  */
 
-  if (last->right && first->left) /* actually, first->left would suffice.  */
-    {
-      /* Need to join them.  */
-      et_forest_occurrence_t prev_node, next_node;
-
-      prev_node = splay (find_rightmost_node (first->left));
-      next_node = splay (find_leftmost_node (last->right));
-      /* prev_node and next_node are consecutive occurrences
-        of the same node.  */
-      if (prev_node->next != next_node)
-       abort ();
+static int len;
+static void *datas[100000];
+static int depths[100000];
 
-      prev_node->right = next_node->right;
-      prev_node->count_right = next_node->count_right;
-      prev_node->next = next_node->next;
-      if (prev_node->right)
-       prev_node->right->parent = prev_node;
+/* Records the path represented by OCC, with depth incremented by DEPTH.  */
 
-      if (prev_node->node->last == next_node)
-       prev_node->node->last = prev_node;
+static int
+record_path_before_1 (struct et_occ *occ, int depth)
+{
+  int mn, m;
 
-      pool_free (forest->occur_pool, next_node);
+  depth += occ->depth;
+  mn = depth;
+
+  if (occ->prev)
+    {
+      m = record_path_before_1 (occ->prev, depth); 
+      if (m < mn)
+       mn = m;
     }
 
-  if (first != last)
+  fprintf (stderr, "%d (%d); ", ((basic_block) occ->of->data)->index, depth);
+  depths[len] = depth;
+  datas[len] = occ->of;
+  len++;
+
+  if (occ->next)
     {
-      node = first->next;
+      m = record_path_before_1 (occ->next, depth);
+      if (m < mn)
+       mn = m;
+    }
 
-      while (node != last)
-       {
-         et_forest_occurrence_t next_node;
+  if (mn != occ->min + depth - occ->depth)
+    abort ();
 
-         splay (node);
+  return mn;
+}
 
-         if (node->left)
-           node->left->parent = 0;
-         if (node->right)
-           node->right->parent = 0;
+/* Records the path represented by a tree containing OCC.  */
 
-         next_node = node->next;
-         pool_free (forest->occur_pool, node);
-         node = next_node;
-       }
-    }
+static void
+record_path_before (struct et_occ *occ)
+{
+  while (occ->parent)
+    occ = occ->parent;
 
-  pool_free (forest->occur_pool, first);
-  if (first != last)
-    pool_free (forest->occur_pool, last);
+  len = 0;
+  record_path_before_1 (occ, 0);
+  fprintf (stderr, "\n");
 }
 
-/* Calculate ET value of the given node.  */
-static inline int
-calculate_value (et_forest_occurrence_t node)
+/* Checks whether the path represented by OCC, with depth incremented by DEPTH,
+   was not changed since the last recording.  */
+
+static int
+check_path_after_1 (struct et_occ *occ, int depth)
 {
-  int value = node->count_left;
+  int mn, m;
+
+  depth += occ->depth;
+  mn = depth;
 
-  while (node->parent)
+  if (occ->next)
     {
-      if (node == node->parent->right)
-       value += node->parent->count_left + 1;
+      m = check_path_after_1 (occ->next, depth); 
+      if (m < mn)
+       mn =  m;
+    }
 
-      node = node->parent;
+  len--;
+  if (depths[len] != depth
+      || datas[len] != occ->of)
+    abort ();
+
+  if (occ->prev)
+    {
+      m = check_path_after_1 (occ->prev, depth);
+      if (m < mn)
+       mn =  m;
     }
 
-  return value;
+  if (mn != occ->min + depth - occ->depth)
+    abort ();
+
+  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 ();
+}
 
+#endif
 
+/* Splay the occurence OCC to the root of the tree.  */
 
-/* Create ET-forest structure.  */
-et_forest_t
-et_forest_create (void)
+static inline void
+et_splay (struct et_occ *occ)
 {
-  et_forest_t forest = xmalloc (sizeof (struct et_forest));
+  struct et_occ *f, *gf, *ggf;
+  int occ_depth, f_depth, gf_depth;
+
+#ifdef DEBUG_ET
+  record_path_before (occ);
+  et_check_tree_sanity (occ);
+#endif
+  while (occ->parent)
+    {
+      occ_depth = occ->depth;
 
-  forest->nnodes = 0;
-  forest->occur_pool = create_alloc_pool ("et_forest_occurrence pool", sizeof (struct et_forest_occurrence), 300);
-  forest->node_pool = create_alloc_pool ("et_forest_node pool", sizeof (struct et_forest_node), 300);
-  return forest;
-}
+      f = occ->parent;
+      f_depth = f->depth;
 
+      gf = f->parent;
 
+      if (!gf)
+       {
+         set_depth_add (occ, f_depth);
+         occ->min_occ = f->min_occ;
+         occ->min = f->min;
 
-/* Deallocate the structure.  */
-void
-et_forest_delete (et_forest_t forest)
+         if (f->prev == occ)
+           {
+             /* 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;
+       }
+
+      gf_depth = gf->depth;
+
+      set_depth_add (occ, f_depth + gf_depth);
+      occ->min_occ = gf->min_occ;
+      occ->min = gf->min;
+
+      ggf = gf->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);
+           }
+       }
+
+      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.  */
+
+static struct et_occ *
+et_new_occ (struct et_node *node)
 {
-  if (forest->nnodes)
-    abort ();
-  free_alloc_pool (forest->occur_pool);
-  free_alloc_pool (forest->node_pool);
-  free (forest);
+  struct et_occ *nw;
+  
+  if (!et_occurences)
+    et_occurences = create_alloc_pool ("et_occ pool", sizeof (struct et_occ), 300);
+  nw = pool_alloc (et_occurences);
+
+  nw->of = node;
+  nw->parent = NULL;
+  nw->prev = NULL;
+  nw->next = NULL;
+
+  nw->depth = 0;
+  nw->min_occ = nw;
+  nw->min = 0;
+
+  return nw;
 }
 
-/* Create new node with VALUE and return the edge.
-   Return NULL when memory allocation failed.  */
-et_forest_node_t
-et_forest_add_node (et_forest_t forest, void *value)
+/* Create a new et tree containing DATA.  */
+
+struct et_node *
+et_new_tree (void *data)
 {
-  /* 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;
+  struct et_node *nw;
+  
+  if (!et_nodes)
+    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;
+
+  return nw;
 }
 
-/* Add new edge to the tree, return 1 if successful.
-   0 indicates that creation of the edge will close the cycle in graph.  */
-int
-et_forest_add_edge (et_forest_t forest ATTRIBUTE_UNUSED,
-                   et_forest_node_t parent_node, et_forest_node_t child_node)
+/* Releases et tree T.  */
+
+void
+et_free_tree (struct et_node *t)
 {
-  et_forest_occurrence_t new_occ, parent_occ, child_occ;
+  while (t->son)
+    et_split (t->son);
 
-  if (! parent_node || ! child_node)
-    abort ();
+  if (t->father)
+    et_split (t);
 
-  parent_occ = parent_node->first;
-  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;
+  pool_free (et_occurences, t->rightmost_occ);
+  pool_free (et_nodes, t);
 }
 
-/* Remove NODE from the tree and all connected edges.  */
+/* Sets father of et tree T to FATHER.  */
+
 void
-et_forest_remove_node (et_forest_t forest, et_forest_node_t node)
+et_set_father (struct et_node *t, struct et_node *father)
 {
-  remove_all_occurrences (forest, node);
-  forest->nnodes--;
+  struct et_node *left, *right;
+  struct et_occ *rmost, *left_part, *new_f_occ, *p;
 
-  pool_free (forest->node_pool, node);
-}
+  /* Update the path represented in the splay tree.  */
+  new_f_occ = et_new_occ (father);
 
-/* Remove edge from the tree, return 1 if successful,
-   0 indicates nonexisting edge.  */
-int
-et_forest_remove_edge (et_forest_t forest ATTRIBUTE_UNUSED,
-                      et_forest_node_t parent_node,
-                      et_forest_node_t child_node)
-{
-  et_forest_occurrence_t parent_pre_occ, parent_post_occ;
+  rmost = father->rightmost_occ;
+  et_splay (rmost);
 
-  splay (child_node->first);
+  left_part = rmost->prev;
 
-  if (! child_node->first->left)
-    return 0;
+  p = t->rightmost_occ;
+  et_splay (p);
 
-  parent_pre_occ = find_rightmost_node (child_node->first->left);
-  if (parent_pre_occ->node != parent_node)
-    abort ();
+  set_prev (new_f_occ, left_part);
+  set_next (new_f_occ, p);
+
+  p->depth++;
+  p->min++;
+  et_recomp_min (new_f_occ);
 
-  splay (parent_pre_occ);
-  parent_pre_occ->right->parent = 0;
+  set_prev (rmost, new_f_occ);
 
-  parent_post_occ = parent_pre_occ->next;
-  splay (parent_post_occ);
+  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;
+    }
 
-  parent_post_occ->left->parent = 0;
+  t->parent_occ = new_f_occ;
 
-  parent_pre_occ->right = parent_post_occ->right;
-  parent_pre_occ->count_right = parent_post_occ->count_right;
-  if (parent_post_occ->right)
-    parent_post_occ->right->parent = parent_pre_occ;
+  /* Update the tree.  */
+  t->father = father;
+  right = father->son;
+  if (right)
+    left = right->left;
+  else
+    left = right = t;
 
-  parent_pre_occ->next = parent_post_occ->next;
+  left->right = t;
+  right->left = t;
+  t->left = left;
+  t->right = right;
 
-  if (parent_post_occ == parent_node->last)
-    parent_node->last = parent_pre_occ;
+  father->son = t;
 
-  pool_free (forest->occur_pool, parent_post_occ);
-  return 1;
+#ifdef DEBUG_ET
+  et_check_tree_sanity (rmost);
+  record_path_before (rmost);
+#endif
 }
 
-/* Return the parent of the NODE if any, NULL otherwise.  */
-et_forest_node_t
-et_forest_parent (et_forest_t forest ATTRIBUTE_UNUSED, et_forest_node_t node)
+/* Splits the edge from T to its father.  */
+
+void
+et_split (struct et_node *t)
 {
-  splay (node->first);
+  struct et_node *father = t->father;
+  struct et_occ *r, *l, *rmost, *p_occ;
 
-  if (node->first->left)
-    return find_rightmost_node (node->first->left)->node;
-  else
-    return 0;
-}
+  /* Update the path represented by the splay tree.  */
+  rmost = t->rightmost_occ;
+  et_splay (rmost);
 
+  for (r = rmost->next; r->prev; r = r->prev)
+    continue;
+  et_splay (r); 
 
-/* Return nearest common ancestor of NODE1 and NODE2.
-   Return NULL of they are in different trees.  */
-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;
-  et_forest_node_t ancestor;
+  r->prev->parent = NULL;
+  p_occ = t->parent_occ;
+  et_splay (p_occ);
+  t->parent_occ = NULL;
 
-  if (node1 == node2)
-    return node1;
+  l = p_occ->prev;
+  p_occ->next->parent = NULL;
 
-  if (! node1 || ! node2)
-    abort ();
+  set_prev (r, l);
 
-  splay (node1->first);
-  splay (node2->first);
+  et_recomp_min (r);
 
-  if (! node1->first->parent)  /* The two vertices are in different trees.  */
-    return 0;
+  et_splay (rmost);
+  rmost->depth = 0;
+  rmost->min = 0;
 
-  value2 = calculate_value (node2->first);
-  value1 = calculate_value (node1->first);
+  pool_free (et_occurences, p_occ);
 
-  if (value1 < value2)
+  /* Update the tree.  */
+  if (father->son == t)
+    father->son = t->right;
+  if (father->son == t)
+    father->son = NULL;
+  else
     {
-      ancestor = node1;
-      max_value = value2;
+      t->left->right = t->right;
+      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
     {
-      ancestor = node2;
-      max_value = value1;
+      ret = o2->prev;
+
+      set_next (o1, o2);
+      if (l)
+       l->parent = o1;
     }
 
-  while (calculate_value (ancestor->last) < max_value)
+  if (0 < o2->depth)
     {
-      /* Find parent node.  */
-      splay (ancestor->first);
-      ancestor = find_rightmost_node (ancestor->first->left) ->node;
+      om = o1;
+      mn = o1->depth;
+    }
+  else
+    {
+      om = o2;
+      mn = o2->depth + o1->depth;
     }
 
-  return ancestor;
-}
+#ifdef DEBUG_ET
+  et_check_tree_sanity (o2);
+#endif
 
-/* Return the value pointer of node set during it's creation.  */
-void *
-et_forest_node_value (et_forest_t forest ATTRIBUTE_UNUSED,
-                     et_forest_node_t node)
-{
-  /* Alloc threading NULL as a special node of the forest.  */
-  if (!node)
-    return NULL;
-  return node->value;
+  if (ret && ret->min + o1->depth + o2->depth < mn)
+    return ret->min_occ->of;
+  else
+    return om->of;
 }
 
-/* Find all sons of NODE and store them into ARRAY allocated by the caller.
-   Return number of nodes found.  */
-int
-et_forest_enumerate_sons (et_forest_t forest ATTRIBUTE_UNUSED,
-                         et_forest_node_t node, et_forest_node_t *array)
+/* Checks whether the node UP is an ancestor of the node DOWN.  */
+
+bool
+et_below (struct et_node *down, struct et_node *up)
 {
-  int n = 0;
-  et_forest_occurrence_t occ = node->first, stop = node->last, occ1;
+  struct et_occ *u = up->rightmost_occ, *d = down->rightmost_occ;
+  struct et_occ *l, *r;
+
+  if (up == down)
+    return true;
+
+  et_splay (u);
+  l = u->prev;
+  r = u->next;
+
+  if (!l)
+    return false;
+
+  l->parent = NULL;
+
+  if (r)
+    r->parent = NULL;
 
-  /* Parent is the rightmost node of the left successor.
-     Look for all occurrences having no right successor
-     and lookup the sons.  */
-  while (occ != stop)
+  et_splay (d);
+
+  if (l == d || l->parent != NULL)
     {
-      splay (occ);
-      if (occ->right)
-       {
-          occ1 = find_leftmost_node (occ->right);
-         if (occ1->node->first == occ1)
-           array[n++] = occ1->node;
-       }
-      occ = occ->next;
+      if (r)
+       r->parent = u;
+      set_prev (u, d);
+#ifdef DEBUG_ET
+      et_check_tree_sanity (u);
+#endif
     }
-  return n;
+  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;
+    }
+
+  if (0 >= d->depth)
+    return false;
+
+  return !d->next || d->next->min + d->depth >= 0;
 }
index f646d59..833146d 100644 (file)
@@ -55,26 +55,28 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.  */
 extern "C" {
 #endif /* __cplusplus */
 
-typedef struct et_forest *et_forest_t;
-typedef struct et_forest_node *et_forest_node_t;
-
-extern et_forest_t et_forest_create (void);
-
-extern void et_forest_delete (et_forest_t);
-
-extern et_forest_node_t et_forest_add_node (et_forest_t, void *);
-extern int et_forest_add_edge (et_forest_t, et_forest_node_t,
-                              et_forest_node_t);
-extern void et_forest_remove_node (et_forest_t, et_forest_node_t);
-extern int et_forest_remove_edge (et_forest_t, et_forest_node_t,
-                                 et_forest_node_t);
-extern et_forest_node_t et_forest_parent (et_forest_t, et_forest_node_t);
-extern et_forest_node_t et_forest_common_ancestor (et_forest_t,
-                                                  et_forest_node_t,
-                                                  et_forest_node_t);
-extern void * et_forest_node_value (et_forest_t, et_forest_node_t);
-extern int et_forest_enumerate_sons (et_forest_t, et_forest_node_t,
-                                    et_forest_node_t *);
+/* The node representing the node in an et tree.  */
+struct et_node
+{
+  void *data;                  /* The data represented by the node.  */
+
+  int dfs_num_in, dfs_num_out; /* Number of the node in the dfs ordering.  */
+
+  struct et_node *father;      /* Father of the node.  */
+  struct et_node *son;         /* The first of the sons of the node.  */
+  struct et_node *left;
+  struct et_node *right;       /* The brothers of the node.  */
+
+  struct et_occ *rightmost_occ;        /* The rightmost occurence.  */
+  struct et_occ *parent_occ;   /* The occurence of the parent node.  */
+};
+
+struct et_node *et_new_tree (void *data);
+void et_free_tree (struct et_node *);
+void et_set_father (struct et_node *, struct et_node *);
+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
 }
index 30ede39..1da182a 100644 (file)
@@ -6408,8 +6408,6 @@ allocate_struct_function (tree fndecl)
   DECL_SAVED_INSNS (fndecl) = cfun;
   cfun->decl = fndecl;
 
-  current_function_name = (*lang_hooks.decl_printable_name) (fndecl, 2);
-
   result = DECL_RESULT (fndecl);
   if (aggregate_value_p (result, fndecl))
     {
index 89a1465..a8c5233 100644 (file)
@@ -183,9 +183,6 @@ struct function GTY(())
 
   /* For function.c.  */
 
-  /* Name of this function.  */
-  const char *name;
-
   /* Points to the FUNCTION_DECL of this function.  */
   tree decl;
 
@@ -534,7 +531,6 @@ extern int virtuals_instantiated;
 extern int trampolines_created;
 
 /* 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_returns_struct (cfun->returns_struct)
 #define current_function_returns_pcc_struct (cfun->returns_pcc_struct)
index b52a083..cf845af 100644 (file)
@@ -161,6 +161,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "basic-block.h"
 #include "output.h"
 #include "function.h"
+#include "langhooks.h"
 #include "expr.h"
 #include "except.h"
 #include "ggc.h"
@@ -855,7 +856,8 @@ gcse_main (rtx f, FILE *file)
   if (file)
     {
       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",
               pass, pass > 1 ? "es" : "", max_pass_bytes);
     }
@@ -3614,7 +3616,8 @@ one_classic_gcse_pass (int pass)
     {
       fprintf (gcse_file, "\n");
       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);
     }
 
@@ -4686,7 +4689,8 @@ one_cprop_pass (int pass, int cprop_jumps, int bypass_jumps)
   if (gcse_file)
     {
       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",
               const_prop_count, copy_prop_count);
     }
@@ -5788,7 +5792,8 @@ one_pre_gcse_pass (int pass)
   if (gcse_file)
     {
       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",
               gcse_subst_count, gcse_create_count);
     }
@@ -6182,9 +6187,6 @@ static sbitmap *hoist_vbeout;
 /* Hoistable expressions.  */
 static sbitmap *hoist_exprs;
 
-/* Dominator bitmaps.  */
-dominance_info dominators;
-
 /* ??? We could compute post dominators and run this algorithm in
    reverse to perform tail merging, doing so would probably be
    more effective than the tail merging code in jump.c.
@@ -6221,7 +6223,7 @@ free_code_hoist_mem (void)
   sbitmap_vector_free (hoist_exprs);
   sbitmap_vector_free (transpout);
 
-  free_dominance_info (dominators);
+  free_dominance_info (CDI_DOMINATORS);
 }
 
 /* Compute the very busy expressions at entry/exit from each block.
@@ -6270,7 +6272,7 @@ compute_code_hoist_data (void)
   compute_local_properties (transp, comp, antloc, &expr_hash_table);
   compute_transpout ();
   compute_code_hoist_vbeinout ();
-  dominators = calculate_dominance_info (CDI_DOMINATORS);
+  calculate_dominance_info (CDI_DOMINATORS);
   if (gcse_file)
     fprintf (gcse_file, "\n");
 }
@@ -6362,7 +6364,7 @@ hoist_code (void)
       int found = 0;
       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
         block.  These are the potentially hoistable expressions.  */
       for (i = 0; i < hoist_vbeout[bb->index]->n_bits; i++)
@@ -8020,7 +8022,8 @@ bypass_jumps (FILE *file)
   if (file)
     {
       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);
     }
 
index d82dd91..483cc7e 100644 (file)
@@ -25,9 +25,11 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 #include "tm.h"
 
 #include "rtl.h"
+#include "tree.h"
 #include "flags.h"
 #include "output.h"
 #include "function.h"
+#include "langhooks.h"
 #include "hard-reg-set.h"
 #include "basic-block.h"
 #include "toplev.h"
@@ -55,7 +57,8 @@ start_fct (FILE *fp)
     case vcg:
       fprintf (fp, "\
 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;
     case no_graph:
       break;
@@ -71,7 +74,8 @@ start_bb (FILE *fp, int bb)
       fprintf (fp, "\
 graph: {\ntitle: \"%s.BB%d\"\nfolding: 1\ncolor: lightblue\n\
 label: \"basic block %d",
-              current_function_name, bb, bb);
+              (*lang_hooks.decl_printable_name) (current_function_decl, 2),
+              bb, bb);
       break;
     case no_graph:
       break;
@@ -113,8 +117,9 @@ node_data (FILE *fp, rtx tmp_rtx)
        case vcg:
          fprintf (fp, "\
 edge: { sourcename: \"%s.0\" targetname: \"%s.%d\" }\n",
-                  current_function_name,
-                  current_function_name, XINT (tmp_rtx, 0));
+                  (*lang_hooks.decl_printable_name) (current_function_decl, 2),
+                  (*lang_hooks.decl_printable_name) (current_function_decl, 2),
+                  XINT (tmp_rtx, 0));
          break;
        case no_graph:
          break;
@@ -126,7 +131,8 @@ edge: { sourcename: \"%s.0\" targetname: \"%s.%d\" }\n",
     case vcg:
       fprintf (fp, "node: {\n  title: \"%s.%d\"\n  color: %s\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) == INSN ? "green"
               : GET_CODE (tmp_rtx) == JUMP_INSN ? "darkgreen"
@@ -178,8 +184,11 @@ draw_edge (FILE *fp, int from, int to, int bb_edge, int class)
        color = "color: green ";
       fprintf (fp,
               "edge: { sourcename: \"%s.%d\" targetname: \"%s.%d\" %s",
-              current_function_name, from,
-              current_function_name, to, color);
+              (*lang_hooks.decl_printable_name) (current_function_decl, 2),
+              from,
+              (*lang_hooks.decl_printable_name) (current_function_decl, 2),
+              to,
+              color);
       if (class)
        fprintf (fp, "class: %d ", class);
       fputs ("}\n", fp);
@@ -209,7 +218,7 @@ end_fct (FILE *fp)
     {
     case vcg:
       fprintf (fp, "node: { title: \"%s.999999\" label: \"END\" }\n}\n",
-              current_function_name);
+              (*lang_hooks.decl_printable_name) (current_function_decl, 2));
       break;
     case no_graph:
       break;
index 24c8fd8..2b10e18 100644 (file)
@@ -84,9 +84,6 @@ static int cond_exec_changed_p;
 /* True if life data ok at present.  */
 static bool life_data_ok;
 
-/* The post-dominator relation on the original block numbers.  */
-static dominance_info post_dominators;
-
 /* Forward references.  */
 static int count_bb_insns (basic_block);
 static rtx first_active_insn (basic_block);
@@ -123,6 +120,7 @@ mark_loop_exit_edges (void)
   edge e;
   
   flow_loops_find (&loops, LOOP_TREE);
+  free_dominance_info (CDI_DOMINATORS);
   
   if (loops.num > 1)
     {
@@ -2105,8 +2103,8 @@ merge_if_block (struct ce_if_block * ce_info)
        {
          bb = fallthru;
          fallthru = block_fallthru (bb);
-         if (post_dominators)
-           delete_from_dominance_info (post_dominators, bb);
+         if (dom_computed[CDI_POST_DOMINATORS] >= DOM_NO_FAST_QUERY)
+           delete_from_dominance_info (CDI_POST_DOMINATORS, bb);
          merge_blocks (combo_bb, bb);
          num_true_changes++;
        }
@@ -2122,8 +2120,8 @@ merge_if_block (struct ce_if_block * ce_info)
       if (combo_bb->global_live_at_end)
        COPY_REG_SET (combo_bb->global_live_at_end,
                      then_bb->global_live_at_end);
-      if (post_dominators)
-       delete_from_dominance_info (post_dominators, then_bb);
+      if (dom_computed[CDI_POST_DOMINATORS] >= DOM_NO_FAST_QUERY)
+       delete_from_dominance_info (CDI_POST_DOMINATORS, then_bb);
       merge_blocks (combo_bb, then_bb);
       num_true_changes++;
     }
@@ -2133,8 +2131,8 @@ merge_if_block (struct ce_if_block * ce_info)
      get their addresses taken.  */
   if (else_bb)
     {
-      if (post_dominators)
-       delete_from_dominance_info (post_dominators, else_bb);
+      if (dom_computed[CDI_POST_DOMINATORS] >= DOM_NO_FAST_QUERY)
+               delete_from_dominance_info (CDI_POST_DOMINATORS, else_bb);
       merge_blocks (combo_bb, else_bb);
       num_true_changes++;
     }
@@ -2190,8 +2188,8 @@ merge_if_block (struct ce_if_block * ce_info)
        COPY_REG_SET (combo_bb->global_live_at_end,
                      join_bb->global_live_at_end);
 
-      if (post_dominators)
-       delete_from_dominance_info (post_dominators, join_bb);
+      if (dom_computed[CDI_POST_DOMINATORS] >= DOM_NO_FAST_QUERY)
+       delete_from_dominance_info (CDI_POST_DOMINATORS, join_bb);
       merge_blocks (combo_bb, join_bb);
       num_true_changes++;
     }
@@ -2271,7 +2269,7 @@ find_if_header (basic_block test_bb, int pass)
       && find_cond_trap (test_bb, then_edge, else_edge))
     goto success;
 
-  if (post_dominators
+  if (dom_computed[CDI_POST_DOMINATORS] >= DOM_NO_FAST_QUERY
       && (! HAVE_conditional_execution || reload_completed))
     {
       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)
   remove_edge (trap_bb == then_bb ? then_edge : else_edge);
   if (trap_bb->pred == NULL)
     {
-      if (post_dominators)
-       delete_from_dominance_info (post_dominators, trap_bb);
+      if (dom_computed[CDI_POST_DOMINATORS] >= DOM_NO_FAST_QUERY)
+       delete_from_dominance_info (CDI_POST_DOMINATORS, trap_bb);
       delete_block (trap_bb);
     }
 
@@ -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);
   then_bb_index = then_bb->index;
-  if (post_dominators)
-    delete_from_dominance_info (post_dominators, then_bb);
+  if (dom_computed[CDI_POST_DOMINATORS] >= DOM_NO_FAST_QUERY)
+    delete_from_dominance_info (CDI_POST_DOMINATORS, then_bb);
   delete_block (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)
     {
       new_bb->index = then_bb_index;
       BASIC_BLOCK (then_bb_index) = new_bb;
-      if (post_dominators)
-       add_to_dominance_info (post_dominators, new_bb);
+      if (dom_computed[CDI_POST_DOMINATORS] >= DOM_NO_FAST_QUERY)
+       add_to_dominance_info (CDI_POST_DOMINATORS, new_bb);
     }
   /* We've possibly created jump to next insn, cleanup_cfg will solve that
      later.  */
@@ -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)
     ;
   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
@@ -2911,8 +2909,8 @@ find_if_case_2 (basic_block test_bb, edge then_edge, edge else_edge)
                    then_bb->global_live_at_start,
                    else_bb->global_live_at_end, BITMAP_IOR);
 
-  if (post_dominators)
-    delete_from_dominance_info (post_dominators, else_bb);
+  if (dom_computed[CDI_POST_DOMINATORS] >= DOM_NO_FAST_QUERY)
+    delete_from_dominance_info (CDI_POST_DOMINATORS, else_bb);
   delete_block (else_bb);
 
   num_true_changes++;
@@ -3217,11 +3215,9 @@ if_convert (int x_life_data_ok)
   free_basic_block_vars (1);
 
   /* Compute postdominators if we think we'll use them.  */
-  post_dominators = NULL;
   if (HAVE_conditional_execution || life_data_ok)
-    {
-      post_dominators = calculate_dominance_info (CDI_POST_DOMINATORS);
-    }
+    calculate_dominance_info (CDI_POST_DOMINATORS);
+
   if (life_data_ok)
     clear_bb_flags ();
 
@@ -3258,8 +3254,7 @@ if_convert (int x_life_data_ok)
     fprintf (rtl_dump_file, "\n\n========== no more changes\n");
 #endif
 
-  if (post_dominators)
-    free_dominance_info (post_dominators);
+  free_dominance_info (CDI_POST_DOMINATORS);
 
   if (rtl_dump_file)
     fflush (rtl_dump_file);
index 13285a3..0b882d9 100644 (file)
@@ -53,7 +53,9 @@ loop_optimizer_init (FILE *dumpfile)
 
       /* No loops.  */
       flow_loops_free (loops);
+      free_dominance_info (CDI_DOMINATORS);
       free (loops);
+
       /* Make chain.  */
       FOR_EACH_BB (bb)
        if (bb->next_bb != EXIT_BLOCK_PTR)
@@ -81,7 +83,7 @@ loop_optimizer_init (FILE *dumpfile)
   flow_loops_dump (loops, dumpfile, NULL, 1);
 
 #ifdef ENABLE_CHECKING
-  verify_dominators (loops->cfg.dom);
+  verify_dominators (CDI_DOMINATORS);
   verify_loop_structure (loops);
 #endif
 
@@ -105,6 +107,7 @@ loop_optimizer_finalize (struct loops *loops, FILE *dumpfile)
 
   /* Clean up.  */
   flow_loops_free (loops);
+  free_dominance_info (CDI_DOMINATORS);
   free (loops);
 
   /* Finalize changes.  */
index dde3c74..6c796af 100644 (file)
@@ -68,14 +68,12 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 
 static void decide_unrolling_and_peeling (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_once_rolling (struct loops *, struct loop *, int);
-static void decide_peel_completely (struct loops *, struct loop *, int);
-static void decide_unroll_stupid (struct loops *, struct loop *, int);
-static void decide_unroll_constant_iterations (struct loops *,
-                                              struct loop *, int);
-static void decide_unroll_runtime_iterations (struct loops *, struct loop *,
-                                             int);
+static void decide_peel_simple (struct loop *, int);
+static void decide_peel_once_rolling (struct loop *, int);
+static void decide_peel_completely (struct loop *, int);
+static void decide_unroll_stupid (struct loop *, int);
+static void decide_unroll_constant_iterations (struct loop *, int);
+static void decide_unroll_runtime_iterations (struct loop *, int);
 static void peel_loop_simple (struct loops *, struct loop *);
 static void peel_loop_completely (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)
       if (check)
        {
 #ifdef ENABLE_CHECKING
-         verify_dominators (loops->cfg.dom);
+         verify_dominators (CDI_DOMINATORS);
          verify_loop_structure (loops);
 #endif
        }
@@ -178,15 +176,15 @@ peel_loops_completely (struct loops *loops, int flags)
 
       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)
-       decide_peel_completely (loops, loop, flags);
+       decide_peel_completely (loop, flags);
 
       if (loop->lpt_decision.decision == LPT_PEEL_COMPLETELY)
        {
          peel_loop_completely (loops, loop);
 #ifdef ENABLE_CHECKING
-         verify_dominators (loops->cfg.dom);
+         verify_dominators (CDI_DOMINATORS);
          verify_loop_structure (loops);
 #endif
        }
@@ -254,13 +252,13 @@ decide_unrolling_and_peeling (struct loops *loops, int flags)
       /* Try transformations one by one in decreasing order of
         priority.  */
 
-      decide_unroll_constant_iterations (loops, loop, flags);
+      decide_unroll_constant_iterations (loop, flags);
       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)
-       decide_unroll_stupid (loops, loop, flags);
+       decide_unroll_stupid (loop, flags);
       if (loop->lpt_decision.decision == LPT_NONE)
-       decide_peel_simple (loops, loop, flags);
+       decide_peel_simple (loop, flags);
 
       loop = next;
     }
@@ -269,8 +267,7 @@ decide_unrolling_and_peeling (struct loops *loops, int flags)
 /* Decide whether the LOOP is once rolling and suitable for complete
    peeling.  */
 static void
-decide_peel_once_rolling (struct loops *loops, struct loop *loop,
-                         int flags ATTRIBUTE_UNUSED)
+decide_peel_once_rolling (struct loop *loop, int flags ATTRIBUTE_UNUSED)
 {
   if (rtl_dump_file)
     fprintf (rtl_dump_file, ";; Considering peeling once rolling loop\n");
@@ -284,7 +281,7 @@ decide_peel_once_rolling (struct loops *loops, struct loop *loop,
     }
 
   /* 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;
 
   /* Check number of iterations.  */
@@ -303,8 +300,7 @@ decide_peel_once_rolling (struct loops *loops, struct loop *loop,
 
 /* Decide whether the LOOP is suitable for complete peeling.  */
 static void
-decide_peel_completely (struct loops *loops, struct loop *loop,
-                       int flags ATTRIBUTE_UNUSED)
+decide_peel_completely (struct loop *loop, int flags ATTRIBUTE_UNUSED)
 {
   unsigned npeel;
 
@@ -352,7 +348,7 @@ decide_peel_completely (struct loops *loops, struct loop *loop,
   /* Check for simple loops.  */
   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;
     }
 
@@ -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.  */
 static void
-decide_unroll_constant_iterations (struct loops *loops, struct loop *loop,
-                                  int flags)
+decide_unroll_constant_iterations (struct loop *loop, int flags)
 {
   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,
   /* Check for simple loops.  */
   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;
     }
 
@@ -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
    and how much.  */
 static void
-decide_unroll_runtime_iterations (struct loops *loops, struct loop *loop,
-                                 int flags)
+decide_unroll_runtime_iterations (struct loop *loop, int flags)
 {
   unsigned nunroll, nunroll_by_av, i;
 
@@ -683,7 +677,7 @@ decide_unroll_runtime_iterations (struct loops *loops, struct loop *loop,
   /* Check for simple loops.  */
   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;
     }
 
@@ -774,7 +768,7 @@ unroll_loop_runtime_iterations (struct loops *loops, struct loop *loop)
       unsigned nldom;
       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++)
        if (!flow_bb_inside_loop_p (loop, ldom[j]))
          dom_bbs[n_dom_bbs++] = ldom[j];
@@ -821,7 +815,7 @@ unroll_loop_runtime_iterations (struct loops *loops, struct loop *loop)
   end_sequence ();
 
   /* 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));
   n_remove_edges = 0;
@@ -844,7 +838,7 @@ unroll_loop_runtime_iterations (struct loops *loops, struct loop *loop)
 
   /* Record the place where switch will be built for preconditioning.  */
   swtch = loop_split_edge_with (loop_preheader_edge (loop),
-                               NULL_RTX, loops);
+                               NULL_RTX);
 
   for (i = 0; i < n_peel; i++)
     {
@@ -862,8 +856,7 @@ unroll_loop_runtime_iterations (struct loops *loops, struct loop *loop)
       j = n_peel - i - (extra_zero_check ? 0 : 1);
       p = REG_BR_PROB_BASE / (i + 2);
 
-      preheader = loop_split_edge_with (loop_preheader_edge (loop),
-                                       NULL_RTX, loops);
+      preheader = loop_split_edge_with (loop_preheader_edge (loop), NULL_RTX);
       label = block_label (preheader);
       start_sequence ();
       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)
       branch_code = get_insns ();
       end_sequence ();
 
-      swtch = loop_split_edge_with (swtch->pred, branch_code, loops);
-      set_immediate_dominator (loops->cfg.dom, preheader, swtch);
+      swtch = loop_split_edge_with (swtch->pred, branch_code);
+      set_immediate_dominator (CDI_DOMINATORS, preheader, swtch);
       swtch->succ->probability = REG_BR_PROB_BASE - p;
       e = make_edge (swtch, preheader,
                     swtch->succ->flags & EDGE_IRREDUCIBLE_LOOP);
@@ -892,8 +885,7 @@ unroll_loop_runtime_iterations (struct loops *loops, struct loop *loop)
       /* Add branch for zero iterations.  */
       p = REG_BR_PROB_BASE / (max_unroll + 1);
       swtch = ezc_swtch;
-      preheader = loop_split_edge_with (loop_preheader_edge (loop),
-                                       NULL_RTX, loops);
+      preheader = loop_split_edge_with (loop_preheader_edge (loop), NULL_RTX);
       label = block_label (preheader);
       start_sequence ();
       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)
       branch_code = get_insns ();
       end_sequence ();
 
-      swtch = loop_split_edge_with (swtch->succ, branch_code, loops);
-      set_immediate_dominator (loops->cfg.dom, preheader, swtch);
+      swtch = loop_split_edge_with (swtch->succ, branch_code);
+      set_immediate_dominator (CDI_DOMINATORS, preheader, swtch);
       swtch->succ->probability = REG_BR_PROB_BASE - p;
       e = make_edge (swtch, preheader,
                     swtch->succ->flags & EDGE_IRREDUCIBLE_LOOP);
@@ -918,7 +910,7 @@ unroll_loop_runtime_iterations (struct loops *loops, struct loop *loop)
     }
 
   /* 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.  */
 
@@ -946,7 +938,7 @@ unroll_loop_runtime_iterations (struct loops *loops, struct loop *loop)
 
 /* Decide whether to simply peel LOOP and how much.  */
 static void
-decide_peel_simple (struct loops *loops, struct loop *loop, int flags)
+decide_peel_simple (struct loop *loop, int flags)
 {
   unsigned npeel;
 
@@ -975,7 +967,7 @@ decide_peel_simple (struct loops *loops, struct loop *loop, int flags)
   /* Check for simple loops.  */
   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;
     }
 
@@ -1062,7 +1054,7 @@ peel_loop_simple (struct loops *loops, struct loop *loop)
 
 /* Decide whether to unroll LOOP stupidly and how much.  */
 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;
 
@@ -1095,7 +1087,7 @@ decide_unroll_stupid (struct loops *loops, struct loop *loop, int flags)
   /* Check for simple loops.  */
   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;
     }
 
index 25728c2..4cfaa2f 100644 (file)
@@ -81,7 +81,7 @@ Software Foundation, 59 Temple Place - Suite 330, Boston, MA
 static struct loop *unswitch_loop (struct loops *, struct loop *,
                                   basic_block);
 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 *);
 static rtx reversed_condition (rtx);
 
@@ -107,7 +107,7 @@ unswitch_loops (struct loops *loops)
 
       unswitch_single_loop (loops, loop, NULL_RTX, 0);
 #ifdef ENABLE_CHECKING
-      verify_dominators (loops->cfg.dom);
+      verify_dominators (CDI_DOMINATORS);
       verify_loop_structure (loops);
 #endif
     }
@@ -117,8 +117,7 @@ unswitch_loops (struct loops *loops)
    basic blocks (for what it means see comments below).  List of basic blocks
    inside LOOP is provided in BODY to save time.  */
 static bool
-may_unswitch_on_p (struct loops *loops, basic_block bb, struct loop *loop,
-                  basic_block *body)
+may_unswitch_on_p (basic_block bb, struct loop *loop, basic_block *body)
 {
   rtx test;
   unsigned i;
@@ -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
      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;
 
   /* 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,
       /* Find a bb to unswitch on.  */
       bbs = get_loop_body (loop);
       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;
 
       if (i == loop->num_nodes)
@@ -295,7 +294,7 @@ unswitch_single_loop (struct loops *loops, struct loop *loop,
     rconds = cond_checked;
 
   /* 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);
   true_first = !(bb->succ->flags & EDGE_FALLTHRU);
   if (rtl_dump_file)
@@ -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 ||
       unswitch_on->succ->succ_next->succ_next)
     abort ();
-  if (!just_once_each_iteration_p (loops, loop, unswitch_on))
+  if (!just_once_each_iteration_p (loop, unswitch_on))
     abort ();
   if (loop->inner)
     abort ();
@@ -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->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;
 
   /* 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)
   fix_loop_placement (nloop);
 
   /* Preserve the simple loop preheaders.  */
-  loop_split_edge_with (loop_preheader_edge (loop), NULL_RTX, loops);
-  loop_split_edge_with (loop_preheader_edge (nloop), NULL_RTX, loops);
+  loop_split_edge_with (loop_preheader_edge (loop), NULL_RTX);
+  loop_split_edge_with (loop_preheader_edge (nloop), NULL_RTX);
 
   return nloop;
 }
index 30de866..74a1f24 100644 (file)
@@ -72,10 +72,8 @@ static void estimate_loops_at_level (struct loop *loop);
 static void propagate_freq (struct loop *);
 static void estimate_bb_frequencies (struct loops *);
 static void counts_to_freqs (void);
-static void process_note_predictions (basic_block, int *, dominance_info,
-                                     dominance_info);
-static void process_note_prediction (basic_block, int *, dominance_info,
-                                    dominance_info, int, int);
+static void process_note_predictions (basic_block, int *);
+static void process_note_prediction (basic_block, int *, int, int);
 static bool last_basic_block_p (basic_block);
 static void compute_function_frequency (void);
 static void choose_function_section (void);
@@ -393,13 +391,12 @@ combine_predictions_for_insn (rtx insn, basic_block bb)
 void
 estimate_probability (struct loops *loops_info)
 {
-  dominance_info dominators, post_dominators;
   basic_block bb;
   unsigned i;
 
   connect_infinite_loops_to_exit ();
-  dominators = calculate_dominance_info (CDI_DOMINATORS);
-  post_dominators = calculate_dominance_info (CDI_POST_DOMINATORS);
+  calculate_dominance_info (CDI_DOMINATORS);
+  calculate_dominance_info (CDI_POST_DOMINATORS);
 
   /* Try to predict out blocks in a loop that are not part of a
      natural loop.  */
@@ -412,11 +409,10 @@ estimate_probability (struct loops *loops_info)
       struct loop_desc desc;
       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;
 
-      if (simple_loop_p (loops_info, loop, &desc)
-         && desc.const_iter)
+      if (simple_loop_p (loop, &desc) && desc.const_iter)
        {
          int prob;
          niter = desc.niter + 1;
@@ -500,8 +496,8 @@ estimate_probability (struct loops *loops_info)
          /* Look for block we are guarding (ie we dominate it,
             but it doesn't postdominate us).  */
          if (e->dest != EXIT_BLOCK_PTR && e->dest != bb
-             && dominated_by_p (dominators, e->dest, e->src)
-             && !dominated_by_p (post_dominators, e->src, e->dest))
+             && dominated_by_p (CDI_DOMINATORS, e->dest, e->src)
+             && !dominated_by_p (CDI_POST_DOMINATORS, e->src, e->dest))
            {
              rtx insn;
 
@@ -618,8 +614,7 @@ estimate_probability (struct loops *loops_info)
        && bb->succ->succ_next != NULL)
       combine_predictions_for_insn (BB_END (bb), bb);
 
-  free_dominance_info (post_dominators);
-  free_dominance_info (dominators);
+  free_dominance_info (CDI_POST_DOMINATORS);
 
   remove_fake_edges ();
   estimate_bb_frequencies (loops_info);
@@ -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).  */
 
 static void
-process_note_prediction (basic_block bb, int *heads,
-                        dominance_info dominators,
-                        dominance_info post_dominators, int pred,
-                        int flags)
+process_note_prediction (basic_block bb, int *heads, int pred, int flags)
 {
   edge e;
   int y;
@@ -736,18 +728,18 @@ process_note_prediction (basic_block bb, int *heads,
          find first dominator that we do not post-dominate (we are
          using already known members of heads array).  */
       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;
 
       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;
          heads[next_ai->index] = ai->index;
          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;
       else
        head = heads[next_ai->index];
@@ -769,7 +761,7 @@ process_note_prediction (basic_block bb, int *heads,
     return;
   for (e = BASIC_BLOCK (y)->succ; e; e = e->succ_next)
     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);
 }
 
@@ -778,9 +770,7 @@ process_note_prediction (basic_block bb, int *heads,
    process_note_prediction.  */
 
 static void
-process_note_predictions (basic_block bb, int *heads,
-                         dominance_info dominators,
-                         dominance_info post_dominators)
+process_note_predictions (basic_block bb, int *heads)
 {
   rtx insn;
   edge e;
@@ -813,8 +803,6 @@ process_note_predictions (basic_block bb, int *heads,
          /* Process single prediction note.  */
          process_note_prediction (bb,
                                   heads,
-                                  dominators,
-                                  post_dominators,
                                   alg, (int) NOTE_PREDICTION_FLAGS (insn));
          delete_insn (insn);
        }
@@ -827,10 +815,7 @@ process_note_predictions (basic_block bb, int *heads,
       /* This block ended from other reasons than because of return.
          If it is because of noreturn call, this should certainly not
          be taken.  Otherwise it is probably some error recovery.  */
-      process_note_prediction (bb,
-                              heads,
-                              dominators,
-                              post_dominators, PRED_NORETURN, NOT_TAKEN);
+      process_note_prediction (bb, heads, PRED_NORETURN, NOT_TAKEN);
     }
 }
 
@@ -841,15 +826,14 @@ void
 note_prediction_to_br_prob (void)
 {
   basic_block bb;
-  dominance_info post_dominators, dominators;
   int *heads;
 
   /* To enable handling of noreturn blocks.  */
   add_noreturn_fake_exit_edges ();
   connect_infinite_loops_to_exit ();
 
-  post_dominators = calculate_dominance_info (CDI_POST_DOMINATORS);
-  dominators = calculate_dominance_info (CDI_DOMINATORS);
+  calculate_dominance_info (CDI_POST_DOMINATORS);
+  calculate_dominance_info (CDI_DOMINATORS);
 
   heads = xmalloc (sizeof (int) * last_basic_block);
   memset (heads, -1, sizeof (int) * last_basic_block);
@@ -858,10 +842,10 @@ note_prediction_to_br_prob (void)
   /* Process all prediction notes.  */
 
   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 (dominators);
+  free_dominance_info (CDI_POST_DOMINATORS);
+  free_dominance_info (CDI_DOMINATORS);
   free (heads);
 
   remove_fake_edges ();
index 138bab3..b8e474d 100644 (file)
@@ -155,7 +155,7 @@ static int *containing_rgn;
 
 void debug_regions (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 *);
 
 extern void debug_live (int, int);
@@ -613,7 +613,7 @@ too_large (int block, int *num_bbs, int *num_insns)
    of edge tables.  That would simplify it somewhat.  */
 
 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;
   char no_loops = 1;
@@ -827,7 +827,7 @@ find_rgns (struct edge_list *edge_list, dominance_info dom)
                    {
                      /* Now verify that the block is dominated by the loop
                         header.  */
-                     if (!dominated_by_p (dom, jbb, bb))
+                     if (!dominated_by_p (CDI_DOMINATORS, jbb, bb))
                        break;
                    }
                }
@@ -2597,7 +2597,6 @@ init_regions (void)
        }
       else
        {
-         dominance_info dom;
          struct edge_list *edge_list;
 
          /* The scheduler runs after estimate_probabilities; therefore, we
@@ -2607,7 +2606,7 @@ init_regions (void)
          edge_list = create_edge_list ();
 
          /* 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
             blocks or any other irregularity with the cfg which prevents
@@ -2615,7 +2614,7 @@ init_regions (void)
          if (build_control_flow (edge_list) != 0)
            find_single_block_region ();
          else
-           find_rgns (edge_list, dom);
+           find_rgns (edge_list);
 
          if (sched_verbose >= 3)
            debug_regions ();
@@ -2625,7 +2624,7 @@ init_regions (void)
 
          /* For now.  This will move as more and more of haifa is converted
             to using the cfg code in flow.c.  */
-         free_dominance_info (dom);
+         free_dominance_info (CDI_DOMINATORS);
        }
     }
 
index eb68ce8..6e34c6d 100644 (file)
@@ -2477,6 +2477,7 @@ rest_of_handle_branch_prob (tree decl, rtx insns)
     estimate_probability (&loops);
 
   flow_loops_free (&loops);
+  free_dominance_info (CDI_DOMINATORS);
   close_dump_file (DFI_bp, print_rtl_with_bb, insns);
   timevar_pop (TV_BRANCH_PROB);
 }
@@ -3014,8 +3015,9 @@ rest_of_handle_loop_optimize (tree decl, rtx insns)
    sooner, but we want the profile feedback to work more
    efficiently.  */
 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;
   timevar_push (TV_LOOP);
   open_dump_file (DFI_loop2, decl);
@@ -3047,6 +3049,7 @@ rest_of_handle_loop2 (tree decl, rtx insns)
   close_dump_file (DFI_loop2, print_rtl_with_bb, get_insns ());
   timevar_pop (TV_LOOP);
   ggc_collect ();
+#endif
 }
 
 /* This is called from finish_function (within langhooks.parse_file)