From afdb85f9dd2a354027eabae91b461df6d08ecb5c Mon Sep 17 00:00:00 2001 From: Richard Biener Date: Thu, 17 Aug 2017 10:04:04 +0000 Subject: [PATCH] re PR fortran/81827 (Large compile time with derived-type rrays) 2017-08-17 Richard Biener 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 --- gcc/ChangeLog | 15 ++++++++++++ gcc/tree-ssa-structalias.c | 49 +++++++++++++++++++++++++++++++++++++- 2 files changed, 63 insertions(+), 1 deletion(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 26eb5451121..d4db491b1f2 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,18 @@ +2017-08-17 Richard Biener + + 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 * gimplify.c (gimplify_adjust_omp_clauses): Compare with 0 instead of diff --git a/gcc/tree-ssa-structalias.c b/gcc/tree-ssa-structalias.c index c120ce40303..c95d1e3784b 100644 --- a/gcc/tree-ssa-structalias.c +++ b/gcc/tree-ssa-structalias.c @@ -257,6 +257,9 @@ struct variable_info /* 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; @@ -389,6 +392,7 @@ new_var_info (tree t, const char *name, bool add_id) /* 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; @@ -422,12 +426,14 @@ get_call_vi (gcall *call) 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; @@ -2892,6 +2898,7 @@ new_scalar_tmp_constraint_exp (const char *name, bool add_id) vi->size = -1; vi->fullsize = -1; vi->is_full_var = 1; + vi->is_reg_var = 1; tmp.var = vi->id; tmp.type = SCALAR; @@ -3930,6 +3937,7 @@ handle_rhs_call (gcall *stmt, vec *results) { 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)) @@ -3943,6 +3951,7 @@ handle_rhs_call (gcall *stmt, vec *results) 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)) @@ -4110,7 +4119,10 @@ handle_const_call (gcall *stmt, vec *results) /* 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); @@ -5712,6 +5724,7 @@ create_function_info_for (tree decl, const char *name, bool add_id, 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; @@ -5727,6 +5740,7 @@ create_function_info_for (tree decl, const char *name, bool add_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; @@ -7075,6 +7089,39 @@ solve_constraints (void) { 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 " -- 2.30.2