]>
Commit | Line | Data |
---|---|---|
5489fcc3 KR |
1 | #include "libiberty.h" |
2 | #include "cg_arcs.h" | |
3 | #include "cg_print.h" | |
4 | #include "hist.h" | |
5 | #include "utils.h" | |
6 | ||
7 | /* | |
8 | * Return value of comparison functions used to sort tables: | |
9 | */ | |
10 | #define LESSTHAN -1 | |
11 | #define EQUALTO 0 | |
12 | #define GREATERTHAN 1 | |
13 | ||
14 | /* declarations of automatically generated functions to output blurbs: */ | |
12516a37 KR |
15 | extern void bsd_callg_blurb PARAMS ((FILE * fp)); |
16 | extern void fsf_callg_blurb PARAMS ((FILE * fp)); | |
5489fcc3 KR |
17 | |
18 | double print_time = 0.0; | |
19 | ||
20 | ||
21 | static void | |
12516a37 | 22 | DEFUN_VOID (print_header) |
5489fcc3 | 23 | { |
12516a37 KR |
24 | if (first_output) |
25 | { | |
26 | first_output = FALSE; | |
27 | } | |
28 | else | |
29 | { | |
30 | printf ("\f\n"); | |
03c35bcb | 31 | } |
12516a37 KR |
32 | if (!bsd_style_output) |
33 | { | |
34 | if (print_descriptions) | |
35 | { | |
36 | printf ("\t\t Call graph (explanation follows)\n\n"); | |
37 | } | |
38 | else | |
39 | { | |
40 | printf ("\t\t\tCall graph\n\n"); | |
03c35bcb KR |
41 | } |
42 | } | |
12516a37 KR |
43 | printf ("\ngranularity: each sample hit covers %ld byte(s)", |
44 | (long) hist_scale * sizeof (UNIT)); | |
45 | if (print_time > 0.0) | |
46 | { | |
47 | printf (" for %.2f%% of %.2f seconds\n\n", | |
48 | 100.0 / print_time, print_time / hz); | |
49 | } | |
50 | else | |
51 | { | |
52 | printf (" no time propagated\n\n"); | |
53 | /* | |
54 | * This doesn't hurt, since all the numerators will be 0.0: | |
55 | */ | |
56 | print_time = 1.0; | |
03c35bcb | 57 | } |
12516a37 KR |
58 | if (bsd_style_output) |
59 | { | |
60 | printf ("%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s %-8.8s\n", | |
61 | "", "", "", "", "called", "total", "parents"); | |
62 | printf ("%-6.6s %5.5s %7.7s %11.11s %7.7s+%-7.7s %-8.8s\t%5.5s\n", | |
63 | "index", "%time", "self", "descendents", | |
64 | "called", "self", "name", "index"); | |
65 | printf ("%6.6s %5.5s %7.7s %11.11s %7.7s/%-7.7s %-8.8s\n", | |
66 | "", "", "", "", "called", "total", "children"); | |
67 | printf ("\n"); | |
68 | } | |
69 | else | |
70 | { | |
71 | printf ("index %% time self children called name\n"); | |
03c35bcb KR |
72 | } |
73 | } | |
5489fcc3 KR |
74 | |
75 | ||
76 | /* | |
77 | * Print a cycle header. | |
78 | */ | |
79 | static void | |
12516a37 | 80 | DEFUN (print_cycle, (cyc), Sym * cyc) |
5489fcc3 | 81 | { |
12516a37 | 82 | char buf[BUFSIZ]; |
5489fcc3 | 83 | |
12516a37 | 84 | sprintf (buf, "[%d]", cyc->cg.index); |
869b94c5 KR |
85 | printf (bsd_style_output |
86 | ? "%-6.6s %5.1f %7.2f %11.2f %7d" | |
87 | : "%-6.6s %5.1f %7.2f %7.2f %7d", buf, | |
12516a37 KR |
88 | 100 * (cyc->cg.prop.self + cyc->cg.prop.child) / print_time, |
89 | cyc->cg.prop.self / hz, cyc->cg.prop.child / hz, cyc->ncalls); | |
90 | if (cyc->cg.self_calls != 0) | |
91 | { | |
92 | printf ("+%-7d", cyc->cg.self_calls); | |
93 | } | |
94 | else | |
95 | { | |
96 | printf (" %7.7s", ""); | |
03c35bcb | 97 | } |
869b94c5 | 98 | printf (" <cycle %d as a whole> [%d]\n", cyc->cg.cyc.num, cyc->cg.index); |
03c35bcb | 99 | } |
5489fcc3 KR |
100 | |
101 | ||
102 | /* | |
103 | * Compare LEFT and RIGHT membmer. Major comparison key is | |
104 | * CG.PROP.SELF+CG.PROP.CHILD, secondary key is NCALLS+CG.SELF_CALLS. | |
105 | */ | |
106 | static int | |
12516a37 | 107 | DEFUN (cmp_member, (left, right), Sym * left AND Sym * right) |
5489fcc3 | 108 | { |
12516a37 KR |
109 | double left_time = left->cg.prop.self + left->cg.prop.child; |
110 | double right_time = right->cg.prop.self + right->cg.prop.child; | |
111 | long left_calls = left->ncalls + left->cg.self_calls; | |
112 | long right_calls = right->ncalls + right->cg.self_calls; | |
113 | ||
114 | if (left_time > right_time) | |
115 | { | |
116 | return GREATERTHAN; | |
03c35bcb | 117 | } |
12516a37 KR |
118 | if (left_time < right_time) |
119 | { | |
120 | return LESSTHAN; | |
03c35bcb | 121 | } |
12516a37 KR |
122 | |
123 | if (left_calls > right_calls) | |
124 | { | |
125 | return GREATERTHAN; | |
03c35bcb | 126 | } |
12516a37 KR |
127 | if (left_calls < right_calls) |
128 | { | |
129 | return LESSTHAN; | |
03c35bcb | 130 | } |
12516a37 | 131 | return EQUALTO; |
03c35bcb | 132 | } |
5489fcc3 KR |
133 | |
134 | ||
135 | /* | |
136 | * Sort members of a cycle. | |
137 | */ | |
138 | static void | |
12516a37 | 139 | DEFUN (sort_members, (cyc), Sym * cyc) |
5489fcc3 | 140 | { |
12516a37 KR |
141 | Sym *todo, *doing, *prev; |
142 | /* | |
143 | * Detach cycle members from cyclehead, and insertion sort them | |
144 | * back on. | |
145 | */ | |
146 | todo = cyc->cg.cyc.next; | |
147 | cyc->cg.cyc.next = 0; | |
148 | for (doing = todo; doing && doing->cg.cyc.next; doing = todo) | |
149 | { | |
150 | todo = doing->cg.cyc.next; | |
151 | for (prev = cyc; prev->cg.cyc.next; prev = prev->cg.cyc.next) | |
152 | { | |
153 | if (cmp_member (doing, prev->cg.cyc.next) == GREATERTHAN) | |
154 | { | |
155 | break; | |
03c35bcb KR |
156 | } |
157 | } | |
12516a37 KR |
158 | doing->cg.cyc.next = prev->cg.cyc.next; |
159 | prev->cg.cyc.next = doing; | |
03c35bcb KR |
160 | } |
161 | } | |
5489fcc3 KR |
162 | |
163 | ||
164 | /* | |
165 | * Print the members of a cycle. | |
166 | */ | |
167 | static void | |
12516a37 | 168 | DEFUN (print_members, (cyc), Sym * cyc) |
5489fcc3 | 169 | { |
12516a37 KR |
170 | Sym *member; |
171 | ||
172 | sort_members (cyc); | |
173 | for (member = cyc->cg.cyc.next; member; member = member->cg.cyc.next) | |
174 | { | |
869b94c5 KR |
175 | printf (bsd_style_output |
176 | ? "%6.6s %5.5s %7.2f %11.2f %7d" | |
177 | : "%6.6s %5.5s %7.2f %7.2f %7d", | |
12516a37 KR |
178 | "", "", member->cg.prop.self / hz, member->cg.prop.child / hz, |
179 | member->ncalls); | |
180 | if (member->cg.self_calls != 0) | |
181 | { | |
182 | printf ("+%-7d", member->cg.self_calls); | |
183 | } | |
184 | else | |
185 | { | |
186 | printf (" %7.7s", ""); | |
03c35bcb | 187 | } |
12516a37 KR |
188 | printf (" "); |
189 | print_name (member); | |
190 | printf ("\n"); | |
03c35bcb KR |
191 | } |
192 | } | |
5489fcc3 KR |
193 | |
194 | ||
195 | /* | |
196 | * Compare two arcs to/from the same child/parent. | |
12516a37 KR |
197 | * - if one arc is a self arc, it's least. |
198 | * - if one arc is within a cycle, it's less than. | |
199 | * - if both arcs are within a cycle, compare arc counts. | |
200 | * - if neither arc is within a cycle, compare with | |
201 | * time + child_time as major key | |
202 | * arc count as minor key | |
5489fcc3 KR |
203 | */ |
204 | static int | |
12516a37 | 205 | DEFUN (cmp_arc, (left, right), Arc * left AND Arc * right) |
5489fcc3 | 206 | { |
12516a37 KR |
207 | Sym *left_parent = left->parent; |
208 | Sym *left_child = left->child; | |
209 | Sym *right_parent = right->parent; | |
210 | Sym *right_child = right->child; | |
211 | double left_time, right_time; | |
212 | ||
213 | DBG (TIMEDEBUG, | |
214 | printf ("[cmp_arc] "); | |
215 | print_name (left_parent); | |
216 | printf (" calls "); | |
217 | print_name (left_child); | |
218 | printf (" %f + %f %d/%d\n", left->time, left->child_time, | |
5489fcc3 | 219 | left->count, left_child->ncalls); |
12516a37 KR |
220 | printf ("[cmp_arc] "); |
221 | print_name (right_parent); | |
222 | printf (" calls "); | |
223 | print_name (right_child); | |
224 | printf (" %f + %f %d/%d\n", right->time, right->child_time, | |
5489fcc3 | 225 | right->count, right_child->ncalls); |
12516a37 KR |
226 | printf ("\n"); |
227 | ); | |
228 | if (left_parent == left_child) | |
229 | { | |
230 | return LESSTHAN; /* left is a self call */ | |
03c35bcb | 231 | } |
12516a37 KR |
232 | if (right_parent == right_child) |
233 | { | |
234 | return GREATERTHAN; /* right is a self call */ | |
03c35bcb | 235 | } |
12516a37 KR |
236 | |
237 | if (left_parent->cg.cyc.num != 0 && left_child->cg.cyc.num != 0 | |
238 | && left_parent->cg.cyc.num == left_child->cg.cyc.num) | |
239 | { | |
240 | /* left is a call within a cycle */ | |
241 | if (right_parent->cg.cyc.num != 0 && right_child->cg.cyc.num != 0 | |
242 | && right_parent->cg.cyc.num == right_child->cg.cyc.num) | |
243 | { | |
244 | /* right is a call within the cycle, too */ | |
245 | if (left->count < right->count) | |
246 | { | |
247 | return LESSTHAN; | |
03c35bcb | 248 | } |
12516a37 KR |
249 | if (left->count > right->count) |
250 | { | |
251 | return GREATERTHAN; | |
03c35bcb | 252 | } |
12516a37 KR |
253 | return EQUALTO; |
254 | } | |
255 | else | |
5489fcc3 | 256 | { |
12516a37 KR |
257 | /* right isn't a call within the cycle */ |
258 | return LESSTHAN; | |
03c35bcb | 259 | } |
12516a37 KR |
260 | } |
261 | else | |
262 | { | |
263 | /* left isn't a call within a cycle */ | |
264 | if (right_parent->cg.cyc.num != 0 && right_child->cg.cyc.num != 0 | |
265 | && right_parent->cg.cyc.num == right_child->cg.cyc.num) | |
5489fcc3 | 266 | { |
12516a37 KR |
267 | /* right is a call within a cycle */ |
268 | return GREATERTHAN; | |
269 | } | |
270 | else | |
271 | { | |
272 | /* neither is a call within a cycle */ | |
273 | left_time = left->time + left->child_time; | |
274 | right_time = right->time + right->child_time; | |
275 | if (left_time < right_time) | |
276 | { | |
277 | return LESSTHAN; | |
03c35bcb | 278 | } |
12516a37 KR |
279 | if (left_time > right_time) |
280 | { | |
281 | return GREATERTHAN; | |
03c35bcb | 282 | } |
12516a37 KR |
283 | if (left->count < right->count) |
284 | { | |
285 | return LESSTHAN; | |
03c35bcb | 286 | } |
12516a37 KR |
287 | if (left->count > right->count) |
288 | { | |
289 | return GREATERTHAN; | |
03c35bcb | 290 | } |
12516a37 | 291 | return EQUALTO; |
03c35bcb KR |
292 | } |
293 | } | |
294 | } | |
5489fcc3 KR |
295 | |
296 | ||
297 | static void | |
12516a37 | 298 | DEFUN (sort_parents, (child), Sym * child) |
5489fcc3 | 299 | { |
12516a37 KR |
300 | Arc *arc, *detached, sorted, *prev; |
301 | ||
302 | /* | |
303 | * Unlink parents from child, then insertion sort back on to | |
304 | * sorted's parents. | |
305 | * *arc the arc you have detached and are inserting. | |
306 | * *detached the rest of the arcs to be sorted. | |
307 | * sorted arc list onto which you insertion sort. | |
308 | * *prev arc before the arc you are comparing. | |
309 | */ | |
310 | sorted.next_parent = 0; | |
311 | for (arc = child->cg.parents; arc; arc = detached) | |
312 | { | |
313 | detached = arc->next_parent; | |
314 | ||
315 | /* consider *arc as disconnected; insert it into sorted: */ | |
316 | for (prev = &sorted; prev->next_parent; prev = prev->next_parent) | |
317 | { | |
318 | if (cmp_arc (arc, prev->next_parent) != GREATERTHAN) | |
319 | { | |
320 | break; | |
03c35bcb KR |
321 | } |
322 | } | |
12516a37 KR |
323 | arc->next_parent = prev->next_parent; |
324 | prev->next_parent = arc; | |
03c35bcb | 325 | } |
12516a37 KR |
326 | |
327 | /* reattach sorted arcs to child: */ | |
328 | child->cg.parents = sorted.next_parent; | |
03c35bcb | 329 | } |
5489fcc3 KR |
330 | |
331 | ||
332 | static void | |
12516a37 | 333 | DEFUN (print_parents, (child), Sym * child) |
5489fcc3 | 334 | { |
12516a37 KR |
335 | Sym *parent; |
336 | Arc *arc; | |
337 | Sym *cycle_head; | |
338 | ||
339 | if (child->cg.cyc.head != 0) | |
340 | { | |
341 | cycle_head = child->cg.cyc.head; | |
342 | } | |
343 | else | |
344 | { | |
345 | cycle_head = child; | |
03c35bcb | 346 | } |
12516a37 KR |
347 | if (!child->cg.parents) |
348 | { | |
349 | printf (bsd_style_output | |
350 | ? "%6.6s %5.5s %7.7s %11.11s %7.7s %7.7s <spontaneous>\n" | |
351 | : "%6.6s %5.5s %7.7s %7.7s %7.7s %7.7s <spontaneous>\n", | |
352 | "", "", "", "", "", ""); | |
353 | return; | |
03c35bcb | 354 | } |
12516a37 KR |
355 | sort_parents (child); |
356 | for (arc = child->cg.parents; arc; arc = arc->next_parent) | |
357 | { | |
358 | parent = arc->parent; | |
359 | if (child == parent || (child->cg.cyc.num != 0 | |
360 | && parent->cg.cyc.num == child->cg.cyc.num)) | |
5489fcc3 | 361 | { |
12516a37 KR |
362 | /* selfcall or call among siblings: */ |
363 | printf (bsd_style_output | |
364 | ? "%6.6s %5.5s %7.7s %11.11s %7d %7.7s " | |
365 | : "%6.6s %5.5s %7.7s %7.7s %7d %7.7s ", | |
366 | "", "", "", "", | |
367 | arc->count, ""); | |
368 | print_name (parent); | |
369 | printf ("\n"); | |
370 | } | |
371 | else | |
372 | { | |
373 | /* regular parent of child: */ | |
374 | printf (bsd_style_output | |
375 | ? "%6.6s %5.5s %7.2f %11.2f %7d/%-7d " | |
376 | : "%6.6s %5.5s %7.2f %7.2f %7d/%-7d ", | |
377 | "", "", | |
378 | arc->time / hz, arc->child_time / hz, | |
379 | arc->count, cycle_head->ncalls); | |
380 | print_name (parent); | |
381 | printf ("\n"); | |
03c35bcb KR |
382 | } |
383 | } | |
384 | } | |
5489fcc3 KR |
385 | |
386 | ||
387 | static void | |
12516a37 | 388 | DEFUN (sort_children, (parent), Sym * parent) |
5489fcc3 | 389 | { |
12516a37 KR |
390 | Arc *arc, *detached, sorted, *prev; |
391 | /* | |
392 | * Unlink children from parent, then insertion sort back on to | |
393 | * sorted's children. | |
394 | * *arc the arc you have detached and are inserting. | |
395 | * *detached the rest of the arcs to be sorted. | |
396 | * sorted arc list onto which you insertion sort. | |
397 | * *prev arc before the arc you are comparing. | |
398 | */ | |
399 | sorted.next_child = 0; | |
400 | for (arc = parent->cg.children; arc; arc = detached) | |
401 | { | |
402 | detached = arc->next_child; | |
403 | ||
404 | /* consider *arc as disconnected; insert it into sorted: */ | |
405 | for (prev = &sorted; prev->next_child; prev = prev->next_child) | |
406 | { | |
407 | if (cmp_arc (arc, prev->next_child) != LESSTHAN) | |
408 | { | |
409 | break; | |
03c35bcb KR |
410 | } |
411 | } | |
12516a37 KR |
412 | arc->next_child = prev->next_child; |
413 | prev->next_child = arc; | |
03c35bcb | 414 | } |
12516a37 KR |
415 | |
416 | /* reattach sorted children to parent: */ | |
417 | parent->cg.children = sorted.next_child; | |
03c35bcb | 418 | } |
5489fcc3 KR |
419 | |
420 | ||
421 | static void | |
12516a37 | 422 | DEFUN (print_children, (parent), Sym * parent) |
5489fcc3 | 423 | { |
12516a37 KR |
424 | Sym *child; |
425 | Arc *arc; | |
426 | ||
427 | sort_children (parent); | |
428 | arc = parent->cg.children; | |
429 | for (arc = parent->cg.children; arc; arc = arc->next_child) | |
430 | { | |
431 | child = arc->child; | |
432 | if (child == parent || (child->cg.cyc.num != 0 | |
433 | && child->cg.cyc.num == parent->cg.cyc.num)) | |
434 | { | |
435 | /* self call or call to sibling: */ | |
436 | printf (bsd_style_output | |
437 | ? "%6.6s %5.5s %7.7s %11.11s %7d %7.7s " | |
438 | : "%6.6s %5.5s %7.7s %7.7s %7d %7.7s ", | |
439 | "", "", "", "", arc->count, ""); | |
440 | print_name (child); | |
441 | printf ("\n"); | |
442 | } | |
443 | else | |
5489fcc3 | 444 | { |
12516a37 KR |
445 | /* regular child of parent: */ |
446 | printf (bsd_style_output | |
447 | ? "%6.6s %5.5s %7.2f %11.2f %7d/%-7d " | |
448 | : "%6.6s %5.5s %7.2f %7.2f %7d/%-7d ", | |
449 | "", "", | |
450 | arc->time / hz, arc->child_time / hz, | |
451 | arc->count, child->cg.cyc.head->ncalls); | |
452 | print_name (child); | |
453 | printf ("\n"); | |
03c35bcb KR |
454 | } |
455 | } | |
456 | } | |
5489fcc3 KR |
457 | |
458 | ||
459 | static void | |
12516a37 | 460 | DEFUN (print_line, (np), Sym * np) |
5489fcc3 | 461 | { |
12516a37 KR |
462 | char buf[BUFSIZ]; |
463 | ||
464 | sprintf (buf, "[%d]", np->cg.index); | |
465 | printf (bsd_style_output | |
466 | ? "%-6.6s %5.1f %7.2f %11.2f" | |
467 | : "%-6.6s %5.1f %7.2f %7.2f", buf, | |
468 | 100 * (np->cg.prop.self + np->cg.prop.child) / print_time, | |
469 | np->cg.prop.self / hz, np->cg.prop.child / hz); | |
470 | if ((np->ncalls + np->cg.self_calls) != 0) | |
471 | { | |
472 | printf (" %7d", np->ncalls); | |
473 | if (np->cg.self_calls != 0) | |
474 | { | |
475 | printf ("+%-7d ", np->cg.self_calls); | |
476 | } | |
477 | else | |
478 | { | |
479 | printf (" %7.7s ", ""); | |
03c35bcb | 480 | } |
12516a37 KR |
481 | } |
482 | else | |
483 | { | |
484 | printf (" %7.7s %7.7s ", "", ""); | |
03c35bcb | 485 | } |
12516a37 KR |
486 | print_name (np); |
487 | printf ("\n"); | |
03c35bcb | 488 | } |
5489fcc3 KR |
489 | |
490 | ||
491 | /* | |
492 | * Print dynamic call graph. | |
493 | */ | |
494 | void | |
12516a37 | 495 | DEFUN (cg_print, (timesortsym), Sym ** timesortsym) |
5489fcc3 | 496 | { |
12516a37 KR |
497 | int index; |
498 | Sym *parent; | |
5489fcc3 | 499 | |
12516a37 KR |
500 | if (print_descriptions && bsd_style_output) |
501 | { | |
502 | bsd_callg_blurb (stdout); | |
03c35bcb | 503 | } |
5489fcc3 | 504 | |
12516a37 | 505 | print_header (); |
5489fcc3 | 506 | |
12516a37 KR |
507 | for (index = 0; index < symtab.len + num_cycles; ++index) |
508 | { | |
509 | parent = timesortsym[index]; | |
510 | if ((ignore_zeros && parent->ncalls == 0 | |
511 | && parent->cg.self_calls == 0 && parent->cg.prop.self == 0 | |
512 | && parent->cg.prop.child == 0) | |
513 | || !parent->cg.print_flag) | |
514 | { | |
515 | continue; | |
03c35bcb | 516 | } |
12516a37 | 517 | if (!parent->name && parent->cg.cyc.num != 0) |
5489fcc3 | 518 | { |
12516a37 KR |
519 | /* cycle header: */ |
520 | print_cycle (parent); | |
521 | print_members (parent); | |
522 | } | |
523 | else | |
524 | { | |
525 | print_parents (parent); | |
526 | print_line (parent); | |
527 | print_children (parent); | |
03c35bcb | 528 | } |
12516a37 KR |
529 | if (bsd_style_output) |
530 | printf ("\n"); | |
531 | printf ("-----------------------------------------------\n"); | |
532 | if (bsd_style_output) | |
533 | printf ("\n"); | |
5489fcc3 | 534 | } |
12516a37 KR |
535 | free (timesortsym); |
536 | if (print_descriptions && !bsd_style_output) | |
537 | { | |
538 | fsf_callg_blurb (stdout); | |
5489fcc3 | 539 | } |
03c35bcb | 540 | } |
5489fcc3 KR |
541 | |
542 | ||
543 | static int | |
12516a37 | 544 | DEFUN (cmp_name, (left, right), const PTR left AND const PTR right) |
5489fcc3 | 545 | { |
12516a37 KR |
546 | const Sym **npp1 = (const Sym **) left; |
547 | const Sym **npp2 = (const Sym **) right; | |
5489fcc3 | 548 | |
12516a37 | 549 | return strcmp ((*npp1)->name, (*npp2)->name); |
03c35bcb | 550 | } |
5489fcc3 KR |
551 | |
552 | ||
553 | void | |
12516a37 | 554 | DEFUN_VOID (cg_print_index) |
5489fcc3 | 555 | { |
12516a37 KR |
556 | int index, nnames, todo, i, j, col, starting_col; |
557 | Sym **name_sorted_syms, *sym; | |
558 | const char *filename; | |
559 | char buf[20]; | |
560 | int column_width = (output_width - 1) / 3; /* don't write in last col! */ | |
561 | /* | |
562 | * Now, sort regular function name alphabetically to create an | |
563 | * index: | |
564 | */ | |
565 | name_sorted_syms = (Sym **) xmalloc ((symtab.len + num_cycles) * sizeof (Sym *)); | |
566 | for (index = 0, nnames = 0; index < symtab.len; index++) | |
567 | { | |
568 | if (ignore_zeros && symtab.base[index].ncalls == 0 | |
569 | && symtab.base[index].hist.time == 0) | |
570 | { | |
571 | continue; | |
03c35bcb | 572 | } |
12516a37 | 573 | name_sorted_syms[nnames++] = &symtab.base[index]; |
03c35bcb | 574 | } |
12516a37 KR |
575 | qsort (name_sorted_syms, nnames, sizeof (Sym *), cmp_name); |
576 | for (index = 1, todo = nnames; index <= num_cycles; index++) | |
577 | { | |
578 | name_sorted_syms[todo++] = &cycle_header[index]; | |
03c35bcb | 579 | } |
12516a37 KR |
580 | printf ("\f\nIndex by function name\n\n"); |
581 | index = (todo + 2) / 3; | |
582 | for (i = 0; i < index; i++) | |
583 | { | |
584 | col = 0; | |
585 | starting_col = 0; | |
586 | for (j = i; j < todo; j += index) | |
5489fcc3 | 587 | { |
12516a37 KR |
588 | sym = name_sorted_syms[j]; |
589 | if (sym->cg.print_flag) | |
590 | { | |
591 | sprintf (buf, "[%d]", sym->cg.index); | |
592 | } | |
593 | else | |
594 | { | |
595 | sprintf (buf, "(%d)", sym->cg.index); | |
03c35bcb | 596 | } |
12516a37 KR |
597 | if (j < nnames) |
598 | { | |
599 | if (bsd_style_output) | |
600 | { | |
601 | printf ("%6.6s %-19.19s", buf, sym->name); | |
602 | } | |
603 | else | |
604 | { | |
605 | col += strlen (buf); | |
606 | for (; col < starting_col + 5; ++col) | |
607 | { | |
608 | putchar (' '); | |
03c35bcb | 609 | } |
12516a37 KR |
610 | printf (" %s ", buf); |
611 | col += print_name_only (sym); | |
612 | if (!line_granularity && sym->is_static && sym->file) | |
613 | { | |
614 | filename = sym->file->name; | |
615 | if (!print_path) | |
616 | { | |
617 | filename = strrchr (filename, '/'); | |
618 | if (filename) | |
619 | { | |
620 | ++filename; | |
621 | } | |
622 | else | |
623 | { | |
624 | filename = sym->file->name; | |
03c35bcb KR |
625 | } |
626 | } | |
12516a37 KR |
627 | printf (" (%s)", filename); |
628 | col += strlen (filename) + 3; | |
03c35bcb KR |
629 | } |
630 | } | |
12516a37 KR |
631 | } |
632 | else | |
633 | { | |
869b94c5 KR |
634 | if (bsd_style_output) |
635 | { | |
636 | printf ("%6.6s ", buf); | |
637 | sprintf (buf, "<cycle %d>", sym->cg.cyc.num); | |
638 | printf ("%-19.19s", buf); | |
639 | } | |
640 | else | |
641 | { | |
642 | col += strlen (buf); | |
643 | for (; col < starting_col + 5; ++col) | |
644 | putchar (' '); | |
645 | printf (" %s ", buf); | |
646 | sprintf (buf, "<cycle %d>", sym->cg.cyc.num); | |
647 | printf ("%s", buf); | |
648 | col += strlen (buf); | |
649 | } | |
03c35bcb | 650 | } |
12516a37 | 651 | starting_col += column_width; |
03c35bcb | 652 | } |
12516a37 | 653 | printf ("\n"); |
03c35bcb | 654 | } |
12516a37 | 655 | free (name_sorted_syms); |
03c35bcb | 656 | } |