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