perf annotate-data: Parse 'lock' prefix from llvm-objdump
authorNamhyung Kim <namhyung@kernel.org>
Wed, 17 Jan 2024 06:26:49 +0000 (22:26 -0800)
committerNamhyung Kim <namhyung@kernel.org>
Mon, 22 Jan 2024 20:08:19 +0000 (12:08 -0800)
For the performance reason, I prefer llvm-objdump over GNU's.  But I
found that llvm-objdump puts x86 lock prefix in a separate line like
below.

  ffffffff81000695: f0                    lock
  ffffffff81000696: ff 83 54 0b 00 00     incl    2900(%rbx)

This should be parsed properly, but I just changed to find the insn
with next offset for now.

This improves the statistics as it can process more instructions.

  Annotate data type stats:
  total 294, ok 144 (49.0%), bad 150 (51.0%)
  -----------------------------------------------------------
          30 : no_sym
          35 : no_mem_ops
          71 : no_var
           6 : no_typeinfo
           8 : bad_offset

Reviewed-by: Ian Rogers <irogers@google.com>
Cc: Stephane Eranian <eranian@google.com>
Cc: Masami Hiramatsu <mhiramat@kernel.org>
Link: https://lore.kernel.org/r/20240117062657.985479-2-namhyung@kernel.org
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
tools/perf/util/annotate.c

index 9b70ab1..8d761be 100644 (file)
@@ -3660,8 +3660,17 @@ static struct disasm_line *find_disasm_line(struct symbol *sym, u64 ip)
        notes = symbol__annotation(sym);
 
        list_for_each_entry(dl, &notes->src->source, al.node) {
-               if (sym->start + dl->al.offset == ip)
+               if (sym->start + dl->al.offset == ip) {
+                       /*
+                        * llvm-objdump places "lock" in a separate line and
+                        * in that case, we want to get the next line.
+                        */
+                       if (!strcmp(dl->ins.name, "lock") && *dl->ops.raw == '\0') {
+                               ip++;
+                               continue;
+                       }
                        return dl;
+               }
        }
        return NULL;
 }
@@ -3758,6 +3767,9 @@ struct annotated_data_type *hist_entry__get_data_type(struct hist_entry *he)
                if (!op_loc->mem_ref)
                        continue;
 
+               /* Recalculate IP since it can be changed due to LOCK prefix */
+               ip = ms->sym->start + dl->al.offset;
+
                mem_type = find_data_type(ms, ip, op_loc->reg, op_loc->offset);
                if (mem_type)
                        istat->good++;