OSDN Git Service

2010-11-24 Tobias Burnus <burnus@net-b.de>
[pf3gnuchains/gcc-fork.git] / gcc / tree-ssa-operands.c
index 9b6d3a3..c83267d 100644 (file)
@@ -1,5 +1,5 @@
 /* SSA operands management for trees.
-   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009
+   Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010
    Free Software Foundation, Inc.
 
 This file is part of GCC.
@@ -25,7 +25,8 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree.h"
 #include "flags.h"
 #include "function.h"
-#include "diagnostic.h"
+#include "tree-pretty-print.h"
+#include "gimple-pretty-print.h"
 #include "tree-flow.h"
 #include "tree-inline.h"
 #include "tree-pass.h"
@@ -126,6 +127,12 @@ static struct
    clobbering sites like function calls or ASM_EXPRs.  */
 #define opf_implicit   (1 << 2)
 
+/* Operand is in a place where address-taken does not imply addressable.  */
+#define opf_non_addressable (1 << 3)
+
+/* Operand is in a place where opf_non_addressable does not apply.  */
+#define opf_not_non_addressable (1 << 4)
+
 /* Array for building all the def operands.  */
 static VEC(tree,heap) *build_defs;
 
@@ -319,9 +326,10 @@ ssa_operand_alloc (unsigned size)
          gcc_unreachable ();
        }
 
-      ptr = (struct ssa_operand_memory_d *)
-             ggc_alloc (sizeof (void *)
-                        + gimple_ssa_operands (cfun)->ssa_operand_mem_size);
+
+      ptr = ggc_alloc_ssa_operand_memory_d (sizeof (void *)
+                        + gimple_ssa_operands (cfun)->ssa_operand_mem_size);
+
       ptr->next = gimple_ssa_operands (cfun)->operand_memory;
       gimple_ssa_operands (cfun)->operand_memory = ptr;
       gimple_ssa_operands (cfun)->operand_memory_index = 0;
@@ -691,15 +699,21 @@ mark_address_taken (tree ref)
      be referenced using pointer arithmetic.  See PR 21407 and the
      ensuing mailing list discussion.  */
   var = get_base_address (ref);
-  if (var && DECL_P (var))
-    TREE_ADDRESSABLE (var) = 1;
+  if (var)
+    {
+      if (DECL_P (var))
+       TREE_ADDRESSABLE (var) = 1;
+      else if (TREE_CODE (var) == MEM_REF
+              && TREE_CODE (TREE_OPERAND (var, 0)) == ADDR_EXPR
+              && DECL_P (TREE_OPERAND (TREE_OPERAND (var, 0), 0)))
+       TREE_ADDRESSABLE (TREE_OPERAND (TREE_OPERAND (var, 0), 0)) = 1;
+    }
 }
 
 
-/* A subroutine of get_expr_operands to handle INDIRECT_REF,
-   ALIGN_INDIRECT_REF and MISALIGNED_INDIRECT_REF.
+/* A subroutine of get_expr_operands to handle MEM_REF.
 
-   STMT is the statement being processed, EXPR is the INDIRECT_REF
+   STMT is the statement being processed, EXPR is the MEM_REF
       that got us here.
 
    FLAGS is as in get_expr_operands.
@@ -723,7 +737,8 @@ get_indirect_ref_operands (gimple stmt, tree expr, int flags,
   /* If requested, add a USE operand for the base pointer.  */
   if (recurse_on_base)
     get_expr_operands (stmt, pptr,
-                      opf_use | (flags & opf_no_vops));
+                      opf_non_addressable | opf_use
+                      | (flags & (opf_no_vops|opf_not_non_addressable)));
 }
 
 
@@ -732,12 +747,13 @@ get_indirect_ref_operands (gimple stmt, tree expr, int flags,
 static void
 get_tmr_operands (gimple stmt, tree expr, int flags)
 {
+  if (TREE_THIS_VOLATILE (expr))
+    gimple_set_has_volatile_ops (stmt, true);
+
   /* First record the real operands.  */
   get_expr_operands (stmt, &TMR_BASE (expr), opf_use | (flags & opf_no_vops));
   get_expr_operands (stmt, &TMR_INDEX (expr), opf_use | (flags & opf_no_vops));
-
-  if (TMR_SYMBOL (expr))
-    mark_address_taken (TMR_SYMBOL (expr));
+  get_expr_operands (stmt, &TMR_INDEX2 (expr), opf_use | (flags & opf_no_vops));
 
   add_virtual_operand (stmt, flags);
 }
@@ -795,13 +811,9 @@ get_asm_expr_operands (gimple stmt)
       /* Memory operands are addressable.  Note that STMT needs the
         address of this operand.  */
       if (!allows_reg && allows_mem)
-       {
-         tree t = get_base_address (TREE_VALUE (link));
-         if (t && DECL_P (t))
-           mark_address_taken (t);
-       }
+       mark_address_taken (TREE_VALUE (link));
 
-      get_expr_operands (stmt, &TREE_VALUE (link), opf_def);
+      get_expr_operands (stmt, &TREE_VALUE (link), opf_def | opf_not_non_addressable);
     }
 
   /* Gather all input operands.  */
@@ -815,13 +827,9 @@ get_asm_expr_operands (gimple stmt)
       /* Memory operands are addressable.  Note that STMT needs the
         address of this operand.  */
       if (!allows_reg && allows_mem)
-       {
-         tree t = get_base_address (TREE_VALUE (link));
-         if (t && DECL_P (t))
-           mark_address_taken (t);
-       }
+       mark_address_taken (TREE_VALUE (link));
 
-      get_expr_operands (stmt, &TREE_VALUE (link), 0);
+      get_expr_operands (stmt, &TREE_VALUE (link), opf_not_non_addressable);
     }
 
   /* Clobber all memory and addressable symbols for asm ("" : : : "memory");  */
@@ -865,7 +873,9 @@ get_expr_operands (gimple stmt, tree *expr_p, int flags)
         reference to it, but the fact that the statement takes its
         address will be of interest to some passes (e.g. alias
         resolution).  */
-      if (!is_gimple_debug (stmt))
+      if ((!(flags & opf_non_addressable)
+          || (flags & opf_not_non_addressable))
+         && !is_gimple_debug (stmt))
        mark_address_taken (TREE_OPERAND (expr, 0));
 
       /* If the address is invariant, there may be no interesting
@@ -879,7 +889,8 @@ get_expr_operands (gimple stmt, tree *expr_p, int flags)
         here are ARRAY_REF indices which will always be real operands
         (GIMPLE does not allow non-registers as array indices).  */
       flags |= opf_no_vops;
-      get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags);
+      get_expr_operands (stmt, &TREE_OPERAND (expr, 0),
+                        flags | opf_not_non_addressable);
       return;
 
     case SSA_NAME:
@@ -896,12 +907,7 @@ get_expr_operands (gimple stmt, tree *expr_p, int flags)
       gcc_assert (gimple_debug_bind_p (stmt));
       return;
 
-    case MISALIGNED_INDIRECT_REF:
-      get_expr_operands (stmt, &TREE_OPERAND (expr, 1), flags);
-      /* fall through */
-
-    case ALIGN_INDIRECT_REF:
-    case INDIRECT_REF:
+    case MEM_REF:
       get_indirect_ref_operands (stmt, expr, flags, true);
       return;
 
@@ -991,11 +997,14 @@ get_expr_operands (gimple stmt, tree *expr_p, int flags)
 
     case DOT_PROD_EXPR:
     case REALIGN_LOAD_EXPR:
+    case WIDEN_MULT_PLUS_EXPR:
+    case WIDEN_MULT_MINUS_EXPR:
+    case FMA_EXPR:
       {
        get_expr_operands (stmt, &TREE_OPERAND (expr, 0), flags);
-        get_expr_operands (stmt, &TREE_OPERAND (expr, 1), flags);
-        get_expr_operands (stmt, &TREE_OPERAND (expr, 2), flags);
-        return;
+       get_expr_operands (stmt, &TREE_OPERAND (expr, 1), flags);
+       get_expr_operands (stmt, &TREE_OPERAND (expr, 2), flags);
+       return;
       }
 
     case FUNCTION_DECL:
@@ -1183,7 +1192,7 @@ swap_tree_operands (gimple stmt, tree *exp0, tree *exp1)
 /* Scan the immediate_use list for VAR making sure its linked properly.
    Return TRUE if there is a problem and emit an error message to F.  */
 
-bool
+DEBUG_FUNCTION bool
 verify_imm_links (FILE *f, tree var)
 {
   use_operand_p ptr, prev, list;
@@ -1307,7 +1316,7 @@ dump_immediate_uses (FILE *file)
 
 /* Dump def-use edges on stderr.  */
 
-void
+DEBUG_FUNCTION void
 debug_immediate_uses (void)
 {
   dump_immediate_uses (stderr);
@@ -1316,7 +1325,7 @@ debug_immediate_uses (void)
 
 /* Dump def-use edges on stderr.  */
 
-void
+DEBUG_FUNCTION void
 debug_immediate_uses_for (tree var)
 {
   dump_immediate_uses_for (stderr, var);