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.h"
27 #include "tree-diagnostic.h"
28 #include "analyzer/analyzer.h"
29 #include "analyzer/region-model.h"
30 #include "analyzer/call-summary.h"
31 #include "analyzer/exploded-graph.h"
37 /* class call_summary. */
40 call_summary::get_state () const
42 return m_enode
->get_state ();
46 call_summary::get_fndecl () const
48 return m_enode
->get_point ().get_fndecl ();
52 call_summary::get_desc () const
55 pp_format_decoder (&pp
) = default_tree_printer
;
57 get_user_facing_desc (&pp
);
58 if (flag_analyzer_verbose_edges
)
59 pp_printf (&pp
, " (call summary; EN: %i)", m_enode
->m_index
);
61 return label_text::take (xstrdup (pp_formatted_text (&pp
)));
64 /* Generate a user-facing description of this call summary.c
65 This has various heuristics for distinguishing between different
67 This will help with debugging, too. */
70 call_summary::get_user_facing_desc (pretty_printer
*pp
) const
72 tree fndecl
= get_fndecl ();
74 /* If there are multiple summaries, try to use the return value to
75 distinguish between them. */
76 if (m_per_fn_data
->m_summaries
.length () > 1)
78 if (tree result
= DECL_RESULT (fndecl
))
80 const region
*result_reg
81 = get_state ().m_region_model
->get_lvalue (result
, NULL
);
82 const svalue
*result_sval
83 = get_state ().m_region_model
->get_store_value (result_reg
, NULL
);
84 switch (result_sval
->get_kind ())
90 const region_svalue
*region_sval
91 = as_a
<const region_svalue
*> (result_sval
);
92 const region
*pointee_reg
= region_sval
->get_pointee ();
93 switch (pointee_reg
->get_kind ())
97 case RK_HEAP_ALLOCATED
:
99 "when %qE returns pointer"
100 " to heap-allocated buffer",
108 const constant_svalue
*constant_sval
109 = as_a
<const constant_svalue
*> (result_sval
);
110 tree cst
= constant_sval
->get_constant ();
111 if (POINTER_TYPE_P (TREE_TYPE (result
))
113 pp_printf (pp
, "when %qE returns NULL", fndecl
);
115 pp_printf (pp
, "when %qE returns %qE", fndecl
, cst
);
123 pp_printf (pp
, "when %qE returns", fndecl
);
126 /* Dump a multiline representation of this object to PP. */
129 call_summary::dump_to_pp (const extrinsic_state
&ext_state
,
133 label_text desc
= get_desc ();
134 pp_printf (pp
, "desc: %qs", desc
.get ());
137 get_state ().dump_to_pp (ext_state
, simple
, true, pp
);
140 /* Dump a multiline representation of this object to FILE. */
143 call_summary::dump (const extrinsic_state
&ext_state
,
148 pp_format_decoder (&pp
) = default_tree_printer
;
149 pp_show_color (&pp
) = pp_show_color (global_dc
->printer
);
150 pp
.buffer
->stream
= fp
;
151 dump_to_pp (ext_state
, &pp
, simple
);
155 /* Dump a multiline representation of this object to stderr. */
158 call_summary::dump (const extrinsic_state
&ext_state
, bool simple
) const
160 dump (ext_state
, stderr
, simple
);
163 /* class call_summary_replay. */
165 /* call_summary_replay's ctor.
166 Populate the cache with params for the summary based on
167 arguments at the caller. */
169 call_summary_replay::call_summary_replay (const call_details
&cd
,
171 call_summary
*summary
,
172 const extrinsic_state
&ext_state
)
175 m_ext_state (ext_state
)
177 region_model_manager
*mgr
= cd
.get_manager ();
179 // populate params based on args
180 tree fndecl
= called_fn
->decl
;
182 /* Get a frame_region for use with respect to the summary.
183 This will be a top-level frame, since that's what's in
185 const frame_region
*summary_frame
186 = mgr
->get_frame_region (NULL
, called_fn
);
189 for (tree iter_parm
= DECL_ARGUMENTS (fndecl
); iter_parm
;
190 iter_parm
= DECL_CHAIN (iter_parm
), ++idx
)
192 /* If there's a mismatching declaration, the call stmt might
193 not have enough args. Handle this case by leaving the
194 rest of the params as uninitialized. */
195 if (idx
>= cd
.num_args ())
197 const svalue
*caller_arg_sval
= cd
.get_arg_svalue (idx
);
198 tree parm_lval
= iter_parm
;
199 if (tree parm_default_ssa
= ssa_default_def (called_fn
, iter_parm
))
200 parm_lval
= parm_default_ssa
;
201 const region
*summary_parm_reg
202 = summary_frame
->get_region_for_local (mgr
, parm_lval
, cd
.get_ctxt ());
203 const svalue
*summary_initial_parm_reg
204 = mgr
->get_or_create_initial_value (summary_parm_reg
);
205 add_svalue_mapping (summary_initial_parm_reg
, caller_arg_sval
);
208 /* Handle any variadic args. */
209 unsigned va_arg_idx
= 0;
210 for (; idx
< cd
.num_args (); idx
++, va_arg_idx
++)
212 const svalue
*caller_arg_sval
= cd
.get_arg_svalue (idx
);
213 const region
*summary_var_arg_reg
214 = mgr
->get_var_arg_region (summary_frame
, va_arg_idx
);
215 const svalue
*summary_initial_var_arg_reg
216 = mgr
->get_or_create_initial_value (summary_var_arg_reg
);
217 add_svalue_mapping (summary_initial_var_arg_reg
, caller_arg_sval
);
221 /* Try to convert SUMMARY_SVAL in the summary to a corresponding svalue
222 in the caller, caching the result.
224 Return NULL if the conversion is not possible. */
227 call_summary_replay::convert_svalue_from_summary (const svalue
*summary_sval
)
229 gcc_assert (summary_sval
);
231 if (const svalue
**slot
232 = m_map_svalue_from_summary_to_caller
.get (summary_sval
))
235 const svalue
*caller_sval
= convert_svalue_from_summary_1 (summary_sval
);
238 add_svalue_mapping (summary_sval
, caller_sval
);
243 /* Implementation of call_summary_replay::convert_svalue_from_summary. */
246 call_summary_replay::convert_svalue_from_summary_1 (const svalue
*summary_sval
)
248 gcc_assert (summary_sval
);
250 switch (summary_sval
->get_kind ())
256 const region_svalue
*region_summary_sval
257 = as_a
<const region_svalue
*> (summary_sval
);
258 const region
*summary_reg
= region_summary_sval
->get_pointee ();
259 const region
*caller_reg
= convert_region_from_summary (summary_reg
);
262 region_model_manager
*mgr
= get_manager ();
263 const svalue
*caller_ptr
264 = mgr
->get_ptr_svalue (summary_sval
->get_type (),
281 const initial_svalue
*initial_summary_sval
282 = as_a
<const initial_svalue
*> (summary_sval
);
283 /* Params should already be in the cache, courtesy of the ctor. */
284 gcc_assert (!initial_summary_sval
->initial_value_of_param_p ());
286 /* Initial value of region within the summary is the value of the
287 region at the point of the call. */
288 const region
*summary_reg
= initial_summary_sval
->get_region ();
289 const region
*caller_reg
= convert_region_from_summary (summary_reg
);
292 const svalue
*caller_sval
293 = m_cd
.get_model ()->get_store_value (caller_reg
, m_cd
.get_ctxt ());
299 const unaryop_svalue
*unaryop_summary_sval
300 = as_a
<const unaryop_svalue
*> (summary_sval
);
301 const svalue
*summary_arg
= unaryop_summary_sval
->get_arg ();
302 const svalue
*caller_arg
= convert_svalue_from_summary (summary_arg
);
305 region_model_manager
*mgr
= get_manager ();
306 return mgr
->get_or_create_unaryop (summary_sval
->get_type (),
307 unaryop_summary_sval
->get_op (),
313 const binop_svalue
*binop_summary_sval
314 = as_a
<const binop_svalue
*> (summary_sval
);
315 const svalue
*summary_arg0
= binop_summary_sval
->get_arg0 ();
316 const svalue
*caller_arg0
= convert_svalue_from_summary (summary_arg0
);
319 const svalue
*summary_arg1
= binop_summary_sval
->get_arg1 ();
320 const svalue
*caller_arg1
= convert_svalue_from_summary (summary_arg1
);
323 region_model_manager
*mgr
= get_manager ();
324 return mgr
->get_or_create_binop (summary_sval
->get_type (),
325 binop_summary_sval
->get_op (),
332 const sub_svalue
*sub_summary_sval
333 = as_a
<const sub_svalue
*> (summary_sval
);
334 region_model_manager
*mgr
= get_manager ();
335 const svalue
*summary_parent_sval
= sub_summary_sval
->get_parent ();
336 if (!summary_parent_sval
)
338 const region
*summary_subregion
= sub_summary_sval
->get_subregion ();
339 if (!summary_subregion
)
341 return mgr
->get_or_create_sub_svalue (summary_sval
->get_type (),
348 const repeated_svalue
*repeated_summary_sval
349 = as_a
<const repeated_svalue
*> (summary_sval
);
350 const svalue
*summary_outer_size
351 = repeated_summary_sval
->get_outer_size ();
352 const svalue
*caller_outer_size
353 = convert_svalue_from_summary (summary_outer_size
);
354 if (!caller_outer_size
)
356 const svalue
*summary_inner_sval
357 = repeated_summary_sval
->get_inner_svalue ();
358 const svalue
*caller_inner_sval
359 = convert_svalue_from_summary (summary_inner_sval
);
360 if (!caller_inner_sval
)
362 region_model_manager
*mgr
= get_manager ();
363 return mgr
->get_or_create_repeated_svalue (summary_sval
->get_type (),
370 const bits_within_svalue
*bits_within_summary_sval
371 = as_a
<const bits_within_svalue
*> (summary_sval
);
372 const bit_range
&bits
= bits_within_summary_sval
->get_bits ();
373 const svalue
*summary_inner_sval
374 = bits_within_summary_sval
->get_inner_svalue ();
375 const svalue
*caller_inner_sval
376 = convert_svalue_from_summary (summary_inner_sval
);
377 if (!caller_inner_sval
)
379 region_model_manager
*mgr
= get_manager ();
380 return mgr
->get_or_create_bits_within (summary_sval
->get_type (),
387 const unmergeable_svalue
*unmergeable_summary_sval
388 = as_a
<const unmergeable_svalue
*> (summary_sval
);
389 const svalue
*summary_arg_sval
= unmergeable_summary_sval
->get_arg ();
390 const svalue
*caller_arg_sval
391 = convert_svalue_from_summary (summary_arg_sval
);
392 if (!caller_arg_sval
)
394 region_model_manager
*mgr
= get_manager ();
395 return mgr
->get_or_create_unmergeable (caller_arg_sval
);
400 const widening_svalue
*widening_summary_sval
401 = as_a
<const widening_svalue
*> (summary_sval
);
402 const function_point
&point
= widening_summary_sval
->get_point ();
403 const svalue
*summary_base_sval
404 = widening_summary_sval
->get_base_svalue ();
405 const svalue
*caller_base_sval
406 = convert_svalue_from_summary (summary_base_sval
);
407 if (!(caller_base_sval
408 && caller_base_sval
->can_have_associated_state_p ()))
410 const svalue
*summary_iter_sval
411 = widening_summary_sval
->get_iter_svalue ();
412 const svalue
*caller_iter_sval
413 = convert_svalue_from_summary (summary_iter_sval
);
414 if (!(caller_iter_sval
415 && caller_iter_sval
->can_have_associated_state_p ()))
417 region_model_manager
*mgr
= get_manager ();
418 return mgr
->get_or_create_widening_svalue
419 (summary_iter_sval
->get_type (),
427 const compound_svalue
*compound_summary_sval
428 = as_a
<const compound_svalue
*> (summary_sval
);
429 region_model_manager
*mgr
= get_manager ();
430 store_manager
*store_mgr
= mgr
->get_store_manager ();
431 binding_map caller_map
;
432 auto_vec
<const binding_key
*> summary_keys
;
433 for (auto kv
: *compound_summary_sval
)
434 summary_keys
.safe_push (kv
.first
);
435 summary_keys
.qsort (binding_key::cmp_ptrs
);
436 for (auto key
: summary_keys
)
438 gcc_assert (key
->concrete_p ());
439 /* No remapping is needed for concrete binding keys. */
441 const svalue
*bound_summary_sval
442 = compound_summary_sval
->get_map ().get (key
);
443 const svalue
*caller_sval
444 = convert_svalue_from_summary (bound_summary_sval
);
446 caller_sval
= mgr
->get_or_create_unknown_svalue (NULL_TREE
);
448 if (const compound_svalue
*inner_compound_sval
449 = caller_sval
->dyn_cast_compound_svalue ())
451 const concrete_binding
*outer_key
452 = as_a
<const concrete_binding
*> (key
);
453 for (auto inner_kv
: *inner_compound_sval
)
455 // These should already be mapped to the caller.
456 const binding_key
*inner_key
= inner_kv
.first
;
457 const svalue
*inner_sval
= inner_kv
.second
;
458 gcc_assert (inner_key
->concrete_p ());
459 const concrete_binding
*concrete_key
460 = as_a
<const concrete_binding
*> (inner_key
);
461 bit_offset_t effective_start
462 = (concrete_key
->get_start_bit_offset ()
463 + outer_key
->get_start_bit_offset ());
464 const concrete_binding
*effective_concrete_key
465 = store_mgr
->get_concrete_binding
467 concrete_key
->get_size_in_bits ());
468 caller_map
.put (effective_concrete_key
, inner_sval
);
472 caller_map
.put (key
, caller_sval
);
474 return mgr
->get_or_create_compound_svalue (summary_sval
->get_type (),
480 region_model_manager
*mgr
= get_manager ();
481 return mgr
->get_or_create_unknown_svalue (summary_sval
->get_type ());
486 const asm_output_svalue
*asm_output_summary_sval
487 = as_a
<const asm_output_svalue
*> (summary_sval
);
488 const char *asm_string
= asm_output_summary_sval
->get_asm_string ();
489 unsigned output_idx
= asm_output_summary_sval
->get_output_idx ();
490 unsigned num_inputs
= asm_output_summary_sval
->get_num_inputs ();
491 unsigned num_outputs
= asm_output_summary_sval
->get_num_outputs ();
492 auto_vec
<const svalue
*> inputs (num_inputs
);
493 for (unsigned idx
= 0; idx
< num_inputs
; idx
++)
495 const svalue
*summary_input
496 = asm_output_summary_sval
->get_input (idx
);
497 const svalue
*caller_input
498 = convert_svalue_from_summary (summary_input
);
501 inputs
.safe_push (caller_input
);
503 region_model_manager
*mgr
= get_manager ();
504 return mgr
->get_or_create_asm_output_svalue (summary_sval
->get_type (),
511 case SK_CONST_FN_RESULT
:
513 const const_fn_result_svalue
*const_fn_result_summary_sval
514 = as_a
<const const_fn_result_svalue
*> (summary_sval
);
515 tree fndecl
= const_fn_result_summary_sval
->get_fndecl ();
516 unsigned num_inputs
= const_fn_result_summary_sval
->get_num_inputs ();
517 auto_vec
<const svalue
*> inputs (num_inputs
);
518 for (unsigned idx
= 0; idx
< num_inputs
; idx
++)
520 const svalue
*summary_input
521 = const_fn_result_summary_sval
->get_input (idx
);
522 const svalue
*caller_input
523 = convert_svalue_from_summary (summary_input
);
526 inputs
.safe_push (caller_input
);
528 region_model_manager
*mgr
= get_manager ();
529 return mgr
->get_or_create_const_fn_result_svalue
530 (summary_sval
->get_type (),
538 /* Try to convert SUMMARY_REG in the summary to a corresponding region
539 in the caller, caching the result.
541 Return NULL if the conversion is not possible. */
544 call_summary_replay::convert_region_from_summary (const region
*summary_reg
)
546 gcc_assert (summary_reg
);
548 if (const region
**slot
549 = m_map_region_from_summary_to_caller
.get (summary_reg
))
552 const region
*caller_reg
= convert_region_from_summary_1 (summary_reg
);
555 add_region_mapping (summary_reg
, caller_reg
);
560 /* Implementation of call_summary_replay::convert_region_from_summary. */
563 call_summary_replay::convert_region_from_summary_1 (const region
*summary_reg
)
565 gcc_assert (summary_reg
);
567 region_model_manager
*mgr
= get_manager ();
568 switch (summary_reg
->get_kind ())
572 /* Top-level regions. */
578 case RK_THREAD_LOCAL
:
580 /* These should never be pointed to by a region_svalue. */
589 /* We can reuse these regions directly. */
594 const symbolic_region
*summary_symbolic_reg
595 = as_a
<const symbolic_region
*> (summary_reg
);
596 const svalue
*summary_ptr_sval
= summary_symbolic_reg
->get_pointer ();
597 const svalue
*caller_ptr_sval
598 = convert_svalue_from_summary (summary_ptr_sval
);
599 if (!caller_ptr_sval
)
601 const region
*caller_reg
602 = get_caller_model ()->deref_rvalue (caller_ptr_sval
,
611 const decl_region
*summary_decl_reg
612 = as_a
<const decl_region
*> (summary_reg
);
613 tree decl
= summary_decl_reg
->get_decl ();
614 switch (TREE_CODE (decl
))
619 /* We don't care about writes to locals within
623 /* We don't care about writes to locals within
625 if (is_global_var (decl
))
626 /* If it's a global, we can reuse the region directly. */
629 /* Otherwise, we don't care about locals. */
632 return m_cd
.get_lhs_region ();
634 /* Writes (by value) to parms should be visible to the caller. */
641 const field_region
*summary_field_reg
642 = as_a
<const field_region
*> (summary_reg
);
643 const region
*summary_parent_reg
= summary_reg
->get_parent_region ();
644 const region
*caller_parent_reg
645 = convert_region_from_summary (summary_parent_reg
);
646 if (!caller_parent_reg
)
648 tree field
= summary_field_reg
->get_field ();
649 return mgr
->get_field_region (caller_parent_reg
, field
);
654 const element_region
*summary_element_reg
655 = as_a
<const element_region
*> (summary_reg
);
656 const region
*summary_parent_reg
= summary_reg
->get_parent_region ();
657 const region
*caller_parent_reg
658 = convert_region_from_summary (summary_parent_reg
);
659 if (!caller_parent_reg
)
661 const svalue
*summary_index
= summary_element_reg
->get_index ();
662 const svalue
*caller_index
663 = convert_svalue_from_summary (summary_index
);
666 return mgr
->get_element_region (caller_parent_reg
,
667 summary_reg
->get_type (),
673 const offset_region
*summary_offset_reg
674 = as_a
<const offset_region
*> (summary_reg
);
675 const region
*summary_parent_reg
= summary_reg
->get_parent_region ();
676 const region
*caller_parent_reg
677 = convert_region_from_summary (summary_parent_reg
);
678 if (!caller_parent_reg
)
680 const svalue
*summary_byte_offset
681 = summary_offset_reg
->get_byte_offset ();
682 const svalue
*caller_byte_offset
683 = convert_svalue_from_summary (summary_byte_offset
);
684 if (!caller_byte_offset
)
686 return mgr
->get_offset_region (caller_parent_reg
,
687 summary_reg
->get_type (),
693 const sized_region
*summary_sized_reg
694 = as_a
<const sized_region
*> (summary_reg
);
695 const region
*summary_parent_reg
= summary_reg
->get_parent_region ();
696 const region
*caller_parent_reg
697 = convert_region_from_summary (summary_parent_reg
);
698 if (!caller_parent_reg
)
700 const svalue
*summary_byte_size
701 = summary_sized_reg
->get_byte_size_sval (mgr
);
702 const svalue
*caller_byte_size
703 = convert_svalue_from_summary (summary_byte_size
);
704 if (!caller_byte_size
)
706 return mgr
->get_sized_region (caller_parent_reg
,
707 summary_reg
->get_type (),
713 const cast_region
*summary_cast_reg
714 = as_a
<const cast_region
*> (summary_reg
);
715 const region
*summary_original_reg
716 = summary_cast_reg
->get_original_region ();
717 const region
*caller_original_reg
718 = convert_region_from_summary (summary_original_reg
);
719 if (!caller_original_reg
)
721 return mgr
->get_cast_region (caller_original_reg
,
722 summary_reg
->get_type ());
725 case RK_HEAP_ALLOCATED
:
727 /* If we have a heap-allocated region in the summary, then
728 it was allocated within the callee.
729 Create a new heap-allocated region to summarize this. */
730 auto_bitmap heap_regs_in_use
;
731 get_caller_model ()->get_referenced_base_regions (heap_regs_in_use
);
732 return mgr
->get_or_create_region_for_heap_alloc (heap_regs_in_use
);
739 const bit_range_region
*summary_bit_range_reg
740 = as_a
<const bit_range_region
*> (summary_reg
);
741 const region
*summary_parent_reg
= summary_reg
->get_parent_region ();
742 const region
*caller_parent_reg
743 = convert_region_from_summary (summary_parent_reg
);
744 if (!caller_parent_reg
)
746 const bit_range
&bits
= summary_bit_range_reg
->get_bits ();
747 return mgr
->get_bit_range (caller_parent_reg
,
748 summary_reg
->get_type (),
757 /* Try to convert SUMMARY_KEY in the summary to a corresponding binding key
760 Return NULL if the conversion is not possible. */
763 call_summary_replay::convert_key_from_summary (const binding_key
*summary_key
)
765 if (summary_key
->concrete_p ())
768 const symbolic_binding
*symbolic_key
= (const symbolic_binding
*)summary_key
;
769 const region
*summary_reg
= symbolic_key
->get_region ();
770 const region
*caller_reg
= convert_region_from_summary (summary_reg
);
773 region_model_manager
*mgr
= get_manager ();
774 store_manager
*store_mgr
= mgr
->get_store_manager ();
775 return store_mgr
->get_symbolic_binding (caller_reg
);
778 /* Record that SUMMARY_SVAL maps to CALLER_SVAL for this replay. */
781 call_summary_replay::add_svalue_mapping (const svalue
*summary_sval
,
782 const svalue
*caller_sval
)
784 gcc_assert (summary_sval
);
785 // CALLER_SVAL can be NULL
786 m_map_svalue_from_summary_to_caller
.put (summary_sval
, caller_sval
);
789 /* Record that SUMMARY_REG maps to CALLER_REG for this replay. */
792 call_summary_replay::add_region_mapping (const region
*summary_reg
,
793 const region
*caller_reg
)
795 gcc_assert (summary_reg
);
796 // CALLER_REG can be NULL
797 m_map_region_from_summary_to_caller
.put (summary_reg
, caller_reg
);
800 /* Dump a multiline representation of this object to PP. */
803 call_summary_replay::dump_to_pp (pretty_printer
*pp
, bool simple
) const
806 pp_string (pp
, "CALL DETAILS:");
808 m_cd
.dump_to_pp (pp
, simple
);
811 pp_string (pp
, "CALLEE SUMMARY:");
813 m_summary
->dump_to_pp (m_ext_state
, pp
, simple
);
815 /* Current state of caller (could be in mid-update). */
817 pp_string (pp
, "CALLER:");
819 m_cd
.get_model ()->dump_to_pp (pp
, simple
, true);
822 pp_string (pp
, "REPLAY STATE:");
824 pp_string (pp
, "svalue mappings from summary to caller:");
826 auto_vec
<const svalue
*> summary_svals
;
827 for (auto kv
: m_map_svalue_from_summary_to_caller
)
828 summary_svals
.safe_push (kv
.first
);
829 summary_svals
.qsort (svalue::cmp_ptr_ptr
);
830 for (auto summary_sval
: summary_svals
)
832 pp_string (pp
, "sval in summary: ");
833 summary_sval
->dump_to_pp (pp
, simple
);
836 const svalue
*caller_sval
837 = *((const_cast<svalue_map_t
&>
838 (m_map_svalue_from_summary_to_caller
)).get (summary_sval
));
839 pp_string (pp
, " sval in caller: ");
840 caller_sval
->dump_to_pp (pp
, simple
);
845 pp_string (pp
, "region mappings from summary to caller:");
847 auto_vec
<const region
*> summary_regs
;
848 for (auto kv
: m_map_region_from_summary_to_caller
)
849 summary_regs
.safe_push (kv
.first
);
850 summary_regs
.qsort (region::cmp_ptr_ptr
);
851 for (auto summary_reg
: summary_regs
)
853 pp_string (pp
, "reg in summary: ");
855 summary_reg
->dump_to_pp (pp
, simple
);
857 pp_string (pp
, "(null)");
860 const region
*caller_reg
861 = *((const_cast<region_map_t
&>
862 (m_map_region_from_summary_to_caller
)).get (summary_reg
));
863 pp_string (pp
, " reg in caller: ");
865 caller_reg
->dump_to_pp (pp
, simple
);
867 pp_string (pp
, "(null)");
872 /* Dump a multiline representation of this object to FILE. */
875 call_summary_replay::dump (FILE *fp
, bool simple
) const
878 pp_format_decoder (&pp
) = default_tree_printer
;
879 pp_show_color (&pp
) = pp_show_color (global_dc
->printer
);
880 pp
.buffer
->stream
= fp
;
881 dump_to_pp (&pp
, simple
);
885 /* Dump a multiline representation of this object to stderr. */
888 call_summary_replay::dump (bool simple
) const
890 dump (stderr
, simple
);
895 #endif /* #if ENABLE_ANALYZER */