re PR middle-end/20623 (ICE: fold check: original tree changed by fold with --enable-checking=fold)
PR middle-end/20623 * tree.h (debug_fold_checksum): Declared. * fold-const.c (build_fold_addr_expr_with_type_1): New. (build_fold_addr_expr_with_type, build_fold_addr_expr): Use build_fold_addr_expr_with_type_1. (fold_addr_expr, debug_fold_checksum): New. (fold_checksum_tree): Don't fold TREE_CHAIN of an SSA_NAME. (fold_unary, fold_comparison, split_address_to_core_and_offset): Use fold_addr_expr. From-SVN: r125929
This commit is contained in:
parent
6f1c9cd02f
commit
70826cbbef
|
@ -1,3 +1,15 @@
|
||||||
|
2007-06-21 Sebastian Pop <sebpop@gmail.com>
|
||||||
|
|
||||||
|
PR middle-end/20623
|
||||||
|
* tree.h (debug_fold_checksum): Declared.
|
||||||
|
* fold-const.c (build_fold_addr_expr_with_type_1): New.
|
||||||
|
(build_fold_addr_expr_with_type, build_fold_addr_expr): Use
|
||||||
|
build_fold_addr_expr_with_type_1.
|
||||||
|
(fold_addr_expr, debug_fold_checksum): New.
|
||||||
|
(fold_checksum_tree): Don't fold TREE_CHAIN of an SSA_NAME.
|
||||||
|
(fold_unary, fold_comparison, split_address_to_core_and_offset):
|
||||||
|
Use fold_addr_expr.
|
||||||
|
|
||||||
2007-06-21 Sebastian Pop <sebpop@gmail.com>
|
2007-06-21 Sebastian Pop <sebpop@gmail.com>
|
||||||
|
|
||||||
PR tree-optimization/19590
|
PR tree-optimization/19590
|
||||||
|
|
145
gcc/fold-const.c
145
gcc/fold-const.c
|
@ -7552,6 +7552,77 @@ fold_view_convert_expr (tree type, tree expr)
|
||||||
return native_interpret_expr (type, buffer, len);
|
return native_interpret_expr (type, buffer, len);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Build an expression for the address of T. Folds away INDIRECT_REF
|
||||||
|
to avoid confusing the gimplify process. When IN_FOLD is true
|
||||||
|
avoid modifications of T. */
|
||||||
|
|
||||||
|
static tree
|
||||||
|
build_fold_addr_expr_with_type_1 (tree t, tree ptrtype, bool in_fold)
|
||||||
|
{
|
||||||
|
/* The size of the object is not relevant when talking about its address. */
|
||||||
|
if (TREE_CODE (t) == WITH_SIZE_EXPR)
|
||||||
|
t = TREE_OPERAND (t, 0);
|
||||||
|
|
||||||
|
/* Note: doesn't apply to ALIGN_INDIRECT_REF */
|
||||||
|
if (TREE_CODE (t) == INDIRECT_REF
|
||||||
|
|| TREE_CODE (t) == MISALIGNED_INDIRECT_REF)
|
||||||
|
{
|
||||||
|
t = TREE_OPERAND (t, 0);
|
||||||
|
|
||||||
|
if (TREE_TYPE (t) != ptrtype)
|
||||||
|
t = build1 (NOP_EXPR, ptrtype, t);
|
||||||
|
}
|
||||||
|
else if (!in_fold)
|
||||||
|
{
|
||||||
|
tree base = t;
|
||||||
|
|
||||||
|
while (handled_component_p (base))
|
||||||
|
base = TREE_OPERAND (base, 0);
|
||||||
|
|
||||||
|
if (DECL_P (base))
|
||||||
|
TREE_ADDRESSABLE (base) = 1;
|
||||||
|
|
||||||
|
t = build1 (ADDR_EXPR, ptrtype, t);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
t = build1 (ADDR_EXPR, ptrtype, t);
|
||||||
|
|
||||||
|
return t;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Build an expression for the address of T with type PTRTYPE. This
|
||||||
|
function modifies the input parameter 'T' by sometimes setting the
|
||||||
|
TREE_ADDRESSABLE flag. */
|
||||||
|
|
||||||
|
tree
|
||||||
|
build_fold_addr_expr_with_type (tree t, tree ptrtype)
|
||||||
|
{
|
||||||
|
return build_fold_addr_expr_with_type_1 (t, ptrtype, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Build an expression for the address of T. This function modifies
|
||||||
|
the input parameter 'T' by sometimes setting the TREE_ADDRESSABLE
|
||||||
|
flag. When called from fold functions, use fold_addr_expr instead. */
|
||||||
|
|
||||||
|
tree
|
||||||
|
build_fold_addr_expr (tree t)
|
||||||
|
{
|
||||||
|
return build_fold_addr_expr_with_type_1 (t,
|
||||||
|
build_pointer_type (TREE_TYPE (t)),
|
||||||
|
false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Same as build_fold_addr_expr, builds an expression for the address
|
||||||
|
of T, but avoids touching the input node 't'. Fold functions
|
||||||
|
should use this version. */
|
||||||
|
|
||||||
|
static tree
|
||||||
|
fold_addr_expr (tree t)
|
||||||
|
{
|
||||||
|
tree ptrtype = build_pointer_type (TREE_TYPE (t));
|
||||||
|
|
||||||
|
return build_fold_addr_expr_with_type_1 (t, ptrtype, true);
|
||||||
|
}
|
||||||
|
|
||||||
/* Fold a unary expression of code CODE and type TYPE with operand
|
/* Fold a unary expression of code CODE and type TYPE with operand
|
||||||
OP0. Return the folded expression if folding is successful.
|
OP0. Return the folded expression if folding is successful.
|
||||||
|
@ -7787,7 +7858,7 @@ fold_unary (enum tree_code code, tree type, tree op0)
|
||||||
if (! offset && bitpos == 0
|
if (! offset && bitpos == 0
|
||||||
&& TYPE_MAIN_VARIANT (TREE_TYPE (type))
|
&& TYPE_MAIN_VARIANT (TREE_TYPE (type))
|
||||||
== TYPE_MAIN_VARIANT (TREE_TYPE (base)))
|
== TYPE_MAIN_VARIANT (TREE_TYPE (base)))
|
||||||
return fold_convert (type, build_fold_addr_expr (base));
|
return fold_convert (type, fold_addr_expr (base));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((TREE_CODE (op0) == MODIFY_EXPR
|
if ((TREE_CODE (op0) == MODIFY_EXPR
|
||||||
|
@ -8864,8 +8935,8 @@ fold_comparison (enum tree_code code, tree type, tree op0, tree op1)
|
||||||
tree op0 = TREE_OPERAND (cref0, 0);
|
tree op0 = TREE_OPERAND (cref0, 0);
|
||||||
tree op1 = TREE_OPERAND (cref1, 0);
|
tree op1 = TREE_OPERAND (cref1, 0);
|
||||||
return fold_build2 (code, type,
|
return fold_build2 (code, type,
|
||||||
build_fold_addr_expr (op0),
|
fold_addr_expr (op0),
|
||||||
build_fold_addr_expr (op1));
|
fold_addr_expr (op1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12775,7 +12846,8 @@ recursive_label:
|
||||||
fold_checksum_tree (TREE_TYPE (expr), ctx, ht);
|
fold_checksum_tree (TREE_TYPE (expr), ctx, ht);
|
||||||
if (TREE_CODE_CLASS (code) != tcc_type
|
if (TREE_CODE_CLASS (code) != tcc_type
|
||||||
&& TREE_CODE_CLASS (code) != tcc_declaration
|
&& TREE_CODE_CLASS (code) != tcc_declaration
|
||||||
&& code != TREE_LIST)
|
&& code != TREE_LIST
|
||||||
|
&& code != SSA_NAME)
|
||||||
fold_checksum_tree (TREE_CHAIN (expr), ctx, ht);
|
fold_checksum_tree (TREE_CHAIN (expr), ctx, ht);
|
||||||
switch (TREE_CODE_CLASS (code))
|
switch (TREE_CODE_CLASS (code))
|
||||||
{
|
{
|
||||||
|
@ -12910,6 +12982,30 @@ fold_build1_stat (enum tree_code code, tree type, tree op0 MEM_STAT_DECL)
|
||||||
return tem;
|
return tem;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Helper function for outputting the checksum of a tree T. When
|
||||||
|
debugging with gdb, you can "define mynext" to be "next" followed
|
||||||
|
by "call debug_fold_checksum (op0)", then just trace down till the
|
||||||
|
outputs differ. */
|
||||||
|
|
||||||
|
void
|
||||||
|
debug_fold_checksum (tree t)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
unsigned char checksum[16];
|
||||||
|
struct md5_ctx ctx;
|
||||||
|
htab_t ht = htab_create (32, htab_hash_pointer, htab_eq_pointer, NULL);
|
||||||
|
|
||||||
|
md5_init_ctx (&ctx);
|
||||||
|
fold_checksum_tree (t, &ctx, ht);
|
||||||
|
md5_finish_ctx (&ctx, checksum);
|
||||||
|
htab_empty (ht);
|
||||||
|
|
||||||
|
for (i = 0; i < 16; i++)
|
||||||
|
fprintf (stderr, "%d ", checksum[i]);
|
||||||
|
|
||||||
|
fprintf (stderr, "\n");
|
||||||
|
}
|
||||||
|
|
||||||
/* Fold a binary tree expression with code CODE of type TYPE with
|
/* Fold a binary tree expression with code CODE of type TYPE with
|
||||||
operands OP0 and OP1. Return a folded expression if successful.
|
operands OP0 and OP1. Return a folded expression if successful.
|
||||||
Otherwise, return a tree expression with code CODE of type TYPE
|
Otherwise, return a tree expression with code CODE of type TYPE
|
||||||
|
@ -14171,45 +14267,6 @@ fold_build_cleanup_point_expr (tree type, tree expr)
|
||||||
return build1 (CLEANUP_POINT_EXPR, type, expr);
|
return build1 (CLEANUP_POINT_EXPR, type, expr);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Build an expression for the address of T. Folds away INDIRECT_REF to
|
|
||||||
avoid confusing the gimplify process. */
|
|
||||||
|
|
||||||
tree
|
|
||||||
build_fold_addr_expr_with_type (tree t, tree ptrtype)
|
|
||||||
{
|
|
||||||
/* The size of the object is not relevant when talking about its address. */
|
|
||||||
if (TREE_CODE (t) == WITH_SIZE_EXPR)
|
|
||||||
t = TREE_OPERAND (t, 0);
|
|
||||||
|
|
||||||
/* Note: doesn't apply to ALIGN_INDIRECT_REF */
|
|
||||||
if (TREE_CODE (t) == INDIRECT_REF
|
|
||||||
|| TREE_CODE (t) == MISALIGNED_INDIRECT_REF)
|
|
||||||
{
|
|
||||||
t = TREE_OPERAND (t, 0);
|
|
||||||
if (TREE_TYPE (t) != ptrtype)
|
|
||||||
t = build1 (NOP_EXPR, ptrtype, t);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
tree base = t;
|
|
||||||
|
|
||||||
while (handled_component_p (base))
|
|
||||||
base = TREE_OPERAND (base, 0);
|
|
||||||
if (DECL_P (base))
|
|
||||||
TREE_ADDRESSABLE (base) = 1;
|
|
||||||
|
|
||||||
t = build1 (ADDR_EXPR, ptrtype, t);
|
|
||||||
}
|
|
||||||
|
|
||||||
return t;
|
|
||||||
}
|
|
||||||
|
|
||||||
tree
|
|
||||||
build_fold_addr_expr (tree t)
|
|
||||||
{
|
|
||||||
return build_fold_addr_expr_with_type (t, build_pointer_type (TREE_TYPE (t)));
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Given a pointer value OP0 and a type TYPE, return a simplified version
|
/* Given a pointer value OP0 and a type TYPE, return a simplified version
|
||||||
of an indirection through OP0, or NULL_TREE if no simplification is
|
of an indirection through OP0, or NULL_TREE if no simplification is
|
||||||
possible. */
|
possible. */
|
||||||
|
@ -14513,7 +14570,7 @@ split_address_to_core_and_offset (tree exp,
|
||||||
core = get_inner_reference (TREE_OPERAND (exp, 0), &bitsize, pbitpos,
|
core = get_inner_reference (TREE_OPERAND (exp, 0), &bitsize, pbitpos,
|
||||||
poffset, &mode, &unsignedp, &volatilep,
|
poffset, &mode, &unsignedp, &volatilep,
|
||||||
false);
|
false);
|
||||||
core = build_fold_addr_expr (core);
|
core = fold_addr_expr (core);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
|
@ -4539,6 +4539,7 @@ extern enum built_in_function builtin_mathfn_code (tree);
|
||||||
extern tree build_function_call_expr (tree, tree);
|
extern tree build_function_call_expr (tree, tree);
|
||||||
extern tree fold_build_call_expr (tree, tree, tree, tree);
|
extern tree fold_build_call_expr (tree, tree, tree, tree);
|
||||||
extern tree fold_builtin_call_array (tree, tree, int, tree *);
|
extern tree fold_builtin_call_array (tree, tree, int, tree *);
|
||||||
|
extern void debug_fold_checksum (tree);
|
||||||
extern tree build_call_expr (tree, int, ...);
|
extern tree build_call_expr (tree, int, ...);
|
||||||
extern tree mathfn_built_in (tree, enum built_in_function fn);
|
extern tree mathfn_built_in (tree, enum built_in_function fn);
|
||||||
extern tree strip_float_extensions (tree);
|
extern tree strip_float_extensions (tree);
|
||||||
|
|
Loading…
Reference in New Issue