libcpp, c, middle-end: Optimize initializers using #embed in C
[official-gcc.git] / gcc / analyzer / call-summary.cc
blobf6d22df547e3ce097fff5bad1ed90ead9d547abf
1 /* Classes for working with summaries of function calls.
2 Copyright (C) 2022 David Malcolm <dmalcolm@redhat.com>.
4 This file is part of GCC.
6 GCC is free software; you can redistribute it and/or modify it
7 under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3, or (at your option)
9 any later version.
11 GCC is distributed in the hope that it will be useful, but
12 WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with GCC; see the file COPYING3. If not see
18 <http://www.gnu.org/licenses/>. */
20 #include "config.h"
21 #define INCLUDE_MEMORY
22 #define INCLUDE_VECTOR
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tree.h"
26 #include "tree-dfa.h"
27 #include "diagnostic-core.h"
28 #include "diagnostic.h"
29 #include "tree-diagnostic.h"
30 #include "analyzer/analyzer.h"
31 #include "analyzer/region-model.h"
32 #include "analyzer/call-summary.h"
33 #include "analyzer/exploded-graph.h"
35 #if ENABLE_ANALYZER
37 namespace ana {
39 /* class call_summary. */
41 const program_state &
42 call_summary::get_state () const
44 return m_enode->get_state ();
47 tree
48 call_summary::get_fndecl () const
50 return m_enode->get_point ().get_fndecl ();
53 label_text
54 call_summary::get_desc () const
56 pretty_printer pp;
57 pp_format_decoder (&pp) = default_tree_printer;
59 get_user_facing_desc (&pp);
60 if (flag_analyzer_verbose_edges)
61 pp_printf (&pp, " (call summary; EN: %i)", m_enode->m_index);
63 return label_text::take (xstrdup (pp_formatted_text (&pp)));
66 /* Generate a user-facing description of this call summary.c
67 This has various heuristics for distinguishing between different
68 summaries.
69 This will help with debugging, too. */
71 void
72 call_summary::get_user_facing_desc (pretty_printer *pp) const
74 tree fndecl = get_fndecl ();
76 /* If there are multiple summaries, try to use the return value to
77 distinguish between them. */
78 if (m_per_fn_data->m_summaries.length () > 1)
80 if (tree result = DECL_RESULT (fndecl))
82 const region *result_reg
83 = get_state ().m_region_model->get_lvalue (result, NULL);
84 const svalue *result_sval
85 = get_state ().m_region_model->get_store_value (result_reg, NULL);
86 switch (result_sval->get_kind ())
88 default:
89 break;
90 case SK_REGION:
92 const region_svalue *region_sval
93 = as_a <const region_svalue *> (result_sval);
94 const region *pointee_reg = region_sval->get_pointee ();
95 switch (pointee_reg->get_kind ())
97 default:
98 break;
99 case RK_HEAP_ALLOCATED:
100 pp_printf (pp,
101 "when %qE returns pointer"
102 " to heap-allocated buffer",
103 fndecl);
104 return;
107 break;
108 case SK_CONSTANT:
110 const constant_svalue *constant_sval
111 = as_a <const constant_svalue *> (result_sval);
112 tree cst = constant_sval->get_constant ();
113 if (POINTER_TYPE_P (TREE_TYPE (result))
114 && zerop (cst))
115 pp_printf (pp, "when %qE returns NULL", fndecl);
116 else
117 pp_printf (pp, "when %qE returns %qE", fndecl, cst);
118 return;
124 /* Fallback. */
125 pp_printf (pp, "when %qE returns", fndecl);
128 /* Dump a multiline representation of this object to PP. */
130 void
131 call_summary::dump_to_pp (const extrinsic_state &ext_state,
132 pretty_printer *pp,
133 bool simple) const
135 label_text desc = get_desc ();
136 pp_printf (pp, "desc: %qs", desc.get ());
137 pp_newline (pp);
139 get_state ().dump_to_pp (ext_state, simple, true, pp);
142 /* Dump a multiline representation of this object to FILE. */
144 void
145 call_summary::dump (const extrinsic_state &ext_state,
146 FILE *fp,
147 bool simple) const
149 tree_dump_pretty_printer pp (fp);
150 dump_to_pp (ext_state, &pp, simple);
153 /* Dump a multiline representation of this object to stderr. */
155 DEBUG_FUNCTION void
156 call_summary::dump (const extrinsic_state &ext_state, bool simple) const
158 dump (ext_state, stderr, simple);
161 /* class call_summary_replay. */
163 /* call_summary_replay's ctor.
164 Populate the cache with params for the summary based on
165 arguments at the caller. */
167 call_summary_replay::call_summary_replay (const call_details &cd,
168 const function &called_fn,
169 call_summary *summary,
170 const extrinsic_state &ext_state)
171 : m_cd (cd),
172 m_summary (summary),
173 m_ext_state (ext_state)
175 region_model_manager *mgr = cd.get_manager ();
177 // populate params based on args
178 tree fndecl = called_fn.decl;
180 /* Get a frame_region for use with respect to the summary.
181 This will be a top-level frame, since that's what's in
182 the summary. */
183 const frame_region *summary_frame
184 = mgr->get_frame_region (NULL, called_fn);
186 unsigned idx = 0;
187 for (tree iter_parm = DECL_ARGUMENTS (fndecl); iter_parm;
188 iter_parm = DECL_CHAIN (iter_parm), ++idx)
190 /* If there's a mismatching declaration, the call stmt might
191 not have enough args. Handle this case by leaving the
192 rest of the params as uninitialized. */
193 if (idx >= cd.num_args ())
194 break;
195 const svalue *caller_arg_sval = cd.get_arg_svalue (idx);
196 tree parm_lval = iter_parm;
197 if (tree parm_default_ssa = get_ssa_default_def (called_fn, iter_parm))
198 parm_lval = parm_default_ssa;
199 const region *summary_parm_reg
200 = summary_frame->get_region_for_local (mgr, parm_lval, cd.get_ctxt ());
201 const svalue *summary_initial_parm_reg
202 = mgr->get_or_create_initial_value (summary_parm_reg);
203 add_svalue_mapping (summary_initial_parm_reg, caller_arg_sval);
206 /* Handle any variadic args. */
207 unsigned va_arg_idx = 0;
208 for (; idx < cd.num_args (); idx++, va_arg_idx++)
210 const svalue *caller_arg_sval = cd.get_arg_svalue (idx);
211 const region *summary_var_arg_reg
212 = mgr->get_var_arg_region (summary_frame, va_arg_idx);
213 const svalue *summary_initial_var_arg_reg
214 = mgr->get_or_create_initial_value (summary_var_arg_reg);
215 add_svalue_mapping (summary_initial_var_arg_reg, caller_arg_sval);
219 /* Try to convert SUMMARY_SVAL in the summary to a corresponding svalue
220 in the caller, caching the result.
222 Return NULL if the conversion is not possible. */
224 const svalue *
225 call_summary_replay::convert_svalue_from_summary (const svalue *summary_sval)
227 gcc_assert (summary_sval);
229 if (const svalue **slot
230 = m_map_svalue_from_summary_to_caller.get (summary_sval))
231 return *slot;
233 const svalue *caller_sval = convert_svalue_from_summary_1 (summary_sval);
235 if (caller_sval)
236 if (summary_sval->get_type () && caller_sval->get_type ())
237 gcc_assert (types_compatible_p (summary_sval->get_type (),
238 caller_sval->get_type ()));
240 /* Add to cache. */
241 add_svalue_mapping (summary_sval, caller_sval);
243 return caller_sval;
246 /* Implementation of call_summary_replay::convert_svalue_from_summary. */
248 const svalue *
249 call_summary_replay::convert_svalue_from_summary_1 (const svalue *summary_sval)
251 gcc_assert (summary_sval);
253 switch (summary_sval->get_kind ())
255 default:
256 gcc_unreachable ();
257 case SK_REGION:
259 const region_svalue *region_summary_sval
260 = as_a <const region_svalue *> (summary_sval);
261 const region *summary_reg = region_summary_sval->get_pointee ();
262 const region *caller_reg = convert_region_from_summary (summary_reg);
263 if (!caller_reg)
264 return NULL;
265 region_model_manager *mgr = get_manager ();
266 const svalue *caller_ptr
267 = mgr->get_ptr_svalue (summary_sval->get_type (),
268 caller_reg);
269 return caller_ptr;
271 break;
273 case SK_CONSTANT:
274 case SK_PLACEHOLDER:
275 case SK_POISONED:
276 case SK_UNKNOWN:
277 return summary_sval;
279 case SK_SETJMP:
280 return NULL; // TODO
282 case SK_INITIAL:
284 const initial_svalue *initial_summary_sval
285 = as_a <const initial_svalue *> (summary_sval);
286 /* Params should already be in the cache, courtesy of the ctor. */
287 gcc_assert (!initial_summary_sval->initial_value_of_param_p ());
289 /* Initial value of region within the summary is the value of the
290 region at the point of the call. */
291 const region *summary_reg = initial_summary_sval->get_region ();
292 const region *caller_reg = convert_region_from_summary (summary_reg);
293 if (!caller_reg)
294 return NULL;
295 const svalue *caller_sval
296 = m_cd.get_model ()->get_store_value (caller_reg, m_cd.get_ctxt ());
297 return caller_sval;
299 break;
300 case SK_UNARYOP:
302 const unaryop_svalue *unaryop_summary_sval
303 = as_a <const unaryop_svalue *> (summary_sval);
304 const svalue *summary_arg = unaryop_summary_sval->get_arg ();
305 const svalue *caller_arg = convert_svalue_from_summary (summary_arg);
306 if (!caller_arg)
307 return NULL;
308 region_model_manager *mgr = get_manager ();
309 return mgr->get_or_create_unaryop (summary_sval->get_type (),
310 unaryop_summary_sval->get_op (),
311 caller_arg);
313 break;
314 case SK_BINOP:
316 const binop_svalue *binop_summary_sval
317 = as_a <const binop_svalue *> (summary_sval);
318 const svalue *summary_arg0 = binop_summary_sval->get_arg0 ();
319 const svalue *caller_arg0 = convert_svalue_from_summary (summary_arg0);
320 if (!caller_arg0)
321 return NULL;
322 const svalue *summary_arg1 = binop_summary_sval->get_arg1 ();
323 const svalue *caller_arg1 = convert_svalue_from_summary (summary_arg1);
324 if (!caller_arg1)
325 return NULL;
326 region_model_manager *mgr = get_manager ();
327 return mgr->get_or_create_binop (summary_sval->get_type (),
328 binop_summary_sval->get_op (),
329 caller_arg0,
330 caller_arg1);
332 break;
333 case SK_SUB:
335 const sub_svalue *sub_summary_sval
336 = as_a <const sub_svalue *> (summary_sval);
337 region_model_manager *mgr = get_manager ();
338 const svalue *summary_parent_sval = sub_summary_sval->get_parent ();
339 if (!summary_parent_sval)
340 return NULL;
341 const region *summary_subregion = sub_summary_sval->get_subregion ();
342 if (!summary_subregion)
343 return NULL;
344 return mgr->get_or_create_sub_svalue (summary_sval->get_type (),
345 summary_parent_sval,
346 summary_subregion);
348 break;
349 case SK_REPEATED:
351 const repeated_svalue *repeated_summary_sval
352 = as_a <const repeated_svalue *> (summary_sval);
353 const svalue *summary_outer_size
354 = repeated_summary_sval->get_outer_size ();
355 const svalue *caller_outer_size
356 = convert_svalue_from_summary (summary_outer_size);
357 if (!caller_outer_size)
358 return NULL;
359 const svalue *summary_inner_sval
360 = repeated_summary_sval->get_inner_svalue ();
361 const svalue *caller_inner_sval
362 = convert_svalue_from_summary (summary_inner_sval);
363 if (!caller_inner_sval)
364 return NULL;
365 region_model_manager *mgr = get_manager ();
366 return mgr->get_or_create_repeated_svalue (summary_sval->get_type (),
367 caller_outer_size,
368 caller_inner_sval);
370 break;
371 case SK_BITS_WITHIN:
373 const bits_within_svalue *bits_within_summary_sval
374 = as_a <const bits_within_svalue *> (summary_sval);
375 const bit_range &bits = bits_within_summary_sval->get_bits ();
376 const svalue *summary_inner_sval
377 = bits_within_summary_sval->get_inner_svalue ();
378 const svalue *caller_inner_sval
379 = convert_svalue_from_summary (summary_inner_sval);
380 if (!caller_inner_sval)
381 return NULL;
382 region_model_manager *mgr = get_manager ();
383 return mgr->get_or_create_bits_within (summary_sval->get_type (),
384 bits,
385 caller_inner_sval);
387 break;
388 case SK_UNMERGEABLE:
390 const unmergeable_svalue *unmergeable_summary_sval
391 = as_a <const unmergeable_svalue *> (summary_sval);
392 const svalue *summary_arg_sval = unmergeable_summary_sval->get_arg ();
393 const svalue *caller_arg_sval
394 = convert_svalue_from_summary (summary_arg_sval);
395 if (!caller_arg_sval)
396 return NULL;
397 region_model_manager *mgr = get_manager ();
398 return mgr->get_or_create_unmergeable (caller_arg_sval);
400 break;
401 case SK_WIDENING:
403 const widening_svalue *widening_summary_sval
404 = as_a <const widening_svalue *> (summary_sval);
405 const function_point &point = widening_summary_sval->get_point ();
406 const svalue *summary_base_sval
407 = widening_summary_sval->get_base_svalue ();
408 const svalue *caller_base_sval
409 = convert_svalue_from_summary (summary_base_sval);
410 if (!(caller_base_sval
411 && caller_base_sval->can_have_associated_state_p ()))
412 return NULL;
413 const svalue *summary_iter_sval
414 = widening_summary_sval->get_iter_svalue ();
415 const svalue *caller_iter_sval
416 = convert_svalue_from_summary (summary_iter_sval);
417 if (!(caller_iter_sval
418 && caller_iter_sval->can_have_associated_state_p ()))
419 return NULL;
420 region_model_manager *mgr = get_manager ();
421 return mgr->get_or_create_widening_svalue
422 (summary_iter_sval->get_type (),
423 point,
424 caller_base_sval,
425 caller_iter_sval);
427 break;
428 case SK_COMPOUND:
430 const compound_svalue *compound_summary_sval
431 = as_a <const compound_svalue *> (summary_sval);
432 region_model_manager *mgr = get_manager ();
433 store_manager *store_mgr = mgr->get_store_manager ();
434 binding_map caller_map;
435 auto_vec <const binding_key *> summary_keys;
436 for (auto kv : *compound_summary_sval)
437 summary_keys.safe_push (kv.first);
438 summary_keys.qsort (binding_key::cmp_ptrs);
439 for (auto key : summary_keys)
441 gcc_assert (key->concrete_p ());
442 /* No remapping is needed for concrete binding keys. */
444 const svalue *bound_summary_sval
445 = compound_summary_sval->get_map ().get (key);
446 const svalue *caller_sval
447 = convert_svalue_from_summary (bound_summary_sval);
448 if (!caller_sval)
449 caller_sval = mgr->get_or_create_unknown_svalue (NULL_TREE);
451 if (const compound_svalue *inner_compound_sval
452 = caller_sval->dyn_cast_compound_svalue ())
454 const concrete_binding *outer_key
455 = as_a <const concrete_binding *> (key);
456 for (auto inner_kv : *inner_compound_sval)
458 // These should already be mapped to the caller.
459 const binding_key *inner_key = inner_kv.first;
460 const svalue *inner_sval = inner_kv.second;
461 gcc_assert (inner_key->concrete_p ());
462 const concrete_binding *concrete_key
463 = as_a <const concrete_binding *> (inner_key);
464 bit_offset_t effective_start
465 = (concrete_key->get_start_bit_offset ()
466 + outer_key->get_start_bit_offset ());
467 const concrete_binding *effective_concrete_key
468 = store_mgr->get_concrete_binding
469 (effective_start,
470 concrete_key->get_size_in_bits ());
471 caller_map.put (effective_concrete_key, inner_sval);
474 else
475 caller_map.put (key, caller_sval);
477 return mgr->get_or_create_compound_svalue (summary_sval->get_type (),
478 caller_map);
480 break;
481 case SK_CONJURED:
483 region_model_manager *mgr = get_manager ();
484 return mgr->get_or_create_unknown_svalue (summary_sval->get_type ());
486 break;
487 case SK_ASM_OUTPUT:
489 const asm_output_svalue *asm_output_summary_sval
490 = as_a <const asm_output_svalue *> (summary_sval);
491 const char *asm_string = asm_output_summary_sval->get_asm_string ();
492 unsigned output_idx = asm_output_summary_sval->get_output_idx ();
493 unsigned num_inputs = asm_output_summary_sval->get_num_inputs ();
494 unsigned num_outputs = asm_output_summary_sval->get_num_outputs ();
495 auto_vec<const svalue *> inputs (num_inputs);
496 for (unsigned idx = 0; idx < num_inputs; idx++)
498 const svalue *summary_input
499 = asm_output_summary_sval->get_input (idx);
500 const svalue *caller_input
501 = convert_svalue_from_summary (summary_input);
502 if (!caller_input)
503 return NULL;
504 inputs.safe_push (caller_input);
506 region_model_manager *mgr = get_manager ();
507 return mgr->get_or_create_asm_output_svalue (summary_sval->get_type (),
508 asm_string,
509 output_idx,
510 num_outputs,
511 inputs);
513 break;
514 case SK_CONST_FN_RESULT:
516 const const_fn_result_svalue *const_fn_result_summary_sval
517 = as_a <const const_fn_result_svalue *> (summary_sval);
518 tree fndecl = const_fn_result_summary_sval->get_fndecl ();
519 unsigned num_inputs = const_fn_result_summary_sval->get_num_inputs ();
520 auto_vec<const svalue *> inputs (num_inputs);
521 for (unsigned idx = 0; idx < num_inputs; idx++)
523 const svalue *summary_input
524 = const_fn_result_summary_sval->get_input (idx);
525 const svalue *caller_input
526 = convert_svalue_from_summary (summary_input);
527 if (!caller_input)
528 return NULL;
529 inputs.safe_push (caller_input);
531 region_model_manager *mgr = get_manager ();
532 return mgr->get_or_create_const_fn_result_svalue
533 (summary_sval->get_type (),
534 fndecl,
535 inputs);
537 break;
541 /* Try to convert SUMMARY_REG in the summary to a corresponding region
542 in the caller, caching the result.
544 Return NULL if the conversion is not possible. */
546 const region *
547 call_summary_replay::convert_region_from_summary (const region *summary_reg)
549 gcc_assert (summary_reg);
551 if (const region **slot
552 = m_map_region_from_summary_to_caller.get (summary_reg))
553 return *slot;
555 const region *caller_reg = convert_region_from_summary_1 (summary_reg);
557 if (caller_reg)
558 if (summary_reg->get_type () && caller_reg->get_type ())
559 gcc_assert (types_compatible_p (summary_reg->get_type (),
560 caller_reg->get_type ()));
562 /* Add to cache. */
563 add_region_mapping (summary_reg, caller_reg);
565 return caller_reg;
568 /* Implementation of call_summary_replay::convert_region_from_summary. */
570 const region *
571 call_summary_replay::convert_region_from_summary_1 (const region *summary_reg)
573 gcc_assert (summary_reg);
575 region_model_manager *mgr = get_manager ();
576 switch (summary_reg->get_kind ())
578 default:
579 gcc_unreachable ();
580 /* Top-level regions. */
581 case RK_FRAME:
582 case RK_GLOBALS:
583 case RK_CODE:
584 case RK_STACK:
585 case RK_HEAP:
586 case RK_THREAD_LOCAL:
587 case RK_ROOT:
588 /* These should never be pointed to by a region_svalue. */
589 gcc_unreachable ();
591 case RK_FUNCTION:
592 case RK_LABEL:
593 case RK_STRING:
594 case RK_ERRNO:
595 case RK_UNKNOWN:
596 case RK_PRIVATE:
597 /* We can reuse these regions directly. */
598 return summary_reg;
600 case RK_SYMBOLIC:
602 const symbolic_region *summary_symbolic_reg
603 = as_a <const symbolic_region *> (summary_reg);
604 const svalue *summary_ptr_sval = summary_symbolic_reg->get_pointer ();
605 const svalue *caller_ptr_sval
606 = convert_svalue_from_summary (summary_ptr_sval);
607 if (!caller_ptr_sval)
608 return NULL;
609 const region *caller_reg
610 = get_caller_model ()->deref_rvalue (caller_ptr_sval,
611 NULL_TREE,
612 get_ctxt ());
613 caller_reg = mgr->get_cast_region (caller_reg,
614 summary_reg->get_type ());
615 return caller_reg;
617 break;
619 case RK_DECL:
621 const decl_region *summary_decl_reg
622 = as_a <const decl_region *> (summary_reg);
623 tree decl = summary_decl_reg->get_decl ();
624 switch (TREE_CODE (decl))
626 default:
627 gcc_unreachable ();
628 case SSA_NAME:
629 /* We don't care about writes to locals within
630 the summary. */
631 return NULL;
632 case VAR_DECL:
633 /* We don't care about writes to locals within
634 the summary. */
635 if (is_global_var (decl))
636 /* If it's a global, we can reuse the region directly. */
637 return summary_reg;
638 else
639 /* Otherwise, we don't care about locals. */
640 return NULL;
641 case RESULT_DECL:
642 return m_cd.get_lhs_region ();
643 case PARM_DECL:
644 /* Writes (by value) to parms should be visible to the caller. */
645 return NULL;
648 break;
649 case RK_FIELD:
651 const field_region *summary_field_reg
652 = as_a <const field_region *> (summary_reg);
653 const region *summary_parent_reg = summary_reg->get_parent_region ();
654 const region *caller_parent_reg
655 = convert_region_from_summary (summary_parent_reg);
656 if (!caller_parent_reg)
657 return NULL;
658 tree field = summary_field_reg->get_field ();
659 return mgr->get_field_region (caller_parent_reg, field);
661 break;
662 case RK_ELEMENT:
664 const element_region *summary_element_reg
665 = as_a <const element_region *> (summary_reg);
666 const region *summary_parent_reg = summary_reg->get_parent_region ();
667 const region *caller_parent_reg
668 = convert_region_from_summary (summary_parent_reg);
669 if (!caller_parent_reg)
670 return NULL;
671 const svalue *summary_index = summary_element_reg->get_index ();
672 const svalue *caller_index
673 = convert_svalue_from_summary (summary_index);
674 if (!caller_index)
675 return NULL;
676 return mgr->get_element_region (caller_parent_reg,
677 summary_reg->get_type (),
678 caller_index);
680 break;
681 case RK_OFFSET:
683 const offset_region *summary_offset_reg
684 = as_a <const offset_region *> (summary_reg);
685 const region *summary_parent_reg = summary_reg->get_parent_region ();
686 const region *caller_parent_reg
687 = convert_region_from_summary (summary_parent_reg);
688 if (!caller_parent_reg)
689 return NULL;
690 const svalue *summary_byte_offset
691 = summary_offset_reg->get_byte_offset ();
692 const svalue *caller_byte_offset
693 = convert_svalue_from_summary (summary_byte_offset);
694 if (!caller_byte_offset)
695 return NULL;
696 return mgr->get_offset_region (caller_parent_reg,
697 summary_reg->get_type (),
698 caller_byte_offset);
700 break;
701 case RK_SIZED:
703 const sized_region *summary_sized_reg
704 = as_a <const sized_region *> (summary_reg);
705 const region *summary_parent_reg = summary_reg->get_parent_region ();
706 const region *caller_parent_reg
707 = convert_region_from_summary (summary_parent_reg);
708 if (!caller_parent_reg)
709 return NULL;
710 const svalue *summary_byte_size
711 = summary_sized_reg->get_byte_size_sval (mgr);
712 const svalue *caller_byte_size
713 = convert_svalue_from_summary (summary_byte_size);
714 if (!caller_byte_size)
715 return NULL;
716 return mgr->get_sized_region (caller_parent_reg,
717 summary_reg->get_type (),
718 caller_byte_size);
720 break;
721 case RK_CAST:
723 const region *summary_parent_reg = summary_reg->get_parent_region ();
724 const region *caller_parent_reg
725 = convert_region_from_summary (summary_parent_reg);
726 if (!caller_parent_reg)
727 return NULL;
728 return mgr->get_cast_region (caller_parent_reg,
729 summary_reg->get_type ());
731 break;
732 case RK_HEAP_ALLOCATED:
734 /* If we have a heap-allocated region in the summary, then
735 it was allocated within the callee.
736 Create a new heap-allocated region to summarize this. */
737 auto_bitmap heap_regs_in_use;
738 get_caller_model ()->get_referenced_base_regions (heap_regs_in_use);
739 return mgr->get_or_create_region_for_heap_alloc (heap_regs_in_use);
741 break;
742 case RK_ALLOCA:
743 return NULL;
744 case RK_BIT_RANGE:
746 const bit_range_region *summary_bit_range_reg
747 = as_a <const bit_range_region *> (summary_reg);
748 const region *summary_parent_reg = summary_reg->get_parent_region ();
749 const region *caller_parent_reg
750 = convert_region_from_summary (summary_parent_reg);
751 if (!caller_parent_reg)
752 return NULL;
753 const bit_range &bits = summary_bit_range_reg->get_bits ();
754 return mgr->get_bit_range (caller_parent_reg,
755 summary_reg->get_type (),
756 bits);
758 break;
759 case RK_VAR_ARG:
760 return NULL;
764 /* Try to convert SUMMARY_KEY in the summary to a corresponding binding key
765 in the caller.
767 Return NULL if the conversion is not possible. */
769 const binding_key *
770 call_summary_replay::convert_key_from_summary (const binding_key *summary_key)
772 if (summary_key->concrete_p ())
773 return summary_key;
775 const symbolic_binding *symbolic_key = (const symbolic_binding *)summary_key;
776 const region *summary_reg = symbolic_key->get_region ();
777 const region *caller_reg = convert_region_from_summary (summary_reg);
778 if (!caller_reg)
779 return NULL;
780 region_model_manager *mgr = get_manager ();
781 store_manager *store_mgr = mgr->get_store_manager ();
782 return store_mgr->get_symbolic_binding (caller_reg);
785 /* Record that SUMMARY_SVAL maps to CALLER_SVAL for this replay. */
787 void
788 call_summary_replay::add_svalue_mapping (const svalue *summary_sval,
789 const svalue *caller_sval)
791 gcc_assert (summary_sval);
792 // CALLER_SVAL can be NULL
793 m_map_svalue_from_summary_to_caller.put (summary_sval, caller_sval);
796 /* Record that SUMMARY_REG maps to CALLER_REG for this replay. */
798 void
799 call_summary_replay::add_region_mapping (const region *summary_reg,
800 const region *caller_reg)
802 gcc_assert (summary_reg);
803 // CALLER_REG can be NULL
804 m_map_region_from_summary_to_caller.put (summary_reg, caller_reg);
807 /* Dump a multiline representation of this object to PP. */
809 void
810 call_summary_replay::dump_to_pp (pretty_printer *pp, bool simple) const
812 pp_newline (pp);
813 pp_string (pp, "CALL DETAILS:");
814 pp_newline (pp);
815 m_cd.dump_to_pp (pp, simple);
817 pp_newline (pp);
818 pp_string (pp, "CALLEE SUMMARY:");
819 pp_newline (pp);
820 m_summary->dump_to_pp (m_ext_state, pp, simple);
822 /* Current state of caller (could be in mid-update). */
823 pp_newline (pp);
824 pp_string (pp, "CALLER:");
825 pp_newline (pp);
826 m_cd.get_model ()->dump_to_pp (pp, simple, true);
828 pp_newline (pp);
829 pp_string (pp, "REPLAY STATE:");
830 pp_newline (pp);
831 pp_string (pp, "svalue mappings from summary to caller:");
832 pp_newline (pp);
833 auto_vec <const svalue *> summary_svals;
834 for (auto kv : m_map_svalue_from_summary_to_caller)
835 summary_svals.safe_push (kv.first);
836 summary_svals.qsort (svalue::cmp_ptr_ptr);
837 for (auto summary_sval : summary_svals)
839 pp_string (pp, "sval in summary: ");
840 summary_sval->dump_to_pp (pp, simple);
841 pp_newline (pp);
843 const svalue *caller_sval
844 = *((const_cast<svalue_map_t &>
845 (m_map_svalue_from_summary_to_caller)).get (summary_sval));
846 pp_string (pp, " sval in caller: ");
847 caller_sval->dump_to_pp (pp, simple);
848 pp_newline (pp);
851 pp_newline (pp);
852 pp_string (pp, "region mappings from summary to caller:");
853 pp_newline (pp);
854 auto_vec <const region *> summary_regs;
855 for (auto kv : m_map_region_from_summary_to_caller)
856 summary_regs.safe_push (kv.first);
857 summary_regs.qsort (region::cmp_ptr_ptr);
858 for (auto summary_reg : summary_regs)
860 pp_string (pp, "reg in summary: ");
861 if (summary_reg)
862 summary_reg->dump_to_pp (pp, simple);
863 else
864 pp_string (pp, "(null)");
865 pp_newline (pp);
867 const region *caller_reg
868 = *((const_cast<region_map_t &>
869 (m_map_region_from_summary_to_caller)).get (summary_reg));
870 pp_string (pp, " reg in caller: ");
871 if (caller_reg)
872 caller_reg->dump_to_pp (pp, simple);
873 else
874 pp_string (pp, "(null)");
875 pp_newline (pp);
879 /* Dump a multiline representation of this object to FILE. */
881 void
882 call_summary_replay::dump (FILE *fp, bool simple) const
884 tree_dump_pretty_printer pp (fp);
885 dump_to_pp (&pp, simple);
888 /* Dump a multiline representation of this object to stderr. */
890 DEBUG_FUNCTION void
891 call_summary_replay::dump (bool simple) const
893 dump (stderr, simple);
896 } // namespace ana
898 #endif /* #if ENABLE_ANALYZER */