OSDN Git Service

2007-02-15 Paolo Bonzini <bonzini@gnu.org>
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-reassoc.c
index 879e570..e216f99 100644 (file)
@@ -38,6 +38,7 @@ Boston, MA 02110-1301, USA.  */
 #include "alloc-pool.h"
 #include "vec.h"
 #include "langhooks.h"
+#include "pointer-set.h"
 
 /*  This is a simple global reassociation pass.  It is, in part, based
     on the LLVM pass of the same name (They do some things more/less
@@ -179,68 +180,38 @@ static alloc_pool operand_entry_pool;
 /* Starting rank number for a given basic block, so that we can rank
    operations using unmovable instructions in that BB based on the bb
    depth.  */
-static unsigned int *bb_rank;
+static long *bb_rank;
 
 /* Operand->rank hashtable.  */
-static htab_t operand_rank;
+static struct pointer_map_t *operand_rank;
 
 
 /* Look up the operand rank structure for expression E.  */
 
-static operand_entry_t
+static inline long
 find_operand_rank (tree e)
 {
-  void **slot;
-  struct operand_entry vrd;
-
-  vrd.op = e;
-  slot = htab_find_slot (operand_rank, &vrd, NO_INSERT);
-  if (!slot)
-    return NULL;
-  return ((operand_entry_t) *slot);
+  void **slot = pointer_map_contains (operand_rank, e);
+  return slot ? (long) *slot : -1;
 }
 
 /* Insert {E,RANK} into the operand rank hashtable.  */
 
-static void
-insert_operand_rank (tree e, unsigned int rank)
+static inline void
+insert_operand_rank (tree e, long rank)
 {
   void **slot;
-  operand_entry_t new_pair = pool_alloc (operand_entry_pool);
-
-  new_pair->op = e;
-  new_pair->rank = rank;
-  slot = htab_find_slot (operand_rank, new_pair, INSERT);
-  gcc_assert (*slot == NULL);
-  *slot = new_pair;
-}
-
-/* Return the hash value for a operand rank structure  */
-
-static hashval_t
-operand_entry_hash (const void *p)
-{
-  const operand_entry_t vr = (operand_entry_t) p;
-  return iterative_hash_expr (vr->op, 0);
-}
-
-/* Return true if two operand rank structures are equal.  */
-
-static int
-operand_entry_eq (const void *p1, const void *p2)
-{
-  const operand_entry_t vr1 = (operand_entry_t) p1;
-  const operand_entry_t vr2 = (operand_entry_t) p2;
-  return vr1->op == vr2->op;
+  gcc_assert (rank > 0);
+  slot = pointer_map_insert (operand_rank, e);
+  gcc_assert (!*slot);
+  *slot = (void *) rank;
 }
 
 /* Given an expression E, return the rank of the expression.  */
 
-static unsigned int
+static long
 get_rank (tree e)
 {
-  operand_entry_t vr;
-
   /* Constants have rank 0.  */
   if (is_gimple_min_invariant (e))
     return 0;
@@ -260,31 +231,31 @@ get_rank (tree e)
     {
       tree stmt;
       tree rhs;
-      unsigned int rank, maxrank;
+      long rank, maxrank;
       int i;
 
       if (TREE_CODE (SSA_NAME_VAR (e)) == PARM_DECL
-         && e == default_def (SSA_NAME_VAR (e)))
-       return find_operand_rank (e)->rank;
+         && SSA_NAME_IS_DEFAULT_DEF (e))
+       return find_operand_rank (e);
 
       stmt = SSA_NAME_DEF_STMT (e);
       if (bb_for_stmt (stmt) == NULL)
        return 0;
 
-      if (TREE_CODE (stmt) != MODIFY_EXPR
+      if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT
          || !ZERO_SSA_OPERANDS (stmt, SSA_OP_VIRTUAL_DEFS))
        return bb_rank[bb_for_stmt (stmt)->index];
 
       /* If we already have a rank for this expression, use that.  */
-      vr = find_operand_rank (e);
-      if (vr)
-       return vr->rank;
+      rank = find_operand_rank (e);
+      if (rank != -1)
+       return rank;
 
       /* Otherwise, find the maximum rank for the operands, or the bb
         rank, whichever is less.   */
       rank = 0;
       maxrank = bb_rank[bb_for_stmt(stmt)->index];
-      rhs = TREE_OPERAND (stmt, 1);
+      rhs = GIMPLE_STMT_OPERAND (stmt, 1);
       if (TREE_CODE_LENGTH (TREE_CODE (rhs)) == 0)
        rank = MAX (rank, get_rank (rhs));
       else
@@ -301,7 +272,7 @@ get_rank (tree e)
        {
          fprintf (dump_file, "Rank for ");
          print_generic_expr (dump_file, e, 0);
-         fprintf (dump_file, " is %d\n", (rank + 1));
+         fprintf (dump_file, " is %ld\n", (rank + 1));
        }
 
       /* Note the rank in the hashtable so we don't recompute it.  */
@@ -378,9 +349,9 @@ static bool
 is_reassociable_op (tree stmt, enum tree_code code)
 {
   if (!IS_EMPTY_STMT (stmt)
-      && TREE_CODE (stmt) == MODIFY_EXPR
-      && TREE_CODE (TREE_OPERAND (stmt, 1)) == code
-      && has_single_use (TREE_OPERAND (stmt, 0)))
+      && TREE_CODE (stmt) == GIMPLE_MODIFY_STMT
+      && TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == code
+      && has_single_use (GIMPLE_STMT_OPERAND (stmt, 0)))
     return true;
   return false;
 }
@@ -395,10 +366,10 @@ get_unary_op (tree name, enum tree_code opcode)
   tree stmt = SSA_NAME_DEF_STMT (name);
   tree rhs;
 
-  if (TREE_CODE (stmt) != MODIFY_EXPR)
+  if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT)
     return NULL_TREE;
 
-  rhs = TREE_OPERAND (stmt, 1);
+  rhs = GIMPLE_STMT_OPERAND (stmt, 1);
   if (TREE_CODE (rhs) == opcode)
     return TREE_OPERAND (rhs, 0);
   return NULL_TREE;
@@ -417,8 +388,8 @@ eliminate_duplicate_pair (enum tree_code opcode,
                          operand_entry_t last)
 {
 
-  /* If we have two of the same op, and the opcode is & or |, we can
-     eliminate one of them.
+  /* If we have two of the same op, and the opcode is & |, min, or max,
+     we can eliminate one of them.
      If we have two of the same op, and the opcode is ^, we can
      eliminate both of them.  */
 
@@ -426,13 +397,15 @@ eliminate_duplicate_pair (enum tree_code opcode,
     {
       switch (opcode)
        {
+       case MAX_EXPR:
+       case MIN_EXPR:
        case BIT_IOR_EXPR:
        case BIT_AND_EXPR:
          if (dump_file && (dump_flags & TDF_DETAILS))
            {
              fprintf (dump_file, "Equivalence: ");
              print_generic_expr (dump_file, curr->op, 0);
-             fprintf (dump_file, " [&|] ");
+             fprintf (dump_file, " [&|minmax] ");
              print_generic_expr (dump_file, last->op, 0);
              fprintf (dump_file, " -> ");
              print_generic_stmt (dump_file, last->op, 0);
@@ -812,7 +785,7 @@ static bool
 is_phi_for_stmt (tree stmt, tree operand)
 {
   tree def_stmt;
-  tree lhs = TREE_OPERAND (stmt, 0);
+  tree lhs = GIMPLE_STMT_OPERAND (stmt, 0);
   use_operand_p arg_p;
   ssa_op_iter i;
 
@@ -837,7 +810,7 @@ static void
 rewrite_expr_tree (tree stmt, unsigned int opindex,
                   VEC(operand_entry_t, heap) * ops)
 {
-  tree rhs = TREE_OPERAND (stmt, 1);
+  tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
   operand_entry_t oe;
 
   /* If we have three operands left, then we want to make sure the one
@@ -950,7 +923,7 @@ static void
 linearize_expr (tree stmt)
 {
   block_stmt_iterator bsinow, bsirhs;
-  tree rhs = TREE_OPERAND (stmt, 1);
+  tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
   enum tree_code rhscode = TREE_CODE (rhs);
   tree binrhs = SSA_NAME_DEF_STMT (TREE_OPERAND (rhs, 1));
   tree binlhs = SSA_NAME_DEF_STMT (TREE_OPERAND (rhs, 0));
@@ -963,11 +936,12 @@ linearize_expr (tree stmt)
   bsirhs = bsi_for_stmt (binrhs);
   bsi_move_before (&bsirhs, &bsinow);
 
-  TREE_OPERAND (rhs, 1) = TREE_OPERAND (TREE_OPERAND (binrhs, 1), 0);
+  TREE_OPERAND (rhs, 1) = TREE_OPERAND (GIMPLE_STMT_OPERAND (binrhs, 1), 0);
   if (TREE_CODE (TREE_OPERAND (rhs, 1)) == SSA_NAME)
     newbinrhs = SSA_NAME_DEF_STMT (TREE_OPERAND (rhs, 1));
-  TREE_OPERAND (TREE_OPERAND (binrhs, 1), 0) = TREE_OPERAND (binlhs, 0);
-  TREE_OPERAND (rhs, 0) = TREE_OPERAND (binrhs, 0);
+  TREE_OPERAND (GIMPLE_STMT_OPERAND (binrhs, 1), 0)
+    = GIMPLE_STMT_OPERAND (binlhs, 0);
+  TREE_OPERAND (rhs, 0) = GIMPLE_STMT_OPERAND (binrhs, 0);
 
   if (dump_file && (dump_flags & TDF_DETAILS))
     {
@@ -989,7 +963,7 @@ linearize_expr (tree stmt)
 
 }
 
-/* If LHS has a single immediate use that is a MODIFY_EXPR, return
+/* If LHS has a single immediate use that is a GIMPLE_MODIFY_STMT, return
    it.  Otherwise, return NULL.  */
 
 static tree
@@ -1003,7 +977,7 @@ get_single_immediate_use (tree lhs)
     {
       if (TREE_CODE (immusestmt) == RETURN_EXPR)
        immusestmt = TREE_OPERAND (immusestmt, 0);
-      if (TREE_CODE (immusestmt) == MODIFY_EXPR)
+      if (TREE_CODE (immusestmt) == GIMPLE_MODIFY_STMT)
        return immusestmt;
     }
   return NULL_TREE;
@@ -1030,13 +1004,13 @@ negate_value (tree tonegate, block_stmt_iterator *bsi)
   /* If we are trying to negate a name, defined by an add, negate the
      add operands instead.  */
   if (TREE_CODE (tonegate) == SSA_NAME
-      && TREE_CODE (negatedef) == MODIFY_EXPR
-      && TREE_CODE (TREE_OPERAND (negatedef, 0)) == SSA_NAME
-      && num_imm_uses (TREE_OPERAND (negatedef, 0)) == 1
-      && TREE_CODE (TREE_OPERAND (negatedef, 1)) == PLUS_EXPR)
+      && TREE_CODE (negatedef) == GIMPLE_MODIFY_STMT
+      && TREE_CODE (GIMPLE_STMT_OPERAND (negatedef, 0)) == SSA_NAME
+      && has_single_use (GIMPLE_STMT_OPERAND (negatedef, 0))
+      && TREE_CODE (GIMPLE_STMT_OPERAND (negatedef, 1)) == PLUS_EXPR)
     {
       block_stmt_iterator bsi;
-      tree binop = TREE_OPERAND (negatedef, 1);
+      tree binop = GIMPLE_STMT_OPERAND (negatedef, 1);
 
       bsi = bsi_for_stmt (negatedef);
       TREE_OPERAND (binop, 0) = negate_value (TREE_OPERAND (binop, 0),
@@ -1045,7 +1019,7 @@ negate_value (tree tonegate, block_stmt_iterator *bsi)
       TREE_OPERAND (binop, 1) = negate_value (TREE_OPERAND (binop, 1),
                                              &bsi);
       update_stmt (negatedef);
-      return TREE_OPERAND (negatedef, 0);
+      return GIMPLE_STMT_OPERAND (negatedef, 0);
     }
 
   tonegate = fold_build1 (NEGATE_EXPR, TREE_TYPE (tonegate), tonegate);
@@ -1066,8 +1040,8 @@ static bool
 should_break_up_subtract (tree stmt)
 {
 
-  tree lhs = TREE_OPERAND (stmt, 0);
-  tree rhs = TREE_OPERAND (stmt, 1);
+  tree lhs = GIMPLE_STMT_OPERAND (stmt, 0);
+  tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
   tree binlhs = TREE_OPERAND (rhs, 0);
   tree binrhs = TREE_OPERAND (rhs, 1);
   tree immusestmt;
@@ -1082,7 +1056,7 @@ should_break_up_subtract (tree stmt)
 
   if (TREE_CODE (lhs) == SSA_NAME
       && (immusestmt = get_single_immediate_use (lhs))
-      && TREE_CODE (TREE_OPERAND (immusestmt, 1)) == PLUS_EXPR)
+      && TREE_CODE (GIMPLE_STMT_OPERAND (immusestmt, 1)) == PLUS_EXPR)
     return true;
   return false;
 
@@ -1093,7 +1067,7 @@ should_break_up_subtract (tree stmt)
 static void
 break_up_subtract (tree stmt, block_stmt_iterator *bsi)
 {
-  tree rhs = TREE_OPERAND (stmt, 1);
+  tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
 
   if (dump_file && (dump_flags & TDF_DETAILS))
     {
@@ -1101,7 +1075,7 @@ break_up_subtract (tree stmt, block_stmt_iterator *bsi)
       print_generic_stmt (dump_file, stmt, 0);
     }
 
-  TREE_SET_CODE (TREE_OPERAND (stmt, 1), PLUS_EXPR);
+  TREE_SET_CODE (GIMPLE_STMT_OPERAND (stmt, 1), PLUS_EXPR);
   TREE_OPERAND (rhs, 1) = negate_value (TREE_OPERAND (rhs, 1), bsi);
 
   update_stmt (stmt);
@@ -1114,7 +1088,7 @@ static void
 linearize_expr_tree (VEC(operand_entry_t, heap) **ops, tree stmt)
 {
   block_stmt_iterator bsinow, bsilhs;
-  tree rhs = TREE_OPERAND (stmt, 1);
+  tree rhs = GENERIC_TREE_OPERAND (stmt, 1);
   tree binrhs = TREE_OPERAND (rhs, 1);
   tree binlhs = TREE_OPERAND (rhs, 0);
   tree binlhsdef, binrhsdef;
@@ -1178,7 +1152,7 @@ linearize_expr_tree (VEC(operand_entry_t, heap) **ops, tree stmt)
   else if (binrhsisreassoc)
     {
       linearize_expr (stmt);
-      gcc_assert (rhs == TREE_OPERAND (stmt, 1));
+      gcc_assert (rhs == GIMPLE_STMT_OPERAND (stmt, 1));
       binlhs = TREE_OPERAND (rhs, 0);
       binrhs = TREE_OPERAND (rhs, 1);
     }
@@ -1211,15 +1185,15 @@ repropagate_negates (void)
         Force the negate operand to the RHS of the PLUS_EXPR, then
         transform the PLUS_EXPR into a MINUS_EXPR.  */
       if (user
-         && TREE_CODE (user) == MODIFY_EXPR
-         && TREE_CODE (TREE_OPERAND (user, 1)) == PLUS_EXPR)
+         && TREE_CODE (user) == GIMPLE_MODIFY_STMT
+         && TREE_CODE (GIMPLE_STMT_OPERAND (user, 1)) == PLUS_EXPR)
        {
-         tree rhs = TREE_OPERAND (user, 1);
+         tree rhs = GIMPLE_STMT_OPERAND (user, 1);
 
          /* If the negated operand appears on the LHS of the
             PLUS_EXPR, exchange the operands of the PLUS_EXPR
             to force the negated operand to the RHS of the PLUS_EXPR.  */
-         if (TREE_OPERAND (TREE_OPERAND (user, 1), 0) == negate)
+         if (TREE_OPERAND (GIMPLE_STMT_OPERAND (user, 1), 0) == negate)
            {
              tree temp = TREE_OPERAND (rhs, 0);
              TREE_OPERAND (rhs, 0) = TREE_OPERAND (rhs, 1);
@@ -1228,7 +1202,7 @@ repropagate_negates (void)
 
          /* Now transform the PLUS_EXPR into a MINUS_EXPR and replace
             the RHS of the PLUS_EXPR with the operand of the NEGATE_EXPR.  */
-         if (TREE_OPERAND (TREE_OPERAND (user, 1), 1) == negate)
+         if (TREE_OPERAND (GIMPLE_STMT_OPERAND (user, 1), 1) == negate)
            {
              TREE_SET_CODE (rhs, MINUS_EXPR);
              TREE_OPERAND (rhs, 1) = get_unary_op (negate, NEGATE_EXPR);
@@ -1263,10 +1237,10 @@ break_up_subtract_bb (basic_block bb)
     {
       tree stmt = bsi_stmt (bsi);
 
-      if (TREE_CODE (stmt) == MODIFY_EXPR)
+      if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
        {
-         tree lhs = TREE_OPERAND (stmt, 0);
-         tree rhs = TREE_OPERAND (stmt, 1);
+         tree lhs = GIMPLE_STMT_OPERAND (stmt, 0);
+         tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
 
          TREE_VISITED (stmt) = 0;
          /* If unsafe math optimizations we can do reassociation for
@@ -1306,10 +1280,10 @@ reassociate_bb (basic_block bb)
     {
       tree stmt = bsi_stmt (bsi);
 
-      if (TREE_CODE (stmt) == MODIFY_EXPR)
+      if (TREE_CODE (stmt) == GIMPLE_MODIFY_STMT)
        {
-         tree lhs = TREE_OPERAND (stmt, 0);
-         tree rhs = TREE_OPERAND (stmt, 1);
+         tree lhs = GIMPLE_STMT_OPERAND (stmt, 0);
+         tree rhs = GIMPLE_STMT_OPERAND (stmt, 1);
 
          /* If this was part of an already processed tree, we don't
             need to touch it again. */
@@ -1331,7 +1305,7 @@ reassociate_bb (basic_block bb)
 
              /* There may be no immediate uses left by the time we
                 get here because we may have eliminated them all.  */
-             if (TREE_CODE (lhs) == SSA_NAME && num_imm_uses (lhs) == 0)
+             if (TREE_CODE (lhs) == SSA_NAME && has_zero_uses (lhs))
                continue;
 
              TREE_VISITED (stmt) = 1;
@@ -1349,14 +1323,15 @@ reassociate_bb (basic_block bb)
                      fprintf (dump_file, "Transforming ");
                      print_generic_expr (dump_file, rhs, 0);
                    }
-                 TREE_OPERAND (stmt, 1) = VEC_last (operand_entry_t, ops)->op;
+                 GIMPLE_STMT_OPERAND (stmt, 1) 
+                   = VEC_last (operand_entry_t, ops)->op;
                  update_stmt (stmt);
 
                  if (dump_file && (dump_flags & TDF_DETAILS))
                    {
                      fprintf (dump_file, " into ");
                      print_generic_stmt (dump_file,
-                                         TREE_OPERAND (stmt, 1), 0);
+                                         GIMPLE_STMT_OPERAND (stmt, 1), 0);
                    }
                }
              else
@@ -1413,9 +1388,9 @@ static void
 init_reassoc (void)
 {
   int i;
-  unsigned int rank = 2;
+  long rank = 2;
   tree param;
-  int *bbs = xmalloc ((last_basic_block + 1) * sizeof (int));
+  int *bbs = XNEWVEC (int, last_basic_block + 1);
 
   memset (&reassociate_stats, 0, sizeof (reassociate_stats));
 
@@ -1425,19 +1400,17 @@ init_reassoc (void)
   /* Reverse RPO (Reverse Post Order) will give us something where
      deeper loops come later.  */
   pre_and_rev_post_order_compute (NULL, bbs, false);
-  bb_rank = xcalloc (last_basic_block + 1, sizeof (unsigned int));
-  
-  operand_rank = htab_create (511, operand_entry_hash,
-                             operand_entry_eq, 0);
+  bb_rank = XCNEWVEC (long, last_basic_block + 1);
+  operand_rank = pointer_map_create ();
 
   /* Give each argument a distinct rank.   */
   for (param = DECL_ARGUMENTS (current_function_decl);
        param;
        param = TREE_CHAIN (param))
     {
-      if (default_def (param) != NULL)
+      if (gimple_default_def (cfun, param) != NULL)
        {
-         tree def = default_def (param);
+         tree def = gimple_default_def (cfun, param);
          insert_operand_rank (def, ++rank);
        }
     }
@@ -1445,7 +1418,7 @@ init_reassoc (void)
   /* Give the chain decl a distinct rank. */
   if (cfun->static_chain_decl != NULL)
     {
-      tree def = default_def (cfun->static_chain_decl);
+      tree def = gimple_default_def (cfun, cfun->static_chain_decl);
       if (def != NULL)
        insert_operand_rank (def, ++rank);
     }
@@ -1479,8 +1452,8 @@ fini_reassoc (void)
       fprintf (dump_file, "Statements rewritten: %d\n",
               reassociate_stats.rewritten);
     }
-  htab_delete (operand_rank);
 
+  pointer_map_destroy (operand_rank);
   free_alloc_pool (operand_entry_pool);
   free (bb_rank);
   VEC_free (tree, heap, broken_up_subtracts);
@@ -1489,7 +1462,7 @@ fini_reassoc (void)
 
 /* Gate and execute functions for Reassociation.  */
 
-static void
+static unsigned int
 execute_reassoc (void)
 {
   init_reassoc ();
@@ -1498,6 +1471,7 @@ execute_reassoc (void)
   repropagate_negates ();
 
   fini_reassoc ();
+  return 0;
 }
 
 struct tree_opt_pass pass_reassoc =