OSDN Git Service

2004-07-14 Andreas Tobler <a.tobler@schweiz.ch>
[pf3gnuchains/gcc-fork.git] / gcc / tree-outof-ssa.c
index ec52f69..d189998 100644 (file)
@@ -116,7 +116,8 @@ static void elim_create (elim_graph, int);
 static void eliminate_phi (edge, int, elim_graph);
 static tree_live_info_p coalesce_ssa_name (var_map, int);
 static void assign_vars (var_map);
-static bool replace_variable (var_map, tree *, tree *);
+static bool replace_use_variable (var_map, use_operand_p, tree *);
+static bool replace_def_variable (var_map, def_operand_p, tree *);
 static void eliminate_virtual_phis (void);
 static void coalesce_abnormal_edges (var_map, conflict_graph, root_var_p);
 static void print_exprs (FILE *, const char *, tree, const char *, tree,
@@ -922,25 +923,25 @@ assign_vars (var_map map)
 }
 
 
-/* Replace *P with whatever variable it has been rewritten to based on the 
-   partitions in MAP.  EXPR is an optional expression vector over SSA versions
-   which is used to replace *P with an expression instead of a variable.  
+/* Replace use operand P with whatever variable it has been rewritten to based 
+   on the partitions in MAP.  EXPR is an optional expression vector over SSA 
+   versions which is used to replace P with an expression instead of a variable.
    If the stmt is changed, return true.  */ 
 
 static inline bool
-replace_variable (var_map map, tree *p, tree *expr)
+replace_use_variable (var_map map, use_operand_p p, tree *expr)
 {
   tree new_var;
-  tree var = *p;
+  tree var = USE_FROM_PTR (p);
 
   /* Check if we are replacing this variable with an expression.  */
   if (expr)
     {
-      int version = SSA_NAME_VERSION (*p);
+      int version = SSA_NAME_VERSION (var);
       if (expr[version])
         {
          tree new_expr = TREE_OPERAND (expr[version], 1);
-         *p = new_expr;
+         SET_USE (p, new_expr);
          /* Clear the stmt's RHS, or GC might bite us.  */
          TREE_OPERAND (expr[version], 1) = NULL_TREE;
          return true;
@@ -950,7 +951,43 @@ replace_variable (var_map map, tree *p, tree *expr)
   new_var = var_to_partition_to_var (map, var);
   if (new_var)
     {
-      *p = new_var;
+      SET_USE (p, new_var);
+      set_is_used (new_var);
+      return true;
+    }
+  return false;
+}
+
+
+/* Replace def operand DEF_P with whatever variable it has been rewritten to 
+   based on the partitions in MAP.  EXPR is an optional expression vector over
+   SSA versions which is used to replace DEF_P with an expression instead of a 
+   variable.  If the stmt is changed, return true.  */ 
+
+static inline bool
+replace_def_variable (var_map map, def_operand_p def_p, tree *expr)
+{
+  tree new_var;
+  tree var = DEF_FROM_PTR (def_p);
+
+  /* Check if we are replacing this variable with an expression.  */
+  if (expr)
+    {
+      int version = SSA_NAME_VERSION (var);
+      if (expr[version])
+        {
+         tree new_expr = TREE_OPERAND (expr[version], 1);
+         SET_DEF (def_p, new_expr);
+         /* Clear the stmt's RHS, or GC might bite us.  */
+         TREE_OPERAND (expr[version], 1) = NULL_TREE;
+         return true;
+       }
+    }
+
+  new_var = var_to_partition_to_var (map, var);
+  if (new_var)
+    {
+      SET_DEF (def_p, new_var);
       set_is_used (new_var);
       return true;
     }
@@ -1146,7 +1183,7 @@ coalesce_vars (var_map map, tree_live_info_p liveinfo)
    it is replaced with the RHS of the defining expression.  */
 
 
-/* Dependancy list element.  This can contain either a partition index or a
+/* Dependency list element.  This can contain either a partition index or a
    version number, depending on which list it is in.  */
 
 typedef struct value_expr_d 
@@ -1171,7 +1208,7 @@ typedef struct temp_expr_table_d
   value_expr_p pending_dependence;
 } *temp_expr_table_p;
 
-/* Used to indicate a dependancy on V_MAY_DEFs.  */
+/* Used to indicate a dependency on V_MAY_DEFs.  */
 #define VIRTUAL_PARTITION(table)       (table->virtual_partition)
 
 static temp_expr_table_p new_temp_expr_table (var_map);
@@ -1361,8 +1398,8 @@ remove_value_from_list (value_expr_p *list, int value)
 }
 
 
-/* Add a dependancy between the def of ssa VERSION and VAR.  if VAR is 
-   replaceable by an expression, add a dependance each of the elements of the 
+/* Add a dependency between the def of ssa VERSION and VAR.  If VAR is 
+   replaceable by an expression, add a dependence each of the elements of the 
    expression.  These are contained in the pending list.  TAB is the
    expression table.  */
 
@@ -1466,7 +1503,7 @@ check_replaceable (temp_expr_table_p tab, tree stmt)
 
   version = SSA_NAME_VERSION (def);
 
-  /* Add this expression to the dependancy list for each use partition.  */
+  /* Add this expression to the dependency list for each use partition.  */
   for (i = 0; i < num_use_ops; i++)
     {
       var = USE_OP (uses, i);
@@ -1498,7 +1535,7 @@ finish_expr (temp_expr_table_p tab, int version, bool replace)
   value_expr_p info, tmp;
   int partition;
 
-  /* Remove this expression from its dependent lists.  The partition dependance
+  /* Remove this expression from its dependent lists.  The partition dependence
      list is retained and transfered later to whomever uses this version.  */
   for (info = (value_expr_p) tab->version_info[version]; info; info = tmp)
     {
@@ -1514,7 +1551,7 @@ finish_expr (temp_expr_table_p tab, int version, bool replace)
         abort ();
 #endif
       free_value_expr (tab, tmp);
-      /* Only clear the bit when the dependancy list is emptied via 
+      /* Only clear the bit when the dependency list is emptied via 
          a replacement. Otherwise kill_expr will take care of it.  */
       if (!(tab->partition_dep_list[partition]) && replace)
         bitmap_clear_bit (tab->partition_in_use, partition);
@@ -1573,7 +1610,7 @@ kill_expr (temp_expr_table_p tab, int partition, bool clear_bit)
 {
   value_expr_p ptr;
 
-  /* Mark every active expr dependant on this var as not replaceable.  */
+  /* Mark every active expr dependent on this var as not replaceable.  */
   while ((ptr = tab->partition_dep_list[partition]) != NULL)
     finish_expr (tab, ptr->value, false);
 
@@ -1582,7 +1619,7 @@ kill_expr (temp_expr_table_p tab, int partition, bool clear_bit)
 }
 
 
-/* This function kills all expressions in TAB which are dependant on virtual 
+/* This function kills all expressions in TAB which are dependent on virtual 
    DEFs.  CLEAR_BIT determines whether partition_in_use gets cleared.  */
 
 static inline void
@@ -1643,7 +1680,7 @@ find_replaceable_in_bb (temp_expr_table_p tab, basic_block bb)
       if (!ann->has_volatile_ops)
        check_replaceable (tab, stmt);
 
-      /* Free any unused dependancy lists.  */
+      /* Free any unused dependency lists.  */
       while ((p = tab->pending_dependence))
        {
          tab->pending_dependence = p->next;
@@ -1726,17 +1763,24 @@ discover_nonconstant_array_refs_r (tree * tp, int *walk_subtrees,
 
   if (TYPE_P (t) || DECL_P (t))
     *walk_subtrees = 0;
-  else if (TREE_CODE (t) == ARRAY_REF)
+  else if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
     {
-      while ((TREE_CODE (t) == ARRAY_REF
-             && is_gimple_min_invariant (TREE_OPERAND (t, 1)))
+      while (((TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
+             && is_gimple_min_invariant (TREE_OPERAND (t, 1))
+             && (!TREE_OPERAND (t, 2)
+                 || is_gimple_min_invariant (TREE_OPERAND (t, 2))))
             || (TREE_CODE (t) == COMPONENT_REF
-                || TREE_CODE (t) == BIT_FIELD_REF
-                || TREE_CODE (t) == REALPART_EXPR
-                || TREE_CODE (t) == IMAGPART_EXPR))
+                && (!TREE_OPERAND (t,2)
+                    || is_gimple_min_invariant (TREE_OPERAND (t, 2))))
+            || TREE_CODE (t) == BIT_FIELD_REF
+            || TREE_CODE (t) == REALPART_EXPR
+            || TREE_CODE (t) == IMAGPART_EXPR
+            || TREE_CODE (t) == VIEW_CONVERT_EXPR
+            || TREE_CODE (t) == NOP_EXPR
+            || TREE_CODE (t) == CONVERT_EXPR)
        t = TREE_OPERAND (t, 0);
 
-      if (TREE_CODE (t) == ARRAY_REF)
+      if (TREE_CODE (t) == ARRAY_REF || TREE_CODE (t) == ARRAY_RANGE_REF)
        {
          t = get_base_address (t);
          if (t && DECL_P (t))
@@ -1832,7 +1876,7 @@ rewrite_trees (var_map map, tree *values)
          use_optype uses;
          def_optype defs;
          tree stmt = bsi_stmt (si);
-         tree *use_p = NULL;
+         use_operand_p use_p;
          int remove = 0, is_copy = 0;
          stmt_ann_t ann;
 
@@ -1850,7 +1894,7 @@ rewrite_trees (var_map map, tree *values)
          for (i = 0; i < num_uses; i++)
            {
              use_p = USE_OP_PTR (uses, i);
-             if (replace_variable (map, use_p, values))
+             if (replace_use_variable (map, use_p, values))
                changed = true;
            }
 
@@ -1871,18 +1915,16 @@ rewrite_trees (var_map map, tree *values)
            {
              for (i = 0; i < num_defs; i++)
                {
-                 tree *def_p = DEF_OP_PTR (defs, i);
+                 def_operand_p def_p = DEF_OP_PTR (defs, i);
 
-                 if (replace_variable (map, def_p, NULL))
+                 if (replace_def_variable (map, def_p, NULL))
                    changed = true;
 
                  /* If both SSA_NAMEs coalesce to the same variable,
                     mark the now redundant copy for removal.  */
                  if (is_copy
                      && num_uses == 1
-                     && use_p
-                     && def_p
-                     && (*def_p == *use_p))
+                     && (DEF_FROM_PTR (def_p) == USE_OP (uses, 0)))
                    remove = 1;
                }
              if (changed)
@@ -2074,7 +2116,7 @@ rewrite_vars_out_of_ssa (bitmap vars)
                      SSA_NAME_DEF_STMT (new_name) = copy;
 
                      /* Now make the argument reference our new SSA_NAME.  */
-                     PHI_ARG_DEF (phi, i) = new_name;
+                     SET_PHI_ARG_DEF (phi, i, new_name);
 
                      /* Queue the statement for insertion.  */
                      bsi_insert_on_edge (PHI_ARG_EDGE (phi, i), copy);