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. */
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
== 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) \
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));