1 | #ifndef _PERF_BRANCH_H |
2 | #define _PERF_BRANCH_H 1 |
3 | /* |
4 | * The linux/stddef.h isn't need here, but is needed for __always_inline used |
5 | * in files included from uapi/linux/perf_event.h such as |
6 | * /usr/include/linux/swab.h and /usr/include/linux/byteorder/little_endian.h, |
7 | * detected in at least musl libc, used in Alpine Linux. -acme |
8 | */ |
9 | #include <stdio.h> |
10 | #include <linux/perf_event.h> |
11 | #include <linux/types.h> |
12 | #include "util/map_symbol.h" |
13 | #include "util/sample.h" |
14 | |
15 | struct branch_flags { |
16 | union { |
17 | u64 value; |
18 | struct { |
19 | u64 mispred:1; |
20 | u64 predicted:1; |
21 | u64 in_tx:1; |
22 | u64 abort:1; |
23 | u64 cycles:16; |
24 | u64 type:4; |
25 | u64 spec:2; |
26 | u64 new_type:4; |
27 | u64 priv:3; |
28 | u64 reserved:31; |
29 | }; |
30 | }; |
31 | }; |
32 | |
33 | struct branch_info { |
34 | struct addr_map_symbol from; |
35 | struct addr_map_symbol to; |
36 | struct branch_flags flags; |
37 | char *srcline_from; |
38 | char *srcline_to; |
39 | }; |
40 | |
41 | struct branch_entry { |
42 | u64 from; |
43 | u64 to; |
44 | struct branch_flags flags; |
45 | }; |
46 | |
47 | struct branch_stack { |
48 | u64 nr; |
49 | u64 hw_idx; |
50 | struct branch_entry entries[]; |
51 | }; |
52 | |
53 | /* |
54 | * The hw_idx is only available when PERF_SAMPLE_BRANCH_HW_INDEX is applied. |
55 | * Otherwise, the output format of a sample with branch stack is |
56 | * struct branch_stack { |
57 | * u64 nr; |
58 | * struct branch_entry entries[0]; |
59 | * } |
60 | * Check whether the hw_idx is available, |
61 | * and return the corresponding pointer of entries[0]. |
62 | */ |
63 | static inline struct branch_entry *perf_sample__branch_entries(struct perf_sample *sample) |
64 | { |
65 | u64 *entry = (u64 *)sample->branch_stack; |
66 | |
67 | entry++; |
68 | if (sample->no_hw_idx) |
69 | return (struct branch_entry *)entry; |
70 | return (struct branch_entry *)(++entry); |
71 | } |
72 | |
73 | struct branch_type_stat { |
74 | bool branch_to; |
75 | u64 counts[PERF_BR_MAX]; |
76 | u64 new_counts[PERF_BR_NEW_MAX]; |
77 | u64 cond_fwd; |
78 | u64 cond_bwd; |
79 | u64 cross_4k; |
80 | u64 cross_2m; |
81 | }; |
82 | |
83 | void branch_type_count(struct branch_type_stat *st, struct branch_flags *flags, |
84 | u64 from, u64 to); |
85 | |
86 | const char *branch_type_name(int type); |
87 | const char *branch_new_type_name(int new_type); |
88 | const char *get_branch_type(struct branch_entry *e); |
89 | void branch_type_stat_display(FILE *fp, const struct branch_type_stat *st); |
90 | int branch_type_str(const struct branch_type_stat *st, char *bf, int bfsize); |
91 | |
92 | const char *branch_spec_desc(int spec); |
93 | |
94 | #endif /* _PERF_BRANCH_H */ |
95 | |