OSDN Git Service

Add file omitted from last checkin.
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-threadedge.c
index 86b2656..f5de5fd 100644 (file)
@@ -6,7 +6,7 @@ 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"
 #include "system.h"
@@ -227,6 +226,7 @@ record_temporary_equivalences_from_stmts_at_dest (edge e,
   for (bsi = bsi_start (e->dest); ! bsi_end_p (bsi); bsi_next (&bsi))
     {
       tree cached_lhs = NULL;
+      tree rhs;
 
       stmt = bsi_stmt (bsi);
 
@@ -253,6 +253,32 @@ record_temporary_equivalences_from_stmts_at_dest (edge e,
          || TREE_CODE (GIMPLE_STMT_OPERAND (stmt, 0)) != SSA_NAME)
        continue;
 
+      rhs = GIMPLE_STMT_OPERAND (stmt, 1);
+
+      /* The result of __builtin_object_size depends on all the arguments
+        of a phi node. Temporarily using only one edge produces invalid
+        results. For example
+
+        if (x < 6)
+          goto l;
+        else
+          goto l;
+
+        l:
+        r = PHI <&w[2].a[1](2), &a.a[6](3)>
+        __builtin_object_size (r, 0)
+
+        The result of __builtin_object_size is defined to be the maximum of
+        remaining bytes. If we use only one edge on the phi, the result will
+        change to be the remaining bytes for the corresponding phi argument. */
+
+      if (TREE_CODE (rhs) == CALL_EXPR)
+       {
+         tree fndecl = get_callee_fndecl (rhs);
+         if (fndecl && DECL_FUNCTION_CODE (fndecl) == BUILT_IN_OBJECT_SIZE)
+           continue;
+       }
+
       /* At this point we have a statement which assigns an RHS to an
         SSA_VAR on the LHS.  We want to try and simplify this statement
         to expose more context sensitive equivalences which in turn may
@@ -260,10 +286,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 (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);
+      if (TREE_CODE (rhs) == SSA_NAME)
+       cached_lhs = rhs;
+      else if (TREE_CODE (rhs) == ASSERT_EXPR)
+       cached_lhs = TREE_OPERAND (rhs, 0);
       else
        {
          /* A statement that is not a trivial copy or ASSERT_EXPR.
@@ -429,9 +455,7 @@ simplify_control_stmt_condition (edge e,
       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)
+      while (CONVERT_EXPR_P (cached_lhs))
        cached_lhs = TREE_OPERAND (cached_lhs, 0);
 
       fold_undefer_overflow_warnings (is_gimple_min_invariant (cached_lhs),