summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2003-05-13 18:58:56 +0000
committerjason <jason@138bc75d-0d04-0410-961f-82ee72b054a4>2003-05-13 18:58:56 +0000
commit10f6a2691da04b880014abffa51a058893b669ef (patch)
tree38e4eda90974c27801ffbbf2262cd0f625dedcde
parent6971805a001c9f86f14f6e80f88ae062eb547f86 (diff)
downloadgcc-10f6a2691da04b880014abffa51a058893b669ef.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@66775 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r--gcc/ChangeLog9
-rw-r--r--gcc/c-semantics.c15
-rw-r--r--gcc/tree.c73
-rw-r--r--gcc/tree.h12
4 files changed, 103 insertions, 6 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0fac8ca2964..0d53c1a2f72 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/c-semantics.c b/gcc/c-semantics.c
index 59620ca3d0f..91ab8738033 100644
--- a/gcc/c-semantics.c
+++ b/gcc/c-semantics.c
@@ -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. */
diff --git a/gcc/tree.c b/gcc/tree.c
index 64b605acdea..5ae362cc9d5 100644
--- a/gcc/tree.c
+++ b/gcc/tree.c
@@ -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;
+}
/* Constructors for pointer, array and function types.
(RECORD_TYPE, UNION_TYPE and ENUMERAL_TYPE nodes are
diff --git a/gcc/tree.h b/gcc/tree.h
index 8c01ca16907..060ecd11189 100644
--- a/gcc/tree.h
+++ b/gcc/tree.h
@@ -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));