1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29: #include "libiberty.h"
30: #include "gprof.h"
31: #include "search_list.h"
32: #include "source.h"
33: #include "symtab.h"
34: #include "call_graph.h"
35: #include "cg_arcs.h"
36: #include "cg_dfn.h"
37: #include "cg_print.h"
38: #include "utils.h"
39: #include "sym_ids.h"
40:
41: static int cmp_topo (const PTR, const PTR);
42: static void propagate_time (Sym *);
43: static void cycle_time (void);
44: static void cycle_link (void);
45: static void inherit_flags (Sym *);
46: static void propagate_flags (Sym **);
47: static int cmp_total (const PTR, const PTR);
48:
49: Sym *cycle_header;
50: unsigned int num_cycles;
51: Arc **arcs;
52: unsigned int numarcs;
53:
54:
55:
56:
57:
58: Arc *
59: arc_lookup (Sym *parent, Sym *child)
60: {
61: Arc *arc;
62:
63: if (!parent || !child)
64: {
65: printf ("[arc_lookup] parent == 0 || child == 0\n");
66: return 0;
67: }
68: DBG (LOOKUPDEBUG, printf ("[arc_lookup] parent %s child %s\n",
69: parent->name, child->name));
70: for (arc = parent->cg.children; arc; arc = arc->next_child)
71: {
72: DBG (LOOKUPDEBUG, printf ("[arc_lookup]\t parent %s child %s\n",
73: arc->parent->name, arc->child->name));
74: if (child->addr >= arc->child->addr
75: && child->end_addr <= arc->child->end_addr)
76: {
77: return arc;
78: }
79: }
80: return 0;
81: }
82:
83:
84:
85:
86:
87: void
88: arc_add (Sym *parent, Sym *child, unsigned long count)
89: {
90: static unsigned int maxarcs = 0;
91: Arc *arc, **newarcs;
92:
93: DBG (TALLYDEBUG, printf ("[arc_add] %lu arcs from %s to %s\n",
94: count, parent->name, child->name));
95: arc = arc_lookup (parent, child);
96: if (arc)
97: {
98:
99:
100:
101: DBG (TALLYDEBUG, printf ("[tally] hit %lu += %lu\n",
102: arc->count, count));
103: arc->count += count;
104: return;
105: }
106: arc = (Arc *) xmalloc (sizeof (*arc));
107: memset (arc, 0, sizeof (*arc));
108: arc->parent = parent;
109: arc->child = child;
110: arc->count = count;
111:
112:
113:
114: if (parent != child)
115: {
116:
117:
118:
119: if (numarcs == maxarcs)
120: {
121:
122: if (maxarcs == 0)
123: maxarcs = 1;
124: maxarcs *= 2;
125:
126:
127: newarcs = (Arc **)xmalloc(sizeof (Arc *) * maxarcs);
128:
129:
130: memcpy (newarcs, arcs, numarcs * sizeof (Arc *));
131:
132:
133: free (arcs);
134:
135:
136: arcs = newarcs;
137: }
138:
139:
140: arcs[numarcs++] = arc;
141: }
142:
143:
144: arc->next_child = parent->cg.children;
145: parent->cg.children = arc;
146:
147:
148: arc->next_parent = child->cg.parents;
149: child->cg.parents = arc;
150: }
151:
152:
153: static int
154: cmp_topo (const PTR lp, const PTR rp)
155: {
156: const Sym *left = *(const Sym **) lp;
157: const Sym *right = *(const Sym **) rp;
158:
159: return left->cg.top_order - right->cg.top_order;
160: }
161:
162:
163: static void
164: propagate_time (Sym *parent)
165: {
166: Arc *arc;
167: Sym *child;
168: double share, prop_share;
169:
170: if (parent->cg.prop.fract == 0.0)
171: {
172: return;
173: }
174:
175:
176:
177: for (arc = parent->cg.children; arc; arc = arc->next_child)
178: {
179: child = arc->child;
180: if (arc->count == 0 || child == parent || child->cg.prop.fract == 0)
181: {
182: continue;
183: }
184: if (child->cg.cyc.head != child)
185: {
186: if (parent->cg.cyc.num == child->cg.cyc.num)
187: {
188: continue;
189: }
190: if (parent->cg.top_order <= child->cg.top_order)
191: {
192: fprintf (stderr, "[propagate] toporder botches\n");
193: }
194: child = child->cg.cyc.head;
195: }
196: else
197: {
198: if (parent->cg.top_order <= child->cg.top_order)
199: {
200: fprintf (stderr, "[propagate] toporder botches\n");
201: continue;
202: }
203: }
204: if (child->ncalls == 0)
205: {
206: continue;
207: }
208:
209:
210: arc->time = child->hist.time * (((double) arc->count)
211: / ((double) child->ncalls));
212: arc->child_time = child->cg.child_time
213: * (((double) arc->count) / ((double) child->ncalls));
214: share = arc->time + arc->child_time;
215: parent->cg.child_time += share;
216:
217:
218: prop_share = parent->cg.prop.fract * share;
219:
220:
221: parent->cg.prop.child += prop_share;
222: arc->time *= parent->cg.prop.fract;
223: arc->child_time *= parent->cg.prop.fract;
224:
225:
226: if (parent->cg.cyc.head != parent)
227: {
228: parent->cg.cyc.head->cg.child_time += share;
229: parent->cg.cyc.head->cg.prop.child += prop_share;
230: }
231: DBG (PROPDEBUG,
232: printf ("[prop_time] child \t");
233: print_name (child);
234: printf (" with %f %f %lu/%lu\n", child->hist.time,
235: child->cg.child_time, arc->count, child->ncalls);
236: printf ("[prop_time] parent\t");
237: print_name (parent);
238: printf ("\n[prop_time] share %f\n", share));
239: }
240: }
241:
242:
243:
244:
245:
246:
247: static void
248: cycle_time ()
249: {
250: Sym *member, *cyc;
251:
252: for (cyc = &cycle_header[1]; cyc <= &cycle_header[num_cycles]; ++cyc)
253: {
254: for (member = cyc->cg.cyc.next; member; member = member->cg.cyc.next)
255: {
256: if (member->cg.prop.fract == 0.0)
257: {
258:
259:
260:
261:
262: continue;
263: }
264: cyc->hist.time += member->hist.time;
265: }
266: cyc->cg.prop.self = cyc->cg.prop.fract * cyc->hist.time;
267: }
268: }
269:
270:
271: static void
272: cycle_link ()
273: {
274: Sym *sym, *cyc, *member;
275: Arc *arc;
276: int num;
277:
278:
279:
280: num_cycles = 0;
281: for (sym = symtab.base; sym < symtab.limit; ++sym)
282: {
283:
284: if (sym->cg.cyc.head == sym && sym->cg.cyc.next)
285: {
286: ++num_cycles;
287: }
288: }
289:
290:
291:
292:
293:
294: cycle_header = (Sym *) xmalloc ((num_cycles + 1) * sizeof (Sym));
295:
296:
297:
298:
299:
300: num = 0;
301: cyc = cycle_header;
302: for (sym = symtab.base; sym < symtab.limit; ++sym)
303: {
304: if (!(sym->cg.cyc.head == sym && sym->cg.cyc.next != 0))
305: {
306: continue;
307: }
308: ++num;
309: ++cyc;
310: sym_init (cyc);
311: cyc->cg.print_flag = TRUE;
312: cyc->cg.top_order = DFN_NAN;
313: cyc->cg.cyc.num = num;
314: cyc->cg.cyc.head = cyc;
315: cyc->cg.cyc.next = sym;
316: DBG (CYCLEDEBUG, printf ("[cycle_link] ");
317: print_name (sym);
318: printf (" is the head of cycle %d\n", num));
319:
320:
321: for (member = sym; member; member = member->cg.cyc.next)
322: {
323: member->cg.cyc.num = num;
324: member->cg.cyc.head = cyc;
325: }
326:
327:
328:
329:
330:
331: for (member = sym; member; member = member->cg.cyc.next)
332: {
333: for (arc = member->cg.parents; arc; arc = arc->next_parent)
334: {
335: if (arc->parent == member)
336: {
337: continue;
338: }
339: if (arc->parent->cg.cyc.num == num)
340: {
341: cyc->cg.self_calls += arc->count;
342: }
343: else
344: {
345: cyc->ncalls += arc->count;
346: }
347: }
348: }
349: }
350: }
351:
352:
353:
354:
355:
356:
357:
358:
359: static void
360: inherit_flags (Sym *child)
361: {
362: Sym *head, *parent, *member;
363: Arc *arc;
364:
365: head = child->cg.cyc.head;
366: if (child == head)
367: {
368:
369: child->cg.print_flag = FALSE;
370: child->cg.prop.fract = 0.0;
371: for (arc = child->cg.parents; arc; arc = arc->next_parent)
372: {
373: parent = arc->parent;
374: if (child == parent)
375: {
376: continue;
377: }
378: child->cg.print_flag |= parent->cg.print_flag;
379:
380:
381:
382:
383:
384: if (child->ncalls != 0)
385: {
386: child->cg.prop.fract += parent->cg.prop.fract
387: * (((double) arc->count) / ((double) child->ncalls));
388: }
389: }
390: }
391: else
392: {
393:
394:
395:
396:
397: head->cg.print_flag = FALSE;
398: head->cg.prop.fract = 0.0;
399: for (member = head->cg.cyc.next; member; member = member->cg.cyc.next)
400: {
401: for (arc = member->cg.parents; arc; arc = arc->next_parent)
402: {
403: if (arc->parent->cg.cyc.head == head)
404: {
405: continue;
406: }
407: parent = arc->parent;
408: head->cg.print_flag |= parent->cg.print_flag;
409:
410:
411:
412:
413:
414: if (head->ncalls != 0)
415: {
416: head->cg.prop.fract += parent->cg.prop.fract
417: * (((double) arc->count) / ((double) head->ncalls));
418: }
419: }
420: }
421: for (member = head; member; member = member->cg.cyc.next)
422: {
423: member->cg.print_flag = head->cg.print_flag;
424: member->cg.prop.fract = head->cg.prop.fract;
425: }
426: }
427: }
428:
429:
430:
431:
432:
433:
434:
435:
436:
437: static void
438: propagate_flags (Sym **symbols)
439: {
440: int index;
441: Sym *old_head, *child;
442:
443: old_head = 0;
444: for (index = symtab.len - 1; index >= 0; --index)
445: {
446: child = symbols[index];
447:
448:
449:
450:
451:
452:
453: if (child->cg.cyc.head != old_head)
454: {
455: old_head = child->cg.cyc.head;
456: inherit_flags (child);
457: }
458: DBG (PROPDEBUG,
459: printf ("[prop_flags] ");
460: print_name (child);
461: printf ("inherits print-flag %d and prop-fract %f\n",
462: child->cg.print_flag, child->cg.prop.fract));
463: if (!child->cg.print_flag)
464: {
465:
466:
467:
468:
469:
470: if (sym_lookup (&syms[INCL_GRAPH], child->addr)
471: || (syms[INCL_GRAPH].len == 0
472: && !sym_lookup (&syms[EXCL_GRAPH], child->addr)))
473: {
474: child->cg.print_flag = TRUE;
475: }
476: }
477: else
478: {
479:
480:
481:
482:
483:
484: if (!sym_lookup (&syms[INCL_GRAPH], child->addr)
485: && sym_lookup (&syms[EXCL_GRAPH], child->addr))
486: {
487: child->cg.print_flag = FALSE;
488: }
489: }
490: if (child->cg.prop.fract == 0.0)
491: {
492:
493:
494:
495:
496:
497: if (sym_lookup (&syms[INCL_TIME], child->addr)
498: || (syms[INCL_TIME].len == 0
499: && !sym_lookup (&syms[EXCL_TIME], child->addr)))
500: {
501: child->cg.prop.fract = 1.0;
502: }
503: }
504: else
505: {
506:
507:
508:
509:
510:
511:
512: if (!sym_lookup (&syms[INCL_TIME], child->addr)
513: && sym_lookup (&syms[EXCL_TIME], child->addr))
514: {
515: child->cg.prop.fract = 0.0;
516: }
517: }
518: child->cg.prop.self = child->hist.time * child->cg.prop.fract;
519: print_time += child->cg.prop.self;
520: DBG (PROPDEBUG,
521: printf ("[prop_flags] ");
522: print_name (child);
523: printf (" ends up with printflag %d and prop-fract %f\n",
524: child->cg.print_flag, child->cg.prop.fract);
525: printf ("[prop_flags] time %f propself %f print_time %f\n",
526: child->hist.time, child->cg.prop.self, print_time));
527: }
528: }
529:
530:
531:
532:
533:
534:
535:
536:
537: static int
538: cmp_total (const PTR lp, const PTR rp)
539: {
540: const Sym *left = *(const Sym **) lp;
541: const Sym *right = *(const Sym **) rp;
542: double diff;
543:
544: diff = (left->cg.prop.self + left->cg.prop.child)
545: - (right->cg.prop.self + right->cg.prop.child);
546: if (diff < 0.0)
547: {
548: return 1;
549: }
550: if (diff > 0.0)
551: {
552: return -1;
553: }
554: if (!left->name && left->cg.cyc.num != 0)
555: {
556: return -1;
557: }
558: if (!right->name && right->cg.cyc.num != 0)
559: {
560: return 1;
561: }
562: if (!left->name)
563: {
564: return -1;
565: }
566: if (!right->name)
567: {
568: return 1;
569: }
570: if (left->name[0] != '_' && right->name[0] == '_')
571: {
572: return -1;
573: }
574: if