aboutsummaryrefslogtreecommitdiffstats
path: root/gcc-4.8/gcc/tree-ssa-structalias.c
diff options
context:
space:
mode:
Diffstat (limited to 'gcc-4.8/gcc/tree-ssa-structalias.c')
-rw-r--r--gcc-4.8/gcc/tree-ssa-structalias.c104
1 files changed, 53 insertions, 51 deletions
diff --git a/gcc-4.8/gcc/tree-ssa-structalias.c b/gcc-4.8/gcc/tree-ssa-structalias.c
index d4b140011..6b52ae961 100644
--- a/gcc-4.8/gcc/tree-ssa-structalias.c
+++ b/gcc-4.8/gcc/tree-ssa-structalias.c
@@ -949,24 +949,27 @@ solution_set_add (bitmap set, HOST_WIDE_INT offset)
bitmap_set_bit (result, i);
else
{
- unsigned HOST_WIDE_INT fieldoffset = vi->offset + offset;
+ HOST_WIDE_INT fieldoffset = vi->offset + offset;
+ unsigned HOST_WIDE_INT size = vi->size;
/* If the offset makes the pointer point to before the
variable use offset zero for the field lookup. */
- if (offset < 0
- && fieldoffset > vi->offset)
- fieldoffset = 0;
-
- if (offset != 0)
+ if (fieldoffset < 0)
+ vi = lookup_vi_for_tree (vi->decl);
+ else
vi = first_or_preceding_vi_for_offset (vi, fieldoffset);
+ do
+ {
bitmap_set_bit (result, vi->id);
- /* If the result is not exactly at fieldoffset include the next
- field as well. See get_constraint_for_ptr_offset for more
- rationale. */
- if (vi->offset != fieldoffset
- && vi->next != NULL)
- bitmap_set_bit (result, vi->next->id);
+ if (!vi->next)
+ break;
+
+ /* We have to include all fields that overlap the current field
+ shifted by offset. */
+ vi = vi->next;
+ }
+ while (vi->offset < fieldoffset + size);
}
}
@@ -1607,16 +1610,21 @@ do_sd_constraint (constraint_graph_t graph, constraint_t c,
{
varinfo_t v = get_varinfo (j);
HOST_WIDE_INT fieldoffset = v->offset + roffset;
+ unsigned HOST_WIDE_INT size = v->size;
unsigned int t;
if (v->is_full_var)
- fieldoffset = v->offset;
+ ;
else if (roffset != 0)
- v = first_vi_for_offset (v, fieldoffset);
- /* If the access is outside of the variable we can ignore it. */
- if (!v)
- continue;
+ {
+ if (fieldoffset < 0)
+ v = lookup_vi_for_tree (v->decl);
+ else
+ v = first_or_preceding_vi_for_offset (v, fieldoffset);
+ }
+ /* We have to include all fields that overlap the current field
+ shifted by roffset. */
do
{
t = find (v->id);
@@ -1633,16 +1641,13 @@ do_sd_constraint (constraint_graph_t graph, constraint_t c,
&& add_graph_edge (graph, lhs, t))
flag |= bitmap_ior_into (sol, get_varinfo (t)->solution);
- /* If the variable is not exactly at the requested offset
- we have to include the next one. */
- if (v->offset == (unsigned HOST_WIDE_INT)fieldoffset
+ if (v->is_full_var
|| v->next == NULL)
break;
v = v->next;
- fieldoffset = v->offset;
}
- while (1);
+ while (v->offset < fieldoffset + size);
}
done:
@@ -1705,15 +1710,20 @@ do_ds_constraint (constraint_t c, bitmap delta)
varinfo_t v = get_varinfo (j);
unsigned int t;
HOST_WIDE_INT fieldoffset = v->offset + loff;
+ unsigned HOST_WIDE_INT size = v->size;
if (v->is_full_var)
- fieldoffset = v->offset;
+ ;
else if (loff != 0)
- v = first_vi_for_offset (v, fieldoffset);
- /* If the access is outside of the variable we can ignore it. */
- if (!v)
- continue;
+ {
+ if (fieldoffset < 0)
+ v = lookup_vi_for_tree (v->decl);
+ else
+ v = first_or_preceding_vi_for_offset (v, fieldoffset);
+ }
+ /* We have to include all fields that overlap the current field
+ shifted by loff. */
do
{
if (v->may_have_pointers)
@@ -1739,16 +1749,13 @@ do_ds_constraint (constraint_t c, bitmap delta)
bitmap_set_bit (changed, t);
}
- /* If the variable is not exactly at the requested offset
- we have to include the next one. */
- if (v->offset == (unsigned HOST_WIDE_INT)fieldoffset
+ if (v->is_full_var
|| v->next == NULL)
break;
v = v->next;
- fieldoffset = v->offset;
}
- while (1);
+ while (v->offset < fieldoffset + size);
}
}
@@ -2997,35 +3004,30 @@ get_constraint_for_ptr_offset (tree ptr, tree offset,
varinfo_t temp;
unsigned HOST_WIDE_INT offset = curr->offset + rhsoffset;
- /* Search the sub-field which overlaps with the
- pointed-to offset. If the result is outside of the variable
- we have to provide a conservative result, as the variable is
- still reachable from the resulting pointer (even though it
- technically cannot point to anything). The last and first
- sub-fields are such conservative results.
- ??? If we always had a sub-field for &object + 1 then
- we could represent this in a more precise way. */
+ /* If curr->offset + rhsoffset is less than zero adjust it. */
if (rhsoffset < 0
&& curr->offset < offset)
offset = 0;
- temp = first_or_preceding_vi_for_offset (curr, offset);
- /* If the found variable is not exactly at the pointed to
- result, we have to include the next variable in the
- solution as well. Otherwise two increments by offset / 2
- do not result in the same or a conservative superset
- solution. */
- if (temp->offset != offset
- && temp->next != NULL)
+ /* We have to include all fields that overlap the current
+ field shifted by rhsoffset. And we include at least
+ the last or the first field of the variable to represent
+ reachability of off-bound addresses, in particular &object + 1,
+ conservatively correct. */
+ temp = first_or_preceding_vi_for_offset (curr, offset);
+ c.var = temp->id;
+ c.offset = 0;
+ temp = temp->next;
+ while (temp
+ && temp->offset < offset + curr->size)
{
struct constraint_expr c2;
- c2.var = temp->next->id;
+ c2.var = temp->id;
c2.type = ADDRESSOF;
c2.offset = 0;
results->safe_push (c2);
+ temp = temp->next;
}
- c.var = temp->id;
- c.offset = 0;
}
else
c.offset = rhsoffset;