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
101 topcmp(nltype
**npp1
, nltype
**npp2
)
103 return (*npp1
) -> toporder
- (*npp2
) -> toporder
;
109 nltype
*parentp
, **timesortnlp
;
115 * initialize various things:
116 * zero out child times.
117 * count self-recursive calls.
118 * indicate that nothing is on cycles.
120 for ( parentp
= nl
; parentp
< npe
; parentp
++ ) {
121 parentp
-> childtime
= 0.0;
122 arcp
= arclookup( parentp
, parentp
);
124 parentp
-> ncall
-= arcp
-> arc_count
;
125 parentp
-> selfcalls
= arcp
-> arc_count
;
127 parentp
-> selfcalls
= 0;
129 parentp
-> npropcall
= parentp
-> ncall
;
130 parentp
-> propfraction
= 0.0;
131 parentp
-> propself
= 0.0;
132 parentp
-> propchild
= 0.0;
133 parentp
-> printflag
= FALSE
;
134 parentp
-> toporder
= DFN_NAN
;
135 parentp
-> cycleno
= 0;
136 parentp
-> cyclehead
= parentp
;
137 parentp
-> cnext
= 0;
139 findcall( parentp
, parentp
-> value
, (parentp
+1) -> value
);
142 for ( pass
= 1 ; ; pass
++ ) {
144 * topologically order things
145 * if any node is unnumbered,
146 * number it and any of its descendents.
148 for ( dfn_init() , parentp
= nl
; parentp
< npe
; parentp
++ ) {
149 if ( parentp
-> toporder
== DFN_NAN
) {
154 * link together nodes on the same cycle
158 * if no cycles to break up, proceed
163 * analyze cycles to determine breakup
166 if ( debug
& BREAKCYCLE
) {
167 printf("[doarcs] pass %d, cycle(s) %d\n" , pass
, ncycle
);
171 printf( "\n\n%s %s\n%s %d:\n" ,
172 "The following arcs were deleted" ,
173 "from the propagation calculation" ,
174 "to reduce the maximum cycle size to", cyclethreshold
);
176 if ( cycleanalyze() )
180 for ( parentp
= nl
; parentp
< npe
; parentp
++ ) {
181 parentp
-> toporder
= DFN_NAN
;
182 parentp
-> cycleno
= 0;
183 parentp
-> cyclehead
= parentp
;
184 parentp
-> cnext
= 0;
190 printf( "\tNone\n\n" );
193 * Sort the symbol table in reverse topological order
195 topsortnlp
= (nltype
**) calloc( nname
, sizeof(nltype
*) );
196 if ( topsortnlp
== NULL
) {
197 fprintf( stderr
, "[doarcs] ran out of memory for topo sorting\n" );
199 for ( index
= 0 ; index
< nname
; index
+= 1 ) {
200 topsortnlp
[ index
] = &nl
[ index
];
202 qsort( topsortnlp
, nname
, sizeof(nltype
*) , topcmp
);
204 if ( debug
& DFNDEBUG
) {
205 printf( "[doarcs] topological sort listing\n" );
206 for ( index
= 0 ; index
< nname
; index
+= 1 ) {
207 printf( "[doarcs] " );
208 printf( "%d:" , topsortnlp
[ index
] -> toporder
);
209 printname( topsortnlp
[ index
] );
215 * starting from the topological top,
216 * propagate print flags to children.
217 * also, calculate propagation fractions.
218 * this happens before time propagation
219 * since time propagation uses the fractions.
223 * starting from the topological bottom,
224 * propogate children times up to parents.
228 * Now, sort by propself + propchild.
229 * sorting both the regular function names
232 timesortnlp
= (nltype
**) calloc( nname
+ ncycle
, sizeof(nltype
*) );
233 if ( timesortnlp
== NULL
) {
234 warnx("ran out of memory for sorting");
236 for ( index
= 0 ; index
< nname
; index
++ ) {
237 timesortnlp
[index
] = &nl
[index
];
239 for ( index
= 1 ; index
<= ncycle
; index
++ ) {
240 timesortnlp
[nname
+index
-1] = &cyclenl
[index
];
242 qsort( timesortnlp
, nname
+ ncycle
, sizeof(nltype
*) , totalcmp
);
243 for ( index
= 0 ; index
< nname
+ ncycle
; index
++ ) {
244 timesortnlp
[ index
] -> index
= index
+ 1;
246 return( timesortnlp
);
254 for ( index
= 0 ; index
< nname
; index
+= 1 ) {
255 timepropagate( topsortnlp
[ index
] );
259 timepropagate(nltype
*parentp
)
266 if ( parentp
-> propfraction
== 0.0 ) {
270 * gather time from children of this parent.
272 for ( arcp
= parentp
-> children
; arcp
; arcp
= arcp
-> arc_childlist
) {
273 childp
= arcp
-> arc_childp
;
274 if ( arcp
-> arc_flags
& DEADARC
) {
277 if ( arcp
-> arc_count
== 0 ) {
280 if ( childp
== parentp
) {
283 if ( childp
-> propfraction
== 0.0 ) {
286 if ( childp
-> cyclehead
!= childp
) {
287 if ( parentp
-> cycleno
== childp
-> cycleno
) {
290 if ( parentp
-> toporder
<= childp
-> toporder
) {
291 fprintf( stderr
, "[propagate] toporder botches\n" );
293 childp
= childp
-> cyclehead
;
295 if ( parentp
-> toporder
<= childp
-> toporder
) {
296 fprintf( stderr
, "[propagate] toporder botches\n" );
300 if ( childp
-> npropcall
== 0 ) {
304 * distribute time for this arc
306 arcp
-> arc_time
= childp
-> time
307 * ( ( (double) arcp
-> arc_count
) /
308 ( (double) childp
-> npropcall
) );
309 arcp
-> arc_childtime
= childp
-> childtime
310 * ( ( (double) arcp
-> arc_count
) /
311 ( (double) childp
-> npropcall
) );
312 share
= arcp
-> arc_time
+ arcp
-> arc_childtime
;
313 parentp
-> childtime
+= share
;
315 * ( 1 - propfraction ) gets lost along the way
317 propshare
= parentp
-> propfraction
* share
;
319 * fix things for printing
321 parentp
-> propchild
+= propshare
;
322 arcp
-> arc_time
*= parentp
-> propfraction
;
323 arcp
-> arc_childtime
*= parentp
-> propfraction
;
325 * add this share to the parent's cycle header, if any.
327 if ( parentp
-> cyclehead
!= parentp
) {
328 parentp
-> cyclehead
-> childtime
+= share
;
329 parentp
-> cyclehead
-> propchild
+= propshare
;
332 if ( debug
& PROPDEBUG
) {
333 printf( "[dotime] child \t" );
335 printf( " with %f %f %d/%d\n" ,
336 childp
-> time
, childp
-> childtime
,
337 arcp
-> arc_count
, childp
-> npropcall
);
338 printf( "[dotime] parent\t" );
339 printname( parentp
);
340 printf( "\n[dotime] share %f\n" , share
);
355 * Count the number of cycles, and initialze the cycle lists
358 for ( nlp
= nl
; nlp
< npe
; nlp
++ ) {
360 * this is how you find unattached cycles
362 if ( nlp
-> cyclehead
== nlp
&& nlp
-> cnext
!= 0 ) {
367 * cyclenl is indexed by cycle number:
368 * i.e. it is origin 1, not origin 0.
370 cyclenl
= (nltype
*) calloc( ncycle
+ 1 , sizeof( nltype
) );
371 if ( cyclenl
== 0 ) {
372 warnx("no room for %d bytes of cycle headers",
373 ( ncycle
+ 1 ) * sizeof( nltype
) );
377 * now link cycles to true cycleheads,
378 * number them, accumulate the data for the cycle
381 for ( nlp
= nl
; nlp
< npe
; nlp
++ ) {
382 if ( !( nlp
-> cyclehead
== nlp
&& nlp
-> cnext
!= 0 ) ) {
386 cyclenlp
= &cyclenl
[cycle
];
387 cyclenlp
-> name
= 0; /* the name */
388 cyclenlp
-> value
= 0; /* the pc entry point */
389 cyclenlp
-> time
= 0.0; /* ticks in this routine */
390 cyclenlp
-> childtime
= 0.0; /* cumulative ticks in children */
391 cyclenlp
-> ncall
= 0; /* how many times called */
392 cyclenlp
-> selfcalls
= 0; /* how many calls to self */
393 cyclenlp
-> propfraction
= 0.0; /* what % of time propagates */
394 cyclenlp
-> propself
= 0.0; /* how much self time propagates */
395 cyclenlp
-> propchild
= 0.0; /* how much child time propagates */
396 cyclenlp
-> printflag
= TRUE
; /* should this be printed? */
397 cyclenlp
-> index
= 0; /* index in the graph list */
398 cyclenlp
-> toporder
= DFN_NAN
; /* graph call chain top-sort order */
399 cyclenlp
-> cycleno
= cycle
; /* internal number of cycle on */
400 cyclenlp
-> cyclehead
= cyclenlp
; /* pointer to head of cycle */
401 cyclenlp
-> cnext
= nlp
; /* pointer to next member of cycle */
402 cyclenlp
-> parents
= 0; /* list of caller arcs */
403 cyclenlp
-> children
= 0; /* list of callee arcs */
405 if ( debug
& CYCLEDEBUG
) {
406 printf( "[cyclelink] " );
408 printf( " is the head of cycle %d\n" , cycle
);
412 * link members to cycle header
414 for ( memberp
= nlp
; memberp
; memberp
= memberp
-> cnext
) {
415 memberp
-> cycleno
= cycle
;
416 memberp
-> cyclehead
= cyclenlp
;
419 * count calls from outside the cycle
420 * and those among cycle members
422 for ( memberp
= nlp
; memberp
; memberp
= memberp
-> cnext
) {
423 for ( arcp
=memberp
->parents
; arcp
; arcp
=arcp
->arc_parentlist
) {
424 if ( arcp
-> arc_parentp
== memberp
) {
427 if ( arcp
-> arc_parentp
-> cycleno
== cycle
) {
428 cyclenlp
-> selfcalls
+= arcp
-> arc_count
;
430 cyclenlp
-> npropcall
+= arcp
-> arc_count
;
438 * analyze cycles to determine breakup
442 arctype
**cyclestack
;
455 * calculate the size of the cycle, and find nodes that
456 * exit the cycle as they are desirable targets to cut
457 * some of their parents
459 for ( done
= TRUE
, cycleno
= 1 ; cycleno
<= ncycle
; cycleno
++ ) {
461 for (nlp
= cyclenl
[ cycleno
] . cnext
; nlp
; nlp
= nlp
-> cnext
) {
463 nlp
-> parentcnt
= 0;
464 nlp
-> flags
&= ~HASCYCLEXIT
;
465 for ( arcp
= nlp
-> parents
; arcp
; arcp
= arcp
-> arc_parentlist
) {
466 nlp
-> parentcnt
+= 1;
467 if ( arcp
-> arc_parentp
-> cycleno
!= cycleno
)
468 nlp
-> flags
|= HASCYCLEXIT
;
471 if ( size
<= cyclethreshold
)
474 cyclestack
= (arctype
**) calloc( size
+ 1 , sizeof( arctype
*) );
475 if ( cyclestack
== 0 ) {
476 warnx("no room for %d bytes of cycle stack",
477 ( size
+ 1 ) * sizeof( arctype
* ) );
481 if ( debug
& BREAKCYCLE
) {
482 printf( "[cycleanalyze] starting cycle %d of %d, size %d\n" ,
483 cycleno
, ncycle
, size
);
486 for ( nlp
= cyclenl
[ cycleno
] . cnext
; nlp
; nlp
= nlp
-> cnext
) {
487 stkp
= &cyclestack
[0];
488 nlp
-> flags
|= CYCLEHEAD
;
489 ret
= descend ( nlp
, cyclestack
, stkp
);
490 nlp
-> flags
&= ~CYCLEHEAD
;
495 if ( cyclecnt
> 0 ) {
497 for ( clp
= cyclehead
; clp
; ) {
498 endlist
= &clp
-> list
[ clp
-> size
];
499 for ( arcpp
= clp
-> list
; arcpp
< endlist
; arcpp
++ )
500 (*arcpp
) -> arc_cyclecnt
--;
509 if ( debug
& BREAKCYCLE
) {
510 printf("%s visited %d, viable %d, newcycle %d, oldcycle %d\n",
511 "[doarcs]" , visited
, viable
, newcycle
, oldcycle
);
517 descend(nltype
*node
, arctype
**stkstart
, arctype
**stkp
)
522 for ( arcp
= node
-> children
; arcp
; arcp
= arcp
-> arc_childlist
) {
526 if ( arcp
-> arc_childp
-> cycleno
!= node
-> cycleno
527 || ( arcp
-> arc_childp
-> flags
& VISITED
)
528 || ( arcp
-> arc_flags
& DEADARC
) )
534 if ( arcp
-> arc_childp
-> flags
& CYCLEHEAD
) {
535 if ( addcycle( stkstart
, stkp
) == FALSE
)
539 arcp
-> arc_childp
-> flags
|= VISITED
;
540 ret
= descend( arcp
-> arc_childp
, stkstart
, stkp
+ 1 );
541 arcp
-> arc_childp
-> flags
&= ~VISITED
;
547 addcycle(arctype
**stkstart
, arctype
**stkend
)
558 size
= stkend
- stkstart
+ 1;
561 for ( arcpp
= stkstart
, minarc
= *arcpp
; arcpp
<= stkend
; arcpp
++ ) {
562 if ( *arcpp
> minarc
)
567 for ( clp
= cyclehead
; clp
; clp
= clp
-> next
) {
568 if ( clp
-> size
!= size
)
571 endlist
= &clp
-> list
[ size
];
572 for ( arcpp
= clp
-> list
; arcpp
< endlist
; arcpp
++ ) {
573 if ( *stkp
++ != *arcpp
)
578 if ( arcpp
== endlist
) {
586 calloc( 1 , sizeof ( cltype
) + ( size
- 1 ) * sizeof( arctype
* ) );
588 warnx("no room for %d bytes of subcycle storage",
589 sizeof ( cltype
) + ( size
- 1 ) * sizeof( arctype
* ) );
593 endlist
= &clp
-> list
[ size
];
594 for ( arcpp
= clp
-> list
; arcpp
< endlist
; arcpp
++ ) {
595 arcp
= *arcpp
= *stkp
++;
598 arcp
-> arc_cyclecnt
++;
599 if ( ( arcp
-> arc_flags
& ONLIST
) == 0 ) {
600 arcp
-> arc_flags
|= ONLIST
;
601 arcp
-> arc_next
= archead
;
606 clp
-> next
= cyclehead
;
610 if ( debug
& SUBCYCLELIST
) {
611 printsubcycle( clp
);
615 if ( cyclecnt
>= CYCLEMAX
)
628 arctype
*maxexitarcp
;
629 arctype
*maxwithparentarcp
;
630 arctype
*maxnoparentarcp
;
632 int maxwithparentcnt
;
636 maxwithparentcnt
= 0;
638 for ( endlist
= &archead
, arcp
= archead
; arcp
; ) {
639 if ( arcp
-> arc_cyclecnt
== 0 ) {
640 arcp
-> arc_flags
&= ~ONLIST
;
641 *endlist
= arcp
-> arc_next
;
642 arcp
-> arc_next
= 0;
646 if ( arcp
-> arc_childp
-> flags
& HASCYCLEXIT
) {
647 if ( arcp
-> arc_cyclecnt
> maxexitcnt
||
648 ( arcp
-> arc_cyclecnt
== maxexitcnt
&&
649 arcp
-> arc_cyclecnt
< maxexitarcp
-> arc_count
) ) {
650 maxexitcnt
= arcp
-> arc_cyclecnt
;
653 } else if ( arcp
-> arc_childp
-> parentcnt
> 1 ) {
654 if ( arcp
-> arc_cyclecnt
> maxwithparentcnt
||
655 ( arcp
-> arc_cyclecnt
== maxwithparentcnt
&&
656 arcp
-> arc_cyclecnt
< maxwithparentarcp
-> arc_count
) ) {
657 maxwithparentcnt
= arcp
-> arc_cyclecnt
;
658 maxwithparentarcp
= arcp
;
661 if ( arcp
-> arc_cyclecnt
> maxnoparentcnt
||
662 ( arcp
-> arc_cyclecnt
== maxnoparentcnt
&&
663 arcp
-> arc_cyclecnt
< maxnoparentarcp
-> arc_count
) ) {
664 maxnoparentcnt
= arcp
-> arc_cyclecnt
;
665 maxnoparentarcp
= arcp
;
668 endlist
= &arcp
-> arc_next
;
669 arcp
= arcp
-> arc_next
;
671 if ( maxexitcnt
> 0 ) {
673 * first choice is edge leading to node with out-of-cycle parent
675 maxarcp
= maxexitarcp
;
679 } else if ( maxwithparentcnt
> 0 ) {
681 * second choice is edge leading to node with at least one
682 * other in-cycle parent
684 maxarcp
= maxwithparentarcp
;
690 * last choice is edge leading to node with only this arc as
691 * a parent (as it will now be orphaned)
693 maxarcp
= maxnoparentarcp
;
698 maxarcp
-> arc_flags
|= DEADARC
;
699 maxarcp
-> arc_childp
-> parentcnt
-= 1;
700 maxarcp
-> arc_childp
-> npropcall
-= maxarcp
-> arc_count
;
702 if ( debug
& BREAKCYCLE
) {
703 printf( "%s delete %s arc: %s (%d) -> %s from %d cycle(s)\n" ,
704 "[compresslist]" , type
, maxarcp
-> arc_parentp
-> name
,
705 maxarcp
-> arc_count
, maxarcp
-> arc_childp
-> name
,
706 maxarcp
-> arc_cyclecnt
);
709 printf( "\t%s to %s with %d calls\n" , maxarcp
-> arc_parentp
-> name
,
710 maxarcp
-> arc_childp
-> name
, maxarcp
-> arc_count
);
712 for ( clp
= cyclehead
; clp
; ) {
713 endlist
= &clp
-> list
[ clp
-> size
];
714 for ( arcpp
= clp
-> list
; arcpp
< endlist
; arcpp
++ )
715 if ( (*arcpp
) -> arc_flags
& DEADARC
)
717 if ( arcpp
== endlist
) {
722 for ( arcpp
= clp
-> list
; arcpp
< endlist
; arcpp
++ )
723 (*arcpp
) -> arc_cyclecnt
--;
732 printsubcycle(cltype
*clp
)
738 printf( "%s <cycle %d>\n" , (*arcpp
) -> arc_parentp
-> name
,
739 (*arcpp
) -> arc_parentp
-> cycleno
) ;
740 for ( endlist
= &clp
-> list
[ clp
-> size
]; arcpp
< endlist
; arcpp
++ )
741 printf( "\t(%d) -> %s\n" , (*arcpp
) -> arc_count
,
742 (*arcpp
) -> arc_childp
-> name
) ;
752 for ( cycle
= 1 ; cycle
<= ncycle
; cycle
+= 1 ) {
753 cyclenlp
= &cyclenl
[ cycle
];
754 for ( childp
= cyclenlp
-> cnext
; childp
; childp
= childp
-> cnext
) {
755 if ( childp
-> propfraction
== 0.0 ) {
757 * all members have the same propfraction except those
758 * that were excluded with -E
762 cyclenlp
-> time
+= childp
-> time
;
764 cyclenlp
-> propself
= cyclenlp
-> propfraction
* cyclenlp
-> time
;
769 * in one top to bottom pass over the topologically sorted namelist
771 * printflag as the union of parents' printflags
772 * propfraction as the sum of fractional parents' propfractions
773 * and while we're here, sum time for functions.
782 for ( index
= nname
-1 ; index
>= 0 ; index
-= 1 ) {
783 childp
= topsortnlp
[ index
];
785 * if we haven't done this function or cycle,
786 * inherit things from parent.
787 * this way, we are linear in the number of arcs
788 * since we do all members of a cycle (and the cycle itself)
789 * as we hit the first member of the cycle.
791 if ( childp
-> cyclehead
!= oldhead
) {
792 oldhead
= childp
-> cyclehead
;
793 inheritflags( childp
);
796 if ( debug
& PROPDEBUG
) {
797 printf( "[doflags] " );
799 printf( " inherits printflag %d and propfraction %f\n" ,
800 childp
-> printflag
, childp
-> propfraction
);
803 if ( ! childp
-> printflag
) {
806 * it gets turned on by
808 * or there not being any -f list and not being on -e list.
810 if ( onlist( flist
, childp
-> name
)
811 || ( !fflag
&& !onlist( elist
, childp
-> name
) ) ) {
812 childp
-> printflag
= TRUE
;
816 * this function has printing parents:
817 * maybe someone wants to shut it up
818 * by putting it on -e list. (but favor -f over -e)
820 if ( ( !onlist( flist
, childp
-> name
) )
821 && onlist( elist
, childp
-> name
) ) {
822 childp
-> printflag
= FALSE
;
825 if ( childp
-> propfraction
== 0.0 ) {
827 * no parents to pass time to.
828 * collect time from children if
830 * or there isn't any -F list and its not on -E list.
832 if ( onlist( Flist
, childp
-> name
)
833 || ( !Fflag
&& !onlist( Elist
, childp
-> name
) ) ) {
834 childp
-> propfraction
= 1.0;
838 * it has parents to pass time to,
839 * but maybe someone wants to shut it up
840 * by puttting it on -E list. (but favor -F over -E)
842 if ( !onlist( Flist
, childp
-> name
)
843 && onlist( Elist
, childp
-> name
) ) {
844 childp
-> propfraction
= 0.0;
847 childp
-> propself
= childp
-> time
* childp
-> propfraction
;
848 printtime
+= childp
-> propself
;
850 if ( debug
& PROPDEBUG
) {
851 printf( "[doflags] " );
853 printf( " ends up with printflag %d and propfraction %f\n" ,
854 childp
-> printflag
, childp
-> propfraction
);
855 printf( "time %f propself %f printtime %f\n" ,
856 childp
-> time
, childp
-> propself
, printtime
);
863 * check if any parent of this child
864 * (or outside parents of this cycle)
865 * have their print flags on and set the
866 * print flag of the child (cycle) appropriately.
867 * similarly, deal with propagation fractions from parents.
869 inheritflags(nltype
*childp
)
876 headp
= childp
-> cyclehead
;
877 if ( childp
== headp
) {
879 * just a regular child, check its parents
881 childp
-> printflag
= FALSE
;
882 childp
-> propfraction
= 0.0;
883 for (arcp
= childp
-> parents
; arcp
; arcp
= arcp
-> arc_parentlist
) {
884 parentp
= arcp
-> arc_parentp
;
885 if ( childp
== parentp
) {
888 childp
-> printflag
|= parentp
-> printflag
;
890 * if the child was never actually called
891 * (e.g. this arc is static (and all others are, too))
892 * no time propagates along this arc.
894 if ( arcp
-> arc_flags
& DEADARC
) {
897 if ( childp
-> npropcall
) {
898 childp
-> propfraction
+= parentp
-> propfraction
899 * ( ( (double) arcp
-> arc_count
)
900 / ( (double) childp
-> npropcall
) );
905 * its a member of a cycle, look at all parents from
908 headp
-> printflag
= FALSE
;
909 headp
-> propfraction
= 0.0;
910 for ( memp
= headp
-> cnext
; memp
; memp
= memp
-> cnext
) {
911 for (arcp
= memp
->parents
; arcp
; arcp
= arcp
->arc_parentlist
) {
912 if ( arcp
-> arc_parentp
-> cyclehead
== headp
) {
915 parentp
= arcp
-> arc_parentp
;
916 headp
-> printflag
|= parentp
-> printflag
;
918 * if the cycle was never actually called
919 * (e.g. this arc is static (and all others are, too))
920 * no time propagates along this arc.
922 if ( arcp
-> arc_flags
& DEADARC
) {
925 if ( headp
-> npropcall
) {
926 headp
-> propfraction
+= parentp
-> propfraction
927 * ( ( (double) arcp
-> arc_count
)
928 / ( (double) headp
-> npropcall
) );
932 for ( memp
= headp
; memp
; memp
= memp
-> cnext
) {
933 memp
-> printflag
= headp
-> printflag
;
934 memp
-> propfraction
= headp
-> propfraction
;