mirror of git://gcc.gnu.org/git/gcc.git
re PR tree-optimization/45623 (GCC 4.5.[01] breaks our ffi on Linux64. ABI break?)
2010-09-16 Richard Guenther <rguenther@suse.de> PR tree-optimization/45623 * tree-ssa-structalias.c (get_constraint_for_ptr_offset): Adjust. (get_constraint_for_component_ref): If computing a constraint for the rhs handle type punning through unions. (get_constraint_for_address_of): Adjust. (get_constraint_for_1): Likewise. (get_constraint_for): Likewise. (get_constraint_for_rhs): New function. (do_structure_copy): Adjust. (make_constraint_to): Likewise. (handle_const_call): Likewise. (find_func_aliases): Likewise. (process_ipa_clobber): Likewise. (create_variable_info_for): Likewise. * gcc.dg/torture/pr45623.c: New testcase. From-SVN: r164333
This commit is contained in:
parent
ff802fa1f3
commit
ed6c4831a9
|
|
@ -1,3 +1,20 @@
|
||||||
|
2010-09-16 Richard Guenther <rguenther@suse.de>
|
||||||
|
|
||||||
|
PR tree-optimization/45623
|
||||||
|
* tree-ssa-structalias.c (get_constraint_for_ptr_offset): Adjust.
|
||||||
|
(get_constraint_for_component_ref): If computing a constraint
|
||||||
|
for the rhs handle type punning through unions.
|
||||||
|
(get_constraint_for_address_of): Adjust.
|
||||||
|
(get_constraint_for_1): Likewise.
|
||||||
|
(get_constraint_for): Likewise.
|
||||||
|
(get_constraint_for_rhs): New function.
|
||||||
|
(do_structure_copy): Adjust.
|
||||||
|
(make_constraint_to): Likewise.
|
||||||
|
(handle_const_call): Likewise.
|
||||||
|
(find_func_aliases): Likewise.
|
||||||
|
(process_ipa_clobber): Likewise.
|
||||||
|
(create_variable_info_for): Likewise.
|
||||||
|
|
||||||
2010-09-16 Ira Rosen <irar@il.ibm.com>
|
2010-09-16 Ira Rosen <irar@il.ibm.com>
|
||||||
|
|
||||||
* tree-vectorizer.c: Fix documentation.
|
* tree-vectorizer.c: Fix documentation.
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,8 @@
|
||||||
|
2010-09-16 Richard Guenther <rguenther@suse.de>
|
||||||
|
|
||||||
|
PR tree-optimization/45623
|
||||||
|
* gcc.dg/torture/pr45623.c: New testcase.
|
||||||
|
|
||||||
2010-09-16 Ira Rosen <irar@il.ibm.com>
|
2010-09-16 Ira Rosen <irar@il.ibm.com>
|
||||||
|
|
||||||
* gcc.dg/vect/bb-slp-8.c: Fix documentation, add space between function
|
* gcc.dg/vect/bb-slp-8.c: Fix documentation, add space between function
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
/* { dg-do run } */
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
extern void abort (void);
|
||||||
|
|
||||||
|
char *s1 = "foo";
|
||||||
|
char *s2 = "bar";
|
||||||
|
|
||||||
|
char **ss1 = &s1;
|
||||||
|
|
||||||
|
typedef union jsval_layout
|
||||||
|
{
|
||||||
|
uint64_t asBits;
|
||||||
|
char **ptr;
|
||||||
|
} jsval_layout;
|
||||||
|
|
||||||
|
int main()
|
||||||
|
{
|
||||||
|
jsval_layout l, m;
|
||||||
|
l.ptr = ss1;
|
||||||
|
m.asBits = l.asBits;
|
||||||
|
char ** data = m.ptr;
|
||||||
|
*data = s2;
|
||||||
|
if (s1 != s2)
|
||||||
|
abort ();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -532,8 +532,9 @@ struct constraint_expr
|
||||||
typedef struct constraint_expr ce_s;
|
typedef struct constraint_expr ce_s;
|
||||||
DEF_VEC_O(ce_s);
|
DEF_VEC_O(ce_s);
|
||||||
DEF_VEC_ALLOC_O(ce_s, heap);
|
DEF_VEC_ALLOC_O(ce_s, heap);
|
||||||
static void get_constraint_for_1 (tree, VEC(ce_s, heap) **, bool);
|
static void get_constraint_for_1 (tree, VEC(ce_s, heap) **, bool, bool);
|
||||||
static void get_constraint_for (tree, VEC(ce_s, heap) **);
|
static void get_constraint_for (tree, VEC(ce_s, heap) **);
|
||||||
|
static void get_constraint_for_rhs (tree, VEC(ce_s, heap) **);
|
||||||
static void do_deref (VEC (ce_s, heap) **);
|
static void do_deref (VEC (ce_s, heap) **);
|
||||||
|
|
||||||
/* Our set constraints are made up of two constraint expressions, one
|
/* Our set constraints are made up of two constraint expressions, one
|
||||||
|
|
@ -2994,7 +2995,7 @@ get_constraint_for_ptr_offset (tree ptr, tree offset,
|
||||||
does not change the points-to solution. */
|
does not change the points-to solution. */
|
||||||
if (!use_field_sensitive)
|
if (!use_field_sensitive)
|
||||||
{
|
{
|
||||||
get_constraint_for (ptr, results);
|
get_constraint_for_rhs (ptr, results);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -3014,7 +3015,7 @@ get_constraint_for_ptr_offset (tree ptr, tree offset,
|
||||||
rhsoffset = UNKNOWN_OFFSET;
|
rhsoffset = UNKNOWN_OFFSET;
|
||||||
}
|
}
|
||||||
|
|
||||||
get_constraint_for (ptr, results);
|
get_constraint_for_rhs (ptr, results);
|
||||||
if (rhsoffset == 0)
|
if (rhsoffset == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -3092,11 +3093,13 @@ get_constraint_for_ptr_offset (tree ptr, tree offset,
|
||||||
|
|
||||||
|
|
||||||
/* Given a COMPONENT_REF T, return the constraint_expr vector for it.
|
/* Given a COMPONENT_REF T, return the constraint_expr vector for it.
|
||||||
If address_p is true the result will be taken its address of. */
|
If address_p is true the result will be taken its address of.
|
||||||
|
If lhs_p is true then the constraint expression is assumed to be used
|
||||||
|
as the lhs. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_constraint_for_component_ref (tree t, VEC(ce_s, heap) **results,
|
get_constraint_for_component_ref (tree t, VEC(ce_s, heap) **results,
|
||||||
bool address_p)
|
bool address_p, bool lhs_p)
|
||||||
{
|
{
|
||||||
tree orig_t = t;
|
tree orig_t = t;
|
||||||
HOST_WIDE_INT bitsize = -1;
|
HOST_WIDE_INT bitsize = -1;
|
||||||
|
|
@ -3124,11 +3127,34 @@ get_constraint_for_component_ref (tree t, VEC(ce_s, heap) **results,
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Handle type-punning through unions. If we are extracting a pointer
|
||||||
|
from a union via a possibly type-punning access that pointer
|
||||||
|
points to anything, similar to a conversion of an integer to
|
||||||
|
a pointer. */
|
||||||
|
if (!lhs_p)
|
||||||
|
{
|
||||||
|
tree u;
|
||||||
|
for (u = t;
|
||||||
|
TREE_CODE (u) == COMPONENT_REF || TREE_CODE (u) == ARRAY_REF;
|
||||||
|
u = TREE_OPERAND (u, 0))
|
||||||
|
if (TREE_CODE (u) == COMPONENT_REF
|
||||||
|
&& TREE_CODE (TREE_TYPE (TREE_OPERAND (u, 0))) == UNION_TYPE)
|
||||||
|
{
|
||||||
|
struct constraint_expr temp;
|
||||||
|
|
||||||
|
temp.offset = 0;
|
||||||
|
temp.var = anything_id;
|
||||||
|
temp.type = ADDRESSOF;
|
||||||
|
VEC_safe_push (ce_s, heap, *results, &temp);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
t = get_ref_base_and_extent (t, &bitpos, &bitsize, &bitmaxsize);
|
t = get_ref_base_and_extent (t, &bitpos, &bitsize, &bitmaxsize);
|
||||||
|
|
||||||
/* Pretend to take the address of the base, we'll take care of
|
/* Pretend to take the address of the base, we'll take care of
|
||||||
adding the required subset of sub-fields below. */
|
adding the required subset of sub-fields below. */
|
||||||
get_constraint_for_1 (t, results, true);
|
get_constraint_for_1 (t, results, true, lhs_p);
|
||||||
gcc_assert (VEC_length (ce_s, *results) == 1);
|
gcc_assert (VEC_length (ce_s, *results) == 1);
|
||||||
result = VEC_last (ce_s, *results);
|
result = VEC_last (ce_s, *results);
|
||||||
|
|
||||||
|
|
@ -3257,8 +3283,6 @@ do_deref (VEC (ce_s, heap) **constraints)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void get_constraint_for_1 (tree, VEC (ce_s, heap) **, bool);
|
|
||||||
|
|
||||||
/* Given a tree T, return the constraint expression for taking the
|
/* Given a tree T, return the constraint expression for taking the
|
||||||
address of it. */
|
address of it. */
|
||||||
|
|
||||||
|
|
@ -3268,7 +3292,7 @@ get_constraint_for_address_of (tree t, VEC (ce_s, heap) **results)
|
||||||
struct constraint_expr *c;
|
struct constraint_expr *c;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
|
|
||||||
get_constraint_for_1 (t, results, true);
|
get_constraint_for_1 (t, results, true, true);
|
||||||
|
|
||||||
FOR_EACH_VEC_ELT (ce_s, *results, i, c)
|
FOR_EACH_VEC_ELT (ce_s, *results, i, c)
|
||||||
{
|
{
|
||||||
|
|
@ -3282,7 +3306,8 @@ get_constraint_for_address_of (tree t, VEC (ce_s, heap) **results)
|
||||||
/* Given a tree T, return the constraint expression for it. */
|
/* Given a tree T, return the constraint expression for it. */
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_constraint_for_1 (tree t, VEC (ce_s, heap) **results, bool address_p)
|
get_constraint_for_1 (tree t, VEC (ce_s, heap) **results, bool address_p,
|
||||||
|
bool lhs_p)
|
||||||
{
|
{
|
||||||
struct constraint_expr temp;
|
struct constraint_expr temp;
|
||||||
|
|
||||||
|
|
@ -3354,10 +3379,11 @@ get_constraint_for_1 (tree t, VEC (ce_s, heap) **results, bool address_p)
|
||||||
case ARRAY_REF:
|
case ARRAY_REF:
|
||||||
case ARRAY_RANGE_REF:
|
case ARRAY_RANGE_REF:
|
||||||
case COMPONENT_REF:
|
case COMPONENT_REF:
|
||||||
get_constraint_for_component_ref (t, results, address_p);
|
get_constraint_for_component_ref (t, results, address_p, lhs_p);
|
||||||
return;
|
return;
|
||||||
case VIEW_CONVERT_EXPR:
|
case VIEW_CONVERT_EXPR:
|
||||||
get_constraint_for_1 (TREE_OPERAND (t, 0), results, address_p);
|
get_constraint_for_1 (TREE_OPERAND (t, 0), results, address_p,
|
||||||
|
lhs_p);
|
||||||
return;
|
return;
|
||||||
/* We are missing handling for TARGET_MEM_REF here. */
|
/* We are missing handling for TARGET_MEM_REF here. */
|
||||||
default:;
|
default:;
|
||||||
|
|
@ -3382,7 +3408,7 @@ get_constraint_for_1 (tree t, VEC (ce_s, heap) **results, bool address_p)
|
||||||
{
|
{
|
||||||
struct constraint_expr *rhsp;
|
struct constraint_expr *rhsp;
|
||||||
unsigned j;
|
unsigned j;
|
||||||
get_constraint_for_1 (val, &tmp, address_p);
|
get_constraint_for_1 (val, &tmp, address_p, lhs_p);
|
||||||
FOR_EACH_VEC_ELT (ce_s, tmp, j, rhsp)
|
FOR_EACH_VEC_ELT (ce_s, tmp, j, rhsp)
|
||||||
VEC_safe_push (ce_s, heap, *results, rhsp);
|
VEC_safe_push (ce_s, heap, *results, rhsp);
|
||||||
VEC_truncate (ce_s, tmp, 0);
|
VEC_truncate (ce_s, tmp, 0);
|
||||||
|
|
@ -3419,7 +3445,18 @@ get_constraint_for (tree t, VEC (ce_s, heap) **results)
|
||||||
{
|
{
|
||||||
gcc_assert (VEC_length (ce_s, *results) == 0);
|
gcc_assert (VEC_length (ce_s, *results) == 0);
|
||||||
|
|
||||||
get_constraint_for_1 (t, results, false);
|
get_constraint_for_1 (t, results, false, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Given a gimple tree T, return the constraint expression vector for it
|
||||||
|
to be used as the rhs of a constraint. */
|
||||||
|
|
||||||
|
static void
|
||||||
|
get_constraint_for_rhs (tree t, VEC (ce_s, heap) **results)
|
||||||
|
{
|
||||||
|
gcc_assert (VEC_length (ce_s, *results) == 0);
|
||||||
|
|
||||||
|
get_constraint_for_1 (t, results, false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -3461,7 +3498,7 @@ do_structure_copy (tree lhsop, tree rhsop)
|
||||||
unsigned j;
|
unsigned j;
|
||||||
|
|
||||||
get_constraint_for (lhsop, &lhsc);
|
get_constraint_for (lhsop, &lhsc);
|
||||||
get_constraint_for (rhsop, &rhsc);
|
get_constraint_for_rhs (rhsop, &rhsc);
|
||||||
lhsp = VEC_index (ce_s, lhsc, 0);
|
lhsp = VEC_index (ce_s, lhsc, 0);
|
||||||
rhsp = VEC_index (ce_s, rhsc, 0);
|
rhsp = VEC_index (ce_s, rhsc, 0);
|
||||||
if (lhsp->type == DEREF
|
if (lhsp->type == DEREF
|
||||||
|
|
@ -3531,7 +3568,7 @@ make_constraint_to (unsigned id, tree op)
|
||||||
includes.offset = 0;
|
includes.offset = 0;
|
||||||
includes.type = SCALAR;
|
includes.type = SCALAR;
|
||||||
|
|
||||||
get_constraint_for (op, &rhsc);
|
get_constraint_for_rhs (op, &rhsc);
|
||||||
FOR_EACH_VEC_ELT (ce_s, rhsc, j, c)
|
FOR_EACH_VEC_ELT (ce_s, rhsc, j, c)
|
||||||
process_constraint (new_constraint (includes, *c));
|
process_constraint (new_constraint (includes, *c));
|
||||||
VEC_free (ce_s, heap, rhsc);
|
VEC_free (ce_s, heap, rhsc);
|
||||||
|
|
@ -3904,7 +3941,7 @@ handle_const_call (gimple stmt, VEC(ce_s, heap) **results)
|
||||||
VEC(ce_s, heap) *argc = NULL;
|
VEC(ce_s, heap) *argc = NULL;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
struct constraint_expr *argp;
|
struct constraint_expr *argp;
|
||||||
get_constraint_for (arg, &argc);
|
get_constraint_for_rhs (arg, &argc);
|
||||||
FOR_EACH_VEC_ELT (ce_s, argc, i, argp)
|
FOR_EACH_VEC_ELT (ce_s, argc, i, argp)
|
||||||
VEC_safe_push (ce_s, heap, *results, argp);
|
VEC_safe_push (ce_s, heap, *results, argp);
|
||||||
VEC_free(ce_s, heap, argc);
|
VEC_free(ce_s, heap, argc);
|
||||||
|
|
@ -4038,7 +4075,7 @@ find_func_aliases (gimple origt)
|
||||||
tree strippedrhs = PHI_ARG_DEF (t, i);
|
tree strippedrhs = PHI_ARG_DEF (t, i);
|
||||||
|
|
||||||
STRIP_NOPS (strippedrhs);
|
STRIP_NOPS (strippedrhs);
|
||||||
get_constraint_for (gimple_phi_arg_def (t, i), &rhsc);
|
get_constraint_for_rhs (gimple_phi_arg_def (t, i), &rhsc);
|
||||||
|
|
||||||
FOR_EACH_VEC_ELT (ce_s, lhsc, j, c)
|
FOR_EACH_VEC_ELT (ce_s, lhsc, j, c)
|
||||||
{
|
{
|
||||||
|
|
@ -4322,7 +4359,7 @@ find_func_aliases (gimple origt)
|
||||||
if (!could_have_pointers (arg))
|
if (!could_have_pointers (arg))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
get_constraint_for (arg, &rhsc);
|
get_constraint_for_rhs (arg, &rhsc);
|
||||||
lhs = get_function_part_constraint (fi, fi_parm_base + j);
|
lhs = get_function_part_constraint (fi, fi_parm_base + j);
|
||||||
while (VEC_length (ce_s, rhsc) != 0)
|
while (VEC_length (ce_s, rhsc) != 0)
|
||||||
{
|
{
|
||||||
|
|
@ -4417,7 +4454,7 @@ find_func_aliases (gimple origt)
|
||||||
&& !(POINTER_TYPE_P (gimple_expr_type (t))
|
&& !(POINTER_TYPE_P (gimple_expr_type (t))
|
||||||
&& !POINTER_TYPE_P (TREE_TYPE (rhsop))))
|
&& !POINTER_TYPE_P (TREE_TYPE (rhsop))))
|
||||||
|| gimple_assign_single_p (t))
|
|| gimple_assign_single_p (t))
|
||||||
get_constraint_for (rhsop, &rhsc);
|
get_constraint_for_rhs (rhsop, &rhsc);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
temp.type = ADDRESSOF;
|
temp.type = ADDRESSOF;
|
||||||
|
|
@ -4468,7 +4505,7 @@ find_func_aliases (gimple origt)
|
||||||
unsigned i;
|
unsigned i;
|
||||||
|
|
||||||
lhs = get_function_part_constraint (fi, fi_result);
|
lhs = get_function_part_constraint (fi, fi_result);
|
||||||
get_constraint_for (gimple_return_retval (t), &rhsc);
|
get_constraint_for_rhs (gimple_return_retval (t), &rhsc);
|
||||||
FOR_EACH_VEC_ELT (ce_s, rhsc, i, rhsp)
|
FOR_EACH_VEC_ELT (ce_s, rhsc, i, rhsp)
|
||||||
process_constraint (new_constraint (lhs, *rhsp));
|
process_constraint (new_constraint (lhs, *rhsp));
|
||||||
}
|
}
|
||||||
|
|
@ -4549,7 +4586,7 @@ process_ipa_clobber (varinfo_t fi, tree ptr)
|
||||||
VEC(ce_s, heap) *ptrc = NULL;
|
VEC(ce_s, heap) *ptrc = NULL;
|
||||||
struct constraint_expr *c, lhs;
|
struct constraint_expr *c, lhs;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
get_constraint_for (ptr, &ptrc);
|
get_constraint_for_rhs (ptr, &ptrc);
|
||||||
lhs = get_function_part_constraint (fi, fi_clobbers);
|
lhs = get_function_part_constraint (fi, fi_clobbers);
|
||||||
FOR_EACH_VEC_ELT (ce_s, ptrc, i, c)
|
FOR_EACH_VEC_ELT (ce_s, ptrc, i, c)
|
||||||
process_constraint (new_constraint (lhs, *c));
|
process_constraint (new_constraint (lhs, *c));
|
||||||
|
|
@ -5430,7 +5467,7 @@ create_variable_info_for (tree decl, const char *name)
|
||||||
VEC (ce_s, heap) *rhsc = NULL;
|
VEC (ce_s, heap) *rhsc = NULL;
|
||||||
struct constraint_expr lhs, *rhsp;
|
struct constraint_expr lhs, *rhsp;
|
||||||
unsigned i;
|
unsigned i;
|
||||||
get_constraint_for (DECL_INITIAL (decl), &rhsc);
|
get_constraint_for_rhs (DECL_INITIAL (decl), &rhsc);
|
||||||
lhs.var = vi->id;
|
lhs.var = vi->id;
|
||||||
lhs.offset = 0;
|
lhs.offset = 0;
|
||||||
lhs.type = SCALAR;
|
lhs.type = SCALAR;
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue