Commit afdb85f9 by Richard Biener Committed by Richard Biener

re PR fortran/81827 (Large compile time with derived-type rrays)

2017-08-17  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/81827
	* tree-ssa-structalias.c (struct variable_info): Add is_reg_var
	flag.
	(new_var_info): Initialize it conservatively.
	(get_call_vi): Mark register vars.
	(new_scalar_tmp_constraint_exp): Likewise.
	(handle_rhs_call): Likewise.
	(handle_const_call): Likewise.
	(create_function_info_for): Likewise.
	(solve_constraints): Sort varinfos to separate register from
	non-register vars to pack points-to solution bitmaps during
	iteration.

From-SVN: r251143
parent cca6b724
2017-08-17 Richard Biener <rguenther@suse.de>
PR tree-optimization/81827
* tree-ssa-structalias.c (struct variable_info): Add is_reg_var
flag.
(new_var_info): Initialize it conservatively.
(get_call_vi): Mark register vars.
(new_scalar_tmp_constraint_exp): Likewise.
(handle_rhs_call): Likewise.
(handle_const_call): Likewise.
(create_function_info_for): Likewise.
(solve_constraints): Sort varinfos to separate register from
non-register vars to pack points-to solution bitmaps during
iteration.
2017-08-17 Marek Polacek <polacek@redhat.com> 2017-08-17 Marek Polacek <polacek@redhat.com>
* gimplify.c (gimplify_adjust_omp_clauses): Compare with 0 instead of * gimplify.c (gimplify_adjust_omp_clauses): Compare with 0 instead of
......
...@@ -257,6 +257,9 @@ struct variable_info ...@@ -257,6 +257,9 @@ struct variable_info
/* True if this is a heap variable. */ /* True if this is a heap variable. */
unsigned int is_heap_var : 1; 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. */ /* True if this field may contain pointers. */
unsigned int may_have_pointers : 1; unsigned int may_have_pointers : 1;
...@@ -389,6 +392,7 @@ new_var_info (tree t, const char *name, bool add_id) ...@@ -389,6 +392,7 @@ new_var_info (tree t, const char *name, bool add_id)
/* We have to treat even local register variables /* We have to treat even local register variables
as escape points. */ as escape points. */
|| (VAR_P (t) && DECL_HARD_REGISTER (t))); || (VAR_P (t) && DECL_HARD_REGISTER (t)));
ret->is_reg_var = (t && TREE_CODE (t) == SSA_NAME);
ret->solution = BITMAP_ALLOC (&pta_obstack); ret->solution = BITMAP_ALLOC (&pta_obstack);
ret->oldsolution = NULL; ret->oldsolution = NULL;
ret->next = 0; ret->next = 0;
...@@ -422,12 +426,14 @@ get_call_vi (gcall *call) ...@@ -422,12 +426,14 @@ get_call_vi (gcall *call)
vi->size = 1; vi->size = 1;
vi->fullsize = 2; vi->fullsize = 2;
vi->is_full_var = true; vi->is_full_var = true;
vi->is_reg_var = true;
vi2 = new_var_info (NULL_TREE, "CALLCLOBBERED", true); vi2 = new_var_info (NULL_TREE, "CALLCLOBBERED", true);
vi2->offset = 1; vi2->offset = 1;
vi2->size = 1; vi2->size = 1;
vi2->fullsize = 2; vi2->fullsize = 2;
vi2->is_full_var = true; vi2->is_full_var = true;
vi2->is_reg_var = true;
vi->next = vi2->id; vi->next = vi2->id;
...@@ -2892,6 +2898,7 @@ new_scalar_tmp_constraint_exp (const char *name, bool add_id) ...@@ -2892,6 +2898,7 @@ new_scalar_tmp_constraint_exp (const char *name, bool add_id)
vi->size = -1; vi->size = -1;
vi->fullsize = -1; vi->fullsize = -1;
vi->is_full_var = 1; vi->is_full_var = 1;
vi->is_reg_var = 1;
tmp.var = vi->id; tmp.var = vi->id;
tmp.type = SCALAR; tmp.type = SCALAR;
...@@ -3930,6 +3937,7 @@ handle_rhs_call (gcall *stmt, vec<ce_s> *results) ...@@ -3930,6 +3937,7 @@ handle_rhs_call (gcall *stmt, vec<ce_s> *results)
{ {
varinfo_t uses = get_call_use_vi (stmt); varinfo_t uses = get_call_use_vi (stmt);
varinfo_t tem = new_var_info (NULL_TREE, "callarg", true); varinfo_t tem = new_var_info (NULL_TREE, "callarg", true);
tem->is_reg_var = true;
make_constraint_to (tem->id, arg); make_constraint_to (tem->id, arg);
make_any_offset_constraints (tem); make_any_offset_constraints (tem);
if (!(flags & EAF_DIRECT)) if (!(flags & EAF_DIRECT))
...@@ -3943,6 +3951,7 @@ handle_rhs_call (gcall *stmt, vec<ce_s> *results) ...@@ -3943,6 +3951,7 @@ handle_rhs_call (gcall *stmt, vec<ce_s> *results)
varinfo_t uses = get_call_use_vi (stmt); varinfo_t uses = get_call_use_vi (stmt);
varinfo_t clobbers = get_call_clobber_vi (stmt); varinfo_t clobbers = get_call_clobber_vi (stmt);
varinfo_t tem = new_var_info (NULL_TREE, "callarg", true); varinfo_t tem = new_var_info (NULL_TREE, "callarg", true);
tem->is_reg_var = true;
make_constraint_to (tem->id, arg); make_constraint_to (tem->id, arg);
make_any_offset_constraints (tem); make_any_offset_constraints (tem);
if (!(flags & EAF_DIRECT)) if (!(flags & EAF_DIRECT))
...@@ -4110,7 +4119,10 @@ handle_const_call (gcall *stmt, vec<ce_s> *results) ...@@ -4110,7 +4119,10 @@ handle_const_call (gcall *stmt, vec<ce_s> *results)
/* May return offsetted arguments. */ /* May return offsetted arguments. */
varinfo_t tem = NULL; varinfo_t tem = NULL;
if (gimple_call_num_args (stmt) != 0) 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) for (k = 0; k < gimple_call_num_args (stmt); ++k)
{ {
tree arg = gimple_call_arg (stmt, k); tree arg = gimple_call_arg (stmt, k);
...@@ -5712,6 +5724,7 @@ create_function_info_for (tree decl, const char *name, bool add_id, ...@@ -5712,6 +5724,7 @@ create_function_info_for (tree decl, const char *name, bool add_id,
clobbervi->fullsize = vi->fullsize; clobbervi->fullsize = vi->fullsize;
clobbervi->is_full_var = true; clobbervi->is_full_var = true;
clobbervi->is_global_var = false; clobbervi->is_global_var = false;
clobbervi->is_reg_var = true;
gcc_assert (prev_vi->offset < clobbervi->offset); gcc_assert (prev_vi->offset < clobbervi->offset);
prev_vi->next = clobbervi->id; prev_vi->next = clobbervi->id;
...@@ -5727,6 +5740,7 @@ create_function_info_for (tree decl, const char *name, bool add_id, ...@@ -5727,6 +5740,7 @@ create_function_info_for (tree decl, const char *name, bool add_id,
usevi->fullsize = vi->fullsize; usevi->fullsize = vi->fullsize;
usevi->is_full_var = true; usevi->is_full_var = true;
usevi->is_global_var = false; usevi->is_global_var = false;
usevi->is_reg_var = true;
gcc_assert (prev_vi->offset < usevi->offset); gcc_assert (prev_vi->offset < usevi->offset);
prev_vi->next = usevi->id; prev_vi->next = usevi->id;
...@@ -7075,6 +7089,39 @@ solve_constraints (void) ...@@ -7075,6 +7089,39 @@ solve_constraints (void)
{ {
struct scc_info *si; 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) if (dump_file)
fprintf (dump_file, fprintf (dump_file,
"\nCollapsing static cycles and doing variable " "\nCollapsing static cycles and doing variable "
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment