xref: /csrg-svn/usr.bin/gprof/printgprof.c (revision 4515)
1*4515Speter #ifndef lint
2*4515Speter     static	char *sccsid = "@(#)printgprof.c	1.1 (Berkeley) 10/15/81";
3*4515Speter #endif lint
4*4515Speter 
5*4515Speter #include "dprof.h"
6*4515Speter 
7*4515Speter printdprof()
8*4515Speter {
9*4515Speter     nltype	**timesortnlp;
10*4515Speter     int		index;
11*4515Speter     nltype	*parentp;
12*4515Speter     nltype	*childp;
13*4515Speter 
14*4515Speter 	/*
15*4515Speter 	 *	Now, sort by time + childtime.
16*4515Speter 	 *	include the cycle headers hiding out past nl[nname].
17*4515Speter 	 */
18*4515Speter     timesortnlp = (nltype **) calloc( nname+1+cyclemax , sizeof(nltype *) );
19*4515Speter     if ( timesortnlp == (nltype **) 0 ) {
20*4515Speter 	fprintf( stderr , "[doarcs] ran out of memory for sorting\n" );
21*4515Speter     }
22*4515Speter     for ( index = 0 ; index < nname+1+cyclemax ; index++ ) {
23*4515Speter 	timesortnlp[index] = &nl[index];
24*4515Speter     }
25*4515Speter     qsort( timesortnlp , nname+1+cyclemax , sizeof(nltype *) , totalcmp );
26*4515Speter     for ( index = 0 ; index < nname+1+cyclemax ; index++ ) {
27*4515Speter 	timesortnlp[ index ] -> index = index + 1;
28*4515Speter     }
29*4515Speter 	/*
30*4515Speter 	 *	Now, print out the structured profiling list
31*4515Speter 	 */
32*4515Speter     actime = 0.0;
33*4515Speter     printf( "\f" );
34*4515Speter     putprofheader();
35*4515Speter     for ( index = 0 ; index < nname + 1 + cyclemax ; index ++ ) {
36*4515Speter 	parentp = timesortnlp[ index ];
37*4515Speter 	if ( zflg == 0 &&
38*4515Speter 	     parentp -> ncall == 0 &&
39*4515Speter 	     parentp -> selfcalls == 0 &&
40*4515Speter 	     parentp -> time == 0 &&
41*4515Speter 	     parentp -> childtime == 0 ) {
42*4515Speter 	    continue;
43*4515Speter 	}
44*4515Speter 	if ( parentp -> name == 0 && parentp -> cycleno != 0 ) {
45*4515Speter 		/*
46*4515Speter 		 *	cycle header
47*4515Speter 		 */
48*4515Speter 	    putprofline( parentp , 0 );
49*4515Speter 	    for ( childp = parentp->cnext ; childp ; childp = childp->cnext ) {
50*4515Speter 		putprofline( childp , 0 );
51*4515Speter 	    }
52*4515Speter 	} else {
53*4515Speter 	    printparents( parentp );
54*4515Speter 	    putprofline( parentp , 1 );
55*4515Speter 	    printchildren( parentp );
56*4515Speter 	}
57*4515Speter 	printf( "\n" );
58*4515Speter     }
59*4515Speter     actime = 0.0;
60*4515Speter }
61*4515Speter 
62*4515Speter printparents( childp )
63*4515Speter     nltype	*childp;
64*4515Speter {
65*4515Speter     nltype	*parentp;
66*4515Speter     arctype	*arcp;
67*4515Speter     nltype	*cycleheadp;
68*4515Speter 
69*4515Speter     if ( childp -> cyclehead != 0 ) {
70*4515Speter 	cycleheadp = childp -> cyclehead;
71*4515Speter     } else {
72*4515Speter 	cycleheadp = childp;
73*4515Speter     }
74*4515Speter     if ( childp -> parents == 0 ) {
75*4515Speter 	printf( "\t%5.5s %7.7s %7.7s %7.7s %7.7s %7.7s      <spontaneous>\n" ,
76*4515Speter 		"" , "" , "" , "" , "" , "" );
77*4515Speter 	return;
78*4515Speter     }
79*4515Speter     sortparents( childp );
80*4515Speter     for ( arcp = childp -> parents ; arcp ; arcp = arcp -> arc_parentlist ) {
81*4515Speter 	parentp = arcp -> arc_parentp;
82*4515Speter 	if ( childp == parentp ||
83*4515Speter 	     ( childp->cycleno != 0 && parentp->cycleno == childp->cycleno ) ) {
84*4515Speter 		/*
85*4515Speter 		 *	selfcall or call amoung siblings
86*4515Speter 		 */
87*4515Speter 	    printf( "\t%5.5s %7.7s %7.7s %7.7s %7d %7.7s      " ,
88*4515Speter 		    "" , "" , "" , "" ,
89*4515Speter 		    arcp -> arc_count , "" );
90*4515Speter 	    printname( parentp );
91*4515Speter 	    printf( "\n" );
92*4515Speter 	} else {
93*4515Speter 		/*
94*4515Speter 		 *	regular parent of child
95*4515Speter 		 */
96*4515Speter 	    printf( "\t%5.5s %7.7s %7.1f %7.1f %7d/%-7d      " , "" , "" ,
97*4515Speter 		    arcp -> arc_time / HZ , arcp -> arc_childtime / HZ ,
98*4515Speter 		    arcp -> arc_count , cycleheadp -> ncall );
99*4515Speter 	    printname( parentp );
100*4515Speter 	    printf( "\n" );
101*4515Speter 	}
102*4515Speter     }
103*4515Speter }
104*4515Speter 
105*4515Speter printchildren( parentp )
106*4515Speter     nltype	*parentp;
107*4515Speter {
108*4515Speter     nltype	*childp;
109*4515Speter     arctype	*arcp;
110*4515Speter 
111*4515Speter     sortchildren( parentp );
112*4515Speter     arcp = parentp -> children;
113*4515Speter     for ( arcp = parentp -> children ; arcp ; arcp = arcp -> arc_childlist ) {
114*4515Speter 	childp = arcp -> arc_childp;
115*4515Speter 	if ( childp == parentp ||
116*4515Speter 	    ( childp->cycleno != 0 && childp->cycleno == parentp->cycleno ) ) {
117*4515Speter 		/*
118*4515Speter 		 *	self call or call to sibling
119*4515Speter 		 */
120*4515Speter 	    printf( "\t%5.5s %7.7s %7.7s %7.7s %7d %7.7s      " ,
121*4515Speter 		    "" , "" , "" , "" ,
122*4515Speter 		    arcp -> arc_count , "" );
123*4515Speter 	    printname( childp );
124*4515Speter 	    printf( "\n" );
125*4515Speter 	} else {
126*4515Speter 		/*
127*4515Speter 		 *	regular child of parent
128*4515Speter 		 */
129*4515Speter 	    printf( "\t%5.5s %7.7s %7.1f %7.1f %7d/%-7d      " , "" , "" ,
130*4515Speter 		    arcp -> arc_time / HZ , arcp -> arc_childtime / HZ ,
131*4515Speter 		    arcp -> arc_count , childp -> cyclehead -> ncall );
132*4515Speter 	    printname( childp );
133*4515Speter 	    printf( "\n" );
134*4515Speter 	}
135*4515Speter     }
136*4515Speter }
137*4515Speter 
138*4515Speter printname( selfp )
139*4515Speter     nltype	*selfp;
140*4515Speter {
141*4515Speter 
142*4515Speter     if ( selfp -> name != 0 ) {
143*4515Speter 	printf( "%s\t" , selfp -> name );
144*4515Speter 	if ( selfp -> index != 0 ) {
145*4515Speter 	    printf( "[%d] " , selfp -> index );
146*4515Speter 	}
147*4515Speter #	ifdef DEBUG
148*4515Speter 	    if ( debug & DFNDEBUG ) {
149*4515Speter 		printf( "{%d} " , selfp -> toporder );
150*4515Speter 	    }
151*4515Speter #	endif DEBUG
152*4515Speter     }
153*4515Speter     if ( selfp -> cycleno != 0 ) {
154*4515Speter 	printf( "<cycle %d>" , selfp -> cycleno );
155*4515Speter     }
156*4515Speter }
157*4515Speter 
158*4515Speter sortchildren( parentp )
159*4515Speter     nltype	*parentp;
160*4515Speter {
161*4515Speter     arctype	*arcp;
162*4515Speter     arctype	*detachedp;
163*4515Speter     arctype	sorted;
164*4515Speter     arctype	*prevp;
165*4515Speter 
166*4515Speter 	/*
167*4515Speter 	 *	unlink children from parent,
168*4515Speter 	 *	then insertion sort back on to sorted's children.
169*4515Speter 	 *	    *arcp	the arc you have detached and are inserting.
170*4515Speter 	 *	    *detachedp	the rest of the arcs to be sorted.
171*4515Speter 	 *	    sorted	arc list onto which you insertion sort.
172*4515Speter 	 *	    *prevp	arc before the arc you are comparing.
173*4515Speter 	 */
174*4515Speter     sorted.arc_childlist = 0;
175*4515Speter     for (   arcp = parentp -> children , detachedp = arcp -> arc_childlist ;
176*4515Speter 	    arcp ;
177*4515Speter 	    arcp = detachedp , detachedp = detachedp -> arc_childlist ) {
178*4515Speter 	    /*
179*4515Speter 	     *	consider *arcp as disconnected
180*4515Speter 	     *	insert it into sorted
181*4515Speter 	     */
182*4515Speter 	for (   prevp = &sorted ;
183*4515Speter 		prevp -> arc_childlist ;
184*4515Speter 		prevp = prevp -> arc_childlist ) {
185*4515Speter 	    if ( arccmp( arcp , prevp -> arc_childlist ) != LESSTHAN ) {
186*4515Speter 		break;
187*4515Speter 	    }
188*4515Speter 	}
189*4515Speter 	arcp -> arc_childlist = prevp -> arc_childlist;
190*4515Speter 	prevp -> arc_childlist = arcp;
191*4515Speter     }
192*4515Speter 	/*
193*4515Speter 	 *	reattach sorted children to parent
194*4515Speter 	 */
195*4515Speter     parentp -> children = sorted.arc_childlist;
196*4515Speter }
197*4515Speter 
198*4515Speter sortparents( childp )
199*4515Speter     nltype	*childp;
200*4515Speter {
201*4515Speter     arctype	*arcp;
202*4515Speter     arctype	*detachedp;
203*4515Speter     arctype	sorted;
204*4515Speter     arctype	*prevp;
205*4515Speter 
206*4515Speter 	/*
207*4515Speter 	 *	unlink parents from child,
208*4515Speter 	 *	then insertion sort back on to sorted's parents.
209*4515Speter 	 *	    *arcp	the arc you have detached and are inserting.
210*4515Speter 	 *	    *detachedp	the rest of the arcs to be sorted.
211*4515Speter 	 *	    sorted	arc list onto which you insertion sort.
212*4515Speter 	 *	    *prevp	arc before the arc you are comparing.
213*4515Speter 	 */
214*4515Speter     sorted.arc_parentlist = 0;
215*4515Speter     for (   arcp = childp -> parents , detachedp = arcp -> arc_parentlist ;
216*4515Speter 	    arcp ;
217*4515Speter 	    arcp = detachedp , detachedp = detachedp -> arc_parentlist ) {
218*4515Speter 	    /*
219*4515Speter 	     *	consider *arcp as disconnected
220*4515Speter 	     *	insert it into sorted
221*4515Speter 	     */
222*4515Speter 	for (   prevp = &sorted ;
223*4515Speter 		prevp -> arc_parentlist ;
224*4515Speter 		prevp = prevp -> arc_parentlist ) {
225*4515Speter 	    if ( arccmp( arcp , prevp -> arc_parentlist ) != GREATERTHAN ) {
226*4515Speter 		break;
227*4515Speter 	    }
228*4515Speter 	}
229*4515Speter 	arcp -> arc_parentlist = prevp -> arc_parentlist;
230*4515Speter 	prevp -> arc_parentlist = arcp;
231*4515Speter     }
232*4515Speter 	/*
233*4515Speter 	 *	reattach sorted arcs to child
234*4515Speter 	 */
235*4515Speter     childp -> parents = sorted.arc_parentlist;
236*4515Speter }
237*4515Speter 
238*4515Speter     /*
239*4515Speter      *	compare two arcs to/from the same child/parent.
240*4515Speter      *	- if one arc is a self arc, it's least.
241*4515Speter      *	- if one arc is within a cycle, it's less than.
242*4515Speter      *	- if both arcs are within a cycle, compare arc counts.
243*4515Speter      *	- if neither arc is within a cycle, compare with
244*4515Speter      *		time + childtime as major key
245*4515Speter      *		arc count as minor key
246*4515Speter      */
247*4515Speter int
248*4515Speter arccmp( thisp , thatp )
249*4515Speter     arctype	*thisp;
250*4515Speter     arctype	*thatp;
251*4515Speter {
252*4515Speter     nltype	*thisparentp = thisp -> arc_parentp;
253*4515Speter     nltype	*thischildp = thisp -> arc_childp;
254*4515Speter     nltype	*thatparentp = thatp -> arc_parentp;
255*4515Speter     nltype	*thatchildp = thatp -> arc_childp;
256*4515Speter     double	thistime;
257*4515Speter     double	thattime;
258*4515Speter 
259*4515Speter #   ifdef DEBUG
260*4515Speter 	if ( debug & TIMEDEBUG ) {
261*4515Speter 	    printf( "[arccmp] " );
262*4515Speter 	    printname( thisparentp );
263*4515Speter 	    printf( " calls " );
264*4515Speter 	    printname ( thischildp );
265*4515Speter 	    printf( " %f + %f %d/%d\n" ,
266*4515Speter 		    thisp -> arc_time , thisp -> arc_childtime ,
267*4515Speter 		    thisp -> arc_count , thischildp -> ncall );
268*4515Speter 	    printf( "[arccmp] " );
269*4515Speter 	    printname( thatparentp );
270*4515Speter 	    printf( " calls " );
271*4515Speter 	    printname( thatchildp );
272*4515Speter 	    printf( " %f + %f %d/%d\n" ,
273*4515Speter 		    thatp -> arc_time , thatp -> arc_childtime ,
274*4515Speter 		    thatp -> arc_count , thatchildp -> ncall );
275*4515Speter 	    printf( "\n" );
276*4515Speter 	}
277*4515Speter #   endif DEBUG
278*4515Speter     if ( thisparentp == thischildp ) {
279*4515Speter 	    /* this is a self call */
280*4515Speter 	return LESSTHAN;
281*4515Speter     }
282*4515Speter     if ( thatparentp == thatchildp ) {
283*4515Speter 	    /* that is a self call */
284*4515Speter 	return GREATERTHAN;
285*4515Speter     }
286*4515Speter     if ( thisparentp -> cycleno != 0 && thischildp -> cycleno != 0 &&
287*4515Speter 	thisparentp -> cycleno == thischildp -> cycleno ) {
288*4515Speter 	    /* this is a call within a cycle */
289*4515Speter 	if ( thatparentp -> cycleno != 0 && thatchildp -> cycleno != 0 &&
290*4515Speter 	    thatparentp -> cycleno == thatchildp -> cycleno ) {
291*4515Speter 		/* that is a call within the cycle, too */
292*4515Speter 	    if ( thisp -> arc_count < thatp -> arc_count ) {
293*4515Speter 		return LESSTHAN;
294*4515Speter 	    }
295*4515Speter 	    if ( thisp -> arc_count > thatp -> arc_count ) {
296*4515Speter 		return GREATERTHAN;
297*4515Speter 	    }
298*4515Speter 	    return EQUALTO;
299*4515Speter 	} else {
300*4515Speter 		/* that isn't a call within the cycle */
301*4515Speter 	    return LESSTHAN;
302*4515Speter 	}
303*4515Speter     } else {
304*4515Speter 	    /* this isn't a call within a cycle */
305*4515Speter 	if ( thatparentp -> cycleno != 0 && thatchildp -> cycleno != 0 &&
306*4515Speter 	    thatparentp -> cycleno == thatchildp -> cycleno ) {
307*4515Speter 		/* that is a call within a cycle */
308*4515Speter 	    return GREATERTHAN;
309*4515Speter 	} else {
310*4515Speter 		/* neither is a call within a cycle */
311*4515Speter 	    thistime = thisp -> arc_time + thisp -> arc_childtime;
312*4515Speter 	    thattime = thatp -> arc_time + thatp -> arc_childtime;
313*4515Speter 	    if ( thistime < thattime )
314*4515Speter 		return LESSTHAN;
315*4515Speter 	    if ( thistime > thattime )
316*4515Speter 		return GREATERTHAN;
317*4515Speter 	    if ( thisp -> arc_count < thatp -> arc_count )
318*4515Speter 		return LESSTHAN;
319*4515Speter 	    if ( thisp -> arc_count > thatp -> arc_count )
320*4515Speter 		return GREATERTHAN;
321*4515Speter 	    return EQUALTO;
322*4515Speter 	}
323*4515Speter     }
324*4515Speter }
325