Commit 029ca388 by Richard Biener Committed by Richard Biener

re PR tree-optimization/91257 (Compile-time and memory-hog hog)

2019-07-30  Richard Biener  <rguenther@suse.de>

	PR tree-optimization/91257
	* bitmap.h (bitmap_ior_into_and_free): Declare.
	* bitmap.c (bitmap_list_unlink_element): Add defaulted param
	whether to add the unliked element to the freelist.
	(bitmap_list_insert_element_after): Add defaulted param for
	an already allocated element.
	(bitmap_ior_into_and_free): New function.
	* tree-ssa-structalias.c (condense_visit): Reduce the
	ponts-to and edge bitmaps of the SCC members in a
	logarithmic fashion rather than all to one.

From-SVN: r273907
parent 1da8ab97
2019-07-30 Richard Biener <rguenther@suse.de>
PR tree-optimization/91257
* bitmap.h (bitmap_ior_into_and_free): Declare.
* bitmap.c (bitmap_list_unlink_element): Add defaulted param
whether to add the unliked element to the freelist.
(bitmap_list_insert_element_after): Add defaulted param for
an already allocated element.
(bitmap_ior_into_and_free): New function.
* tree-ssa-structalias.c (condense_visit): Reduce the
ponts-to and edge bitmaps of the SCC members in a
logarithmic fashion rather than all to one.
2019-07-30 Richard Sandiford <richard.sandiford@arm.com> 2019-07-30 Richard Sandiford <richard.sandiford@arm.com>
* tree-ssa-math-opts.c (convert_mult_to_fma): Add a mul_cond * tree-ssa-math-opts.c (convert_mult_to_fma): Add a mul_cond
......
...@@ -267,7 +267,8 @@ bitmap_list_link_element (bitmap head, bitmap_element *element) ...@@ -267,7 +267,8 @@ bitmap_list_link_element (bitmap head, bitmap_element *element)
and return it to the freelist. */ and return it to the freelist. */
static inline void static inline void
bitmap_list_unlink_element (bitmap head, bitmap_element *element) bitmap_list_unlink_element (bitmap head, bitmap_element *element,
bool to_freelist = true)
{ {
bitmap_element *next = element->next; bitmap_element *next = element->next;
bitmap_element *prev = element->prev; bitmap_element *prev = element->prev;
...@@ -294,18 +295,21 @@ bitmap_list_unlink_element (bitmap head, bitmap_element *element) ...@@ -294,18 +295,21 @@ bitmap_list_unlink_element (bitmap head, bitmap_element *element)
head->indx = 0; head->indx = 0;
} }
bitmap_elem_to_freelist (head, element); if (to_freelist)
bitmap_elem_to_freelist (head, element);
} }
/* Insert a new uninitialized element into bitmap HEAD after element /* Insert a new uninitialized element (or NODE if not NULL) into bitmap
ELT. If ELT is NULL, insert the element at the start. Return the HEAD after element ELT. If ELT is NULL, insert the element at the start.
new element. */ Return the new element. */
static bitmap_element * static bitmap_element *
bitmap_list_insert_element_after (bitmap head, bitmap_list_insert_element_after (bitmap head,
bitmap_element *elt, unsigned int indx) bitmap_element *elt, unsigned int indx,
bitmap_element *node = NULL)
{ {
bitmap_element *node = bitmap_element_allocate (head); if (!node)
node = bitmap_element_allocate (head);
node->indx = indx; node->indx = indx;
gcc_checking_assert (!head->tree_form); gcc_checking_assert (!head->tree_form);
...@@ -2026,6 +2030,56 @@ bitmap_ior_into (bitmap a, const_bitmap b) ...@@ -2026,6 +2030,56 @@ bitmap_ior_into (bitmap a, const_bitmap b)
return changed; return changed;
} }
/* A |= B. Return true if A changes. Free B (re-using its storage
for the result). */
bool
bitmap_ior_into_and_free (bitmap a, bitmap *b_)
{
bitmap b = *b_;
bitmap_element *a_elt = a->first;
bitmap_element *b_elt = b->first;
bitmap_element *a_prev = NULL;
bitmap_element **a_prev_pnext = &a->first;
bool changed = false;
gcc_checking_assert (!a->tree_form && !b->tree_form);
gcc_assert (a->obstack == b->obstack);
if (a == b)
return false;
while (b_elt)
{
/* If A lags behind B, just advance it. */
if (!a_elt || a_elt->indx == b_elt->indx)
{
changed = bitmap_elt_ior (a, a_elt, a_prev, a_elt, b_elt, changed);
b_elt = b_elt->next;
}
else if (a_elt->indx > b_elt->indx)
{
bitmap_element *b_elt_next = b_elt->next;
bitmap_list_unlink_element (b, b_elt, false);
bitmap_list_insert_element_after (a, a_prev, b_elt->indx, b_elt);
b_elt = b_elt_next;
}
a_prev = *a_prev_pnext;
a_prev_pnext = &a_prev->next;
a_elt = *a_prev_pnext;
}
gcc_checking_assert (!a->current == !a->first);
if (a->current)
a->indx = a->current->indx;
if (b->obstack)
BITMAP_FREE (*b_);
else
bitmap_clear (b);
return changed;
}
/* DST = A ^ B */ /* DST = A ^ B */
void void
......
...@@ -415,6 +415,7 @@ extern void bitmap_clear_range (bitmap, unsigned int, unsigned int); ...@@ -415,6 +415,7 @@ extern void bitmap_clear_range (bitmap, unsigned int, unsigned int);
extern void bitmap_set_range (bitmap, unsigned int, unsigned int); extern void bitmap_set_range (bitmap, unsigned int, unsigned int);
extern bool bitmap_ior (bitmap, const_bitmap, const_bitmap); extern bool bitmap_ior (bitmap, const_bitmap, const_bitmap);
extern bool bitmap_ior_into (bitmap, const_bitmap); extern bool bitmap_ior_into (bitmap, const_bitmap);
extern bool bitmap_ior_into_and_free (bitmap, bitmap *);
extern void bitmap_xor (bitmap, const_bitmap, const_bitmap); extern void bitmap_xor (bitmap, const_bitmap, const_bitmap);
extern void bitmap_xor_into (bitmap, const_bitmap); extern void bitmap_xor_into (bitmap, const_bitmap);
......
...@@ -2071,36 +2071,73 @@ condense_visit (constraint_graph_t graph, class scc_info *si, unsigned int n) ...@@ -2071,36 +2071,73 @@ condense_visit (constraint_graph_t graph, class scc_info *si, unsigned int n)
/* See if any components have been identified. */ /* See if any components have been identified. */
if (si->dfs[n] == my_dfs) if (si->dfs[n] == my_dfs)
{ {
while (si->scc_stack.length () != 0 if (si->scc_stack.length () != 0
&& si->dfs[si->scc_stack.last ()] >= my_dfs) && si->dfs[si->scc_stack.last ()] >= my_dfs)
{ {
unsigned int w = si->scc_stack.pop (); /* Find the first node of the SCC and do non-bitmap work. */
si->node_mapping[w] = n; bool direct_p = true;
unsigned first = si->scc_stack.length ();
if (!bitmap_bit_p (graph->direct_nodes, w)) do
bitmap_clear_bit (graph->direct_nodes, n);
/* Unify our nodes. */
if (graph->preds[w])
{
if (!graph->preds[n])
graph->preds[n] = BITMAP_ALLOC (&predbitmap_obstack);
bitmap_ior_into (graph->preds[n], graph->preds[w]);
}
if (graph->implicit_preds[w])
{ {
if (!graph->implicit_preds[n]) --first;
graph->implicit_preds[n] = BITMAP_ALLOC (&predbitmap_obstack); unsigned int w = si->scc_stack[first];
bitmap_ior_into (graph->implicit_preds[n], si->node_mapping[w] = n;
graph->implicit_preds[w]); if (!bitmap_bit_p (graph->direct_nodes, w))
direct_p = false;
} }
if (graph->points_to[w]) while (first > 0
&& si->dfs[si->scc_stack[first - 1]] >= my_dfs);
if (!direct_p)
bitmap_clear_bit (graph->direct_nodes, n);
/* Want to reduce to node n, push that first. */
si->scc_stack.reserve (1);
si->scc_stack.quick_push (si->scc_stack[first]);
si->scc_stack[first] = n;
unsigned scc_size = si->scc_stack.length () - first;
unsigned split = scc_size / 2;
unsigned carry = scc_size - split * 2;
while (split > 0)
{ {
if (!graph->points_to[n]) for (unsigned i = 0; i < split; ++i)
graph->points_to[n] = BITMAP_ALLOC (&predbitmap_obstack); {
bitmap_ior_into (graph->points_to[n], unsigned a = si->scc_stack[first + i];
graph->points_to[w]); unsigned b = si->scc_stack[first + split + carry + i];
/* Unify our nodes. */
if (graph->preds[b])
{
if (!graph->preds[a])
std::swap (graph->preds[a], graph->preds[b]);
else
bitmap_ior_into_and_free (graph->preds[a],
&graph->preds[b]);
}
if (graph->implicit_preds[b])
{
if (!graph->implicit_preds[a])
std::swap (graph->implicit_preds[a],
graph->implicit_preds[b]);
else
bitmap_ior_into_and_free (graph->implicit_preds[a],
&graph->implicit_preds[b]);
}
if (graph->points_to[b])
{
if (!graph->points_to[a])
std::swap (graph->points_to[a], graph->points_to[b]);
else
bitmap_ior_into_and_free (graph->points_to[a],
&graph->points_to[b]);
}
}
unsigned remain = split + carry;
split = remain / 2;
carry = remain - split * 2;
} }
/* Actually pop the SCC. */
si->scc_stack.truncate (first);
} }
bitmap_set_bit (si->deleted, n); bitmap_set_bit (si->deleted, n);
} }
......
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