From patchwork Wed Nov 22 11:14:15 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxim Kuvyrkov X-Patchwork-Id: 746017 Delivered-To: patch@linaro.org Received: by 2002:a5d:6706:0:b0:32d:baff:b0ca with SMTP id o6csp239826wru; Wed, 22 Nov 2023 03:16:05 -0800 (PST) X-Google-Smtp-Source: AGHT+IHKzK04B1AU4XZdzER8QgeFOVKLcb0UKGZWrx04LM0YbXaTnQHl4EkfEg0KVUk7z1YB7u7u X-Received: by 2002:a05:6358:5284:b0:168:dd37:172d with SMTP id g4-20020a056358528400b00168dd37172dmr2050979rwa.20.1700651765206; Wed, 22 Nov 2023 03:16:05 -0800 (PST) ARC-Seal: i=2; a=rsa-sha256; t=1700651765; cv=pass; d=google.com; s=arc-20160816; b=gejRSiiqAU2l62EDhiDjuQs26bgwxogrzwZ6mXVacbRyXV0bGhBQ8bntowtlmzxO2E 1BeG5/JKu5CcQ48n79VLC9BZt8cUwagoTvqdz1KURIqGsIeWoqCbRf7VTlQsy19TdWKi uleZcCCW8D6WjyVRECRspQq+eyV+lL3rPRw6e90Mw2IRKmUcN1ftsSx2Cw3TkkJ/n/G4 efNG/ow822k2HsVVY6xq2B3tdWU+GTh6+ajLadkOm0FxUZsD9S4BwhCViGogGGifkyLw S1a52XngNjGu48DaE5LRN6xPrg17WWfwFJBCwVvYqmvCN8nVBYRNME2A9Z3g7n3xh2ES J0Kw== ARC-Message-Signature: i=2; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=errors-to:list-subscribe:list-help:list-post:list-archive :list-unsubscribe:list-id:precedence:content-transfer-encoding :mime-version:references:in-reply-to:message-id:date:subject:cc:to :from:dkim-signature:arc-filter:dmarc-filter:delivered-to; bh=/2q13E4r51XZH8OiSadDqo+qaM2cMIFU1eeD/lDAAXg=; fh=WFm8hI3He6vfed9bNVx/Tt8MS1NEGxq9c34GiEnOLuU=; b=ZRBF1k/ooIs/FSL3KJJyPX/50i9zQ8+1VW1/ieqOFK7gpT24k1luKKhdHH1wNDXp4B KHstQfM9doVxe9LQS0f3vQXPEXqC8pyOHIPJzWXsJNEhvp9mZlIKjquGlpSaWbb/EF4g /MpDkhTtDnyHjjpkC6tyM2fSsKH93YKAgxdggLRCRL2rUX5I62QqsBUtQzcjMqoKJkPo TdoYyYSYrqd9/YxQZJdhrA4p8sq4PkAKbvOk8gvceozQyfaiKOUlTx8pj3tr3JYFaPM7 Z/+aCV6/ZMb+CJkxUpEDPDFSphTMA08pFtwUlquChX4oODxNVKVTtSw3l+EDLDdINHoz EGjg== ARC-Authentication-Results: i=2; mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=tqYTBMva; arc=pass (i=1); spf=pass (google.com: domain of gcc-patches-bounces+patch=linaro.org@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+patch=linaro.org@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Return-Path: Received: from server2.sourceware.org (server2.sourceware.org. [8.43.85.97]) by mx.google.com with ESMTPS id f2-20020a05620a280200b00773fe581c18si11721413qkp.463.2023.11.22.03.16.04 for (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Nov 2023 03:16:05 -0800 (PST) Received-SPF: pass (google.com: domain of gcc-patches-bounces+patch=linaro.org@gcc.gnu.org designates 8.43.85.97 as permitted sender) client-ip=8.43.85.97; Authentication-Results: mx.google.com; dkim=pass header.i=@linaro.org header.s=google header.b=tqYTBMva; arc=pass (i=1); spf=pass (google.com: domain of gcc-patches-bounces+patch=linaro.org@gcc.gnu.org designates 8.43.85.97 as permitted sender) smtp.mailfrom="gcc-patches-bounces+patch=linaro.org@gcc.gnu.org"; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=linaro.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id C8F1D385C422 for ; Wed, 22 Nov 2023 11:16:04 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mail-lf1-x130.google.com (mail-lf1-x130.google.com [IPv6:2a00:1450:4864:20::130]) by sourceware.org (Postfix) with ESMTPS id 1835C3857C60 for ; Wed, 22 Nov 2023 11:15:08 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 1835C3857C60 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 1835C3857C60 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2a00:1450:4864:20::130 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1700651718; cv=none; b=jG8IQJ1qsne23OC81LHFI834/1gM3jRFySVKK5a52UtncZ+lv4ADE+UENLw2M3cdMM8L96qNgq62BqwJAT248W1JG1i0M6c6BVWcV46AJWd/uYg42M7aVtB0i5B0Dy6UUyX6lvhL2WPwvh4BlrR/V2HHNWx33PMDyHbFZOEhick= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1700651718; c=relaxed/simple; bh=nWpaDlOUd5tc0pQp/oeSeTfPwMPXerVZazc930uQSzA=; h=DKIM-Signature:From:To:Subject:Date:Message-Id:MIME-Version; b=qqQbt9Fdxd+0D3QqxxshWTf8yCXuPboLWhqq8gdiYqD26RbT4A3dsZsIsIsrVnWJN/sPrNa/o28DNfqdT5EZYbkGG7KgNLlO6tMZSX6azjpk118cw0668vxS6wZwaqBtdgFCpgQjNqtsWDaOAJheaCF3H5aGVY0SlBD+5WIuXEM= ARC-Authentication-Results: i=1; server2.sourceware.org Received: by mail-lf1-x130.google.com with SMTP id 2adb3069b0e04-507f63fcbf6so1637795e87.1 for ; Wed, 22 Nov 2023 03:15:08 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=linaro.org; s=google; t=1700651706; x=1701256506; darn=gcc.gnu.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=/2q13E4r51XZH8OiSadDqo+qaM2cMIFU1eeD/lDAAXg=; b=tqYTBMva+XkMDd6m8Ocpwkoah2QjcJdyZAUuKdjz4ILIDH/Y2ud1UUeaLND/97N9cc kLssCcV/5dyA6r+9N+PpEuqlBHkh/7Ci3xX0rUUBu+RiBRTqn6rdfiI13Sy6Z4mpFiLY kzglIANsWgvJyTH8yYOPlNBh3yGPZAzKQxujtOaAtEcDO2iCE1fXYpf7OtZfJUgVez3d e9GwWg/LjUEuZfvqBcaEeb97z0S0H1N+lkUOz94KqetIeeANU1Xb/f/w/m33bK7CirzF bEQRHjO4N+1j4TXLXOPU/oFayHpFG4IItAWvYq7R2CluVKKBy6/PIBw+4loBfMF+pZUb nNKQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1700651706; x=1701256506; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=/2q13E4r51XZH8OiSadDqo+qaM2cMIFU1eeD/lDAAXg=; b=Ww+ofovkdqjkkQtwO9y5gIAGBQvy7X59SygKoXv1cbNXOu4vmSLa5KljE9ZfxjUeP/ OfXc+Fn9MKuofSNz+C5/q9dHimOEJXljPZY5Nc1pBwNIt13+MTsIwKKeOofcUzZXC+lm nz5/UkrKAHKYeeV7gkTz3DyMnFJGlwIYsX0Fdsd7gRw/MRj1yNKpDMawcIgS3IuRaWiI pcLIF/1FuOpaj/4/Q2fLe7W/hGzuoSi+34vU9Sun7jSwZzcI+5X+2SiHoQ6rr9rgvNlN PA3BTLDfZAZKgQUlZIPnvs1EyLTfKBE5ioqcJfu7osm4r76DYX9cmQdQ5mDTSjpZ+bnL TvQQ== X-Gm-Message-State: AOJu0YyV5e0aAVkplltbYPu5CIK6JX7syHnP7+wvZBE+U/XjV3OnCQK3 3sO3yepFx1sLq4kGuVxl6xiUYe8ordEECsApLW2JQkU= X-Received: by 2002:a05:6512:3b22:b0:507:9d5c:62e3 with SMTP id f34-20020a0565123b2200b005079d5c62e3mr1412200lfv.5.1700651705736; Wed, 22 Nov 2023 03:15:05 -0800 (PST) Received: from localhost.localdomain (static.225.72.216.95.clients.your-server.de. [95.216.72.225]) by smtp.gmail.com with ESMTPSA id t13-20020a195f0d000000b0050919538b00sm1848553lfb.79.2023.11.22.03.15.04 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Wed, 22 Nov 2023 03:15:04 -0800 (PST) From: Maxim Kuvyrkov To: gcc-patches@gcc.gnu.org Cc: Maxim Kuvyrkov , Bernd Schmidt , Vladimir Makarov , Jeff Law , Alexander Monakov , Richard Guenther Subject: [PATCH v3 8/8] Improve logging of scheduler dependency analysis context Date: Wed, 22 Nov 2023 11:14:15 +0000 Message-Id: <20231122111415.815147-9-maxim.kuvyrkov@linaro.org> X-Mailer: git-send-email 2.34.1 In-Reply-To: <20231120120649.672893-1-maxim.kuvyrkov@linaro.org> References: <20231120120649.672893-1-maxim.kuvyrkov@linaro.org> MIME-Version: 1.0 X-Spam-Status: No, score=-12.0 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, 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 X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces+patch=linaro.org@gcc.gnu.org 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); }