summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--tools/perf/ui/browsers/annotate.c73
-rw-r--r--tools/perf/util/annotate.h2
2 files changed, 74 insertions, 1 deletions
diff --git a/tools/perf/ui/browsers/annotate.c b/tools/perf/ui/browsers/annotate.c
index 5995a8b..6ec1795 100644
--- a/tools/perf/ui/browsers/annotate.c
+++ b/tools/perf/ui/browsers/annotate.c
@@ -53,6 +53,7 @@ struct annotate_browser {
int max_jump_sources;
int nr_jumps;
bool searching_backwards;
+ bool have_cycles;
u8 addr_width;
u8 jumps_width;
u8 target_width;
@@ -390,7 +391,7 @@ static void annotate_browser__calc_percent(struct annotate_browser *browser,
max_percent = bpos->samples[i].percent;
}
- if (max_percent < 0.01) {
+ if (max_percent < 0.01 && pos->ipc == 0) {
RB_CLEAR_NODE(&bpos->rb_node);
continue;
}
@@ -869,6 +870,75 @@ int hist_entry__tui_annotate(struct hist_entry *he, struct perf_evsel *evsel,
return map_symbol__tui_annotate(&he->ms, evsel, hbt);
}
+
+static unsigned count_insn(struct annotate_browser *browser, u64 start, u64 end)
+{
+ unsigned n_insn = 0;
+ u64 offset;
+
+ for (offset = start; offset <= end; offset++) {
+ if (browser->offsets[offset])
+ n_insn++;
+ }
+ return n_insn;
+}
+
+static void count_and_fill(struct annotate_browser *browser, u64 start, u64 end,
+ struct cyc_hist *ch)
+{
+ unsigned n_insn;
+ u64 offset;
+
+ n_insn = count_insn(browser, start, end);
+ if (n_insn && ch->num && ch->cycles) {
+ float ipc = n_insn / ((double)ch->cycles / (double)ch->num);
+
+ /* Hide data when there are too many overlaps. */
+ if (ch->reset >= 0x7fff || ch->reset >= ch->num / 2)
+ return;
+
+ for (offset = start; offset <= end; offset++) {
+ struct disasm_line *dl = browser->offsets[offset];
+
+ if (dl)
+ dl->ipc = ipc;
+ }
+ }
+}
+
+/*
+ * This should probably be in util/annotate.c to share with the tty
+ * annotate, but right now we need the per byte offsets arrays,
+ * which are only here.
+ */
+static void annotate__compute_ipc(struct annotate_browser *browser, size_t size,
+ struct symbol *sym)
+{
+ u64 offset;
+ struct annotation *notes = symbol__annotation(sym);
+
+ if (!notes->src || !notes->src->cycles_hist)
+ return;
+
+ pthread_mutex_lock(&notes->lock);
+ for (offset = 0; offset < size; ++offset) {
+ struct cyc_hist *ch;
+
+ ch = &notes->src->cycles_hist[offset];
+ if (ch && ch->cycles) {
+ struct disasm_line *dl;
+
+ if (ch->have_start)
+ count_and_fill(browser, ch->start, offset, ch);
+ dl = browser->offsets[offset];
+ if (dl && ch->num_aggr)
+ dl->cycles = ch->cycles_aggr / ch->num_aggr;
+ browser->have_cycles = true;
+ }
+ }
+ pthread_mutex_unlock(&notes->lock);
+}
+
static void annotate_browser__mark_jump_targets(struct annotate_browser *browser,
size_t size)
{
@@ -991,6 +1061,7 @@ int symbol__tui_annotate(struct symbol *sym, struct map *map,
}
annotate_browser__mark_jump_targets(&browser, size);
+ annotate__compute_ipc(&browser, size, sym);
browser.addr_width = browser.target_width = browser.min_addr_width = hex_width(size);
browser.max_addr_width = hex_width(sym->end);
diff --git a/tools/perf/util/annotate.h b/tools/perf/util/annotate.h
index a06518d..e999609 100644
--- a/tools/perf/util/annotate.h
+++ b/tools/perf/util/annotate.h
@@ -59,6 +59,8 @@ struct disasm_line {
char *name;
struct ins *ins;
int line_nr;
+ float ipc;
+ u64 cycles;
struct ins_operands ops;
};