2 * Copyright (c) 1983, 1993
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 * @(#)arcs.c 8.1 (Berkeley) 6/6/93
34 * $FreeBSD: src/usr.bin/gprof/arcs.c,v 1.6 1999/08/28 01:01:54 peter Exp $
35 * $DragonFly: src/usr.bin/gprof/arcs.c,v 1.5 2006/01/22 03:43:37 swildner Exp $
49 * add (or just increment) an arc
51 addarc(nltype
*parentp
, nltype
*childp
, long count
)
56 if ( debug
& TALLYDEBUG
) {
57 printf( "[addarc] %d arcs from %s to %s\n" ,
58 count
, parentp
-> name
, childp
-> name
);
61 arcp
= arclookup( parentp
, childp
);
64 * a hit: just increment the count.
67 if ( debug
& TALLYDEBUG
) {
68 printf( "[tally] hit %d += %d\n" ,
69 arcp
-> arc_count
, count
);
72 arcp
-> arc_count
+= count
;
75 arcp
= (arctype
*)calloc( 1 , sizeof *arcp
);
76 arcp
-> arc_parentp
= parentp
;
77 arcp
-> arc_childp
= childp
;
78 arcp
-> arc_count
= count
;
80 * prepend this child to the children of this parent
82 arcp
-> arc_childlist
= parentp
-> children
;
83 parentp
-> children
= arcp
;
85 * prepend this parent to the parents of this child
87 arcp
-> arc_parentlist
= childp
-> parents
;
88 childp
-> parents
= arcp
;
92 * the code below topologically sorts the graph (collapsing cycles),
93 * and propagates time bottom up and flags top down.
97 * the topologically sorted name list pointers
102 topcmp(const void *arg1
, const void *arg2
)
104 nltype
*const*npp1
= arg1
;
105 nltype
*const*npp2
= arg2
;
107 return (*npp1
) -> toporder
- (*npp2
) -> toporder
;
113 nltype
*parentp
, **timesortnlp
;
119 * initialize various things:
120 * zero out child times.
121 * count self-recursive calls.
122 * indicate that nothing is on cycles.
124 for ( parentp
= nl
; parentp
< npe
; parentp
++ ) {
125 parentp
-> childtime
= 0.0;
126 arcp
= arclookup( parentp
, parentp
);
128 parentp
-> ncall
-= arcp
-> arc_count
;
129 parentp
-> selfcalls
= arcp
-> arc_count
;
131 parentp
-> selfcalls
= 0;
133 parentp
-> npropcall
= parentp
-> ncall
;
134 parentp
-> propfraction
= 0.0;
135 parentp
-> propself
= 0.0;
136 parentp
-> propchild
= 0.0;
137 parentp
-> printflag
= FALSE
;
138 parentp
-> toporder
= DFN_NAN
;
139 parentp
-> cycleno
= 0;
140 parentp
-> cyclehead
= parentp
;
141 parentp
-> cnext
= 0;
143 findcall( parentp
, parentp
-> value
, (parentp
+1) -> value
);
146 for ( pass
= 1 ; ; pass
++ ) {
148 * topologically order things
149 * if any node is unnumbered,
150 * number it and any of its descendents.
152 for ( dfn_init() , parentp
= nl
; parentp
< npe
; parentp
++ ) {
153 if ( parentp
-> toporder
== DFN_NAN
) {
158 * link together nodes on the same cycle
162 * if no cycles to break up, proceed
167 * analyze cycles to determine breakup
170 if ( debug
& BREAKCYCLE
) {
171 printf("[doarcs] pass %d, cycle(s) %d\n" , pass
, ncycle
);
175 printf( "\n\n%s %s\n%s %d:\n" ,
176 "The following arcs were deleted" ,
177 "from the propagation calculation" ,
178 "to reduce the maximum cycle size to", cyclethreshold
);
180 if ( cycleanalyze() )
184 for ( parentp
= nl
; parentp
< npe
; parentp
++ ) {
185 parentp
-> toporder
= DFN_NAN
;
186 parentp
-> cycleno
= 0;
187 parentp
-> cyclehead
= parentp
;
188 parentp
-> cnext
= 0;
194 printf( "\tNone\n\n" );
197 * Sort the symbol table in reverse topological order
199 topsortnlp
= (nltype
**) calloc( nname
, sizeof(nltype
*) );
200 if ( topsortnlp
== NULL
) {
201 fprintf( stderr
, "[doarcs] ran out of memory for topo sorting\n" );
203 for ( index
= 0 ; index
< nname
; index
+= 1 ) {
204 topsortnlp
[ index
] = &nl
[ index
];
206 qsort( topsortnlp
, nname
, sizeof(nltype
*) , topcmp
);
208 if ( debug
& DFNDEBUG
) {
209 printf( "[doarcs] topological sort listing\n" );
210 for ( index
= 0 ; index
< nname
; index
+= 1 ) {
211 printf( "[doarcs] " );
212 printf( "%d:" , topsortnlp
[ index
] -> toporder
);
213 printname( topsortnlp
[ index
] );
219 * starting from the topological top,
220 * propagate print flags to children.
221 * also, calculate propagation fractions.
222 * this happens before time propagation
223 * since time propagation uses the fractions.
227 * starting from the topological bottom,
228 * propogate children times up to parents.
232 * Now, sort by propself + propchild.
233 * sorting both the regular function names
236 timesortnlp
= (nltype
**) calloc( nname
+ ncycle
, sizeof(nltype
*) );
237 if ( timesortnlp
== NULL
) {
238 warnx("ran out of memory for sorting");
240 for ( index
= 0 ; index
< nname
; index
++ ) {
241 timesortnlp
[index
] = &nl
[index
];
243 for ( index
= 1 ; index
<= ncycle
; index
++ ) {
244 timesortnlp
[nname
+index
-1] = &cyclenl
[index
];
246 qsort( timesortnlp
, nname
+ ncycle
, sizeof(nltype
*) , totalcmp
);
247 for ( index
= 0 ; index
< nname
+ ncycle
; index
++ ) {
248 timesortnlp
[ index
] -> index
= index
+ 1;
250 return( timesortnlp
);
258 for ( index
= 0 ; index
< nname
; index
+= 1 ) {
259 timepropagate( topsortnlp
[ index
] );
263 timepropagate(nltype
*parentp
)
270 if ( parentp
-> propfraction
== 0.0 ) {
274 * gather time from children of this parent.
276 for ( arcp
= parentp
-> children
; arcp
; arcp
= arcp
-> arc_childlist
) {
277 childp
= arcp
-> arc_childp
;
278 if ( arcp
-> arc_flags
& DEADARC
) {
281 if ( arcp
-> arc_count
== 0 ) {
284 if ( childp
== parentp
) {
287 if ( childp
-> propfraction
== 0.0 ) {
290 if ( childp
-> cyclehead
!= childp
) {
291 if ( parentp
-> cycleno
== childp
-> cycleno
) {
294 if ( parentp
-> toporder
<= childp
-> toporder
) {
295 fprintf( stderr
, "[propagate] toporder botches\n" );
297 childp
= childp
-> cyclehead
;
299 if ( parentp
-> toporder
<= childp
-> toporder
) {
300 fprintf( stderr
, "[propagate] toporder botches\n" );
304 if ( childp
-> npropcall
== 0 ) {
308 * distribute time for this arc
310 arcp
-> arc_time
= childp
-> time
311 * ( ( (double) arcp
-> arc_count
) /
312 ( (double) childp
-> npropcall
) );
313 arcp
-> arc_childtime
= childp
-> childtime
314 * ( ( (double) arcp
-> arc_count
) /
315 ( (double) childp
-> npropcall
) );
316 share
= arcp
-> arc_time
+ arcp
-> arc_childtime
;
317 parentp
-> childtime
+= share
;
319 * ( 1 - propfraction ) gets lost along the way
321 propshare
= parentp
-> propfraction
* share
;
323 * fix things for printing
325 parentp
-> propchild
+= propshare
;
326 arcp
-> arc_time
*= parentp
-> propfraction
;
327 arcp
-> arc_childtime
*= parentp
-> propfraction
;
329 * add this share to the parent's cycle header, if any.
331 if ( parentp
-> cyclehead
!= parentp
) {
332 parentp
-> cyclehead
-> childtime
+= share
;
333 parentp
-> cyclehead
-> propchild
+= propshare
;
336 if ( debug
& PROPDEBUG
) {
337 printf( "[dotime] child \t" );
339 printf( " with %f %f %d/%d\n" ,
340 childp
-> time
, childp
-> childtime
,
341 arcp
-> arc_count
, childp
-> npropcall
);
342 printf( "[dotime] parent\t" );
343 printname( parentp
);
344 printf( "\n[dotime] share %f\n" , share
);
359 * Count the number of cycles, and initialze the cycle lists
362 for ( nlp
= nl
; nlp
< npe
; nlp
++ ) {
364 * this is how you find unattached cycles
366 if ( nlp
-> cyclehead
== nlp
&& nlp
-> cnext
!= 0 ) {
371 * cyclenl is indexed by cycle number:
372 * i.e. it is origin 1, not origin 0.
374 cyclenl
= (nltype
*) calloc( ncycle
+ 1 , sizeof( nltype
) );
375 if ( cyclenl
== 0 ) {
376 warnx("no room for %d bytes of cycle headers",
377 ( ncycle
+ 1 ) * sizeof( nltype
) );
381 * now link cycles to true cycleheads,
382 * number them, accumulate the data for the cycle
385 for ( nlp
= nl
; nlp
< npe
; nlp
++ ) {
386 if ( !( nlp
-> cyclehead
== nlp
&& nlp
-> cnext
!= 0 ) ) {
390 cyclenlp
= &cyclenl
[cycle
];
391 cyclenlp
-> name
= 0; /* the name */
392 cyclenlp
-> value
= 0; /* the pc entry point */
393 cyclenlp
-> time
= 0.0; /* ticks in this routine */
394 cyclenlp
-> childtime
= 0.0; /* cumulative ticks in children */
395 cyclenlp
-> ncall
= 0; /* how many times called */
396 cyclenlp
-> selfcalls
= 0; /* how many calls to self */
397 cyclenlp
-> propfraction
= 0.0; /* what % of time propagates */
398 cyclenlp
-> propself
= 0.0; /* how much self time propagates */
399 cyclenlp
-> propchild
= 0.0; /* how much child time propagates */
400 cyclenlp
-> printflag
= TRUE
; /* should this be printed? */
401 cyclenlp
-> index
= 0; /* index in the graph list */
402 cyclenlp
-> toporder
= DFN_NAN
; /* graph call chain top-sort order */
403 cyclenlp
-> cycleno
= cycle
; /* internal number of cycle on */
404 cyclenlp
-> cyclehead
= cyclenlp
; /* pointer to head of cycle */
405 cyclenlp
-> cnext
= nlp
; /* pointer to next member of cycle */
406 cyclenlp
-> parents
= 0; /* list of caller arcs */
407 cyclenlp
-> children
= 0; /* list of callee arcs */
409 if ( debug
& CYCLEDEBUG
) {
410 printf( "[cyclelink] " );
412 printf( " is the head of cycle %d\n" , cycle
);
416 * link members to cycle header
418 for ( memberp
= nlp
; memberp
; memberp
= memberp
-> cnext
) {
419 memberp
-> cycleno
= cycle
;
420 memberp
-> cyclehead
= cyclenlp
;
423 * count calls from outside the cycle
424 * and those among cycle members
426 for ( memberp
= nlp
; memberp
; memberp
= memberp
-> cnext
) {
427 for ( arcp
=memberp
->parents
; arcp
; arcp
=arcp
->arc_parentlist
) {
428 if ( arcp
-> arc_parentp
== memberp
) {
431 if ( arcp
-> arc_parentp
-> cycleno
== cycle
) {
432 cyclenlp
-> selfcalls
+= arcp
-> arc_count
;
434 cyclenlp
-> npropcall
+= arcp
-> arc_count
;
442 * analyze cycles to determine breakup
446 arctype
**cyclestack
;
459 * calculate the size of the cycle, and find nodes that
460 * exit the cycle as they are desirable targets to cut
461 * some of their parents
463 for ( done
= TRUE
, cycleno
= 1 ; cycleno
<= ncycle
; cycleno
++ ) {
465 for (nlp
= cyclenl
[ cycleno
] . cnext
; nlp
; nlp
= nlp
-> cnext
) {
467 nlp
-> parentcnt
= 0;
468 nlp
-> flags
&= ~HASCYCLEXIT
;
469 for ( arcp
= nlp
-> parents
; arcp
; arcp
= arcp
-> arc_parentlist
) {
470 nlp
-> parentcnt
+= 1;
471 if ( arcp
-> arc_parentp
-> cycleno
!= cycleno
)
472 nlp
-> flags
|= HASCYCLEXIT
;
475 if ( size
<= cyclethreshold
)
478 cyclestack
= (arctype
**) calloc( size
+ 1 , sizeof( arctype
*) );
479 if ( cyclestack
== 0 ) {
480 warnx("no room for %d bytes of cycle stack",
481 ( size
+ 1 ) * sizeof( arctype
* ) );
485 if ( debug
& BREAKCYCLE
) {
486 printf( "[cycleanalyze] starting cycle %d of %d, size %d\n" ,
487 cycleno
, ncycle
, size
);
490 for ( nlp
= cyclenl
[ cycleno
] . cnext
; nlp
; nlp
= nlp
-> cnext
) {
491 stkp
= &cyclestack
[0];
492 nlp
-> flags
|= CYCLEHEAD
;
493 ret
= descend ( nlp
, cyclestack
, stkp
);
494 nlp
-> flags
&= ~CYCLEHEAD
;
499 if ( cyclecnt
> 0 ) {
501 for ( clp
= cyclehead
; clp
; ) {
502 endlist
= &clp
-> list
[ clp
-> size
];
503 for ( arcpp
= clp
-> list
; arcpp
< endlist
; arcpp
++ )
504 (*arcpp
) -> arc_cyclecnt
--;
513 if ( debug
& BREAKCYCLE
) {
514 printf("%s visited %d, viable %d, newcycle %d, oldcycle %d\n",
515 "[doarcs]" , visited
, viable
, newcycle
, oldcycle
);
521 descend(nltype
*node
, arctype
**stkstart
, arctype
**stkp
)
526 for ( arcp
= node
-> children
; arcp
; arcp
= arcp
-> arc_childlist
) {
530 if ( arcp
-> arc_childp
-> cycleno
!= node
-> cycleno
531 || ( arcp
-> arc_childp
-> flags
& VISITED
)
532 || ( arcp
-> arc_flags
& DEADARC
) )
538 if ( arcp
-> arc_childp
-> flags
& CYCLEHEAD
) {
539 if ( addcycle( stkstart
, stkp
) == FALSE
)
543 arcp
-> arc_childp
-> flags
|= VISITED
;
544 ret
= descend( arcp
-> arc_childp
, stkstart
, stkp
+ 1 );
545 arcp
-> arc_childp
-> flags
&= ~VISITED
;
551 addcycle(arctype
**stkstart
, arctype
**stkend
)
562 size
= stkend
- stkstart
+ 1;
565 for ( arcpp
= stkstart
, minarc
= *arcpp
; arcpp
<= stkend
; arcpp
++ ) {
566 if ( *arcpp
> minarc
)
571 for ( clp
= cyclehead
; clp
; clp
= clp
-> next
) {
572 if ( clp
-> size
!= size
)
575 endlist
= &clp
-> list
[ size
];
576 for ( arcpp
= clp
-> list
; arcpp
< endlist
; arcpp
++ ) {
577 if ( *stkp
++ != *arcpp
)
582 if ( arcpp
== endlist
) {
590 calloc( 1 , sizeof ( cltype
) + ( size
- 1 ) * sizeof( arctype
* ) );
592 warnx("no room for %d bytes of subcycle storage",
593 sizeof ( cltype
) + ( size
- 1 ) * sizeof( arctype
* ) );
597 endlist
= &clp
-> list
[ size
];
598 for ( arcpp
= clp
-> list
; arcpp
< endlist
; arcpp
++ ) {
599 arcp
= *arcpp
= *stkp
++;
602 arcp
-> arc_cyclecnt
++;
603 if ( ( arcp
-> arc_flags
& ONLIST
) == 0 ) {
604 arcp
-> arc_flags
|= ONLIST
;
605 arcp
-> arc_next
= archead
;
610 clp
-> next
= cyclehead
;
614 if ( debug
& SUBCYCLELIST
) {
615 printsubcycle( clp
);
619 if ( cyclecnt
>= CYCLEMAX
)
632 arctype
*maxexitarcp
;
633 arctype
*maxwithparentarcp
;
634 arctype
*maxnoparentarcp
;
636 int maxwithparentcnt
;
640 maxwithparentcnt
= 0;
642 for ( endlist
= &archead
, arcp
= archead
; arcp
; ) {
643 if ( arcp
-> arc_cyclecnt
== 0 ) {
644 arcp
-> arc_flags
&= ~ONLIST
;
645 *endlist
= arcp
-> arc_next
;
646 arcp
-> arc_next
= 0;
650 if ( arcp
-> arc_childp
-> flags
& HASCYCLEXIT
) {
651 if ( arcp
-> arc_cyclecnt
> maxexitcnt
||
652 ( arcp
-> arc_cyclecnt
== maxexitcnt
&&
653 arcp
-> arc_cyclecnt
< maxexitarcp
-> arc_count
) ) {
654 maxexitcnt
= arcp
-> arc_cyclecnt
;
657 } else if ( arcp
-> arc_childp
-> parentcnt
> 1 ) {
658 if ( arcp
-> arc_cyclecnt
> maxwithparentcnt
||
659 ( arcp
-> arc_cyclecnt
== maxwithparentcnt
&&
660 arcp
-> arc_cyclecnt
< maxwithparentarcp
-> arc_count
) ) {
661 maxwithparentcnt
= arcp
-> arc_cyclecnt
;
662 maxwithparentarcp
= arcp
;
665 if ( arcp
-> arc_cyclecnt
> maxnoparentcnt
||
666 ( arcp
-> arc_cyclecnt
== maxnoparentcnt
&&
667 arcp
-> arc_cyclecnt
< maxnoparentarcp
-> arc_count
) ) {
668 maxnoparentcnt
= arcp
-> arc_cyclecnt
;
669 maxnoparentarcp
= arcp
;
672 endlist
= &arcp
-> arc_next
;
673 arcp
= arcp
-> arc_next
;
675 if ( maxexitcnt
> 0 ) {
677 * first choice is edge leading to node with out-of-cycle parent
679 maxarcp
= maxexitarcp
;
683 } else if ( maxwithparentcnt
> 0 ) {
685 * second choice is edge leading to node with at least one
686 * other in-cycle parent
688 maxarcp
= maxwithparentarcp
;
694 * last choice is edge leading to node with only this arc as
695 * a parent (as it will now be orphaned)
697 maxarcp
= maxnoparentarcp
;
702 maxarcp
-> arc_flags
|= DEADARC
;
703 maxarcp
-> arc_childp
-> parentcnt
-= 1;
704 maxarcp
-> arc_childp
-> npropcall
-= maxarcp
-> arc_count
;
706 if ( debug
& BREAKCYCLE
) {
707 printf( "%s delete %s arc: %s (%d) -> %s from %d cycle(s)\n" ,
708 "[compresslist]" , type
, maxarcp
-> arc_parentp
-> name
,
709 maxarcp
-> arc_count
, maxarcp
-> arc_childp
-> name
,
710 maxarcp
-> arc_cyclecnt
);
713 printf( "\t%s to %s with %d calls\n" , maxarcp
-> arc_parentp
-> name
,
714 maxarcp
-> arc_childp
-> name
, maxarcp
-> arc_count
);
716 for ( clp
= cyclehead
; clp
; ) {
717 endlist
= &clp
-> list
[ clp
-> size
];
718 for ( arcpp
= clp
-> list
; arcpp
< endlist
; arcpp
++ )
719 if ( (*arcpp
) -> arc_flags
& DEADARC
)
721 if ( arcpp
== endlist
) {
726 for ( arcpp
= clp
-> list
; arcpp
< endlist
; arcpp
++ )
727 (*arcpp
) -> arc_cyclecnt
--;
736 printsubcycle(cltype
*clp
)
742 printf( "%s <cycle %d>\n" , (*arcpp
) -> arc_parentp
-> name
,
743 (*arcpp
) -> arc_parentp
-> cycleno
) ;
744 for ( endlist
= &clp
-> list
[ clp
-> size
]; arcpp
< endlist
; arcpp
++ )
745 printf( "\t(%d) -> %s\n" , (*arcpp
) -> arc_count
,
746 (*arcpp
) -> arc_childp
-> name
) ;
756 for ( cycle
= 1 ; cycle
<= ncycle
; cycle
+= 1 ) {
757 cyclenlp
= &cyclenl
[ cycle
];
758 for ( childp
= cyclenlp
-> cnext
; childp
; childp
= childp
-> cnext
) {
759 if ( childp
-> propfraction
== 0.0 ) {
761 * all members have the same propfraction except those
762 * that were excluded with -E
766 cyclenlp
-> time
+= childp
-> time
;
768 cyclenlp
-> propself
= cyclenlp
-> propfraction
* cyclenlp
-> time
;
773 * in one top to bottom pass over the topologically sorted namelist
775 * printflag as the union of parents' printflags
776 * propfraction as the sum of fractional parents' propfractions
777 * and while we're here, sum time for functions.
786 for ( index
= nname
-1 ; index
>= 0 ; index
-= 1 ) {
787 childp
= topsortnlp
[ index
];
789 * if we haven't done this function or cycle,
790 * inherit things from parent.
791 * this way, we are linear in the number of arcs
792 * since we do all members of a cycle (and the cycle itself)
793 * as we hit the first member of the cycle.
795 if ( childp
-> cyclehead
!= oldhead
) {
796 oldhead
= childp
-> cyclehead
;
797 inheritflags( childp
);
800 if ( debug
& PROPDEBUG
) {
801 printf( "[doflags] " );
803 printf( " inherits printflag %d and propfraction %f\n" ,
804 childp
-> printflag
, childp
-> propfraction
);
807 if ( ! childp
-> printflag
) {
810 * it gets turned on by
812 * or there not being any -f list and not being on -e list.
814 if ( onlist( flist
, childp
-> name
)
815 || ( !fflag
&& !onlist( elist
, childp
-> name
) ) ) {
816 childp
-> printflag
= TRUE
;
820 * this function has printing parents:
821 * maybe someone wants to shut it up
822 * by putting it on -e list. (but favor -f over -e)
824 if ( ( !onlist( flist
, childp
-> name
) )
825 && onlist( elist
, childp
-> name
) ) {
826 childp
-> printflag
= FALSE
;
829 if ( childp
-> propfraction
== 0.0 ) {
831 * no parents to pass time to.
832 * collect time from children if
834 * or there isn't any -F list and its not on -E list.
836 if ( onlist( Flist
, childp
-> name
)
837 || ( !Fflag
&& !onlist( Elist
, childp
-> name
) ) ) {
838 childp
-> propfraction
= 1.0;
842 * it has parents to pass time to,
843 * but maybe someone wants to shut it up
844 * by puttting it on -E list. (but favor -F over -E)
846 if ( !onlist( Flist
, childp
-> name
)
847 && onlist( Elist
, childp
-> name
) ) {
848 childp
-> propfraction
= 0.0;
851 childp
-> propself
= childp
-> time
* childp
-> propfraction
;
852 printtime
+= childp
-> propself
;
854 if ( debug
& PROPDEBUG
) {
855 printf( "[doflags] " );
857 printf( " ends up with printflag %d and propfraction %f\n" ,
858 childp
-> printflag
, childp
-> propfraction
);
859 printf( "time %f propself %f printtime %f\n" ,
860 childp
-> time
, childp
-> propself
, printtime
);
867 * check if any parent of this child
868 * (or outside parents of this cycle)
869 * have their print flags on and set the
870 * print flag of the child (cycle) appropriately.
871 * similarly, deal with propagation fractions from parents.
873 inheritflags(nltype
*childp
)
880 headp
= childp
-> cyclehead
;
881 if ( childp
== headp
) {
883 * just a regular child, check its parents
885 childp
-> printflag
= FALSE
;
886 childp
-> propfraction
= 0.0;
887 for (arcp
= childp
-> parents
; arcp
; arcp
= arcp
-> arc_parentlist
) {
888 parentp
= arcp
-> arc_parentp
;
889 if ( childp
== parentp
) {
892 childp
-> printflag
|= parentp
-> printflag
;
894 * if the child was never actually called
895 * (e.g. this arc is static (and all others are, too))
896 * no time propagates along this arc.
898 if ( arcp
-> arc_flags
& DEADARC
) {
901 if ( childp
-> npropcall
) {
902 childp
-> propfraction
+= parentp
-> propfraction
903 * ( ( (double) arcp
-> arc_count
)
904 / ( (double) childp
-> npropcall
) );
909 * its a member of a cycle, look at all parents from
912 headp
-> printflag
= FALSE
;
913 headp
-> propfraction
= 0.0;
914 for ( memp
= headp
-> cnext
; memp
; memp
= memp
-> cnext
) {
915 for (arcp
= memp
->parents
; arcp
; arcp
= arcp
->arc_parentlist
) {
916 if ( arcp
-> arc_parentp
-> cyclehead
== headp
) {
919 parentp
= arcp
-> arc_parentp
;
920 headp
-> printflag
|= parentp
-> printflag
;
922 * if the cycle was never actually called
923 * (e.g. this arc is static (and all others are, too))
924 * no time propagates along this arc.
926 if ( arcp
-> arc_flags
& DEADARC
) {
929 if ( headp
-> npropcall
) {
930 headp
-> propfraction
+= parentp
-> propfraction
931 * ( ( (double) arcp
-> arc_count
)
932 / ( (double) headp
-> npropcall
) );
936 for ( memp
= headp
; memp
; memp
= memp
-> cnext
) {
937 memp
-> printflag
= headp
-> printflag
;
938 memp
-> propfraction
= headp
-> propfraction
;