OSDN Git Service

PR ada/23995
[pf3gnuchains/gcc-fork.git] / gcc / tree-gimple.c
index 82b82a4..284f577 100644 (file)
@@ -1,5 +1,5 @@
 /* Functions to analyze and validate GIMPLE trees.
-   Copyright (C) 2002, 2003, 2004 Free Software Foundation, Inc.
+   Copyright (C) 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
    Contributed by Diego Novillo <dnovillo@redhat.com>
    Rewritten by Jason Merrill <jason@redhat.com>
 
@@ -17,8 +17,8 @@ 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, 59 Temple Place - Suite 330,
-Boston, MA 02111-1307, USA.  */
+the Free Software Foundation, 51 Franklin Street, Fifth Floor,
+Boston, MA 02110-1301, USA.  */
 
 #include "config.h"
 #include "system.h"
@@ -73,6 +73,7 @@ is_gimple_formal_tmp_rhs (tree t)
     case COMPLEX_CST:
     case VECTOR_CST:
     case OBJ_TYPE_REF:
+    case ASSERT_EXPR:
       return true;
 
     default:
@@ -111,9 +112,12 @@ is_gimple_reg_rhs (tree t)
 bool
 is_gimple_mem_rhs (tree t)
 {
-  /* If we're dealing with a renamable type, either source or dest
-     must be a renamed variable.  */
-  if (is_gimple_reg_type (TREE_TYPE (t)))
+  /* If we're dealing with a renamable type, either source or dest must be
+     a renamed variable.  Also force a temporary if the type doesn't need
+     to be stored in memory, since it's cheap and prevents erroneous
+     tailcalls (PR 17526).  */
+  if (is_gimple_reg_type (TREE_TYPE (t))
+      || TYPE_MODE (TREE_TYPE (t)) != BLKmode)
     return is_gimple_val (t);
   else
     return is_gimple_formal_tmp_rhs (t);
@@ -132,16 +136,6 @@ rhs_predicate_for (tree lhs)
     return is_gimple_mem_rhs;
 }
 
-/* Returns true if T is a valid CONSTRUCTOR component in GIMPLE, either
-   a val or another CONSTRUCTOR.  */
-
-bool
-is_gimple_constructor_elt (tree t)
-{
-  return (is_gimple_val (t)
-         || TREE_CODE (t) == CONSTRUCTOR);
-}
-
 /*  Return true if T is a valid LHS for a GIMPLE assignment expression.  */
 
 bool
@@ -168,10 +162,7 @@ bool
 is_gimple_addressable (tree t)
 {
   return (is_gimple_id (t) || handled_component_p (t)
-         || TREE_CODE (t) == REALPART_EXPR
-         || TREE_CODE (t) == IMAGPART_EXPR
          || INDIRECT_REF_P (t));
-
 }
 
 /* Return true if T is function invariant.  Or rather a restricted
@@ -190,7 +181,7 @@ is_gimple_min_invariant (tree t)
     case STRING_CST:
     case COMPLEX_CST:
     case VECTOR_CST:
-      return !TREE_OVERFLOW (t);
+      return true;
 
     default:
       return false;
@@ -269,27 +260,63 @@ is_gimple_id (tree t)
 bool
 is_gimple_reg_type (tree type)
 {
-  return (!AGGREGATE_TYPE_P (type)
-          && TREE_CODE (type) != COMPLEX_TYPE);
+  return !AGGREGATE_TYPE_P (type);
 }
 
-
-/* Return true if T is a scalar register variable.  */
+/* Return true if T is a non-aggregate register variable.  */
 
 bool
 is_gimple_reg (tree t)
 {
+  var_ann_t ann;
+
   if (TREE_CODE (t) == SSA_NAME)
     t = SSA_NAME_VAR (t);
 
-  return (is_gimple_variable (t)
-         && is_gimple_reg_type (TREE_TYPE (t))
-         /* A volatile decl is not acceptable because we can't reuse it as
-            needed.  We need to copy it into a temp first.  */
-         && ! TREE_THIS_VOLATILE (t)
-         && ! needs_to_live_in_memory (t));
+  if (!is_gimple_variable (t))
+    return false;
+
+  if (!is_gimple_reg_type (TREE_TYPE (t)))
+    return false;
+
+  /* A volatile decl is not acceptable because we can't reuse it as
+     needed.  We need to copy it into a temp first.  */
+  if (TREE_THIS_VOLATILE (t))
+    return false;
+
+  /* We define "registers" as things that can be renamed as needed,
+     which with our infrastructure does not apply to memory.  */
+  if (needs_to_live_in_memory (t))
+    return false;
+
+  /* Hard register variables are an interesting case.  For those that
+     are call-clobbered, we don't know where all the calls are, since
+     we don't (want to) take into account which operations will turn
+     into libcalls at the rtl level.  For those that are call-saved,
+     we don't currently model the fact that calls may in fact change
+     global hard registers, nor do we examine ASM_CLOBBERS at the tree
+     level, and so miss variable changes that might imply.  All around,
+     it seems safest to not do too much optimization with these at the
+     tree level at all.  We'll have to rely on the rtl optimizers to
+     clean this up, as there we've got all the appropriate bits exposed.  */
+  if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t))
+    return false;
+
+  /* Complex values must have been put into ssa form.  That is, no 
+     assignments to the individual components.  */
+  if (TREE_CODE (TREE_TYPE (t)) == COMPLEX_TYPE)
+    return DECL_COMPLEX_GIMPLE_REG_P (t);
+
+  /* Some compiler temporaries are created to be used exclusively in
+     virtual operands (currently memory tags and sub-variables).
+     These variables should never be considered GIMPLE registers.  */
+  if (DECL_ARTIFICIAL (t) && (ann = var_ann (t)) != NULL)
+    return ann->mem_tag_kind == NOT_A_TAG;
+
+  return true;
 }
 
+
 /* Returns true if T is a GIMPLE formal temporary variable.  */
 
 bool
@@ -349,6 +376,16 @@ is_gimple_val (tree t)
   return (is_gimple_variable (t) || is_gimple_min_invariant (t));
 }
 
+/* Similarly, but accept hard registers as inputs to asm statements.  */
+
+bool
+is_gimple_asm_val (tree t)
+{
+  if (TREE_CODE (t) == VAR_DECL && DECL_HARD_REGISTER (t))
+    return true;
+
+  return is_gimple_val (t);
+}
 
 /* Return true if T is a GIMPLE minimal lvalue.  */
 
@@ -396,16 +433,19 @@ get_call_expr_in (tree t)
   return NULL_TREE;
 }
 
-/* Given a memory reference expression, return the base address.  Note that,
-   in contrast with get_base_var, this will not recurse inside INDIRECT_REF
-   expressions.  Therefore, given the reference PTR->FIELD, this function
-   will return *PTR.  Whereas get_base_var would've returned PTR.  */
+/* Given a memory reference expression T, return its base address.
+   The base address of a memory reference expression is the main
+   object being referenced.  For instance, the base address for
+   'array[i].fld[j]' is 'array'.  You can think of this as stripping
+   away the offset part from a memory address.
+
+   This function calls handled_component_p to strip away all the inner
+   parts of the memory reference until it reaches the base object.  */
 
 tree
 get_base_address (tree t)
 {
-  while (TREE_CODE (t) == REALPART_EXPR || TREE_CODE (t) == IMAGPART_EXPR
-        || handled_component_p (t))
+  while (handled_component_p (t))
     t = TREE_OPERAND (t, 0);
   
   if (SSA_VAR_P (t)
@@ -421,7 +461,7 @@ void
 recalculate_side_effects (tree t)
 {
   enum tree_code code = TREE_CODE (t);
-  int fro = first_rtl_op (code);
+  int len = TREE_CODE_LENGTH (code);
   int i;
 
   switch (TREE_CODE_CLASS (code))
@@ -450,7 +490,7 @@ recalculate_side_effects (tree t)
     case tcc_binary:      /* a binary arithmetic expression */
     case tcc_reference:   /* a reference */
       TREE_SIDE_EFFECTS (t) = TREE_THIS_VOLATILE (t);
-      for (i = 0; i < fro; ++i)
+      for (i = 0; i < len; ++i)
        {
          tree op = TREE_OPERAND (t, i);
          if (op && TREE_SIDE_EFFECTS (op))