1 1.1 mrg /* Callgraph summary data structure. 2 1.8 mrg Copyright (C) 2014-2022 Free Software Foundation, Inc. 3 1.1 mrg Contributed by Martin Liska 4 1.1 mrg 5 1.1 mrg This file is part of GCC. 6 1.1 mrg 7 1.1 mrg GCC is free software; you can redistribute it and/or modify it under 8 1.1 mrg the terms of the GNU General Public License as published by the Free 9 1.1 mrg Software Foundation; either version 3, or (at your option) any later 10 1.1 mrg version. 11 1.1 mrg 12 1.1 mrg GCC is distributed in the hope that it will be useful, but WITHOUT ANY 13 1.1 mrg WARRANTY; without even the implied warranty of MERCHANTABILITY or 14 1.1 mrg FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 15 1.1 mrg for more details. 16 1.1 mrg 17 1.1 mrg You should have received a copy of the GNU General Public License 18 1.1 mrg along with GCC; see the file COPYING3. If not see 19 1.1 mrg <http://www.gnu.org/licenses/>. */ 20 1.1 mrg 21 1.1 mrg #ifndef GCC_SYMBOL_SUMMARY_H 22 1.1 mrg #define GCC_SYMBOL_SUMMARY_H 23 1.1 mrg 24 1.5 mrg /* Base class for function_summary and fast_function_summary classes. */ 25 1.1 mrg 26 1.1 mrg template <class T> 27 1.5 mrg class function_summary_base 28 1.1 mrg { 29 1.1 mrg public: 30 1.1 mrg /* Default construction takes SYMTAB as an argument. */ 31 1.8 mrg function_summary_base (symbol_table *symtab, 32 1.8 mrg cgraph_node_hook symtab_insertion, 33 1.8 mrg cgraph_node_hook symtab_removal, 34 1.8 mrg cgraph_2node_hook symtab_duplication 35 1.8 mrg CXX_MEM_STAT_INFO): 36 1.8 mrg m_symtab (symtab), m_symtab_insertion (symtab_insertion), 37 1.8 mrg m_symtab_removal (symtab_removal), 38 1.8 mrg m_symtab_duplication (symtab_duplication), 39 1.8 mrg m_symtab_insertion_hook (NULL), m_symtab_duplication_hook (NULL), 40 1.6 mrg m_allocator ("function summary" PASS_MEM_STAT) 41 1.8 mrg { 42 1.8 mrg enable_insertion_hook (); 43 1.8 mrg m_symtab_removal_hook 44 1.8 mrg = m_symtab->add_cgraph_removal_hook (m_symtab_removal, this); 45 1.8 mrg enable_duplication_hook (); 46 1.8 mrg } 47 1.1 mrg 48 1.1 mrg /* Basic implementation of insert operation. */ 49 1.8 mrg virtual void insert (cgraph_node *, T *) 50 1.8 mrg { 51 1.8 mrg /* In most cases, it makes no sense to create summaries without 52 1.8 mrg initializing them. */ 53 1.8 mrg gcc_unreachable (); 54 1.8 mrg } 55 1.1 mrg 56 1.1 mrg /* Basic implementation of removal operation. */ 57 1.1 mrg virtual void remove (cgraph_node *, T *) {} 58 1.1 mrg 59 1.1 mrg /* Basic implementation of duplication operation. */ 60 1.8 mrg virtual void duplicate (cgraph_node *, cgraph_node *, T *, T *) 61 1.8 mrg { 62 1.8 mrg /* It makes no sense to not copy anything during duplication. */ 63 1.8 mrg gcc_unreachable (); 64 1.8 mrg } 65 1.1 mrg 66 1.5 mrg /* Enable insertion hook invocation. */ 67 1.5 mrg void enable_insertion_hook () 68 1.5 mrg { 69 1.8 mrg if (m_symtab_insertion_hook == NULL) 70 1.8 mrg m_symtab_insertion_hook 71 1.8 mrg = m_symtab->add_cgraph_insertion_hook (m_symtab_insertion, this); 72 1.5 mrg } 73 1.5 mrg 74 1.5 mrg /* Enable insertion hook invocation. */ 75 1.5 mrg void disable_insertion_hook () 76 1.5 mrg { 77 1.8 mrg if (m_symtab_insertion_hook != NULL) 78 1.8 mrg { 79 1.8 mrg m_symtab->remove_cgraph_insertion_hook (m_symtab_insertion_hook); 80 1.8 mrg m_symtab_insertion_hook = NULL; 81 1.8 mrg } 82 1.8 mrg } 83 1.8 mrg 84 1.8 mrg /* Enable duplication hook invocation. */ 85 1.8 mrg void enable_duplication_hook () 86 1.8 mrg { 87 1.8 mrg if (m_symtab_duplication_hook == NULL) 88 1.8 mrg m_symtab_duplication_hook 89 1.8 mrg = m_symtab->add_cgraph_duplication_hook (m_symtab_duplication, this); 90 1.8 mrg } 91 1.8 mrg 92 1.8 mrg /* Enable duplication hook invocation. */ 93 1.8 mrg void disable_duplication_hook () 94 1.8 mrg { 95 1.8 mrg if (m_symtab_duplication_hook != NULL) 96 1.8 mrg { 97 1.8 mrg m_symtab->remove_cgraph_duplication_hook (m_symtab_duplication_hook); 98 1.8 mrg m_symtab_duplication_hook = NULL; 99 1.8 mrg } 100 1.5 mrg } 101 1.5 mrg 102 1.5 mrg protected: 103 1.1 mrg /* Allocates new data that are stored within map. */ 104 1.1 mrg T* allocate_new () 105 1.1 mrg { 106 1.3 mrg /* Call gcc_internal_because we do not want to call finalizer for 107 1.3 mrg a type T. We call dtor explicitly. */ 108 1.6 mrg return is_ggc () ? new (ggc_internal_alloc (sizeof (T))) T () 109 1.6 mrg : m_allocator.allocate () ; 110 1.1 mrg } 111 1.1 mrg 112 1.1 mrg /* Release an item that is stored within map. */ 113 1.1 mrg void release (T *item) 114 1.1 mrg { 115 1.5 mrg if (is_ggc ()) 116 1.6 mrg ggc_delete (item); 117 1.1 mrg else 118 1.6 mrg m_allocator.remove (item); 119 1.1 mrg } 120 1.1 mrg 121 1.5 mrg /* Unregister all call-graph hooks. */ 122 1.5 mrg void unregister_hooks (); 123 1.5 mrg 124 1.8 mrg /* Symbol table the summary is registered to. */ 125 1.8 mrg symbol_table *m_symtab; 126 1.8 mrg 127 1.8 mrg /* Insertion function defined by a summary. */ 128 1.8 mrg cgraph_node_hook m_symtab_insertion; 129 1.8 mrg /* Removal function defined by a summary. */ 130 1.8 mrg cgraph_node_hook m_symtab_removal; 131 1.8 mrg /* Duplication function defined by a summary. */ 132 1.8 mrg cgraph_2node_hook m_symtab_duplication; 133 1.8 mrg 134 1.5 mrg /* Internal summary insertion hook pointer. */ 135 1.5 mrg cgraph_node_hook_list *m_symtab_insertion_hook; 136 1.5 mrg /* Internal summary removal hook pointer. */ 137 1.5 mrg cgraph_node_hook_list *m_symtab_removal_hook; 138 1.5 mrg /* Internal summary duplication hook pointer. */ 139 1.5 mrg cgraph_2node_hook_list *m_symtab_duplication_hook; 140 1.5 mrg 141 1.5 mrg private: 142 1.5 mrg /* Return true when the summary uses GGC memory for allocation. */ 143 1.5 mrg virtual bool is_ggc () = 0; 144 1.6 mrg 145 1.6 mrg /* Object allocator for heap allocation. */ 146 1.6 mrg object_allocator<T> m_allocator; 147 1.5 mrg }; 148 1.5 mrg 149 1.5 mrg template <typename T> 150 1.5 mrg void 151 1.5 mrg function_summary_base<T>::unregister_hooks () 152 1.5 mrg { 153 1.8 mrg disable_insertion_hook (); 154 1.5 mrg m_symtab->remove_cgraph_removal_hook (m_symtab_removal_hook); 155 1.8 mrg disable_duplication_hook (); 156 1.5 mrg } 157 1.5 mrg 158 1.5 mrg /* We want to pass just pointer types as argument for function_summary 159 1.5 mrg template class. */ 160 1.5 mrg 161 1.5 mrg template <class T> 162 1.5 mrg class function_summary 163 1.5 mrg { 164 1.5 mrg private: 165 1.5 mrg function_summary(); 166 1.5 mrg }; 167 1.5 mrg 168 1.5 mrg /* Function summary is a helper class that is used to associate a data structure 169 1.5 mrg related to a callgraph node. Typical usage can be seen in IPA passes which 170 1.5 mrg create a temporary pass-related structures. The summary class registers 171 1.5 mrg hooks that are triggered when a new node is inserted, duplicated and deleted. 172 1.5 mrg A user of a summary class can ovewrite virtual methods than are triggered by 173 1.5 mrg the summary if such hook is triggered. Apart from a callgraph node, the user 174 1.5 mrg is given a data structure tied to the node. 175 1.5 mrg 176 1.5 mrg The function summary class can work both with a heap-allocated memory and 177 1.5 mrg a memory gained by garbage collected memory. */ 178 1.5 mrg 179 1.5 mrg template <class T> 180 1.5 mrg class GTY((user)) function_summary <T *>: public function_summary_base<T> 181 1.5 mrg { 182 1.5 mrg public: 183 1.5 mrg /* Default construction takes SYMTAB as an argument. */ 184 1.6 mrg function_summary (symbol_table *symtab, bool ggc = false CXX_MEM_STAT_INFO); 185 1.5 mrg 186 1.5 mrg /* Destructor. */ 187 1.6 mrg virtual ~function_summary (); 188 1.1 mrg 189 1.5 mrg /* Traverses all summarys with a function F called with 190 1.5 mrg ARG as argument. */ 191 1.5 mrg template<typename Arg, bool (*f)(const T &, Arg)> 192 1.5 mrg void traverse (Arg a) const 193 1.4 mrg { 194 1.7 mrg m_map.template traverse <f> (a); 195 1.4 mrg } 196 1.4 mrg 197 1.5 mrg /* Getter for summary callgraph node pointer. If a summary for a node 198 1.5 mrg does not exist it will be created. */ 199 1.5 mrg T* get_create (cgraph_node *node) 200 1.1 mrg { 201 1.5 mrg bool existed; 202 1.5 mrg T **v = &m_map.get_or_insert (node->get_uid (), &existed); 203 1.5 mrg if (!existed) 204 1.5 mrg *v = this->allocate_new (); 205 1.1 mrg 206 1.5 mrg return *v; 207 1.1 mrg } 208 1.1 mrg 209 1.5 mrg /* Getter for summary callgraph node pointer. */ 210 1.5 mrg T* get (cgraph_node *node) ATTRIBUTE_PURE 211 1.1 mrg { 212 1.5 mrg T **v = m_map.get (node->get_uid ()); 213 1.5 mrg return v == NULL ? NULL : *v; 214 1.1 mrg } 215 1.1 mrg 216 1.5 mrg /* Remove node from summary. */ 217 1.5 mrg using function_summary_base<T>::remove; 218 1.5 mrg void remove (cgraph_node *node) 219 1.1 mrg { 220 1.5 mrg int uid = node->get_uid (); 221 1.5 mrg T **v = m_map.get (uid); 222 1.1 mrg if (v) 223 1.1 mrg { 224 1.5 mrg m_map.remove (uid); 225 1.5 mrg this->release (*v); 226 1.1 mrg } 227 1.1 mrg } 228 1.1 mrg 229 1.5 mrg /* Return true if a summary for the given NODE already exists. */ 230 1.5 mrg bool exists (cgraph_node *node) 231 1.1 mrg { 232 1.5 mrg return m_map.get (node->get_uid ()) != NULL; 233 1.5 mrg } 234 1.5 mrg 235 1.5 mrg /* Symbol insertion hook that is registered to symbol table. */ 236 1.5 mrg static void symtab_insertion (cgraph_node *node, void *data); 237 1.1 mrg 238 1.5 mrg /* Symbol removal hook that is registered to symbol table. */ 239 1.5 mrg static void symtab_removal (cgraph_node *node, void *data); 240 1.1 mrg 241 1.5 mrg /* Symbol duplication hook that is registered to symbol table. */ 242 1.5 mrg static void symtab_duplication (cgraph_node *node, cgraph_node *node2, 243 1.5 mrg void *data); 244 1.1 mrg 245 1.1 mrg protected: 246 1.1 mrg /* Indication if we use ggc summary. */ 247 1.1 mrg bool m_ggc; 248 1.1 mrg 249 1.1 mrg private: 250 1.5 mrg /* Indication if we use ggc summary. */ 251 1.5 mrg virtual bool is_ggc () 252 1.1 mrg { 253 1.5 mrg return m_ggc; 254 1.5 mrg } 255 1.1 mrg 256 1.5 mrg typedef int_hash <int, 0, -1> map_hash; 257 1.1 mrg 258 1.1 mrg /* Main summary store, where summary ID is used as key. */ 259 1.3 mrg hash_map <map_hash, T *> m_map; 260 1.1 mrg 261 1.1 mrg template <typename U> friend void gt_ggc_mx (function_summary <U *> * const &); 262 1.1 mrg template <typename U> friend void gt_pch_nx (function_summary <U *> * const &); 263 1.1 mrg template <typename U> friend void gt_pch_nx (function_summary <U *> * const &, 264 1.1 mrg gt_pointer_operator, void *); 265 1.1 mrg }; 266 1.1 mrg 267 1.1 mrg template <typename T> 268 1.6 mrg function_summary<T *>::function_summary (symbol_table *symtab, bool ggc 269 1.6 mrg MEM_STAT_DECL): 270 1.8 mrg function_summary_base<T> (symtab, function_summary::symtab_insertion, 271 1.8 mrg function_summary::symtab_removal, 272 1.8 mrg function_summary::symtab_duplication 273 1.8 mrg PASS_MEM_STAT), 274 1.8 mrg m_ggc (ggc), m_map (13, ggc, true, GATHER_STATISTICS PASS_MEM_STAT) {} 275 1.5 mrg 276 1.5 mrg template <typename T> 277 1.6 mrg function_summary<T *>::~function_summary () 278 1.5 mrg { 279 1.5 mrg this->unregister_hooks (); 280 1.5 mrg 281 1.5 mrg /* Release all summaries. */ 282 1.5 mrg typedef typename hash_map <map_hash, T *>::iterator map_iterator; 283 1.5 mrg for (map_iterator it = m_map.begin (); it != m_map.end (); ++it) 284 1.5 mrg this->release ((*it).second); 285 1.5 mrg } 286 1.5 mrg 287 1.5 mrg template <typename T> 288 1.5 mrg void 289 1.5 mrg function_summary<T *>::symtab_insertion (cgraph_node *node, void *data) 290 1.5 mrg { 291 1.5 mrg gcc_checking_assert (node->get_uid ()); 292 1.5 mrg function_summary *summary = (function_summary <T *> *) (data); 293 1.8 mrg summary->insert (node, summary->get_create (node)); 294 1.5 mrg } 295 1.5 mrg 296 1.5 mrg template <typename T> 297 1.5 mrg void 298 1.5 mrg function_summary<T *>::symtab_removal (cgraph_node *node, void *data) 299 1.5 mrg { 300 1.5 mrg gcc_checking_assert (node->get_uid ()); 301 1.5 mrg function_summary *summary = (function_summary <T *> *) (data); 302 1.5 mrg summary->remove (node); 303 1.5 mrg } 304 1.5 mrg 305 1.5 mrg template <typename T> 306 1.5 mrg void 307 1.5 mrg function_summary<T *>::symtab_duplication (cgraph_node *node, 308 1.5 mrg cgraph_node *node2, void *data) 309 1.5 mrg { 310 1.5 mrg function_summary *summary = (function_summary <T *> *) (data); 311 1.5 mrg T *v = summary->get (node); 312 1.5 mrg 313 1.5 mrg if (v) 314 1.5 mrg summary->duplicate (node, node2, v, summary->get_create (node2)); 315 1.5 mrg } 316 1.5 mrg 317 1.5 mrg template <typename T> 318 1.1 mrg void 319 1.1 mrg gt_ggc_mx(function_summary<T *>* const &summary) 320 1.1 mrg { 321 1.1 mrg gcc_checking_assert (summary->m_ggc); 322 1.1 mrg gt_ggc_mx (&summary->m_map); 323 1.1 mrg } 324 1.1 mrg 325 1.1 mrg template <typename T> 326 1.1 mrg void 327 1.6 mrg gt_pch_nx (function_summary<T *> *const &) 328 1.1 mrg { 329 1.6 mrg gcc_unreachable (); 330 1.1 mrg } 331 1.1 mrg 332 1.1 mrg template <typename T> 333 1.1 mrg void 334 1.6 mrg gt_pch_nx (function_summary<T *> *const &, gt_pointer_operator, void *) 335 1.1 mrg { 336 1.6 mrg gcc_unreachable (); 337 1.1 mrg } 338 1.1 mrg 339 1.5 mrg /* Help template from std c++11. */ 340 1.5 mrg 341 1.5 mrg template<typename T, typename U> 342 1.5 mrg struct is_same 343 1.5 mrg { 344 1.5 mrg static const bool value = false; 345 1.5 mrg }; 346 1.5 mrg 347 1.5 mrg template<typename T> 348 1.5 mrg struct is_same<T,T> //specialization 349 1.5 mrg { 350 1.5 mrg static const bool value = true; 351 1.5 mrg }; 352 1.5 mrg 353 1.5 mrg /* We want to pass just pointer types as argument for fast_function_summary 354 1.5 mrg template class. */ 355 1.4 mrg 356 1.5 mrg template <class T, class V> 357 1.5 mrg class fast_function_summary 358 1.4 mrg { 359 1.4 mrg private: 360 1.5 mrg fast_function_summary (); 361 1.4 mrg }; 362 1.4 mrg 363 1.5 mrg /* Function vector summary is a fast implementation of function_summary that 364 1.5 mrg utilizes vector as primary storage of summaries. */ 365 1.4 mrg 366 1.5 mrg template <class T, class V> 367 1.5 mrg class GTY((user)) fast_function_summary <T *, V> 368 1.5 mrg : public function_summary_base<T> 369 1.4 mrg { 370 1.4 mrg public: 371 1.4 mrg /* Default construction takes SYMTAB as an argument. */ 372 1.6 mrg fast_function_summary (symbol_table *symtab CXX_MEM_STAT_INFO); 373 1.5 mrg 374 1.5 mrg /* Destructor. */ 375 1.6 mrg virtual ~fast_function_summary (); 376 1.5 mrg 377 1.5 mrg /* Traverses all summarys with a function F called with 378 1.5 mrg ARG as argument. */ 379 1.5 mrg template<typename Arg, bool (*f)(const T &, Arg)> 380 1.5 mrg void traverse (Arg a) const 381 1.4 mrg { 382 1.5 mrg for (unsigned i = 0; i < m_vector->length (); i++) 383 1.5 mrg if ((*m_vector[i]) != NULL) 384 1.6 mrg f ((*m_vector)[i], a); 385 1.4 mrg } 386 1.4 mrg 387 1.5 mrg /* Getter for summary callgraph node pointer. If a summary for a node 388 1.5 mrg does not exist it will be created. */ 389 1.5 mrg T* get_create (cgraph_node *node) 390 1.4 mrg { 391 1.5 mrg int id = node->get_summary_id (); 392 1.5 mrg if (id == -1) 393 1.5 mrg id = this->m_symtab->assign_summary_id (node); 394 1.5 mrg 395 1.5 mrg if ((unsigned int)id >= m_vector->length ()) 396 1.8 mrg vec_safe_grow_cleared (m_vector, 397 1.8 mrg this->m_symtab->cgraph_max_summary_id); 398 1.5 mrg 399 1.5 mrg if ((*m_vector)[id] == NULL) 400 1.5 mrg (*m_vector)[id] = this->allocate_new (); 401 1.4 mrg 402 1.5 mrg return (*m_vector)[id]; 403 1.5 mrg } 404 1.4 mrg 405 1.5 mrg /* Getter for summary callgraph node pointer. */ 406 1.5 mrg T* get (cgraph_node *node) ATTRIBUTE_PURE 407 1.5 mrg { 408 1.5 mrg return exists (node) ? (*m_vector)[node->get_summary_id ()] : NULL; 409 1.5 mrg } 410 1.4 mrg 411 1.5 mrg using function_summary_base<T>::remove; 412 1.5 mrg void remove (cgraph_node *node) 413 1.5 mrg { 414 1.5 mrg if (exists (node)) 415 1.5 mrg { 416 1.5 mrg int id = node->get_summary_id (); 417 1.5 mrg this->release ((*m_vector)[id]); 418 1.5 mrg (*m_vector)[id] = NULL; 419 1.5 mrg } 420 1.4 mrg } 421 1.4 mrg 422 1.5 mrg /* Return true if a summary for the given NODE already exists. */ 423 1.5 mrg bool exists (cgraph_node *node) 424 1.4 mrg { 425 1.5 mrg int id = node->get_summary_id (); 426 1.5 mrg return (id != -1 427 1.5 mrg && (unsigned int)id < m_vector->length () 428 1.5 mrg && (*m_vector)[id] != NULL); 429 1.4 mrg } 430 1.4 mrg 431 1.5 mrg /* Symbol insertion hook that is registered to symbol table. */ 432 1.5 mrg static void symtab_insertion (cgraph_node *node, void *data); 433 1.5 mrg 434 1.5 mrg /* Symbol removal hook that is registered to symbol table. */ 435 1.5 mrg static void symtab_removal (cgraph_node *node, void *data); 436 1.5 mrg 437 1.5 mrg /* Symbol duplication hook that is registered to symbol table. */ 438 1.5 mrg static void symtab_duplication (cgraph_node *node, cgraph_node *node2, 439 1.5 mrg void *data); 440 1.5 mrg 441 1.5 mrg private: 442 1.5 mrg virtual bool is_ggc (); 443 1.5 mrg 444 1.5 mrg /* Summary is stored in the vector. */ 445 1.5 mrg vec <T *, V> *m_vector; 446 1.5 mrg 447 1.5 mrg template <typename U> friend void gt_ggc_mx (fast_function_summary <U *, va_gc> * const &); 448 1.5 mrg template <typename U> friend void gt_pch_nx (fast_function_summary <U *, va_gc> * const &); 449 1.5 mrg template <typename U> friend void gt_pch_nx (fast_function_summary <U *, va_gc> * const &, 450 1.5 mrg gt_pointer_operator, void *); 451 1.5 mrg }; 452 1.5 mrg 453 1.5 mrg template <typename T, typename V> 454 1.8 mrg fast_function_summary<T *, V>::fast_function_summary (symbol_table *symtab 455 1.8 mrg MEM_STAT_DECL): 456 1.8 mrg function_summary_base<T> (symtab, 457 1.8 mrg fast_function_summary::symtab_insertion, 458 1.8 mrg fast_function_summary::symtab_removal, 459 1.8 mrg fast_function_summary::symtab_duplication 460 1.8 mrg PASS_MEM_STAT), m_vector (NULL) 461 1.5 mrg { 462 1.6 mrg vec_alloc (m_vector, 13 PASS_MEM_STAT); 463 1.5 mrg } 464 1.5 mrg 465 1.5 mrg template <typename T, typename V> 466 1.6 mrg fast_function_summary<T *, V>::~fast_function_summary () 467 1.5 mrg { 468 1.5 mrg this->unregister_hooks (); 469 1.5 mrg 470 1.5 mrg /* Release all summaries. */ 471 1.5 mrg for (unsigned i = 0; i < m_vector->length (); i++) 472 1.5 mrg if ((*m_vector)[i] != NULL) 473 1.5 mrg this->release ((*m_vector)[i]); 474 1.5 mrg vec_free (m_vector); 475 1.5 mrg } 476 1.5 mrg 477 1.5 mrg template <typename T, typename V> 478 1.5 mrg void 479 1.5 mrg fast_function_summary<T *, V>::symtab_insertion (cgraph_node *node, void *data) 480 1.5 mrg { 481 1.5 mrg gcc_checking_assert (node->get_uid ()); 482 1.5 mrg fast_function_summary *summary = (fast_function_summary <T *, V> *) (data); 483 1.8 mrg summary->insert (node, summary->get_create (node)); 484 1.5 mrg } 485 1.5 mrg 486 1.5 mrg template <typename T, typename V> 487 1.5 mrg void 488 1.5 mrg fast_function_summary<T *, V>::symtab_removal (cgraph_node *node, void *data) 489 1.5 mrg { 490 1.5 mrg gcc_checking_assert (node->get_uid ()); 491 1.5 mrg fast_function_summary *summary = (fast_function_summary <T *, V> *) (data); 492 1.5 mrg 493 1.5 mrg if (summary->exists (node)) 494 1.5 mrg summary->remove (node); 495 1.5 mrg } 496 1.5 mrg 497 1.5 mrg template <typename T, typename V> 498 1.5 mrg void 499 1.5 mrg fast_function_summary<T *, V>::symtab_duplication (cgraph_node *node, 500 1.5 mrg cgraph_node *node2, 501 1.5 mrg void *data) 502 1.5 mrg { 503 1.5 mrg fast_function_summary *summary = (fast_function_summary <T *, V> *) (data); 504 1.5 mrg T *v = summary->get (node); 505 1.5 mrg 506 1.5 mrg if (v) 507 1.5 mrg { 508 1.5 mrg T *duplicate = summary->get_create (node2); 509 1.5 mrg summary->duplicate (node, node2, v, duplicate); 510 1.5 mrg } 511 1.5 mrg } 512 1.5 mrg 513 1.5 mrg template <typename T, typename V> 514 1.5 mrg inline bool 515 1.5 mrg fast_function_summary<T *, V>::is_ggc () 516 1.5 mrg { 517 1.5 mrg return is_same<V, va_gc>::value; 518 1.5 mrg } 519 1.5 mrg 520 1.5 mrg template <typename T> 521 1.5 mrg void 522 1.5 mrg gt_ggc_mx (fast_function_summary<T *, va_heap>* const &) 523 1.5 mrg { 524 1.5 mrg } 525 1.5 mrg 526 1.5 mrg template <typename T> 527 1.5 mrg void 528 1.5 mrg gt_pch_nx (fast_function_summary<T *, va_heap>* const &) 529 1.5 mrg { 530 1.5 mrg } 531 1.5 mrg 532 1.5 mrg template <typename T> 533 1.5 mrg void 534 1.5 mrg gt_pch_nx (fast_function_summary<T *, va_heap>* const&, gt_pointer_operator, 535 1.5 mrg void *) 536 1.5 mrg { 537 1.5 mrg } 538 1.5 mrg 539 1.5 mrg template <typename T> 540 1.5 mrg void 541 1.5 mrg gt_ggc_mx (fast_function_summary<T *, va_gc>* const &summary) 542 1.5 mrg { 543 1.5 mrg ggc_test_and_set_mark (summary->m_vector); 544 1.5 mrg gt_ggc_mx (summary->m_vector); 545 1.5 mrg } 546 1.5 mrg 547 1.5 mrg template <typename T> 548 1.5 mrg void 549 1.6 mrg gt_pch_nx (fast_function_summary<T *, va_gc> *const &) 550 1.5 mrg { 551 1.6 mrg gcc_unreachable (); 552 1.5 mrg } 553 1.5 mrg 554 1.5 mrg template <typename T> 555 1.5 mrg void 556 1.6 mrg gt_pch_nx (fast_function_summary<T *, va_gc> *const &, gt_pointer_operator, 557 1.6 mrg void *) 558 1.5 mrg { 559 1.6 mrg gcc_unreachable (); 560 1.5 mrg } 561 1.5 mrg 562 1.5 mrg /* Base class for call_summary and fast_call_summary classes. */ 563 1.5 mrg 564 1.5 mrg template <class T> 565 1.5 mrg class call_summary_base 566 1.5 mrg { 567 1.5 mrg public: 568 1.5 mrg /* Default construction takes SYMTAB as an argument. */ 569 1.8 mrg call_summary_base (symbol_table *symtab, cgraph_edge_hook symtab_removal, 570 1.8 mrg cgraph_2edge_hook symtab_duplication CXX_MEM_STAT_INFO): 571 1.8 mrg m_symtab (symtab), m_symtab_removal (symtab_removal), 572 1.8 mrg m_symtab_duplication (symtab_duplication), m_symtab_duplication_hook (NULL), 573 1.6 mrg m_initialize_when_cloning (false), 574 1.6 mrg m_allocator ("call summary" PASS_MEM_STAT) 575 1.8 mrg { 576 1.8 mrg m_symtab_removal_hook 577 1.8 mrg = m_symtab->add_edge_removal_hook (m_symtab_removal, this); 578 1.8 mrg enable_duplication_hook (); 579 1.8 mrg } 580 1.5 mrg 581 1.4 mrg /* Basic implementation of removal operation. */ 582 1.4 mrg virtual void remove (cgraph_edge *, T *) {} 583 1.4 mrg 584 1.4 mrg /* Basic implementation of duplication operation. */ 585 1.8 mrg virtual void duplicate (cgraph_edge *, cgraph_edge *, T *, T *) 586 1.8 mrg { 587 1.8 mrg gcc_unreachable (); 588 1.8 mrg } 589 1.8 mrg 590 1.8 mrg /* Enable duplication hook invocation. */ 591 1.8 mrg void enable_duplication_hook () 592 1.8 mrg { 593 1.8 mrg if (m_symtab_duplication_hook == NULL) 594 1.8 mrg m_symtab_duplication_hook 595 1.8 mrg = m_symtab->add_edge_duplication_hook (m_symtab_duplication, 596 1.8 mrg this); 597 1.8 mrg } 598 1.8 mrg 599 1.8 mrg /* Enable duplication hook invocation. */ 600 1.8 mrg void disable_duplication_hook () 601 1.8 mrg { 602 1.8 mrg if (m_symtab_duplication_hook != NULL) 603 1.8 mrg { 604 1.8 mrg m_symtab->remove_edge_duplication_hook (m_symtab_duplication_hook); 605 1.8 mrg m_symtab_duplication_hook = NULL; 606 1.8 mrg } 607 1.8 mrg } 608 1.4 mrg 609 1.5 mrg protected: 610 1.4 mrg /* Allocates new data that are stored within map. */ 611 1.4 mrg T* allocate_new () 612 1.4 mrg { 613 1.4 mrg /* Call gcc_internal_because we do not want to call finalizer for 614 1.4 mrg a type T. We call dtor explicitly. */ 615 1.6 mrg return is_ggc () ? new (ggc_internal_alloc (sizeof (T))) T () 616 1.6 mrg : m_allocator.allocate (); 617 1.4 mrg } 618 1.4 mrg 619 1.4 mrg /* Release an item that is stored within map. */ 620 1.4 mrg void release (T *item) 621 1.4 mrg { 622 1.5 mrg if (is_ggc ()) 623 1.6 mrg ggc_delete (item); 624 1.4 mrg else 625 1.6 mrg m_allocator.remove (item); 626 1.4 mrg } 627 1.4 mrg 628 1.5 mrg /* Unregister all call-graph hooks. */ 629 1.5 mrg void unregister_hooks (); 630 1.5 mrg 631 1.5 mrg /* Symbol table the summary is registered to. */ 632 1.5 mrg symbol_table *m_symtab; 633 1.5 mrg 634 1.8 mrg /* Removal function defined by a summary. */ 635 1.8 mrg cgraph_edge_hook m_symtab_removal; 636 1.8 mrg /* Duplication function defined by a summary. */ 637 1.8 mrg cgraph_2edge_hook m_symtab_duplication; 638 1.8 mrg 639 1.5 mrg /* Internal summary removal hook pointer. */ 640 1.5 mrg cgraph_edge_hook_list *m_symtab_removal_hook; 641 1.5 mrg /* Internal summary duplication hook pointer. */ 642 1.5 mrg cgraph_2edge_hook_list *m_symtab_duplication_hook; 643 1.5 mrg /* Initialize summary for an edge that is cloned. */ 644 1.5 mrg bool m_initialize_when_cloning; 645 1.5 mrg 646 1.5 mrg private: 647 1.5 mrg /* Return true when the summary uses GGC memory for allocation. */ 648 1.5 mrg virtual bool is_ggc () = 0; 649 1.6 mrg 650 1.6 mrg /* Object allocator for heap allocation. */ 651 1.6 mrg object_allocator<T> m_allocator; 652 1.5 mrg }; 653 1.5 mrg 654 1.5 mrg template <typename T> 655 1.5 mrg void 656 1.5 mrg call_summary_base<T>::unregister_hooks () 657 1.5 mrg { 658 1.5 mrg m_symtab->remove_edge_removal_hook (m_symtab_removal_hook); 659 1.8 mrg disable_duplication_hook (); 660 1.5 mrg } 661 1.5 mrg 662 1.5 mrg /* An impossible class templated by non-pointers so, which makes sure that only 663 1.5 mrg summaries gathering pointers can be created. */ 664 1.5 mrg 665 1.5 mrg template <class T> 666 1.5 mrg class call_summary 667 1.5 mrg { 668 1.5 mrg private: 669 1.5 mrg call_summary (); 670 1.5 mrg }; 671 1.5 mrg 672 1.5 mrg /* Class to store auxiliary information about call graph edges. */ 673 1.5 mrg 674 1.5 mrg template <class T> 675 1.5 mrg class GTY((user)) call_summary <T *>: public call_summary_base<T> 676 1.5 mrg { 677 1.5 mrg public: 678 1.5 mrg /* Default construction takes SYMTAB as an argument. */ 679 1.6 mrg call_summary (symbol_table *symtab, bool ggc = false 680 1.6 mrg CXX_MEM_STAT_INFO) 681 1.8 mrg : call_summary_base<T> (symtab, call_summary::symtab_removal, 682 1.8 mrg call_summary::symtab_duplication PASS_MEM_STAT), 683 1.8 mrg m_ggc (ggc), m_map (13, ggc, true, GATHER_STATISTICS PASS_MEM_STAT) {} 684 1.4 mrg 685 1.5 mrg /* Destructor. */ 686 1.6 mrg virtual ~call_summary (); 687 1.5 mrg 688 1.5 mrg /* Traverses all summarys with an edge E called with 689 1.5 mrg ARG as argument. */ 690 1.5 mrg template<typename Arg, bool (*f)(const T &, Arg)> 691 1.5 mrg void traverse (Arg a) const 692 1.4 mrg { 693 1.7 mrg m_map.template traverse <f> (a); 694 1.4 mrg } 695 1.4 mrg 696 1.5 mrg /* Getter for summary callgraph edge pointer. 697 1.5 mrg If a summary for an edge does not exist, it will be created. */ 698 1.5 mrg T* get_create (cgraph_edge *edge) 699 1.4 mrg { 700 1.5 mrg bool existed; 701 1.5 mrg T **v = &m_map.get_or_insert (edge->get_uid (), &existed); 702 1.5 mrg if (!existed) 703 1.5 mrg *v = this->allocate_new (); 704 1.5 mrg 705 1.5 mrg return *v; 706 1.5 mrg } 707 1.4 mrg 708 1.5 mrg /* Getter for summary callgraph edge pointer. */ 709 1.5 mrg T* get (cgraph_edge *edge) ATTRIBUTE_PURE 710 1.5 mrg { 711 1.5 mrg T **v = m_map.get (edge->get_uid ()); 712 1.5 mrg return v == NULL ? NULL : *v; 713 1.5 mrg } 714 1.4 mrg 715 1.5 mrg /* Remove edge from summary. */ 716 1.5 mrg using call_summary_base<T>::remove; 717 1.5 mrg void remove (cgraph_edge *edge) 718 1.5 mrg { 719 1.5 mrg int uid = edge->get_uid (); 720 1.5 mrg T **v = m_map.get (uid); 721 1.4 mrg if (v) 722 1.4 mrg { 723 1.5 mrg m_map.remove (uid); 724 1.5 mrg this->release (*v); 725 1.4 mrg } 726 1.4 mrg } 727 1.4 mrg 728 1.5 mrg /* Return true if a summary for the given EDGE already exists. */ 729 1.5 mrg bool exists (cgraph_edge *edge) 730 1.5 mrg { 731 1.5 mrg return m_map.get (edge->get_uid ()) != NULL; 732 1.5 mrg } 733 1.5 mrg 734 1.5 mrg /* Symbol removal hook that is registered to symbol table. */ 735 1.5 mrg static void symtab_removal (cgraph_edge *edge, void *data); 736 1.5 mrg 737 1.4 mrg /* Symbol duplication hook that is registered to symbol table. */ 738 1.4 mrg static void symtab_duplication (cgraph_edge *edge1, cgraph_edge *edge2, 739 1.5 mrg void *data); 740 1.4 mrg 741 1.4 mrg protected: 742 1.4 mrg /* Indication if we use ggc summary. */ 743 1.4 mrg bool m_ggc; 744 1.4 mrg 745 1.4 mrg private: 746 1.5 mrg /* Indication if we use ggc summary. */ 747 1.5 mrg virtual bool is_ggc () 748 1.4 mrg { 749 1.5 mrg return m_ggc; 750 1.4 mrg } 751 1.4 mrg 752 1.5 mrg typedef int_hash <int, 0, -1> map_hash; 753 1.4 mrg 754 1.4 mrg /* Main summary store, where summary ID is used as key. */ 755 1.4 mrg hash_map <map_hash, T *> m_map; 756 1.4 mrg 757 1.4 mrg template <typename U> friend void gt_ggc_mx (call_summary <U *> * const &); 758 1.4 mrg template <typename U> friend void gt_pch_nx (call_summary <U *> * const &); 759 1.4 mrg template <typename U> friend void gt_pch_nx (call_summary <U *> * const &, 760 1.4 mrg gt_pointer_operator, void *); 761 1.4 mrg }; 762 1.4 mrg 763 1.4 mrg template <typename T> 764 1.6 mrg call_summary<T *>::~call_summary () 765 1.5 mrg { 766 1.5 mrg this->unregister_hooks (); 767 1.5 mrg 768 1.5 mrg /* Release all summaries. */ 769 1.5 mrg typedef typename hash_map <map_hash, T *>::iterator map_iterator; 770 1.5 mrg for (map_iterator it = m_map.begin (); it != m_map.end (); ++it) 771 1.5 mrg this->release ((*it).second); 772 1.5 mrg } 773 1.5 mrg 774 1.5 mrg template <typename T> 775 1.5 mrg void 776 1.5 mrg call_summary<T *>::symtab_removal (cgraph_edge *edge, void *data) 777 1.5 mrg { 778 1.5 mrg call_summary *summary = (call_summary <T *> *) (data); 779 1.5 mrg summary->remove (edge); 780 1.5 mrg } 781 1.5 mrg 782 1.5 mrg template <typename T> 783 1.5 mrg void 784 1.5 mrg call_summary<T *>::symtab_duplication (cgraph_edge *edge1, 785 1.5 mrg cgraph_edge *edge2, void *data) 786 1.5 mrg { 787 1.5 mrg call_summary *summary = (call_summary <T *> *) (data); 788 1.5 mrg T *edge1_summary = NULL; 789 1.5 mrg 790 1.5 mrg if (summary->m_initialize_when_cloning) 791 1.5 mrg edge1_summary = summary->get_create (edge1); 792 1.5 mrg else 793 1.5 mrg edge1_summary = summary->get (edge1); 794 1.5 mrg 795 1.5 mrg if (edge1_summary) 796 1.5 mrg summary->duplicate (edge1, edge2, edge1_summary, 797 1.5 mrg summary->get_create (edge2)); 798 1.5 mrg } 799 1.5 mrg 800 1.5 mrg template <typename T> 801 1.5 mrg void 802 1.4 mrg gt_ggc_mx(call_summary<T *>* const &summary) 803 1.4 mrg { 804 1.4 mrg gcc_checking_assert (summary->m_ggc); 805 1.4 mrg gt_ggc_mx (&summary->m_map); 806 1.4 mrg } 807 1.4 mrg 808 1.4 mrg template <typename T> 809 1.4 mrg void 810 1.6 mrg gt_pch_nx (call_summary<T *> *const &) 811 1.4 mrg { 812 1.6 mrg gcc_unreachable (); 813 1.4 mrg } 814 1.4 mrg 815 1.4 mrg template <typename T> 816 1.4 mrg void 817 1.6 mrg gt_pch_nx (call_summary<T *> *const &, gt_pointer_operator, void *) 818 1.4 mrg { 819 1.6 mrg gcc_unreachable (); 820 1.4 mrg } 821 1.4 mrg 822 1.5 mrg /* We want to pass just pointer types as argument for fast_call_summary 823 1.5 mrg template class. */ 824 1.5 mrg 825 1.5 mrg template <class T, class V> 826 1.5 mrg class fast_call_summary 827 1.5 mrg { 828 1.5 mrg private: 829 1.5 mrg fast_call_summary (); 830 1.5 mrg }; 831 1.5 mrg 832 1.5 mrg /* Call vector summary is a fast implementation of call_summary that 833 1.5 mrg utilizes vector as primary storage of summaries. */ 834 1.5 mrg 835 1.5 mrg template <class T, class V> 836 1.5 mrg class GTY((user)) fast_call_summary <T *, V>: public call_summary_base<T> 837 1.5 mrg { 838 1.5 mrg public: 839 1.5 mrg /* Default construction takes SYMTAB as an argument. */ 840 1.6 mrg fast_call_summary (symbol_table *symtab CXX_MEM_STAT_INFO) 841 1.8 mrg : call_summary_base<T> (symtab, fast_call_summary::symtab_removal, 842 1.8 mrg fast_call_summary::symtab_duplication PASS_MEM_STAT), 843 1.8 mrg m_vector (NULL) 844 1.5 mrg { 845 1.6 mrg vec_alloc (m_vector, 13 PASS_MEM_STAT); 846 1.5 mrg } 847 1.5 mrg 848 1.5 mrg /* Destructor. */ 849 1.6 mrg virtual ~fast_call_summary (); 850 1.5 mrg 851 1.5 mrg /* Traverses all summarys with an edge F called with 852 1.5 mrg ARG as argument. */ 853 1.5 mrg template<typename Arg, bool (*f)(const T &, Arg)> 854 1.5 mrg void traverse (Arg a) const 855 1.5 mrg { 856 1.5 mrg for (unsigned i = 0; i < m_vector->length (); i++) 857 1.5 mrg if ((*m_vector[i]) != NULL) 858 1.6 mrg f ((*m_vector)[i], a); 859 1.5 mrg } 860 1.5 mrg 861 1.5 mrg /* Getter for summary callgraph edge pointer. 862 1.5 mrg If a summary for an edge does not exist, it will be created. */ 863 1.5 mrg T* get_create (cgraph_edge *edge) 864 1.5 mrg { 865 1.5 mrg int id = edge->get_summary_id (); 866 1.5 mrg if (id == -1) 867 1.5 mrg id = this->m_symtab->assign_summary_id (edge); 868 1.5 mrg 869 1.5 mrg if ((unsigned)id >= m_vector->length ()) 870 1.8 mrg vec_safe_grow_cleared (m_vector, this->m_symtab->edges_max_summary_id); 871 1.5 mrg 872 1.5 mrg if ((*m_vector)[id] == NULL) 873 1.5 mrg (*m_vector)[id] = this->allocate_new (); 874 1.5 mrg 875 1.5 mrg return (*m_vector)[id]; 876 1.5 mrg } 877 1.5 mrg 878 1.5 mrg /* Getter for summary callgraph edge pointer. */ 879 1.5 mrg T* get (cgraph_edge *edge) ATTRIBUTE_PURE 880 1.5 mrg { 881 1.5 mrg return exists (edge) ? (*m_vector)[edge->get_summary_id ()] : NULL; 882 1.5 mrg } 883 1.5 mrg 884 1.5 mrg /* Remove edge from summary. */ 885 1.5 mrg using call_summary_base<T>::remove; 886 1.5 mrg void remove (cgraph_edge *edge) 887 1.5 mrg { 888 1.5 mrg if (exists (edge)) 889 1.5 mrg { 890 1.5 mrg int id = edge->get_summary_id (); 891 1.5 mrg this->release ((*m_vector)[id]); 892 1.5 mrg (*m_vector)[id] = NULL; 893 1.5 mrg } 894 1.5 mrg } 895 1.5 mrg 896 1.5 mrg /* Return true if a summary for the given EDGE already exists. */ 897 1.5 mrg bool exists (cgraph_edge *edge) 898 1.5 mrg { 899 1.5 mrg int id = edge->get_summary_id (); 900 1.5 mrg return (id != -1 901 1.5 mrg && (unsigned)id < m_vector->length () 902 1.5 mrg && (*m_vector)[id] != NULL); 903 1.5 mrg } 904 1.5 mrg 905 1.5 mrg /* Symbol removal hook that is registered to symbol table. */ 906 1.5 mrg static void symtab_removal (cgraph_edge *edge, void *data); 907 1.5 mrg 908 1.5 mrg /* Symbol duplication hook that is registered to symbol table. */ 909 1.5 mrg static void symtab_duplication (cgraph_edge *edge1, cgraph_edge *edge2, 910 1.5 mrg void *data); 911 1.5 mrg 912 1.5 mrg private: 913 1.5 mrg virtual bool is_ggc (); 914 1.5 mrg 915 1.5 mrg /* Summary is stored in the vector. */ 916 1.5 mrg vec <T *, V> *m_vector; 917 1.5 mrg 918 1.5 mrg template <typename U> friend void gt_ggc_mx (fast_call_summary <U *, va_gc> * const &); 919 1.5 mrg template <typename U> friend void gt_pch_nx (fast_call_summary <U *, va_gc> * const &); 920 1.5 mrg template <typename U> friend void gt_pch_nx (fast_call_summary <U *, va_gc> * const &, 921 1.5 mrg gt_pointer_operator, void *); 922 1.5 mrg }; 923 1.5 mrg 924 1.5 mrg template <typename T, typename V> 925 1.6 mrg fast_call_summary<T *, V>::~fast_call_summary () 926 1.5 mrg { 927 1.5 mrg this->unregister_hooks (); 928 1.5 mrg 929 1.5 mrg /* Release all summaries. */ 930 1.5 mrg for (unsigned i = 0; i < m_vector->length (); i++) 931 1.5 mrg if ((*m_vector)[i] != NULL) 932 1.5 mrg this->release ((*m_vector)[i]); 933 1.5 mrg vec_free (m_vector); 934 1.5 mrg } 935 1.5 mrg 936 1.5 mrg template <typename T, typename V> 937 1.5 mrg void 938 1.5 mrg fast_call_summary<T *, V>::symtab_removal (cgraph_edge *edge, void *data) 939 1.5 mrg { 940 1.5 mrg fast_call_summary *summary = (fast_call_summary <T *, V> *) (data); 941 1.5 mrg summary->remove (edge); 942 1.5 mrg } 943 1.5 mrg 944 1.5 mrg template <typename T, typename V> 945 1.5 mrg void 946 1.5 mrg fast_call_summary<T *, V>::symtab_duplication (cgraph_edge *edge1, 947 1.5 mrg cgraph_edge *edge2, void *data) 948 1.5 mrg { 949 1.5 mrg fast_call_summary *summary = (fast_call_summary <T *, V> *) (data); 950 1.5 mrg T *edge1_summary = NULL; 951 1.5 mrg 952 1.5 mrg if (summary->m_initialize_when_cloning) 953 1.5 mrg edge1_summary = summary->get_create (edge1); 954 1.5 mrg else 955 1.5 mrg edge1_summary = summary->get (edge1); 956 1.5 mrg 957 1.5 mrg if (edge1_summary) 958 1.5 mrg { 959 1.5 mrg T *duplicate = summary->get_create (edge2); 960 1.5 mrg summary->duplicate (edge1, edge2, edge1_summary, duplicate); 961 1.5 mrg } 962 1.5 mrg } 963 1.5 mrg 964 1.5 mrg template <typename T, typename V> 965 1.5 mrg inline bool 966 1.5 mrg fast_call_summary<T *, V>::is_ggc () 967 1.5 mrg { 968 1.5 mrg return is_same<V, va_gc>::value; 969 1.5 mrg } 970 1.5 mrg 971 1.5 mrg template <typename T> 972 1.5 mrg void 973 1.6 mrg gt_ggc_mx (fast_call_summary<T *, va_heap>* const &summary ATTRIBUTE_UNUSED) 974 1.5 mrg { 975 1.5 mrg } 976 1.5 mrg 977 1.5 mrg template <typename T> 978 1.5 mrg void 979 1.6 mrg gt_pch_nx (fast_call_summary<T *, va_heap>* const &summary ATTRIBUTE_UNUSED) 980 1.5 mrg { 981 1.5 mrg } 982 1.5 mrg 983 1.5 mrg template <typename T> 984 1.5 mrg void 985 1.6 mrg gt_pch_nx (fast_call_summary<T *, va_heap>* const& summary ATTRIBUTE_UNUSED, 986 1.6 mrg gt_pointer_operator op ATTRIBUTE_UNUSED, 987 1.6 mrg void *cookie ATTRIBUTE_UNUSED) 988 1.5 mrg { 989 1.5 mrg } 990 1.5 mrg 991 1.5 mrg template <typename T> 992 1.5 mrg void 993 1.5 mrg gt_ggc_mx (fast_call_summary<T *, va_gc>* const &summary) 994 1.5 mrg { 995 1.5 mrg ggc_test_and_set_mark (summary->m_vector); 996 1.5 mrg gt_ggc_mx (&summary->m_vector); 997 1.5 mrg } 998 1.5 mrg 999 1.5 mrg template <typename T> 1000 1.5 mrg void 1001 1.6 mrg gt_pch_nx (fast_call_summary<T *, va_gc> *const &) 1002 1.5 mrg { 1003 1.6 mrg gcc_unreachable (); 1004 1.5 mrg } 1005 1.5 mrg 1006 1.5 mrg template <typename T> 1007 1.5 mrg void 1008 1.6 mrg gt_pch_nx (fast_call_summary<T *, va_gc> *const &, gt_pointer_operator, void *) 1009 1.5 mrg { 1010 1.6 mrg gcc_unreachable (); 1011 1.5 mrg } 1012 1.5 mrg 1013 1.1 mrg #endif /* GCC_SYMBOL_SUMMARY_H */ 1014