This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[PATCH] Fix PR49645, with C FE pieces
- From: Richard Guenther <rguenther at suse dot de>
- To: gcc-patches at gcc dot gnu dot org
- Cc: "Joseph S. Myers" <joseph at codesourcery dot com>
- Date: Wed, 6 Jul 2011 15:26:07 +0200 (CEST)
- Subject: [PATCH] Fix PR49645, with C FE pieces
This fixes PR49645 - with MEM_REF the value-numbering machinery
to look through aggregate copies wasn't working reliably as
we have two representations for X, X and MEM[&X]. The following
patch fixes that by internally always using the more complicated
representation.
The patch needs consistent DECL_HARD_REGISTER settings to avoid
generating MEM_REFs for them though and the C frontend fails
to set that flag for global variables - hence the c-decl.c part
(otherwise compile.exp 20041119-1.c ICEs).
Bootstrapped and tested on x86_64-unknown-linux-gnu, are the
C frontend parts ok for trunk?
Thanks,
Richard.
2011-07-06 Richard Guenther <rguenther@suse.de>
PR tree-optimization/49645
* c-decl.c (finish_decl): Also set DECL_HARD_REGISTER for global
register variables.
* tree-ssa-sccvn.c (vn_reference_op_eq): Disregard differences
in type qualification here ...
(copy_reference_ops_from_ref): ... not here.
(vn_reference_lookup_3): ... or here.
(copy_reference_ops_from_ref): Record decl bases as MEM[&decl].
(vn_reference_lookup): Do the lookup with a valueized ao-ref.
* g++.dg/tree-ssa/pr8781.C: Disable SRA.
Index: gcc/c-decl.c
===================================================================
*** gcc/c-decl.c (revision 175905)
--- gcc/c-decl.c (working copy)
*************** finish_decl (tree decl, location_t init_
*** 4357,4362 ****
--- 4357,4364 ----
when a tentative file-scope definition is seen.
But at end of compilation, do output code for them. */
DECL_DEFER_OUTPUT (decl) = 1;
+ if (asmspec && C_DECL_REGISTER (decl))
+ DECL_HARD_REGISTER (decl) = 1;
rest_of_decl_compilation (decl, true, 0);
}
else
Index: gcc/tree-ssa-sccvn.c
===================================================================
*** gcc/tree-ssa-sccvn.c (revision 175905)
--- gcc/tree-ssa-sccvn.c (working copy)
*************** vn_reference_op_eq (const void *p1, cons
*** 391,401 ****
const_vn_reference_op_t const vro1 = (const_vn_reference_op_t) p1;
const_vn_reference_op_t const vro2 = (const_vn_reference_op_t) p2;
! return vro1->opcode == vro2->opcode
! && types_compatible_p (vro1->type, vro2->type)
! && expressions_equal_p (vro1->op0, vro2->op0)
! && expressions_equal_p (vro1->op1, vro2->op1)
! && expressions_equal_p (vro1->op2, vro2->op2);
}
/* Compute the hash for a reference operand VRO1. */
--- 391,405 ----
const_vn_reference_op_t const vro1 = (const_vn_reference_op_t) p1;
const_vn_reference_op_t const vro2 = (const_vn_reference_op_t) p2;
! return (vro1->opcode == vro2->opcode
! /* We do not care for differences in type qualification. */
! && (vro1->type == vro2->type
! || (vro1->type && vro2->type
! && types_compatible_p (TYPE_MAIN_VARIANT (vro1->type),
! TYPE_MAIN_VARIANT (vro2->type))))
! && expressions_equal_p (vro1->op0, vro2->op0)
! && expressions_equal_p (vro1->op1, vro2->op1)
! && expressions_equal_p (vro1->op2, vro2->op2));
}
/* Compute the hash for a reference operand VRO1. */
*************** copy_reference_ops_from_ref (tree ref, V
*** 579,585 ****
memset (&temp, 0, sizeof (temp));
/* We do not care for spurious type qualifications. */
! temp.type = TYPE_MAIN_VARIANT (TREE_TYPE (ref));
temp.opcode = TREE_CODE (ref);
temp.op0 = TMR_INDEX (ref);
temp.op1 = TMR_STEP (ref);
--- 583,589 ----
memset (&temp, 0, sizeof (temp));
/* We do not care for spurious type qualifications. */
! temp.type = TREE_TYPE (ref);
temp.opcode = TREE_CODE (ref);
temp.op0 = TMR_INDEX (ref);
temp.op1 = TMR_STEP (ref);
*************** copy_reference_ops_from_ref (tree ref, V
*** 610,617 ****
vn_reference_op_s temp;
memset (&temp, 0, sizeof (temp));
! /* We do not care for spurious type qualifications. */
! temp.type = TYPE_MAIN_VARIANT (TREE_TYPE (ref));
temp.opcode = TREE_CODE (ref);
temp.off = -1;
--- 614,620 ----
vn_reference_op_s temp;
memset (&temp, 0, sizeof (temp));
! temp.type = TREE_TYPE (ref);
temp.opcode = TREE_CODE (ref);
temp.off = -1;
*************** copy_reference_ops_from_ref (tree ref, V
*** 676,691 ****
temp.off = off.low;
}
break;
case STRING_CST:
case INTEGER_CST:
case COMPLEX_CST:
case VECTOR_CST:
case REAL_CST:
case CONSTRUCTOR:
- case VAR_DECL:
- case PARM_DECL:
- case CONST_DECL:
- case RESULT_DECL:
case SSA_NAME:
temp.op0 = ref;
break;
--- 679,711 ----
temp.off = off.low;
}
break;
+ case VAR_DECL:
+ if (DECL_HARD_REGISTER (ref))
+ {
+ temp.op0 = ref;
+ break;
+ }
+ /* Fallthru. */
+ case PARM_DECL:
+ case CONST_DECL:
+ case RESULT_DECL:
+ /* Canonicalize decls to MEM[&decl] which is what we end up with
+ when valueizing MEM[ptr] with ptr = &decl. */
+ temp.opcode = MEM_REF;
+ temp.op0 = build_int_cst (build_pointer_type (TREE_TYPE (ref)), 0);
+ temp.off = 0;
+ VEC_safe_push (vn_reference_op_s, heap, *result, &temp);
+ temp.opcode = ADDR_EXPR;
+ temp.op0 = build_fold_addr_expr (ref);
+ temp.type = TREE_TYPE (temp.op0);
+ temp.off = -1;
+ break;
case STRING_CST:
case INTEGER_CST:
case COMPLEX_CST:
case VECTOR_CST:
case REAL_CST:
case CONSTRUCTOR:
case SSA_NAME:
temp.op0 = ref;
break;
*************** vn_reference_lookup_3 (ao_ref *ref, tree
*** 1580,1586 ****
op.op0 = build_int_cst (ptr_type_node, at - rhs_offset);
op.off = at - lhs_offset + rhs_offset;
VEC_replace (vn_reference_op_s, vr->operands, 0, &op);
! op.type = TYPE_MAIN_VARIANT (TREE_TYPE (rhs));
op.opcode = TREE_CODE (rhs);
op.op0 = rhs;
op.off = -1;
--- 1600,1606 ----
op.op0 = build_int_cst (ptr_type_node, at - rhs_offset);
op.off = at - lhs_offset + rhs_offset;
VEC_replace (vn_reference_op_s, vr->operands, 0, &op);
! op.type = TREE_TYPE (rhs);
op.opcode = TREE_CODE (rhs);
op.op0 = rhs;
op.off = -1;
*************** vn_reference_lookup (tree op, tree vuse,
*** 1692,1698 ****
{
vn_reference_t wvnresult;
ao_ref r;
! ao_ref_init (&r, op);
vn_walk_kind = kind;
wvnresult =
(vn_reference_t)walk_non_aliased_vuses (&r, vr1.vuse,
--- 1712,1723 ----
{
vn_reference_t wvnresult;
ao_ref r;
! /* Make sure to use a valueized reference ... */
! if (!ao_ref_init_from_vn_reference (&r, vr1.set, vr1.type, vr1.operands))
! ao_ref_init (&r, op);
! else
! /* ... but also preserve a full reference tree for advanced TBAA. */
! r.ref = op;
vn_walk_kind = kind;
wvnresult =
(vn_reference_t)walk_non_aliased_vuses (&r, vr1.vuse,
Index: gcc/testsuite/g++.dg/tree-ssa/pr8781.C
===================================================================
*** gcc/testsuite/g++.dg/tree-ssa/pr8781.C (revision 175905)
--- gcc/testsuite/g++.dg/tree-ssa/pr8781.C (working copy)
***************
*** 1,5 ****
/* { dg-do compile } */
! /* { dg-options "-O -fdump-tree-fre1-details" } */
int f();
--- 1,5 ----
/* { dg-do compile } */
! /* { dg-options "-O -fno-tree-sra -fdump-tree-fre1-details" } */
int f();