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>
This commit is contained in:
Zecheng Li 2026-03-09 13:55:16 -04:00 committed by Namhyung Kim
parent ace1630317
commit 8b8d8b8f17
3 changed files with 30 additions and 30 deletions

View File

@ -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 @@ static int find_data_type_die(struct data_loc_info *dloc, Dwarf_Die *type_die)
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 @@ static int find_data_type_die(struct data_loc_info *dloc, Dwarf_Die *type_die)
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);

View File

@ -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;
}

View File

@ -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);