OSDN Git Service

PR middle-end/40815
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-reassoc.c
index 5fd5967..cf05de5 100644 (file)
@@ -1,5 +1,5 @@
 /* Reassociation for trees.
-   Copyright (C) 2005, 2007, 2008, 2009 Free Software Foundation, Inc.
+   Copyright (C) 2005, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
    Contributed by Daniel Berlin <dan@dberlin.org>
 
 This file is part of GCC.
@@ -32,6 +32,7 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-dump.h"
 #include "timevar.h"
 #include "tree-iterator.h"
+#include "real.h"
 #include "tree-pass.h"
 #include "alloc-pool.h"
 #include "vec.h"
@@ -466,6 +467,8 @@ eliminate_duplicate_pair (enum tree_code opcode,
   return false;
 }
 
+static VEC(tree, heap) *plus_negates;
+
 /* If OPCODE is PLUS_EXPR, CURR->OP is really a negate expression,
    look in OPS for a corresponding positive operation to cancel it
    out.  If we find one, remove the other from OPS, replace
@@ -520,6 +523,10 @@ eliminate_plus_minus_pair (enum tree_code opcode,
        }
     }
 
+  /* CURR->OP is a negate expr in a plus expr: save it for later
+     inspection in repropagate_negates().  */
+  VEC_safe_push (tree, heap, plus_negates, curr->op);
+
   return false;
 }
 
@@ -844,7 +851,7 @@ build_and_add_sum (tree tmpvar, tree op1, tree op2, enum tree_code opcode)
   if ((!op1def || gimple_nop_p (op1def))
       && (!op2def || gimple_nop_p (op2def)))
     {
-      gsi = gsi_start_bb (single_succ (ENTRY_BLOCK_PTR));
+      gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR));
       gsi_insert_before (&gsi, sum, GSI_NEW_STMT);
     }
   else if ((!op1def || gimple_nop_p (op1def))
@@ -853,7 +860,7 @@ build_and_add_sum (tree tmpvar, tree op1, tree op2, enum tree_code opcode)
     {
       if (gimple_code (op2def) == GIMPLE_PHI)
        {
-         gsi = gsi_start_bb (gimple_bb (op2def));
+         gsi = gsi_after_labels (gimple_bb (op2def));
          gsi_insert_before (&gsi, sum, GSI_NEW_STMT);
        }
       else
@@ -878,7 +885,7 @@ build_and_add_sum (tree tmpvar, tree op1, tree op2, enum tree_code opcode)
     {
       if (gimple_code (op1def) == GIMPLE_PHI)
        {
-         gsi = gsi_start_bb (gimple_bb (op1def));
+         gsi = gsi_after_labels (gimple_bb (op1def));
          gsi_insert_before (&gsi, sum, GSI_NEW_STMT);
        }
       else
@@ -1499,8 +1506,6 @@ get_single_immediate_use (tree lhs)
   return NULL;
 }
 
-static VEC(tree, heap) *broken_up_subtracts;
-
 /* Recursively negate the value of TONEGATE, and return the SSA_NAME
    representing the negated value.  Insertions of any necessary
    instructions go before GSI.
@@ -1543,7 +1548,6 @@ negate_value (tree tonegate, gimple_stmt_iterator *gsi)
   tonegate = fold_build1 (NEGATE_EXPR, TREE_TYPE (tonegate), tonegate);
   resultofnegate = force_gimple_operand_gsi (gsi, tonegate, true,
                                             NULL_TREE, true, GSI_SAME_STMT);
-  VEC_safe_push (tree, heap, broken_up_subtracts, resultofnegate);
   return resultofnegate;
 }
 
@@ -1699,7 +1703,7 @@ repropagate_negates (void)
   unsigned int i = 0;
   tree negate;
 
-  for (i = 0; VEC_iterate (tree, broken_up_subtracts, i, negate); i++)
+  for (i = 0; VEC_iterate (tree, plus_negates, i, negate); i++)
     {
       gimple user = get_single_immediate_use (negate);
 
@@ -2013,7 +2017,7 @@ init_reassoc (void)
 
   free (bbs);
   calculate_dominance_info (CDI_POST_DOMINATORS);
-  broken_up_subtracts = NULL;
+  plus_negates = NULL;
 }
 
 /* Cleanup after the reassociation pass, and print stats if
@@ -2034,7 +2038,7 @@ fini_reassoc (void)
   pointer_map_destroy (operand_rank);
   free_alloc_pool (operand_entry_pool);
   free (bb_rank);
-  VEC_free (tree, heap, broken_up_subtracts);
+  VEC_free (tree, heap, plus_negates);
   free_dominance_info (CDI_POST_DOMINATORS);
   loop_optimizer_finalize ();
 }