Commit de2c7eb5 authored by Namhyung Kim's avatar Namhyung Kim Committed by Arnaldo Carvalho de Melo
Browse files

perf annotate: Split branch stack cycles information out of 'struct annotation_line'



The cycles info is used only when branch stack is provided.  Separate
them from 'struct annotation_line' into a separate struct and lazy
allocate them to save some memory.

Committer notes:

Make annotation__compute_ipc() check if the lazy allocation works,
bailing out if so, its callers already do error checking and
propagation.

Signed-off-by: default avatarNamhyung Kim <namhyung@kernel.org>
Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Christophe JAILLET <christophe.jaillet@wanadoo.fr>
Cc: Ian Rogers <irogers@google.com>
Cc: Ingo Molnar <mingo@kernel.org>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Peter Zijlstra <peterz@infradead.org>
Link: https://lore.kernel.org/r/20231103191907.54531-2-namhyung@kernel.org


Signed-off-by: default avatarArnaldo Carvalho de Melo <acme@redhat.com>
parent 89d5c48c
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -337,7 +337,7 @@ static void annotate_browser__calc_percent(struct annotate_browser *browser,
				max_percent = percent;
		}

		if (max_percent < 0.01 && pos->al.ipc == 0) {
		if (max_percent < 0.01 && (!pos->al.cycles || pos->al.cycles->ipc == 0)) {
			RB_CLEAR_NODE(&pos->al.rb_node);
			continue;
		}
+44 −17
Original line number Diff line number Diff line
@@ -1100,8 +1100,8 @@ static void annotation__count_and_fill(struct annotation *notes, u64 start, u64
		for (offset = start; offset <= end; offset++) {
			struct annotation_line *al = notes->offsets[offset];

			if (al && al->ipc == 0.0) {
				al->ipc = ipc;
			if (al && al->cycles && al->cycles->ipc == 0.0) {
				al->cycles->ipc = ipc;
				cover_insn++;
			}
		}
@@ -1114,12 +1114,13 @@ static void annotation__count_and_fill(struct annotation *notes, u64 start, u64
	}
}

void annotation__compute_ipc(struct annotation *notes, size_t size)
static int annotation__compute_ipc(struct annotation *notes, size_t size)
{
	int err = 0;
	s64 offset;

	if (!notes->src || !notes->src->cycles_hist)
		return;
		return 0;

	notes->total_insn = annotation__count_insn(notes, 0, size - 1);
	notes->hit_cycles = 0;
@@ -1134,18 +1135,39 @@ void annotation__compute_ipc(struct annotation *notes, size_t size)
		if (ch && ch->cycles) {
			struct annotation_line *al;

			al = notes->offsets[offset];
			if (al && al->cycles == NULL) {
				al->cycles = zalloc(sizeof(*al->cycles));
				if (al->cycles == NULL) {
					err = ENOMEM;
					break;
				}
			}
			if (ch->have_start)
				annotation__count_and_fill(notes, ch->start, offset, ch);
			al = notes->offsets[offset];
			if (al && ch->num_aggr) {
				al->cycles = ch->cycles_aggr / ch->num_aggr;
				al->cycles_max = ch->cycles_max;
				al->cycles_min = ch->cycles_min;
				al->cycles->avg = ch->cycles_aggr / ch->num_aggr;
				al->cycles->max = ch->cycles_max;
				al->cycles->min = ch->cycles_min;
			}
			notes->have_cycles = true;
		}
	}

	if (err) {
		while (++offset < (s64)size) {
			struct cyc_hist *ch = &notes->src->cycles_hist[offset];

			if (ch && ch->cycles) {
				struct annotation_line *al = notes->offsets[offset];
				if (al)
					zfree(&al->cycles);
			}
		}
	}

	annotation__unlock(notes);
	return 0;
}

int addr_map_symbol__inc_samples(struct addr_map_symbol *ams, struct perf_sample *sample,
@@ -1225,6 +1247,7 @@ static void annotation_line__exit(struct annotation_line *al)
{
	zfree_srcline(&al->path);
	zfree(&al->line);
	zfree(&al->cycles);
}

static size_t disasm_line_size(int nr)
@@ -3083,8 +3106,8 @@ static void __annotation_line__write(struct annotation_line *al, struct annotati
	int printed;

	if (first_line && (al->offset == -1 || percent_max == 0.0)) {
		if (notes->have_cycles) {
			if (al->ipc == 0.0 && al->cycles == 0)
		if (notes->have_cycles && al->cycles) {
			if (al->cycles->ipc == 0.0 && al->cycles->avg == 0)
				show_title = true;
		} else
			show_title = true;
@@ -3121,17 +3144,17 @@ static void __annotation_line__write(struct annotation_line *al, struct annotati
	}

	if (notes->have_cycles) {
		if (al->ipc)
			obj__printf(obj, "%*.2f ", ANNOTATION__IPC_WIDTH - 1, al->ipc);
		if (al->cycles && al->cycles->ipc)
			obj__printf(obj, "%*.2f ", ANNOTATION__IPC_WIDTH - 1, al->cycles->ipc);
		else if (!show_title)
			obj__printf(obj, "%*s", ANNOTATION__IPC_WIDTH, " ");
		else
			obj__printf(obj, "%*s ", ANNOTATION__IPC_WIDTH - 1, "IPC");

		if (!notes->options->show_minmax_cycle) {
			if (al->cycles)
			if (al->cycles && al->cycles->avg)
				obj__printf(obj, "%*" PRIu64 " ",
					   ANNOTATION__CYCLES_WIDTH - 1, al->cycles);
					   ANNOTATION__CYCLES_WIDTH - 1, al->cycles->avg);
			else if (!show_title)
				obj__printf(obj, "%*s",
					    ANNOTATION__CYCLES_WIDTH, " ");
@@ -3145,8 +3168,8 @@ static void __annotation_line__write(struct annotation_line *al, struct annotati

				scnprintf(str, sizeof(str),
					"%" PRIu64 "(%" PRIu64 "/%" PRIu64 ")",
					al->cycles, al->cycles_min,
					al->cycles_max);
					al->cycles->avg, al->cycles->min,
					al->cycles->max);

				obj__printf(obj, "%*s ",
					    ANNOTATION__MINMAX_CYCLES_WIDTH - 1,
@@ -3264,7 +3287,11 @@ int symbol__annotate2(struct map_symbol *ms, struct evsel *evsel,

	annotation__set_offsets(notes, size);
	annotation__mark_jump_targets(notes, sym);
	annotation__compute_ipc(notes, size);

	err = annotation__compute_ipc(notes, size);
	if (err)
		goto out_free_offsets;

	annotation__init_column_widths(notes, sym);
	notes->nr_events = nr_pcnt;

+9 −6
Original line number Diff line number Diff line
@@ -130,6 +130,13 @@ struct annotation_data {
	struct sym_hist_entry	 he;
};

struct cycles_info {
	float			 ipc;
	u64			 avg;
	u64			 max;
	u64			 min;
};

struct annotation_line {
	struct list_head	 node;
	struct rb_node		 rb_node;
@@ -137,12 +144,9 @@ struct annotation_line {
	char			*line;
	int			 line_nr;
	char			*fileloc;
	int			 jump_sources;
	float			 ipc;
	u64			 cycles;
	u64			 cycles_max;
	u64			 cycles_min;
	char			*path;
	struct cycles_info	*cycles;
	int			 jump_sources;
	u32			 idx;
	int			 idx_asm;
	int			 data_nr;
@@ -325,7 +329,6 @@ static inline bool annotation_line__filter(struct annotation_line *al, struct an
}

void annotation__set_offsets(struct annotation *notes, s64 size);
void annotation__compute_ipc(struct annotation *notes, size_t size);
void annotation__mark_jump_targets(struct annotation *notes, struct symbol *sym);
void annotation__update_column_widths(struct annotation *notes);
void annotation__init_column_widths(struct annotation *notes, struct symbol *sym);