/* True if this is a heap variable. */
unsigned int is_heap_var : 1;
+ /* True if this is a register variable. */
+ unsigned int is_reg_var : 1;
+
/* True if this field may contain pointers. */
unsigned int may_have_pointers : 1;
/* We have to treat even local register variables
as escape points. */
|| (VAR_P (t) && DECL_HARD_REGISTER (t)));
+ ret->is_reg_var = (t && TREE_CODE (t) == SSA_NAME);
ret->solution = BITMAP_ALLOC (&pta_obstack);
ret->oldsolution = NULL;
ret->next = 0;
vi->size = 1;
vi->fullsize = 2;
vi->is_full_var = true;
+ vi->is_reg_var = true;
vi2 = new_var_info (NULL_TREE, "CALLCLOBBERED", true);
vi2->offset = 1;
vi2->size = 1;
vi2->fullsize = 2;
vi2->is_full_var = true;
+ vi2->is_reg_var = true;
vi->next = vi2->id;
vi->size = -1;
vi->fullsize = -1;
vi->is_full_var = 1;
+ vi->is_reg_var = 1;
tmp.var = vi->id;
tmp.type = SCALAR;
{
varinfo_t uses = get_call_use_vi (stmt);
varinfo_t tem = new_var_info (NULL_TREE, "callarg", true);
+ tem->is_reg_var = true;
make_constraint_to (tem->id, arg);
make_any_offset_constraints (tem);
if (!(flags & EAF_DIRECT))
varinfo_t uses = get_call_use_vi (stmt);
varinfo_t clobbers = get_call_clobber_vi (stmt);
varinfo_t tem = new_var_info (NULL_TREE, "callarg", true);
+ tem->is_reg_var = true;
make_constraint_to (tem->id, arg);
make_any_offset_constraints (tem);
if (!(flags & EAF_DIRECT))
/* May return offsetted arguments. */
varinfo_t tem = NULL;
if (gimple_call_num_args (stmt) != 0)
- tem = new_var_info (NULL_TREE, "callarg", true);
+ {
+ tem = new_var_info (NULL_TREE, "callarg", true);
+ tem->is_reg_var = true;
+ }
for (k = 0; k < gimple_call_num_args (stmt); ++k)
{
tree arg = gimple_call_arg (stmt, k);
clobbervi->fullsize = vi->fullsize;
clobbervi->is_full_var = true;
clobbervi->is_global_var = false;
+ clobbervi->is_reg_var = true;
gcc_assert (prev_vi->offset < clobbervi->offset);
prev_vi->next = clobbervi->id;
usevi->fullsize = vi->fullsize;
usevi->is_full_var = true;
usevi->is_global_var = false;
+ usevi->is_reg_var = true;
gcc_assert (prev_vi->offset < usevi->offset);
prev_vi->next = usevi->id;
{
struct scc_info *si;
+ /* Sort varinfos so that ones that cannot be pointed to are last.
+ This makes bitmaps more efficient. */
+ unsigned int *map = XNEWVEC (unsigned int, varmap.length ());
+ for (unsigned i = 0; i < integer_id + 1; ++i)
+ map[i] = i;
+ /* Start with non-register vars (as possibly address-taken), followed
+ by register vars as conservative set of vars never appearing in
+ the points-to solution bitmaps. */
+ unsigned j = integer_id + 1;
+ for (unsigned i = integer_id + 1; i < varmap.length (); ++i)
+ if (! varmap[i]->is_reg_var)
+ map[i] = j++;
+ for (unsigned i = integer_id + 1; i < varmap.length (); ++i)
+ if (varmap[i]->is_reg_var)
+ map[i] = j++;
+ /* Shuffle varmap according to map. */
+ for (unsigned i = integer_id + 1; i < varmap.length (); ++i)
+ {
+ while (map[varmap[i]->id] != i)
+ std::swap (varmap[i], varmap[map[varmap[i]->id]]);
+ gcc_assert (bitmap_empty_p (varmap[i]->solution));
+ varmap[i]->id = i;
+ varmap[i]->next = map[varmap[i]->next];
+ varmap[i]->head = map[varmap[i]->head];
+ }
+ /* Finally rewrite constraints. */
+ for (unsigned i = 0; i < constraints.length (); ++i)
+ {
+ constraints[i]->lhs.var = map[constraints[i]->lhs.var];
+ constraints[i]->rhs.var = map[constraints[i]->rhs.var];
+ }
+ free (map);
+
if (dump_file)
fprintf (dump_file,
"\nCollapsing static cycles and doing variable "