alias.c (ncr_compar): New function.

2014-04-15  Richard Biener  <rguenther@suse.de>

	* alias.c (ncr_compar): New function.
	(nonoverlapping_component_refs_p): Re-implement in O (n log n).

From-SVN: r209413
This commit is contained in:
Richard Biener 2014-04-15 10:18:28 +00:00 committed by Richard Biener
parent 1999fd7dde
commit d8e4ce6d85
2 changed files with 103 additions and 40 deletions

View File

@ -1,3 +1,8 @@
2014-04-15 Richard Biener <rguenther@suse.de>
* alias.c (ncr_compar): New function.
(nonoverlapping_component_refs_p): Re-implement in O (n log n).
2014-04-15 Richard Biener <rguenther@suse.de>
* alias.c (record_component_aliases): Do not walk BINFOs.

View File

@ -2248,6 +2248,25 @@ read_dependence (const_rtx mem, const_rtx x)
return false;
}
/* qsort compare function to sort FIELD_DECLs after their
DECL_FIELD_CONTEXT TYPE_UID. */
static inline int
ncr_compar (const void *field1_, const void *field2_)
{
const_tree field1 = *(const_tree *) const_cast <void *>(field1_);
const_tree field2 = *(const_tree *) const_cast <void *>(field2_);
unsigned int uid1
= TYPE_UID (TYPE_MAIN_VARIANT (DECL_FIELD_CONTEXT (field1)));
unsigned int uid2
= TYPE_UID (TYPE_MAIN_VARIANT (DECL_FIELD_CONTEXT (field2)));
if (uid1 < uid2)
return -1;
else if (uid1 > uid2)
return 1;
return 0;
}
/* Return true if we can determine that the fields referenced cannot
overlap for any pair of objects. */
@ -2255,7 +2274,6 @@ static bool
nonoverlapping_component_refs_p (const_rtx rtlx, const_rtx rtly)
{
const_tree x = MEM_EXPR (rtlx), y = MEM_EXPR (rtly);
const_tree fieldx, fieldy, typex, typey, orig_y;
if (!flag_strict_aliasing
|| !x || !y
@ -2263,49 +2281,89 @@ nonoverlapping_component_refs_p (const_rtx rtlx, const_rtx rtly)
|| TREE_CODE (y) != COMPONENT_REF)
return false;
do
auto_vec<const_tree, 16> fieldsx;
while (TREE_CODE (x) == COMPONENT_REF)
{
/* The comparison has to be done at a common type, since we don't
know how the inheritance hierarchy works. */
orig_y = y;
do
{
fieldx = TREE_OPERAND (x, 1);
typex = TYPE_MAIN_VARIANT (DECL_FIELD_CONTEXT (fieldx));
y = orig_y;
do
{
fieldy = TREE_OPERAND (y, 1);
typey = TYPE_MAIN_VARIANT (DECL_FIELD_CONTEXT (fieldy));
if (typex == typey)
goto found;
y = TREE_OPERAND (y, 0);
}
while (y && TREE_CODE (y) == COMPONENT_REF);
x = TREE_OPERAND (x, 0);
}
while (x && TREE_CODE (x) == COMPONENT_REF);
/* Never found a common type. */
return false;
found:
/* If we're left with accessing different fields of a structure, then no
possible overlap, unless they are both bitfields. */
if (TREE_CODE (typex) == RECORD_TYPE && fieldx != fieldy)
return !(DECL_BIT_FIELD (fieldx) && DECL_BIT_FIELD (fieldy));
/* The comparison on the current field failed. If we're accessing
a very nested structure, look at the next outer level. */
tree field = TREE_OPERAND (x, 1);
tree type = TYPE_MAIN_VARIANT (DECL_FIELD_CONTEXT (field));
if (TREE_CODE (type) == RECORD_TYPE)
fieldsx.safe_push (field);
x = TREE_OPERAND (x, 0);
}
if (fieldsx.length () == 0)
return false;
auto_vec<const_tree, 16> fieldsy;
while (TREE_CODE (y) == COMPONENT_REF)
{
tree field = TREE_OPERAND (y, 1);
tree type = TYPE_MAIN_VARIANT (DECL_FIELD_CONTEXT (field));
if (TREE_CODE (type) == RECORD_TYPE)
fieldsy.safe_push (TREE_OPERAND (y, 1));
y = TREE_OPERAND (y, 0);
}
while (x && y
&& TREE_CODE (x) == COMPONENT_REF
&& TREE_CODE (y) == COMPONENT_REF);
if (fieldsy.length () == 0)
return false;
/* Most common case first. */
if (fieldsx.length () == 1
&& fieldsy.length () == 1)
return ((TYPE_MAIN_VARIANT (DECL_FIELD_CONTEXT (fieldsx[0]))
== TYPE_MAIN_VARIANT (DECL_FIELD_CONTEXT (fieldsy[0])))
&& fieldsx[0] != fieldsy[0]
&& !(DECL_BIT_FIELD (fieldsx[0]) && DECL_BIT_FIELD (fieldsy[0])));
if (fieldsx.length () == 2)
{
if (ncr_compar (&fieldsx[0], &fieldsx[1]) == 1)
{
const_tree tem = fieldsx[0];
fieldsx[0] = fieldsx[1];
fieldsx[1] = tem;
}
}
else
fieldsx.qsort (ncr_compar);
if (fieldsy.length () == 2)
{
if (ncr_compar (&fieldsy[0], &fieldsy[1]) == 1)
{
const_tree tem = fieldsy[0];
fieldsy[0] = fieldsy[1];
fieldsy[1] = tem;
}
}
else
fieldsy.qsort (ncr_compar);
unsigned i = 0, j = 0;
do
{
const_tree fieldx = fieldsx[i];
const_tree fieldy = fieldsy[j];
tree typex = TYPE_MAIN_VARIANT (DECL_FIELD_CONTEXT (fieldx));
tree typey = TYPE_MAIN_VARIANT (DECL_FIELD_CONTEXT (fieldy));
if (typex == typey)
{
/* We're left with accessing different fields of a structure,
no possible overlap, unless they are both bitfields. */
if (fieldx != fieldy)
return !(DECL_BIT_FIELD (fieldx) && DECL_BIT_FIELD (fieldy));
}
if (TYPE_UID (typex) < TYPE_UID (typey))
{
i++;
if (i == fieldsx.length ())
break;
}
else
{
j++;
if (j == fieldsy.length ())
break;
}
}
while (1);
return false;
}