2015-08-04 Thomas Preud'homme <thomas.preudhomme@arm.com>
[official-gcc.git] / gcc / vec.c
blob48b10c464855ae427d87529cf31ea8734ff8ac9a
1 /* Vector API for GNU compiler.
2 Copyright (C) 2004-2015 Free Software Foundation, Inc.
3 Contributed by Nathan Sidwell <nathan@codesourcery.com>
4 Re-implemented in C++ by Diego Novillo <dnovillo@google.com>
6 This file is part of GCC.
8 GCC is free software; you can redistribute it and/or modify it under
9 the terms of the GNU General Public License as published by the Free
10 Software Foundation; either version 3, or (at your option) any later
11 version.
13 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
14 WARRANTY; without even the implied warranty of MERCHANTABILITY or
15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
16 for more details.
18 You should have received a copy of the GNU General Public License
19 along with GCC; see the file COPYING3. If not see
20 <http://www.gnu.org/licenses/>. */
22 /* This file is compiled twice: once for the generator programs
23 once for the compiler. */
24 #ifdef GENERATOR_FILE
25 #include "bconfig.h"
26 #else
27 #include "config.h"
28 #endif
30 #include "system.h"
31 #include "coretypes.h"
32 #include "hash-table.h"
34 /* vNULL is an empty type with a template cast operation that returns
35 a zero-initialized vec<T, A, L> instance. Use this when you want
36 to assign nil values to new vec instances or pass a nil vector as
37 a function call argument.
39 We use this technique because vec<T, A, L> must be PODs (they are
40 stored in unions and passed in vararg functions), this means that
41 they cannot have ctors/dtors. */
42 vnull vNULL;
44 /* Vector memory usage. */
45 struct vec_usage: public mem_usage
47 /* Default constructor. */
48 vec_usage (): m_items (0), m_items_peak (0) {}
50 /* Constructor. */
51 vec_usage (size_t allocated, size_t times, size_t peak,
52 size_t items, size_t items_peak)
53 : mem_usage (allocated, times, peak),
54 m_items (items), m_items_peak (items_peak) {}
56 /* Comparison operator. */
57 inline bool
58 operator< (const vec_usage &second) const
60 return (m_allocated == second.m_allocated ?
61 (m_peak == second.m_peak ? m_times < second.m_times
62 : m_peak < second.m_peak) : m_allocated < second.m_allocated);
65 /* Sum the usage with SECOND usage. */
66 vec_usage
67 operator+ (const vec_usage &second)
69 return vec_usage (m_allocated + second.m_allocated,
70 m_times + second.m_times,
71 m_peak + second.m_peak,
72 m_items + second.m_items,
73 m_items_peak + second.m_items_peak);
76 /* Dump usage coupled to LOC location, where TOTAL is sum of all rows. */
77 inline void
78 dump (mem_location *loc, mem_usage &total) const
80 char s[4096];
81 sprintf (s, "%s:%i (%s)", loc->get_trimmed_filename (),
82 loc->m_line, loc->m_function);
84 s[48] = '\0';
86 fprintf (stderr, "%-48s %10li:%4.1f%%%10li%10li:%4.1f%%%11li%11li\n", s,
87 (long)m_allocated, m_allocated * 100.0 / total.m_allocated,
88 (long)m_peak, (long)m_times, m_times * 100.0 / total.m_times,
89 (long)m_items, (long)m_items_peak);
92 /* Dump footer. */
93 inline void
94 dump_footer ()
96 print_dash_line ();
97 fprintf (stderr, "%s%55li%25li%17li\n", "Total", (long)m_allocated,
98 (long)m_times, (long)m_items);
99 print_dash_line ();
102 /* Dump header with NAME. */
103 static inline void
104 dump_header (const char *name)
106 fprintf (stderr, "%-48s %11s%15s%10s%17s%11s\n", name, "Leak", "Peak",
107 "Times", "Leak items", "Peak items");
108 print_dash_line ();
111 /* Compare wrapper used by qsort method. */
112 static int
113 compare (const void *first, const void *second)
115 typedef std::pair<mem_location *, vec_usage *> mem_pair_t;
117 const mem_pair_t f = *(const mem_pair_t *)first;
118 const mem_pair_t s = *(const mem_pair_t *)second;
120 return (*f.second) < (*s.second);
123 /* Current number of items allocated. */
124 size_t m_items;
125 /* Peak value of number of allocated items. */
126 size_t m_items_peak;
129 /* Vector memory description. */
130 static mem_alloc_description <vec_usage> vec_mem_desc;
132 /* Account the overhead. */
134 void
135 vec_prefix::register_overhead (void *ptr, size_t size, size_t elements
136 MEM_STAT_DECL)
138 vec_mem_desc.register_descriptor (ptr, VEC_ORIGIN, false
139 FINAL_PASS_MEM_STAT);
140 vec_usage *usage = vec_mem_desc.register_instance_overhead (size, ptr);
141 usage->m_items += elements;
142 if (usage->m_items_peak < usage->m_items)
143 usage->m_items_peak = usage->m_items;
146 /* Notice that the memory allocated for the vector has been freed. */
148 void
149 vec_prefix::release_overhead (void *ptr, size_t size, bool in_dtor
150 MEM_STAT_DECL)
152 if (!vec_mem_desc.contains_descriptor_for_instance (ptr))
153 vec_mem_desc.register_descriptor (ptr, VEC_ORIGIN,
154 false FINAL_PASS_MEM_STAT);
155 vec_mem_desc.release_instance_overhead (ptr, size, in_dtor);
159 /* Calculate the number of slots to reserve a vector, making sure that
160 it is of at least DESIRED size by growing ALLOC exponentially. */
162 unsigned
163 vec_prefix::calculate_allocation_1 (unsigned alloc, unsigned desired)
165 /* We must have run out of room. */
166 gcc_assert (alloc < desired);
168 /* Exponential growth. */
169 if (!alloc)
170 alloc = 4;
171 else if (alloc < 16)
172 /* Double when small. */
173 alloc = alloc * 2;
174 else
175 /* Grow slower when large. */
176 alloc = (alloc * 3 / 2);
178 /* If this is still too small, set it to the right size. */
179 if (alloc < desired)
180 alloc = desired;
181 return alloc;
184 /* Dump per-site memory statistics. */
186 void
187 dump_vec_loc_statistics (void)
189 vec_mem_desc.dump (VEC_ORIGIN);