1 /* Support for plotting bar charts in dumps.
2    Copyright (C) 2020 Free Software Foundation, Inc.
3    Contributed by David Malcolm <dmalcolm@redhat.com>.
4 
5 This file is part of GCC.
6 
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
11 
12 GCC is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 General Public License for more details.
16 
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3.  If not see
19 <http://www.gnu.org/licenses/>.  */
20 
21 #include "config.h"
22 #include "system.h"
23 #include "coretypes.h"
24 #include "pretty-print.h"
25 #include "analyzer/bar-chart.h"
26 
27 #if ENABLE_ANALYZER
28 
29 namespace ana {
30 
31 /* class bar_chart.  */
32 
33 /* Add an item, taking a copy of NAME.  */
34 
35 void
add_item(const char * name,value_t value)36 bar_chart::add_item (const char *name, value_t value)
37 {
38   m_items.safe_push (new item (name, value));
39 }
40 
41 /* Print the data to PP.  */
42 
43 void
print(pretty_printer * pp) const44 bar_chart::print (pretty_printer *pp) const
45 {
46   /* Get maximum printing widths and maximum value.  */
47   size_t max_width_name = 0;
48   size_t max_width_value = 0;
49   value_t max_value = 0;
50   unsigned i;
51   item *item;
52   char digit_buffer[128];
53   FOR_EACH_VEC_ELT (m_items, i, item)
54     {
55       max_width_name = MAX (max_width_name, item->m_strlen);
56       sprintf (digit_buffer, "%li", item->m_value);
57       max_width_value = MAX (max_width_value, strlen (digit_buffer));
58       max_value = MAX (max_value, item->m_value);
59     }
60 
61   /* Print items.  */
62   FOR_EACH_VEC_ELT (m_items, i, item)
63     {
64       /* Print left-aligned name, padding to max_width_name.  */
65       pp_string (pp, item->m_name);
66       print_padding (pp, max_width_name - item->m_strlen);
67 
68       pp_string (pp, ": ");
69 
70       /* Print right-aligned name, padding to max_width_value.  */
71       sprintf (digit_buffer, "%li", item->m_value);
72       const size_t value_width = strlen (digit_buffer);
73       print_padding (pp, max_width_value - value_width);
74       pp_string (pp, digit_buffer);
75 
76       pp_character (pp, '|');
77 
78       /* Print bar, scaled in proportion to max value.  */
79       const int max_width_bar
80 	= MIN (max_value, 76 - (max_width_name + max_width_value + 4));
81       const int bar_width
82 	= (max_value > 0 ? (max_width_bar * item->m_value) / max_value : 0);
83       for (int j = 0; j < bar_width; j++)
84 	pp_character (pp, '#');
85       print_padding (pp, max_width_bar - bar_width);
86       pp_character (pp, '|');
87       pp_newline (pp);
88     }
89 }
90 
91 /* Print COUNT spaces to PP.  */
92 
93 void
print_padding(pretty_printer * pp,size_t count)94 bar_chart::print_padding (pretty_printer *pp, size_t count)
95 {
96   for (size_t i = 0; i < count; i++)
97     pp_character (pp, ' ');
98 }
99 
100 } // namespace ana
101 
102 #endif /* #if ENABLE_ANALYZER */
103