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