OSDN Git Service

2008-01-12 Sebastian Pop <sebastian.pop@amd.com>
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-ter.c
index 2bd58cc..670d963 100644 (file)
@@ -1,12 +1,12 @@
 /* Routines for performing Temporary Expression Replacement (TER) in SSA trees.
-   Copyright (C) 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
    Contributed by Andrew MacLeod  <amacleod@redhat.com>
 
 This file is part of GCC.
 
 GCC is free software; you can redistribute it and/or modify
 it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
 any later version.
 
 GCC is distributed in the hope that it will be useful,
@@ -15,9 +15,8 @@ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 GNU General Public License for more details.
 
 You should have received a copy of the GNU General Public License
-along with GCC; see the file COPYING.  If not, write to
-the Free Software Foundation, 51 Franklin Street, Fifth Floor,
-Boston, MA 02110-1301, USA.  */
+along with GCC; see the file COPYING3.  If not see
+<http://www.gnu.org/licenses/>.  */
 
 
 #include "config.h"
@@ -25,29 +24,11 @@ Boston, MA 02110-1301, USA.  */
 #include "coretypes.h"
 #include "tm.h"
 #include "tree.h"
-#include "flags.h"
-#include "rtl.h"
-#include "tm_p.h"
-#include "ggc.h"
-#include "langhooks.h"
-#include "hard-reg-set.h"
-#include "basic-block.h"
-#include "output.h"
-#include "expr.h"
-#include "function.h"
 #include "diagnostic.h"
 #include "bitmap.h"
 #include "tree-flow.h"
-#include "tree-gimple.h"
-#include "tree-inline.h"
-#include "varray.h"
-#include "timevar.h"
-#include "hashtab.h"
 #include "tree-dump.h"
 #include "tree-ssa-live.h"
-#include "tree-pass.h"
-#include "toplev.h"
-#include "vecprim.h"
 
 
 /* Temporary Expression Replacement (TER)
@@ -98,13 +79,13 @@ Boston, MA 02110-1301, USA.  */
    v_9 = a_2 * n_12
    <...>
 
-   If b_5, b_8 and b_14 are all colaesced together...
+   If b_5, b_8 and b_14 are all coalesced together...
    The expression b_5 + 6 CANNOT replace the use in the statement defining v_9
    because b_8 is in fact killing the value of b_5 since they share a partition
-   and will be assigned the same memory or regster location.
+   and will be assigned the same memory or register location.
    
    TER implements this but stepping through the instructions in a block and
-   tracking potential expressions for replacement, and the paritions they are
+   tracking potential expressions for replacement, and the partitions they are
    dependent on.  Expressions are represented by the SSA_NAME_VERSION of the
    DEF on the LHS of a GIMPLE_MODIFY_STMT and the expression is the RHS.
 
@@ -128,8 +109,8 @@ Boston, MA 02110-1301, USA.  */
    an expression from the partition kill lists when a decision is made whether
    to replace it or not.  This is indexed by ssa version number as well, and
    indicates a partition number.  virtual operands are not tracked individually,
-   but they are summarized by an artifical partition called VIRTUAL_PARTITION.
-   This means a MAY or MUST def will kill *ALL* expressions that are dependant
+   but they are summarized by an artificial partition called VIRTUAL_PARTITION.
+   This means a MAY or MUST def will kill *ALL* expressions that are dependent
    on a virtual operand.
    Note that the EXPR_DECL_UID and this bitmap represent very similar 
    information, but the info in one is not easy to obtain from the other.
@@ -139,11 +120,11 @@ Boston, MA 02110-1301, USA.  */
    longer be valid if a definition into this partition takes place.
 
    PARTITION_IN_USE is simply a bitmap which is used to track which partitions
-   currently have sokmething in their kill list.  This is used at the end of 
+   currently have something in their kill list.  This is used at the end of 
    a block to clear out the KILL_LIST bitmaps at the end of each block.
 
    NEW_REPLACEABLE_DEPENDENCIES is used as a temporary place to store 
-   dependencies which will be reused by the current defintion. ALl the uses
+   dependencies which will be reused by the current definition. ALl the uses
    on an expression are processed before anything else is done. If a use is
    determined to be a replaceable expression AND the current stmt is also going
    to be replaceable, all the dependencies of this replaceable use will be
@@ -179,13 +160,13 @@ typedef struct temp_expr_table_d
   tree *replaceable_expressions;       /* Replacement expression table.  */
   bitmap *expr_decl_uids;              /* Base uids of exprs.  */
   bitmap *kill_list;                   /* Expr's killed by a partition.  */
-  int virtual_partition;               /* Psuedo partition for virtual ops.  */
-  bitmap partition_in_use;             /* Partitions with kill entires.  */
+  int virtual_partition;               /* Pseudo partition for virtual ops.  */
+  bitmap partition_in_use;             /* Partitions with kill entries.  */
   bitmap new_replaceable_dependencies; /* Holding place for pending dep's.  */
   int *num_in_part;                    /* # of ssa_names in a partition.  */
 } *temp_expr_table_p;
 
-/* Used to indicate a dependency on V_MAY_DEFs.  */
+/* Used to indicate a dependency on VDEFs.  */
 #define VIRTUAL_PARTITION(table)       (table->virtual_partition)
 
 #ifdef ENABLE_CHECKING
@@ -246,6 +227,7 @@ free_temp_expr_table (temp_expr_table_p t)
 #endif
 
   BITMAP_FREE (t->partition_in_use);
+  BITMAP_FREE (t->new_replaceable_dependencies);
 
   for (i = 0; i <= num_ssa_names; i++)
     if (t->expr_decl_uids[i])
@@ -254,6 +236,7 @@ free_temp_expr_table (temp_expr_table_p t)
 
   free (t->kill_list);
   free (t->partition_dependencies);
+  free (t->num_in_part);
 
   if (t->replaceable_expressions)
     ret = t->replaceable_expressions;
@@ -274,7 +257,7 @@ version_to_be_replaced_p (temp_expr_table_p tab, int version)
 }
 
 
-/* Add partition P to the list if partititons VERSION is dependent on.  TAB is 
+/* Add partition P to the list if partitions VERSION is dependent on.  TAB is 
    the expression table */
 
 static inline void
@@ -385,6 +368,10 @@ is_replaceable_p (tree stmt)
   if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
     return false;
 
+  /* If the statement may throw an exception, it cannot be replaced.  */
+  if (tree_could_throw_p (stmt))
+    return false;
+
   /* Punt if there is more than 1 def.  */
   def = SINGLE_SSA_TREE_OPERAND (stmt, SSA_OP_DEF);
   if (!def)
@@ -402,8 +389,8 @@ is_replaceable_p (tree stmt)
   if (TREE_CODE (use_stmt) == PHI_NODE)
     return false;
 
-  /* There must be no V_MAY_DEFS or V_MUST_DEFS.  */
-  if (!(ZERO_SSA_OPERANDS (stmt, (SSA_OP_VMAYDEF | SSA_OP_VMUSTDEF))))
+  /* There must be no VDEFs.  */
+  if (!(ZERO_SSA_OPERANDS (stmt, SSA_OP_VDEF)))
     return false;
 
   /* Float expressions must go through memory if float-store is on.  */
@@ -411,16 +398,17 @@ is_replaceable_p (tree stmt)
       && FLOAT_TYPE_P (TREE_TYPE (GENERIC_TREE_OPERAND (stmt, 1))))
     return false;
 
-  /* Calls to functions with side-effects cannot be replaced.  */
+  /* An assignment with a register variable on the RHS is not
+     replaceable.  */
+  if (TREE_CODE (GENERIC_TREE_OPERAND (stmt, 1)) == VAR_DECL
+      && DECL_HARD_REGISTER (GENERIC_TREE_OPERAND (stmt, 1)))
+    return false;
+
+  /* No function calls can be replaced.  */
   if ((call_expr = get_call_expr_in (stmt)) != NULL_TREE)
-    {
-      int call_flags = call_expr_flags (call_expr);
-      if (TREE_SIDE_EFFECTS (call_expr)
-         && !(call_flags & (ECF_PURE | ECF_CONST | ECF_NORETURN)))
-       return false;
-    }
+    return false;
 
-  /* Leave any stmt with voltile operands alone as well.  */
+  /* Leave any stmt with volatile operands alone as well.  */
   if (stmt_ann (stmt)->has_volatile_ops)
     return false;
   
@@ -452,7 +440,7 @@ finished_with_expr (temp_expr_table_p tab, int version, bool free_expr)
 }
 
 
-/* Create an expression entry fora replaceable expression.  */
+/* Create an expression entry for a replaceable expression.  */
 
 static void 
 process_replaceable (temp_expr_table_p tab, tree stmt)
@@ -690,7 +678,8 @@ dump_replaceable_exprs (FILE *f, tree *expr)
        gcc_assert (var != NULL_TREE);
        print_generic_expr (f, var, TDF_SLIM);
        fprintf (f, " replace with --> ");
-       print_generic_expr (f, TREE_OPERAND (stmt, 1), TDF_SLIM);
+       print_generic_expr (f, GENERIC_TREE_OPERAND (stmt, 1),
+                           TDF_SLIM);
        fprintf (f, "\n");
       }
   fprintf (f, "\n");