|| (TREE_CODE (t) == VAR_DECL
&& DECL_HARD_REGISTER (t)));
ret->solution = BITMAP_ALLOC (&pta_obstack);
- ret->oldsolution = BITMAP_ALLOC (&oldpta_obstack);
+ ret->oldsolution = NULL;
ret->next = NULL;
stats.total_vars++;
}
BITMAP_FREE (get_varinfo (from)->solution);
- BITMAP_FREE (get_varinfo (from)->oldsolution);
+ if (get_varinfo (from)->oldsolution)
+ BITMAP_FREE (get_varinfo (from)->oldsolution);
- if (stats.iterations > 0)
- {
- BITMAP_FREE (get_varinfo (to)->oldsolution);
- get_varinfo (to)->oldsolution = BITMAP_ALLOC (&oldpta_obstack);
- }
+ if (stats.iterations > 0
+ && get_varinfo (to)->oldsolution)
+ BITMAP_FREE (get_varinfo (to)->oldsolution);
}
if (valid_graph_edge (graph, to, to))
{
constraint_t c;
bitmap solution;
VEC(constraint_t,heap) *complex = graph->complex[i];
+ varinfo_t vi = get_varinfo (i);
bool solution_empty;
/* Compute the changed set of solution bits. */
- bitmap_and_compl (pts, get_varinfo (i)->solution,
- get_varinfo (i)->oldsolution);
+ if (vi->oldsolution)
+ bitmap_and_compl (pts, vi->solution, vi->oldsolution);
+ else
+ bitmap_copy (pts, vi->solution);
if (bitmap_empty_p (pts))
continue;
- bitmap_ior_into (get_varinfo (i)->oldsolution, pts);
+ if (vi->oldsolution)
+ bitmap_ior_into (vi->oldsolution, pts);
+ else
+ {
+ vi->oldsolution = BITMAP_ALLOC (&oldpta_obstack);
+ bitmap_copy (vi->oldsolution, pts);
+ }
- solution = get_varinfo (i)->solution;
+ solution = vi->solution;
solution_empty = bitmap_empty_p (solution);
/* Process the complex constraints */
{
struct constraint_expr c;
unsigned int j, n;
- HOST_WIDE_INT rhsunitoffset, rhsoffset;
+ HOST_WIDE_INT rhsoffset;
/* If we do not do field-sensitive PTA adding offsets to pointers
does not change the points-to solution. */
solution which includes all sub-fields of all pointed-to
variables of ptr. */
if (offset == NULL_TREE
- || !host_integerp (offset, 0))
+ || TREE_CODE (offset) != INTEGER_CST)
rhsoffset = UNKNOWN_OFFSET;
else
{
- /* Make sure the bit-offset also fits. */
- rhsunitoffset = TREE_INT_CST_LOW (offset);
- rhsoffset = rhsunitoffset * BITS_PER_UNIT;
- if (rhsunitoffset != rhsoffset / BITS_PER_UNIT)
+ /* Sign-extend the offset. */
+ double_int soffset
+ = double_int_sext (tree_to_double_int (offset),
+ TYPE_PRECISION (TREE_TYPE (offset)));
+ if (!double_int_fits_in_shwi_p (soffset))
rhsoffset = UNKNOWN_OFFSET;
+ else
+ {
+ /* Make sure the bit-offset also fits. */
+ HOST_WIDE_INT rhsunitoffset = soffset.low;
+ rhsoffset = rhsunitoffset * BITS_PER_UNIT;
+ if (rhsunitoffset != rhsoffset / BITS_PER_UNIT)
+ rhsoffset = UNKNOWN_OFFSET;
+ }
}
get_constraint_for_rhs (ptr, results);
{
struct constraint_expr cs;
varinfo_t vi, curr;
- tree off = double_int_to_tree (sizetype, mem_ref_offset (t));
- get_constraint_for_ptr_offset (TREE_OPERAND (t, 0), off, results);
+ get_constraint_for_ptr_offset (TREE_OPERAND (t, 0),
+ TREE_OPERAND (t, 1), results);
do_deref (results);
/* If we are not taking the address then make sure to process
all subvariables we might access. */
+ if (address_p)
+ return;
+
cs = *VEC_last (ce_s, *results);
- if (address_p
- || cs.type != SCALAR)
+ if (cs.type == DEREF)
+ {
+ /* For dereferences this means we have to defer it
+ to solving time. */
+ VEC_last (ce_s, *results)->offset = UNKNOWN_OFFSET;
+ return;
+ }
+ if (cs.type != SCALAR)
return;
vi = get_varinfo (cs.var);