[PATCH 5/6] perf annotate-data: Handle multi regs in find_data_type_block()

From: Namhyung Kim
Date: Thu May 02 2024 - 02:01:17 EST


The instruction tracking should be the same for the both registers.
Just do it once and compare the result with multi regs as with the
previous patches. Then we don't need to call find_data_type_block()
separately for each reg. Let's remove the 'reg' argument from the
relevant functions.

Signed-off-by: Namhyung Kim <namhyung@xxxxxxxxxx>
---
tools/perf/util/annotate-data.c | 23 ++++++++++++-----------
1 file changed, 12 insertions(+), 11 deletions(-)

diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-data.c
index 245e3ef3e2ff..68fe7999f033 100644
--- a/tools/perf/util/annotate-data.c
+++ b/tools/perf/util/annotate-data.c
@@ -1258,11 +1258,12 @@ static void setup_stack_canary(struct data_loc_info *dloc)
* are similar to global variables and no additional info is needed.
*/
static int check_matching_type(struct type_state *state,
- struct data_loc_info *dloc, int reg,
+ struct data_loc_info *dloc,
Dwarf_Die *cu_die, Dwarf_Die *type_die)
{
Dwarf_Word size;
u32 insn_offset = dloc->ip - dloc->ms->sym->start;
+ int reg = dloc->op->reg1;

pr_debug_dtp("chk [%x] reg%d offset=%#x ok=%d kind=%d",
insn_offset, reg, dloc->op->offset,
@@ -1448,7 +1449,7 @@ static int check_matching_type(struct type_state *state,
}

/* Iterate instructions in basic blocks and update type table */
-static int find_data_type_insn(struct data_loc_info *dloc, int reg,
+static int find_data_type_insn(struct data_loc_info *dloc,
struct list_head *basic_blocks,
struct die_var_type *var_types,
Dwarf_Die *cu_die, Dwarf_Die *type_die)
@@ -1481,7 +1482,7 @@ static int find_data_type_insn(struct data_loc_info *dloc, int reg,
update_var_state(&state, dloc, addr, dl->al.offset, var_types);

if (this_ip == dloc->ip) {
- ret = check_matching_type(&state, dloc, reg,
+ ret = check_matching_type(&state, dloc,
cu_die, type_die);
goto out;
}
@@ -1502,7 +1503,7 @@ static int find_data_type_insn(struct data_loc_info *dloc, int reg,
* Construct a list of basic blocks for each scope with variables and try to find
* the data type by updating a type state table through instructions.
*/
-static int find_data_type_block(struct data_loc_info *dloc, int reg,
+static int find_data_type_block(struct data_loc_info *dloc,
Dwarf_Die *cu_die, Dwarf_Die *scopes,
int nr_scopes, Dwarf_Die *type_die)
{
@@ -1550,7 +1551,7 @@ static int find_data_type_block(struct data_loc_info *dloc, int reg,
fixup_var_address(var_types, start);

/* Find from start of this scope to the target instruction */
- found = find_data_type_insn(dloc, reg, &basic_blocks, var_types,
+ found = find_data_type_insn(dloc, &basic_blocks, var_types,
cu_die, type_die);
if (found > 0) {
char buf[64];
@@ -1716,8 +1717,13 @@ static int find_data_type_die(struct data_loc_info *dloc, Dwarf_Die *type_die)
goto out;
}

+ if (loc->multi_regs && reg == loc->reg1 && loc->reg1 != loc->reg2) {
+ reg = loc->reg2;
+ goto retry;
+ }
+
if (reg != DWARF_REG_PC) {
- ret = find_data_type_block(dloc, reg, &cu_die, scopes,
+ ret = find_data_type_block(dloc, &cu_die, scopes,
nr_scopes, type_die);
if (ret == 0) {
ann_data_stat.insn_track++;
@@ -1725,11 +1731,6 @@ static int find_data_type_die(struct data_loc_info *dloc, Dwarf_Die *type_die)
}
}

- if (loc->multi_regs && reg == loc->reg1 && loc->reg1 != loc->reg2) {
- reg = loc->reg2;
- goto retry;
- }
-
if (ret < 0) {
pr_debug_dtp("no variable found\n");
ann_data_stat.no_var++;
--
2.45.0.rc1.225.g2a3ae87e7f-goog