summaryrefslogtreecommitdiff
path: root/tools/perf
diff options
context:
space:
mode:
authorZecheng Li <zecheng@google.com>2026-03-09 13:55:16 -0400
committerNamhyung Kim <namhyung@kernel.org>2026-03-19 14:42:29 -0700
commit8b8d8b8f17dfa817e4e94ce4e8f26d92f6f65504 (patch)
tree05fb3be1579dd538db05ade2893df4d94d0b2528 /tools/perf
parentace16303179efad4e1a2aebb27a661e5d1e7277d (diff)
perf dwarf-aux: Skip check_variable for variable lookup
Both die_find_variable_by_reg and die_find_variable_by_addr call match_var_offset which already performs sufficient checking and type matching. The additional check_variable call is redundant, and its need_pointer logic is only a heuristic. Since DWARF encodes accurate type information, which match_var_offset verifies, skipping check_variable improves both coverage and accuracy. Return the matched type from die_find_variable_by_reg and die_find_variable_by_addr via the existing `type` field in find_var_data, removing the need for check_variable in find_data_type_die. Signed-off-by: Zecheng Li <zecheng@google.com> Signed-off-by: Zecheng Li <zli94@ncsu.edu> Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Diffstat (limited to 'tools/perf')
-rw-r--r--tools/perf/util/annotate-data.c42
-rw-r--r--tools/perf/util/dwarf-aux.c13
-rw-r--r--tools/perf/util/dwarf-aux.h5
3 files changed, 30 insertions, 30 deletions
diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-data.c
index cda020ea18d5..23a09bf58f86 100644
--- a/tools/perf/util/annotate-data.c
+++ b/tools/perf/util/annotate-data.c
@@ -814,9 +814,8 @@ bool get_global_var_type(Dwarf_Die *cu_die, struct data_loc_info *dloc,
}
/* Try to get the variable by address first */
- if (die_find_variable_by_addr(cu_die, var_addr, &var_die, &offset) &&
- check_variable(dloc, &var_die, type_die, DWARF_REG_PC, offset,
- /*is_fbreg=*/false) == PERF_TMR_OK) {
+ if (die_find_variable_by_addr(cu_die, var_addr, &var_die, type_die,
+ &offset)) {
var_name = dwarf_diename(&var_die);
*var_offset = offset;
goto ok;
@@ -1606,12 +1605,13 @@ retry:
if (reg == DWARF_REG_PC) {
if (!die_find_variable_by_addr(&scopes[i], dloc->var_addr,
- &var_die, &type_offset))
+ &var_die, &mem_die,
+ &type_offset))
continue;
} else {
/* Look up variables/parameters in this scope */
if (!die_find_variable_by_reg(&scopes[i], pc, reg,
- &type_offset, is_fbreg, &var_die))
+ &mem_die, &type_offset, is_fbreg, &var_die))
continue;
}
@@ -1619,26 +1619,20 @@ retry:
dwarf_diename(&var_die), (long)dwarf_dieoffset(&var_die),
i+1, nr_scopes, (long)dwarf_dieoffset(&scopes[i]));
- /* Found a variable, see if it's correct */
- result = check_variable(dloc, &var_die, &mem_die, reg, type_offset, is_fbreg);
- if (result == PERF_TMR_OK) {
- if (reg == DWARF_REG_PC) {
- pr_debug_dtp("addr=%#"PRIx64" type_offset=%#x\n",
- dloc->var_addr, type_offset);
- } else if (reg == DWARF_REG_FB || is_fbreg) {
- pr_debug_dtp("stack_offset=%#x type_offset=%#x\n",
- fb_offset, type_offset);
- } else {
- pr_debug_dtp("type_offset=%#x\n", type_offset);
- }
-
- if (!found || is_better_type(type_die, &mem_die)) {
- *type_die = mem_die;
- dloc->type_offset = type_offset;
- found = true;
- }
+ if (reg == DWARF_REG_PC) {
+ pr_debug_dtp("addr=%#"PRIx64" type_offset=%#x\n",
+ dloc->var_addr, type_offset);
+ } else if (reg == DWARF_REG_FB || is_fbreg) {
+ pr_debug_dtp("stack_offset=%#x type_offset=%#x\n",
+ fb_offset, type_offset);
} else {
- pr_debug_dtp("failed: %s\n", match_result_str(result));
+ pr_debug_dtp("type_offset=%#x\n", type_offset);
+ }
+
+ if (!found || is_better_type(type_die, &mem_die)) {
+ *type_die = mem_die;
+ dloc->type_offset = type_offset;
+ found = true;
}
pr_debug_location(&var_die, pc, reg);
diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c
index 3b0fc9038f19..1484aa756826 100644
--- a/tools/perf/util/dwarf-aux.c
+++ b/tools/perf/util/dwarf-aux.c
@@ -1560,7 +1560,7 @@ static int __die_find_var_reg_cb(Dwarf_Die *die_mem, void *arg)
* when the variable is in the stack.
*/
Dwarf_Die *die_find_variable_by_reg(Dwarf_Die *sc_die, Dwarf_Addr pc, int reg,
- int *poffset, bool is_fbreg,
+ Dwarf_Die *type_die, int *poffset, bool is_fbreg,
Dwarf_Die *die_mem)
{
struct find_var_data data = {
@@ -1572,8 +1572,10 @@ Dwarf_Die *die_find_variable_by_reg(Dwarf_Die *sc_die, Dwarf_Addr pc, int reg,
Dwarf_Die *result;
result = die_find_child(sc_die, __die_find_var_reg_cb, &data, die_mem);
- if (result)
+ if (result) {
*poffset = data.offset;
+ *type_die = data.type;
+ }
return result;
}
@@ -1617,7 +1619,8 @@ static int __die_find_var_addr_cb(Dwarf_Die *die_mem, void *arg)
* This is usually for global variables.
*/
Dwarf_Die *die_find_variable_by_addr(Dwarf_Die *sc_die, Dwarf_Addr addr,
- Dwarf_Die *die_mem, int *offset)
+ Dwarf_Die *die_mem, Dwarf_Die *type_die,
+ int *offset)
{
struct find_var_data data = {
.addr = addr,
@@ -1625,8 +1628,10 @@ Dwarf_Die *die_find_variable_by_addr(Dwarf_Die *sc_die, Dwarf_Addr addr,
Dwarf_Die *result;
result = die_find_child(sc_die, __die_find_var_addr_cb, &data, die_mem);
- if (result)
+ if (result) {
*offset = data.offset;
+ *type_die = data.type;
+ }
return result;
}
diff --git a/tools/perf/util/dwarf-aux.h b/tools/perf/util/dwarf-aux.h
index 99d2735122d5..939a59c91796 100644
--- a/tools/perf/util/dwarf-aux.h
+++ b/tools/perf/util/dwarf-aux.h
@@ -165,12 +165,13 @@ int die_get_var_range(Dwarf_Die *sp_die, Dwarf_Die *vr_die, struct strbuf *buf);
/* Find a variable saved in the 'reg' at given address */
Dwarf_Die *die_find_variable_by_reg(Dwarf_Die *sc_die, Dwarf_Addr pc, int reg,
- int *poffset, bool is_fbreg,
+ Dwarf_Die *type_die, int *poffset, bool is_fbreg,
Dwarf_Die *die_mem);
/* Find a (global) variable located in the 'addr' */
Dwarf_Die *die_find_variable_by_addr(Dwarf_Die *sc_die, Dwarf_Addr addr,
- Dwarf_Die *die_mem, int *offset);
+ Dwarf_Die *die_mem, Dwarf_Die *type_die,
+ int *offset);
/* Save all variables and parameters in this scope */
void die_collect_vars(Dwarf_Die *sc_die, struct die_var_type **var_types);