From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mail-pl1-x635.google.com (mail-pl1-x635.google.com [IPv6:2607:f8b0:4864:20::635]) by sourceware.org (Postfix) with ESMTPS id 74D043858C54 for ; Mon, 15 Jan 2024 13:08:20 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 74D043858C54 Authentication-Results: sourceware.org; dmarc=pass (p=none dis=none) header.from=linaro.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=linaro.org ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 74D043858C54 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2607:f8b0:4864:20::635 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1705324111; cv=none; b=mO7gfsjh2qMX3a1BUan+gHia/ukZc8/bW0HCWZubNWOj4kPBi0kFYxAxqj8vdK4DwAhoWl1qu/xFeYdosqNuDpIlFIRi9hNPJqfOyq2tZ6Esj2KUeC8P10ZkouJFNlY7Hx3xFntEZk3Sw73ZtOWnmxPA6ZLqQPiyKQMeF8hTerU= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1705324111; c=relaxed/simple; bh=fprKGBo8gQQZN085GnV7hqrGYU9eQIQ1Hkoaq4Ip2K0=; h=DKIM-Signature:MIME-Version:From:Date:Message-ID:Subject:To; b=PQKLd7zXFtwnWM9w950gmk58yadQ33mISKNPenLX6sfDFGQJ4MsD9/fZwH9GZl0qgkVNAW4N1QoISQy95dVP1JnRoRrVbZhkgWDaJ3ObkonEFSCexGXInsrT7ASfJ3SMfFaI7Uek6KMdUfqY9n8w0jdH0FzCbqcbN6jc0I0Rffo= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-pl1-x635.google.com with SMTP id d9443c01a7336-1d5c0d58909so2157185ad.0 for ; Mon, 15 Jan 2024 05:08:20 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1705324098; x=1705928898; darn=gcc.gnu.org; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:from:to:cc:subject:date:message-id:reply-to; bh=VRS4gpGKdURhKaaK9Q2cI5oN7f3oONDFiwtewJbO4aM=; b=LIg9LamYZ5oJ/GU/BHaOc9fIVTA8xQ5oIK4/ieOBa6ORV6vPT78O1iDqKeZbIy8NNG O0cAL5N77a16/TP9Qsyz0OfXXgd+YqG2rKbG5FBMFZnbc7g/ABvGOSbAmcPJpY3Tz4Ng haXUmkZyctV8owAKIu02peuRsePgPgd7HRI9tybcwJITtMYzojlfeYkxJZIONbTGGZNw 1dcGmcR9MqgmZp+DflPsiq1hWTAXYZ8ZYJvUb41j0Ru5u5pzT4pHXOQr3L4QfLl9K/28 HAWd+YCgSQOcsrNS4GKY81ZmRSN++ZZnno8XSZFdG8hkACCjyIQrezIZO2FIEr00qMYY TjZA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1705324098; x=1705928898; h=cc:to:subject:message-id:date:from:in-reply-to:references :mime-version:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=VRS4gpGKdURhKaaK9Q2cI5oN7f3oONDFiwtewJbO4aM=; b=k4mq5oh5i4bG7ECB66KhE7OtkGdDL3yn+5XF+WUYxQkT8mpR5oXNmASeAzNf1zQ4mp M5qJEzLnVaUXqtx6L/ypZBSMeEDjfbcb2SV+oUxujidX53tAR1Ed102N2YGGFjVEQwJj M9AL8dyCUR6nC+Ap8zcUBn7z+6Ld3niGBErUsnw65soL8E+aVJ07Wb1swvhnL/AfEn2M JHrMZFvgFVsbvagEpITGQjCwzD+eQYaj+NP0G1Iycba7Bc/iJDrYTuSlm3oK3ZWodovM UBCY83PlQHGDIsKqenkO/ukuLfrlGnZI7WJQuFdBuxiiPWoKV0aKrA/QHr5iRGdbQ5Cm g5nQ== X-Gm-Message-State: AOJu0YxCIXDPmaswmaXI3PSOZKKs8ptFK0K2BQwD7jv4E02X24jDlNCL FT4h/cc8iHOy/Xv6/QCUTWhqKBncka3qgv6L7otqtAgcvX8gCtc58pFVZuBLkA== X-Google-Smtp-Source: AGHT+IGLm/R5dwG79/DptFAfB8XpeuQWLaPk+clcGOjRcw77jLWl0mLeHFGdAjpIQSvl+MR9cZ4S3rH0ch10Kzs8MUs= X-Received: by 2002:a17:90b:1e47:b0:28e:4761:cfff with SMTP id pi7-20020a17090b1e4700b0028e4761cfffmr3083454pjb.0.1705324098579; Mon, 15 Jan 2024 05:08:18 -0800 (PST) MIME-Version: 1.0 References: <20231120120649.672893-1-maxim.kuvyrkov@linaro.org> <20231122111415.815147-9-maxim.kuvyrkov@linaro.org> In-Reply-To: <20231122111415.815147-9-maxim.kuvyrkov@linaro.org> From: Maxim Kuvyrkov Date: Mon, 15 Jan 2024 17:08:07 +0400 Message-ID: Subject: Re: [PATCH v3 8/8] Improve logging of scheduler dependency analysis context To: gcc-patches@gcc.gnu.org Cc: Bernd Schmidt , Vladimir Makarov , Jeff Law , Alexander Monakov , Richard Guenther Content-Type: multipart/alternative; boundary="0000000000001f8706060efbb51e" X-Spam-Status: No, score=-9.5 required=5.0 tests=BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,GIT_PATCH_0,HTML_MESSAGE,RCVD_IN_DNSWL_NONE,SPF_HELO_NONE,SPF_PASS,TXREP,T_SCC_BODY_TEXT_LINE autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org List-Id: --0000000000001f8706060efbb51e Content-Type: text/plain; charset="UTF-8" Dear scheduler maintainers, Gentle ping. This patch improves debugging output, it does not touch scheduling logic. On Wed, 22 Nov 2023 at 15:15, Maxim Kuvyrkov wrote: > Scheduler dependency analysis uses two main data structures: > 1. reg_pending_* data contains effects of INSN on the register file, > which is then incorporated into ... > 2. deps_desc object, which contains commulative information about all > instructions processed from deps_desc object's initialization. > > This patch adds debug dumping of (2). > > Dependency analysis contexts (aka deps_desc objects) are huge, but > each instruction affects only a small amount of data in these objects. > Therefore, it is most useful to dump differential information > compared to the dependency state after previous instruction. > > gcc/ChangeLog: > > * sched-deps.cc (reset_deps, dump_rtx_insn_list) > (rtx_insn_list_same_p): New helper functions. > (dump_deps_desc_diff): New function to dump dependency information. > (sched_analysis_prev_deps): New static variable. > (sched_analyze_insn): Dump dependency information. > (init_deps_global, finish_deps_global): Handle > sched_analysis_prev_deps. > * sched-int.h (struct deps_reg): Update comments. > * sched-rgn.cc (concat_insn_list, concat_expr_list): Update > comments. > --- > gcc/sched-deps.cc | 197 ++++++++++++++++++++++++++++++++++++++++++++++ > gcc/sched-int.h | 9 ++- > gcc/sched-rgn.cc | 5 ++ > 3 files changed, 210 insertions(+), 1 deletion(-) > > diff --git a/gcc/sched-deps.cc b/gcc/sched-deps.cc > index f9290c82fd2..edca9927e23 100644 > --- a/gcc/sched-deps.cc > +++ b/gcc/sched-deps.cc > @@ -1677,6 +1677,15 @@ delete_all_dependences (rtx_insn *insn) > sd_delete_dep (sd_it); > } > > +/* Re-initialize existing dependency context DEPS to be a copy of FROM. > */ > +static void > +reset_deps (class deps_desc *deps, class deps_desc *from) > +{ > + free_deps (deps); > + init_deps (deps, false); > + deps_join (deps, from); > +} > + > /* All insns in a scheduling group except the first should only have > dependencies on the previous insn in the group. So we find the > first instruction in the scheduling group by walking the dependence > @@ -2960,6 +2969,177 @@ dump_reg_pending_data (FILE *file, rtx_insn *insn) > } > } > > +/* Dump rtx_insn_list LIST. > + Consider moving to lists.cc if there are users outside of > sched-deps.cc. */ > +static void > +dump_rtx_insn_list (FILE *file, rtx_insn_list *list) > +{ > + for (; list; list = list->next ()) > + fprintf (file, " %d", INSN_UID (list->insn ())); > +} > + > +/* Return TRUE if lists A and B have same elements in the same order. */ > +static bool > +rtx_insn_list_same_p (rtx_insn_list *a, rtx_insn_list *b) > +{ > + for (; a && b; a = a->next (), b = b->next ()) > + if (a->insn () != b->insn ()) > + return false; > + > + if (a || b) > + return false; > + > + return true; > +} > + > +/* Dump parts of DEPS that are different from PREV. > + Dumping all information from dependency context produces huge > + hard-to-analize logs; differential dumping is way more managable. */ > +static void > +dump_deps_desc_diff (FILE *file, class deps_desc *deps, class deps_desc > *prev) > +{ > + /* Each "paragraph" is a single line of output. */ > + > + /* Note on param_max_pending_list_length: > + During normal dependency analysis various lists should not exceed > this > + limit. Searching for "!!!" in scheduler logs can point to potential > bugs > + or poorly-handled corner-cases. */ > + > + if (!rtx_insn_list_same_p (deps->pending_read_insns, > + prev->pending_read_insns)) > + { > + fprintf (file, ";; deps pending mem reads length(%d):", > + deps->pending_read_list_length); > + if ((deps->pending_read_list_length + > deps->pending_write_list_length) > + >= param_max_pending_list_length) > + fprintf (file, "%d insns!!!", deps->pending_read_list_length); > + else > + dump_rtx_insn_list (file, deps->pending_read_insns); > + fprintf (file, "\n"); > + } > + > + if (!rtx_insn_list_same_p (deps->pending_write_insns, > + prev->pending_write_insns)) > + { > + fprintf (file, ";; deps pending mem writes length(%d):", > + deps->pending_write_list_length); > + if ((deps->pending_read_list_length + > deps->pending_write_list_length) > + >= param_max_pending_list_length) > + fprintf (file, "%d insns!!!", deps->pending_write_list_length); > + else > + dump_rtx_insn_list (file, deps->pending_write_insns); > + fprintf (file, "\n"); > + } > + > + if (!rtx_insn_list_same_p (deps->pending_jump_insns, > + prev->pending_jump_insns)) > + { > + fprintf (file, ";; deps pending jump length(%d):", > + deps->pending_flush_length); > + if (deps->pending_flush_length >= param_max_pending_list_length) > + fprintf (file, "%d insns!!!", deps->pending_flush_length); > + else > + dump_rtx_insn_list (file, deps->pending_jump_insns); > + fprintf (file, "\n"); > + } > + > + fprintf (file, ";; last"); > + if (!rtx_insn_list_same_p (deps->last_pending_memory_flush, > + prev->last_pending_memory_flush)) > + { > + fprintf (file, " memory_flush("); > + dump_rtx_insn_list (file, deps->last_pending_memory_flush); > + fprintf (file, ")"); > + } > + if (!rtx_insn_list_same_p (deps->last_function_call, > + prev->last_function_call)) > + { > + fprintf (file, " call("); > + dump_rtx_insn_list (file, deps->last_function_call); > + fprintf (file, ")"); > + } > + if (!rtx_insn_list_same_p (deps->last_function_call_may_noreturn, > + prev->last_function_call_may_noreturn)) > + { > + fprintf (file, " noreturn("); > + dump_rtx_insn_list (file, deps->last_function_call_may_noreturn); > + fprintf (file, ")"); > + } > + fprintf (file, "\n"); > + > + fprintf (file, ";; sched_before_next"); > + if (!rtx_insn_list_same_p (deps->sched_before_next_call, > + prev->sched_before_next_call)) > + { > + fprintf (file, " call("); > + dump_rtx_insn_list (file, deps->sched_before_next_call); > + fprintf (file, ")"); > + } > + if (!rtx_insn_list_same_p (deps->sched_before_next_jump, > + prev->sched_before_next_jump)) > + { > + fprintf (file, " jump("); > + dump_rtx_insn_list (file, deps->sched_before_next_jump); > + fprintf (file, ")"); > + } > + fprintf (file, " in_post_call_group_p(%d)\n", > deps->in_post_call_group_p); > + > + fprintf (file, ";; last_debug_insn(%d) last_args_size(%d) > last_prologue(", > + deps->last_debug_insn ? INSN_UID (deps->last_debug_insn) : -1, > + deps->last_args_size ? INSN_UID (deps->last_args_size) : -1); > + dump_rtx_insn_list (file, deps->last_prologue); > + fprintf (file, ") last_epilogue("); > + dump_rtx_insn_list (file, deps->last_epilogue); > + fprintf (file, ") last_logue_was_epilogue(%d)\n", > + deps->last_logue_was_epilogue); > + > + int i; > + > + gcc_assert (deps->max_reg == prev->max_reg); > + for (i = 0; i < deps->max_reg; ++i) > + { > + struct deps_reg *reg_last = &deps->reg_last[i]; > + struct deps_reg *reg_prev = &prev->reg_last[i]; > + > + if (rtx_insn_list_same_p (reg_last->uses, reg_prev->uses) > + && rtx_insn_list_same_p (reg_last->sets, reg_prev->sets) > + && rtx_insn_list_same_p (reg_last->implicit_sets, > + reg_prev->implicit_sets) > + && rtx_insn_list_same_p (reg_last->control_uses, > + reg_prev->control_uses) > + && rtx_insn_list_same_p (reg_last->clobbers, > + reg_prev->clobbers)) > + continue; > + > + fprintf (file, ";; reg %u: uses(", i); > + if (reg_last->uses_length >= param_max_pending_list_length) > + fprintf (file, "%d insns!!!", reg_last->uses_length); > + else > + dump_rtx_insn_list (file, reg_last->uses); > + if (reg_last->clobbers_length >= param_max_pending_list_length) > + { > + fprintf (file, ") clobbers("); > + fprintf (file, "%d insns!!!", reg_last->clobbers_length); > + } > + else > + { > + fprintf (file, ") sets("); > + dump_rtx_insn_list (file, reg_last->sets); > + fprintf (file, ") implicit_sets("); > + dump_rtx_insn_list (file, reg_last->implicit_sets); > + fprintf (file, ") control_uses("); > + dump_rtx_insn_list (file, reg_last->control_uses); > + fprintf (file, ") clobbers("); > + dump_rtx_insn_list (file, reg_last->clobbers); > + } > + fprintf (file, ")\n"); > + } > +} > + > +/* Dependency analysis state before current insn. > + Used by dump_deps_desc_diff(). */ > +static class deps_desc *sched_analysis_prev_deps; > + > /* Analyze an INSN with pattern X to find all dependencies. > This analysis uses two main data structures: > 1. reg_pending_* data contains effects of INSN on the register file, > @@ -3627,6 +3807,16 @@ sched_analyze_insn (class deps_desc *deps, rtx x, > rtx_insn *insn) > deps->last_logue_was_epilogue = true; > } > } > + > + if (sched_verbose >= 8) > + { > + dump_deps_desc_diff (sched_dump, deps, sched_analysis_prev_deps); > + reset_deps (sched_analysis_prev_deps, deps); > + fprintf (sched_dump, ";; "); > + dump_lists (sched_dump, insn, SD_LIST_BACK, > + DUMP_LISTS_ALL | DUMP_DEP_PRO); > + fprintf (sched_dump, "\n"); > + } > } > > /* Return TRUE if INSN might not always return normally (e.g. call exit, > @@ -4305,6 +4495,9 @@ init_deps_global (void) > sched_deps_info->note_mem_dep = haifa_note_mem_dep; > sched_deps_info->note_dep = haifa_note_dep; > } > + > + sched_analysis_prev_deps = XNEW (class deps_desc); > + init_deps (sched_analysis_prev_deps, false); > } > > /* Free everything used by the dependency analysis code. */ > @@ -4316,6 +4509,10 @@ finish_deps_global (void) > FREE_REG_SET (reg_pending_clobbers); > FREE_REG_SET (reg_pending_uses); > FREE_REG_SET (reg_pending_control_uses); > + > + free_deps (sched_analysis_prev_deps); > + free (sched_analysis_prev_deps); > + sched_analysis_prev_deps = NULL; > } > > /* Estimate the weakness of dependence between MEM1 and MEM2. */ > diff --git a/gcc/sched-int.h b/gcc/sched-int.h > index 64a2f0bcff9..8a3109ce86e 100644 > --- a/gcc/sched-int.h > +++ b/gcc/sched-int.h > @@ -455,7 +455,9 @@ struct deps_reg > int clobbers_length; > }; > > -/* Describe state of dependencies used during sched_analyze phase. */ > +/* Describe state of dependencies used during sched_analyze phase. > + Please consider updating sched-deps.cc:dump_deps_desc_diff() when > adding > + new fields. */ > class deps_desc > { > public: > @@ -499,6 +501,11 @@ public: > large lists. */ > int pending_flush_length; > > + /* Below are lists (and not just a single instructions) to allow > inter-block > + dependency analysis. Each block > + may add a single insn to below lists, but when merging dependency > + analysis context from multiple predecessor blocks, we may get a > list. */ > + > /* The last insn upon which all memory references must depend. > This is an insn which flushed the pending lists, creating a > dependency > between it and all previously pending memory references. This > creates > diff --git a/gcc/sched-rgn.cc b/gcc/sched-rgn.cc > index da3ec0458ff..72f0a2de66e 100644 > --- a/gcc/sched-rgn.cc > +++ b/gcc/sched-rgn.cc > @@ -2590,6 +2590,10 @@ static rtx_insn_list * > concat_insn_list (rtx_insn_list *copy, rtx_insn_list *old) > { > if (!old) > + /* concat_*_LIST() will return a reversed copy of COPY. Working with > + reversed copies would complicate dependency dumping in > + dump_deps_desc_diff(), which internally uses reset_deps() and > + deps_join(). Therefore, use copy_INSN_LIST() when OLD is NULL. */ > return copy_INSN_LIST (copy); > return concat_INSN_LIST (copy, old); > } > @@ -2599,6 +2603,7 @@ static rtx_expr_list * > concat_expr_list (rtx_expr_list *copy, rtx_expr_list *old) > { > if (!old) > + /* See comment in concat_insn_list() above. */ > return copy_EXPR_LIST (copy); > return concat_EXPR_LIST (copy, old); > } > -- > 2.34.1 > > -- Maxim Kuvyrkov www.linaro.org --0000000000001f8706060efbb51e--