OSDN Git Service

* gcc.c (getenv_spec_function): New function.
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-threadedge.c
index b8d4b13..72018c0 100644 (file)
@@ -1,5 +1,5 @@
 /* SSA Jump Threading
-   Copyright (C) 2005, 2006 Free Software Foundation, Inc.
+   Copyright (C) 2005, 2006, 2007 Free Software Foundation, Inc.
    Contributed by Jeff Law  <law@redhat.com>
 
 This file is part of GCC.
@@ -84,18 +84,20 @@ static tree
 lhs_of_dominating_assert (tree op, basic_block bb, tree stmt)
 {
   imm_use_iterator imm_iter;
-  use_operand_p imm_use;
+  tree use_stmt;
+  use_operand_p use_p;
 
-  FOR_EACH_IMM_USE_SAFE (imm_use, imm_iter, op)
+  FOR_EACH_IMM_USE_FAST (use_p, imm_iter, op)
     {
-      tree use_stmt = USE_STMT (imm_use);
-
+      use_stmt = USE_STMT (use_p);
       if (use_stmt != stmt
-          && TREE_CODE (use_stmt) == MODIFY_EXPR
-          && TREE_CODE (TREE_OPERAND (use_stmt, 1)) == ASSERT_EXPR
-          && TREE_OPERAND (TREE_OPERAND (use_stmt, 1), 0) == op
+          && TREE_CODE (use_stmt) == GIMPLE_MODIFY_STMT
+          && TREE_CODE (GIMPLE_STMT_OPERAND (use_stmt, 1)) == ASSERT_EXPR
+          && TREE_OPERAND (GIMPLE_STMT_OPERAND (use_stmt, 1), 0) == op
          && dominated_by_p (CDI_DOMINATORS, bb, bb_for_stmt (use_stmt)))
-       op = TREE_OPERAND (use_stmt, 0);
+       {
+         return GIMPLE_STMT_OPERAND (use_stmt, 0);
+       }
     }
   return op;
 }
@@ -120,7 +122,7 @@ remove_temporary_equivalences (VEC(tree, heap) **stack)
 
       dest = VEC_pop (tree, *stack);
 
-      /* A NULL value indicates we should stop unwinding, oherwise
+      /* A NULL value indicates we should stop unwinding, otherwise
         pop off the next entry as they're recorded in pairs.  */
       if (dest == NULL)
        break;
@@ -243,11 +245,11 @@ record_temporary_equivalences_from_stmts_at_dest (edge e,
       if (stmt_count > max_stmt_count)
        return NULL;
 
-      /* If this is not a MODIFY_EXPR which sets an SSA_NAME to a new
+      /* If this is not a GIMPLE_MODIFY_STMT which sets an SSA_NAME to a new
         value, then do not try to simplify this statement as it will
         not simplify in any way that is helpful for jump threading.  */
-      if (TREE_CODE (stmt) != MODIFY_EXPR
-         || TREE_CODE (TREE_OPERAND (stmt, 0)) != SSA_NAME)
+      if (TREE_CODE (stmt) != GIMPLE_MODIFY_STMT
+         || TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) != SSA_NAME)
        continue;
 
       /* At this point we have a statement which assigns an RHS to an
@@ -257,10 +259,10 @@ record_temporary_equivalences_from_stmts_at_dest (edge e,
 
         Handle simple copy operations as well as implied copies from
         ASSERT_EXPRs.  */
-      if (TREE_CODE (TREE_OPERAND (stmt, 1)) == SSA_NAME)
-       cached_lhs = TREE_OPERAND (stmt, 1);
-      else if (TREE_CODE (TREE_OPERAND (stmt, 1)) == ASSERT_EXPR)
-       cached_lhs = TREE_OPERAND (TREE_OPERAND (stmt, 1), 0);
+      if (TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == SSA_NAME)
+       cached_lhs = GIMPLE_STMT_OPERAND (stmt, 1);
+      else if (TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == ASSERT_EXPR)
+       cached_lhs = TREE_OPERAND (GIMPLE_STMT_OPERAND (stmt, 1), 0);
       else
        {
          /* A statement that is not a trivial copy or ASSERT_EXPR.
@@ -294,19 +296,19 @@ record_temporary_equivalences_from_stmts_at_dest (edge e,
             here, because fold expects all the operands of an expression
             to be folded before the expression itself is folded, but we
             can't just substitute the folded condition here.  */
-         if (TREE_CODE (TREE_OPERAND (stmt, 1)) == COND_EXPR)
+         if (TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 1)) == COND_EXPR)
            {
-             tree cond = COND_EXPR_COND (TREE_OPERAND (stmt, 1));
+             tree cond = COND_EXPR_COND (GIMPLE_STMT_OPERAND (stmt, 1));
              cond = fold (cond);
              if (cond == boolean_true_node)
-               pre_fold_expr = COND_EXPR_THEN (TREE_OPERAND (stmt, 1));
+               pre_fold_expr = COND_EXPR_THEN (GIMPLE_STMT_OPERAND (stmt, 1));
              else if (cond == boolean_false_node)
-               pre_fold_expr = COND_EXPR_ELSE (TREE_OPERAND (stmt, 1));
+               pre_fold_expr = COND_EXPR_ELSE (GIMPLE_STMT_OPERAND (stmt, 1));
              else
-               pre_fold_expr = TREE_OPERAND (stmt, 1);
+               pre_fold_expr = GIMPLE_STMT_OPERAND (stmt, 1);
            }
          else
-           pre_fold_expr = TREE_OPERAND (stmt, 1);
+           pre_fold_expr = GIMPLE_STMT_OPERAND (stmt, 1);
 
          if (pre_fold_expr)
            {
@@ -329,7 +331,7 @@ record_temporary_equivalences_from_stmts_at_dest (edge e,
       if (cached_lhs
          && (TREE_CODE (cached_lhs) == SSA_NAME
              || is_gimple_min_invariant (cached_lhs)))
-       record_temporary_equivalence (TREE_OPERAND (stmt, 0),
+       record_temporary_equivalence (GIMPLE_STMT_OPERAND (stmt, 0),
                                      cached_lhs,
                                      stack);
     }
@@ -423,12 +425,17 @@ simplify_control_stmt_condition (edge e,
 
       /* We absolutely do not care about any type conversions
          we only care about a zero/nonzero value.  */
+      fold_defer_overflow_warnings ();
+
       cached_lhs = fold (COND_EXPR_COND (dummy_cond));
       while (TREE_CODE (cached_lhs) == NOP_EXPR
             || TREE_CODE (cached_lhs) == CONVERT_EXPR
             || TREE_CODE (cached_lhs) == NON_LVALUE_EXPR)
        cached_lhs = TREE_OPERAND (cached_lhs, 0);
-           
+
+      fold_undefer_overflow_warnings (is_gimple_min_invariant (cached_lhs),
+                                     stmt, WARN_STRICT_OVERFLOW_CONDITIONAL);
+
       /* If we have not simplified the condition down to an invariant,
         then use the pass specific callback to simplify the condition.  */
       if (! is_gimple_min_invariant (cached_lhs))
@@ -441,10 +448,14 @@ simplify_control_stmt_condition (edge e,
     {
       cached_lhs = cond;
 
-      /* Get the variable's current value from the equivalency chains.  */
-      while (cached_lhs
-            && TREE_CODE (cached_lhs) == SSA_NAME
-            && SSA_NAME_VALUE (cached_lhs))
+      /* Get the variable's current value from the equivalency chains.
+
+        It is possible to get loops in the SSA_NAME_VALUE chains
+        (consider threading the backedge of a loop where we have
+        a loop invariant SSA_NAME used in the condition.  */
+      if (cached_lhs
+         && TREE_CODE (cached_lhs) == SSA_NAME
+         && SSA_NAME_VALUE (cached_lhs))
        cached_lhs = SSA_NAME_VALUE (cached_lhs);
 
       /* If we're dominated by a suitable ASSERT_EXPR, then