* Makefile.tpl (all): Avoid a trailing backslash.
[deliverable/binutils-gdb.git] / gprof / cg_print.c
CommitLineData
ef368dac
NC
1/* cg_print.c - Print routines for displaying call graphs.
2
651dbc76 3 Copyright 2000, 2001, 2002, 2004, 2007 Free Software Foundation, Inc.
ef368dac
NC
4
5 This file is part of GNU Binutils.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
651dbc76 9 the Free Software Foundation; either version 3 of the License, or
ef368dac
NC
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program; if not, write to the Free Software
44eb1801
NC
19 Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA
20 02110-1301, USA. */
ef368dac 21\f
6d9c411a 22#include "gprof.h"
ecba005f 23#include "libiberty.h"
6d9c411a
AM
24#include "search_list.h"
25#include "source.h"
26#include "symtab.h"
252b5132
RH
27#include "cg_arcs.h"
28#include "cg_print.h"
29#include "hist.h"
30#include "utils.h"
1355568a 31#include "corefile.h"
252b5132 32
ef368dac 33/* Return value of comparison functions used to sort tables. */
252b5132
RH
34#define LESSTHAN -1
35#define EQUALTO 0
36#define GREATERTHAN 1
37
3e8f6abf
BE
38static void print_header (void);
39static void print_cycle (Sym *);
40static int cmp_member (Sym *, Sym *);
41static void sort_members (Sym *);
42static void print_members (Sym *);
43static int cmp_arc (Arc *, Arc *);
44static void sort_parents (Sym *);
45static void print_parents (Sym *);
46static void sort_children (Sym *);
47static void print_children (Sym *);
48static void print_line (Sym *);
49static int cmp_name (const PTR, const PTR);
50static int cmp_arc_count (const PTR, const PTR);
51static int cmp_fun_nuses (const PTR, const PTR);
1355568a 52static void order_and_dump_functions_by_arcs
3e8f6abf 53 (Arc **, unsigned long, int, Arc **, unsigned long *);
1355568a 54
ef368dac 55/* Declarations of automatically generated functions to output blurbs. */
3e8f6abf
BE
56extern void bsd_callg_blurb (FILE * fp);
57extern void fsf_callg_blurb (FILE * fp);
252b5132
RH
58
59double print_time = 0.0;
60
61
62static void
1355568a 63print_header ()
252b5132
RH
64{
65 if (first_output)
b34976b6 66 first_output = FALSE;
252b5132 67 else
ef368dac 68 printf ("\f\n");
0eee5820 69
252b5132
RH
70 if (!bsd_style_output)
71 {
72 if (print_descriptions)
ef368dac 73 printf (_("\t\t Call graph (explanation follows)\n\n"));
252b5132 74 else
ef368dac 75 printf (_("\t\t\tCall graph\n\n"));
252b5132 76 }
0eee5820 77
252b5132 78 printf (_("\ngranularity: each sample hit covers %ld byte(s)"),
d2df793a 79 (long) hist_scale * (long) sizeof (UNIT));
0eee5820 80
252b5132 81 if (print_time > 0.0)
ef368dac
NC
82 printf (_(" for %.2f%% of %.2f seconds\n\n"),
83 100.0 / print_time, print_time / hz);
252b5132
RH
84 else
85 {
86 printf (_(" no time propagated\n\n"));
0eee5820 87
ef368dac 88 /* This doesn't hurt, since all the numerators will be 0.0. */
252b5132
RH
89 print_time = 1.0;
90 }
0eee5820 91
252b5132
RH
92 if (bsd_style_output)
93 {
94 printf ("%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s %-8.8s\n",
95 "", "", "", "", _("called"), _("total"), _("parents"));
96 printf ("%-6.6s %5.5s %7.7s %11.11s %7.7s+%-7.7s %-8.8s\t%5.5s\n",
af6dfb5b 97 _("index"), _("%time"), _("self"), _("descendants"),
252b5132
RH
98 _("called"), _("self"), _("name"), _("index"));
99 printf ("%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s %-8.8s\n",
100 "", "", "", "", _("called"), _("total"), _("children"));
101 printf ("\n");
102 }
103 else
104 {
105 printf (_("index %% time self children called name\n"));
106 }
107}
108
ef368dac 109/* Print a cycle header. */
252b5132 110
252b5132 111static void
3e8f6abf 112print_cycle (Sym *cyc)
252b5132
RH
113{
114 char buf[BUFSIZ];
115
116 sprintf (buf, "[%d]", cyc->cg.index);
117 printf (bsd_style_output
118 ? "%-6.6s %5.1f %7.2f %11.2f %7lu"
119 : "%-6.6s %5.1f %7.2f %7.2f %7lu", buf,
120 100 * (cyc->cg.prop.self + cyc->cg.prop.child) / print_time,
121 cyc->cg.prop.self / hz, cyc->cg.prop.child / hz, cyc->ncalls);
0eee5820 122
252b5132 123 if (cyc->cg.self_calls != 0)
ef368dac 124 printf ("+%-7lu", cyc->cg.self_calls);
252b5132 125 else
ef368dac
NC
126 printf (" %7.7s", "");
127
252b5132
RH
128 printf (_(" <cycle %d as a whole> [%d]\n"), cyc->cg.cyc.num, cyc->cg.index);
129}
130
ef368dac
NC
131/* Compare LEFT and RIGHT membmer. Major comparison key is
132 CG.PROP.SELF+CG.PROP.CHILD, secondary key is NCALLS+CG.SELF_CALLS. */
252b5132 133
252b5132 134static int
3e8f6abf 135cmp_member (Sym *left, Sym *right)
252b5132
RH
136{
137 double left_time = left->cg.prop.self + left->cg.prop.child;
138 double right_time = right->cg.prop.self + right->cg.prop.child;
139 unsigned long left_calls = left->ncalls + left->cg.self_calls;
140 unsigned long right_calls = right->ncalls + right->cg.self_calls;
141
142 if (left_time > right_time)
ef368dac
NC
143 return GREATERTHAN;
144
252b5132 145 if (left_time < right_time)
ef368dac 146 return LESSTHAN;
252b5132
RH
147
148 if (left_calls > right_calls)
ef368dac
NC
149 return GREATERTHAN;
150
252b5132 151 if (left_calls < right_calls)
ef368dac
NC
152 return LESSTHAN;
153
252b5132
RH
154 return EQUALTO;
155}
156
ef368dac 157/* Sort members of a cycle. */
252b5132 158
252b5132 159static void
3e8f6abf 160sort_members (Sym *cyc)
252b5132
RH
161{
162 Sym *todo, *doing, *prev;
0eee5820 163
ef368dac
NC
164 /* Detach cycle members from cyclehead,
165 and insertion sort them back on. */
252b5132
RH
166 todo = cyc->cg.cyc.next;
167 cyc->cg.cyc.next = 0;
0eee5820 168
2d7b9687 169 for (doing = todo; doing != NULL; doing = todo)
252b5132
RH
170 {
171 todo = doing->cg.cyc.next;
0eee5820 172
252b5132
RH
173 for (prev = cyc; prev->cg.cyc.next; prev = prev->cg.cyc.next)
174 {
175 if (cmp_member (doing, prev->cg.cyc.next) == GREATERTHAN)
ef368dac 176 break;
252b5132 177 }
0eee5820 178
252b5132
RH
179 doing->cg.cyc.next = prev->cg.cyc.next;
180 prev->cg.cyc.next = doing;
181 }
182}
183
ef368dac 184/* Print the members of a cycle. */
252b5132 185
252b5132 186static void
3e8f6abf 187print_members (Sym *cyc)
252b5132
RH
188{
189 Sym *member;
190
191 sort_members (cyc);
0eee5820 192
252b5132
RH
193 for (member = cyc->cg.cyc.next; member; member = member->cg.cyc.next)
194 {
195 printf (bsd_style_output
196 ? "%6.6s %5.5s %7.2f %11.2f %7lu"
197 : "%6.6s %5.5s %7.2f %7.2f %7lu",
198 "", "", member->cg.prop.self / hz, member->cg.prop.child / hz,
199 member->ncalls);
0eee5820 200
252b5132 201 if (member->cg.self_calls != 0)
ef368dac 202 printf ("+%-7lu", member->cg.self_calls);
252b5132 203 else
ef368dac
NC
204 printf (" %7.7s", "");
205
252b5132
RH
206 printf (" ");
207 print_name (member);
208 printf ("\n");
209 }
210}
211
ef368dac 212/* Compare two arcs to/from the same child/parent.
0eee5820
AM
213 - if one arc is a self arc, it's least.
214 - if one arc is within a cycle, it's less than.
215 - if both arcs are within a cycle, compare arc counts.
216 - if neither arc is within a cycle, compare with
217 time + child_time as major key
218 arc count as minor key. */
252b5132 219
252b5132 220static int
3e8f6abf 221cmp_arc (Arc *left, Arc *right)
252b5132
RH
222{
223 Sym *left_parent = left->parent;
224 Sym *left_child = left->child;
225 Sym *right_parent = right->parent;
226 Sym *right_child = right->child;
227 double left_time, right_time;
228
229 DBG (TIMEDEBUG,
230 printf ("[cmp_arc] ");
231 print_name (left_parent);
232 printf (" calls ");
233 print_name (left_child);
234 printf (" %f + %f %lu/%lu\n", left->time, left->child_time,
235 left->count, left_child->ncalls);
236 printf ("[cmp_arc] ");
237 print_name (right_parent);
238 printf (" calls ");
239 print_name (right_child);
240 printf (" %f + %f %lu/%lu\n", right->time, right->child_time,
241 right->count, right_child->ncalls);
242 printf ("\n");
243 );
0eee5820 244
252b5132 245 if (left_parent == left_child)
ef368dac
NC
246 return LESSTHAN; /* Left is a self call. */
247
252b5132 248 if (right_parent == right_child)
ef368dac 249 return GREATERTHAN; /* Right is a self call. */
252b5132
RH
250
251 if (left_parent->cg.cyc.num != 0 && left_child->cg.cyc.num != 0
252 && left_parent->cg.cyc.num == left_child->cg.cyc.num)
253 {
ef368dac 254 /* Left is a call within a cycle. */
252b5132
RH
255 if (right_parent->cg.cyc.num != 0 && right_child->cg.cyc.num != 0
256 && right_parent->cg.cyc.num == right_child->cg.cyc.num)
257 {
ef368dac 258 /* Right is a call within the cycle, too. */
252b5132 259 if (left->count < right->count)
ef368dac
NC
260 return LESSTHAN;
261
252b5132 262 if (left->count > right->count)
ef368dac
NC
263 return GREATERTHAN;
264
252b5132
RH
265 return EQUALTO;
266 }
267 else
268 {
ef368dac 269 /* Right isn't a call within the cycle. */
252b5132
RH
270 return LESSTHAN;
271 }
272 }
273 else
274 {
ef368dac 275 /* Left isn't a call within a cycle. */
252b5132
RH
276 if (right_parent->cg.cyc.num != 0 && right_child->cg.cyc.num != 0
277 && right_parent->cg.cyc.num == right_child->cg.cyc.num)
278 {
ef368dac 279 /* Right is a call within a cycle. */
252b5132
RH
280 return GREATERTHAN;
281 }
282 else
283 {
ef368dac 284 /* Neither is a call within a cycle. */
252b5132
RH
285 left_time = left->time + left->child_time;
286 right_time = right->time + right->child_time;
0eee5820 287
252b5132 288 if (left_time < right_time)
ef368dac
NC
289 return LESSTHAN;
290
252b5132 291 if (left_time > right_time)
ef368dac
NC
292 return GREATERTHAN;
293
252b5132 294 if (left->count < right->count)
ef368dac
NC
295 return LESSTHAN;
296
252b5132 297 if (left->count > right->count)
ef368dac
NC
298 return GREATERTHAN;
299
252b5132
RH
300 return EQUALTO;
301 }
302 }
303}
304
305
306static void
3e8f6abf 307sort_parents (Sym * child)
252b5132
RH
308{
309 Arc *arc, *detached, sorted, *prev;
310
ef368dac
NC
311 /* Unlink parents from child, then insertion sort back on to
312 sorted's parents.
0eee5820
AM
313 *arc the arc you have detached and are inserting.
314 *detached the rest of the arcs to be sorted.
315 sorted arc list onto which you insertion sort.
316 *prev arc before the arc you are comparing. */
252b5132 317 sorted.next_parent = 0;
0eee5820 318
252b5132
RH
319 for (arc = child->cg.parents; arc; arc = detached)
320 {
321 detached = arc->next_parent;
322
ef368dac 323 /* Consider *arc as disconnected; insert it into sorted. */
252b5132
RH
324 for (prev = &sorted; prev->next_parent; prev = prev->next_parent)
325 {
326 if (cmp_arc (arc, prev->next_parent) != GREATERTHAN)
ef368dac 327 break;
252b5132 328 }
0eee5820 329
252b5132
RH
330 arc->next_parent = prev->next_parent;
331 prev->next_parent = arc;
332 }
333
ef368dac 334 /* Reattach sorted arcs to child. */
252b5132
RH
335 child->cg.parents = sorted.next_parent;
336}
337
338
339static void
3e8f6abf 340print_parents (Sym *child)
252b5132
RH
341{
342 Sym *parent;
343 Arc *arc;
344 Sym *cycle_head;
345
346 if (child->cg.cyc.head != 0)
ef368dac 347 cycle_head = child->cg.cyc.head;
252b5132 348 else
ef368dac 349 cycle_head = child;
0eee5820 350
252b5132
RH
351 if (!child->cg.parents)
352 {
353 printf (bsd_style_output
354 ? _("%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s <spontaneous>\n")
355 : _("%6.6s %5.5s %7.7s %7.7s %7.7s %7.7s <spontaneous>\n"),
356 "", "", "", "", "", "");
357 return;
358 }
0eee5820 359
252b5132 360 sort_parents (child);
0eee5820 361
252b5132
RH
362 for (arc = child->cg.parents; arc; arc = arc->next_parent)
363 {
364 parent = arc->parent;
365 if (child == parent || (child->cg.cyc.num != 0
366 && parent->cg.cyc.num == child->cg.cyc.num))
367 {
ef368dac 368 /* Selfcall or call among siblings. */
252b5132
RH
369 printf (bsd_style_output
370 ? "%6.6s %5.5s %7.7s %11.11s %7lu %7.7s "
371 : "%6.6s %5.5s %7.7s %7.7s %7lu %7.7s ",
372 "", "", "", "",
373 arc->count, "");
374 print_name (parent);
375 printf ("\n");
376 }
377 else
378 {
ef368dac 379 /* Regular parent of child. */
252b5132
RH
380 printf (bsd_style_output
381 ? "%6.6s %5.5s %7.2f %11.2f %7lu/%-7lu "
382 : "%6.6s %5.5s %7.2f %7.2f %7lu/%-7lu ",
383 "", "",
384 arc->time / hz, arc->child_time / hz,
385 arc->count, cycle_head->ncalls);
386 print_name (parent);
387 printf ("\n");
388 }
389 }
390}
391
392
393static void
3e8f6abf 394sort_children (Sym *parent)
252b5132
RH
395{
396 Arc *arc, *detached, sorted, *prev;
0eee5820 397
ef368dac
NC
398 /* Unlink children from parent, then insertion sort back on to
399 sorted's children.
0eee5820
AM
400 *arc the arc you have detached and are inserting.
401 *detached the rest of the arcs to be sorted.
402 sorted arc list onto which you insertion sort.
403 *prev arc before the arc you are comparing. */
252b5132 404 sorted.next_child = 0;
0eee5820 405
252b5132
RH
406 for (arc = parent->cg.children; arc; arc = detached)
407 {
408 detached = arc->next_child;
409
ef368dac 410 /* Consider *arc as disconnected; insert it into sorted. */
252b5132
RH
411 for (prev = &sorted; prev->next_child; prev = prev->next_child)
412 {
413 if (cmp_arc (arc, prev->next_child) != LESSTHAN)
ef368dac 414 break;
252b5132 415 }
0eee5820 416
252b5132
RH
417 arc->next_child = prev->next_child;
418 prev->next_child = arc;
419 }
420
ef368dac 421 /* Reattach sorted children to parent. */
252b5132
RH
422 parent->cg.children = sorted.next_child;
423}
424
425
426static void
3e8f6abf 427print_children (Sym *parent)
252b5132
RH
428{
429 Sym *child;
430 Arc *arc;
431
432 sort_children (parent);
433 arc = parent->cg.children;
0eee5820 434
252b5132
RH
435 for (arc = parent->cg.children; arc; arc = arc->next_child)
436 {
437 child = arc->child;
438 if (child == parent || (child->cg.cyc.num != 0
439 && child->cg.cyc.num == parent->cg.cyc.num))
440 {
ef368dac 441 /* Self call or call to sibling. */
252b5132
RH
442 printf (bsd_style_output
443 ? "%6.6s %5.5s %7.7s %11.11s %7lu %7.7s "
444 : "%6.6s %5.5s %7.7s %7.7s %7lu %7.7s ",
445 "", "", "", "", arc->count, "");
446 print_name (child);
447 printf ("\n");
448 }
449 else
450 {
ef368dac 451 /* Regular child of parent. */
252b5132
RH
452 printf (bsd_style_output
453 ? "%6.6s %5.5s %7.2f %11.2f %7lu/%-7lu "
454 : "%6.6s %5.5s %7.2f %7.2f %7lu/%-7lu ",
455 "", "",
456 arc->time / hz, arc->child_time / hz,
457 arc->count, child->cg.cyc.head->ncalls);
458 print_name (child);
459 printf ("\n");
460 }
461 }
462}
463
464
465static void
3e8f6abf 466print_line (Sym *np)
252b5132
RH
467{
468 char buf[BUFSIZ];
469
470 sprintf (buf, "[%d]", np->cg.index);
471 printf (bsd_style_output
472 ? "%-6.6s %5.1f %7.2f %11.2f"
473 : "%-6.6s %5.1f %7.2f %7.2f", buf,
474 100 * (np->cg.prop.self + np->cg.prop.child) / print_time,
475 np->cg.prop.self / hz, np->cg.prop.child / hz);
0eee5820 476
252b5132
RH
477 if ((np->ncalls + np->cg.self_calls) != 0)
478 {
479 printf (" %7lu", np->ncalls);
0eee5820 480
252b5132 481 if (np->cg.self_calls != 0)
252b5132 482 printf ("+%-7lu ", np->cg.self_calls);
252b5132 483 else
252b5132 484 printf (" %7.7s ", "");
252b5132
RH
485 }
486 else
487 {
488 printf (" %7.7s %7.7s ", "", "");
489 }
0eee5820 490
252b5132
RH
491 print_name (np);
492 printf ("\n");
493}
494
495
ef368dac
NC
496/* Print dynamic call graph. */
497
252b5132 498void
3e8f6abf 499cg_print (Sym ** timesortsym)
252b5132
RH
500{
501 unsigned int index;
502 Sym *parent;
503
504 if (print_descriptions && bsd_style_output)
ef368dac 505 bsd_callg_blurb (stdout);
252b5132
RH
506
507 print_header ();
508
509 for (index = 0; index < symtab.len + num_cycles; ++index)
510 {
511 parent = timesortsym[index];
0eee5820 512
252b5132
RH
513 if ((ignore_zeros && parent->ncalls == 0
514 && parent->cg.self_calls == 0 && parent->cg.prop.self == 0
515 && parent->cg.prop.child == 0)
516 || !parent->cg.print_flag
517 || (line_granularity && ! parent->is_func))
ef368dac 518 continue;
0eee5820 519
252b5132
RH
520 if (!parent->name && parent->cg.cyc.num != 0)
521 {
ef368dac 522 /* Cycle header. */
252b5132
RH
523 print_cycle (parent);
524 print_members (parent);
525 }
526 else
527 {
528 print_parents (parent);
529 print_line (parent);
530 print_children (parent);
531 }
0eee5820 532
252b5132
RH
533 if (bsd_style_output)
534 printf ("\n");
0eee5820 535
252b5132 536 printf ("-----------------------------------------------\n");
0eee5820 537
252b5132
RH
538 if (bsd_style_output)
539 printf ("\n");
540 }
0eee5820 541
252b5132 542 free (timesortsym);
0eee5820 543
252b5132 544 if (print_descriptions && !bsd_style_output)
ef368dac 545 fsf_callg_blurb (stdout);
252b5132
RH
546}
547
548
549static int
3e8f6abf 550cmp_name (const PTR left, const PTR right)
252b5132
RH
551{
552 const Sym **npp1 = (const Sym **) left;
553 const Sym **npp2 = (const Sym **) right;
554
555 return strcmp ((*npp1)->name, (*npp2)->name);
556}
557
558
559void
1355568a 560cg_print_index ()
252b5132
RH
561{
562 unsigned int index;
563 unsigned int nnames, todo, i, j;
564 int col, starting_col;
565 Sym **name_sorted_syms, *sym;
566 const char *filename;
567 char buf[20];
ef368dac 568 int column_width = (output_width - 1) / 3; /* Don't write in last col! */
0eee5820 569
ef368dac
NC
570 /* Now, sort regular function name
571 alphabetically to create an index. */
252b5132 572 name_sorted_syms = (Sym **) xmalloc ((symtab.len + num_cycles) * sizeof (Sym *));
0eee5820 573
252b5132
RH
574 for (index = 0, nnames = 0; index < symtab.len; index++)
575 {
576 if (ignore_zeros && symtab.base[index].ncalls == 0
577 && symtab.base[index].hist.time == 0)
ef368dac
NC
578 continue;
579
252b5132
RH
580 name_sorted_syms[nnames++] = &symtab.base[index];
581 }
0eee5820 582
252b5132 583 qsort (name_sorted_syms, nnames, sizeof (Sym *), cmp_name);
0eee5820 584
252b5132 585 for (index = 1, todo = nnames; index <= num_cycles; index++)
ef368dac
NC
586 name_sorted_syms[todo++] = &cycle_header[index];
587
252b5132
RH
588 printf ("\f\n");
589 printf (_("Index by function name\n\n"));
590 index = (todo + 2) / 3;
0eee5820 591
252b5132
RH
592 for (i = 0; i < index; i++)
593 {
594 col = 0;
595 starting_col = 0;
0eee5820 596
252b5132
RH
597 for (j = i; j < todo; j += index)
598 {
599 sym = name_sorted_syms[j];
0eee5820 600
252b5132 601 if (sym->cg.print_flag)
ef368dac 602 sprintf (buf, "[%d]", sym->cg.index);
252b5132 603 else
ef368dac
NC
604 sprintf (buf, "(%d)", sym->cg.index);
605
252b5132
RH
606 if (j < nnames)
607 {
608 if (bsd_style_output)
609 {
610 printf ("%6.6s %-19.19s", buf, sym->name);
611 }
612 else
613 {
614 col += strlen (buf);
0eee5820 615
252b5132 616 for (; col < starting_col + 5; ++col)
ef368dac
NC
617 putchar (' ');
618
252b5132
RH
619 printf (" %s ", buf);
620 col += print_name_only (sym);
0eee5820 621
252b5132
RH
622 if (!line_granularity && sym->is_static && sym->file)
623 {
624 filename = sym->file->name;
0eee5820 625
252b5132
RH
626 if (!print_path)
627 {
628 filename = strrchr (filename, '/');
0eee5820 629
252b5132 630 if (filename)
ef368dac 631 ++filename;
252b5132 632 else
ef368dac 633 filename = sym->file->name;
252b5132 634 }
0eee5820 635
252b5132
RH
636 printf (" (%s)", filename);
637 col += strlen (filename) + 3;
638 }
639 }
640 }
641 else
642 {
643 if (bsd_style_output)
644 {
645 printf ("%6.6s ", buf);
646 sprintf (buf, _("<cycle %d>"), sym->cg.cyc.num);
647 printf ("%-19.19s", buf);
648 }
649 else
650 {
651 col += strlen (buf);
652 for (; col < starting_col + 5; ++col)
653 putchar (' ');
654 printf (" %s ", buf);
655 sprintf (buf, _("<cycle %d>"), sym->cg.cyc.num);
656 printf ("%s", buf);
657 col += strlen (buf);
658 }
659 }
0eee5820 660
252b5132
RH
661 starting_col += column_width;
662 }
0eee5820 663
252b5132
RH
664 printf ("\n");
665 }
0eee5820 666
252b5132
RH
667 free (name_sorted_syms);
668}
669
ef368dac
NC
670/* Compare two arcs based on their usage counts.
671 We want to sort in descending order. */
672
252b5132 673static int
3e8f6abf 674cmp_arc_count (const PTR left, const PTR right)
252b5132
RH
675{
676 const Arc **npp1 = (const Arc **) left;
677 const Arc **npp2 = (const Arc **) right;
678
679 if ((*npp1)->count > (*npp2)->count)
680 return -1;
681 else if ((*npp1)->count < (*npp2)->count)
682 return 1;
683 else
684 return 0;
685}
686
ef368dac
NC
687/* Compare two funtions based on their usage counts.
688 We want to sort in descending order. */
689
252b5132 690static int
3e8f6abf 691cmp_fun_nuses (const PTR left, const PTR right)
252b5132
RH
692{
693 const Sym **npp1 = (const Sym **) left;
694 const Sym **npp2 = (const Sym **) right;
695
696 if ((*npp1)->nuses > (*npp2)->nuses)
697 return -1;
698 else if ((*npp1)->nuses < (*npp2)->nuses)
699 return 1;
700 else
701 return 0;
702}
703
704/* Print a suggested function ordering based on the profiling data.
705
706 We perform 4 major steps when ordering functions:
707
708 * Group unused functions together and place them at the
709 end of the function order.
710
711 * Search the highest use arcs (those which account for 90% of
712 the total arc count) for functions which have several parents.
713
714 Group those with the most call sites together (currently the
715 top 1.25% which have at least five different call sites).
716
717 These are emitted at the start of the function order.
718
719 * Use a greedy placement algorithm to place functions which
720 occur in the top 99% of the arcs in the profile. Some provisions
721 are made to handle high usage arcs where the parent and/or
722 child has already been placed.
723
724 * Run the same greedy placement algorithm on the remaining
725 arcs to place the leftover functions.
726
727
728 The various "magic numbers" should (one day) be tuneable by command
729 line options. They were arrived at by benchmarking a few applications
730 with various values to see which values produced better overall function
731 orderings.
732
733 Of course, profiling errors, machine limitations (PA long calls), and
734 poor cutoff values for the placement algorithm may limit the usefullness
735 of the resulting function order. Improvements would be greatly appreciated.
0eee5820 736
252b5132
RH
737 Suggestions:
738
739 * Place the functions with many callers near the middle of the
740 list to reduce long calls.
741
742 * Propagate arc usage changes as functions are placed. Ie if
743 func1 and func2 are placed together, arcs to/from those arcs
744 to the same parent/child should be combined, then resort the
745 arcs to choose the next one.
746
747 * Implement some global positioning algorithm to place the
748 chains made by the greedy local positioning algorithm. Probably
749 by examining arcs which haven't been placed yet to tie two
750 chains together.
751
752 * Take a function's size and time into account in the algorithm;
753 size in particular is important on the PA (long calls). Placing
754 many small functions onto their own page may be wise.
755
756 * Use better profiling information; many published algorithms
757 are based on call sequences through time, rather than just
758 arc counts.
759
760 * Prodecure cloning could improve performance when a small number
761 of arcs account for most of the calls to a particular function.
762
763 * Use relocation information to avoid moving unused functions
764 completely out of the code stream; this would avoid severe lossage
765 when the profile data bears little resemblance to actual runs.
766
767 * Propagation of arc usages should also improve .o link line
768 ordering which shares the same arc placement algorithm with
769 the function ordering code (in fact it is a degenerate case
770 of function ordering). */
0eee5820 771
252b5132 772void
1355568a 773cg_print_function_ordering ()
252b5132
RH
774{
775 unsigned long index, used, unused, scratch_index;
776 unsigned long unplaced_arc_count, high_arc_count, scratch_arc_count;
777#ifdef __GNUC__
778 unsigned long long total_arcs, tmp_arcs_count;
779#else
780 unsigned long total_arcs, tmp_arcs_count;
781#endif
782 Sym **unused_syms, **used_syms, **scratch_syms;
783 Arc **unplaced_arcs, **high_arcs, **scratch_arcs;
784
785 index = 0;
786 used = 0;
787 unused = 0;
788 scratch_index = 0;
789 unplaced_arc_count = 0;
790 high_arc_count = 0;
791 scratch_arc_count = 0;
792
793 /* First group all the unused functions together. */
794 unused_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *));
795 used_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *));
796 scratch_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *));
797 high_arcs = (Arc **) xmalloc (numarcs * sizeof (Arc *));
798 scratch_arcs = (Arc **) xmalloc (numarcs * sizeof (Arc *));
799 unplaced_arcs = (Arc **) xmalloc (numarcs * sizeof (Arc *));
800
801 /* Walk through all the functions; mark those which are never
802 called as placed (we'll emit them as a group later). */
803 for (index = 0, used = 0, unused = 0; index < symtab.len; index++)
804 {
805 if (symtab.base[index].ncalls == 0)
806 {
d401d98a
AM
807 unused_syms[unused++] = &symtab.base[index];
808 symtab.base[index].has_been_placed = 1;
252b5132
RH
809 }
810 else
811 {
812 used_syms[used++] = &symtab.base[index];
813 symtab.base[index].has_been_placed = 0;
814 symtab.base[index].next = 0;
815 symtab.base[index].prev = 0;
816 symtab.base[index].nuses = 0;
817 }
818 }
819
820 /* Sort the arcs from most used to least used. */
821 qsort (arcs, numarcs, sizeof (Arc *), cmp_arc_count);
822
823 /* Compute the total arc count. Also mark arcs as unplaced.
824
825 Note we don't compensate for overflow if that happens!
826 Overflow is much less likely when this file is compiled
827 with GCC as it can double-wide integers via long long. */
828 total_arcs = 0;
829 for (index = 0; index < numarcs; index++)
830 {
831 total_arcs += arcs[index]->count;
832 arcs[index]->has_been_placed = 0;
833 }
834
835 /* We want to pull out those functions which are referenced
836 by many highly used arcs and emit them as a group. This
837 could probably use some tuning. */
838 tmp_arcs_count = 0;
839 for (index = 0; index < numarcs; index++)
840 {
841 tmp_arcs_count += arcs[index]->count;
842
843 /* Count how many times each parent and child are used up
844 to our threshhold of arcs (90%). */
845 if ((double)tmp_arcs_count / (double)total_arcs > 0.90)
846 break;
847
848 arcs[index]->child->nuses++;
849 }
850
851 /* Now sort a temporary symbol table based on the number of
852 times each function was used in the highest used arcs. */
853 memcpy (scratch_syms, used_syms, used * sizeof (Sym *));
854 qsort (scratch_syms, used, sizeof (Sym *), cmp_fun_nuses);
855
856 /* Now pick out those symbols we're going to emit as
857 a group. We take up to 1.25% of the used symbols. */
858 for (index = 0; index < used / 80; index++)
859 {
860 Sym *sym = scratch_syms[index];
861 Arc *arc;
862
863 /* If we hit symbols that aren't used from many call sites,
864 then we can quit. We choose five as the low limit for
865 no particular reason. */
866 if (sym->nuses == 5)
867 break;
868
869 /* We're going to need the arcs between these functions.
870 Unfortunately, we don't know all these functions
871 until we're done. So we keep track of all the arcs
872 to the functions we care about, then prune out those
0eee5820 873 which are uninteresting.
252b5132
RH
874
875 An interesting variation would be to quit when we found
876 multi-call site functions which account for some percentage
877 of the arcs. */
252b5132 878 arc = sym->cg.children;
0eee5820 879
252b5132
RH
880 while (arc)
881 {
882 if (arc->parent != arc->child)
883 scratch_arcs[scratch_arc_count++] = arc;
884 arc->has_been_placed = 1;
885 arc = arc->next_child;
886 }
887
888 arc = sym->cg.parents;
0eee5820 889
252b5132
RH
890 while (arc)
891 {
892 if (arc->parent != arc->child)
893 scratch_arcs[scratch_arc_count++] = arc;
894 arc->has_been_placed = 1;
895 arc = arc->next_parent;
896 }
897
898 /* Keep track of how many symbols we're going to place. */
899 scratch_index = index;
900
ef368dac
NC
901 /* A lie, but it makes identifying
902 these functions easier later. */
252b5132
RH
903 sym->has_been_placed = 1;
904 }
905
ef368dac
NC
906 /* Now walk through the temporary arcs and copy
907 those we care about into the high arcs array. */
252b5132
RH
908 for (index = 0; index < scratch_arc_count; index++)
909 {
910 Arc *arc = scratch_arcs[index];
911
912 /* If this arc refers to highly used functions, then
913 then we want to keep it. */
914 if (arc->child->has_been_placed
915 && arc->parent->has_been_placed)
916 {
917 high_arcs[high_arc_count++] = scratch_arcs[index];
918
919 /* We need to turn of has_been_placed since we're going to
920 use the main arc placement algorithm on these arcs. */
921 arc->child->has_been_placed = 0;
922 arc->parent->has_been_placed = 0;
923 }
924 }
925
ef368dac
NC
926 /* Dump the multi-site high usage functions which are not
927 going to be ordered by the main ordering algorithm. */
252b5132
RH
928 for (index = 0; index < scratch_index; index++)
929 {
930 if (scratch_syms[index]->has_been_placed)
931 printf ("%s\n", scratch_syms[index]->name);
932 }
933
ef368dac
NC
934 /* Now we can order the multi-site high use
935 functions based on the arcs between them. */
252b5132
RH
936 qsort (high_arcs, high_arc_count, sizeof (Arc *), cmp_arc_count);
937 order_and_dump_functions_by_arcs (high_arcs, high_arc_count, 1,
938 unplaced_arcs, &unplaced_arc_count);
939
ef368dac
NC
940 /* Order and dump the high use functions left,
941 these typically have only a few call sites. */
252b5132
RH
942 order_and_dump_functions_by_arcs (arcs, numarcs, 0,
943 unplaced_arcs, &unplaced_arc_count);
944
945 /* Now place the rarely used functions. */
946 order_and_dump_functions_by_arcs (unplaced_arcs, unplaced_arc_count, 1,
947 scratch_arcs, &scratch_arc_count);
948
949 /* Output any functions not emitted by the order_and_dump calls. */
950 for (index = 0; index < used; index++)
951 if (used_syms[index]->has_been_placed == 0)
952 printf("%s\n", used_syms[index]->name);
953
954 /* Output the unused functions. */
955 for (index = 0; index < unused; index++)
956 printf("%s\n", unused_syms[index]->name);
957
958 unused_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *));
959 used_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *));
960 scratch_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *));
961 high_arcs = (Arc **) xmalloc (numarcs * sizeof (Arc *));
962 scratch_arcs = (Arc **) xmalloc (numarcs * sizeof (Arc *));
963 unplaced_arcs = (Arc **) xmalloc (numarcs * sizeof (Arc *));
964
965 free (unused_syms);
966 free (used_syms);
967 free (scratch_syms);
968 free (high_arcs);
969 free (scratch_arcs);
970 free (unplaced_arcs);
971}
972
1355568a 973/* Place functions based on the arcs in THE_ARCS with ARC_COUNT entries;
252b5132
RH
974 place unused arcs into UNPLACED_ARCS/UNPLACED_ARC_COUNT.
975
1355568a
AM
976 If ALL is nonzero, then place all functions referenced by THE_ARCS,
977 else only place those referenced in the top 99% of the arcs in THE_ARCS. */
252b5132
RH
978
979#define MOST 0.99
980static void
1355568a 981order_and_dump_functions_by_arcs (the_arcs, arc_count, all,
252b5132 982 unplaced_arcs, unplaced_arc_count)
1355568a
AM
983 Arc **the_arcs;
984 unsigned long arc_count;
252b5132
RH
985 int all;
986 Arc **unplaced_arcs;
987 unsigned long *unplaced_arc_count;
988{
989#ifdef __GNUC__
990 unsigned long long tmp_arcs, total_arcs;
991#else
992 unsigned long tmp_arcs, total_arcs;
993#endif
994 unsigned int index;
995
996 /* If needed, compute the total arc count.
997
998 Note we don't compensate for overflow if that happens! */
999 if (! all)
1000 {
1001 total_arcs = 0;
1355568a
AM
1002 for (index = 0; index < arc_count; index++)
1003 total_arcs += the_arcs[index]->count;
252b5132
RH
1004 }
1005 else
1006 total_arcs = 0;
1007
1008 tmp_arcs = 0;
0eee5820 1009
1355568a 1010 for (index = 0; index < arc_count; index++)
252b5132
RH
1011 {
1012 Sym *sym1, *sym2;
1013 Sym *child, *parent;
1014
1355568a 1015 tmp_arcs += the_arcs[index]->count;
252b5132
RH
1016
1017 /* Ignore this arc if it's already been placed. */
1355568a 1018 if (the_arcs[index]->has_been_placed)
252b5132
RH
1019 continue;
1020
1355568a
AM
1021 child = the_arcs[index]->child;
1022 parent = the_arcs[index]->parent;
252b5132
RH
1023
1024 /* If we're not using all arcs, and this is a rarely used
1025 arc, then put it on the unplaced_arc list. Similarly
1026 if both the parent and child of this arc have been placed. */
1027 if ((! all && (double)tmp_arcs / (double)total_arcs > MOST)
1028 || child->has_been_placed || parent->has_been_placed)
1029 {
1355568a 1030 unplaced_arcs[(*unplaced_arc_count)++] = the_arcs[index];
252b5132
RH
1031 continue;
1032 }
1033
1034 /* If all slots in the parent and child are full, then there isn't
1035 anything we can do right now. We'll place this arc on the
1036 unplaced arc list in the hope that a global positioning
1037 algorithm can use it to place function chains. */
1038 if (parent->next && parent->prev && child->next && child->prev)
1039 {
1355568a 1040 unplaced_arcs[(*unplaced_arc_count)++] = the_arcs[index];
252b5132
RH
1041 continue;
1042 }
1043
1044 /* If the parent is unattached, then find the closest
1045 place to attach it onto child's chain. Similarly
1046 for the opposite case. */
1047 if (!parent->next && !parent->prev)
1048 {
1049 int next_count = 0;
1050 int prev_count = 0;
1051 Sym *prev = child;
1052 Sym *next = child;
1053
1054 /* Walk to the beginning and end of the child's chain. */
1055 while (next->next)
1056 {
1057 next = next->next;
1058 next_count++;
1059 }
1060
1061 while (prev->prev)
1062 {
1063 prev = prev->prev;
1064 prev_count++;
1065 }
0eee5820 1066
252b5132
RH
1067 /* Choose the closest. */
1068 child = next_count < prev_count ? next : prev;
ef368dac 1069 }
252b5132
RH
1070 else if (! child->next && !child->prev)
1071 {
1072 int next_count = 0;
1073 int prev_count = 0;
1074 Sym *prev = parent;
1075 Sym *next = parent;
1076
1077 while (next->next)
1078 {
1079 next = next->next;
1080 next_count++;
1081 }
1082
1083 while (prev->prev)
1084 {
1085 prev = prev->prev;
1086 prev_count++;
1087 }
1088
1089 parent = prev_count < next_count ? prev : next;
1090 }
1091 else
1092 {
1093 /* Couldn't find anywhere to attach the functions,
1094 put the arc on the unplaced arc list. */
1355568a 1095 unplaced_arcs[(*unplaced_arc_count)++] = the_arcs[index];
252b5132
RH
1096 continue;
1097 }
1098
1099 /* Make sure we don't tie two ends together. */
1100 sym1 = parent;
1101 if (sym1->next)
1102 while (sym1->next)
1103 sym1 = sym1->next;
1104 else
1105 while (sym1->prev)
1106 sym1 = sym1->prev;
1107
1108 sym2 = child;
1109 if (sym2->next)
1110 while (sym2->next)
1111 sym2 = sym2->next;
1112 else
1113 while (sym2->prev)
1114 sym2 = sym2->prev;
1115
1116 if (sym1 == child
1117 && sym2 == parent)
1118 {
1119 /* This would tie two ends together. */
1355568a 1120 unplaced_arcs[(*unplaced_arc_count)++] = the_arcs[index];
252b5132
RH
1121 continue;
1122 }
1123
1124 if (parent->next)
1125 {
1126 /* Must attach to the parent's prev field. */
1127 if (! child->next)
1128 {
1129 /* parent-prev and child-next */
1130 parent->prev = child;
1131 child->next = parent;
1355568a 1132 the_arcs[index]->has_been_placed = 1;
252b5132
RH
1133 }
1134 }
1135 else if (parent->prev)
1136 {
1137 /* Must attach to the parent's next field. */
1138 if (! child->prev)
1139 {
1140 /* parent-next and child-prev */
1141 parent->next = child;
1142 child->prev = parent;
1355568a 1143 the_arcs[index]->has_been_placed = 1;
252b5132
RH
1144 }
1145 }
1146 else
1147 {
1148 /* Can attach to either field in the parent, depends
1149 on where we've got space in the child. */
1150 if (child->prev)
1151 {
ef368dac 1152 /* parent-prev and child-next. */
252b5132
RH
1153 parent->prev = child;
1154 child->next = parent;
1355568a 1155 the_arcs[index]->has_been_placed = 1;
252b5132
RH
1156 }
1157 else
1158 {
ef368dac 1159 /* parent-next and child-prev. */
252b5132
RH
1160 parent->next = child;
1161 child->prev = parent;
1355568a 1162 the_arcs[index]->has_been_placed = 1;
252b5132
RH
1163 }
1164 }
1165 }
1166
1167 /* Dump the chains of functions we've made. */
1355568a 1168 for (index = 0; index < arc_count; index++)
252b5132
RH
1169 {
1170 Sym *sym;
1355568a
AM
1171 if (the_arcs[index]->parent->has_been_placed
1172 || the_arcs[index]->child->has_been_placed)
252b5132
RH
1173 continue;
1174
1355568a 1175 sym = the_arcs[index]->parent;
252b5132
RH
1176
1177 /* If this symbol isn't attached to any other
1178 symbols, then we've got a rarely used arc.
1179
1180 Skip it for now, we'll deal with them later. */
1181 if (sym->next == NULL
1182 && sym->prev == NULL)
1183 continue;
1184
1185 /* Get to the start of this chain. */
1186 while (sym->prev)
1187 sym = sym->prev;
1188
1189 while (sym)
1190 {
1191 /* Mark it as placed. */
1192 sym->has_been_placed = 1;
1193 printf ("%s\n", sym->name);
1194 sym = sym->next;
1195 }
1196 }
1197
ef368dac
NC
1198 /* If we want to place all the arcs, then output
1199 those which weren't placed by the main algorithm. */
252b5132 1200 if (all)
1355568a 1201 for (index = 0; index < arc_count; index++)
252b5132
RH
1202 {
1203 Sym *sym;
1355568a
AM
1204 if (the_arcs[index]->parent->has_been_placed
1205 || the_arcs[index]->child->has_been_placed)
252b5132
RH
1206 continue;
1207
1355568a 1208 sym = the_arcs[index]->parent;
252b5132
RH
1209
1210 sym->has_been_placed = 1;
1211 printf ("%s\n", sym->name);
1212 }
1213}
1214
1215/* Print a suggested .o ordering for files on a link line based
1216 on profiling information. This uses the function placement
1217 code for the bulk of its work. */
1218
252b5132 1219void
1355568a 1220cg_print_file_ordering ()
252b5132
RH
1221{
1222 unsigned long scratch_arc_count, index;
1223 Arc **scratch_arcs;
252b5132
RH
1224 char *last;
1225
1226 scratch_arc_count = 0;
1227
1228 scratch_arcs = (Arc **) xmalloc (numarcs * sizeof (Arc *));
1229 for (index = 0; index < numarcs; index++)
1230 {
1231 if (! arcs[index]->parent->mapped
1232 || ! arcs[index]->child->mapped)
1233 arcs[index]->has_been_placed = 1;
1234 }
1235
1236 order_and_dump_functions_by_arcs (arcs, numarcs, 0,
1237 scratch_arcs, &scratch_arc_count);
1238
1239 /* Output .o's not handled by the main placement algorithm. */
1240 for (index = 0; index < symtab.len; index++)
1241 {
1242 if (symtab.base[index].mapped
1243 && ! symtab.base[index].has_been_placed)
1244 printf ("%s\n", symtab.base[index].name);
1245 }
1246
1247 /* Now output any .o's that didn't have any text symbols. */
1248 last = NULL;
1249 for (index = 0; index < symbol_map_count; index++)
1250 {
1251 unsigned int index2;
1252
ef368dac
NC
1253 /* Don't bother searching if this symbol
1254 is the same as the previous one. */
252b5132
RH
1255 if (last && !strcmp (last, symbol_map[index].file_name))
1256 continue;
1257
1258 for (index2 = 0; index2 < symtab.len; index2++)
1259 {
1260 if (! symtab.base[index2].mapped)
1261 continue;
1262
1263 if (!strcmp (symtab.base[index2].name, symbol_map[index].file_name))
1264 break;
1265 }
1266
ef368dac
NC
1267 /* If we didn't find it in the symbol table, then it must
1268 be a .o with no text symbols. Output it last. */
252b5132
RH
1269 if (index2 == symtab.len)
1270 printf ("%s\n", symbol_map[index].file_name);
1271 last = symbol_map[index].file_name;
0eee5820 1272 }
252b5132 1273}
This page took 0.440105 seconds and 4 git commands to generate.