cg_arcs.c

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

C
686
字号
  head = child->cg.cyc.head;  if (child == head)    {      /* just a regular child, check its parents: */      child->cg.print_flag = FALSE;      child->cg.prop.fract = 0.0;      for (arc = child->cg.parents; arc; arc = arc->next_parent)	{	  parent = arc->parent;	  if (child == parent)	    {	      continue;	    }	  child->cg.print_flag |= parent->cg.print_flag;	  /*	   * If the child was never actually called (e.g., this arc	   * is static (and all others are, too)) no time propagates	   * along this arc.	   */	  if (child->ncalls != 0)	    {	      child->cg.prop.fract += parent->cg.prop.fract		* (((double) arc->count) / ((double) child->ncalls));	    }	}    }  else    {      /*       * Its a member of a cycle, look at all parents from outside       * the cycle.       */      head->cg.print_flag = FALSE;      head->cg.prop.fract = 0.0;      for (member = head->cg.cyc.next; member; member = member->cg.cyc.next)	{	  for (arc = member->cg.parents; arc; arc = arc->next_parent)	    {	      if (arc->parent->cg.cyc.head == head)		{		  continue;		}	      parent = arc->parent;	      head->cg.print_flag |= parent->cg.print_flag;	      /*	       * If the cycle was never actually called (e.g. this	       * arc is static (and all others are, too)) no time	       * propagates along this arc.	       */	      if (head->ncalls != 0)		{		  head->cg.prop.fract += parent->cg.prop.fract		    * (((double) arc->count) / ((double) head->ncalls));		}	    }	}      for (member = head; member; member = member->cg.cyc.next)	{	  member->cg.print_flag = head->cg.print_flag;	  member->cg.prop.fract = head->cg.prop.fract;	}    }}/* * In one top-to-bottom pass over the topologically sorted symbols * propagate: *      cg.print_flag as the union of parents' print_flags *      propfraction as the sum of fractional parents' propfractions * and while we're here, sum time for functions. */static voidDEFUN (propagate_flags, (symbols), Sym ** symbols){  int index;  Sym *old_head, *child;  old_head = 0;  for (index = symtab.len - 1; index >= 0; --index)    {      child = symbols[index];      /*       * If we haven't done this function or cycle, inherit things       * from parent.  This way, we are linear in the number of arcs       * since we do all members of a cycle (and the cycle itself)       * as we hit the first member of the cycle.       */      if (child->cg.cyc.head != old_head)	{	  old_head = child->cg.cyc.head;	  inherit_flags (child);	}      DBG (PROPDEBUG,	   printf ("[prop_flags] ");	   print_name (child);	   printf ("inherits print-flag %d and prop-fract %f\n",		   child->cg.print_flag, child->cg.prop.fract));      if (!child->cg.print_flag)	{	  /*	   * Printflag is off. It gets turned on by being in the	   * INCL_GRAPH table, or there being an empty INCL_GRAPH	   * table and not being in the EXCL_GRAPH table.	   */	  if (sym_lookup (&syms[INCL_GRAPH], child->addr)	      || (syms[INCL_GRAPH].len == 0		  && !sym_lookup (&syms[EXCL_GRAPH], child->addr)))	    {	      child->cg.print_flag = TRUE;	    }	}      else	{	  /*	   * This function has printing parents: maybe someone wants	   * to shut it up by putting it in the EXCL_GRAPH table.	   * (But favor INCL_GRAPH over EXCL_GRAPH.)	   */	  if (!sym_lookup (&syms[INCL_GRAPH], child->addr)	      && sym_lookup (&syms[EXCL_GRAPH], child->addr))	    {	      child->cg.print_flag = FALSE;	    }	}      if (child->cg.prop.fract == 0.0)	{	  /*	   * No parents to pass time to.  Collect time from children	   * if its in the INCL_TIME table, or there is an empty	   * INCL_TIME table and its not in the EXCL_TIME table.	   */	  if (sym_lookup (&syms[INCL_TIME], child->addr)	      || (syms[INCL_TIME].len == 0		  && !sym_lookup (&syms[EXCL_TIME], child->addr)))	    {	      child->cg.prop.fract = 1.0;	    }	}      else	{	  /*	   * It has parents to pass time to, but maybe someone wants	   * to shut it up by puttting it in the EXCL_TIME table.	   * (But favor being in INCL_TIME tabe over being in	   * EXCL_TIME table.)	   */	  if (!sym_lookup (&syms[INCL_TIME], child->addr)	      && sym_lookup (&syms[EXCL_TIME], child->addr))	    {	      child->cg.prop.fract = 0.0;	    }	}      child->cg.prop.self = child->hist.time * child->cg.prop.fract;      print_time += child->cg.prop.self;      DBG (PROPDEBUG,	   printf ("[prop_flags] ");	   print_name (child);	   printf (" ends up with printflag %d and prop-fract %f\n",		   child->cg.print_flag, child->cg.prop.fract);	   printf ("[prop_flags] time %f propself %f print_time %f\n",		   child->hist.time, child->cg.prop.self, print_time));    }}/* * Compare by decreasing propagated time.  If times are equal, but one * is a cycle header, say that's first (e.g. less, i.e. -1).  If one's * name doesn't have an underscore and the other does, say that one is * first.  All else being equal, compare by names. */static intDEFUN (cmp_total, (lp, rp), const PTR lp AND const PTR rp){  const Sym *left = *(const Sym **) lp;  const Sym *right = *(const Sym **) rp;  double diff;  diff = (left->cg.prop.self + left->cg.prop.child)    - (right->cg.prop.self + right->cg.prop.child);  if (diff < 0.0)    {      return 1;    }  if (diff > 0.0)    {      return -1;    }  if (!left->name && left->cg.cyc.num != 0)    {      return -1;    }  if (!right->name && right->cg.cyc.num != 0)    {      return 1;    }  if (!left->name)    {      return -1;    }  if (!right->name)    {      return 1;    }  if (left->name[0] != '_' && right->name[0] == '_')    {      return -1;    }  if (left->name[0] == '_' && right->name[0] != '_')    {      return 1;    }  if (left->ncalls > right->ncalls)    {      return -1;    }  if (left->ncalls < right->ncalls)    {      return 1;    }  return strcmp (left->name, right->name);}/* * Topologically sort the graph (collapsing cycles), and propagates * time bottom up and flags top down. */Sym **DEFUN_VOID (cg_assemble){  Sym *parent, **time_sorted_syms, **top_sorted_syms;  unsigned int index;  Arc *arc;  /*   * initialize various things:   *      zero out child times.   *      count self-recursive calls.   *      indicate that nothing is on cycles.   */  for (parent = symtab.base; parent < symtab.limit; parent++)    {      parent->cg.child_time = 0.0;      arc = arc_lookup (parent, parent);      if (arc && parent == arc->child)	{	  parent->ncalls -= arc->count;	  parent->cg.self_calls = arc->count;	}      else	{	  parent->cg.self_calls = 0;	}      parent->cg.prop.fract = 0.0;      parent->cg.prop.self = 0.0;      parent->cg.prop.child = 0.0;      parent->cg.print_flag = FALSE;      parent->cg.top_order = DFN_NAN;      parent->cg.cyc.num = 0;      parent->cg.cyc.head = parent;      parent->cg.cyc.next = 0;      if (ignore_direct_calls)	{	  find_call (parent, parent->addr, (parent + 1)->addr);	}    }  /*   * Topologically order things.  If any node is unnumbered, number   * it and any of its descendents.   */  for (parent = symtab.base; parent < symtab.limit; parent++)    {      if (parent->cg.top_order == DFN_NAN)	{	  cg_dfn (parent);	}    }  /* link together nodes on the same cycle: */  cycle_link ();  /* sort the symbol table in reverse topological order: */  top_sorted_syms = (Sym **) xmalloc (symtab.len * sizeof (Sym *));  for (index = 0; index < symtab.len; ++index)    {      top_sorted_syms[index] = &symtab.base[index];    }  qsort (top_sorted_syms, symtab.len, sizeof (Sym *), cmp_topo);  DBG (DFNDEBUG,       printf ("[cg_assemble] topological sort listing\n");       for (index = 0; index < symtab.len; ++index)       {       printf ("[cg_assemble] ");       printf ("%d:", top_sorted_syms[index]->cg.top_order);       print_name (top_sorted_syms[index]);       printf ("\n");       }  );  /*   * Starting from the topological top, propagate print flags to   * children.  also, calculate propagation fractions.  this happens   * before time propagation since time propagation uses the   * fractions.   */  propagate_flags (top_sorted_syms);  /*   * Starting from the topological bottom, propogate children times   * up to parents.   */  cycle_time ();  for (index = 0; index < symtab.len; ++index)    {      propagate_time (top_sorted_syms[index]);    }  free (top_sorted_syms);  /*   * Now, sort by CG.PROP.SELF + CG.PROP.CHILD.  Sorting both the regular   * function names and cycle headers.   */  time_sorted_syms = (Sym **) xmalloc ((symtab.len + num_cycles) * sizeof (Sym *));  for (index = 0; index < symtab.len; index++)    {      time_sorted_syms[index] = &symtab.base[index];    }  for (index = 1; index <= num_cycles; index++)    {      time_sorted_syms[symtab.len + index - 1] = &cycle_header[index];    }  qsort (time_sorted_syms, symtab.len + num_cycles, sizeof (Sym *),	 cmp_total);  for (index = 0; index < symtab.len + num_cycles; index++)    {      time_sorted_syms[index]->cg.index = index + 1;    }  return time_sorted_syms;}

⌨️ 快捷键说明

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