d: Merge upstream dmd, druntime 2bbf64907c, phobos b64bfbf91
[official-gcc.git] / gcc / analyzer / call-summary.cc
blobecb6fb13c9eceed0ecf0ce37c6d921fa60b3a2de
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 #include "system.h"
23 #include "coretypes.h"
24 #include "tree.h"
25 #include "tree-dfa.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"
33 #if ENABLE_ANALYZER
35 namespace ana {
37 /* class call_summary. */
39 const program_state &
40 call_summary::get_state () const
42 return m_enode->get_state ();
45 tree
46 call_summary::get_fndecl () const
48 return m_enode->get_point ().get_fndecl ();
51 label_text
52 call_summary::get_desc () const
54 pretty_printer pp;
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
66 summaries.
67 This will help with debugging, too. */
69 void
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 ())
86 default:
87 break;
88 case SK_REGION:
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 ())
95 default:
96 break;
97 case RK_HEAP_ALLOCATED:
98 pp_printf (pp,
99 "when %qE returns pointer"
100 " to heap-allocated buffer",
101 fndecl);
102 return;
105 break;
106 case SK_CONSTANT:
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))
112 && zerop (cst))
113 pp_printf (pp, "when %qE returns NULL", fndecl);
114 else
115 pp_printf (pp, "when %qE returns %qE", fndecl, cst);
116 return;
122 /* Fallback. */
123 pp_printf (pp, "when %qE returns", fndecl);
126 /* Dump a multiline representation of this object to PP. */
128 void
129 call_summary::dump_to_pp (const extrinsic_state &ext_state,
130 pretty_printer *pp,
131 bool simple) const
133 label_text desc = get_desc ();
134 pp_printf (pp, "desc: %qs", desc.get ());
135 pp_newline (pp);
137 get_state ().dump_to_pp (ext_state, simple, true, pp);
140 /* Dump a multiline representation of this object to FILE. */
142 void
143 call_summary::dump (const extrinsic_state &ext_state,
144 FILE *fp,
145 bool simple) const
147 pretty_printer pp;
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);
152 pp_flush (&pp);
155 /* Dump a multiline representation of this object to stderr. */
157 DEBUG_FUNCTION void
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,
170 function *called_fn,
171 call_summary *summary,
172 const extrinsic_state &ext_state)
173 : m_cd (cd),
174 m_summary (summary),
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
184 the summary. */
185 const frame_region *summary_frame
186 = mgr->get_frame_region (NULL, called_fn);
188 unsigned idx = 0;
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 ())
196 break;
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. */
226 const svalue *
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))
233 return *slot;
235 const svalue *caller_sval = convert_svalue_from_summary_1 (summary_sval);
237 /* Add to cache. */
238 add_svalue_mapping (summary_sval, caller_sval);
240 return caller_sval;
243 /* Implementation of call_summary_replay::convert_svalue_from_summary. */
245 const svalue *
246 call_summary_replay::convert_svalue_from_summary_1 (const svalue *summary_sval)
248 gcc_assert (summary_sval);
250 switch (summary_sval->get_kind ())
252 default:
253 gcc_unreachable ();
254 case SK_REGION:
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);
260 if (!caller_reg)
261 return NULL;
262 region_model_manager *mgr = get_manager ();
263 const svalue *caller_ptr
264 = mgr->get_ptr_svalue (summary_sval->get_type (),
265 caller_reg);
266 return caller_ptr;
268 break;
270 case SK_CONSTANT:
271 case SK_PLACEHOLDER:
272 case SK_POISONED:
273 case SK_UNKNOWN:
274 return summary_sval;
276 case SK_SETJMP:
277 return NULL; // TODO
279 case SK_INITIAL:
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);
290 if (!caller_reg)
291 return NULL;
292 const svalue *caller_sval
293 = m_cd.get_model ()->get_store_value (caller_reg, m_cd.get_ctxt ());
294 return caller_sval;
296 break;
297 case SK_UNARYOP:
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);
303 if (!caller_arg)
304 return NULL;
305 region_model_manager *mgr = get_manager ();
306 return mgr->get_or_create_unaryop (summary_sval->get_type (),
307 unaryop_summary_sval->get_op (),
308 caller_arg);
310 break;
311 case SK_BINOP:
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);
317 if (!caller_arg0)
318 return NULL;
319 const svalue *summary_arg1 = binop_summary_sval->get_arg1 ();
320 const svalue *caller_arg1 = convert_svalue_from_summary (summary_arg1);
321 if (!caller_arg1)
322 return NULL;
323 region_model_manager *mgr = get_manager ();
324 return mgr->get_or_create_binop (summary_sval->get_type (),
325 binop_summary_sval->get_op (),
326 caller_arg0,
327 caller_arg1);
329 break;
330 case SK_SUB:
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)
337 return NULL;
338 const region *summary_subregion = sub_summary_sval->get_subregion ();
339 if (!summary_subregion)
340 return NULL;
341 return mgr->get_or_create_sub_svalue (summary_sval->get_type (),
342 summary_parent_sval,
343 summary_subregion);
345 break;
346 case SK_REPEATED:
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)
355 return NULL;
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)
361 return NULL;
362 region_model_manager *mgr = get_manager ();
363 return mgr->get_or_create_repeated_svalue (summary_sval->get_type (),
364 caller_outer_size,
365 caller_inner_sval);
367 break;
368 case SK_BITS_WITHIN:
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)
378 return NULL;
379 region_model_manager *mgr = get_manager ();
380 return mgr->get_or_create_bits_within (summary_sval->get_type (),
381 bits,
382 caller_inner_sval);
384 break;
385 case SK_UNMERGEABLE:
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)
393 return NULL;
394 region_model_manager *mgr = get_manager ();
395 return mgr->get_or_create_unmergeable (caller_arg_sval);
397 break;
398 case SK_WIDENING:
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 ()))
409 return NULL;
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 ()))
416 return NULL;
417 region_model_manager *mgr = get_manager ();
418 return mgr->get_or_create_widening_svalue
419 (summary_iter_sval->get_type (),
420 point,
421 caller_base_sval,
422 caller_iter_sval);
424 break;
425 case SK_COMPOUND:
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);
445 if (!caller_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
466 (effective_start,
467 concrete_key->get_size_in_bits ());
468 caller_map.put (effective_concrete_key, inner_sval);
471 else
472 caller_map.put (key, caller_sval);
474 return mgr->get_or_create_compound_svalue (summary_sval->get_type (),
475 caller_map);
477 break;
478 case SK_CONJURED:
480 region_model_manager *mgr = get_manager ();
481 return mgr->get_or_create_unknown_svalue (summary_sval->get_type ());
483 break;
484 case SK_ASM_OUTPUT:
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);
499 if (!caller_input)
500 return NULL;
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 (),
505 asm_string,
506 output_idx,
507 num_outputs,
508 inputs);
510 break;
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);
524 if (!caller_input)
525 return NULL;
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 (),
531 fndecl,
532 inputs);
534 break;
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. */
543 const region *
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))
550 return *slot;
552 const region *caller_reg = convert_region_from_summary_1 (summary_reg);
554 /* Add to cache. */
555 add_region_mapping (summary_reg, caller_reg);
557 return caller_reg;
560 /* Implementation of call_summary_replay::convert_region_from_summary. */
562 const region *
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 ())
570 default:
571 gcc_unreachable ();
572 /* Top-level regions. */
573 case RK_FRAME:
574 case RK_GLOBALS:
575 case RK_CODE:
576 case RK_STACK:
577 case RK_HEAP:
578 case RK_THREAD_LOCAL:
579 case RK_ROOT:
580 /* These should never be pointed to by a region_svalue. */
581 gcc_unreachable ();
583 case RK_FUNCTION:
584 case RK_LABEL:
585 case RK_STRING:
586 case RK_ERRNO:
587 case RK_UNKNOWN:
588 case RK_PRIVATE:
589 /* We can reuse these regions directly. */
590 return summary_reg;
592 case RK_SYMBOLIC:
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)
600 return NULL;
601 const region *caller_reg
602 = get_caller_model ()->deref_rvalue (caller_ptr_sval,
603 NULL_TREE,
604 get_ctxt ());
605 return caller_reg;
607 break;
609 case RK_DECL:
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))
616 default:
617 gcc_unreachable ();
618 case SSA_NAME:
619 /* We don't care about writes to locals within
620 the summary. */
621 return NULL;
622 case VAR_DECL:
623 /* We don't care about writes to locals within
624 the summary. */
625 if (is_global_var (decl))
626 /* If it's a global, we can reuse the region directly. */
627 return summary_reg;
628 else
629 /* Otherwise, we don't care about locals. */
630 return NULL;
631 case RESULT_DECL:
632 return m_cd.get_lhs_region ();
633 case PARM_DECL:
634 /* Writes (by value) to parms should be visible to the caller. */
635 return NULL;
638 break;
639 case RK_FIELD:
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)
647 return NULL;
648 tree field = summary_field_reg->get_field ();
649 return mgr->get_field_region (caller_parent_reg, field);
651 break;
652 case RK_ELEMENT:
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)
660 return NULL;
661 const svalue *summary_index = summary_element_reg->get_index ();
662 const svalue *caller_index
663 = convert_svalue_from_summary (summary_index);
664 if (!caller_index)
665 return NULL;
666 return mgr->get_element_region (caller_parent_reg,
667 summary_reg->get_type (),
668 caller_index);
670 break;
671 case RK_OFFSET:
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)
679 return NULL;
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)
685 return NULL;
686 return mgr->get_offset_region (caller_parent_reg,
687 summary_reg->get_type (),
688 caller_byte_offset);
690 break;
691 case RK_SIZED:
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)
699 return NULL;
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)
705 return NULL;
706 return mgr->get_sized_region (caller_parent_reg,
707 summary_reg->get_type (),
708 caller_byte_size);
710 break;
711 case RK_CAST:
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)
720 return NULL;
721 return mgr->get_cast_region (caller_original_reg,
722 summary_reg->get_type ());
724 break;
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);
734 break;
735 case RK_ALLOCA:
736 return NULL;
737 case RK_BIT_RANGE:
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)
745 return NULL;
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 (),
749 bits);
751 break;
752 case RK_VAR_ARG:
753 return NULL;
757 /* Try to convert SUMMARY_KEY in the summary to a corresponding binding key
758 in the caller.
760 Return NULL if the conversion is not possible. */
762 const binding_key *
763 call_summary_replay::convert_key_from_summary (const binding_key *summary_key)
765 if (summary_key->concrete_p ())
766 return summary_key;
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);
771 if (!caller_reg)
772 return NULL;
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. */
780 void
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. */
791 void
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. */
802 void
803 call_summary_replay::dump_to_pp (pretty_printer *pp, bool simple) const
805 pp_newline (pp);
806 pp_string (pp, "CALL DETAILS:");
807 pp_newline (pp);
808 m_cd.dump_to_pp (pp, simple);
810 pp_newline (pp);
811 pp_string (pp, "CALLEE SUMMARY:");
812 pp_newline (pp);
813 m_summary->dump_to_pp (m_ext_state, pp, simple);
815 /* Current state of caller (could be in mid-update). */
816 pp_newline (pp);
817 pp_string (pp, "CALLER:");
818 pp_newline (pp);
819 m_cd.get_model ()->dump_to_pp (pp, simple, true);
821 pp_newline (pp);
822 pp_string (pp, "REPLAY STATE:");
823 pp_newline (pp);
824 pp_string (pp, "svalue mappings from summary to caller:");
825 pp_newline (pp);
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);
834 pp_newline (pp);
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);
841 pp_newline (pp);
844 pp_newline (pp);
845 pp_string (pp, "region mappings from summary to caller:");
846 pp_newline (pp);
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: ");
854 if (summary_reg)
855 summary_reg->dump_to_pp (pp, simple);
856 else
857 pp_string (pp, "(null)");
858 pp_newline (pp);
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: ");
864 if (caller_reg)
865 caller_reg->dump_to_pp (pp, simple);
866 else
867 pp_string (pp, "(null)");
868 pp_newline (pp);
872 /* Dump a multiline representation of this object to FILE. */
874 void
875 call_summary_replay::dump (FILE *fp, bool simple) const
877 pretty_printer pp;
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);
882 pp_flush (&pp);
885 /* Dump a multiline representation of this object to stderr. */
887 DEBUG_FUNCTION void
888 call_summary_replay::dump (bool simple) const
890 dump (stderr, simple);
893 } // namespace ana
895 #endif /* #if ENABLE_ANALYZER */