[gcc/testsuite]
[official-gcc.git] / libstdc++-v3 / include / profile / impl / profiler_map_to_unordered_map.h
blob18051904172ec0b490b77f9c644cbe351c15ac1a
1 // -*- C++ -*-
2 //
3 // Copyright (C) 2009-2017 Free Software Foundation, Inc.
4 //
5 // This file is part of the GNU ISO C++ Library. This library is free
6 // software; you can redistribute it and/or modify it under the
7 // terms of the GNU General Public License as published by the
8 // Free Software Foundation; either version 3, or (at your option)
9 // any later version.
11 // This library is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 // GNU General Public License for more details.
16 // Under Section 7 of GPL version 3, you are granted additional
17 // permissions described in the GCC Runtime Library Exception, version
18 // 3.1, as published by the Free Software Foundation.
20 // You should have received a copy of the GNU General Public License along
21 // with this library; see the file COPYING3. If not see
22 // <http://www.gnu.org/licenses/>.
24 /** @file profile/impl/profiler_map_to_unordered_map.h
25 * @brief Diagnostics for map to unordered_map.
28 // Written by Silvius Rus.
30 #ifndef _GLIBCXX_PROFILE_PROFILER_MAP_TO_UNORDERED_MAP_H
31 #define _GLIBCXX_PROFILE_PROFILER_MAP_TO_UNORDERED_MAP_H 1
33 #include "profile/impl/profiler.h"
34 #include "profile/impl/profiler_node.h"
35 #include "profile/impl/profiler_trace.h"
37 namespace __gnu_profile
39 inline int
40 __log2(std::size_t __size)
42 for (int __bit_count = sizeof(std::size_t) - 1; __bit_count >= 0;
43 -- __bit_count)
44 if ((2 << __bit_count) & __size)
45 return __bit_count;
46 return 0;
49 inline float
50 __map_insert_cost(std::size_t __size)
51 { return (_GLIBCXX_PROFILE_DATA(__map_insert_cost_factor).__value
52 * static_cast<float>(__log2(__size))); }
54 inline float
55 __map_erase_cost(std::size_t __size)
56 { return (_GLIBCXX_PROFILE_DATA(__map_erase_cost_factor).__value
57 * static_cast<float>(__log2(__size))); }
59 inline float
60 __map_find_cost(std::size_t __size)
61 { return (_GLIBCXX_PROFILE_DATA(__map_find_cost_factor).__value
62 * static_cast<float>(__log2(__size))); }
64 /** @brief A map-to-unordered_map instrumentation line in the
65 object table. */
66 class __map2umap_info
67 : public __object_info_base
69 public:
70 __map2umap_info(__stack_t __stack)
71 : __object_info_base(__stack), _M_insert(0), _M_erase(0), _M_find(0),
72 _M_iterate(0), _M_umap_cost(0.0), _M_map_cost(0.0)
73 { }
75 void
76 __merge(const __map2umap_info& __o)
78 __object_info_base::__merge(__o);
79 _M_insert += __o._M_insert;
80 _M_erase += __o._M_erase;
81 _M_find += __o._M_find;
82 _M_iterate += __o._M_iterate;
83 _M_umap_cost += __o._M_umap_cost;
84 _M_map_cost += __o._M_map_cost;
87 void
88 __write(FILE* __f) const
90 std::fprintf(__f, "%Zu %Zu %Zu %Zu %.0f %.0f\n",
91 _M_insert, _M_erase, _M_find, _M_iterate, _M_map_cost,
92 _M_umap_cost);
95 float
96 __magnitude() const
97 { return _M_map_cost - _M_umap_cost; }
99 std::string
100 __advice() const
101 { return "prefer an unordered container"; }
103 void
104 __record_insert(std::size_t __size, std::size_t __count)
106 ++_M_insert;
107 if (__count)
109 _M_map_cost += __count * __map_insert_cost(__size);
110 _M_umap_cost
111 += (__count
112 * _GLIBCXX_PROFILE_DATA(__umap_insert_cost_factor).__value);
116 void
117 __record_erase(std::size_t __size, std::size_t __count)
119 ++_M_erase;
120 if (__count)
122 _M_map_cost += __count * __map_erase_cost(__size);
123 _M_umap_cost
124 += (__count
125 * _GLIBCXX_PROFILE_DATA(__umap_erase_cost_factor).__value);
129 void
130 __record_find(std::size_t __size)
132 ++_M_find;
133 _M_map_cost += __map_find_cost(__size);
134 _M_umap_cost += _GLIBCXX_PROFILE_DATA(__umap_find_cost_factor).__value;
137 void
138 __record_iterate(int __count)
139 { __gnu_cxx::__atomic_add(&_M_iterate, __count); }
141 void
142 __set_iterate_costs()
144 _M_umap_cost
145 += (_M_iterate
146 * _GLIBCXX_PROFILE_DATA(__umap_iterate_cost_factor).__value);
147 _M_map_cost
148 += (_M_iterate
149 * _GLIBCXX_PROFILE_DATA(__map_iterate_cost_factor).__value);
152 private:
153 std::size_t _M_insert;
154 std::size_t _M_erase;
155 std::size_t _M_find;
156 mutable _Atomic_word _M_iterate;
157 float _M_umap_cost;
158 float _M_map_cost;
162 /** @brief A map-to-unordered_map instrumentation line in the
163 stack table. */
164 class __map2umap_stack_info
165 : public __map2umap_info
167 public:
168 __map2umap_stack_info(const __map2umap_info& __o)
169 : __map2umap_info(__o) { }
172 /** @brief Map-to-unordered_map instrumentation producer. */
173 class __trace_map2umap
174 : public __trace_base<__map2umap_info, __map2umap_stack_info>
176 public:
177 __trace_map2umap()
178 : __trace_base<__map2umap_info, __map2umap_stack_info>()
179 { __id = "ordered-to-unordered"; }
181 // Call at destruction/clean to set container final size.
182 void
183 __destruct(__map2umap_info* __obj_info)
185 __obj_info->__set_iterate_costs();
186 __retire_object(__obj_info);
190 inline void
191 __trace_map_to_unordered_map_init()
192 { _GLIBCXX_PROFILE_DATA(_S_map2umap) = new __trace_map2umap(); }
194 inline void
195 __trace_map_to_unordered_map_free()
196 { delete _GLIBCXX_PROFILE_DATA(_S_map2umap); }
198 inline void
199 __trace_map_to_unordered_map_report(FILE* __f,
200 __warning_vector_t& __warnings)
201 { __trace_report(_GLIBCXX_PROFILE_DATA(_S_map2umap), __f, __warnings); }
203 inline __map2umap_info*
204 __trace_map_to_unordered_map_construct()
206 if (!__profcxx_init())
207 return 0;
209 if (!__reentrance_guard::__get_in())
210 return 0;
212 __reentrance_guard __get_out;
213 return _GLIBCXX_PROFILE_DATA(_S_map2umap)->__add_object(__get_stack());
216 inline void
217 __trace_map_to_unordered_map_insert(__map2umap_info* __info,
218 std::size_t __size, std::size_t __count)
220 if (!__info)
221 return;
223 __info->__record_insert(__size, __count);
226 inline void
227 __trace_map_to_unordered_map_erase(__map2umap_info* __info,
228 std::size_t __size, std::size_t __count)
230 if (!__info)
231 return;
233 __info->__record_erase(__size, __count);
236 inline void
237 __trace_map_to_unordered_map_find(__map2umap_info* __info,
238 std::size_t __size)
240 if (!__info)
241 return;
243 __info->__record_find(__size);
246 inline void
247 __trace_map_to_unordered_map_iterate(__map2umap_info* __info,
248 int)
250 if (!__info)
251 return;
253 // We only collect if an iteration took place no matter in what side.
254 __info->__record_iterate(1);
257 inline void
258 __trace_map_to_unordered_map_invalidate(__map2umap_info* __info)
260 if (!__info)
261 return;
263 __info->__set_invalid();
266 inline void
267 __trace_map_to_unordered_map_destruct(__map2umap_info* __info)
269 if (!__info)
270 return;
272 _GLIBCXX_PROFILE_DATA(_S_map2umap)->__destruct(__info);
274 } // namespace __gnu_profile
275 #endif /* _GLIBCXX_PROFILE_PROFILER_MAP_TO_UNORDERED_MAP_H */