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)
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/>. */
21 #define INCLUDE_MEMORY
22 #define INCLUDE_VECTOR
24 #include "coretypes.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"
39 /* class call_summary. */
42 call_summary::get_state () const
44 return m_enode
->get_state ();
48 call_summary::get_fndecl () const
50 return m_enode
->get_point ().get_fndecl ();
54 call_summary::get_desc () const
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
69 This will help with debugging, too. */
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 ())
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 ())
99 case RK_HEAP_ALLOCATED
:
101 "when %qE returns pointer"
102 " to heap-allocated buffer",
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
))
115 pp_printf (pp
, "when %qE returns NULL", fndecl
);
117 pp_printf (pp
, "when %qE returns %qE", fndecl
, cst
);
125 pp_printf (pp
, "when %qE returns", fndecl
);
128 /* Dump a multiline representation of this object to PP. */
131 call_summary::dump_to_pp (const extrinsic_state
&ext_state
,
135 label_text desc
= get_desc ();
136 pp_printf (pp
, "desc: %qs", desc
.get ());
139 get_state ().dump_to_pp (ext_state
, simple
, true, pp
);
142 /* Dump a multiline representation of this object to FILE. */
145 call_summary::dump (const extrinsic_state
&ext_state
,
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. */
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
)
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
183 const frame_region
*summary_frame
184 = mgr
->get_frame_region (NULL
, called_fn
);
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 ())
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. */
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
))
233 const svalue
*caller_sval
= convert_svalue_from_summary_1 (summary_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 ()));
241 add_svalue_mapping (summary_sval
, caller_sval
);
246 /* Implementation of call_summary_replay::convert_svalue_from_summary. */
249 call_summary_replay::convert_svalue_from_summary_1 (const svalue
*summary_sval
)
251 gcc_assert (summary_sval
);
253 switch (summary_sval
->get_kind ())
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
);
265 region_model_manager
*mgr
= get_manager ();
266 const svalue
*caller_ptr
267 = mgr
->get_ptr_svalue (summary_sval
->get_type (),
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
);
295 const svalue
*caller_sval
296 = m_cd
.get_model ()->get_store_value (caller_reg
, m_cd
.get_ctxt ());
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
);
308 region_model_manager
*mgr
= get_manager ();
309 return mgr
->get_or_create_unaryop (summary_sval
->get_type (),
310 unaryop_summary_sval
->get_op (),
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
);
322 const svalue
*summary_arg1
= binop_summary_sval
->get_arg1 ();
323 const svalue
*caller_arg1
= convert_svalue_from_summary (summary_arg1
);
326 region_model_manager
*mgr
= get_manager ();
327 return mgr
->get_or_create_binop (summary_sval
->get_type (),
328 binop_summary_sval
->get_op (),
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
)
341 const region
*summary_subregion
= sub_summary_sval
->get_subregion ();
342 if (!summary_subregion
)
344 return mgr
->get_or_create_sub_svalue (summary_sval
->get_type (),
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
)
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
)
365 region_model_manager
*mgr
= get_manager ();
366 return mgr
->get_or_create_repeated_svalue (summary_sval
->get_type (),
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
)
382 region_model_manager
*mgr
= get_manager ();
383 return mgr
->get_or_create_bits_within (summary_sval
->get_type (),
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
)
397 region_model_manager
*mgr
= get_manager ();
398 return mgr
->get_or_create_unmergeable (caller_arg_sval
);
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 ()))
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 ()))
420 region_model_manager
*mgr
= get_manager ();
421 return mgr
->get_or_create_widening_svalue
422 (summary_iter_sval
->get_type (),
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
);
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
470 concrete_key
->get_size_in_bits ());
471 caller_map
.put (effective_concrete_key
, inner_sval
);
475 caller_map
.put (key
, caller_sval
);
477 return mgr
->get_or_create_compound_svalue (summary_sval
->get_type (),
483 region_model_manager
*mgr
= get_manager ();
484 return mgr
->get_or_create_unknown_svalue (summary_sval
->get_type ());
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
);
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 (),
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
);
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 (),
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. */
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
))
555 const region
*caller_reg
= convert_region_from_summary_1 (summary_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 ()));
563 add_region_mapping (summary_reg
, caller_reg
);
568 /* Implementation of call_summary_replay::convert_region_from_summary. */
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 ())
580 /* Top-level regions. */
586 case RK_THREAD_LOCAL
:
588 /* These should never be pointed to by a region_svalue. */
597 /* We can reuse these regions directly. */
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
)
609 const region
*caller_reg
610 = get_caller_model ()->deref_rvalue (caller_ptr_sval
,
613 caller_reg
= mgr
->get_cast_region (caller_reg
,
614 summary_reg
->get_type ());
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
))
629 /* We don't care about writes to locals within
633 /* We don't care about writes to locals within
635 if (is_global_var (decl
))
636 /* If it's a global, we can reuse the region directly. */
639 /* Otherwise, we don't care about locals. */
642 return m_cd
.get_lhs_region ();
644 /* Writes (by value) to parms should be visible to the caller. */
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
)
658 tree field
= summary_field_reg
->get_field ();
659 return mgr
->get_field_region (caller_parent_reg
, field
);
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
)
671 const svalue
*summary_index
= summary_element_reg
->get_index ();
672 const svalue
*caller_index
673 = convert_svalue_from_summary (summary_index
);
676 return mgr
->get_element_region (caller_parent_reg
,
677 summary_reg
->get_type (),
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
)
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
)
696 return mgr
->get_offset_region (caller_parent_reg
,
697 summary_reg
->get_type (),
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
)
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
)
716 return mgr
->get_sized_region (caller_parent_reg
,
717 summary_reg
->get_type (),
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
)
728 return mgr
->get_cast_region (caller_parent_reg
,
729 summary_reg
->get_type ());
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
);
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
)
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 (),
764 /* Try to convert SUMMARY_KEY in the summary to a corresponding binding key
767 Return NULL if the conversion is not possible. */
770 call_summary_replay::convert_key_from_summary (const binding_key
*summary_key
)
772 if (summary_key
->concrete_p ())
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
);
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. */
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. */
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. */
810 call_summary_replay::dump_to_pp (pretty_printer
*pp
, bool simple
) const
813 pp_string (pp
, "CALL DETAILS:");
815 m_cd
.dump_to_pp (pp
, simple
);
818 pp_string (pp
, "CALLEE SUMMARY:");
820 m_summary
->dump_to_pp (m_ext_state
, pp
, simple
);
822 /* Current state of caller (could be in mid-update). */
824 pp_string (pp
, "CALLER:");
826 m_cd
.get_model ()->dump_to_pp (pp
, simple
, true);
829 pp_string (pp
, "REPLAY STATE:");
831 pp_string (pp
, "svalue mappings from summary to caller:");
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
);
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
);
852 pp_string (pp
, "region mappings from summary to caller:");
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: ");
862 summary_reg
->dump_to_pp (pp
, simple
);
864 pp_string (pp
, "(null)");
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: ");
872 caller_reg
->dump_to_pp (pp
, simple
);
874 pp_string (pp
, "(null)");
879 /* Dump a multiline representation of this object to FILE. */
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. */
891 call_summary_replay::dump (bool simple
) const
893 dump (stderr
, simple
);
898 #endif /* #if ENABLE_ANALYZER */