tree.h (STRIP_MAIN_TYPE_NOPS): New macro.
authorJason Merrill <jason@redhat.com>
Tue, 13 May 2003 18:58:56 +0000 (14:58 -0400)
committerJason Merrill <jason@gcc.gnu.org>
Tue, 13 May 2003 18:58:56 +0000 (14:58 -0400)
        * tree.h (STRIP_MAIN_TYPE_NOPS): New macro.

        * tree.c (iterative_hash_expr): New fn.

        * c-semantics.c (emit_local_var): Don't mess with temp slots if
        there's no initializer.

From-SVN: r66775

gcc/ChangeLog
gcc/c-semantics.c
gcc/tree.c
gcc/tree.h

index 0fac8ca296497d11910f620dd2f63bf2132e8fd9..0d53c1a2f7219e92eee76b270aeeefb534482765 100644 (file)
@@ -1,3 +1,12 @@
+2003-05-13  Jason Merrill  <jason@redhat.com>
+
+       * tree.h (STRIP_MAIN_TYPE_NOPS): New macro.
+
+       * tree.c (iterative_hash_expr): New fn.
+
+       * c-semantics.c (emit_local_var): Don't mess with temp slots if
+       there's no initializer.
+
 2003-05-13  Richard Sandiford  <rsandifo@redhat.com>
 
        * final.c (final_scan_insn): Apply the effects of frame-related
index 59620ca3d0fd0690230b93c55c9daa0f97ad632e..91ab8738033b1d5f8ed7c12eecfc67ea8a9fdb01 100644 (file)
@@ -286,14 +286,17 @@ emit_local_var (decl)
        expand_decl (decl);
     }
 
-  /* Actually do the initialization.  */
-  if (stmts_are_full_exprs_p ())
-    expand_start_target_temps ();
+  if (DECL_INITIAL (decl))
+    {
+      /* Actually do the initialization.  */
+      if (stmts_are_full_exprs_p ())
+       expand_start_target_temps ();
 
-  expand_decl_init (decl);
+      expand_decl_init (decl);
 
-  if (stmts_are_full_exprs_p ())
-    expand_end_target_temps ();
+      if (stmts_are_full_exprs_p ())
+       expand_end_target_temps ();
+    }
 }
 
 /* Helper for generating the RTL at the beginning of a scope.  */
index 64b605acdea2257ccdde41f624b61dffcf84e8fd..5ae362cc9d5e3a5fa15d12b4dfb4e82cd784d8c6 100644 (file)
@@ -3491,6 +3491,79 @@ compare_tree_int (t, u)
   else
     return 1;
 }
+
+/* Generate a hash value for an expression.  This can be used iteratively
+   by passing a previous result as the "val" argument.
+
+   This function is intended to produce the same hash for expressions which
+   would compare equal using operand_equal_p.  */
+
+hashval_t
+iterative_hash_expr (tree t, hashval_t val)
+{
+  int i;
+  enum tree_code code;
+  char class;
+
+  if (t == NULL_TREE)
+    return iterative_hash_object (t, val);
+
+  code = TREE_CODE (t);
+  class = TREE_CODE_CLASS (code);
+
+  if (class == 'd')
+    {
+      /* Decls we can just compare by pointer.  */
+      val = iterative_hash_object (t, val);
+    }
+  else if (class == 'c')
+    {
+      /* Alas, constants aren't shared, so we can't rely on pointer
+        identity.  */
+      if (code == INTEGER_CST)
+       {
+         val = iterative_hash_object (TREE_INT_CST_LOW (t), val);
+         val = iterative_hash_object (TREE_INT_CST_HIGH (t), val);
+       }
+      else if (code == REAL_CST)
+       val = iterative_hash (TREE_REAL_CST_PTR (t),
+                             sizeof (REAL_VALUE_TYPE), val);
+      else if (code == STRING_CST)
+       val = iterative_hash (TREE_STRING_POINTER (t),
+                             TREE_STRING_LENGTH (t), val);
+      else if (code == COMPLEX_CST)
+       {
+         val = iterative_hash_expr (TREE_REALPART (t), val);
+         val = iterative_hash_expr (TREE_IMAGPART (t), val);
+       }
+      else if (code == VECTOR_CST)
+       val = iterative_hash_expr (TREE_VECTOR_CST_ELTS (t), val);
+      else
+       abort ();
+    }
+  else if (IS_EXPR_CODE_CLASS (class) || class == 'r')
+    {
+      val = iterative_hash_object (code, val);
+
+      if (code == NOP_EXPR || code == CONVERT_EXPR
+         || code == NON_LVALUE_EXPR)
+       val = iterative_hash_object (TREE_TYPE (t), val);
+  
+      for (i = first_rtl_op (code) - 1; i >= 0; --i)
+       val = iterative_hash_expr (TREE_OPERAND (t, i), val);
+    }
+  else if (code == TREE_LIST)
+    {
+      /* A list of expressions, for a CALL_EXPR or as the elements of a
+        VECTOR_CST.  */
+      for (; t; t = TREE_CHAIN (t))
+       val = iterative_hash_expr (TREE_VALUE (t), val);
+    }
+  else
+    abort ();
+
+  return val;
+}
 \f
 /* Constructors for pointer, array and function types.
    (RECORD_TYPE, UNION_TYPE and ENUMERAL_TYPE nodes are
index 8c01ca169079a7975b46bce9b1ba18d5ed18de7a..060ecd1118911e719d24850c498209196b193baf 100644 (file)
@@ -427,6 +427,17 @@ extern void tree_operand_check_failed PARAMS ((int, enum tree_code,
             == TREE_UNSIGNED (TREE_TYPE (TREE_OPERAND (EXP, 0))))) \
     (EXP) = TREE_OPERAND (EXP, 0)
 
+/* Like STRIP_NOPS, but don't alter the TREE_TYPE main variant either.  */
+
+#define STRIP_MAIN_TYPE_NOPS(EXP)                                      \
+  while ((TREE_CODE (EXP) == NOP_EXPR                                  \
+         || TREE_CODE (EXP) == CONVERT_EXPR                            \
+         || TREE_CODE (EXP) == NON_LVALUE_EXPR)                        \
+        && TREE_OPERAND (EXP, 0) != error_mark_node                    \
+        && (TYPE_MAIN_VARIANT (TREE_TYPE (EXP))                        \
+            == TYPE_MAIN_VARIANT (TREE_TYPE (TREE_OPERAND (EXP, 0))))) \
+    (EXP) = TREE_OPERAND (EXP, 0)
+
 /* Like STRIP_NOPS, but don't alter the TREE_TYPE either.  */
 
 #define STRIP_TYPE_NOPS(EXP) \
@@ -2955,6 +2966,7 @@ extern bool variably_modified_type_p    PARAMS ((tree));
 extern int tree_log2                   PARAMS ((tree));
 extern int tree_floor_log2             PARAMS ((tree));
 extern int simple_cst_equal            PARAMS ((tree, tree));
+extern unsigned int iterative_hash_expr        PARAMS ((tree, unsigned int));
 extern int compare_tree_int            PARAMS ((tree,
                                                 unsigned HOST_WIDE_INT));
 extern int type_list_equal             PARAMS ((tree, tree));