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