121959Sdist /* 221959Sdist * Copyright (c) 1983 Regents of the University of California. 334199Sbostic * All rights reserved. 434199Sbostic * 542683Sbostic * %sccs.include.redist.c% 621959Sdist */ 721959Sdist 84509Speter #ifndef lint 9*52651Smckusick static char sccsid[] = "@(#)dfn.c 5.5 (Berkeley) 02/24/92"; 1034199Sbostic #endif /* not lint */ 114509Speter 124509Speter #include <stdio.h> 134560Speter #include "gprof.h" 144509Speter 154509Speter #define DFN_DEPTH 100 164509Speter struct dfnstruct { 174509Speter nltype *nlentryp; 184509Speter int cycletop; 194509Speter }; 204509Speter typedef struct dfnstruct dfntype; 214509Speter 224509Speter dfntype dfn_stack[ DFN_DEPTH ]; 23*52651Smckusick int dfn_depth; 244509Speter 25*52651Smckusick int dfn_counter; 264509Speter 27*52651Smckusick dfn_init() 28*52651Smckusick { 29*52651Smckusick 30*52651Smckusick dfn_depth = 0; 31*52651Smckusick dfn_counter = DFN_NAN; 32*52651Smckusick } 33*52651Smckusick 344509Speter /* 354509Speter * given this parent, depth first number its children. 364509Speter */ 374509Speter dfn( parentp ) 384509Speter nltype *parentp; 394509Speter { 404509Speter arctype *arcp; 414509Speter 424509Speter # ifdef DEBUG 434509Speter if ( debug & DFNDEBUG ) { 444509Speter printf( "[dfn] dfn(" ); 454509Speter printname( parentp ); 464509Speter printf( ")\n" ); 474509Speter } 484509Speter # endif DEBUG 494509Speter /* 504509Speter * if we're already numbered, no need to look any furthur. 514509Speter */ 524509Speter if ( dfn_numbered( parentp ) ) { 534509Speter return; 544509Speter } 554509Speter /* 564509Speter * if we're already busy, must be a cycle 574509Speter */ 584509Speter if ( dfn_busy( parentp ) ) { 594509Speter dfn_findcycle( parentp ); 604509Speter return; 614509Speter } 624509Speter /* 634509Speter * visit yourself before your children 644509Speter */ 654509Speter dfn_pre_visit( parentp ); 664509Speter /* 674509Speter * visit children 684509Speter */ 694509Speter for ( arcp = parentp -> children ; arcp ; arcp = arcp -> arc_childlist ) { 70*52651Smckusick if ( arcp -> arc_flags & DEADARC ) 71*52651Smckusick continue; 724509Speter dfn( arcp -> arc_childp ); 734509Speter } 744509Speter /* 754509Speter * visit yourself after your children 764509Speter */ 774509Speter dfn_post_visit( parentp ); 784509Speter } 794509Speter 804509Speter /* 814509Speter * push a parent onto the stack and mark it busy 824509Speter */ 834509Speter dfn_pre_visit( parentp ) 844509Speter nltype *parentp; 854509Speter { 864509Speter 874509Speter dfn_depth += 1; 884509Speter if ( dfn_depth >= DFN_DEPTH ) { 894509Speter fprintf( stderr , "[dfn] out of my depth (dfn_stack overflow)\n" ); 904509Speter exit( 1 ); 914509Speter } 924509Speter dfn_stack[ dfn_depth ].nlentryp = parentp; 934509Speter dfn_stack[ dfn_depth ].cycletop = dfn_depth; 944509Speter parentp -> toporder = DFN_BUSY; 954509Speter # ifdef DEBUG 964509Speter if ( debug & DFNDEBUG ) { 974509Speter printf( "[dfn_pre_visit]\t\t%d:" , dfn_depth ); 984509Speter printname( parentp ); 994509Speter printf( "\n" ); 1004509Speter } 1014509Speter # endif DEBUG 1024509Speter } 1034509Speter 1044509Speter /* 1054509Speter * are we already numbered? 1064509Speter */ 1074509Speter bool 1084509Speter dfn_numbered( childp ) 1094509Speter nltype *childp; 1104509Speter { 1114509Speter 11210284Speter return ( childp -> toporder != DFN_NAN && childp -> toporder != DFN_BUSY ); 1134509Speter } 1144509Speter 1154509Speter /* 1164509Speter * are we already busy? 1174509Speter */ 1184509Speter bool 1194509Speter dfn_busy( childp ) 1204509Speter nltype *childp; 1214509Speter { 1224509Speter 12310284Speter if ( childp -> toporder == DFN_NAN ) { 1244509Speter return FALSE; 1254509Speter } 1264509Speter return TRUE; 1274509Speter } 1284509Speter 1294509Speter /* 1304509Speter * MISSING: an explanation 1314509Speter */ 1324509Speter dfn_findcycle( childp ) 1334509Speter nltype *childp; 1344509Speter { 1354509Speter int cycletop; 1364509Speter nltype *cycleheadp; 1374509Speter nltype *tailp; 1384509Speter int index; 1394509Speter 1404509Speter for ( cycletop = dfn_depth ; cycletop > 0 ; cycletop -= 1 ) { 1414509Speter cycleheadp = dfn_stack[ cycletop ].nlentryp; 1424509Speter if ( childp == cycleheadp ) { 1434509Speter break; 1444509Speter } 1454509Speter if ( childp -> cyclehead != childp && 1464509Speter childp -> cyclehead == cycleheadp ) { 1474509Speter break; 1484509Speter } 1494509Speter } 1504509Speter if ( cycletop <= 0 ) { 1514509Speter fprintf( stderr , "[dfn_findcycle] couldn't find head of cycle\n" ); 1524509Speter exit( 1 ); 1534509Speter } 1544509Speter # ifdef DEBUG 1554509Speter if ( debug & DFNDEBUG ) { 1564509Speter printf( "[dfn_findcycle] dfn_depth %d cycletop %d " , 1574509Speter dfn_depth , cycletop ); 1584509Speter printname( cycleheadp ); 1594509Speter printf( "\n" ); 1604509Speter } 1614509Speter # endif DEBUG 1624509Speter if ( cycletop == dfn_depth ) { 1634509Speter /* 1644509Speter * this is previous function, e.g. this calls itself 1654509Speter * sort of boring 1664509Speter */ 1674509Speter dfn_self_cycle( childp ); 1684509Speter } else { 1694509Speter /* 1704509Speter * glom intervening functions that aren't already 1714509Speter * glommed into this cycle. 1724509Speter * things have been glommed when their cyclehead field 1734509Speter * points to the head of the cycle they are glommed into. 1744509Speter */ 1754509Speter for ( tailp = cycleheadp ; tailp -> cnext ; tailp = tailp -> cnext ) { 1764509Speter /* void: chase down to tail of things already glommed */ 1774509Speter # ifdef DEBUG 1784509Speter if ( debug & DFNDEBUG ) { 1794509Speter printf( "[dfn_findcycle] tail " ); 1804509Speter printname( tailp ); 1814509Speter printf( "\n" ); 1824509Speter } 1834509Speter # endif DEBUG 1844509Speter } 1854509Speter /* 1864509Speter * if what we think is the top of the cycle 1874509Speter * has a cyclehead field, then it's not really the 1884509Speter * head of the cycle, which is really what we want 1894509Speter */ 1904509Speter if ( cycleheadp -> cyclehead != cycleheadp ) { 1914509Speter cycleheadp = cycleheadp -> cyclehead; 1924509Speter # ifdef DEBUG 1934509Speter if ( debug & DFNDEBUG ) { 1944509Speter printf( "[dfn_findcycle] new cyclehead " ); 1954509Speter printname( cycleheadp ); 1964509Speter printf( "\n" ); 1974509Speter } 1984509Speter # endif DEBUG 1994509Speter } 2004509Speter for ( index = cycletop + 1 ; index <= dfn_depth ; index += 1 ) { 2014509Speter childp = dfn_stack[ index ].nlentryp; 2024509Speter if ( childp -> cyclehead == childp ) { 2034509Speter /* 2044509Speter * not yet glommed anywhere, glom it 2054509Speter * and fix any children it has glommed 2064509Speter */ 2074509Speter tailp -> cnext = childp; 2084509Speter childp -> cyclehead = cycleheadp; 2094509Speter # ifdef DEBUG 2104509Speter if ( debug & DFNDEBUG ) { 2114509Speter printf( "[dfn_findcycle] glomming " ); 2124509Speter printname( childp ); 2134509Speter printf( " onto " ); 2144509Speter printname( cycleheadp ); 2154509Speter printf( "\n" ); 2164509Speter } 2174509Speter # endif DEBUG 2184509Speter for ( tailp = childp ; tailp->cnext ; tailp = tailp->cnext ) { 2194509Speter tailp -> cnext -> cyclehead = cycleheadp; 2204509Speter # ifdef DEBUG 2214509Speter if ( debug & DFNDEBUG ) { 2224509Speter printf( "[dfn_findcycle] and its tail " ); 2234509Speter printname( tailp -> cnext ); 2244509Speter printf( " onto " ); 2254509Speter printname( cycleheadp ); 2264509Speter printf( "\n" ); 2274509Speter } 2284509Speter # endif DEBUG 2294509Speter } 2304509Speter } else if ( childp -> cyclehead != cycleheadp /* firewall */ ) { 2314509Speter fprintf( stderr , 2324509Speter "[dfn_busy] glommed, but not to cyclehead\n" ); 2334509Speter } 2344509Speter } 2354509Speter } 2364509Speter } 2374509Speter 2384509Speter /* 2394509Speter * deal with self-cycles 2404509Speter * for lint: ARGSUSED 2414509Speter */ 2424509Speter dfn_self_cycle( parentp ) 2434509Speter nltype *parentp; 2444509Speter { 2454509Speter /* 2464509Speter * since we are taking out self-cycles elsewhere 2474509Speter * no need for the special case, here. 2484509Speter */ 2494509Speter # ifdef DEBUG 2504509Speter if ( debug & DFNDEBUG ) { 2514509Speter printf( "[dfn_self_cycle] " ); 2524509Speter printname( parentp ); 2534509Speter printf( "\n" ); 2544509Speter } 2554509Speter # endif DEBUG 2564509Speter } 2574509Speter 2584509Speter /* 2594509Speter * visit a node after all its children 2604509Speter * [MISSING: an explanation] 2614509Speter * and pop it off the stack 2624509Speter */ 2634509Speter dfn_post_visit( parentp ) 2644509Speter nltype *parentp; 2654509Speter { 2664509Speter nltype *memberp; 2674509Speter 2684509Speter # ifdef DEBUG 2694509Speter if ( debug & DFNDEBUG ) { 2704509Speter printf( "[dfn_post_visit]\t%d: " , dfn_depth ); 2714509Speter printname( parentp ); 2724509Speter printf( "\n" ); 2734509Speter } 2744509Speter # endif DEBUG 2754509Speter /* 2764509Speter * number functions and things in their cycles 2774509Speter * unless the function is itself part of a cycle 2784509Speter */ 2794509Speter if ( parentp -> cyclehead == parentp ) { 2804509Speter dfn_counter += 1; 2814509Speter for ( memberp = parentp ; memberp ; memberp = memberp -> cnext ) { 2824509Speter memberp -> toporder = dfn_counter; 2834509Speter # ifdef DEBUG 2844509Speter if ( debug & DFNDEBUG ) { 2854509Speter printf( "[dfn_post_visit]\t\tmember " ); 2864509Speter printname( memberp ); 2874509Speter printf( " -> toporder = %d\n" , dfn_counter ); 2884509Speter } 2894509Speter # endif DEBUG 2904509Speter } 2914509Speter } else { 2924509Speter # ifdef DEBUG 2934509Speter if ( debug & DFNDEBUG ) { 2944509Speter printf( "[dfn_post_visit]\t\tis part of a cycle\n" ); 2954509Speter } 2964509Speter # endif DEBUG 2974509Speter } 2984509Speter dfn_depth -= 1; 2994509Speter } 300