cg_print.c

来自「基于4个mips核的noc设计」· C语言 代码 · 共 1,268 行 · 第 1/3 页

C
1,268
字号
/* cg_print.c -  Print routines for displaying call graphs.   Copyright 2000, 2001 Free Software Foundation, Inc.   This file is part of GNU Binutils.   This program is free software; you can redistribute it and/or modify   it under the terms of the GNU General Public License as published by   the Free Software Foundation; either version 2 of the License, or   (at your option) any later version.   This program is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the   GNU General Public License for more details.   You should have received a copy of the GNU General Public License   along with this program; if not, write to the Free Software   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA   02111-1307, USA.  */#include "libiberty.h"#include "cg_arcs.h"#include "cg_print.h"#include "hist.h"#include "utils.h"/* Return value of comparison functions used to sort tables.  */#define	LESSTHAN	-1#define	EQUALTO		0#define	GREATERTHAN	1static void order_and_dump_functions_by_arcs PARAMS ((Arc **, unsigned long,						      int, Arc **,						      unsigned long *));/* Declarations of automatically generated functions to output blurbs.  */extern void bsd_callg_blurb PARAMS ((FILE * fp));extern void fsf_callg_blurb PARAMS ((FILE * fp));double print_time = 0.0;static voidDEFUN_VOID (print_header){  if (first_output)    first_output = FALSE;  else    printf ("\f\n");  if (!bsd_style_output)    {      if (print_descriptions)	printf (_("\t\t     Call graph (explanation follows)\n\n"));      else	printf (_("\t\t\tCall graph\n\n"));    }  printf (_("\ngranularity: each sample hit covers %ld byte(s)"),	  (long) hist_scale * sizeof (UNIT));  if (print_time > 0.0)    printf (_(" for %.2f%% of %.2f seconds\n\n"),	    100.0 / print_time, print_time / hz);  else    {      printf (_(" no time propagated\n\n"));      /* This doesn't hurt, since all the numerators will be 0.0.  */      print_time = 1.0;    }  if (bsd_style_output)    {      printf ("%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s     %-8.8s\n",	      "", "", "", "", _("called"), _("total"), _("parents"));      printf ("%-6.6s %5.5s %7.7s %11.11s %7.7s+%-7.7s %-8.8s\t%5.5s\n",	      _("index"), _("%time"), _("self"), _("descendents"),	      _("called"), _("self"), _("name"), _("index"));      printf ("%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s     %-8.8s\n",	      "", "", "", "", _("called"), _("total"), _("children"));      printf ("\n");    }  else    {      printf (_("index %% time    self  children    called     name\n"));    }}/* Print a cycle header.  */static voidDEFUN (print_cycle, (cyc), Sym * cyc){  char buf[BUFSIZ];  sprintf (buf, "[%d]", cyc->cg.index);  printf (bsd_style_output	  ? "%-6.6s %5.1f %7.2f %11.2f %7lu"	  : "%-6.6s %5.1f %7.2f %7.2f %7lu", buf,	  100 * (cyc->cg.prop.self + cyc->cg.prop.child) / print_time,	  cyc->cg.prop.self / hz, cyc->cg.prop.child / hz, cyc->ncalls);  if (cyc->cg.self_calls != 0)    printf ("+%-7lu", cyc->cg.self_calls);  else    printf (" %7.7s", "");  printf (_(" <cycle %d as a whole> [%d]\n"), cyc->cg.cyc.num, cyc->cg.index);}/* Compare LEFT and RIGHT membmer.  Major comparison key is   CG.PROP.SELF+CG.PROP.CHILD, secondary key is NCALLS+CG.SELF_CALLS.  */static intDEFUN (cmp_member, (left, right), Sym * left AND Sym * right){  double left_time = left->cg.prop.self + left->cg.prop.child;  double right_time = right->cg.prop.self + right->cg.prop.child;  unsigned long left_calls = left->ncalls + left->cg.self_calls;  unsigned long right_calls = right->ncalls + right->cg.self_calls;  if (left_time > right_time)    return GREATERTHAN;  if (left_time < right_time)    return LESSTHAN;  if (left_calls > right_calls)    return GREATERTHAN;  if (left_calls < right_calls)    return LESSTHAN;  return EQUALTO;}/* Sort members of a cycle.  */static voidDEFUN (sort_members, (cyc), Sym * cyc){  Sym *todo, *doing, *prev;  /* Detach cycle members from cyclehead,     and insertion sort them back on.  */  todo = cyc->cg.cyc.next;  cyc->cg.cyc.next = 0;  for (doing = todo; doing && doing->cg.cyc.next; doing = todo)    {      todo = doing->cg.cyc.next;      for (prev = cyc; prev->cg.cyc.next; prev = prev->cg.cyc.next)	{	  if (cmp_member (doing, prev->cg.cyc.next) == GREATERTHAN)	    break;	}      doing->cg.cyc.next = prev->cg.cyc.next;      prev->cg.cyc.next = doing;    }}/* Print the members of a cycle.  */static voidDEFUN (print_members, (cyc), Sym * cyc){  Sym *member;  sort_members (cyc);  for (member = cyc->cg.cyc.next; member; member = member->cg.cyc.next)    {      printf (bsd_style_output	      ? "%6.6s %5.5s %7.2f %11.2f %7lu"	      : "%6.6s %5.5s %7.2f %7.2f %7lu",	      "", "", member->cg.prop.self / hz, member->cg.prop.child / hz,	      member->ncalls);      if (member->cg.self_calls != 0)	printf ("+%-7lu", member->cg.self_calls);      else	printf (" %7.7s", "");      printf ("     ");      print_name (member);      printf ("\n");    }}/* Compare two arcs to/from the same child/parent.	- if one arc is a self arc, it's least.	- if one arc is within a cycle, it's less than.	- if both arcs are within a cycle, compare arc counts.	- if neither arc is within a cycle, compare with		time + child_time as major key		arc count as minor key.  */static intDEFUN (cmp_arc, (left, right), Arc * left AND Arc * right){  Sym *left_parent = left->parent;  Sym *left_child = left->child;  Sym *right_parent = right->parent;  Sym *right_child = right->child;  double left_time, right_time;  DBG (TIMEDEBUG,       printf ("[cmp_arc] ");       print_name (left_parent);       printf (" calls ");       print_name (left_child);       printf (" %f + %f %lu/%lu\n", left->time, left->child_time,	       left->count, left_child->ncalls);       printf ("[cmp_arc] ");       print_name (right_parent);       printf (" calls ");       print_name (right_child);       printf (" %f + %f %lu/%lu\n", right->time, right->child_time,	       right->count, right_child->ncalls);       printf ("\n");    );  if (left_parent == left_child)    return LESSTHAN;		/* Left is a self call.  */  if (right_parent == right_child)    return GREATERTHAN;		/* Right is a self call.  */  if (left_parent->cg.cyc.num != 0 && left_child->cg.cyc.num != 0      && left_parent->cg.cyc.num == left_child->cg.cyc.num)    {      /* Left is a call within a cycle.  */      if (right_parent->cg.cyc.num != 0 && right_child->cg.cyc.num != 0	  && right_parent->cg.cyc.num == right_child->cg.cyc.num)	{	  /* Right is a call within the cycle, too.  */	  if (left->count < right->count)	    return LESSTHAN;	  if (left->count > right->count)	    return GREATERTHAN;	  return EQUALTO;	}      else	{	  /* Right isn't a call within the cycle.  */	  return LESSTHAN;	}    }  else    {      /* Left isn't a call within a cycle.  */      if (right_parent->cg.cyc.num != 0 && right_child->cg.cyc.num != 0	  && right_parent->cg.cyc.num == right_child->cg.cyc.num)	{	  /* Right is a call within a cycle.  */	  return GREATERTHAN;	}      else	{	  /* Neither is a call within a cycle.  */	  left_time = left->time + left->child_time;	  right_time = right->time + right->child_time;	  if (left_time < right_time)	    return LESSTHAN;	  if (left_time > right_time)	    return GREATERTHAN;	  if (left->count < right->count)	    return LESSTHAN;	  if (left->count > right->count)	    return GREATERTHAN;	  return EQUALTO;	}    }}static voidDEFUN (sort_parents, (child), Sym * child){  Arc *arc, *detached, sorted, *prev;  /* Unlink parents from child, then insertion sort back on to     sorted's parents.	  *arc        the arc you have detached and are inserting.	  *detached   the rest of the arcs to be sorted.	  sorted      arc list onto which you insertion sort.	  *prev       arc before the arc you are comparing.  */  sorted.next_parent = 0;  for (arc = child->cg.parents; arc; arc = detached)    {      detached = arc->next_parent;      /* Consider *arc as disconnected; insert it into sorted.  */      for (prev = &sorted; prev->next_parent; prev = prev->next_parent)	{	  if (cmp_arc (arc, prev->next_parent) != GREATERTHAN)	    break;	}      arc->next_parent = prev->next_parent;      prev->next_parent = arc;    }  /* Reattach sorted arcs to child.  */  child->cg.parents = sorted.next_parent;}static voidDEFUN (print_parents, (child), Sym * child){  Sym *parent;  Arc *arc;  Sym *cycle_head;  if (child->cg.cyc.head != 0)    cycle_head = child->cg.cyc.head;  else    cycle_head = child;  if (!child->cg.parents)    {      printf (bsd_style_output	      ? _("%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s     <spontaneous>\n")	      : _("%6.6s %5.5s %7.7s %7.7s %7.7s %7.7s     <spontaneous>\n"),	      "", "", "", "", "", "");      return;    }  sort_parents (child);  for (arc = child->cg.parents; arc; arc = arc->next_parent)    {      parent = arc->parent;      if (child == parent || (child->cg.cyc.num != 0			      && parent->cg.cyc.num == child->cg.cyc.num))	{	  /* Selfcall or call among siblings.  */	  printf (bsd_style_output		  ? "%6.6s %5.5s %7.7s %11.11s %7lu %7.7s     "		  : "%6.6s %5.5s %7.7s %7.7s %7lu %7.7s     ",		  "", "", "", "",		  arc->count, "");	  print_name (parent);	  printf ("\n");	}      else	{	  /* Regular parent of child.  */	  printf (bsd_style_output		  ? "%6.6s %5.5s %7.2f %11.2f %7lu/%-7lu     "		  : "%6.6s %5.5s %7.2f %7.2f %7lu/%-7lu     ",		  "", "",		  arc->time / hz, arc->child_time / hz,		  arc->count, cycle_head->ncalls);	  print_name (parent);	  printf ("\n");	}    }}static voidDEFUN (sort_children, (parent), Sym * parent){  Arc *arc, *detached, sorted, *prev;  /* Unlink children from parent, then insertion sort back on to     sorted's children.	  *arc        the arc you have detached and are inserting.	  *detached   the rest of the arcs to be sorted.	  sorted      arc list onto which you insertion sort.	  *prev       arc before the arc you are comparing.  */  sorted.next_child = 0;  for (arc = parent->cg.children; arc; arc = detached)    {      detached = arc->next_child;      /* Consider *arc as disconnected; insert it into sorted.  */      for (prev = &sorted; prev->next_child; prev = prev->next_child)	{	  if (cmp_arc (arc, prev->next_child) != LESSTHAN)	    break;	}      arc->next_child = prev->next_child;      prev->next_child = arc;    }  /* Reattach sorted children to parent.  */  parent->cg.children = sorted.next_child;}static voidDEFUN (print_children, (parent), Sym * parent){  Sym *child;  Arc *arc;  sort_children (parent);  arc = parent->cg.children;  for (arc = parent->cg.children; arc; arc = arc->next_child)    {      child = arc->child;      if (child == parent || (child->cg.cyc.num != 0			      && child->cg.cyc.num == parent->cg.cyc.num))	{	  /* Self call or call to sibling.  */	  printf (bsd_style_output

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?