Commit e6952dce authored by Kan Liang's avatar Kan Liang Committed by Arnaldo Carvalho de Melo

perf annotate: Display the branch counter histogram

Display the branch counter histogram in the annotation view.

Press 'B' to display the branch counter's abbreviation list as well.

  Samples: 1M of events 'anon group { branch-instructions:ppp, branch-misses }',
  4000 Hz, Event count (approx.):
  f3  /home/sdp/test/tchain_edit [Percent: local period]
  Percent       │ IPC Cycle       Branch Counter (Average IPC: 1.39, IPC Coverage: 29.4%)
                │                                     0000000000401755 <f3>:
    0.00   0.00 │                                       endbr64
                │                                       push    %rbp
                │                                       mov     %rsp,%rbp
                │                                       movl    $0x0,-0x4(%rbp)
    0.00   0.00 │1.33     3          |A   |-   |      ↓ jmp     25
   11.03  11.03 │                                 11:   mov     -0x4(%rbp),%eax
                │                                       and     $0x1,%eax
                │                                       test    %eax,%eax
   17.13  17.13 │2.41     1          |A   |-   |      ↓ je      21
                │                                       addl    $0x1,-0x4(%rbp)
   21.84  21.84 │2.22     2          |AA  |-   |      ↓ jmp     25
   17.13  17.13 │                                 21:   addl    $0x1,-0x4(%rbp)
   21.84  21.84 │                                 25:   cmpl    $0x270f,-0x4(%rbp)
   11.03  11.03 │0.61     3          |A   |-   |      ↑ jle     11
                │                                       nop
                │                                       pop     %rbp
    0.00   0.00 │0.24    20          |AA  |B   |      ← ret
Originally-by: default avatarTinghao Zhang <tinghao.zhang@intel.com>
Reviewed-by: default avatarAndi Kleen <ak@linux.intel.com>
Signed-off-by: default avatarKan Liang <kan.liang@linux.intel.com>
Acked-by: default avatarNamhyung Kim <namhyung@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Ian Rogers <irogers@google.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Cc: Stephane Eranian <eranian@google.com>
Link: https://lore.kernel.org/r/20240813160208.2493643-8-kan.liang@linux.intel.comSigned-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 20d6f555
......@@ -927,11 +927,15 @@ int cmd_annotate(int argc, const char **argv)
sort_order = "dso,symbol";
/*
* Set SORT_MODE__BRANCH so that annotate display IPC/Cycle
* if branch info is in perf data in TUI mode.
* Set SORT_MODE__BRANCH so that annotate displays IPC/Cycle and
* branch counters, if the corresponding branch info is available
* in the perf data in the TUI mode.
*/
if ((use_browser == 1 || annotate.use_stdio2) && annotate.has_br_stack)
if ((use_browser == 1 || annotate.use_stdio2) && annotate.has_br_stack) {
sort__mode = SORT_MODE__BRANCH;
if (annotate.session->evlist->nr_br_cntr > 0)
annotate_opts.show_br_cntr = true;
}
if (setup_sorting(NULL) < 0)
usage_with_options(annotate_usage, options);
......
......@@ -156,6 +156,7 @@ static void annotate_browser__draw_current_jump(struct ui_browser *browser)
struct symbol *sym = ms->sym;
struct annotation *notes = symbol__annotation(sym);
u8 pcnt_width = annotation__pcnt_width(notes);
u8 cntr_width = annotation__br_cntr_width();
int width;
int diff = 0;
......@@ -205,13 +206,13 @@ static void annotate_browser__draw_current_jump(struct ui_browser *browser)
ui_browser__set_color(browser, HE_COLORSET_JUMP_ARROWS);
__ui_browser__line_arrow(browser,
pcnt_width + 2 + notes->src->widths.addr + width,
pcnt_width + 2 + notes->src->widths.addr + width + cntr_width,
from, to);
diff = is_fused(ab, cursor);
if (diff > 0) {
ui_browser__mark_fused(browser,
pcnt_width + 3 + notes->src->widths.addr + width,
pcnt_width + 3 + notes->src->widths.addr + width + cntr_width,
from - diff, diff, to > from);
}
}
......@@ -714,6 +715,7 @@ static int annotate_browser__run(struct annotate_browser *browser,
struct annotation *notes = symbol__annotation(ms->sym);
const char *help = "Press 'h' for help on key bindings";
int delay_secs = hbt ? hbt->refresh : 0;
char *br_cntr_text = NULL;
char title[256];
int key;
......@@ -730,6 +732,8 @@ static int annotate_browser__run(struct annotate_browser *browser,
nd = browser->curr_hot;
annotation_br_cntr_abbr_list(&br_cntr_text, evsel, false);
while (1) {
key = ui_browser__run(&browser->b, delay_secs);
......@@ -796,6 +800,7 @@ static int annotate_browser__run(struct annotate_browser *browser,
"r Run available scripts\n"
"p Toggle percent type [local/global]\n"
"b Toggle percent base [period/hits]\n"
"B Branch counter abbr list (Optional)\n"
"? Search string backwards\n"
"f Toggle showing offsets to full address\n");
continue;
......@@ -904,6 +909,14 @@ static int annotate_browser__run(struct annotate_browser *browser,
hists__scnprintf_title(hists, title, sizeof(title));
annotate_browser__show(&browser->b, title, help);
continue;
case 'B':
if (br_cntr_text)
ui_browser__help_window(&browser->b, br_cntr_text);
else {
ui_browser__help_window(&browser->b,
"\n The branch counter is not available.\n");
}
continue;
case 'f':
annotation__toggle_full_addr(notes, ms);
continue;
......@@ -923,6 +936,7 @@ static int annotate_browser__run(struct annotate_browser *browser,
}
out:
ui_browser__hide(&browser->b);
free(br_cntr_text);
return key;
}
......
......@@ -3705,7 +3705,8 @@ int block_hists_tui_browse(struct block_hist *bh, struct evsel *evsel,
memset(&action, 0, sizeof(action));
annotation_br_cntr_abbr_list(&br_cntr_text, evsel, false);
if (!annotation_br_cntr_abbr_list(&br_cntr_text, evsel, false))
annotate_opts.show_br_cntr = true;
while (1) {
key = hist_browser__run(browser, "? - help", true, 0);
......
......@@ -501,8 +501,10 @@ static void annotation__count_and_fill(struct annotation *notes, u64 start, u64
}
}
static int annotation__compute_ipc(struct annotation *notes, size_t size)
static int annotation__compute_ipc(struct annotation *notes, size_t size,
struct evsel *evsel)
{
unsigned int br_cntr_nr = evsel->evlist->nr_br_cntr;
int err = 0;
s64 offset;
......@@ -537,6 +539,20 @@ static int annotation__compute_ipc(struct annotation *notes, size_t size)
al->cycles->max = ch->cycles_max;
al->cycles->min = ch->cycles_min;
}
if (al && notes->branch->br_cntr) {
if (!al->br_cntr) {
al->br_cntr = calloc(br_cntr_nr, sizeof(u64));
if (!al->br_cntr) {
err = ENOMEM;
break;
}
}
al->num_aggr = ch->num_aggr;
al->br_cntr_nr = br_cntr_nr;
al->evsel = evsel;
memcpy(al->br_cntr, &notes->branch->br_cntr[offset * br_cntr_nr],
br_cntr_nr * sizeof(u64));
}
}
}
......@@ -548,8 +564,10 @@ static int annotation__compute_ipc(struct annotation *notes, size_t size)
struct annotation_line *al;
al = annotated_source__get_line(notes->src, offset);
if (al)
if (al) {
zfree(&al->cycles);
zfree(&al->br_cntr);
}
}
}
}
......@@ -1960,6 +1978,22 @@ static void __annotation_line__write(struct annotation_line *al, struct annotati
"Cycle(min/max)");
}
if (annotate_opts.show_br_cntr) {
if (show_title) {
obj__printf(obj, "%*s ",
ANNOTATION__BR_CNTR_WIDTH,
"Branch Counter");
} else {
char *buf;
if (!annotation_br_cntr_entry(&buf, al->br_cntr_nr, al->br_cntr,
al->num_aggr, al->evsel)) {
obj__printf(obj, "%*s ", ANNOTATION__BR_CNTR_WIDTH, buf);
free(buf);
}
}
}
if (show_title && !*al->line) {
ipc_coverage_string(bf, sizeof(bf), notes);
obj__printf(obj, "%*s", ANNOTATION__AVG_IPC_WIDTH, bf);
......@@ -2056,7 +2090,7 @@ int symbol__annotate2(struct map_symbol *ms, struct evsel *evsel,
annotation__set_index(notes);
annotation__mark_jump_targets(notes, sym);
err = annotation__compute_ipc(notes, size);
err = annotation__compute_ipc(notes, size, evsel);
if (err)
return err;
......
......@@ -31,6 +31,7 @@ struct annotated_data_type;
#define ANNOTATION__CYCLES_WIDTH 6
#define ANNOTATION__MINMAX_CYCLES_WIDTH 19
#define ANNOTATION__AVG_IPC_WIDTH 36
#define ANNOTATION__BR_CNTR_WIDTH 30
#define ANNOTATION_DUMMY_LEN 256
struct annotation_options {
......@@ -44,6 +45,7 @@ struct annotation_options {
show_nr_jumps,
show_minmax_cycle,
show_asm_raw,
show_br_cntr,
annotate_src,
full_addr;
u8 offset_level;
......@@ -104,6 +106,10 @@ struct annotation_line {
char *fileloc;
char *path;
struct cycles_info *cycles;
int num_aggr;
int br_cntr_nr;
u64 *br_cntr;
struct evsel *evsel;
int jump_sources;
u32 idx;
int idx_asm;
......@@ -353,6 +359,11 @@ static inline bool annotation_line__filter(struct annotation_line *al)
return annotate_opts.hide_src_code && al->offset == -1;
}
static inline u8 annotation__br_cntr_width(void)
{
return annotate_opts.show_br_cntr ? ANNOTATION__BR_CNTR_WIDTH : 0;
}
void annotation__update_column_widths(struct annotation *notes);
void annotation__toggle_full_addr(struct annotation *notes, struct map_symbol *ms);
......
......@@ -1015,6 +1015,7 @@ static void annotation_line__exit(struct annotation_line *al)
zfree_srcline(&al->path);
zfree(&al->line);
zfree(&al->cycles);
zfree(&al->br_cntr);
}
static size_t disasm_line_size(int nr)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment