Commit 112c5547 authored by Kan Liang's avatar Kan Liang Committed by Namhyung Kim

perf script: Print source line for each jump in brstackinsn

With the srcline option, the perf script only prints a source line at
the beginning of a sample with call/ret from functions, but not for
each jump in brstackinsn. It's useful to print a source line for each
jump in brstackinsn when the end user analyze the full assembler
sequences of branch sequences for the sample.

The srccode option can also be used to locate the source code line.
However, it's printed almost for every line and makes the output less
readable.

 $perf script -F +brstackinsn,+srcline --xed

Before the patch,

 tchain_edit_deb 1463275 15228549.107820:     282495 instructions:u:            401133 f3+0xd (/home/kan/os.li>
  tchain_edit.c:22
        f3+40:  tchain_edit.c:20
        000000000040114e                        jle 0x401133                    # PRED 6 cycles [6]
        0000000000401133                        movl  -0x4(%rbp), %eax
        0000000000401136                        and $0x1, %eax
        0000000000401139                        test %eax, %eax
        000000000040113b                        jz 0x401143
        000000000040113d                        addl  $0x1, -0x4(%rbp)
        0000000000401141                        jmp 0x401147                    # PRED 3 cycles [9] 2.00 IPC
        0000000000401147                        cmpl  $0x3e7, -0x4(%rbp)
        000000000040114e                        jle 0x401133                    # PRED 6 cycles [15] 0.33 IPC

After the patch,

 tchain_edit_deb 1463275 15228549.107820:     282495 instructions:u:            401133 f3+0xd (/home/kan/os.li>
  tchain_edit.c:22
        f3+40:  tchain_edit.c:20
        000000000040114e                        jle 0x401133                     srcline: tchain_edit.c:20      # PRED 6 cycles [6]
        0000000000401133                        movl  -0x4(%rbp), %eax
        0000000000401136                        and $0x1, %eax
        0000000000401139                        test %eax, %eax
        000000000040113b                        jz 0x401143
        000000000040113d                        addl  $0x1, -0x4(%rbp)
        0000000000401141                        jmp 0x401147                     srcline: tchain_edit.c:23      # PRED 3 cycles [9] 2.00 IPC
        0000000000401147                        cmpl  $0x3e7, -0x4(%rbp)
        000000000040114e                        jle 0x401133                     srcline: tchain_edit.c:20      # PRED 6 cycles [15] 0.33 IPC
Signed-off-by: default avatarKan Liang <kan.liang@linux.intel.com>
Reviewed-by: default avatarIan Rogers <irogers@google.com>
Cc: ahmad.yasin@intel.com
Cc: amiri.khalil@intel.com
Cc: ak@linux.intel.com
Signed-off-by: default avatarNamhyung Kim <namhyung@kernel.org>
Link: https://lore.kernel.org/r/20240205145819.1943114-1-kan.liang@linux.intel.com
parent 8ce5fa4d
...@@ -1162,7 +1162,8 @@ static int print_srccode(struct thread *thread, u8 cpumode, uint64_t addr) ...@@ -1162,7 +1162,8 @@ static int print_srccode(struct thread *thread, u8 cpumode, uint64_t addr)
static int ip__fprintf_jump(uint64_t ip, struct branch_entry *en, static int ip__fprintf_jump(uint64_t ip, struct branch_entry *en,
struct perf_insn *x, u8 *inbuf, int len, struct perf_insn *x, u8 *inbuf, int len,
int insn, FILE *fp, int *total_cycles, int insn, FILE *fp, int *total_cycles,
struct perf_event_attr *attr) struct perf_event_attr *attr,
struct thread *thread)
{ {
int ilen = 0; int ilen = 0;
int printed = fprintf(fp, "\t%016" PRIx64 "\t%-30s\t", ip, int printed = fprintf(fp, "\t%016" PRIx64 "\t%-30s\t", ip,
...@@ -1171,6 +1172,16 @@ static int ip__fprintf_jump(uint64_t ip, struct branch_entry *en, ...@@ -1171,6 +1172,16 @@ static int ip__fprintf_jump(uint64_t ip, struct branch_entry *en,
if (PRINT_FIELD(BRSTACKINSNLEN)) if (PRINT_FIELD(BRSTACKINSNLEN))
printed += fprintf(fp, "ilen: %d\t", ilen); printed += fprintf(fp, "ilen: %d\t", ilen);
if (PRINT_FIELD(SRCLINE)) {
struct addr_location al;
addr_location__init(&al);
thread__find_map(thread, x->cpumode, ip, &al);
printed += map__fprintf_srcline(al.map, al.addr, " srcline: ", fp);
printed += fprintf(fp, "\t");
addr_location__exit(&al);
}
printed += fprintf(fp, "#%s%s%s%s", printed += fprintf(fp, "#%s%s%s%s",
en->flags.predicted ? " PRED" : "", en->flags.predicted ? " PRED" : "",
en->flags.mispred ? " MISPRED" : "", en->flags.mispred ? " MISPRED" : "",
...@@ -1182,6 +1193,7 @@ static int ip__fprintf_jump(uint64_t ip, struct branch_entry *en, ...@@ -1182,6 +1193,7 @@ static int ip__fprintf_jump(uint64_t ip, struct branch_entry *en,
if (insn) if (insn)
printed += fprintf(fp, " %.2f IPC", (float)insn / en->flags.cycles); printed += fprintf(fp, " %.2f IPC", (float)insn / en->flags.cycles);
} }
return printed + fprintf(fp, "\n"); return printed + fprintf(fp, "\n");
} }
...@@ -1260,7 +1272,7 @@ static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample, ...@@ -1260,7 +1272,7 @@ static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample,
x.cpumode, x.cpu, &lastsym, attr, fp); x.cpumode, x.cpu, &lastsym, attr, fp);
printed += ip__fprintf_jump(entries[nr - 1].from, &entries[nr - 1], printed += ip__fprintf_jump(entries[nr - 1].from, &entries[nr - 1],
&x, buffer, len, 0, fp, &total_cycles, &x, buffer, len, 0, fp, &total_cycles,
attr); attr, thread);
if (PRINT_FIELD(SRCCODE)) if (PRINT_FIELD(SRCCODE))
printed += print_srccode(thread, x.cpumode, entries[nr - 1].from); printed += print_srccode(thread, x.cpumode, entries[nr - 1].from);
} }
...@@ -1291,7 +1303,7 @@ static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample, ...@@ -1291,7 +1303,7 @@ static int perf_sample__fprintf_brstackinsn(struct perf_sample *sample,
printed += ip__fprintf_sym(ip, thread, x.cpumode, x.cpu, &lastsym, attr, fp); printed += ip__fprintf_sym(ip, thread, x.cpumode, x.cpu, &lastsym, attr, fp);
if (ip == end) { if (ip == end) {
printed += ip__fprintf_jump(ip, &entries[i], &x, buffer + off, len - off, ++insn, fp, printed += ip__fprintf_jump(ip, &entries[i], &x, buffer + off, len - off, ++insn, fp,
&total_cycles, attr); &total_cycles, attr, thread);
if (PRINT_FIELD(SRCCODE)) if (PRINT_FIELD(SRCCODE))
printed += print_srccode(thread, x.cpumode, ip); printed += print_srccode(thread, x.cpumode, ip);
break; break;
......
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