callchain.c (b49a821ed9e05fa0ccbaec2555052b2a920be517) callchain.c (a1a8bed32de197801bb861fbf13cd01496df3e05)
1/*
2 * Copyright (C) 2009-2011, Frederic Weisbecker <fweisbec@gmail.com>
3 *
4 * Handle the callchains from the stream in an ad-hoc radix tree and then
5 * sort them in an rbtree.
6 *
7 * Using a radix for code path provides a fast retrieval and factorizes
8 * memory use. Also that lets us use the paths in a hierarchical graph view.

--- 549 unchanged lines hidden (view full) ---

558 }
559 call->ip = cursor_node->ip;
560 call->ms.sym = cursor_node->sym;
561 call->ms.map = map__get(cursor_node->map);
562
563 if (cursor_node->branch) {
564 call->branch_count = 1;
565
1/*
2 * Copyright (C) 2009-2011, Frederic Weisbecker <fweisbec@gmail.com>
3 *
4 * Handle the callchains from the stream in an ad-hoc radix tree and then
5 * sort them in an rbtree.
6 *
7 * Using a radix for code path provides a fast retrieval and factorizes
8 * memory use. Also that lets us use the paths in a hierarchical graph view.

--- 549 unchanged lines hidden (view full) ---

558 }
559 call->ip = cursor_node->ip;
560 call->ms.sym = cursor_node->sym;
561 call->ms.map = map__get(cursor_node->map);
562
563 if (cursor_node->branch) {
564 call->branch_count = 1;
565
566 if (cursor_node->branch_flags.predicted)
567 call->predicted_count = 1;
566 if (cursor_node->branch_from) {
567 /*
568 * branch_from is set with value somewhere else
569 * to imply it's "to" of a branch.
570 */
571 call->brtype_stat.branch_to = true;
568
572
569 if (cursor_node->branch_flags.abort)
570 call->abort_count = 1;
573 if (cursor_node->branch_flags.predicted)
574 call->predicted_count = 1;
571
575
572 call->cycles_count = cursor_node->branch_flags.cycles;
573 call->iter_count = cursor_node->nr_loop_iter;
574 call->samples_count = cursor_node->samples;
576 if (cursor_node->branch_flags.abort)
577 call->abort_count = 1;
575
578
576 branch_type_count(&call->brtype_stat,
577 &cursor_node->branch_flags,
578 cursor_node->branch_from,
579 cursor_node->ip);
579 branch_type_count(&call->brtype_stat,
580 &cursor_node->branch_flags,
581 cursor_node->branch_from,
582 cursor_node->ip);
583 } else {
584 /*
585 * It's "from" of a branch
586 */
587 call->brtype_stat.branch_to = false;
588 call->cycles_count =
589 cursor_node->branch_flags.cycles;
590 call->iter_count = cursor_node->nr_loop_iter;
591 call->samples_count = cursor_node->samples;
592 }
580 }
581
582 list_add_tail(&call->list, &node->val);
583
584 callchain_cursor_advance(cursor);
585 cursor_node = callchain_cursor_current(cursor);
586 }
587 return 0;

--- 92 unchanged lines hidden (view full) ---

680 left = cnode->ip;
681 right = node->ip;
682 }
683
684 if (left == right) {
685 if (node->branch) {
686 cnode->branch_count++;
687
593 }
594
595 list_add_tail(&call->list, &node->val);
596
597 callchain_cursor_advance(cursor);
598 cursor_node = callchain_cursor_current(cursor);
599 }
600 return 0;

--- 92 unchanged lines hidden (view full) ---

693 left = cnode->ip;
694 right = node->ip;
695 }
696
697 if (left == right) {
698 if (node->branch) {
699 cnode->branch_count++;
700
688 if (node->branch_flags.predicted)
689 cnode->predicted_count++;
701 if (node->branch_from) {
702 /*
703 * It's "to" of a branch
704 */
705 cnode->brtype_stat.branch_to = true;
690
706
691 if (node->branch_flags.abort)
692 cnode->abort_count++;
707 if (node->branch_flags.predicted)
708 cnode->predicted_count++;
693
709
694 cnode->cycles_count += node->branch_flags.cycles;
695 cnode->iter_count += node->nr_loop_iter;
696 cnode->samples_count += node->samples;
710 if (node->branch_flags.abort)
711 cnode->abort_count++;
697
712
698 branch_type_count(&cnode->brtype_stat,
699 &node->branch_flags,
700 node->branch_from,
701 node->ip);
713 branch_type_count(&cnode->brtype_stat,
714 &node->branch_flags,
715 node->branch_from,
716 node->ip);
717 } else {
718 /*
719 * It's "from" of a branch
720 */
721 cnode->brtype_stat.branch_to = false;
722 cnode->cycles_count +=
723 node->branch_flags.cycles;
724 cnode->iter_count += node->nr_loop_iter;
725 cnode->samples_count += node->samples;
726 }
702 }
703
704 return MATCH_EQ;
705 }
706
707 return left > right ? MATCH_GT : MATCH_LT;
708}
709

--- 521 unchanged lines hidden (view full) ---

1231{
1232 int printed;
1233
1234 printed = scnprintf(bf, bfsize, "%s%s:%" PRId64 "", (idx) ? " " : " (", str, value);
1235
1236 return printed;
1237}
1238
727 }
728
729 return MATCH_EQ;
730 }
731
732 return left > right ? MATCH_GT : MATCH_LT;
733}
734

--- 521 unchanged lines hidden (view full) ---

1256{
1257 int printed;
1258
1259 printed = scnprintf(bf, bfsize, "%s%s:%" PRId64 "", (idx) ? " " : " (", str, value);
1260
1261 return printed;
1262}
1263
1239static int count_float_printf(int idx, const char *str, float value, char *bf, int bfsize)
1264static int count_float_printf(int idx, const char *str, float value,
1265 char *bf, int bfsize, float threshold)
1240{
1241 int printed;
1242
1266{
1267 int printed;
1268
1269 if (threshold != 0.0 && value < threshold)
1270 return 0;
1271
1243 printed = scnprintf(bf, bfsize, "%s%s:%.1f%%", (idx) ? " " : " (", str, value);
1244
1245 return printed;
1246}
1247
1272 printed = scnprintf(bf, bfsize, "%s%s:%.1f%%", (idx) ? " " : " (", str, value);
1273
1274 return printed;
1275}
1276
1248static int counts_str_build(char *bf, int bfsize,
1249 u64 branch_count, u64 predicted_count,
1250 u64 abort_count, u64 cycles_count,
1251 u64 iter_count, u64 samples_count,
1252 struct branch_type_stat *brtype_stat)
1277static int branch_to_str(char *bf, int bfsize,
1278 u64 branch_count, u64 predicted_count,
1279 u64 abort_count,
1280 struct branch_type_stat *brtype_stat)
1253{
1281{
1254 u64 cycles;
1255 int printed, i = 0;
1256
1282 int printed, i = 0;
1283
1257 if (branch_count == 0)
1258 return scnprintf(bf, bfsize, " (calltrace)");
1259
1260 printed = branch_type_str(brtype_stat, bf, bfsize);
1261 if (printed)
1262 i++;
1263
1264 if (predicted_count < branch_count) {
1265 printed += count_float_printf(i++, "predicted",
1266 predicted_count * 100.0 / branch_count,
1284 printed = branch_type_str(brtype_stat, bf, bfsize);
1285 if (printed)
1286 i++;
1287
1288 if (predicted_count < branch_count) {
1289 printed += count_float_printf(i++, "predicted",
1290 predicted_count * 100.0 / branch_count,
1267 bf + printed, bfsize - printed);
1291 bf + printed, bfsize - printed, 0.0);
1268 }
1269
1270 if (abort_count) {
1271 printed += count_float_printf(i++, "abort",
1272 abort_count * 100.0 / branch_count,
1292 }
1293
1294 if (abort_count) {
1295 printed += count_float_printf(i++, "abort",
1296 abort_count * 100.0 / branch_count,
1273 bf + printed, bfsize - printed);
1297 bf + printed, bfsize - printed, 0.1);
1274 }
1275
1298 }
1299
1300 if (i)
1301 printed += scnprintf(bf + printed, bfsize - printed, ")");
1302
1303 return printed;
1304}
1305
1306static int branch_from_str(char *bf, int bfsize,
1307 u64 branch_count,
1308 u64 cycles_count, u64 iter_count,
1309 u64 samples_count)
1310{
1311 int printed = 0, i = 0;
1312 u64 cycles;
1313
1276 cycles = cycles_count / branch_count;
1277 if (cycles) {
1278 printed += count_pri64_printf(i++, "cycles",
1279 cycles,
1280 bf + printed, bfsize - printed);
1281 }
1282
1283 if (iter_count && samples_count) {
1284 printed += count_pri64_printf(i++, "iterations",
1285 iter_count / samples_count,
1286 bf + printed, bfsize - printed);
1287 }
1288
1289 if (i)
1314 cycles = cycles_count / branch_count;
1315 if (cycles) {
1316 printed += count_pri64_printf(i++, "cycles",
1317 cycles,
1318 bf + printed, bfsize - printed);
1319 }
1320
1321 if (iter_count && samples_count) {
1322 printed += count_pri64_printf(i++, "iterations",
1323 iter_count / samples_count,
1324 bf + printed, bfsize - printed);
1325 }
1326
1327 if (i)
1290 return scnprintf(bf + printed, bfsize - printed, ")");
1328 printed += scnprintf(bf + printed, bfsize - printed, ")");
1291
1329
1292 bf[0] = 0;
1293 return 0;
1330 return printed;
1294}
1295
1331}
1332
1333static int counts_str_build(char *bf, int bfsize,
1334 u64 branch_count, u64 predicted_count,
1335 u64 abort_count, u64 cycles_count,
1336 u64 iter_count, u64 samples_count,
1337 struct branch_type_stat *brtype_stat)
1338{
1339 int printed;
1340
1341 if (branch_count == 0)
1342 return scnprintf(bf, bfsize, " (calltrace)");
1343
1344 if (brtype_stat->branch_to) {
1345 printed = branch_to_str(bf, bfsize, branch_count,
1346 predicted_count, abort_count, brtype_stat);
1347 } else {
1348 printed = branch_from_str(bf, bfsize, branch_count,
1349 cycles_count, iter_count, samples_count);
1350 }
1351
1352 if (!printed)
1353 bf[0] = 0;
1354
1355 return printed;
1356}
1357
1296static int callchain_counts_printf(FILE *fp, char *bf, int bfsize,
1297 u64 branch_count, u64 predicted_count,
1298 u64 abort_count, u64 cycles_count,
1299 u64 iter_count, u64 samples_count,
1300 struct branch_type_stat *brtype_stat)
1301{
1302 char str[256];
1303

--- 170 unchanged lines hidden ---
1358static int callchain_counts_printf(FILE *fp, char *bf, int bfsize,
1359 u64 branch_count, u64 predicted_count,
1360 u64 abort_count, u64 cycles_count,
1361 u64 iter_count, u64 samples_count,
1362 struct branch_type_stat *brtype_stat)
1363{
1364 char str[256];
1365

--- 170 unchanged lines hidden ---