aix: Fix building fat library for AIX
[official-gcc.git] / gcc / analyzer / call-summary.cc
blobc2c9c71f79b49a1eacf196881c22ff5089d0b0f8
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-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"
34 #if ENABLE_ANALYZER
36 namespace ana {
38 /* class call_summary. */
40 const program_state &
41 call_summary::get_state () const
43 return m_enode->get_state ();
46 tree
47 call_summary::get_fndecl () const
49 return m_enode->get_point ().get_fndecl ();
52 label_text
53 call_summary::get_desc () const
55 pretty_printer pp;
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
67 summaries.
68 This will help with debugging, too. */
70 void
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 ())
87 default:
88 break;
89 case SK_REGION:
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 ())
96 default:
97 break;
98 case RK_HEAP_ALLOCATED:
99 pp_printf (pp,
100 "when %qE returns pointer"
101 " to heap-allocated buffer",
102 fndecl);
103 return;
106 break;
107 case SK_CONSTANT:
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))
113 && zerop (cst))
114 pp_printf (pp, "when %qE returns NULL", fndecl);
115 else
116 pp_printf (pp, "when %qE returns %qE", fndecl, cst);
117 return;
123 /* Fallback. */
124 pp_printf (pp, "when %qE returns", fndecl);
127 /* Dump a multiline representation of this object to PP. */
129 void
130 call_summary::dump_to_pp (const extrinsic_state &ext_state,
131 pretty_printer *pp,
132 bool simple) const
134 label_text desc = get_desc ();
135 pp_printf (pp, "desc: %qs", desc.get ());
136 pp_newline (pp);
138 get_state ().dump_to_pp (ext_state, simple, true, pp);
141 /* Dump a multiline representation of this object to FILE. */
143 void
144 call_summary::dump (const extrinsic_state &ext_state,
145 FILE *fp,
146 bool simple) const
148 pretty_printer pp;
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);
153 pp_flush (&pp);
156 /* Dump a multiline representation of this object to stderr. */
158 DEBUG_FUNCTION void
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)
174 : m_cd (cd),
175 m_summary (summary),
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
185 the summary. */
186 const frame_region *summary_frame
187 = mgr->get_frame_region (NULL, called_fn);
189 unsigned idx = 0;
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 ())
197 break;
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. */
227 const svalue *
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))
234 return *slot;
236 const svalue *caller_sval = convert_svalue_from_summary_1 (summary_sval);
238 if (caller_sval)
239 if (summary_sval->get_type () && caller_sval->get_type ())
240 gcc_assert (types_compatible_p (summary_sval->get_type (),
241 caller_sval->get_type ()));
243 /* Add to cache. */
244 add_svalue_mapping (summary_sval, caller_sval);
246 return caller_sval;
249 /* Implementation of call_summary_replay::convert_svalue_from_summary. */
251 const svalue *
252 call_summary_replay::convert_svalue_from_summary_1 (const svalue *summary_sval)
254 gcc_assert (summary_sval);
256 switch (summary_sval->get_kind ())
258 default:
259 gcc_unreachable ();
260 case SK_REGION:
262 const region_svalue *region_summary_sval
263 = as_a <const region_svalue *> (summary_sval);
264 const region *summary_reg = region_summary_sval->get_pointee ();
265 const region *caller_reg = convert_region_from_summary (summary_reg);
266 if (!caller_reg)
267 return NULL;
268 region_model_manager *mgr = get_manager ();
269 const svalue *caller_ptr
270 = mgr->get_ptr_svalue (summary_sval->get_type (),
271 caller_reg);
272 return caller_ptr;
274 break;
276 case SK_CONSTANT:
277 case SK_PLACEHOLDER:
278 case SK_POISONED:
279 case SK_UNKNOWN:
280 return summary_sval;
282 case SK_SETJMP:
283 return NULL; // TODO
285 case SK_INITIAL:
287 const initial_svalue *initial_summary_sval
288 = as_a <const initial_svalue *> (summary_sval);
289 /* Params should already be in the cache, courtesy of the ctor. */
290 gcc_assert (!initial_summary_sval->initial_value_of_param_p ());
292 /* Initial value of region within the summary is the value of the
293 region at the point of the call. */
294 const region *summary_reg = initial_summary_sval->get_region ();
295 const region *caller_reg = convert_region_from_summary (summary_reg);
296 if (!caller_reg)
297 return NULL;
298 const svalue *caller_sval
299 = m_cd.get_model ()->get_store_value (caller_reg, m_cd.get_ctxt ());
300 return caller_sval;
302 break;
303 case SK_UNARYOP:
305 const unaryop_svalue *unaryop_summary_sval
306 = as_a <const unaryop_svalue *> (summary_sval);
307 const svalue *summary_arg = unaryop_summary_sval->get_arg ();
308 const svalue *caller_arg = convert_svalue_from_summary (summary_arg);
309 if (!caller_arg)
310 return NULL;
311 region_model_manager *mgr = get_manager ();
312 return mgr->get_or_create_unaryop (summary_sval->get_type (),
313 unaryop_summary_sval->get_op (),
314 caller_arg);
316 break;
317 case SK_BINOP:
319 const binop_svalue *binop_summary_sval
320 = as_a <const binop_svalue *> (summary_sval);
321 const svalue *summary_arg0 = binop_summary_sval->get_arg0 ();
322 const svalue *caller_arg0 = convert_svalue_from_summary (summary_arg0);
323 if (!caller_arg0)
324 return NULL;
325 const svalue *summary_arg1 = binop_summary_sval->get_arg1 ();
326 const svalue *caller_arg1 = convert_svalue_from_summary (summary_arg1);
327 if (!caller_arg1)
328 return NULL;
329 region_model_manager *mgr = get_manager ();
330 return mgr->get_or_create_binop (summary_sval->get_type (),
331 binop_summary_sval->get_op (),
332 caller_arg0,
333 caller_arg1);
335 break;
336 case SK_SUB:
338 const sub_svalue *sub_summary_sval
339 = as_a <const sub_svalue *> (summary_sval);
340 region_model_manager *mgr = get_manager ();
341 const svalue *summary_parent_sval = sub_summary_sval->get_parent ();
342 if (!summary_parent_sval)
343 return NULL;
344 const region *summary_subregion = sub_summary_sval->get_subregion ();
345 if (!summary_subregion)
346 return NULL;
347 return mgr->get_or_create_sub_svalue (summary_sval->get_type (),
348 summary_parent_sval,
349 summary_subregion);
351 break;
352 case SK_REPEATED:
354 const repeated_svalue *repeated_summary_sval
355 = as_a <const repeated_svalue *> (summary_sval);
356 const svalue *summary_outer_size
357 = repeated_summary_sval->get_outer_size ();
358 const svalue *caller_outer_size
359 = convert_svalue_from_summary (summary_outer_size);
360 if (!caller_outer_size)
361 return NULL;
362 const svalue *summary_inner_sval
363 = repeated_summary_sval->get_inner_svalue ();
364 const svalue *caller_inner_sval
365 = convert_svalue_from_summary (summary_inner_sval);
366 if (!caller_inner_sval)
367 return NULL;
368 region_model_manager *mgr = get_manager ();
369 return mgr->get_or_create_repeated_svalue (summary_sval->get_type (),
370 caller_outer_size,
371 caller_inner_sval);
373 break;
374 case SK_BITS_WITHIN:
376 const bits_within_svalue *bits_within_summary_sval
377 = as_a <const bits_within_svalue *> (summary_sval);
378 const bit_range &bits = bits_within_summary_sval->get_bits ();
379 const svalue *summary_inner_sval
380 = bits_within_summary_sval->get_inner_svalue ();
381 const svalue *caller_inner_sval
382 = convert_svalue_from_summary (summary_inner_sval);
383 if (!caller_inner_sval)
384 return NULL;
385 region_model_manager *mgr = get_manager ();
386 return mgr->get_or_create_bits_within (summary_sval->get_type (),
387 bits,
388 caller_inner_sval);
390 break;
391 case SK_UNMERGEABLE:
393 const unmergeable_svalue *unmergeable_summary_sval
394 = as_a <const unmergeable_svalue *> (summary_sval);
395 const svalue *summary_arg_sval = unmergeable_summary_sval->get_arg ();
396 const svalue *caller_arg_sval
397 = convert_svalue_from_summary (summary_arg_sval);
398 if (!caller_arg_sval)
399 return NULL;
400 region_model_manager *mgr = get_manager ();
401 return mgr->get_or_create_unmergeable (caller_arg_sval);
403 break;
404 case SK_WIDENING:
406 const widening_svalue *widening_summary_sval
407 = as_a <const widening_svalue *> (summary_sval);
408 const function_point &point = widening_summary_sval->get_point ();
409 const svalue *summary_base_sval
410 = widening_summary_sval->get_base_svalue ();
411 const svalue *caller_base_sval
412 = convert_svalue_from_summary (summary_base_sval);
413 if (!(caller_base_sval
414 && caller_base_sval->can_have_associated_state_p ()))
415 return NULL;
416 const svalue *summary_iter_sval
417 = widening_summary_sval->get_iter_svalue ();
418 const svalue *caller_iter_sval
419 = convert_svalue_from_summary (summary_iter_sval);
420 if (!(caller_iter_sval
421 && caller_iter_sval->can_have_associated_state_p ()))
422 return NULL;
423 region_model_manager *mgr = get_manager ();
424 return mgr->get_or_create_widening_svalue
425 (summary_iter_sval->get_type (),
426 point,
427 caller_base_sval,
428 caller_iter_sval);
430 break;
431 case SK_COMPOUND:
433 const compound_svalue *compound_summary_sval
434 = as_a <const compound_svalue *> (summary_sval);
435 region_model_manager *mgr = get_manager ();
436 store_manager *store_mgr = mgr->get_store_manager ();
437 binding_map caller_map;
438 auto_vec <const binding_key *> summary_keys;
439 for (auto kv : *compound_summary_sval)
440 summary_keys.safe_push (kv.first);
441 summary_keys.qsort (binding_key::cmp_ptrs);
442 for (auto key : summary_keys)
444 gcc_assert (key->concrete_p ());
445 /* No remapping is needed for concrete binding keys. */
447 const svalue *bound_summary_sval
448 = compound_summary_sval->get_map ().get (key);
449 const svalue *caller_sval
450 = convert_svalue_from_summary (bound_summary_sval);
451 if (!caller_sval)
452 caller_sval = mgr->get_or_create_unknown_svalue (NULL_TREE);
454 if (const compound_svalue *inner_compound_sval
455 = caller_sval->dyn_cast_compound_svalue ())
457 const concrete_binding *outer_key
458 = as_a <const concrete_binding *> (key);
459 for (auto inner_kv : *inner_compound_sval)
461 // These should already be mapped to the caller.
462 const binding_key *inner_key = inner_kv.first;
463 const svalue *inner_sval = inner_kv.second;
464 gcc_assert (inner_key->concrete_p ());
465 const concrete_binding *concrete_key
466 = as_a <const concrete_binding *> (inner_key);
467 bit_offset_t effective_start
468 = (concrete_key->get_start_bit_offset ()
469 + outer_key->get_start_bit_offset ());
470 const concrete_binding *effective_concrete_key
471 = store_mgr->get_concrete_binding
472 (effective_start,
473 concrete_key->get_size_in_bits ());
474 caller_map.put (effective_concrete_key, inner_sval);
477 else
478 caller_map.put (key, caller_sval);
480 return mgr->get_or_create_compound_svalue (summary_sval->get_type (),
481 caller_map);
483 break;
484 case SK_CONJURED:
486 region_model_manager *mgr = get_manager ();
487 return mgr->get_or_create_unknown_svalue (summary_sval->get_type ());
489 break;
490 case SK_ASM_OUTPUT:
492 const asm_output_svalue *asm_output_summary_sval
493 = as_a <const asm_output_svalue *> (summary_sval);
494 const char *asm_string = asm_output_summary_sval->get_asm_string ();
495 unsigned output_idx = asm_output_summary_sval->get_output_idx ();
496 unsigned num_inputs = asm_output_summary_sval->get_num_inputs ();
497 unsigned num_outputs = asm_output_summary_sval->get_num_outputs ();
498 auto_vec<const svalue *> inputs (num_inputs);
499 for (unsigned idx = 0; idx < num_inputs; idx++)
501 const svalue *summary_input
502 = asm_output_summary_sval->get_input (idx);
503 const svalue *caller_input
504 = convert_svalue_from_summary (summary_input);
505 if (!caller_input)
506 return NULL;
507 inputs.safe_push (caller_input);
509 region_model_manager *mgr = get_manager ();
510 return mgr->get_or_create_asm_output_svalue (summary_sval->get_type (),
511 asm_string,
512 output_idx,
513 num_outputs,
514 inputs);
516 break;
517 case SK_CONST_FN_RESULT:
519 const const_fn_result_svalue *const_fn_result_summary_sval
520 = as_a <const const_fn_result_svalue *> (summary_sval);
521 tree fndecl = const_fn_result_summary_sval->get_fndecl ();
522 unsigned num_inputs = const_fn_result_summary_sval->get_num_inputs ();
523 auto_vec<const svalue *> inputs (num_inputs);
524 for (unsigned idx = 0; idx < num_inputs; idx++)
526 const svalue *summary_input
527 = const_fn_result_summary_sval->get_input (idx);
528 const svalue *caller_input
529 = convert_svalue_from_summary (summary_input);
530 if (!caller_input)
531 return NULL;
532 inputs.safe_push (caller_input);
534 region_model_manager *mgr = get_manager ();
535 return mgr->get_or_create_const_fn_result_svalue
536 (summary_sval->get_type (),
537 fndecl,
538 inputs);
540 break;
544 /* Try to convert SUMMARY_REG in the summary to a corresponding region
545 in the caller, caching the result.
547 Return NULL if the conversion is not possible. */
549 const region *
550 call_summary_replay::convert_region_from_summary (const region *summary_reg)
552 gcc_assert (summary_reg);
554 if (const region **slot
555 = m_map_region_from_summary_to_caller.get (summary_reg))
556 return *slot;
558 const region *caller_reg = convert_region_from_summary_1 (summary_reg);
560 if (caller_reg)
561 if (summary_reg->get_type () && caller_reg->get_type ())
562 gcc_assert (types_compatible_p (summary_reg->get_type (),
563 caller_reg->get_type ()));
565 /* Add to cache. */
566 add_region_mapping (summary_reg, caller_reg);
568 return caller_reg;
571 /* Implementation of call_summary_replay::convert_region_from_summary. */
573 const region *
574 call_summary_replay::convert_region_from_summary_1 (const region *summary_reg)
576 gcc_assert (summary_reg);
578 region_model_manager *mgr = get_manager ();
579 switch (summary_reg->get_kind ())
581 default:
582 gcc_unreachable ();
583 /* Top-level regions. */
584 case RK_FRAME:
585 case RK_GLOBALS:
586 case RK_CODE:
587 case RK_STACK:
588 case RK_HEAP:
589 case RK_THREAD_LOCAL:
590 case RK_ROOT:
591 /* These should never be pointed to by a region_svalue. */
592 gcc_unreachable ();
594 case RK_FUNCTION:
595 case RK_LABEL:
596 case RK_STRING:
597 case RK_ERRNO:
598 case RK_UNKNOWN:
599 case RK_PRIVATE:
600 /* We can reuse these regions directly. */
601 return summary_reg;
603 case RK_SYMBOLIC:
605 const symbolic_region *summary_symbolic_reg
606 = as_a <const symbolic_region *> (summary_reg);
607 const svalue *summary_ptr_sval = summary_symbolic_reg->get_pointer ();
608 const svalue *caller_ptr_sval
609 = convert_svalue_from_summary (summary_ptr_sval);
610 if (!caller_ptr_sval)
611 return NULL;
612 const region *caller_reg
613 = get_caller_model ()->deref_rvalue (caller_ptr_sval,
614 NULL_TREE,
615 get_ctxt ());
616 caller_reg = mgr->get_cast_region (caller_reg,
617 summary_reg->get_type ());
618 return caller_reg;
620 break;
622 case RK_DECL:
624 const decl_region *summary_decl_reg
625 = as_a <const decl_region *> (summary_reg);
626 tree decl = summary_decl_reg->get_decl ();
627 switch (TREE_CODE (decl))
629 default:
630 gcc_unreachable ();
631 case SSA_NAME:
632 /* We don't care about writes to locals within
633 the summary. */
634 return NULL;
635 case VAR_DECL:
636 /* We don't care about writes to locals within
637 the summary. */
638 if (is_global_var (decl))
639 /* If it's a global, we can reuse the region directly. */
640 return summary_reg;
641 else
642 /* Otherwise, we don't care about locals. */
643 return NULL;
644 case RESULT_DECL:
645 return m_cd.get_lhs_region ();
646 case PARM_DECL:
647 /* Writes (by value) to parms should be visible to the caller. */
648 return NULL;
651 break;
652 case RK_FIELD:
654 const field_region *summary_field_reg
655 = as_a <const field_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 tree field = summary_field_reg->get_field ();
662 return mgr->get_field_region (caller_parent_reg, field);
664 break;
665 case RK_ELEMENT:
667 const element_region *summary_element_reg
668 = as_a <const element_region *> (summary_reg);
669 const region *summary_parent_reg = summary_reg->get_parent_region ();
670 const region *caller_parent_reg
671 = convert_region_from_summary (summary_parent_reg);
672 if (!caller_parent_reg)
673 return NULL;
674 const svalue *summary_index = summary_element_reg->get_index ();
675 const svalue *caller_index
676 = convert_svalue_from_summary (summary_index);
677 if (!caller_index)
678 return NULL;
679 return mgr->get_element_region (caller_parent_reg,
680 summary_reg->get_type (),
681 caller_index);
683 break;
684 case RK_OFFSET:
686 const offset_region *summary_offset_reg
687 = as_a <const offset_region *> (summary_reg);
688 const region *summary_parent_reg = summary_reg->get_parent_region ();
689 const region *caller_parent_reg
690 = convert_region_from_summary (summary_parent_reg);
691 if (!caller_parent_reg)
692 return NULL;
693 const svalue *summary_byte_offset
694 = summary_offset_reg->get_byte_offset ();
695 const svalue *caller_byte_offset
696 = convert_svalue_from_summary (summary_byte_offset);
697 if (!caller_byte_offset)
698 return NULL;
699 return mgr->get_offset_region (caller_parent_reg,
700 summary_reg->get_type (),
701 caller_byte_offset);
703 break;
704 case RK_SIZED:
706 const sized_region *summary_sized_reg
707 = as_a <const sized_region *> (summary_reg);
708 const region *summary_parent_reg = summary_reg->get_parent_region ();
709 const region *caller_parent_reg
710 = convert_region_from_summary (summary_parent_reg);
711 if (!caller_parent_reg)
712 return NULL;
713 const svalue *summary_byte_size
714 = summary_sized_reg->get_byte_size_sval (mgr);
715 const svalue *caller_byte_size
716 = convert_svalue_from_summary (summary_byte_size);
717 if (!caller_byte_size)
718 return NULL;
719 return mgr->get_sized_region (caller_parent_reg,
720 summary_reg->get_type (),
721 caller_byte_size);
723 break;
724 case RK_CAST:
726 const cast_region *summary_cast_reg
727 = as_a <const cast_region *> (summary_reg);
728 const region *summary_original_reg
729 = summary_cast_reg->get_original_region ();
730 const region *caller_original_reg
731 = convert_region_from_summary (summary_original_reg);
732 if (!caller_original_reg)
733 return NULL;
734 return mgr->get_cast_region (caller_original_reg,
735 summary_reg->get_type ());
737 break;
738 case RK_HEAP_ALLOCATED:
740 /* If we have a heap-allocated region in the summary, then
741 it was allocated within the callee.
742 Create a new heap-allocated region to summarize this. */
743 auto_bitmap heap_regs_in_use;
744 get_caller_model ()->get_referenced_base_regions (heap_regs_in_use);
745 return mgr->get_or_create_region_for_heap_alloc (heap_regs_in_use);
747 break;
748 case RK_ALLOCA:
749 return NULL;
750 case RK_BIT_RANGE:
752 const bit_range_region *summary_bit_range_reg
753 = as_a <const bit_range_region *> (summary_reg);
754 const region *summary_parent_reg = summary_reg->get_parent_region ();
755 const region *caller_parent_reg
756 = convert_region_from_summary (summary_parent_reg);
757 if (!caller_parent_reg)
758 return NULL;
759 const bit_range &bits = summary_bit_range_reg->get_bits ();
760 return mgr->get_bit_range (caller_parent_reg,
761 summary_reg->get_type (),
762 bits);
764 break;
765 case RK_VAR_ARG:
766 return NULL;
770 /* Try to convert SUMMARY_KEY in the summary to a corresponding binding key
771 in the caller.
773 Return NULL if the conversion is not possible. */
775 const binding_key *
776 call_summary_replay::convert_key_from_summary (const binding_key *summary_key)
778 if (summary_key->concrete_p ())
779 return summary_key;
781 const symbolic_binding *symbolic_key = (const symbolic_binding *)summary_key;
782 const region *summary_reg = symbolic_key->get_region ();
783 const region *caller_reg = convert_region_from_summary (summary_reg);
784 if (!caller_reg)
785 return NULL;
786 region_model_manager *mgr = get_manager ();
787 store_manager *store_mgr = mgr->get_store_manager ();
788 return store_mgr->get_symbolic_binding (caller_reg);
791 /* Record that SUMMARY_SVAL maps to CALLER_SVAL for this replay. */
793 void
794 call_summary_replay::add_svalue_mapping (const svalue *summary_sval,
795 const svalue *caller_sval)
797 gcc_assert (summary_sval);
798 // CALLER_SVAL can be NULL
799 m_map_svalue_from_summary_to_caller.put (summary_sval, caller_sval);
802 /* Record that SUMMARY_REG maps to CALLER_REG for this replay. */
804 void
805 call_summary_replay::add_region_mapping (const region *summary_reg,
806 const region *caller_reg)
808 gcc_assert (summary_reg);
809 // CALLER_REG can be NULL
810 m_map_region_from_summary_to_caller.put (summary_reg, caller_reg);
813 /* Dump a multiline representation of this object to PP. */
815 void
816 call_summary_replay::dump_to_pp (pretty_printer *pp, bool simple) const
818 pp_newline (pp);
819 pp_string (pp, "CALL DETAILS:");
820 pp_newline (pp);
821 m_cd.dump_to_pp (pp, simple);
823 pp_newline (pp);
824 pp_string (pp, "CALLEE SUMMARY:");
825 pp_newline (pp);
826 m_summary->dump_to_pp (m_ext_state, pp, simple);
828 /* Current state of caller (could be in mid-update). */
829 pp_newline (pp);
830 pp_string (pp, "CALLER:");
831 pp_newline (pp);
832 m_cd.get_model ()->dump_to_pp (pp, simple, true);
834 pp_newline (pp);
835 pp_string (pp, "REPLAY STATE:");
836 pp_newline (pp);
837 pp_string (pp, "svalue mappings from summary to caller:");
838 pp_newline (pp);
839 auto_vec <const svalue *> summary_svals;
840 for (auto kv : m_map_svalue_from_summary_to_caller)
841 summary_svals.safe_push (kv.first);
842 summary_svals.qsort (svalue::cmp_ptr_ptr);
843 for (auto summary_sval : summary_svals)
845 pp_string (pp, "sval in summary: ");
846 summary_sval->dump_to_pp (pp, simple);
847 pp_newline (pp);
849 const svalue *caller_sval
850 = *((const_cast<svalue_map_t &>
851 (m_map_svalue_from_summary_to_caller)).get (summary_sval));
852 pp_string (pp, " sval in caller: ");
853 caller_sval->dump_to_pp (pp, simple);
854 pp_newline (pp);
857 pp_newline (pp);
858 pp_string (pp, "region mappings from summary to caller:");
859 pp_newline (pp);
860 auto_vec <const region *> summary_regs;
861 for (auto kv : m_map_region_from_summary_to_caller)
862 summary_regs.safe_push (kv.first);
863 summary_regs.qsort (region::cmp_ptr_ptr);
864 for (auto summary_reg : summary_regs)
866 pp_string (pp, "reg in summary: ");
867 if (summary_reg)
868 summary_reg->dump_to_pp (pp, simple);
869 else
870 pp_string (pp, "(null)");
871 pp_newline (pp);
873 const region *caller_reg
874 = *((const_cast<region_map_t &>
875 (m_map_region_from_summary_to_caller)).get (summary_reg));
876 pp_string (pp, " reg in caller: ");
877 if (caller_reg)
878 caller_reg->dump_to_pp (pp, simple);
879 else
880 pp_string (pp, "(null)");
881 pp_newline (pp);
885 /* Dump a multiline representation of this object to FILE. */
887 void
888 call_summary_replay::dump (FILE *fp, bool simple) const
890 pretty_printer pp;
891 pp_format_decoder (&pp) = default_tree_printer;
892 pp_show_color (&pp) = pp_show_color (global_dc->printer);
893 pp.buffer->stream = fp;
894 dump_to_pp (&pp, simple);
895 pp_flush (&pp);
898 /* Dump a multiline representation of this object to stderr. */
900 DEBUG_FUNCTION void
901 call_summary_replay::dump (bool simple) const
903 dump (stderr, simple);
906 } // namespace ana
908 #endif /* #if ENABLE_ANALYZER */