analyzer: add heuristics for switch on enum type [PR105273]
[platform/upstream/gcc.git] / gcc / analyzer / supergraph.cc
1 /* "Supergraph" classes that combine CFGs and callgraph into one digraph.
2    Copyright (C) 2019-2022 Free Software Foundation, Inc.
3    Contributed by David Malcolm <dmalcolm@redhat.com>.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published by
9 the Free Software Foundation; either version 3, or (at your option)
10 any later version.
11
12 GCC is distributed in the hope that it will be useful, but
13 WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with GCC; see the file COPYING3.  If not see
19 <http://www.gnu.org/licenses/>.  */
20
21 #include "config.h"
22 #define INCLUDE_MEMORY
23 #include "system.h"
24 #include "coretypes.h"
25 #include "tree.h"
26 #include "tm.h"
27 #include "toplev.h"
28 #include "hash-table.h"
29 #include "vec.h"
30 #include "ggc.h"
31 #include "basic-block.h"
32 #include "function.h"
33 #include "gimple.h"
34 #include "gimple-iterator.h"
35 #include "gimple-fold.h"
36 #include "tree-eh.h"
37 #include "gimple-expr.h"
38 #include "is-a.h"
39 #include "timevar.h"
40 #include "gimple-pretty-print.h"
41 #include "tree-pretty-print.h"
42 #include "graphviz.h"
43 #include "cgraph.h"
44 #include "tree-dfa.h"
45 #include "bitmap.h"
46 #include "cfganal.h"
47 #include "function.h"
48 #include "analyzer/analyzer.h"
49 #include "ordered-hash-map.h"
50 #include "options.h"
51 #include "cgraph.h"
52 #include "cfg.h"
53 #include "digraph.h"
54 #include "tree-cfg.h"
55 #include "analyzer/supergraph.h"
56 #include "analyzer/analyzer-logging.h"
57
58 #if ENABLE_ANALYZER
59
60 namespace ana {
61
62 /* Get the function of the ultimate alias target being called at EDGE,
63    if any.  */
64
65 function *
66 get_ultimate_function_for_cgraph_edge (cgraph_edge *edge)
67 {
68   cgraph_node *ultimate_node = edge->callee->ultimate_alias_target ();
69   if (!ultimate_node)
70     return NULL;
71   return ultimate_node->get_fun ();
72 }
73
74 /* Get the cgraph_edge, but only if there's an underlying function body.  */
75
76 cgraph_edge *
77 supergraph_call_edge (function *fun, const gimple *stmt)
78 {
79   const gcall *call = dyn_cast<const gcall *> (stmt);
80   if (!call)
81     return NULL;
82   cgraph_edge *edge
83     = cgraph_node::get (fun->decl)->get_edge (const_cast <gimple *> (stmt));
84   if (!edge)
85     return NULL;
86   if (!edge->callee)
87     return NULL; /* e.g. for a function pointer.  */
88   if (!get_ultimate_function_for_cgraph_edge (edge))
89     return NULL;
90   return edge;
91 }
92
93 /* class saved_uids.
94
95    In order to ensure consistent results without relying on the ordering
96    of pointer values we assign a uid to each gimple stmt, globally unique
97    across all functions.
98
99    Normally, the stmt uids are a scratch space that each pass can freely
100    assign its own values to.  However, in the case of LTO, the uids are
101    used to associate call stmts with callgraph edges between the WPA phase
102    (where the analyzer runs in LTO mode) and the LTRANS phase; if the
103    analyzer changes them in the WPA phase, it leads to errors when
104    streaming the code back in at LTRANS.
105    lto_prepare_function_for_streaming has code to renumber the stmt UIDs
106    when the code is streamed back out, but for some reason this isn't
107    called for clones.
108
109    Hence, as a workaround, this class has responsibility for tracking
110    the original uids and restoring them once the pass is complete
111    (in the supergraph dtor).  */
112
113 /* Give STMT a globally unique uid, storing its original uid so it can
114    later be restored.  */
115
116 void
117 saved_uids::make_uid_unique (gimple *stmt)
118 {
119   unsigned next_uid = m_old_stmt_uids.length ();
120   unsigned old_stmt_uid = stmt->uid;
121   stmt->uid = next_uid;
122   m_old_stmt_uids.safe_push
123     (std::pair<gimple *, unsigned> (stmt, old_stmt_uid));
124 }
125
126 /* Restore the saved uids of all stmts.  */
127
128 void
129 saved_uids::restore_uids () const
130 {
131   unsigned i;
132   std::pair<gimple *, unsigned> *pair;
133   FOR_EACH_VEC_ELT (m_old_stmt_uids, i, pair)
134     pair->first->uid = pair->second;
135 }
136
137 /* supergraph's ctor.  Walk the callgraph, building supernodes for each
138    CFG basic block, splitting the basic blocks at callsites.  Join
139    together the supernodes with interprocedural and intraprocedural
140    superedges as appropriate.
141    Assign UIDs to the gimple stmts.  */
142
143 supergraph::supergraph (logger *logger)
144 {
145   auto_timevar tv (TV_ANALYZER_SUPERGRAPH);
146
147   LOG_FUNC (logger);
148
149   /* First pass: make supernodes (and assign UIDs to the gimple stmts).  */
150   {
151     /* Sort the cgraph_nodes?  */
152     cgraph_node *node;
153     FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
154     {
155       function *fun = node->get_fun ();
156
157       /* Ensure that EDGE_DFS_BACK is correct for every CFG edge in
158          the supergraph (by doing it per-function).  */
159       auto_cfun sentinel (fun);
160       mark_dfs_back_edges ();
161
162       const int start_idx = m_nodes.length ();
163
164       basic_block bb;
165       FOR_ALL_BB_FN (bb, fun)
166         {
167           /* The initial supernode for the BB gets the phi nodes (if any).  */
168           supernode *node_for_stmts = add_node (fun, bb, NULL, phi_nodes (bb));
169           m_bb_to_initial_node.put (bb, node_for_stmts);
170           for (gphi_iterator gpi = gsi_start_phis (bb); !gsi_end_p (gpi);
171                gsi_next (&gpi))
172             {
173               gimple *stmt = gsi_stmt (gpi);
174               m_stmt_to_node_t.put (stmt, node_for_stmts);
175               m_stmt_uids.make_uid_unique (stmt);
176             }
177
178           /* Append statements from BB to the current supernode, splitting
179              them into a new supernode at each call site; such call statements
180              appear in both supernodes (representing call and return).  */
181           gimple_stmt_iterator gsi;
182           for (gsi = gsi_start_bb (bb); !gsi_end_p (gsi); gsi_next (&gsi))
183             {
184               gimple *stmt = gsi_stmt (gsi);
185               node_for_stmts->m_stmts.safe_push (stmt);
186               m_stmt_to_node_t.put (stmt, node_for_stmts);
187               m_stmt_uids.make_uid_unique (stmt);
188               if (cgraph_edge *edge = supergraph_call_edge (fun, stmt))
189                 {
190                   m_cgraph_edge_to_caller_prev_node.put(edge, node_for_stmts);
191                   node_for_stmts = add_node (fun, bb, as_a <gcall *> (stmt),
192                                              NULL);
193                   m_cgraph_edge_to_caller_next_node.put (edge, node_for_stmts);
194                 }
195                else
196                 {
197                   // maybe call is via a function pointer
198                   if (gcall *call = dyn_cast<gcall *> (stmt))
199                   {
200                     cgraph_edge *edge 
201                       = cgraph_node::get (fun->decl)->get_edge (stmt);
202                     if (!edge || !edge->callee)
203                     {
204                       supernode *old_node_for_stmts = node_for_stmts;
205                       node_for_stmts = add_node (fun, bb, call, NULL);
206
207                       superedge *sedge 
208                         = new callgraph_superedge (old_node_for_stmts,
209                                                    node_for_stmts,
210                                                    SUPEREDGE_INTRAPROCEDURAL_CALL,
211                                                    NULL);
212                       add_edge (sedge);
213                     }
214                   }
215                 }
216             }
217
218           m_bb_to_final_node.put (bb, node_for_stmts);
219         }
220
221       const unsigned num_snodes = m_nodes.length () - start_idx;
222       m_function_to_num_snodes.put (fun, num_snodes);
223
224       if (logger)
225         {
226           const int end_idx = m_nodes.length () - 1;
227           logger->log ("SN: %i...%i: function %qD",
228                        start_idx, end_idx, fun->decl);
229         }
230     }
231   }
232
233   /* Second pass: make superedges.  */
234   {
235     /* Make superedges for CFG edges.  */
236     for (bb_to_node_t::iterator iter = m_bb_to_final_node.begin ();
237          iter != m_bb_to_final_node.end ();
238          ++iter)
239       {
240         basic_block bb = (*iter).first;
241         supernode *src_supernode = (*iter).second;
242
243         ::edge cfg_edge;
244         int idx;
245         if (bb->succs)
246           FOR_EACH_VEC_ELT (*bb->succs, idx, cfg_edge)
247             {
248               basic_block dest_cfg_block = cfg_edge->dest;
249               supernode *dest_supernode
250                 = *m_bb_to_initial_node.get (dest_cfg_block);
251               cfg_superedge *cfg_sedge
252                 = add_cfg_edge (src_supernode, dest_supernode, cfg_edge);
253               m_cfg_edge_to_cfg_superedge.put (cfg_edge, cfg_sedge);
254             }
255       }
256
257     /* Make interprocedural superedges for calls.  */
258     {
259       for (cgraph_edge_to_node_t::iterator iter
260              = m_cgraph_edge_to_caller_prev_node.begin ();
261            iter != m_cgraph_edge_to_caller_prev_node.end ();
262            ++iter)
263         {
264           cgraph_edge *edge = (*iter).first;
265           supernode *caller_prev_supernode = (*iter).second;
266           function* callee_fn = get_ultimate_function_for_cgraph_edge (edge);
267           if (!callee_fn || !callee_fn->cfg)
268             continue;
269           basic_block callee_cfg_block = ENTRY_BLOCK_PTR_FOR_FN (callee_fn);
270           supernode *callee_supernode
271             = *m_bb_to_initial_node.get (callee_cfg_block);
272           call_superedge *sedge
273             = add_call_superedge (caller_prev_supernode,
274                                   callee_supernode,
275                                   edge);
276           m_cgraph_edge_to_call_superedge.put (edge, sedge);
277         }
278     }
279
280     /* Make interprocedural superedges for returns.  */
281     {
282       for (cgraph_edge_to_node_t::iterator iter
283              = m_cgraph_edge_to_caller_next_node.begin ();
284            iter != m_cgraph_edge_to_caller_next_node.end ();
285            ++iter)
286         {
287           cgraph_edge *edge = (*iter).first;
288           supernode *caller_next_supernode = (*iter).second;
289           function* callee_fn = get_ultimate_function_for_cgraph_edge (edge);
290           if (!callee_fn || !callee_fn->cfg)
291             continue;
292           basic_block callee_cfg_block = EXIT_BLOCK_PTR_FOR_FN (callee_fn);
293           supernode *callee_supernode
294             = *m_bb_to_initial_node.get (callee_cfg_block);
295           return_superedge *sedge
296             = add_return_superedge (callee_supernode,
297                                     caller_next_supernode,
298                                     edge);
299           m_cgraph_edge_to_return_superedge.put (edge, sedge);
300         }
301     }
302
303     /* Make intraprocedural superedges linking the two halves of a call.  */
304     {
305       for (cgraph_edge_to_node_t::iterator iter
306              = m_cgraph_edge_to_caller_prev_node.begin ();
307            iter != m_cgraph_edge_to_caller_prev_node.end ();
308            ++iter)
309         {
310           cgraph_edge *edge = (*iter).first;
311           supernode *caller_prev_supernode = (*iter).second;
312           supernode *caller_next_supernode
313             = *m_cgraph_edge_to_caller_next_node.get (edge);
314           superedge *sedge
315             = new callgraph_superedge (caller_prev_supernode,
316                                        caller_next_supernode,
317                                        SUPEREDGE_INTRAPROCEDURAL_CALL,
318                                        edge);
319           add_edge (sedge);
320           m_cgraph_edge_to_intraproc_superedge.put (edge, sedge);
321         }
322
323     }
324   }
325 }
326
327 /* supergraph's dtor.  Reset stmt uids.  */
328
329 supergraph::~supergraph ()
330 {
331   m_stmt_uids.restore_uids ();
332 }
333
334 /* Dump this graph in .dot format to PP, using DUMP_ARGS.
335    Cluster the supernodes by function, then by BB from original CFG.  */
336
337 void
338 supergraph::dump_dot_to_pp (pretty_printer *pp,
339                             const dump_args_t &dump_args) const
340 {
341   graphviz_out gv (pp);
342
343   pp_string (pp, "digraph \"");
344   pp_write_text_to_stream (pp);
345   pp_string (pp, "supergraph");
346   pp_write_text_as_dot_label_to_stream (pp, /*for_record=*/false);
347   pp_string (pp, "\" {\n");
348   gv.indent ();
349
350   gv.println ("overlap=false;");
351   gv.println ("compound=true;");
352
353   /* TODO: maybe (optionally) sub-subdivide by TU, for LTO; see also:
354      https://gcc-python-plugin.readthedocs.io/en/latest/_images/sample-supergraph.png
355   */
356
357   /* Break out the supernodes into clusters by function.  */
358   {
359     cgraph_node *node;
360     FOR_EACH_FUNCTION_WITH_GIMPLE_BODY (node)
361     {
362       function *fun = node->get_fun ();
363       const char *funcname = function_name (fun);
364       gv.println ("subgraph \"cluster_%s\" {",
365                   funcname);
366       gv.indent ();
367       pp_printf (pp,
368                  ("style=\"dashed\";"
369                   " color=\"black\";"
370                   " label=\"%s\";\n"),
371                  funcname);
372
373       /* Break out the nodes into clusters by BB from original CFG.  */
374       {
375         basic_block bb;
376         FOR_ALL_BB_FN (bb, fun)
377           {
378             if (dump_args.m_flags & SUPERGRAPH_DOT_SHOW_BBS)
379               {
380                 gv.println ("subgraph \"cluster_%s_bb_%i\" {",
381                             funcname, bb->index);
382                 gv.indent ();
383                 pp_printf (pp,
384                            ("style=\"dashed\";"
385                             " color=\"black\";"
386                             " label=\"bb: %i\";\n"),
387                            bb->index);
388               }
389
390             // TODO: maybe keep an index per-function/per-bb to speed this up???
391             int i;
392             supernode *n;
393             FOR_EACH_VEC_ELT (m_nodes, i, n)
394               if (n->m_fun == fun && n->m_bb == bb)
395                 n->dump_dot (&gv, dump_args);
396
397             if (dump_args.m_flags & SUPERGRAPH_DOT_SHOW_BBS)
398               {
399                 /* Terminate per-bb "subgraph" */
400                 gv.outdent ();
401                 gv.println ("}");
402               }
403           }
404       }
405
406       /* Add an invisible edge from ENTRY to EXIT, to improve the graph layout.  */
407       pp_string (pp, "\t");
408       get_node_for_function_entry (fun)->dump_dot_id (pp);
409       pp_string (pp, ":s -> ");
410       get_node_for_function_exit (fun)->dump_dot_id (pp);
411       pp_string (pp, ":n [style=\"invis\",constraint=true];\n");
412
413       /* Terminate per-function "subgraph" */
414       gv.outdent ();
415       gv.println ("}");
416     }
417   }
418
419   /* Superedges.  */
420   int i;
421   superedge *e;
422   FOR_EACH_VEC_ELT (m_edges, i, e)
423     e->dump_dot (&gv, dump_args);
424
425   /* Terminate "digraph" */
426   gv.outdent ();
427   gv.println ("}");
428 }
429
430 /* Dump this graph in .dot format to FP, using DUMP_ARGS.  */
431
432 void
433 supergraph::dump_dot_to_file (FILE *fp, const dump_args_t &dump_args) const
434 {
435   pretty_printer *pp = global_dc->printer->clone ();
436   pp_show_color (pp) = 0;
437   /* %qE in logs for SSA_NAMEs should show the ssa names, rather than
438      trying to prettify things by showing the underlying var.  */
439   pp_format_decoder (pp) = default_tree_printer;
440
441   pp->buffer->stream = fp;
442   dump_dot_to_pp (pp, dump_args);
443   pp_flush (pp);
444   delete pp;
445 }
446
447 /* Dump this graph in .dot format to PATH, using DUMP_ARGS.  */
448
449 void
450 supergraph::dump_dot (const char *path, const dump_args_t &dump_args) const
451 {
452   FILE *fp = fopen (path, "w");
453   dump_dot_to_file (fp, dump_args);
454   fclose (fp);
455 }
456
457 /* Return a new json::object of the form
458    {"nodes" : [objs for snodes],
459     "edges" : [objs for sedges]}.  */
460
461 json::object *
462 supergraph::to_json () const
463 {
464   json::object *sgraph_obj = new json::object ();
465
466   /* Nodes.  */
467   {
468     json::array *nodes_arr = new json::array ();
469     unsigned i;
470     supernode *n;
471     FOR_EACH_VEC_ELT (m_nodes, i, n)
472       nodes_arr->append (n->to_json ());
473     sgraph_obj->set ("nodes", nodes_arr);
474   }
475
476   /* Edges.  */
477   {
478     json::array *edges_arr = new json::array ();
479     unsigned i;
480     superedge *n;
481     FOR_EACH_VEC_ELT (m_edges, i, n)
482       edges_arr->append (n->to_json ());
483     sgraph_obj->set ("edges", edges_arr);
484   }
485
486   return sgraph_obj;
487 }
488
489 /* Create a supernode for BB within FUN and add it to this supergraph.
490
491    If RETURNING_CALL is non-NULL, the supernode represents the resumption
492    of the basic block after returning from that call.
493
494    If PHI_NODES is non-NULL, this is the initial supernode for the basic
495    block, and is responsible for any handling of the phi nodes.  */
496
497 supernode *
498 supergraph::add_node (function *fun, basic_block bb, gcall *returning_call,
499                       gimple_seq phi_nodes)
500 {
501   supernode *n = new supernode (fun, bb, returning_call, phi_nodes,
502                                 m_nodes.length ());
503   m_nodes.safe_push (n);
504   return n;
505 }
506
507 /* Create a new cfg_superedge from SRC to DEST for the underlying CFG edge E,
508    adding it to this supergraph.
509
510    If the edge is for a switch statement, create a switch_cfg_superedge
511    subclass.  */
512
513 cfg_superedge *
514 supergraph::add_cfg_edge (supernode *src, supernode *dest, ::edge e)
515 {
516   /* Special-case switch edges.  */
517   gimple *stmt = src->get_last_stmt ();
518   cfg_superedge *new_edge;
519   if (stmt && stmt->code == GIMPLE_SWITCH)
520     new_edge = new switch_cfg_superedge (src, dest, e);
521   else
522     new_edge = new cfg_superedge (src, dest, e);
523   add_edge (new_edge);
524   return new_edge;
525 }
526
527 /* Create and add a call_superedge representing an interprocedural call
528    from SRC to DEST, using CEDGE.  */
529
530 call_superedge *
531 supergraph::add_call_superedge (supernode *src, supernode *dest,
532                                 cgraph_edge *cedge)
533 {
534   call_superedge *new_edge = new call_superedge (src, dest, cedge);
535   add_edge (new_edge);
536   return new_edge;
537 }
538
539 /* Create and add a return_superedge representing returning from an
540    interprocedural call, returning from SRC to DEST, using CEDGE.  */
541
542 return_superedge *
543 supergraph::add_return_superedge (supernode *src, supernode *dest,
544                                   cgraph_edge *cedge)
545 {
546   return_superedge *new_edge = new return_superedge (src, dest, cedge);
547   add_edge (new_edge);
548   return new_edge;
549 }
550
551 /* Implementation of dnode::dump_dot vfunc for supernodes.
552
553    Write a cluster for the node, and within it a .dot node showing
554    the phi nodes and stmts.  Call into any node annotator from ARGS to
555    potentially add other records to the cluster.  */
556
557 void
558 supernode::dump_dot (graphviz_out *gv, const dump_args_t &args) const
559 {
560   gv->println ("subgraph cluster_node_%i {",
561                m_index);
562   gv->indent ();
563
564   gv->println("style=\"solid\";");
565   gv->println("color=\"black\";");
566   gv->println("fillcolor=\"lightgrey\";");
567   gv->println("label=\"sn: %i (bb: %i)\";", m_index, m_bb->index);
568
569   pretty_printer *pp = gv->get_pp ();
570
571   if (args.m_node_annotator)
572     args.m_node_annotator->add_node_annotations (gv, *this, false);
573
574   gv->write_indent ();
575   dump_dot_id (pp);
576   pp_printf (pp,
577              " [shape=none,margin=0,style=filled,fillcolor=%s,label=<",
578              "lightgrey");
579   pp_string (pp, "<TABLE BORDER=\"0\">");
580   pp_write_text_to_stream (pp);
581
582   bool had_row = false;
583
584   /* Give any annotator the chance to add its own per-node TR elements. */
585   if (args.m_node_annotator)
586     if (args.m_node_annotator->add_node_annotations (gv, *this, true))
587       had_row = true;
588
589   if (m_returning_call)
590     {
591       gv->begin_trtd ();
592       pp_string (pp, "returning call: ");
593       gv->end_tdtr ();
594
595       gv->begin_tr ();
596       gv->begin_td ();
597       pp_gimple_stmt_1 (pp, m_returning_call, 0, (dump_flags_t)0);
598       pp_write_text_as_html_like_dot_to_stream (pp);
599       gv->end_td ();
600       /* Give any annotator the chance to add per-stmt TD elements to
601          this row.  */
602       if (args.m_node_annotator)
603         args.m_node_annotator->add_stmt_annotations (gv, m_returning_call,
604                                                      true);
605       gv->end_tr ();
606
607       /* Give any annotator the chance to add per-stmt TR elements.  */
608       if (args.m_node_annotator)
609         args.m_node_annotator->add_stmt_annotations (gv, m_returning_call,
610                                                      false);
611       pp_newline (pp);
612
613       had_row = true;
614     }
615
616   if (entry_p ())
617     {
618       pp_string (pp, "<TR><TD>ENTRY</TD></TR>");
619       pp_newline (pp);
620       had_row = true;
621     }
622
623   if (return_p ())
624     {
625       pp_string (pp, "<TR><TD>EXIT</TD></TR>");
626       pp_newline (pp);
627       had_row = true;
628     }
629
630   /* Phi nodes.  */
631   for (gphi_iterator gpi = const_cast<supernode *> (this)->start_phis ();
632        !gsi_end_p (gpi); gsi_next (&gpi))
633     {
634       const gimple *stmt = gsi_stmt (gpi);
635       gv->begin_tr ();
636       gv->begin_td ();
637       pp_gimple_stmt_1 (pp, stmt, 0, (dump_flags_t)0);
638       pp_write_text_as_html_like_dot_to_stream (pp);
639       gv->end_td ();
640       /* Give any annotator the chance to add per-phi TD elements to
641          this row.  */
642       if (args.m_node_annotator)
643         args.m_node_annotator->add_stmt_annotations (gv, stmt, true);
644       gv->end_tr ();
645
646       /* Give any annotator the chance to add per-phi TR elements.  */
647       if (args.m_node_annotator)
648         args.m_node_annotator->add_stmt_annotations (gv, stmt, false);
649
650       pp_newline (pp);
651       had_row = true;
652     }
653
654   /* Statements.  */
655   int i;
656   gimple *stmt;
657   FOR_EACH_VEC_ELT (m_stmts, i, stmt)
658     {
659       gv->begin_tr ();
660       gv->begin_td ();
661       pp_gimple_stmt_1 (pp, stmt, 0, (dump_flags_t)0);
662       pp_write_text_as_html_like_dot_to_stream (pp);
663       gv->end_td ();
664       /* Give any annotator the chance to add per-stmt TD elements to
665          this row.  */
666       if (args.m_node_annotator)
667         args.m_node_annotator->add_stmt_annotations (gv, stmt, true);
668       gv->end_tr ();
669
670       /* Give any annotator the chance to add per-stmt TR elements.  */
671       if (args.m_node_annotator)
672         args.m_node_annotator->add_stmt_annotations (gv, stmt, false);
673
674       pp_newline (pp);
675       had_row = true;
676     }
677
678   /* Give any annotator the chance to add additional per-node TR elements
679      to the end of the TABLE. */
680   if (args.m_node_annotator)
681     if (args.m_node_annotator->add_after_node_annotations (gv, *this))
682       had_row = true;
683
684   /* Graphviz requires a TABLE element to have at least one TR
685      (and each TR to have at least one TD).  */
686   if (!had_row)
687     {
688       pp_string (pp, "<TR><TD>(empty)</TD></TR>");
689       pp_newline (pp);
690     }
691
692   pp_string (pp, "</TABLE>>];\n\n");
693   pp_flush (pp);
694
695   /* Terminate "subgraph" */
696   gv->outdent ();
697   gv->println ("}");
698 }
699
700 /* Write an ID for this node to PP, for use in .dot output.  */
701
702 void
703 supernode::dump_dot_id (pretty_printer *pp) const
704 {
705   pp_printf (pp, "node_%i", m_index);
706 }
707
708 /* Return a new json::object of the form
709    {"idx": int,
710     "fun": optional str
711     "bb_idx": int,
712     "returning_call": optional str,
713     "phis": [str],
714     "stmts" : [str]}.  */
715
716 json::object *
717 supernode::to_json () const
718 {
719   json::object *snode_obj = new json::object ();
720
721   snode_obj->set ("idx", new json::integer_number (m_index));
722   snode_obj->set ("bb_idx", new json::integer_number (m_bb->index));
723   if (function *fun = get_function ())
724     snode_obj->set ("fun", new json::string (function_name (fun)));
725
726   if (m_returning_call)
727     {
728       pretty_printer pp;
729       pp_format_decoder (&pp) = default_tree_printer;
730       pp_gimple_stmt_1 (&pp, m_returning_call, 0, (dump_flags_t)0);
731       snode_obj->set ("returning_call",
732                       new json::string (pp_formatted_text (&pp)));
733     }
734
735   /* Phi nodes.  */
736   {
737     json::array *phi_arr = new json::array ();
738     for (gphi_iterator gpi = const_cast<supernode *> (this)->start_phis ();
739          !gsi_end_p (gpi); gsi_next (&gpi))
740       {
741         const gimple *stmt = gsi_stmt (gpi);
742         pretty_printer pp;
743         pp_format_decoder (&pp) = default_tree_printer;
744         pp_gimple_stmt_1 (&pp, stmt, 0, (dump_flags_t)0);
745         phi_arr->append (new json::string (pp_formatted_text (&pp)));
746       }
747     snode_obj->set ("phis", phi_arr);
748   }
749
750   /* Statements.  */
751   {
752     json::array *stmt_arr = new json::array ();
753     int i;
754     gimple *stmt;
755     FOR_EACH_VEC_ELT (m_stmts, i, stmt)
756       {
757         pretty_printer pp;
758         pp_format_decoder (&pp) = default_tree_printer;
759         pp_gimple_stmt_1 (&pp, stmt, 0, (dump_flags_t)0);
760         stmt_arr->append (new json::string (pp_formatted_text (&pp)));
761       }
762     snode_obj->set ("stmts", stmt_arr);
763   }
764
765   return snode_obj;
766 }
767
768 /* Get a location_t for the start of this supernode.  */
769
770 location_t
771 supernode::get_start_location () const
772 {
773   if (m_returning_call
774       && get_pure_location (m_returning_call->location) != UNKNOWN_LOCATION)
775     return m_returning_call->location;
776
777   int i;
778   gimple *stmt;
779   FOR_EACH_VEC_ELT (m_stmts, i, stmt)
780     if (get_pure_location (stmt->location) != UNKNOWN_LOCATION)
781       return stmt->location;
782
783   if (entry_p ())
784     {
785       // TWEAK: show the decl instead; this leads to more readable output:
786       return DECL_SOURCE_LOCATION (m_fun->decl);
787
788       return m_fun->function_start_locus;
789     }
790   if (return_p ())
791     return m_fun->function_end_locus;
792
793   return UNKNOWN_LOCATION;
794 }
795
796 /* Get a location_t for the end of this supernode.  */
797
798 location_t
799 supernode::get_end_location () const
800 {
801   int i;
802   gimple *stmt;
803   FOR_EACH_VEC_ELT_REVERSE (m_stmts, i, stmt)
804     if (get_pure_location (stmt->location) != UNKNOWN_LOCATION)
805       return stmt->location;
806
807   if (m_returning_call
808       && get_pure_location (m_returning_call->location) != UNKNOWN_LOCATION)
809     return m_returning_call->location;
810
811   if (entry_p ())
812     return m_fun->function_start_locus;
813   if (return_p ())
814     return m_fun->function_end_locus;
815
816   return UNKNOWN_LOCATION;
817 }
818
819 /* Given STMT within this supernode, return its index within m_stmts.  */
820
821 unsigned int
822 supernode::get_stmt_index (const gimple *stmt) const
823 {
824   unsigned i;
825   gimple *iter_stmt;
826   FOR_EACH_VEC_ELT (m_stmts, i, iter_stmt)
827     if (iter_stmt == stmt)
828       return i;
829   gcc_unreachable ();
830 }
831
832 /* Get a string for PK.  */
833
834 static const char *
835 edge_kind_to_string (enum edge_kind kind)
836 {
837   switch (kind)
838     {
839     default:
840       gcc_unreachable ();
841     case SUPEREDGE_CFG_EDGE:
842       return "SUPEREDGE_CFG_EDGE";
843     case SUPEREDGE_CALL:
844       return "SUPEREDGE_CALL";
845     case SUPEREDGE_RETURN:
846       return "SUPEREDGE_RETURN";
847     case SUPEREDGE_INTRAPROCEDURAL_CALL:
848       return "SUPEREDGE_INTRAPROCEDURAL_CALL";
849     }
850 };
851
852 /* Dump this superedge to PP.  */
853
854 void
855 superedge::dump (pretty_printer *pp) const
856 {
857   pp_printf (pp, "edge: SN: %i -> SN: %i", m_src->m_index, m_dest->m_index);
858   label_text desc (get_description (false));
859   if (strlen (desc.get ()) > 0)
860     {
861       pp_space (pp);
862       pp_string (pp, desc.get ());
863     }
864 }
865
866 /* Dump this superedge to stderr.  */
867
868 DEBUG_FUNCTION void
869 superedge::dump () const
870 {
871   pretty_printer pp;
872   pp_format_decoder (&pp) = default_tree_printer;
873   pp_show_color (&pp) = pp_show_color (global_dc->printer);
874   pp.buffer->stream = stderr;
875   dump (&pp);
876   pp_newline (&pp);
877   pp_flush (&pp);
878 }
879
880 /* Implementation of dedge::dump_dot for superedges.
881    Write a .dot edge to GV representing this superedge.  */
882
883 void
884 superedge::dump_dot (graphviz_out *gv, const dump_args_t &) const
885 {
886   const char *style = "\"solid,bold\"";
887   const char *color = "black";
888   int weight = 10;
889   const char *constraint = "true";
890
891   switch (m_kind)
892     {
893     default:
894       gcc_unreachable ();
895     case SUPEREDGE_CFG_EDGE:
896       break;
897     case SUPEREDGE_CALL:
898       color = "red";
899       break;
900     case SUPEREDGE_RETURN:
901       color = "green";
902       break;
903     case SUPEREDGE_INTRAPROCEDURAL_CALL:
904       style = "\"dotted\"";
905       break;
906     }
907
908   /* Adapted from graph.cc:draw_cfg_node_succ_edges.  */
909   if (::edge cfg_edge = get_any_cfg_edge ())
910     {
911       if (cfg_edge->flags & EDGE_FAKE)
912         {
913           style = "dotted";
914           color = "green";
915           weight = 0;
916         }
917       else if (cfg_edge->flags & EDGE_DFS_BACK)
918         {
919           style = "\"dotted,bold\"";
920           color = "blue";
921           weight = 10;
922         }
923       else if (cfg_edge->flags & EDGE_FALLTHRU)
924         {
925           color = "blue";
926           weight = 100;
927         }
928
929       if (cfg_edge->flags & EDGE_ABNORMAL)
930         color = "red";
931     }
932
933   gv->write_indent ();
934
935   pretty_printer *pp = gv->get_pp ();
936
937   m_src->dump_dot_id (pp);
938   pp_string (pp, " -> ");
939   m_dest->dump_dot_id (pp);
940   pp_printf (pp,
941              (" [style=%s, color=%s, weight=%d, constraint=%s,"
942               " ltail=\"cluster_node_%i\", lhead=\"cluster_node_%i\""
943               " headlabel=\""),
944              style, color, weight, constraint,
945              m_src->m_index, m_dest->m_index);
946
947   dump_label_to_pp (pp, false);
948
949   pp_printf (pp, "\"];\n");
950 }
951
952 /* Return a new json::object of the form
953    {"kind"   : str,
954     "src_idx": int, the index of the source supernode,
955     "dst_idx": int, the index of the destination supernode,
956     "desc"   : str.  */
957
958 json::object *
959 superedge::to_json () const
960 {
961   json::object *sedge_obj = new json::object ();
962   sedge_obj->set ("kind", new json::string (edge_kind_to_string (m_kind)));
963   sedge_obj->set ("src_idx", new json::integer_number (m_src->m_index));
964   sedge_obj->set ("dst_idx", new json::integer_number (m_dest->m_index));
965
966   {
967     pretty_printer pp;
968     pp_format_decoder (&pp) = default_tree_printer;
969     dump_label_to_pp (&pp, false);
970     sedge_obj->set ("desc", new json::string (pp_formatted_text (&pp)));
971   }
972
973   return sedge_obj;
974 }
975
976 /* If this is an intraprocedural superedge, return the associated
977    CFG edge.  Otherwise, return NULL.  */
978
979 ::edge
980 superedge::get_any_cfg_edge () const
981 {
982   if (const cfg_superedge *sub = dyn_cast_cfg_superedge ())
983     return sub->get_cfg_edge ();
984   return NULL;
985 }
986
987 /* If this is an interprocedural superedge, return the associated
988    cgraph_edge *.  Otherwise, return NULL.  */
989
990 cgraph_edge *
991 superedge::get_any_callgraph_edge () const
992 {
993   if (const callgraph_superedge *sub = dyn_cast_callgraph_superedge ())
994     return sub->m_cedge;
995   return NULL;
996 }
997
998 /* Build a description of this superedge (e.g. "true" for the true
999    edge of a conditional, or "case 42:" for a switch case).
1000
1001    If USER_FACING is false, the result also contains any underlying
1002    CFG edge flags. e.g. " (flags FALLTHRU | DFS_BACK)".  */
1003
1004 label_text
1005 superedge::get_description (bool user_facing) const
1006 {
1007   pretty_printer pp;
1008   dump_label_to_pp (&pp, user_facing);
1009   return label_text::take (xstrdup (pp_formatted_text (&pp)));
1010 }
1011
1012 /* Implementation of superedge::dump_label_to_pp for non-switch CFG
1013    superedges.
1014
1015    For true/false edges, print "true" or "false" to PP.
1016
1017    If USER_FACING is false, also print flags on the underlying CFG edge to
1018    PP.  */
1019
1020 void
1021 cfg_superedge::dump_label_to_pp (pretty_printer *pp,
1022                                  bool user_facing) const
1023 {
1024   if (true_value_p ())
1025     pp_printf (pp, "true");
1026   else if (false_value_p ())
1027     pp_printf (pp, "false");
1028
1029   if (user_facing)
1030     return;
1031
1032   /* Express edge flags as a string with " | " separator.
1033      e.g. " (flags FALLTHRU | DFS_BACK)".  */
1034   if (get_flags ())
1035     {
1036       pp_string (pp, " (flags ");
1037       bool seen_flag = false;
1038 #define DEF_EDGE_FLAG(NAME,IDX)                 \
1039   do {                                          \
1040     if (get_flags () & EDGE_##NAME)                     \
1041       {                                         \
1042         if (seen_flag)                          \
1043           pp_string (pp, " | ");                        \
1044         pp_printf (pp, "%s", (#NAME));          \
1045         seen_flag = true;                       \
1046       }                                         \
1047   } while (0);
1048 #include "cfg-flags.def"
1049 #undef DEF_EDGE_FLAG
1050       pp_string (pp, ")");
1051     }
1052
1053   /* Otherwise, no label.  */
1054 }
1055
1056 /* Get the index number for this edge for use in phi stmts
1057    in its destination.  */
1058
1059 size_t
1060 cfg_superedge::get_phi_arg_idx () const
1061 {
1062   return m_cfg_edge->dest_idx;
1063 }
1064
1065 /* Get the phi argument for PHI for this CFG edge.  */
1066
1067 tree
1068 cfg_superedge::get_phi_arg (const gphi *phi) const
1069 {
1070   size_t index = get_phi_arg_idx ();
1071   return gimple_phi_arg_def (phi, index);
1072 }
1073
1074 switch_cfg_superedge::switch_cfg_superedge (supernode *src,
1075                                             supernode *dst,
1076                                             ::edge e)
1077 : cfg_superedge (src, dst, e)
1078 {
1079   /* Populate m_case_labels with all cases which go to DST.  */
1080   const gswitch *gswitch = get_switch_stmt ();
1081   for (unsigned i = 0; i < gimple_switch_num_labels (gswitch); i++)
1082     {
1083       tree case_ = gimple_switch_label (gswitch, i);
1084       basic_block bb = label_to_block (src->get_function (),
1085                                        CASE_LABEL (case_));
1086       if (bb == dst->m_bb)
1087         m_case_labels.safe_push (case_);
1088     }
1089 }
1090
1091 /* Implementation of superedge::dump_label_to_pp for CFG superedges for
1092    "switch" statements.
1093
1094    Print "case VAL:", "case LOWER ... UPPER:", or "default:" to PP.  */
1095
1096 void
1097 switch_cfg_superedge::dump_label_to_pp (pretty_printer *pp,
1098                                         bool user_facing ATTRIBUTE_UNUSED) const
1099 {
1100   if (user_facing)
1101     {
1102       for (unsigned i = 0; i < m_case_labels.length (); ++i)
1103         {
1104           if (i > 0)
1105             pp_string (pp, ", ");
1106           tree case_label = m_case_labels[i];
1107           gcc_assert (TREE_CODE (case_label) == CASE_LABEL_EXPR);
1108           tree lower_bound = CASE_LOW (case_label);
1109           tree upper_bound = CASE_HIGH (case_label);
1110           if (lower_bound)
1111             {
1112               pp_printf (pp, "case ");
1113               dump_generic_node (pp, lower_bound, 0, (dump_flags_t)0, false);
1114               if (upper_bound)
1115                 {
1116                   pp_printf (pp, " ... ");
1117                   dump_generic_node (pp, upper_bound, 0, (dump_flags_t)0,
1118                                      false);
1119                 }
1120               pp_printf (pp, ":");
1121             }
1122           else
1123             pp_printf (pp, "default:");
1124         }
1125     }
1126   else
1127     {
1128       pp_character (pp, '{');
1129       for (unsigned i = 0; i < m_case_labels.length (); ++i)
1130         {
1131           if (i > 0)
1132             pp_string (pp, ", ");
1133           tree case_label = m_case_labels[i];
1134           gcc_assert (TREE_CODE (case_label) == CASE_LABEL_EXPR);
1135           tree lower_bound = CASE_LOW (case_label);
1136           tree upper_bound = CASE_HIGH (case_label);
1137           if (lower_bound)
1138             {
1139               if (upper_bound)
1140                 {
1141                   pp_character (pp, '[');
1142                   dump_generic_node (pp, lower_bound, 0, (dump_flags_t)0,
1143                                      false);
1144                   pp_string (pp, ", ");
1145                   dump_generic_node (pp, upper_bound, 0, (dump_flags_t)0,
1146                                      false);
1147                   pp_character (pp, ']');
1148                 }
1149               else
1150                 dump_generic_node (pp, lower_bound, 0, (dump_flags_t)0, false);
1151             }
1152           else
1153             pp_printf (pp, "default");
1154         }
1155       pp_character (pp, '}');
1156       if (implicitly_created_default_p ())
1157         {
1158           pp_string (pp, " IMPLICITLY CREATED");
1159         }
1160     }
1161 }
1162
1163 /* Return true iff this edge is purely for an implicitly-created "default".  */
1164
1165 bool
1166 switch_cfg_superedge::implicitly_created_default_p () const
1167 {
1168   if (m_case_labels.length () != 1)
1169     return false;
1170
1171   tree case_label = m_case_labels[0];
1172   gcc_assert (TREE_CODE (case_label) == CASE_LABEL_EXPR);
1173   if (CASE_LOW (case_label))
1174     return false;
1175
1176   /* We have a single "default" case.
1177      Assume that it was implicitly created if it has UNKNOWN_LOCATION.  */
1178   return EXPR_LOCATION (case_label) == UNKNOWN_LOCATION;
1179 }
1180
1181 /* Implementation of superedge::dump_label_to_pp for interprocedural
1182    superedges.  */
1183
1184 void
1185 callgraph_superedge::dump_label_to_pp (pretty_printer *pp,
1186                                        bool user_facing ATTRIBUTE_UNUSED) const
1187 {
1188   switch (m_kind)
1189     {
1190     default:
1191     case SUPEREDGE_CFG_EDGE:
1192       gcc_unreachable ();
1193
1194     case SUPEREDGE_CALL:
1195       pp_printf (pp, "call");
1196       break;
1197
1198     case SUPEREDGE_RETURN:
1199       pp_printf (pp, "return");
1200       break;
1201
1202     case SUPEREDGE_INTRAPROCEDURAL_CALL:
1203       pp_printf (pp, "intraproc link");
1204       break;
1205     }
1206 }
1207
1208 /* Get the function that was called at this interprocedural call/return
1209    edge.  */
1210
1211 function *
1212 callgraph_superedge::get_callee_function () const
1213 {
1214   return get_ultimate_function_for_cgraph_edge (m_cedge);
1215 }
1216
1217 /* Get the calling function at this interprocedural call/return edge.  */
1218
1219 function *
1220 callgraph_superedge::get_caller_function () const
1221 {
1222   return m_cedge->caller->get_fun ();
1223 }
1224
1225 /* Get the fndecl that was called at this interprocedural call/return
1226    edge.  */
1227
1228 tree
1229 callgraph_superedge::get_callee_decl () const
1230 {
1231   return get_callee_function ()->decl;
1232 }
1233
1234 /* Get the gcall * of this interprocedural call/return edge.  */
1235
1236 gcall *
1237 callgraph_superedge::get_call_stmt () const
1238 {
1239   if (m_cedge)
1240     return m_cedge->call_stmt;
1241   
1242   return m_src->get_final_call ();
1243 }
1244
1245 /* Get the calling fndecl at this interprocedural call/return edge.  */
1246
1247 tree
1248 callgraph_superedge::get_caller_decl () const
1249 {
1250   return get_caller_function ()->decl;
1251 }
1252
1253 /* Given PARM_TO_FIND, a PARM_DECL, identify its index (writing it
1254    to *OUT if OUT is non-NULL), and return the corresponding argument
1255    at the callsite.  */
1256
1257 tree
1258 callgraph_superedge::get_arg_for_parm (tree parm_to_find,
1259                                        callsite_expr *out) const
1260 {
1261   gcc_assert  (TREE_CODE (parm_to_find) == PARM_DECL);
1262
1263   tree callee = get_callee_decl ();
1264   const gcall *call_stmt = get_call_stmt ();
1265
1266   unsigned i = 0;
1267   for (tree iter_parm = DECL_ARGUMENTS (callee); iter_parm;
1268        iter_parm = DECL_CHAIN (iter_parm), ++i)
1269     {
1270       if (i >= gimple_call_num_args (call_stmt))
1271         return NULL_TREE;
1272       if (iter_parm == parm_to_find)
1273         {
1274           if (out)
1275             *out = callsite_expr::from_zero_based_param (i);
1276           return gimple_call_arg (call_stmt, i);
1277         }
1278     }
1279
1280   /* Not found.  */
1281   return NULL_TREE;
1282 }
1283
1284 /* Look for a use of ARG_TO_FIND as an argument at this callsite.
1285    If found, return the default SSA def of the corresponding parm within
1286    the callee, and if OUT is non-NULL, write the index to *OUT.
1287    Only the first match is handled.  */
1288
1289 tree
1290 callgraph_superedge::get_parm_for_arg (tree arg_to_find,
1291                                        callsite_expr *out) const
1292 {
1293   tree callee = get_callee_decl ();
1294   const gcall *call_stmt = get_call_stmt ();
1295
1296   unsigned i = 0;
1297   for (tree iter_parm = DECL_ARGUMENTS (callee); iter_parm;
1298        iter_parm = DECL_CHAIN (iter_parm), ++i)
1299     {
1300       if (i >= gimple_call_num_args (call_stmt))
1301         return NULL_TREE;
1302       tree param = gimple_call_arg (call_stmt, i);
1303       if (arg_to_find == param)
1304         {
1305           if (out)
1306             *out = callsite_expr::from_zero_based_param (i);
1307           return ssa_default_def (get_callee_function (), iter_parm);
1308         }
1309     }
1310
1311   /* Not found.  */
1312   return NULL_TREE;
1313 }
1314
1315 /* Map caller_expr back to an expr within the callee, or return NULL_TREE.
1316    If non-NULL is returned, populate OUT.  */
1317
1318 tree
1319 callgraph_superedge::map_expr_from_caller_to_callee (tree caller_expr,
1320                                                      callsite_expr *out) const
1321 {
1322   /* Is it an argument (actual param)?  If so, convert to
1323      parameter (formal param).  */
1324   tree parm = get_parm_for_arg (caller_expr, out);
1325   if (parm)
1326     return parm;
1327   /* Otherwise try return value.  */
1328   if (caller_expr == gimple_call_lhs (get_call_stmt ()))
1329     {
1330       if (out)
1331         *out = callsite_expr::from_return_value ();
1332       return DECL_RESULT (get_callee_decl ());
1333     }
1334
1335   return NULL_TREE;
1336 }
1337
1338 /* Map callee_expr back to an expr within the caller, or return NULL_TREE.
1339    If non-NULL is returned, populate OUT.  */
1340
1341 tree
1342 callgraph_superedge::map_expr_from_callee_to_caller (tree callee_expr,
1343                                                      callsite_expr *out) const
1344 {
1345   if (callee_expr == NULL_TREE)
1346     return NULL_TREE;
1347
1348   /* If it's a parameter (formal param), get the argument (actual param).  */
1349   if (TREE_CODE (callee_expr) == PARM_DECL)
1350     return get_arg_for_parm (callee_expr, out);
1351
1352   /* Similar for the default SSA name of the PARM_DECL.  */
1353   if (TREE_CODE (callee_expr) == SSA_NAME
1354       && SSA_NAME_IS_DEFAULT_DEF (callee_expr)
1355       && TREE_CODE (SSA_NAME_VAR (callee_expr)) == PARM_DECL)
1356     return get_arg_for_parm (SSA_NAME_VAR (callee_expr), out);
1357
1358   /* Otherwise try return value.  */
1359   if (callee_expr == DECL_RESULT (get_callee_decl ()))
1360     {
1361       if (out)
1362         *out = callsite_expr::from_return_value ();
1363       return gimple_call_lhs (get_call_stmt ());
1364     }
1365
1366   return NULL_TREE;
1367 }
1368
1369 } // namespace ana
1370
1371 #endif /* #if ENABLE_ANALYZER */