Annotation of 43BSDReno/pgrm/gprof/dfn.c, revision 1.1

1.1     ! root        1: /*
        !             2:  * Copyright (c) 1983 Regents of the University of California.
        !             3:  * All rights reserved.
        !             4:  *
        !             5:  * Redistribution and use in source and binary forms are permitted
        !             6:  * provided that: (1) source distributions retain this entire copyright
        !             7:  * notice and comment, and (2) distributions including binaries display
        !             8:  * the following acknowledgement:  ``This product includes software
        !             9:  * developed by the University of California, Berkeley and its contributors''
        !            10:  * in the documentation or other materials provided with the distribution
        !            11:  * and in all advertising materials mentioning features or use of this
        !            12:  * software. Neither the name of the University nor the names of its
        !            13:  * contributors may be used to endorse or promote products derived
        !            14:  * from this software without specific prior written permission.
        !            15:  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
        !            16:  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
        !            17:  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
        !            18:  */
        !            19: 
        !            20: #ifndef lint
        !            21: static char sccsid[] = "@(#)dfn.c      5.4 (Berkeley) 6/1/90";
        !            22: #endif /* not lint */
        !            23: 
        !            24: #include <stdio.h>
        !            25: #include "gprof.h"
        !            26: 
        !            27: #define        DFN_DEPTH       100
        !            28: struct dfnstruct {
        !            29:     nltype     *nlentryp;
        !            30:     int                cycletop;
        !            31: };
        !            32: typedef struct dfnstruct       dfntype;
        !            33: 
        !            34: dfntype        dfn_stack[ DFN_DEPTH ];
        !            35: int    dfn_depth = 0;
        !            36: 
        !            37: int    dfn_counter = DFN_NAN;
        !            38: 
        !            39:     /*
        !            40:      * given this parent, depth first number its children.
        !            41:      */
        !            42: dfn( parentp )
        !            43:     nltype     *parentp;
        !            44: {
        !            45:     arctype    *arcp;
        !            46: 
        !            47: #   ifdef DEBUG
        !            48:        if ( debug & DFNDEBUG ) {
        !            49:            printf( "[dfn] dfn(" );
        !            50:            printname( parentp );
        !            51:            printf( ")\n" );
        !            52:        }
        !            53: #   endif DEBUG
        !            54:        /*
        !            55:         *      if we're already numbered, no need to look any furthur.
        !            56:         */
        !            57:     if ( dfn_numbered( parentp ) ) {
        !            58:        return;
        !            59:     }
        !            60:        /*
        !            61:         *      if we're already busy, must be a cycle
        !            62:         */
        !            63:     if ( dfn_busy( parentp ) ) {
        !            64:        dfn_findcycle( parentp );
        !            65:        return;
        !            66:     }
        !            67:        /*
        !            68:         *      visit yourself before your children
        !            69:         */
        !            70:     dfn_pre_visit( parentp );
        !            71:        /*
        !            72:         *      visit children
        !            73:         */
        !            74:     for ( arcp = parentp -> children ; arcp ; arcp = arcp -> arc_childlist ) {
        !            75:            dfn( arcp -> arc_childp );
        !            76:     }
        !            77:        /*
        !            78:         *      visit yourself after your children
        !            79:         */
        !            80:     dfn_post_visit( parentp );
        !            81: }
        !            82: 
        !            83:     /*
        !            84:      * push a parent onto the stack and mark it busy
        !            85:      */
        !            86: dfn_pre_visit( parentp )
        !            87:     nltype     *parentp;
        !            88: {
        !            89: 
        !            90:     dfn_depth += 1;
        !            91:     if ( dfn_depth >= DFN_DEPTH ) {
        !            92:        fprintf( stderr , "[dfn] out of my depth (dfn_stack overflow)\n" );
        !            93:        exit( 1 );
        !            94:     }
        !            95:     dfn_stack[ dfn_depth ].nlentryp = parentp;
        !            96:     dfn_stack[ dfn_depth ].cycletop = dfn_depth;
        !            97:     parentp -> toporder = DFN_BUSY;
        !            98: #   ifdef DEBUG
        !            99:        if ( debug & DFNDEBUG ) {
        !           100:            printf( "[dfn_pre_visit]\t\t%d:" , dfn_depth );
        !           101:            printname( parentp );
        !           102:            printf( "\n" );
        !           103:        }
        !           104: #   endif DEBUG
        !           105: }
        !           106: 
        !           107:     /*
        !           108:      * are we already numbered?
        !           109:      */
        !           110: bool
        !           111: dfn_numbered( childp )
        !           112:     nltype     *childp;
        !           113: {
        !           114:     
        !           115:     return ( childp -> toporder != DFN_NAN && childp -> toporder != DFN_BUSY );
        !           116: }
        !           117: 
        !           118:     /*
        !           119:      * are we already busy?
        !           120:      */
        !           121: bool
        !           122: dfn_busy( childp )
        !           123:     nltype     *childp;
        !           124: {
        !           125: 
        !           126:     if ( childp -> toporder == DFN_NAN ) {
        !           127:        return FALSE;
        !           128:     }
        !           129:     return TRUE;
        !           130: }
        !           131: 
        !           132:     /*
        !           133:      * MISSING: an explanation
        !           134:      */
        !           135: dfn_findcycle( childp )
        !           136:     nltype     *childp;
        !           137: {
        !           138:     int                cycletop;
        !           139:     nltype     *cycleheadp;
        !           140:     nltype     *tailp;
        !           141:     int                index;
        !           142: 
        !           143:     for ( cycletop = dfn_depth ; cycletop > 0 ; cycletop -= 1 ) {
        !           144:        cycleheadp = dfn_stack[ cycletop ].nlentryp;
        !           145:        if ( childp == cycleheadp ) {
        !           146:            break;
        !           147:        }
        !           148:        if ( childp -> cyclehead != childp &&
        !           149:            childp -> cyclehead == cycleheadp ) {
        !           150:            break;
        !           151:        }
        !           152:     }
        !           153:     if ( cycletop <= 0 ) {
        !           154:        fprintf( stderr , "[dfn_findcycle] couldn't find head of cycle\n" );
        !           155:        exit( 1 );
        !           156:     }
        !           157: #   ifdef DEBUG
        !           158:        if ( debug & DFNDEBUG ) {
        !           159:            printf( "[dfn_findcycle] dfn_depth %d cycletop %d " ,
        !           160:                    dfn_depth , cycletop  );
        !           161:            printname( cycleheadp );
        !           162:            printf( "\n" );
        !           163:        }
        !           164: #   endif DEBUG
        !           165:     if ( cycletop == dfn_depth ) {
        !           166:            /*
        !           167:             *  this is previous function, e.g. this calls itself
        !           168:             *  sort of boring
        !           169:             */
        !           170:        dfn_self_cycle( childp );
        !           171:     } else {
        !           172:            /*
        !           173:             *  glom intervening functions that aren't already
        !           174:             *  glommed into this cycle.
        !           175:             *  things have been glommed when their cyclehead field
        !           176:             *  points to the head of the cycle they are glommed into.
        !           177:             */
        !           178:        for ( tailp = cycleheadp ; tailp -> cnext ; tailp = tailp -> cnext ) {
        !           179:            /* void: chase down to tail of things already glommed */
        !           180: #          ifdef DEBUG
        !           181:                if ( debug & DFNDEBUG ) {
        !           182:                    printf( "[dfn_findcycle] tail " );
        !           183:                    printname( tailp );
        !           184:                    printf( "\n" );
        !           185:                }
        !           186: #          endif DEBUG
        !           187:        }
        !           188:            /*
        !           189:             *  if what we think is the top of the cycle
        !           190:             *  has a cyclehead field, then it's not really the
        !           191:             *  head of the cycle, which is really what we want
        !           192:             */ 
        !           193:        if ( cycleheadp -> cyclehead != cycleheadp ) {
        !           194:            cycleheadp = cycleheadp -> cyclehead;
        !           195: #          ifdef DEBUG
        !           196:                if ( debug & DFNDEBUG ) {
        !           197:                    printf( "[dfn_findcycle] new cyclehead " );
        !           198:                    printname( cycleheadp );
        !           199:                    printf( "\n" );
        !           200:                }
        !           201: #          endif DEBUG
        !           202:        }
        !           203:        for ( index = cycletop + 1 ; index <= dfn_depth ; index += 1 ) {
        !           204:            childp = dfn_stack[ index ].nlentryp;
        !           205:            if ( childp -> cyclehead == childp ) {
        !           206:                    /*
        !           207:                     *  not yet glommed anywhere, glom it
        !           208:                     *  and fix any children it has glommed
        !           209:                     */
        !           210:                tailp -> cnext = childp;
        !           211:                childp -> cyclehead = cycleheadp;
        !           212: #              ifdef DEBUG
        !           213:                    if ( debug & DFNDEBUG ) {
        !           214:                        printf( "[dfn_findcycle] glomming " );
        !           215:                        printname( childp );
        !           216:                        printf( " onto " );
        !           217:                        printname( cycleheadp );
        !           218:                        printf( "\n" );
        !           219:                    }
        !           220: #              endif DEBUG
        !           221:                for ( tailp = childp ; tailp->cnext ; tailp = tailp->cnext ) {
        !           222:                    tailp -> cnext -> cyclehead = cycleheadp;
        !           223: #                  ifdef DEBUG
        !           224:                        if ( debug & DFNDEBUG ) {
        !           225:                            printf( "[dfn_findcycle] and its tail " );
        !           226:                            printname( tailp -> cnext );
        !           227:                            printf( " onto " );
        !           228:                            printname( cycleheadp );
        !           229:                            printf( "\n" );
        !           230:                        }
        !           231: #                  endif DEBUG
        !           232:                }
        !           233:            } else if ( childp -> cyclehead != cycleheadp /* firewall */ ) {
        !           234:                fprintf( stderr ,
        !           235:                        "[dfn_busy] glommed, but not to cyclehead\n" );
        !           236:            }
        !           237:        }
        !           238:     }
        !           239: }
        !           240: 
        !           241:     /*
        !           242:      * deal with self-cycles
        !           243:      * for lint: ARGSUSED
        !           244:      */
        !           245: dfn_self_cycle( parentp )
        !           246:     nltype     *parentp;
        !           247: {
        !           248:        /*
        !           249:         *      since we are taking out self-cycles elsewhere
        !           250:         *      no need for the special case, here.
        !           251:         */
        !           252: #   ifdef DEBUG
        !           253:        if ( debug & DFNDEBUG ) {
        !           254:            printf( "[dfn_self_cycle] " );
        !           255:            printname( parentp );
        !           256:            printf( "\n" );
        !           257:        }
        !           258: #   endif DEBUG
        !           259: }
        !           260: 
        !           261:     /*
        !           262:      * visit a node after all its children
        !           263:      * [MISSING: an explanation]
        !           264:      * and pop it off the stack
        !           265:      */
        !           266: dfn_post_visit( parentp )
        !           267:     nltype     *parentp;
        !           268: {
        !           269:     nltype     *memberp;
        !           270: 
        !           271: #   ifdef DEBUG
        !           272:        if ( debug & DFNDEBUG ) {
        !           273:            printf( "[dfn_post_visit]\t%d: " , dfn_depth );
        !           274:            printname( parentp );
        !           275:            printf( "\n" );
        !           276:        }
        !           277: #   endif DEBUG
        !           278:        /*
        !           279:         *      number functions and things in their cycles
        !           280:         *      unless the function is itself part of a cycle
        !           281:         */
        !           282:     if ( parentp -> cyclehead == parentp ) {
        !           283:        dfn_counter += 1;
        !           284:        for ( memberp = parentp ; memberp ; memberp = memberp -> cnext ) {
        !           285:            memberp -> toporder = dfn_counter;
        !           286: #          ifdef DEBUG
        !           287:                if ( debug & DFNDEBUG ) {
        !           288:                    printf( "[dfn_post_visit]\t\tmember " );
        !           289:                    printname( memberp );
        !           290:                    printf( " -> toporder = %d\n" , dfn_counter );
        !           291:                }
        !           292: #          endif DEBUG
        !           293:        }
        !           294:     } else {
        !           295: #      ifdef DEBUG
        !           296:            if ( debug & DFNDEBUG ) {
        !           297:                printf( "[dfn_post_visit]\t\tis part of a cycle\n" );
        !           298:            }
        !           299: #      endif DEBUG
        !           300:     }
        !           301:     dfn_depth -= 1;
        !           302: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.