Received: by 2002:ab2:620c:0:b0:1ef:ffd0:ce49 with SMTP id o12csp899721lqt; Tue, 19 Mar 2024 07:14:31 -0700 (PDT) X-Forwarded-Encrypted: i=3; AJvYcCU/haxZ/vVYepWuKGFIelDF15bPQ27GfNjdU+BQ++S0btXSMK1sSav2Rum/lOnNNjbo/191SA+GgDnO1nyCJLABbL19626q8kLPU84ACg== X-Google-Smtp-Source: AGHT+IH4EEy86a5wxx4Qnc7Ulusb208NsOhJp3UoS0gsnt9RVJ5dfqFBwPoq7otXCWRbspXe5yBg X-Received: by 2002:a05:6a20:bf0f:b0:1a3:6d94:d2f1 with SMTP id gc15-20020a056a20bf0f00b001a36d94d2f1mr2346889pzb.58.1710857670832; Tue, 19 Mar 2024 07:14:30 -0700 (PDT) ARC-Seal: i=2; a=rsa-sha256; t=1710857670; cv=pass; d=google.com; s=arc-20160816; b=0aap1PV42yZB+UDT40+pGAKgH1BHszKINxCrilGhLFc+xUuEfli0XKN7z5OWSKyno8 JDi3pcuMLgq5jz5mf8JSnPbApvT3z1jcTICGQl5ifJvbZKHnEt+X3seK0bX93QbBAQ5p OnIBssk1FRmA4DmEDvAb4YQJS7Rp/S+qdukzAxEtPld8M4emlRioeGMJxuGncecySocw x5f+YQxn0xb8KW7Z61mEpLglX/y4agjF9mpvgjYkUc5UNbAJTURNY/DPTSZ+1zzzsubh d9aFbrLnBOeWS5SsFksMBIUkfgQpGUdUP0BvxQQndGyBVdPkjHRHzOwXYYQftHyMbCCC ydhQ== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=in-reply-to:content-disposition:mime-version:list-unsubscribe :list-subscribe:list-id:precedence:references:message-id:subject:cc :to:from:date:dkim-signature; bh=UIPcdKbynZKz316pAXpfkX7EUlk1ghMAdjUad/1FV+s=; fh=W3KJ4rXcu85ubgqT2134A/cdx6WzcKhVk/3nUKtpIrQ=; b=WqVXpc3QR4ilWMtYoifY8RMuiEPPCsqq7zeZWCyYek4Nl+ZpXptVVampYs94HJ4pMR 2qNYsAbrM4ZOkSVgmV+EIO83VhSeSJrT5qCU/OS+f2Wz+1IwP46Ym89RjJjkSXgQYiw8 Dk9Qs1C5VW4/R7tOa1EMHVIlFyAkf2y2x/mXtxvKPlSaFSMOjQhzIhe74g7J9JQA6f2Q Vg9WuFsRGmGf1sY3mNVz6FGawGafy/hwtfh6MD15ELlW8I64xg0TcZQHZ1zuvbsJrsFv hFTJDPS6PbIGa81nCHA+LWpRb61ve1f1ONfOYC4sQ89PvkdDFmoXIzuOSjEyNGaXW7Ei 7khQ==; dara=google.com ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=FSjdOEtu; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-107626-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-107626-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Return-Path: Received: from sy.mirrors.kernel.org (sy.mirrors.kernel.org. [147.75.48.161]) by mx.google.com with ESMTPS id o18-20020a634e52000000b005d8bb714e7csi10161682pgl.593.2024.03.19.07.14.30 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Tue, 19 Mar 2024 07:14:30 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel+bounces-107626-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) client-ip=147.75.48.161; Authentication-Results: mx.google.com; dkim=pass header.i=@kernel.org header.s=k20201202 header.b=FSjdOEtu; arc=pass (i=1 dkim=pass dkdomain=kernel.org); spf=pass (google.com: domain of linux-kernel+bounces-107626-linux.lists.archive=gmail.com@vger.kernel.org designates 147.75.48.161 as permitted sender) smtp.mailfrom="linux-kernel+bounces-107626-linux.lists.archive=gmail.com@vger.kernel.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=kernel.org Received: from smtp.subspace.kernel.org (wormhole.subspace.kernel.org [52.25.139.140]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by sy.mirrors.kernel.org (Postfix) with ESMTPS id 75EF2B22D17 for ; Tue, 19 Mar 2024 14:08:05 +0000 (UTC) Received: from localhost.localdomain (localhost.localdomain [127.0.0.1]) by smtp.subspace.kernel.org (Postfix) with ESMTP id 8172B8174F; Tue, 19 Mar 2024 14:07:56 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b="FSjdOEtu" Received: from smtp.kernel.org (aws-us-west-2-korg-mail-1.web.codeaurora.org [10.30.226.201]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 71EF77D3EA; Tue, 19 Mar 2024 14:07:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=10.30.226.201 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710857275; cv=none; b=MBar7SOZHA46ibikv/HY7XI/uUCcKIskSnrSzZ2vjL7jBGsriy1FVqxCNye7BoNElN5M9u7Epfn2DOU8WBK92/UJF5i7MTBswA9KEwtsHkezct1lekW0n2YkGm07jNI7HUR7tilnZA4YGzHRGLVFOJV8x79C3lwNzYzQAlvsBFw= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1710857275; c=relaxed/simple; bh=whjopwoEzBnJ3lAqV1OpmOuPzXIKKn5zyX9NmUxF5w4=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=o9vbpwgl8qEbxqKpy1Em1r7FwciNF//pIpuGSuQbwzTpEX9zumQOhNhw98wAQVRjP1iGeJeObse1q9ZUwoXdociHoRtToVWc2AqWyxyiSNp7HiuYx7KLVnrkdaGpS/lYwGYTqfaqifv2jxBhrvgqInJ2lb2OgNnLGYXsdMhomOw= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=kernel.org header.i=@kernel.org header.b=FSjdOEtu; arc=none smtp.client-ip=10.30.226.201 Received: by smtp.kernel.org (Postfix) with ESMTPSA id 81FEBC433C7; Tue, 19 Mar 2024 14:07:54 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=kernel.org; s=k20201202; t=1710857275; bh=whjopwoEzBnJ3lAqV1OpmOuPzXIKKn5zyX9NmUxF5w4=; h=Date:From:To:Cc:Subject:References:In-Reply-To:From; b=FSjdOEtuVHIs0UCv9gZbt8h18f+vzZ89f4GQ2HB1CLYD50uZtOyI1bEz8fFvBNd5d Tc8Khc7R7ppY2KhabW+kwWfns6HlQ5qKaxUcwUR+zPQzhw1ZeTy+pfAAgTn/2zPBvj wlBHG2EdL7aUP/aev380jgFZJzT9ooWqWtn512E53SzPnw48pepCjfZ9+Eu42COzCX E8pQpFE8zZFTc1BTiRYla3WjSMBKRs/FxLtGotyyz6n1KnORGGsJOAUPRQ/baDjoOh BVNR2HYJ81pDBTZ7VeC4LHuholoVJRKE2yOQ3o1XQhNXDp8y4Nq/8zExNXhC4srfWs vjLk1eCMSR94g== Date: Tue, 19 Mar 2024 11:07:51 -0300 From: Arnaldo Carvalho de Melo To: Namhyung Kim Cc: Ian Rogers , Jiri Olsa , Adrian Hunter , Peter Zijlstra , Ingo Molnar , LKML , linux-perf-users@vger.kernel.org, Linus Torvalds , Stephane Eranian , Masami Hiramatsu , linux-toolchains@vger.kernel.org, linux-trace-devel@vger.kernel.org Subject: Re: [PATCH 09/23] perf annotate-data: Maintain variable type info Message-ID: References: <20240319055115.4063940-1-namhyung@kernel.org> <20240319055115.4063940-10-namhyung@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline In-Reply-To: <20240319055115.4063940-10-namhyung@kernel.org> On Mon, Mar 18, 2024 at 10:51:01PM -0700, Namhyung Kim wrote: > As it collected basic block and variable information in each scope, it > now can build a state table to find matching variable at the location. > > The struct type_state is to keep the type info saved in each register > and stack slot. The update_var_state() updates the table when it finds > variables in the current address. It expects die_collect_vars() filled > a list of variables with type info and starting address. > > Signed-off-by: Namhyung Kim > --- > tools/perf/util/annotate-data.c | 173 ++++++++++++++++++++++++++++++++ > tools/perf/util/dwarf-aux.c | 4 + > 2 files changed, 177 insertions(+) > > diff --git a/tools/perf/util/annotate-data.c b/tools/perf/util/annotate-data.c > index f482ccfdaa91..8eaa06f1cee5 100644 > --- a/tools/perf/util/annotate-data.c > +++ b/tools/perf/util/annotate-data.c > @@ -46,6 +46,62 @@ static void pr_debug_type_name(Dwarf_Die *die) > free(str); > } > > +/* Type information in a register, valid when ok is true */ > +struct type_state_reg { > + Dwarf_Die type; > + bool ok; > +}; > + > +/* Type information in a stack location, dynamically allocated */ > +struct type_state_stack { > + struct list_head list; > + Dwarf_Die type; > + int offset; > + int size; > + bool compound; > +}; > + > +/* FIXME: This should be arch-dependent */ > +#define TYPE_STATE_MAX_REGS 16 > + > +/* > + * State table to maintain type info in each register and stack location. > + * It'll be updated when new variable is allocated or type info is moved > + * to a new location (register or stack). As it'd be used with the > + * shortest path of basic blocks, it only maintains a single table. > + */ > +struct type_state { > + struct type_state_reg regs[TYPE_STATE_MAX_REGS]; > + struct list_head stack_vars; > +}; > + > +static bool has_reg_type(struct type_state *state, int reg) > +{ > + return (unsigned)reg < ARRAY_SIZE(state->regs); > +} > + > +/* These declarations will be remove once they are changed to static */ > +void init_type_state(struct type_state *state, struct arch *arch __maybe_unused); > +void exit_type_state(struct type_state *state); > +void update_var_state(struct type_state *state, struct data_loc_info *dloc, > + u64 addr, u64 insn_offset, struct die_var_type *var_types); > + > +void init_type_state(struct type_state *state, struct arch *arch __maybe_unused) > +{ > + memset(state, 0, sizeof(*state)); > + INIT_LIST_HEAD(&state->stack_vars); > +} > + > +void exit_type_state(struct type_state *state) > +{ > + struct type_state_stack *stack, *tmp; > + > + list_for_each_entry_safe(stack, tmp, &state->stack_vars, list) { > + list_del(&stack->list); list_del_init()? > + free(stack); > + } > +} > + > /* > * Compare type name and size to maintain them in a tree. > * I'm not sure if DWARF would have information of a single type in many > @@ -262,6 +318,123 @@ static int check_variable(Dwarf_Die *var_die, Dwarf_Die *type_die, int offset, > return 0; > } > > +static struct type_state_stack *find_stack_state(struct type_state *state, > + int offset) > +{ > + struct type_state_stack *stack; > + > + list_for_each_entry(stack, &state->stack_vars, list) { > + if (offset == stack->offset) > + return stack; > + > + if (stack->compound && stack->offset < offset && > + offset < stack->offset + stack->size) > + return stack; > + } > + return NULL; > +} > + > +static void set_stack_state(struct type_state_stack *stack, int offset, > + Dwarf_Die *type_die) > +{ > + int tag; > + Dwarf_Word size; > + > + if (dwarf_aggregate_size(type_die, &size) < 0) > + size = 0; > + > + tag = dwarf_tag(type_die); > + > + stack->type = *type_die; > + stack->size = size; > + stack->offset = offset; > + > + switch (tag) { > + case DW_TAG_structure_type: > + case DW_TAG_union_type: > + stack->compound = true; > + break; > + default: > + stack->compound = false; > + break; > + } > +} > + > +static struct type_state_stack *findnew_stack_state(struct type_state *state, > + int offset, Dwarf_Die *type_die) > +{ > + struct type_state_stack *stack = find_stack_state(state, offset); > + > + if (stack) { > + set_stack_state(stack, offset, type_die); > + return stack; > + } > + > + stack = malloc(sizeof(*stack)); > + if (stack) { > + set_stack_state(stack, offset, type_die); > + list_add(&stack->list, &state->stack_vars); > + } > + return stack; > +} > + > +/** > + * update_var_state - Update type state using given variables > + * @state: type state table > + * @dloc: data location info > + * @addr: instruction address to match with variable > + * @insn_offset: instruction offset (for debug) > + * @var_types: list of variables with type info > + * > + * This function fills the @state table using @var_types info. Each variable > + * is used only at the given location and updates an entry in the table. > + */ > +void update_var_state(struct type_state *state, struct data_loc_info *dloc, > + u64 addr, u64 insn_offset, struct die_var_type *var_types) > +{ > + Dwarf_Die mem_die; > + struct die_var_type *var; > + int fbreg = dloc->fbreg; > + int fb_offset = 0; > + > + if (dloc->fb_cfa) { > + if (die_get_cfa(dloc->di->dbg, addr, &fbreg, &fb_offset) < 0) > + fbreg = -1; > + } > + > + for (var = var_types; var != NULL; var = var->next) { > + if (var->addr != addr) > + continue; > + /* Get the type DIE using the offset */ > + if (!dwarf_offdie(dloc->di->dbg, var->die_off, &mem_die)) > + continue; > + > + if (var->reg == DWARF_REG_FB) { > + findnew_stack_state(state, var->offset, &mem_die); > + > + pr_debug_dtp("var [%"PRIx64"] -%#x(stack) type=", > + insn_offset, -var->offset); > + pr_debug_type_name(&mem_die); > + } else if (var->reg == fbreg) { > + findnew_stack_state(state, var->offset - fb_offset, &mem_die); > + > + pr_debug_dtp("var [%"PRIx64"] -%#x(stack) type=", > + insn_offset, -var->offset + fb_offset); > + pr_debug_type_name(&mem_die); > + } else if (has_reg_type(state, var->reg) && var->offset == 0) { > + struct type_state_reg *reg; > + > + reg = &state->regs[var->reg]; > + reg->type = mem_die; > + reg->ok = true; > + > + pr_debug_dtp("var [%"PRIx64"] reg%d type=", > + insn_offset, var->reg); > + pr_debug_type_name(&mem_die); > + } > + } > +} > + > /* The result will be saved in @type_die */ > static int find_data_type_die(struct data_loc_info *dloc, Dwarf_Die *type_die) > { > diff --git a/tools/perf/util/dwarf-aux.c b/tools/perf/util/dwarf-aux.c > index 9080119a258c..41dbbb25b256 100644 > --- a/tools/perf/util/dwarf-aux.c > +++ b/tools/perf/util/dwarf-aux.c > @@ -9,6 +9,7 @@ > #include > #include "debug.h" > #include "dwarf-aux.h" > +#include "dwarf-regs.h" > #include "strbuf.h" > #include "string2.h" > > @@ -1190,6 +1191,8 @@ static int reg_from_dwarf_op(Dwarf_Op *op) > case DW_OP_regx: > case DW_OP_bregx: > return op->number; > + case DW_OP_fbreg: > + return DWARF_REG_FB; > default: > break; > } > @@ -1203,6 +1206,7 @@ static int offset_from_dwarf_op(Dwarf_Op *op) > case DW_OP_regx: > return 0; > case DW_OP_breg0 ... DW_OP_breg31: > + case DW_OP_fbreg: > return op->number; > case DW_OP_bregx: > return op->number2; > -- > 2.44.0.291.gc1ea87d7ee-goog