Fix typo in comment.
[libfirm] / ir / opt / data_flow_scalar_replace.c
index f923a5c..a84b9dd 100644 (file)
@@ -1,31 +1,36 @@
 /*
- * Project:     libFIRM
- * File name:   ir/opt/data_flow_scalar_replace.c
- * Purpose:     scalar replacement of arrays and compounds
- * Author:      Beyhan Veliev
- * Modified by: Michael Beck
- * Created:
- * CVS-ID:      $Id$
- * Copyright:   (c) 1998-2005 Universität Karlsruhe
- * Licence:     This file protected by GPL -  GNU GENERAL PUBLIC LICENSE.
+ * Copyright (C) 1995-2008 University of Karlsruhe.  All right reserved.
+ *
+ * This file is part of libFirm.
+ *
+ * This file may be distributed and/or modified under the terms of the
+ * GNU General Public License version 2 as published by the Free Software
+ * Foundation and appearing in the file LICENSE.GPL included in the
+ * packaging of this file.
+ *
+ * Licensees holding valid libFirm Professional Edition licenses may use
+ * this file in accordance with the libFirm Commercial License.
+ * Agreement provided with the Software.
+ *
+ * This file is provided AS IS with NO WARRANTY OF ANY KIND, INCLUDING THE
+ * WARRANTY OF DESIGN, MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE.
+ */
+
+/**
+ * @file
+ * @brief   scalar replacement of arrays and compounds
+ * @author  Beyhan Veliev, Michael Beck
+ * @version $Id$
  */
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#ifdef HAVE_ALLOCA_H
-#include <alloca.h>
-#endif
-
-#ifdef HAVE_MALLOC_H
-#include <malloc.h>
-#endif
+#include "iroptimize.h"
 
-#ifdef HAVE_STRING_H
 #include <string.h>
-#endif
 
-#include "data_flow_scalar_replace.h"
 #include "irflag_t.h"
 #include "irouts.h"
 #include "pset.h"
@@ -38,8 +43,8 @@
 #include "irloop.h"
 #include "analyze_irg_args.h"
 #include "irprintf.h"
-#include "compute_loop_info.h"
 #include "irgopt.h"
+#include "xmalloc.h"
 
 #define SET_ENT_VNUM(ent, vnum) set_entity_link(ent, INT_TO_PTR(vnum))
 #define GET_ENT_VNUM(ent)       (unsigned)PTR_TO_INT(get_entity_link(ent))
 
 
 typedef struct _ent_leaves_t{
-  entity  *ent;               /**< An entity, that contains scalars for replace.*/
+  ir_entity *ent;             /**< An entity, that contains scalars for replace.*/
   pset *leaves;               /**< All leaves of this entity.*/
 } ent_leaves_t;
 
 typedef struct _sels_t {
   ir_node *sel;               /**< A sel node, thats entity have scalars.*/
-  entity  *ent;               /**< The entity of this sel node.*/
+  ir_entity  *ent;            /**< The entity of this sel node.*/
 }sels_t;
 
 typedef struct _call_access_t {
@@ -88,7 +93,7 @@ typedef struct _leave_t {
  * accesses like a.b.c[8].d
  */
 typedef union {
-  entity *ent;
+  ir_entity *ent;
   tarval *tv;
 } path_elem_t;
 
@@ -129,6 +134,7 @@ static int ent_leaves_t_cmp(const void *elt, const void *key, size_t size)
 {
   const ent_leaves_t *c1 = elt;
   const ent_leaves_t *c2 = key;
+  (void) size;
 
   return c1->ent != c2->ent;
 }
@@ -140,8 +146,8 @@ static int ent_leaves_t_cmp(const void *elt, const void *key, size_t size)
  */
 static int ent_cmp(const void *elt, const void *key)
 {
-  const entity *c1 = elt;
-  const entity *c2 = key;
+  const ir_entity *c1 = elt;
+  const ir_entity *c2 = key;
 
   return c1 != c2;
 }
@@ -155,6 +161,7 @@ static int sels_cmp(const void *elt, const void *key, size_t size)
 {
   const sels_t *c1 = elt;
   const sels_t *c2 = key;
+  (void) size;
 
   return c1->sel != c2->sel;
 }
@@ -166,10 +173,10 @@ static int sels_cmp(const void *elt, const void *key, size_t size)
  */
 static int leave_cmp(const void *elt, const void *key)
 {
-  const ir_node *c1 = elt;
-  const ir_node *c2 = key;
+  ir_node *c1 = (ir_node *)elt;
+  ir_node *c2 = (ir_node *)key;
 
-  return c1->attr.s.ent != c2->attr.s.ent;
+  return get_Sel_entity(c1) != get_Sel_entity(c2);
 }
 
 /**
@@ -181,6 +188,7 @@ static int call_cmp(const void *elt, const void *key, size_t size)
 {
   const call_access_t *c1 = elt;
   const call_access_t *c2 = key;
+  (void) size;
 
   return c1->call != c2->call;
 }
@@ -194,6 +202,7 @@ static int path_cmp(const void *elt, const void *key, size_t size)
 {
   const path_t *p1 = elt;
   const path_t *p2 = key;
+  (void) size;
 
   /* we can use memcmp here, because identical tarvals should have identical addresses */
   return memcmp(p1->path, p2->path, p1->path_len * sizeof(p1->path[0]));
@@ -234,7 +243,7 @@ static int is_const_sel(ir_node *sel) {
  * Returns non-zero, if the address of an entity
  * represented by a Sel node (or it's successor Sels) is taken.
  */
-static int is_address_taken(ir_node *sel)
+static int is_address_taken_2(ir_node *sel)
 {
   int i;
 
@@ -257,7 +266,7 @@ static int is_address_taken(ir_node *sel)
 
     case iro_Sel: {
       /* Check the Sel successor of Sel */
-      int res = is_address_taken(succ);
+      int res = is_address_taken_2(succ);
 
       if (res)
         return 1;
@@ -285,7 +294,7 @@ static int is_address_taken(ir_node *sel)
  * @param ent  the entity that will be scalar replaced
  * @param sel  a Sel node that selects some fields of this entity
  */
-static void link_all_leave_sels(entity *ent, ir_node *sel)
+static void link_all_leave_sels(ir_entity *ent, ir_node *sel)
 {
   int i, n;
 
@@ -353,7 +362,7 @@ static int find_possible_replacements(ir_graph *irg)
     ir_node *succ = get_irn_out(irg_frame, i);
 
     if (get_irn_op(succ) == op_Sel) {
-      entity *ent = get_Sel_entity(succ);
+      ir_entity *ent = get_Sel_entity(succ);
       set_entity_link(ent, NULL);
     }
   }
@@ -367,7 +376,7 @@ static int find_possible_replacements(ir_graph *irg)
     ir_node *succ = get_irn_out(irg_frame, i);
 
     if (get_irn_op(succ) == op_Sel) {
-      entity *ent = get_Sel_entity(succ);
+      ir_entity *ent = get_Sel_entity(succ);
       ir_type *ent_type;
 
       if (get_entity_link(ent) == ADDRESS_TAKEN)
@@ -388,7 +397,7 @@ static int find_possible_replacements(ir_graph *irg)
 
       /* we can handle arrays, structs and atomic types yet */
       if (is_Array_type(ent_type) || is_Struct_type(ent_type) || is_atomic_type(ent_type)) {
-        if (is_address_taken(succ)) {
+        if (is_address_taken_2(succ)) {
           if (get_entity_link(ent)) /* killing one */
             --res;
           set_entity_link(ent, ADDRESS_TAKEN);
@@ -468,7 +477,7 @@ static path_t *find_path(ir_node *sel, unsigned len)
  *
  * @return the next free value number
  */
-static unsigned allocate_value_numbers(set *set_sels, pset *leaves, entity *ent, unsigned vnum)
+static unsigned allocate_value_numbers(set *set_sels, pset *leaves, ir_entity *ent, unsigned vnum)
 {
   ir_node *sel, *next;
   path_t *key, *path;
@@ -612,13 +621,13 @@ static void sync_stored_scalars(ir_node *blk, env_t *env) {
       val_arr = get_irn_link(pred);
 
       if(val_arr[GET_ENT_VNUM(value_ent->ent)].access_type == SYNCED)
-       /* This entity was synced.*/
-       continue;
+        /* This entity was synced.*/
+        continue;
 
       if(val_arr[GET_ENT_VNUM(value_ent->ent)].access_type <= 3) {
 
-       /* To avoid repeated sync of this entity in this block.*/
-       val_arr[GET_ENT_VNUM(value_ent->ent)].access_type = SYNCED;
+        /* To avoid repeated sync of this entity in this block.*/
+        val_arr[GET_ENT_VNUM(value_ent->ent)].access_type = SYNCED;
         /* In this predecessor block is this entity not acessed.
          * We must sync in the end ot this block.*/
         if(get_Block_n_cfgpreds(blk) > 1)
@@ -791,15 +800,12 @@ static void split_call_mem_edge(env_t *env, ir_node *call, pset *accessed_entiti
   call_access_t           key_call, *value_call;
   ir_node                 *call_blk, *new_mem_state, *leave;
   ir_node                 *sync, **in;
-  entity                  *ent;
+  ir_entity               *ent;
   unsigned                ent_vnum;
   int                     fix_irn = 0;                  /**< Set to 1 if we must add this call to it fix list.*/
   int                     *accessed_leaves_vnum = NULL; /**< An arraw, where are saved the value number, that
                                                              are synced from call's sync node, if we need it.*/
 
-  if(get_irn_node_nr(call) == 2763)
-    printf("\nHi\n");
-
   call_blk = get_nodes_block(call);
   val_arr  = get_irn_link(call_blk);
   /* An array to save the memory edges, that must be
@@ -976,7 +982,7 @@ static void split_memory_edge(ir_node *irn, void *ctx) {
  * @param block A block from the current ir graph.
  * @param vnum  The value number, that must be found.
  */
-static ir_node *find_value(ir_node *block, unsigned vnum)
+static ir_node *find_vnum_value(ir_node *block, unsigned vnum)
 {
   value_arr_entry_t *val_arr;
   int               i;
@@ -993,7 +999,7 @@ static ir_node *find_value(ir_node *block, unsigned vnum)
     for (i = get_Block_n_cfgpreds(block) - 1; i >= 0; --i) {
       ir_node *pred = get_Block_cfgpred(block, i);
 
-      res = find_value(get_nodes_block(pred), vnum);
+      res = find_vnum_value(get_nodes_block(pred), vnum);
       if (res)
         return res;
     }
@@ -1009,7 +1015,7 @@ static ir_node *find_value(ir_node *block, unsigned vnum)
 static void fix_ls(env_t *env)
 {
   fixlist_entry_t *l;
-  ir_node      *irn, *block, *pred, *val;
+  ir_node      *irn, *block, *pred, *val = NULL;
   ir_op        *op;
   int          i;
 
@@ -1023,7 +1029,7 @@ static void fix_ls(env_t *env)
       pred = get_nodes_block(pred);
 
       inc_irg_block_visited(current_ir_graph);
-      val = find_value(pred, l->vnum);
+      val = find_vnum_value(pred, l->vnum);
 
       if (val)
         break;
@@ -1031,12 +1037,12 @@ static void fix_ls(env_t *env)
 
     if(val) {
       if(op == op_Store)
-       set_Store_mem(irn, val);
+        set_Store_mem(irn, val);
       else
-       if(op == op_Load)
-         set_Load_mem(irn, val);
-       else
-         set_Call_mem(irn, val);
+        if(op == op_Load)
+          set_Load_mem(irn, val);
+        else
+          set_Call_mem(irn, val);
     }
   }
 }
@@ -1062,7 +1068,7 @@ static void fix_phis(env_t *env)
       pred = get_nodes_block(pred);
 
       inc_irg_block_visited(current_ir_graph);
-      val = find_value(pred, l->vnum);
+      val = find_vnum_value(pred, l->vnum);
 
       if (val)
         set_irn_n(phi, i, val);
@@ -1096,7 +1102,7 @@ static void fix_syncs(env_t *env)
     /* We first repair the global memory edge at the first position of sync predecessors.*/
     if(get_irn_op(get_irn_n(sync, 0)) == op_Unknown) {
       inc_irg_block_visited(current_ir_graph);
-      val = find_value(pred, env->gl_mem_vnum);
+      val = find_vnum_value(pred, env->gl_mem_vnum);
 
       if(val)
        set_irn_n(sync, 0, val);
@@ -1108,7 +1114,7 @@ static void fix_syncs(env_t *env)
       assert(k <= ARR_LEN(l->accessed_vnum) && "The algorythm for sync repair is wron");
       if(get_irn_op(get_irn_n(sync, i)) == op_Unknown) {
         inc_irg_block_visited(current_ir_graph);
-        val = find_value(pred, l->accessed_vnum[k++]);
+        val = find_vnum_value(pred, l->accessed_vnum[k++]);
 
         if(val)
           set_irn_n(sync, i, val);
@@ -1146,7 +1152,7 @@ static void sync_mem_edges(env_t *env) {
   if(val_arr[env->gl_mem_vnum].mem_edge_state == NULL) {
     /* We must search through blocks for this memory state.*/
     inc_irg_block_visited(current_ir_graph);
-    in[0] = find_value(Return_blk, env->gl_mem_vnum);
+    in[0] = find_vnum_value(Return_blk, env->gl_mem_vnum);
   }
   else
     in[0] = val_arr[env->gl_mem_vnum].mem_edge_state;
@@ -1160,7 +1166,7 @@ static void sync_mem_edges(env_t *env) {
       if(val_arr[vnum].mem_edge_state == NULL) {
         /* We must search through blocks for this memory state.*/
         inc_irg_block_visited(current_ir_graph);
-        in[i] = find_value(Return_blk, vnum);
+        in[i] = find_vnum_value(Return_blk, vnum);
       }
       else
         in[i] = val_arr[vnum].mem_edge_state;
@@ -1213,7 +1219,7 @@ static void analyse_calls(ir_node *irn, void *ctx) {
   unsigned int        acces_type;
   ir_node             *param, *call_ptr, *blk;
   ir_op               *op;
-  entity              *meth_ent;
+  ir_entity           *meth_ent;
   sels_t              key_sels, *value_sels;
   call_access_t       key_call, *value_call;
   value_arr_entry_t   *val_arr;
@@ -1284,21 +1290,6 @@ static void analyse_calls(ir_node *irn, void *ctx) {
   }
 }
 
-static int have_blk_phi_mem(ir_node *blk) {
-
-  int     i;
-  ir_node *out;
-
-  for(i = get_irn_n_outs(blk) - 1; i >= 0; i--) {
-
-    out = get_irn_out(blk, i);
-    if(get_irn_op(out) == op_Phi)
-      return 1;
-  }
-
-  return 0;
-}
-
 static int set_block_dominated_first_access(ir_node *blk, int vnum, unsigned int access) {
 
   ir_node *idom, *succ;
@@ -1345,7 +1336,7 @@ static void set_block_access(ir_node *irn, void *ctx){
       vnum = GET_ENT_VNUM(value_leaves->ent);
 
       if((get_Block_n_cfgpreds(irn) > 1) && (val_arr[vnum].access_type > 3))
-       env->changes =  set_block_dominated_first_access(irn, vnum, val_arr[vnum].access_type);
+        env->changes =  set_block_dominated_first_access(irn, vnum, val_arr[vnum].access_type);
 
       if((val_arr_pred[vnum].access_type > 3) && (val_arr[vnum].access_type < 3)) {
         /* We have found a block for update it access and value number information.*/
@@ -1508,13 +1499,13 @@ void data_flow_scalar_replacement_opt(ir_graph *irg) {
   remove_critical_cf_edges(irg);
 
   /* Call algorithm that computes the out edges.*/
-  if (get_irg_outs_state(irg) != outs_consistent)
-    compute_irg_outs(irg);
+  assure_irg_outs(irg);
 
   /* Call algorithm that computes the loop information.*/
-  compute_loop_info(irg);
+  construct_cf_backedges(irg);
+
   /* Call algorithm that computes the dominance information.*/
-  compute_doms(irg);
+  assure_doms(irg);
 
   /* Find possible scalar replacements */
   if (find_possible_replacements(irg)) {
@@ -1526,7 +1517,7 @@ void data_flow_scalar_replacement_opt(ir_graph *irg) {
       ir_node *succ = get_irn_out(irg_frame, i);
 
       if (get_irn_op(succ) == op_Sel) {
-        entity *ent = get_Sel_entity(succ);
+        ir_entity *ent = get_Sel_entity(succ);
 
         if (get_entity_link(ent) == NULL || get_entity_link(ent) == ADDRESS_TAKEN)
           continue;
@@ -1540,9 +1531,6 @@ void data_flow_scalar_replacement_opt(ir_graph *irg) {
       }
     }
 
-    if(get_firm_verbosity())
-      printf("vnumber in data flow= %i\n", vnum);
-
     /* Allocate value number for the globule memory edge.
      * and a value number for the value numbers state.*/
     vnum = vnum + 2;