xref: /csrg-svn/usr.bin/gprof/printgprof.c (revision 4562)
14515Speter #ifndef lint
2*4562Speter     static	char *sccsid = "@(#)printgprof.c	1.2 (Berkeley) 10/20/81";
34515Speter #endif lint
44515Speter 
5*4562Speter #include "gprof.h"
64515Speter 
7*4562Speter printgprof()
84515Speter {
94515Speter     nltype	**timesortnlp;
104515Speter     int		index;
114515Speter     nltype	*parentp;
124515Speter     nltype	*childp;
134515Speter 
144515Speter 	/*
154515Speter 	 *	Now, sort by time + childtime.
164515Speter 	 *	include the cycle headers hiding out past nl[nname].
174515Speter 	 */
184515Speter     timesortnlp = (nltype **) calloc( nname+1+cyclemax , sizeof(nltype *) );
194515Speter     if ( timesortnlp == (nltype **) 0 ) {
204515Speter 	fprintf( stderr , "[doarcs] ran out of memory for sorting\n" );
214515Speter     }
224515Speter     for ( index = 0 ; index < nname+1+cyclemax ; index++ ) {
234515Speter 	timesortnlp[index] = &nl[index];
244515Speter     }
254515Speter     qsort( timesortnlp , nname+1+cyclemax , sizeof(nltype *) , totalcmp );
264515Speter     for ( index = 0 ; index < nname+1+cyclemax ; index++ ) {
274515Speter 	timesortnlp[ index ] -> index = index + 1;
284515Speter     }
294515Speter 	/*
304515Speter 	 *	Now, print out the structured profiling list
314515Speter 	 */
324515Speter     actime = 0.0;
334515Speter     printf( "\f" );
344515Speter     putprofheader();
354515Speter     for ( index = 0 ; index < nname + 1 + cyclemax ; index ++ ) {
364515Speter 	parentp = timesortnlp[ index ];
374515Speter 	if ( zflg == 0 &&
384515Speter 	     parentp -> ncall == 0 &&
394515Speter 	     parentp -> selfcalls == 0 &&
404515Speter 	     parentp -> time == 0 &&
414515Speter 	     parentp -> childtime == 0 ) {
424515Speter 	    continue;
434515Speter 	}
444515Speter 	if ( parentp -> name == 0 && parentp -> cycleno != 0 ) {
454515Speter 		/*
464515Speter 		 *	cycle header
474515Speter 		 */
484515Speter 	    putprofline( parentp , 0 );
494515Speter 	    for ( childp = parentp->cnext ; childp ; childp = childp->cnext ) {
504515Speter 		putprofline( childp , 0 );
514515Speter 	    }
524515Speter 	} else {
534515Speter 	    printparents( parentp );
544515Speter 	    putprofline( parentp , 1 );
554515Speter 	    printchildren( parentp );
564515Speter 	}
574515Speter 	printf( "\n" );
584515Speter     }
594515Speter     actime = 0.0;
604515Speter }
614515Speter 
624515Speter printparents( childp )
634515Speter     nltype	*childp;
644515Speter {
654515Speter     nltype	*parentp;
664515Speter     arctype	*arcp;
674515Speter     nltype	*cycleheadp;
684515Speter 
694515Speter     if ( childp -> cyclehead != 0 ) {
704515Speter 	cycleheadp = childp -> cyclehead;
714515Speter     } else {
724515Speter 	cycleheadp = childp;
734515Speter     }
744515Speter     if ( childp -> parents == 0 ) {
754515Speter 	printf( "\t%5.5s %7.7s %7.7s %7.7s %7.7s %7.7s      <spontaneous>\n" ,
764515Speter 		"" , "" , "" , "" , "" , "" );
774515Speter 	return;
784515Speter     }
794515Speter     sortparents( childp );
804515Speter     for ( arcp = childp -> parents ; arcp ; arcp = arcp -> arc_parentlist ) {
814515Speter 	parentp = arcp -> arc_parentp;
824515Speter 	if ( childp == parentp ||
834515Speter 	     ( childp->cycleno != 0 && parentp->cycleno == childp->cycleno ) ) {
844515Speter 		/*
854515Speter 		 *	selfcall or call amoung siblings
864515Speter 		 */
874515Speter 	    printf( "\t%5.5s %7.7s %7.7s %7.7s %7d %7.7s      " ,
884515Speter 		    "" , "" , "" , "" ,
894515Speter 		    arcp -> arc_count , "" );
904515Speter 	    printname( parentp );
914515Speter 	    printf( "\n" );
924515Speter 	} else {
934515Speter 		/*
944515Speter 		 *	regular parent of child
954515Speter 		 */
964515Speter 	    printf( "\t%5.5s %7.7s %7.1f %7.1f %7d/%-7d      " , "" , "" ,
974515Speter 		    arcp -> arc_time / HZ , arcp -> arc_childtime / HZ ,
984515Speter 		    arcp -> arc_count , cycleheadp -> ncall );
994515Speter 	    printname( parentp );
1004515Speter 	    printf( "\n" );
1014515Speter 	}
1024515Speter     }
1034515Speter }
1044515Speter 
1054515Speter printchildren( parentp )
1064515Speter     nltype	*parentp;
1074515Speter {
1084515Speter     nltype	*childp;
1094515Speter     arctype	*arcp;
1104515Speter 
1114515Speter     sortchildren( parentp );
1124515Speter     arcp = parentp -> children;
1134515Speter     for ( arcp = parentp -> children ; arcp ; arcp = arcp -> arc_childlist ) {
1144515Speter 	childp = arcp -> arc_childp;
1154515Speter 	if ( childp == parentp ||
1164515Speter 	    ( childp->cycleno != 0 && childp->cycleno == parentp->cycleno ) ) {
1174515Speter 		/*
1184515Speter 		 *	self call or call to sibling
1194515Speter 		 */
1204515Speter 	    printf( "\t%5.5s %7.7s %7.7s %7.7s %7d %7.7s      " ,
1214515Speter 		    "" , "" , "" , "" ,
1224515Speter 		    arcp -> arc_count , "" );
1234515Speter 	    printname( childp );
1244515Speter 	    printf( "\n" );
1254515Speter 	} else {
1264515Speter 		/*
1274515Speter 		 *	regular child of parent
1284515Speter 		 */
1294515Speter 	    printf( "\t%5.5s %7.7s %7.1f %7.1f %7d/%-7d      " , "" , "" ,
1304515Speter 		    arcp -> arc_time / HZ , arcp -> arc_childtime / HZ ,
1314515Speter 		    arcp -> arc_count , childp -> cyclehead -> ncall );
1324515Speter 	    printname( childp );
1334515Speter 	    printf( "\n" );
1344515Speter 	}
1354515Speter     }
1364515Speter }
1374515Speter 
1384515Speter printname( selfp )
1394515Speter     nltype	*selfp;
1404515Speter {
1414515Speter 
1424515Speter     if ( selfp -> name != 0 ) {
1434515Speter 	printf( "%s\t" , selfp -> name );
1444515Speter 	if ( selfp -> index != 0 ) {
1454515Speter 	    printf( "[%d] " , selfp -> index );
1464515Speter 	}
1474515Speter #	ifdef DEBUG
1484515Speter 	    if ( debug & DFNDEBUG ) {
1494515Speter 		printf( "{%d} " , selfp -> toporder );
1504515Speter 	    }
1514515Speter #	endif DEBUG
1524515Speter     }
1534515Speter     if ( selfp -> cycleno != 0 ) {
1544515Speter 	printf( "<cycle %d>" , selfp -> cycleno );
1554515Speter     }
1564515Speter }
1574515Speter 
1584515Speter sortchildren( parentp )
1594515Speter     nltype	*parentp;
1604515Speter {
1614515Speter     arctype	*arcp;
1624515Speter     arctype	*detachedp;
1634515Speter     arctype	sorted;
1644515Speter     arctype	*prevp;
1654515Speter 
1664515Speter 	/*
1674515Speter 	 *	unlink children from parent,
1684515Speter 	 *	then insertion sort back on to sorted's children.
1694515Speter 	 *	    *arcp	the arc you have detached and are inserting.
1704515Speter 	 *	    *detachedp	the rest of the arcs to be sorted.
1714515Speter 	 *	    sorted	arc list onto which you insertion sort.
1724515Speter 	 *	    *prevp	arc before the arc you are comparing.
1734515Speter 	 */
1744515Speter     sorted.arc_childlist = 0;
1754515Speter     for (   arcp = parentp -> children , detachedp = arcp -> arc_childlist ;
1764515Speter 	    arcp ;
1774515Speter 	    arcp = detachedp , detachedp = detachedp -> arc_childlist ) {
1784515Speter 	    /*
1794515Speter 	     *	consider *arcp as disconnected
1804515Speter 	     *	insert it into sorted
1814515Speter 	     */
1824515Speter 	for (   prevp = &sorted ;
1834515Speter 		prevp -> arc_childlist ;
1844515Speter 		prevp = prevp -> arc_childlist ) {
1854515Speter 	    if ( arccmp( arcp , prevp -> arc_childlist ) != LESSTHAN ) {
1864515Speter 		break;
1874515Speter 	    }
1884515Speter 	}
1894515Speter 	arcp -> arc_childlist = prevp -> arc_childlist;
1904515Speter 	prevp -> arc_childlist = arcp;
1914515Speter     }
1924515Speter 	/*
1934515Speter 	 *	reattach sorted children to parent
1944515Speter 	 */
1954515Speter     parentp -> children = sorted.arc_childlist;
1964515Speter }
1974515Speter 
1984515Speter sortparents( childp )
1994515Speter     nltype	*childp;
2004515Speter {
2014515Speter     arctype	*arcp;
2024515Speter     arctype	*detachedp;
2034515Speter     arctype	sorted;
2044515Speter     arctype	*prevp;
2054515Speter 
2064515Speter 	/*
2074515Speter 	 *	unlink parents from child,
2084515Speter 	 *	then insertion sort back on to sorted's parents.
2094515Speter 	 *	    *arcp	the arc you have detached and are inserting.
2104515Speter 	 *	    *detachedp	the rest of the arcs to be sorted.
2114515Speter 	 *	    sorted	arc list onto which you insertion sort.
2124515Speter 	 *	    *prevp	arc before the arc you are comparing.
2134515Speter 	 */
2144515Speter     sorted.arc_parentlist = 0;
2154515Speter     for (   arcp = childp -> parents , detachedp = arcp -> arc_parentlist ;
2164515Speter 	    arcp ;
2174515Speter 	    arcp = detachedp , detachedp = detachedp -> arc_parentlist ) {
2184515Speter 	    /*
2194515Speter 	     *	consider *arcp as disconnected
2204515Speter 	     *	insert it into sorted
2214515Speter 	     */
2224515Speter 	for (   prevp = &sorted ;
2234515Speter 		prevp -> arc_parentlist ;
2244515Speter 		prevp = prevp -> arc_parentlist ) {
2254515Speter 	    if ( arccmp( arcp , prevp -> arc_parentlist ) != GREATERTHAN ) {
2264515Speter 		break;
2274515Speter 	    }
2284515Speter 	}
2294515Speter 	arcp -> arc_parentlist = prevp -> arc_parentlist;
2304515Speter 	prevp -> arc_parentlist = arcp;
2314515Speter     }
2324515Speter 	/*
2334515Speter 	 *	reattach sorted arcs to child
2344515Speter 	 */
2354515Speter     childp -> parents = sorted.arc_parentlist;
2364515Speter }
2374515Speter 
2384515Speter     /*
2394515Speter      *	compare two arcs to/from the same child/parent.
2404515Speter      *	- if one arc is a self arc, it's least.
2414515Speter      *	- if one arc is within a cycle, it's less than.
2424515Speter      *	- if both arcs are within a cycle, compare arc counts.
2434515Speter      *	- if neither arc is within a cycle, compare with
2444515Speter      *		time + childtime as major key
2454515Speter      *		arc count as minor key
2464515Speter      */
2474515Speter int
2484515Speter arccmp( thisp , thatp )
2494515Speter     arctype	*thisp;
2504515Speter     arctype	*thatp;
2514515Speter {
2524515Speter     nltype	*thisparentp = thisp -> arc_parentp;
2534515Speter     nltype	*thischildp = thisp -> arc_childp;
2544515Speter     nltype	*thatparentp = thatp -> arc_parentp;
2554515Speter     nltype	*thatchildp = thatp -> arc_childp;
2564515Speter     double	thistime;
2574515Speter     double	thattime;
2584515Speter 
2594515Speter #   ifdef DEBUG
2604515Speter 	if ( debug & TIMEDEBUG ) {
2614515Speter 	    printf( "[arccmp] " );
2624515Speter 	    printname( thisparentp );
2634515Speter 	    printf( " calls " );
2644515Speter 	    printname ( thischildp );
2654515Speter 	    printf( " %f + %f %d/%d\n" ,
2664515Speter 		    thisp -> arc_time , thisp -> arc_childtime ,
2674515Speter 		    thisp -> arc_count , thischildp -> ncall );
2684515Speter 	    printf( "[arccmp] " );
2694515Speter 	    printname( thatparentp );
2704515Speter 	    printf( " calls " );
2714515Speter 	    printname( thatchildp );
2724515Speter 	    printf( " %f + %f %d/%d\n" ,
2734515Speter 		    thatp -> arc_time , thatp -> arc_childtime ,
2744515Speter 		    thatp -> arc_count , thatchildp -> ncall );
2754515Speter 	    printf( "\n" );
2764515Speter 	}
2774515Speter #   endif DEBUG
2784515Speter     if ( thisparentp == thischildp ) {
2794515Speter 	    /* this is a self call */
2804515Speter 	return LESSTHAN;
2814515Speter     }
2824515Speter     if ( thatparentp == thatchildp ) {
2834515Speter 	    /* that is a self call */
2844515Speter 	return GREATERTHAN;
2854515Speter     }
2864515Speter     if ( thisparentp -> cycleno != 0 && thischildp -> cycleno != 0 &&
2874515Speter 	thisparentp -> cycleno == thischildp -> cycleno ) {
2884515Speter 	    /* this is a call within a cycle */
2894515Speter 	if ( thatparentp -> cycleno != 0 && thatchildp -> cycleno != 0 &&
2904515Speter 	    thatparentp -> cycleno == thatchildp -> cycleno ) {
2914515Speter 		/* that is a call within the cycle, too */
2924515Speter 	    if ( thisp -> arc_count < thatp -> arc_count ) {
2934515Speter 		return LESSTHAN;
2944515Speter 	    }
2954515Speter 	    if ( thisp -> arc_count > thatp -> arc_count ) {
2964515Speter 		return GREATERTHAN;
2974515Speter 	    }
2984515Speter 	    return EQUALTO;
2994515Speter 	} else {
3004515Speter 		/* that isn't a call within the cycle */
3014515Speter 	    return LESSTHAN;
3024515Speter 	}
3034515Speter     } else {
3044515Speter 	    /* this isn't a call within a cycle */
3054515Speter 	if ( thatparentp -> cycleno != 0 && thatchildp -> cycleno != 0 &&
3064515Speter 	    thatparentp -> cycleno == thatchildp -> cycleno ) {
3074515Speter 		/* that is a call within a cycle */
3084515Speter 	    return GREATERTHAN;
3094515Speter 	} else {
3104515Speter 		/* neither is a call within a cycle */
3114515Speter 	    thistime = thisp -> arc_time + thisp -> arc_childtime;
3124515Speter 	    thattime = thatp -> arc_time + thatp -> arc_childtime;
3134515Speter 	    if ( thistime < thattime )
3144515Speter 		return LESSTHAN;
3154515Speter 	    if ( thistime > thattime )
3164515Speter 		return GREATERTHAN;
3174515Speter 	    if ( thisp -> arc_count < thatp -> arc_count )
3184515Speter 		return LESSTHAN;
3194515Speter 	    if ( thisp -> arc_count > thatp -> arc_count )
3204515Speter 		return GREATERTHAN;
3214515Speter 	    return EQUALTO;
3224515Speter 	}
3234515Speter     }
3244515Speter }
325