Linux Audio

Check our new training course

Loading...
v5.4
  1#include "util/map_symbol.h"
 
 
  2#include "util/branch.h"
  3#include <linux/kernel.h>
  4
  5static bool cross_area(u64 addr1, u64 addr2, int size)
  6{
  7	u64 align1, align2;
  8
  9	align1 = addr1 & ~(size - 1);
 10	align2 = addr2 & ~(size - 1);
 11
 12	return (align1 != align2) ? true : false;
 13}
 14
 15#define AREA_4K		4096
 16#define AREA_2M		(2 * 1024 * 1024)
 17
 18void branch_type_count(struct branch_type_stat *st, struct branch_flags *flags,
 19		       u64 from, u64 to)
 20{
 21	if (flags->type == PERF_BR_UNKNOWN || from == 0)
 22		return;
 23
 24	st->counts[flags->type]++;
 25
 26	if (flags->type == PERF_BR_COND) {
 27		if (to > from)
 28			st->cond_fwd++;
 29		else
 30			st->cond_bwd++;
 31	}
 32
 33	if (cross_area(from, to, AREA_2M))
 34		st->cross_2m++;
 35	else if (cross_area(from, to, AREA_4K))
 36		st->cross_4k++;
 37}
 38
 39const char *branch_type_name(int type)
 40{
 41	const char *branch_names[PERF_BR_MAX] = {
 42		"N/A",
 43		"COND",
 44		"UNCOND",
 45		"IND",
 46		"CALL",
 47		"IND_CALL",
 48		"RET",
 49		"SYSCALL",
 50		"SYSRET",
 51		"COND_CALL",
 52		"COND_RET"
 53	};
 54
 55	if (type >= 0 && type < PERF_BR_MAX)
 56		return branch_names[type];
 57
 58	return NULL;
 59}
 60
 61void branch_type_stat_display(FILE *fp, struct branch_type_stat *st)
 62{
 63	u64 total = 0;
 64	int i;
 65
 66	for (i = 0; i < PERF_BR_MAX; i++)
 67		total += st->counts[i];
 68
 69	if (total == 0)
 70		return;
 71
 72	fprintf(fp, "\n#");
 73	fprintf(fp, "\n# Branch Statistics:");
 74	fprintf(fp, "\n#");
 75
 76	if (st->cond_fwd > 0) {
 77		fprintf(fp, "\n%8s: %5.1f%%",
 78			"COND_FWD",
 79			100.0 * (double)st->cond_fwd / (double)total);
 80	}
 81
 82	if (st->cond_bwd > 0) {
 83		fprintf(fp, "\n%8s: %5.1f%%",
 84			"COND_BWD",
 85			100.0 * (double)st->cond_bwd / (double)total);
 86	}
 87
 88	if (st->cross_4k > 0) {
 89		fprintf(fp, "\n%8s: %5.1f%%",
 90			"CROSS_4K",
 91			100.0 * (double)st->cross_4k / (double)total);
 92	}
 93
 94	if (st->cross_2m > 0) {
 95		fprintf(fp, "\n%8s: %5.1f%%",
 96			"CROSS_2M",
 97			100.0 * (double)st->cross_2m / (double)total);
 98	}
 99
100	for (i = 0; i < PERF_BR_MAX; i++) {
101		if (st->counts[i] > 0)
102			fprintf(fp, "\n%8s: %5.1f%%",
103				branch_type_name(i),
104				100.0 *
105				(double)st->counts[i] / (double)total);
106	}
107}
108
109static int count_str_scnprintf(int idx, const char *str, char *bf, int size)
110{
111	return scnprintf(bf, size, "%s%s", (idx) ? " " : " (", str);
112}
113
114int branch_type_str(struct branch_type_stat *st, char *bf, int size)
115{
116	int i, j = 0, printed = 0;
117	u64 total = 0;
118
119	for (i = 0; i < PERF_BR_MAX; i++)
120		total += st->counts[i];
121
122	if (total == 0)
123		return 0;
124
125	if (st->cond_fwd > 0)
126		printed += count_str_scnprintf(j++, "COND_FWD", bf + printed, size - printed);
127
128	if (st->cond_bwd > 0)
129		printed += count_str_scnprintf(j++, "COND_BWD", bf + printed, size - printed);
130
131	for (i = 0; i < PERF_BR_MAX; i++) {
132		if (i == PERF_BR_COND)
133			continue;
134
135		if (st->counts[i] > 0)
136			printed += count_str_scnprintf(j++, branch_type_name(i), bf + printed, size - printed);
137	}
138
139	if (st->cross_4k > 0)
140		printed += count_str_scnprintf(j++, "CROSS_4K", bf + printed, size - printed);
141
142	if (st->cross_2m > 0)
143		printed += count_str_scnprintf(j++, "CROSS_2M", bf + printed, size - printed);
144
145	return printed;
146}
v4.17
  1#include "perf.h"
  2#include "util/util.h"
  3#include "util/debug.h"
  4#include "util/branch.h"
 
  5
  6static bool cross_area(u64 addr1, u64 addr2, int size)
  7{
  8	u64 align1, align2;
  9
 10	align1 = addr1 & ~(size - 1);
 11	align2 = addr2 & ~(size - 1);
 12
 13	return (align1 != align2) ? true : false;
 14}
 15
 16#define AREA_4K		4096
 17#define AREA_2M		(2 * 1024 * 1024)
 18
 19void branch_type_count(struct branch_type_stat *st, struct branch_flags *flags,
 20		       u64 from, u64 to)
 21{
 22	if (flags->type == PERF_BR_UNKNOWN || from == 0)
 23		return;
 24
 25	st->counts[flags->type]++;
 26
 27	if (flags->type == PERF_BR_COND) {
 28		if (to > from)
 29			st->cond_fwd++;
 30		else
 31			st->cond_bwd++;
 32	}
 33
 34	if (cross_area(from, to, AREA_2M))
 35		st->cross_2m++;
 36	else if (cross_area(from, to, AREA_4K))
 37		st->cross_4k++;
 38}
 39
 40const char *branch_type_name(int type)
 41{
 42	const char *branch_names[PERF_BR_MAX] = {
 43		"N/A",
 44		"COND",
 45		"UNCOND",
 46		"IND",
 47		"CALL",
 48		"IND_CALL",
 49		"RET",
 50		"SYSCALL",
 51		"SYSRET",
 52		"COND_CALL",
 53		"COND_RET"
 54	};
 55
 56	if (type >= 0 && type < PERF_BR_MAX)
 57		return branch_names[type];
 58
 59	return NULL;
 60}
 61
 62void branch_type_stat_display(FILE *fp, struct branch_type_stat *st)
 63{
 64	u64 total = 0;
 65	int i;
 66
 67	for (i = 0; i < PERF_BR_MAX; i++)
 68		total += st->counts[i];
 69
 70	if (total == 0)
 71		return;
 72
 73	fprintf(fp, "\n#");
 74	fprintf(fp, "\n# Branch Statistics:");
 75	fprintf(fp, "\n#");
 76
 77	if (st->cond_fwd > 0) {
 78		fprintf(fp, "\n%8s: %5.1f%%",
 79			"COND_FWD",
 80			100.0 * (double)st->cond_fwd / (double)total);
 81	}
 82
 83	if (st->cond_bwd > 0) {
 84		fprintf(fp, "\n%8s: %5.1f%%",
 85			"COND_BWD",
 86			100.0 * (double)st->cond_bwd / (double)total);
 87	}
 88
 89	if (st->cross_4k > 0) {
 90		fprintf(fp, "\n%8s: %5.1f%%",
 91			"CROSS_4K",
 92			100.0 * (double)st->cross_4k / (double)total);
 93	}
 94
 95	if (st->cross_2m > 0) {
 96		fprintf(fp, "\n%8s: %5.1f%%",
 97			"CROSS_2M",
 98			100.0 * (double)st->cross_2m / (double)total);
 99	}
100
101	for (i = 0; i < PERF_BR_MAX; i++) {
102		if (st->counts[i] > 0)
103			fprintf(fp, "\n%8s: %5.1f%%",
104				branch_type_name(i),
105				100.0 *
106				(double)st->counts[i] / (double)total);
107	}
108}
109
110static int count_str_scnprintf(int idx, const char *str, char *bf, int size)
111{
112	return scnprintf(bf, size, "%s%s", (idx) ? " " : " (", str);
113}
114
115int branch_type_str(struct branch_type_stat *st, char *bf, int size)
116{
117	int i, j = 0, printed = 0;
118	u64 total = 0;
119
120	for (i = 0; i < PERF_BR_MAX; i++)
121		total += st->counts[i];
122
123	if (total == 0)
124		return 0;
125
126	if (st->cond_fwd > 0)
127		printed += count_str_scnprintf(j++, "COND_FWD", bf + printed, size - printed);
128
129	if (st->cond_bwd > 0)
130		printed += count_str_scnprintf(j++, "COND_BWD", bf + printed, size - printed);
131
132	for (i = 0; i < PERF_BR_MAX; i++) {
133		if (i == PERF_BR_COND)
134			continue;
135
136		if (st->counts[i] > 0)
137			printed += count_str_scnprintf(j++, branch_type_name(i), bf + printed, size - printed);
138	}
139
140	if (st->cross_4k > 0)
141		printed += count_str_scnprintf(j++, "CROSS_4K", bf + printed, size - printed);
142
143	if (st->cross_2m > 0)
144		printed += count_str_scnprintf(j++, "CROSS_2M", bf + printed, size - printed);
145
146	return printed;
147}