https://gcc.gnu.org/g:ddc72ba6c6c2c84a1a95340840bd5fde1f2bde44

commit r15-3928-gddc72ba6c6c2c84a1a95340840bd5fde1f2bde44
Author: Jakub Jelinek <ja...@redhat.com>
Date:   Fri Sep 27 16:06:29 2024 +0200

    diagnostic: Use vec instead of custom array reallocations for 
m_classification_history/m_push_list [PR116847]
    
    diagnostic.h already relies on vec.h, it uses auto_vec in one spot.
    
    The following patch converts m_classification_history and m_push_list
    hand-managed arrays to vec templates.
    The main advantage is exponential rather than linear reallocation,
    e.g. with current libstdc++ headers if one includes all the standard
    headers there could be ~ 300 reallocations of the m_classification_history
    array (sure, not all of them will result in actually copying the data, but
    still).
    In addition to that it fixes some formatting issues in the code.
    
    2024-09-26  Jakub Jelinek  <ja...@redhat.com>
    
            PR libstdc++/116847
            * diagnostic.h (diagnostic_option_classifier): Change type
            of m_classification_history from diagnostic_classification_change_t 
*
            to vec<diagnostic_classification_change_t>.  Change type of
            m_push_list from int * to vec<int>.  Remove 
m_n_classification_history
            and m_n_push members.
            * diagnostic.cc (diagnostic_option_classifier::init): Set 
m_push_list
            to vNULL rather than nullptr.  Don't initialize m_n_push.  
Initialize
            m_classification_history to vNULL.
            (diagnostic_option_classifier::fini): Call release () method on
            m_push_list instead of free on it.  Call release () on
            m_classification_history.  Don't clear m_n_push.
            (diagnostic_option_classifier::push): Adjust for m_push_list and
            m_classification_history being vectors rather than custom allocated
            arrays with counter.
            (diagnostic_option_classifier::pop): Likewise.
            (classify_diagnostic): Adjust for m_classification_history being
            vector rather than custom allocated array with counter.
            (update_effective_level_from_pragmas): Likewise.

Diff:
---
 gcc/diagnostic.cc | 68 +++++++++++++++++++++++--------------------------------
 gcc/diagnostic.h  |  8 ++-----
 2 files changed, 30 insertions(+), 46 deletions(-)

diff --git a/gcc/diagnostic.cc b/gcc/diagnostic.cc
index 152eb9d35a8e..ffe61f73d196 100644
--- a/gcc/diagnostic.cc
+++ b/gcc/diagnostic.cc
@@ -143,8 +143,8 @@ diagnostic_option_classifier::init (int n_opts)
   m_classify_diagnostic = XNEWVEC (diagnostic_t, n_opts);
   for (int i = 0; i < n_opts; i++)
     m_classify_diagnostic[i] = DK_UNSPECIFIED;
-  m_push_list = nullptr;
-  m_n_push = 0;
+  m_push_list = vNULL;
+  m_classification_history = vNULL;
 }
 
 void
@@ -152,8 +152,8 @@ diagnostic_option_classifier::fini ()
 {
   XDELETEVEC (m_classify_diagnostic);
   m_classify_diagnostic = nullptr;
-  free (m_push_list);
-  m_n_push = 0;
+  m_classification_history.release ();
+  m_push_list.release ();
 }
 
 /* Save all diagnostic classifications in a stack.  */
@@ -161,8 +161,7 @@ diagnostic_option_classifier::fini ()
 void
 diagnostic_option_classifier::push ()
 {
-  m_push_list = (int *) xrealloc (m_push_list, (m_n_push + 1) * sizeof (int));
-  m_push_list[m_n_push ++] = m_n_classification_history;
+  m_push_list.safe_push (m_classification_history.length ());
 }
 
 /* Restore the topmost classification set off the stack.  If the stack
@@ -173,19 +172,13 @@ diagnostic_option_classifier::pop (location_t where)
 {
   int jump_to;
 
-  if (m_n_push)
-    jump_to = m_push_list [-- m_n_push];
+  if (!m_push_list.is_empty ())
+    jump_to = m_push_list.pop ();
   else
     jump_to = 0;
 
-  const int i = m_n_classification_history;
-  m_classification_history =
-    (diagnostic_classification_change_t *) xrealloc (m_classification_history, 
(i + 1)
-                                                    * sizeof 
(diagnostic_classification_change_t));
-  m_classification_history[i].location = where;
-  m_classification_history[i].option = jump_to;
-  m_classification_history[i].kind = DK_POP;
-  m_n_classification_history ++;
+  diagnostic_classification_change_t v = { where, jump_to, DK_POP };
+  m_classification_history.safe_push (v);
 }
 
 /* Initialize the diagnostic message outputting machinery.  */
@@ -880,31 +873,27 @@ classify_diagnostic (const diagnostic_context *context,
      the pragmas were.  */
   if (where != UNKNOWN_LOCATION)
     {
-      int i;
+      unsigned i;
 
       /* Record the command-line status, so we can reset it back on DK_POP. */
       if (old_kind == DK_UNSPECIFIED)
        {
-         old_kind = !context->option_enabled_p (option_id)
-           ? DK_IGNORED : DK_ANY;
+         old_kind = (!context->option_enabled_p (option_id)
+                     ? DK_IGNORED : DK_ANY);
          m_classify_diagnostic[option_id.m_idx] = old_kind;
        }
 
-      for (i = m_n_classification_history - 1; i >= 0; i --)
-       if (m_classification_history[i].option == option_id.m_idx)
+      diagnostic_classification_change_t *p;
+      FOR_EACH_VEC_ELT_REVERSE (m_classification_history, i, p)
+       if (p->option == option_id.m_idx)
          {
-           old_kind = m_classification_history[i].kind;
+           old_kind = p->kind;
            break;
          }
 
-      i = m_n_classification_history;
-      m_classification_history =
-       (diagnostic_classification_change_t *) xrealloc 
(m_classification_history, (i + 1)
-                                                        * sizeof 
(diagnostic_classification_change_t));
-      m_classification_history[i].location = where;
-      m_classification_history[i].option = option_id.m_idx;
-      m_classification_history[i].kind = new_kind;
-      m_n_classification_history ++;
+      diagnostic_classification_change_t v
+       = { where, option_id.m_idx, new_kind };
+      m_classification_history.safe_push (v);
     }
   else
     m_classify_diagnostic[option_id.m_idx] = new_kind;
@@ -1033,7 +1022,7 @@ diagnostic_t
 diagnostic_option_classifier::
 update_effective_level_from_pragmas (diagnostic_info *diagnostic) const
 {
-  if (m_n_classification_history <= 0)
+  if (m_classification_history.is_empty ())
     return DK_UNSPECIFIED;
 
   /* Iterate over the locations, checking the diagnostic disposition
@@ -1043,27 +1032,26 @@ update_effective_level_from_pragmas (diagnostic_info 
*diagnostic) const
   for (location_t loc: diagnostic->m_iinfo.m_ilocs)
     {
       /* FIXME: Stupid search.  Optimize later. */
-      for (int i = m_n_classification_history - 1; i >= 0; i --)
+      unsigned int i;
+      diagnostic_classification_change_t *p;
+      FOR_EACH_VEC_ELT_REVERSE (m_classification_history, i, p)
        {
-         const diagnostic_classification_change_t &hist
-           = m_classification_history[i];
-
-         location_t pragloc = hist.location;
+         location_t pragloc = p->location;
          if (!linemap_location_before_p (line_table, pragloc, loc))
            continue;
 
-         if (hist.kind == (int) DK_POP)
+         if (p->kind == (int) DK_POP)
            {
              /* Move on to the next region.  */
-             i = hist.option;
+             i = p->option;
              continue;
            }
 
-         diagnostic_option_id option = hist.option;
+         diagnostic_option_id option = p->option;
          /* The option 0 is for all the diagnostics.  */
          if (option == 0 || option == diagnostic->option_id)
            {
-             diagnostic_t kind = hist.kind;
+             diagnostic_t kind = p->kind;
              if (kind != DK_UNSPECIFIED)
                diagnostic->kind = kind;
              return kind;
diff --git a/gcc/diagnostic.h b/gcc/diagnostic.h
index 8d20316ddc79..c3300fc96340 100644
--- a/gcc/diagnostic.h
+++ b/gcc/diagnostic.h
@@ -287,14 +287,10 @@ private:
      binary-wise or end-to-front, to find the most recent
      classification for a given diagnostic, given the location of the
      diagnostic.  */
-  diagnostic_classification_change_t *m_classification_history;
-
-  /* The size of the above array.  */
-  int m_n_classification_history;
+  vec<diagnostic_classification_change_t> m_classification_history;
 
   /* For pragma push/pop.  */
-  int *m_push_list;
-  int m_n_push;
+  vec<int> m_push_list;
 };
 
 /* A bundle of options relating to printing the user's source code

Reply via email to