tools/perf/builtin-annotate.c

Source file repositories/reference/linux-study-clean/tools/perf/builtin-annotate.c

File Facts

System
Linux kernel
Corpus path
tools/perf/builtin-annotate.c
Extension
.c
Size
25521 bytes
Lines
952
Domain
Support Tooling And Documentation
Bucket
tools
Inferred role
Support Tooling And Documentation: implementation source
Status
source implementation candidate

Why This File Exists

Repository support layer: documentation, build tooling, samples, user-space helper tools, generated initramfs support, licenses, and validation utilities.

Dependency Surface

Detected Declarations

Annotated Snippet

struct perf_annotate {
	struct perf_tool tool;
	struct perf_session *session;
#ifdef HAVE_SLANG_SUPPORT
	bool	   use_tui;
#endif
	bool	   use_stdio, use_stdio2;
#ifdef HAVE_GTK2_SUPPORT
	bool	   use_gtk;
#endif
	bool	   skip_missing;
	bool	   has_br_stack;
	bool	   group_set;
	bool	   data_type;
	bool	   type_stat;
	bool	   insn_stat;
	float	   min_percent;
	const char *sym_hist_filter;
	const char *cpu_list;
	const char *target_data_type;
	DECLARE_BITMAP(cpu_bitmap, MAX_NR_CPUS);
};

/*
 * Given one basic block:
 *
 *	from	to		branch_i
 *	* ----> *
 *		|
 *		| block
 *		v
 *		* ----> *
 *		from	to	branch_i+1
 *
 * where the horizontal are the branches and the vertical is the executed
 * block of instructions.
 *
 * We count, for each 'instruction', the number of blocks that covered it as
 * well as count the ratio each branch is taken.
 *
 * We can do this without knowing the actual instruction stream by keeping
 * track of the address ranges. We break down ranges such that there is no
 * overlap and iterate from the start until the end.
 *
 * @acme: once we parse the objdump output _before_ processing the samples,
 * we can easily fold the branch.cycles IPC bits in.
 */
static void process_basic_block(struct addr_map_symbol *start,
				struct addr_map_symbol *end,
				struct branch_flags *flags)
{
	struct symbol *sym = start->ms.sym;
	struct annotation *notes = sym ? symbol__annotation(sym) : NULL;
	struct block_range_iter iter;
	struct block_range *entry;
	struct annotated_branch *branch;

	/*
	 * Sanity; NULL isn't executable and the CPU cannot execute backwards
	 */
	if (!start->addr || start->addr > end->addr)
		return;

	iter = block_range__create(start->addr, end->addr);
	if (!block_range_iter__valid(&iter))
		return;

	branch = annotation__get_branch(notes);

	/*
	 * First block in range is a branch target.
	 */
	entry = block_range_iter(&iter);
	assert(entry->is_target);
	entry->entry++;

	do {
		entry = block_range_iter(&iter);

		entry->coverage++;
		entry->sym = sym;

		if (branch)
			branch->max_coverage = max(branch->max_coverage, entry->coverage);

	} while (block_range_iter__next(&iter));

	/*
	 * Last block in rage is a branch.
	 */

Annotation

Implementation Notes