Hello.

When inserting into fast_call_summary (or fast_function_summary), we grow
a vector to a _exact_ size based on cgraph_max_summary_id or 
edges_max_summary_id.
Problem is that it causes very many reallocation and we should rather use 
::reserve
function that selects a reasonable size of a new vector.

Patch can bootstrap on x86_64-linux-gnu and survives regression tests.
Fixes chromium WPA build time:
https://gist.githubusercontent.com/marxin/223890df4d8d8e490b6b2918b77dacad/raw/f766f6546739e739a273639dde90ac6179aa3077/chromium-gcc10-fixed-summary-crash.svg

Ready to be installed?
Thanks,
Martin

gcc/ChangeLog:

        * symbol-summary.h: Call vec_safe_reserve before grow is called
        in order to grow to a reasonable size.
        * vec.h (vec_safe_reserve): Add missing function for vl_ptr
        type.
---
 gcc/symbol-summary.h | 13 ++++++++++---
 gcc/vec.h            | 11 +++++++++++
 2 files changed, 21 insertions(+), 3 deletions(-)

diff --git a/gcc/symbol-summary.h b/gcc/symbol-summary.h
index a38eb1db778..fa1df5c8015 100644
--- a/gcc/symbol-summary.h
+++ b/gcc/symbol-summary.h
@@ -354,8 +354,11 @@ public:
       id = this->m_symtab->assign_summary_id (node);
if ((unsigned int)id >= m_vector->length ())
-      vec_safe_grow_cleared (m_vector,
-                            this->m_symtab->cgraph_max_summary_id);
+      {
+       int newlen = this->m_symtab->cgraph_max_summary_id;
+       vec_safe_reserve (m_vector, newlen - m_vector->length ());
+       m_vector->quick_grow_cleared (newlen);
+      }
if ((*m_vector)[id] == NULL)
       (*m_vector)[id] = this->allocate_new ();
@@ -812,7 +815,11 @@ public:
       id = this->m_symtab->assign_summary_id (edge);
if ((unsigned)id >= m_vector->length ())
-      vec_safe_grow_cleared (m_vector, this->m_symtab->edges_max_summary_id);
+      {
+       int newlen = this->m_symtab->edges_max_summary_id;
+       m_vector->reserve (newlen - m_vector->length ());
+       m_vector->quick_grow_cleared (newlen);
+      }
if ((*m_vector)[id] == NULL)
       (*m_vector)[id] = this->allocate_new ();
diff --git a/gcc/vec.h b/gcc/vec.h
index bd7c7351dcd..3ad99b83690 100644
--- a/gcc/vec.h
+++ b/gcc/vec.h
@@ -753,6 +753,17 @@ vec_safe_grow_cleared (vec<T, va_heap, vl_ptr> *&v,
   v->safe_grow_cleared (len PASS_MEM_STAT);
 }
+/* If V does not have space for NELEMS elements, call
+   V->reserve(NELEMS, EXACT).  */
+
+template<typename T>
+inline bool
+vec_safe_reserve (vec<T, va_heap, vl_ptr> *&v, unsigned nelems, bool exact = 
false
+                 CXX_MEM_STAT_INFO)
+{
+  return v->reserve (nelems, exact);
+}
+
/* If V is NULL return false, otherwise return V->iterate(IX, PTR). */
 template<typename T, typename A>
--
2.27.0

Reply via email to