fixed doxygen output
[libfirm] / ir / opt / ldstopt.c
index b572914..a74aae4 100644 (file)
@@ -238,7 +238,7 @@ static void collect_nodes(ir_node *node, void *env)
       }
     }
   }
-  else if (op == op_Block) { /* check, if it's an exception block */
+  else if (op == op_Block) {
     int i;
 
     for (i = get_Block_n_cfgpreds(node) - 1; i >= 0; --i) {
@@ -255,7 +255,7 @@ static void collect_nodes(ir_node *node, void *env)
       bl_info    = get_block_info(pred_block, wenv);
 
       if (is_fragile_op(pred))
-             bl_info->flags |= BLOCK_HAS_EXC;
+        bl_info->flags |= BLOCK_HAS_EXC;
       else if (is_irn_forking(pred))
         bl_info->flags |= BLOCK_HAS_COND;
 
@@ -271,7 +271,7 @@ static void collect_nodes(ir_node *node, void *env)
 /**
  * Returns an entity if the address ptr points to a constant one.
  */
-static entity *find_constant_entity(ir_node *ptr)
+static ir_entity *find_constant_entity(ir_node *ptr)
 {
   for (;;) {
     ir_op *op = get_irn_op(ptr);
@@ -280,8 +280,8 @@ static entity *find_constant_entity(ir_node *ptr)
       return get_SymConst_entity(ptr);
     }
     else if (op == op_Sel) {
-      entity  *ent = get_Sel_entity(ptr);
-      ir_type *tp  = get_entity_owner(ent);
+      ir_entity *ent = get_Sel_entity(ptr);
+      ir_type   *tp  = get_entity_owner(ent);
 
       /* Do not fiddle with polymorphism. */
       if (is_Class_type(get_entity_owner(ent)) &&
@@ -350,7 +350,7 @@ static long get_Sel_array_index_long(ir_node *n, int dim) {
  */
 static compound_graph_path *rec_get_accessed_path(ir_node *ptr, int depth) {
   compound_graph_path *res = NULL;
-  entity              *root, *field;
+  ir_entity           *root, *field;
   int                 path_len, pos;
 
   if (get_irn_op(ptr) == op_SymConst) {
@@ -574,9 +574,8 @@ static unsigned follow_Load_chain(ir_node *load, ir_node *curr) {
 static unsigned optimize_load(ir_node *load)
 {
   ldst_info_t *info = get_irn_link(load);
-  ir_mode *load_mode = get_Load_mode(load);
   ir_node *mem, *ptr, *new_node;
-  entity *ent;
+  ir_entity *ent;
   unsigned res = 0;
 
   /* do NOT touch volatile loads for now */
@@ -600,9 +599,9 @@ static unsigned optimize_load(ir_node *load)
 
       if (get_irn_op(skip_Proj(mem)) == op_Alloc) {
         /* ok, check the types */
-        entity  *ent    = get_Sel_entity(ptr);
-        ir_type *s_type = get_entity_type(ent);
-        ir_type *a_type = get_Alloc_type(mem);
+        ir_entity *ent    = get_Sel_entity(ptr);
+        ir_type   *s_type = get_entity_type(ent);
+        ir_type   *a_type = get_Alloc_type(mem);
 
         if (is_SubClass_of(s_type, a_type)) {
           /* ok, condition met: there can't be an exception because
@@ -714,7 +713,7 @@ static unsigned optimize_load(ir_node *load)
           {
             int j;
             for (j = 0; j < get_compound_graph_path_length(path); ++j) {
-              entity *node = get_compound_graph_path_node(path, j);
+              ir_entity *node = get_compound_graph_path_node(path, j);
               fprintf(stdout, ".%s", get_entity_name(node));
               if (is_Array_type(get_entity_owner(node)))
                       fprintf(stdout, "[%d]", get_compound_graph_path_array_index(path, j));
@@ -854,7 +853,6 @@ static unsigned follow_Load_chain_for_Store(ir_node *store, ir_node *curr) {
  */
 static unsigned optimize_store(ir_node *store)
 {
-  ldst_info_t *info = get_irn_link(store);
   ir_node *ptr, *mem;
 
   if (get_Store_volatility(store) == volatility_is_volatile)
@@ -881,10 +879,10 @@ static unsigned optimize_store(ir_node *store)
  *
  *   val1   val2   val3          val1  val2  val3
  *    |      |      |               \    |    /
- *   Str    Str    Str               \   |   /
+ *  Store  Store  Store              \   |   /
  *      \    |    /                   PhiData
  *       \   |   /                       |
- *        \  |  /                       Str
+ *        \  |  /                      Store
  *          PhiM
  *
  * @endverbatim
@@ -896,9 +894,9 @@ static unsigned optimize_store(ir_node *store)
 static unsigned optimize_phi(ir_node *phi, walk_env_t *wenv)
 {
   int i, n;
-  ir_node *store, *old_store, *ptr, *block, *phiM, *phiD, *exc, *projM;
+  ir_node *store, *old_store, *ptr, *block, *phi_block, *phiM, *phiD, *exc, *projM;
   ir_mode *mode;
-  ir_node **inM, **inD;
+  ir_node **inM, **inD, **stores;
   int *idx;
   dbg_info *db = NULL;
   ldst_info_t *info;
@@ -918,13 +916,20 @@ static unsigned optimize_phi(ir_node *phi, walk_env_t *wenv)
   if (get_irn_op(store) != op_Store)
     return 0;
 
+  block = get_nodes_block(store);
+
   /* abort on dead blocks */
-  if (is_Block_dead(get_nodes_block(store)))
+  if (is_Block_dead(block))
     return 0;
 
-  /* check if the block has only one successor */
-  bl_info = get_irn_link(get_nodes_block(store));
-  if (bl_info->flags)
+  /* check if the block is post dominated by Phi-block
+     and has no exception exit */
+  bl_info = get_irn_link(block);
+  if (bl_info->flags & BLOCK_HAS_EXC)
+    return 0;
+
+  phi_block = get_nodes_block(phi);
+  if (! block_postdominates(phi_block, block))
     return 0;
 
   /* this is the address of the store */
@@ -949,12 +954,18 @@ static unsigned optimize_phi(ir_node *phi, walk_env_t *wenv)
       return 0;
 
     /* abort on dead blocks */
-    if (is_Block_dead(get_nodes_block(store)))
+    block = get_nodes_block(pred);
+    if (is_Block_dead(block))
       return 0;
 
-    /* check if the block has only one successor */
-    bl_info = get_irn_link(get_nodes_block(store));
-    if (bl_info->flags)
+    /* check if the block is post dominated by Phi-block
+       and has no exception exit. Note that block must be different from
+          Phi-block, else we would move a Store from end End of a block to its
+          Start... */
+    bl_info = get_irn_link(block);
+    if (bl_info->flags & BLOCK_HAS_EXC)
+      return 0;
+    if (block == phi_block || ! block_postdominates(phi_block, block))
       return 0;
   }
 
@@ -975,24 +986,42 @@ static unsigned optimize_phi(ir_node *phi, walk_env_t *wenv)
    * Is only allowed if the predecessor blocks have only one successor.
    */
 
-  /* first step: collect all inputs */
+  NEW_ARR_A(ir_node *, stores, n);
   NEW_ARR_A(ir_node *, inM, n);
   NEW_ARR_A(ir_node *, inD, n);
   NEW_ARR_A(int, idx, n);
 
+  /* Prepare: Collect all Store nodes.  We must do this
+     first because we otherwise may loose a store when exchanging its
+     memory Proj.
+   */
+  for (i = 0; i < n; ++i)
+    stores[i] = skip_Proj(get_Phi_pred(phi, i));
+
+  /* Prepare: Skip the memory Proj: we need this in the case some stores
+     are cascaded.
+     Beware: One Store might be included more than once in the stores[]
+     list, so we must prevent to do the exchange more than once.
+   */
   for (i = 0; i < n; ++i) {
-    ir_node *pred = skip_Proj(get_Phi_pred(phi, i));
-    info = get_irn_link(pred);
+    ir_node *store = stores[i];
+    ir_node *proj_m;
 
-    inM[i] = get_Store_mem(pred);
-    inD[i] = get_Store_value(pred);
-    idx[i] = info->exc_idx;
+    info = get_irn_link(store);
+    proj_m = info->projs[pn_Store_M];
 
-    /* Should we here replace the Proj after the Store by
-     * the Store's memory? Would be save but should not be needed,
-     * because we checked that all pred blocks have only one
-     * control flow successor.
-     */
+    if (is_Proj(proj_m) && get_Proj_pred(proj_m) == store)
+      exchange(proj_m, get_Store_mem(store));
+  }
+
+  /* first step: collect all inputs */
+  for (i = 0; i < n; ++i) {
+    ir_node *store = stores[i];
+    info = get_irn_link(store);
+
+    inM[i] = get_Store_mem(store);
+    inD[i] = get_Store_value(store);
+    idx[i] = info->exc_idx;
   }
   block = get_nodes_block(phi);
 
@@ -1069,7 +1098,6 @@ static void do_load_store_optimize(ir_node *n, void *env)
 void optimize_load_store(ir_graph *irg)
 {
   walk_env_t env;
-  int        was_activ;
 
   assert(get_irg_phase_state(irg) != phase_building);
   assert(get_irg_pinned(irg) != op_pin_state_floats &&
@@ -1078,12 +1106,10 @@ void optimize_load_store(ir_graph *irg)
   if (! get_opt_redundant_loadstore())
     return;
 
-  was_activ = edges_activated(irg);
-  if (was_activ) {
-    /* we need "fresh" edges */
-    edges_deactivate(irg);
-  }
-  edges_activate(irg);
+  edges_assure(irg);
+
+  /* for Phi optimization post-dominators are needed ... */
+  assure_postdoms(irg);
 
   obstack_init(&env.obst);
   env.changes = 0;
@@ -1108,7 +1134,4 @@ void optimize_load_store(ir_graph *irg)
        have Bad() predecessors. */
     set_irg_doms_inconsistent(irg);
   }
-
-  if (! was_activ)
-    edges_deactivate(irg);
 }