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
23 #include "coretypes.h"
26 #include "diagnostic-core.h"
27 #include "diagnostic.h"
28 #include "tree-diagnostic.h"
29 #include "analyzer/analyzer.h"
30 #include "analyzer/region-model.h"
31 #include "analyzer/call-summary.h"
32 #include "analyzer/exploded-graph.h"
38 /* class call_summary. */
41 call_summary::get_state () const
43 return m_enode
->get_state ();
47 call_summary::get_fndecl () const
49 return m_enode
->get_point ().get_fndecl ();
53 call_summary::get_desc () const
56 pp_format_decoder (&pp
) = default_tree_printer
;
58 get_user_facing_desc (&pp
);
59 if (flag_analyzer_verbose_edges
)
60 pp_printf (&pp
, " (call summary; EN: %i)", m_enode
->m_index
);
62 return label_text::take (xstrdup (pp_formatted_text (&pp
)));
65 /* Generate a user-facing description of this call summary.c
66 This has various heuristics for distinguishing between different
68 This will help with debugging, too. */
71 call_summary::get_user_facing_desc (pretty_printer
*pp
) const
73 tree fndecl
= get_fndecl ();
75 /* If there are multiple summaries, try to use the return value to
76 distinguish between them. */
77 if (m_per_fn_data
->m_summaries
.length () > 1)
79 if (tree result
= DECL_RESULT (fndecl
))
81 const region
*result_reg
82 = get_state ().m_region_model
->get_lvalue (result
, NULL
);
83 const svalue
*result_sval
84 = get_state ().m_region_model
->get_store_value (result_reg
, NULL
);
85 switch (result_sval
->get_kind ())
91 const region_svalue
*region_sval
92 = as_a
<const region_svalue
*> (result_sval
);
93 const region
*pointee_reg
= region_sval
->get_pointee ();
94 switch (pointee_reg
->get_kind ())
98 case RK_HEAP_ALLOCATED
:
100 "when %qE returns pointer"
101 " to heap-allocated buffer",
109 const constant_svalue
*constant_sval
110 = as_a
<const constant_svalue
*> (result_sval
);
111 tree cst
= constant_sval
->get_constant ();
112 if (POINTER_TYPE_P (TREE_TYPE (result
))
114 pp_printf (pp
, "when %qE returns NULL", fndecl
);
116 pp_printf (pp
, "when %qE returns %qE", fndecl
, cst
);
124 pp_printf (pp
, "when %qE returns", fndecl
);
127 /* Dump a multiline representation of this object to PP. */
130 call_summary::dump_to_pp (const extrinsic_state
&ext_state
,
134 label_text desc
= get_desc ();
135 pp_printf (pp
, "desc: %qs", desc
.get ());
138 get_state ().dump_to_pp (ext_state
, simple
, true, pp
);
141 /* Dump a multiline representation of this object to FILE. */
144 call_summary::dump (const extrinsic_state
&ext_state
,
149 pp_format_decoder (&pp
) = default_tree_printer
;
150 pp_show_color (&pp
) = pp_show_color (global_dc
->printer
);
151 pp
.buffer
->stream
= fp
;
152 dump_to_pp (ext_state
, &pp
, simple
);
156 /* Dump a multiline representation of this object to stderr. */
159 call_summary::dump (const extrinsic_state
&ext_state
, bool simple
) const
161 dump (ext_state
, stderr
, simple
);
164 /* class call_summary_replay. */
166 /* call_summary_replay's ctor.
167 Populate the cache with params for the summary based on
168 arguments at the caller. */
170 call_summary_replay::call_summary_replay (const call_details
&cd
,
171 const function
&called_fn
,
172 call_summary
*summary
,
173 const extrinsic_state
&ext_state
)
176 m_ext_state (ext_state
)
178 region_model_manager
*mgr
= cd
.get_manager ();
180 // populate params based on args
181 tree fndecl
= called_fn
.decl
;
183 /* Get a frame_region for use with respect to the summary.
184 This will be a top-level frame, since that's what's in
186 const frame_region
*summary_frame
187 = mgr
->get_frame_region (NULL
, called_fn
);
190 for (tree iter_parm
= DECL_ARGUMENTS (fndecl
); iter_parm
;
191 iter_parm
= DECL_CHAIN (iter_parm
), ++idx
)
193 /* If there's a mismatching declaration, the call stmt might
194 not have enough args. Handle this case by leaving the
195 rest of the params as uninitialized. */
196 if (idx
>= cd
.num_args ())
198 const svalue
*caller_arg_sval
= cd
.get_arg_svalue (idx
);
199 tree parm_lval
= iter_parm
;
200 if (tree parm_default_ssa
= get_ssa_default_def (called_fn
, iter_parm
))
201 parm_lval
= parm_default_ssa
;
202 const region
*summary_parm_reg
203 = summary_frame
->get_region_for_local (mgr
, parm_lval
, cd
.get_ctxt ());
204 const svalue
*summary_initial_parm_reg
205 = mgr
->get_or_create_initial_value (summary_parm_reg
);
206 add_svalue_mapping (summary_initial_parm_reg
, caller_arg_sval
);
209 /* Handle any variadic args. */
210 unsigned va_arg_idx
= 0;
211 for (; idx
< cd
.num_args (); idx
++, va_arg_idx
++)
213 const svalue
*caller_arg_sval
= cd
.get_arg_svalue (idx
);
214 const region
*summary_var_arg_reg
215 = mgr
->get_var_arg_region (summary_frame
, va_arg_idx
);
216 const svalue
*summary_initial_var_arg_reg
217 = mgr
->get_or_create_initial_value (summary_var_arg_reg
);
218 add_svalue_mapping (summary_initial_var_arg_reg
, caller_arg_sval
);
222 /* Try to convert SUMMARY_SVAL in the summary to a corresponding svalue
223 in the caller, caching the result.
225 Return NULL if the conversion is not possible. */
228 call_summary_replay::convert_svalue_from_summary (const svalue
*summary_sval
)
230 gcc_assert (summary_sval
);
232 if (const svalue
**slot
233 = m_map_svalue_from_summary_to_caller
.get (summary_sval
))
236 const svalue
*caller_sval
= convert_svalue_from_summary_1 (summary_sval
);
239 add_svalue_mapping (summary_sval
, caller_sval
);
244 /* Implementation of call_summary_replay::convert_svalue_from_summary. */
247 call_summary_replay::convert_svalue_from_summary_1 (const svalue
*summary_sval
)
249 gcc_assert (summary_sval
);
251 switch (summary_sval
->get_kind ())
257 const region_svalue
*region_summary_sval
258 = as_a
<const region_svalue
*> (summary_sval
);
259 const region
*summary_reg
= region_summary_sval
->get_pointee ();
260 const region
*caller_reg
= convert_region_from_summary (summary_reg
);
263 region_model_manager
*mgr
= get_manager ();
264 const svalue
*caller_ptr
265 = mgr
->get_ptr_svalue (summary_sval
->get_type (),
282 const initial_svalue
*initial_summary_sval
283 = as_a
<const initial_svalue
*> (summary_sval
);
284 /* Params should already be in the cache, courtesy of the ctor. */
285 gcc_assert (!initial_summary_sval
->initial_value_of_param_p ());
287 /* Initial value of region within the summary is the value of the
288 region at the point of the call. */
289 const region
*summary_reg
= initial_summary_sval
->get_region ();
290 const region
*caller_reg
= convert_region_from_summary (summary_reg
);
293 const svalue
*caller_sval
294 = m_cd
.get_model ()->get_store_value (caller_reg
, m_cd
.get_ctxt ());
300 const unaryop_svalue
*unaryop_summary_sval
301 = as_a
<const unaryop_svalue
*> (summary_sval
);
302 const svalue
*summary_arg
= unaryop_summary_sval
->get_arg ();
303 const svalue
*caller_arg
= convert_svalue_from_summary (summary_arg
);
306 region_model_manager
*mgr
= get_manager ();
307 return mgr
->get_or_create_unaryop (summary_sval
->get_type (),
308 unaryop_summary_sval
->get_op (),
314 const binop_svalue
*binop_summary_sval
315 = as_a
<const binop_svalue
*> (summary_sval
);
316 const svalue
*summary_arg0
= binop_summary_sval
->get_arg0 ();
317 const svalue
*caller_arg0
= convert_svalue_from_summary (summary_arg0
);
320 const svalue
*summary_arg1
= binop_summary_sval
->get_arg1 ();
321 const svalue
*caller_arg1
= convert_svalue_from_summary (summary_arg1
);
324 region_model_manager
*mgr
= get_manager ();
325 return mgr
->get_or_create_binop (summary_sval
->get_type (),
326 binop_summary_sval
->get_op (),
333 const sub_svalue
*sub_summary_sval
334 = as_a
<const sub_svalue
*> (summary_sval
);
335 region_model_manager
*mgr
= get_manager ();
336 const svalue
*summary_parent_sval
= sub_summary_sval
->get_parent ();
337 if (!summary_parent_sval
)
339 const region
*summary_subregion
= sub_summary_sval
->get_subregion ();
340 if (!summary_subregion
)
342 return mgr
->get_or_create_sub_svalue (summary_sval
->get_type (),
349 const repeated_svalue
*repeated_summary_sval
350 = as_a
<const repeated_svalue
*> (summary_sval
);
351 const svalue
*summary_outer_size
352 = repeated_summary_sval
->get_outer_size ();
353 const svalue
*caller_outer_size
354 = convert_svalue_from_summary (summary_outer_size
);
355 if (!caller_outer_size
)
357 const svalue
*summary_inner_sval
358 = repeated_summary_sval
->get_inner_svalue ();
359 const svalue
*caller_inner_sval
360 = convert_svalue_from_summary (summary_inner_sval
);
361 if (!caller_inner_sval
)
363 region_model_manager
*mgr
= get_manager ();
364 return mgr
->get_or_create_repeated_svalue (summary_sval
->get_type (),
371 const bits_within_svalue
*bits_within_summary_sval
372 = as_a
<const bits_within_svalue
*> (summary_sval
);
373 const bit_range
&bits
= bits_within_summary_sval
->get_bits ();
374 const svalue
*summary_inner_sval
375 = bits_within_summary_sval
->get_inner_svalue ();
376 const svalue
*caller_inner_sval
377 = convert_svalue_from_summary (summary_inner_sval
);
378 if (!caller_inner_sval
)
380 region_model_manager
*mgr
= get_manager ();
381 return mgr
->get_or_create_bits_within (summary_sval
->get_type (),
388 const unmergeable_svalue
*unmergeable_summary_sval
389 = as_a
<const unmergeable_svalue
*> (summary_sval
);
390 const svalue
*summary_arg_sval
= unmergeable_summary_sval
->get_arg ();
391 const svalue
*caller_arg_sval
392 = convert_svalue_from_summary (summary_arg_sval
);
393 if (!caller_arg_sval
)
395 region_model_manager
*mgr
= get_manager ();
396 return mgr
->get_or_create_unmergeable (caller_arg_sval
);
401 const widening_svalue
*widening_summary_sval
402 = as_a
<const widening_svalue
*> (summary_sval
);
403 const function_point
&point
= widening_summary_sval
->get_point ();
404 const svalue
*summary_base_sval
405 = widening_summary_sval
->get_base_svalue ();
406 const svalue
*caller_base_sval
407 = convert_svalue_from_summary (summary_base_sval
);
408 if (!(caller_base_sval
409 && caller_base_sval
->can_have_associated_state_p ()))
411 const svalue
*summary_iter_sval
412 = widening_summary_sval
->get_iter_svalue ();
413 const svalue
*caller_iter_sval
414 = convert_svalue_from_summary (summary_iter_sval
);
415 if (!(caller_iter_sval
416 && caller_iter_sval
->can_have_associated_state_p ()))
418 region_model_manager
*mgr
= get_manager ();
419 return mgr
->get_or_create_widening_svalue
420 (summary_iter_sval
->get_type (),
428 const compound_svalue
*compound_summary_sval
429 = as_a
<const compound_svalue
*> (summary_sval
);
430 region_model_manager
*mgr
= get_manager ();
431 store_manager
*store_mgr
= mgr
->get_store_manager ();
432 binding_map caller_map
;
433 auto_vec
<const binding_key
*> summary_keys
;
434 for (auto kv
: *compound_summary_sval
)
435 summary_keys
.safe_push (kv
.first
);
436 summary_keys
.qsort (binding_key::cmp_ptrs
);
437 for (auto key
: summary_keys
)
439 gcc_assert (key
->concrete_p ());
440 /* No remapping is needed for concrete binding keys. */
442 const svalue
*bound_summary_sval
443 = compound_summary_sval
->get_map ().get (key
);
444 const svalue
*caller_sval
445 = convert_svalue_from_summary (bound_summary_sval
);
447 caller_sval
= mgr
->get_or_create_unknown_svalue (NULL_TREE
);
449 if (const compound_svalue
*inner_compound_sval
450 = caller_sval
->dyn_cast_compound_svalue ())
452 const concrete_binding
*outer_key
453 = as_a
<const concrete_binding
*> (key
);
454 for (auto inner_kv
: *inner_compound_sval
)
456 // These should already be mapped to the caller.
457 const binding_key
*inner_key
= inner_kv
.first
;
458 const svalue
*inner_sval
= inner_kv
.second
;
459 gcc_assert (inner_key
->concrete_p ());
460 const concrete_binding
*concrete_key
461 = as_a
<const concrete_binding
*> (inner_key
);
462 bit_offset_t effective_start
463 = (concrete_key
->get_start_bit_offset ()
464 + outer_key
->get_start_bit_offset ());
465 const concrete_binding
*effective_concrete_key
466 = store_mgr
->get_concrete_binding
468 concrete_key
->get_size_in_bits ());
469 caller_map
.put (effective_concrete_key
, inner_sval
);
473 caller_map
.put (key
, caller_sval
);
475 return mgr
->get_or_create_compound_svalue (summary_sval
->get_type (),
481 region_model_manager
*mgr
= get_manager ();
482 return mgr
->get_or_create_unknown_svalue (summary_sval
->get_type ());
487 const asm_output_svalue
*asm_output_summary_sval
488 = as_a
<const asm_output_svalue
*> (summary_sval
);
489 const char *asm_string
= asm_output_summary_sval
->get_asm_string ();
490 unsigned output_idx
= asm_output_summary_sval
->get_output_idx ();
491 unsigned num_inputs
= asm_output_summary_sval
->get_num_inputs ();
492 unsigned num_outputs
= asm_output_summary_sval
->get_num_outputs ();
493 auto_vec
<const svalue
*> inputs (num_inputs
);
494 for (unsigned idx
= 0; idx
< num_inputs
; idx
++)
496 const svalue
*summary_input
497 = asm_output_summary_sval
->get_input (idx
);
498 const svalue
*caller_input
499 = convert_svalue_from_summary (summary_input
);
502 inputs
.safe_push (caller_input
);
504 region_model_manager
*mgr
= get_manager ();
505 return mgr
->get_or_create_asm_output_svalue (summary_sval
->get_type (),
512 case SK_CONST_FN_RESULT
:
514 const const_fn_result_svalue
*const_fn_result_summary_sval
515 = as_a
<const const_fn_result_svalue
*> (summary_sval
);
516 tree fndecl
= const_fn_result_summary_sval
->get_fndecl ();
517 unsigned num_inputs
= const_fn_result_summary_sval
->get_num_inputs ();
518 auto_vec
<const svalue
*> inputs (num_inputs
);
519 for (unsigned idx
= 0; idx
< num_inputs
; idx
++)
521 const svalue
*summary_input
522 = const_fn_result_summary_sval
->get_input (idx
);
523 const svalue
*caller_input
524 = convert_svalue_from_summary (summary_input
);
527 inputs
.safe_push (caller_input
);
529 region_model_manager
*mgr
= get_manager ();
530 return mgr
->get_or_create_const_fn_result_svalue
531 (summary_sval
->get_type (),
539 /* Try to convert SUMMARY_REG in the summary to a corresponding region
540 in the caller, caching the result.
542 Return NULL if the conversion is not possible. */
545 call_summary_replay::convert_region_from_summary (const region
*summary_reg
)
547 gcc_assert (summary_reg
);
549 if (const region
**slot
550 = m_map_region_from_summary_to_caller
.get (summary_reg
))
553 const region
*caller_reg
= convert_region_from_summary_1 (summary_reg
);
556 add_region_mapping (summary_reg
, caller_reg
);
561 /* Implementation of call_summary_replay::convert_region_from_summary. */
564 call_summary_replay::convert_region_from_summary_1 (const region
*summary_reg
)
566 gcc_assert (summary_reg
);
568 region_model_manager
*mgr
= get_manager ();
569 switch (summary_reg
->get_kind ())
573 /* Top-level regions. */
579 case RK_THREAD_LOCAL
:
581 /* These should never be pointed to by a region_svalue. */
590 /* We can reuse these regions directly. */
595 const symbolic_region
*summary_symbolic_reg
596 = as_a
<const symbolic_region
*> (summary_reg
);
597 const svalue
*summary_ptr_sval
= summary_symbolic_reg
->get_pointer ();
598 const svalue
*caller_ptr_sval
599 = convert_svalue_from_summary (summary_ptr_sval
);
600 if (!caller_ptr_sval
)
602 const region
*caller_reg
603 = get_caller_model ()->deref_rvalue (caller_ptr_sval
,
612 const decl_region
*summary_decl_reg
613 = as_a
<const decl_region
*> (summary_reg
);
614 tree decl
= summary_decl_reg
->get_decl ();
615 switch (TREE_CODE (decl
))
620 /* We don't care about writes to locals within
624 /* We don't care about writes to locals within
626 if (is_global_var (decl
))
627 /* If it's a global, we can reuse the region directly. */
630 /* Otherwise, we don't care about locals. */
633 return m_cd
.get_lhs_region ();
635 /* Writes (by value) to parms should be visible to the caller. */
642 const field_region
*summary_field_reg
643 = as_a
<const field_region
*> (summary_reg
);
644 const region
*summary_parent_reg
= summary_reg
->get_parent_region ();
645 const region
*caller_parent_reg
646 = convert_region_from_summary (summary_parent_reg
);
647 if (!caller_parent_reg
)
649 tree field
= summary_field_reg
->get_field ();
650 return mgr
->get_field_region (caller_parent_reg
, field
);
655 const element_region
*summary_element_reg
656 = as_a
<const element_region
*> (summary_reg
);
657 const region
*summary_parent_reg
= summary_reg
->get_parent_region ();
658 const region
*caller_parent_reg
659 = convert_region_from_summary (summary_parent_reg
);
660 if (!caller_parent_reg
)
662 const svalue
*summary_index
= summary_element_reg
->get_index ();
663 const svalue
*caller_index
664 = convert_svalue_from_summary (summary_index
);
667 return mgr
->get_element_region (caller_parent_reg
,
668 summary_reg
->get_type (),
674 const offset_region
*summary_offset_reg
675 = as_a
<const offset_region
*> (summary_reg
);
676 const region
*summary_parent_reg
= summary_reg
->get_parent_region ();
677 const region
*caller_parent_reg
678 = convert_region_from_summary (summary_parent_reg
);
679 if (!caller_parent_reg
)
681 const svalue
*summary_byte_offset
682 = summary_offset_reg
->get_byte_offset ();
683 const svalue
*caller_byte_offset
684 = convert_svalue_from_summary (summary_byte_offset
);
685 if (!caller_byte_offset
)
687 return mgr
->get_offset_region (caller_parent_reg
,
688 summary_reg
->get_type (),
694 const sized_region
*summary_sized_reg
695 = as_a
<const sized_region
*> (summary_reg
);
696 const region
*summary_parent_reg
= summary_reg
->get_parent_region ();
697 const region
*caller_parent_reg
698 = convert_region_from_summary (summary_parent_reg
);
699 if (!caller_parent_reg
)
701 const svalue
*summary_byte_size
702 = summary_sized_reg
->get_byte_size_sval (mgr
);
703 const svalue
*caller_byte_size
704 = convert_svalue_from_summary (summary_byte_size
);
705 if (!caller_byte_size
)
707 return mgr
->get_sized_region (caller_parent_reg
,
708 summary_reg
->get_type (),
714 const cast_region
*summary_cast_reg
715 = as_a
<const cast_region
*> (summary_reg
);
716 const region
*summary_original_reg
717 = summary_cast_reg
->get_original_region ();
718 const region
*caller_original_reg
719 = convert_region_from_summary (summary_original_reg
);
720 if (!caller_original_reg
)
722 return mgr
->get_cast_region (caller_original_reg
,
723 summary_reg
->get_type ());
726 case RK_HEAP_ALLOCATED
:
728 /* If we have a heap-allocated region in the summary, then
729 it was allocated within the callee.
730 Create a new heap-allocated region to summarize this. */
731 auto_bitmap heap_regs_in_use
;
732 get_caller_model ()->get_referenced_base_regions (heap_regs_in_use
);
733 return mgr
->get_or_create_region_for_heap_alloc (heap_regs_in_use
);
740 const bit_range_region
*summary_bit_range_reg
741 = as_a
<const bit_range_region
*> (summary_reg
);
742 const region
*summary_parent_reg
= summary_reg
->get_parent_region ();
743 const region
*caller_parent_reg
744 = convert_region_from_summary (summary_parent_reg
);
745 if (!caller_parent_reg
)
747 const bit_range
&bits
= summary_bit_range_reg
->get_bits ();
748 return mgr
->get_bit_range (caller_parent_reg
,
749 summary_reg
->get_type (),
758 /* Try to convert SUMMARY_KEY in the summary to a corresponding binding key
761 Return NULL if the conversion is not possible. */
764 call_summary_replay::convert_key_from_summary (const binding_key
*summary_key
)
766 if (summary_key
->concrete_p ())
769 const symbolic_binding
*symbolic_key
= (const symbolic_binding
*)summary_key
;
770 const region
*summary_reg
= symbolic_key
->get_region ();
771 const region
*caller_reg
= convert_region_from_summary (summary_reg
);
774 region_model_manager
*mgr
= get_manager ();
775 store_manager
*store_mgr
= mgr
->get_store_manager ();
776 return store_mgr
->get_symbolic_binding (caller_reg
);
779 /* Record that SUMMARY_SVAL maps to CALLER_SVAL for this replay. */
782 call_summary_replay::add_svalue_mapping (const svalue
*summary_sval
,
783 const svalue
*caller_sval
)
785 gcc_assert (summary_sval
);
786 // CALLER_SVAL can be NULL
787 m_map_svalue_from_summary_to_caller
.put (summary_sval
, caller_sval
);
790 /* Record that SUMMARY_REG maps to CALLER_REG for this replay. */
793 call_summary_replay::add_region_mapping (const region
*summary_reg
,
794 const region
*caller_reg
)
796 gcc_assert (summary_reg
);
797 // CALLER_REG can be NULL
798 m_map_region_from_summary_to_caller
.put (summary_reg
, caller_reg
);
801 /* Dump a multiline representation of this object to PP. */
804 call_summary_replay::dump_to_pp (pretty_printer
*pp
, bool simple
) const
807 pp_string (pp
, "CALL DETAILS:");
809 m_cd
.dump_to_pp (pp
, simple
);
812 pp_string (pp
, "CALLEE SUMMARY:");
814 m_summary
->dump_to_pp (m_ext_state
, pp
, simple
);
816 /* Current state of caller (could be in mid-update). */
818 pp_string (pp
, "CALLER:");
820 m_cd
.get_model ()->dump_to_pp (pp
, simple
, true);
823 pp_string (pp
, "REPLAY STATE:");
825 pp_string (pp
, "svalue mappings from summary to caller:");
827 auto_vec
<const svalue
*> summary_svals
;
828 for (auto kv
: m_map_svalue_from_summary_to_caller
)
829 summary_svals
.safe_push (kv
.first
);
830 summary_svals
.qsort (svalue::cmp_ptr_ptr
);
831 for (auto summary_sval
: summary_svals
)
833 pp_string (pp
, "sval in summary: ");
834 summary_sval
->dump_to_pp (pp
, simple
);
837 const svalue
*caller_sval
838 = *((const_cast<svalue_map_t
&>
839 (m_map_svalue_from_summary_to_caller
)).get (summary_sval
));
840 pp_string (pp
, " sval in caller: ");
841 caller_sval
->dump_to_pp (pp
, simple
);
846 pp_string (pp
, "region mappings from summary to caller:");
848 auto_vec
<const region
*> summary_regs
;
849 for (auto kv
: m_map_region_from_summary_to_caller
)
850 summary_regs
.safe_push (kv
.first
);
851 summary_regs
.qsort (region::cmp_ptr_ptr
);
852 for (auto summary_reg
: summary_regs
)
854 pp_string (pp
, "reg in summary: ");
856 summary_reg
->dump_to_pp (pp
, simple
);
858 pp_string (pp
, "(null)");
861 const region
*caller_reg
862 = *((const_cast<region_map_t
&>
863 (m_map_region_from_summary_to_caller
)).get (summary_reg
));
864 pp_string (pp
, " reg in caller: ");
866 caller_reg
->dump_to_pp (pp
, simple
);
868 pp_string (pp
, "(null)");
873 /* Dump a multiline representation of this object to FILE. */
876 call_summary_replay::dump (FILE *fp
, bool simple
) const
879 pp_format_decoder (&pp
) = default_tree_printer
;
880 pp_show_color (&pp
) = pp_show_color (global_dc
->printer
);
881 pp
.buffer
->stream
= fp
;
882 dump_to_pp (&pp
, simple
);
886 /* Dump a multiline representation of this object to stderr. */
889 call_summary_replay::dump (bool simple
) const
891 dump (stderr
, simple
);
896 #endif /* #if ENABLE_ANALYZER */