From patchwork Wed Sep 18 20:36:12 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Arsen_Arsenovi=C4=87?= X-Patchwork-Id: 1986996 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@legolas.ozlabs.org Authentication-Results: legolas.ozlabs.org; dkim=pass (2048-bit key; unprotected) header.d=aarsen.me header.i=@aarsen.me header.a=rsa-sha256 header.s=MBO0001 header.b=bWW3iAA6; dkim-atps=neutral Authentication-Results: legolas.ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=2620:52:3:1:0:246e:9693:128c; helo=server2.sourceware.org; envelope-from=gcc-patches-bounces~incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=patchwork.ozlabs.org) Received: from server2.sourceware.org (server2.sourceware.org [IPv6:2620:52:3:1:0:246e:9693:128c]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (secp384r1) server-digest SHA384) (No client certificate requested) by legolas.ozlabs.org (Postfix) with ESMTPS id 4X8B1n10gZz1y2q for ; Thu, 19 Sep 2024 07:02:52 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id B00F8385C6C1 for ; Wed, 18 Sep 2024 21:02:50 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from mout-p-202.mailbox.org (mout-p-202.mailbox.org [IPv6:2001:67c:2050:0:465::202]) by sourceware.org (Postfix) with ESMTPS id 7CF83385842A for ; Wed, 18 Sep 2024 21:02:27 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 7CF83385842A Authentication-Results: sourceware.org; dmarc=pass (p=reject dis=none) header.from=aarsen.me Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=aarsen.me ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 7CF83385842A Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=2001:67c:2050:0:465::202 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1726693350; cv=none; b=MTckxWYjSR8JO8tpqez8yxxZ8MUz1vVd0XgZz7nRRFi7SWGkzkBMSEtsDbi3Y1YuWGh891jjXtkyBmBId5chiO4krxB8FZWZT5RLOHTNlUi939wweDEa+7/47Q7QTsMZYh5RywiZDLckxhVmNEQATV4+Y1xqwVHXM70Odgs6hYM= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1726693350; c=relaxed/simple; bh=j2mBA3KgTQOJBZlGj7hz2cf3BmU5eAyUcmRw1jpudJI=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=Qqr8QYSu0NHArWxqyDD2qwVIsOXRC2TiZfnrJ1PU9eBy5/a7ydCEMGt7VUlyc74cj/qgk8KLHkX/gJEkWu1lWUVfYXC754tMlYKlt1hwxaLjp05GrfggXpx99n8v2rOiAz+Qu8UQ51PzWsAFw7B8la2dhBM2TO8+b5w5DlKW93Q= ARC-Authentication-Results: i=1; server2.sourceware.org Received: from smtp202.mailbox.org (smtp202.mailbox.org [10.196.197.202]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by mout-p-202.mailbox.org (Postfix) with ESMTPS id 4X8B1D48m3z9sFB; Wed, 18 Sep 2024 23:02:24 +0200 (CEST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aarsen.me; s=MBO0001; t=1726693344; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=nUh+0soduOtNs1MyUjFA2UCqFahWYGJba24BqtcaFnQ=; b=bWW3iAA625pPX/jPX9OQ/JwjiNsQg9o2uHSEYNfjYX5eCu4nBQY5APhKSfZhdrlPZ7QidC nj/NuvgFkDG7l6O8fF2KzssZX5v+WI7pv+0cLZPrDdHQZJCTJkKWG0ALA56x7sCl5/g32E uzSrNSUksGN4oBYNLyuXVk4SzASHp1V69vFgFB9WuzhzBF5BWv8TJ21lVQr5jPqSb8GoYU RGcPUTYKWXLOjltpKS08hSWZkAo4nDrm5j7V/B7idKduo1GRCwo8zus1N7jLYEH0uq8Udp R3SOKYV0Xyhp8zsGtnbxFyfd38m4yEF98utQpeggZDkpYCzC/X2oyeJ9zriDTg== From: =?utf-8?q?Arsen_Arsenovi=C4=87?= To: Jason Merrill Cc: gcc-patches@gcc.gnu.org, Iain Sandoe , Jonathan Wakely , =?utf-8?q?Arsen_Arsenovi=C4=87?= Subject: [PATCH 1/2] c++: Implement a coroutine language debug dump Date: Wed, 18 Sep 2024 22:36:12 +0200 Message-ID: <20240918210202.192478-2-arsen@aarsen.me> In-Reply-To: <20240918210202.192478-1-arsen@aarsen.me> References: <20240918210202.192478-1-arsen@aarsen.me> MIME-Version: 1.0 X-Spam-Status: No, score=-10.9 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, KAM_INFOUSMEBIZ, RCVD_IN_DNSWL_LOW, SPF_HELO_NONE, SPF_PASS, TXREP 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~incoming=patchwork.ozlabs.org@gcc.gnu.org This provides to people working on coroutines, as well as writing tests for coroutines, a way to have insight into the results and inputs of the coroutine transformation passes, which is quite essential to understanding what happens in the coroutine transformation. Currently, the information dumped is the pre-transform function (which is not otherwise available), the generated ramp function, the generated frame type, the transformed actor/resumer, and the destroyer stub. While debugging this, I've also encountered a minor bug in c-pretty-print.cc, where it tried to check DECL_REGISTER of DECLs that did not support it. I've added a check for that. Similary, I found one in pp_cxx_template_parameter, where TREE_TYPE was called on the list cell the template parameter was in rather than on the parameter itself. I've fixed that. And, lastly, there appeared to be no way to pretty-print a FIELD_DECL, so I added support to cxx_pretty_printer::declaration for it (by reusing the VAR_DECL path). Co-authored-by: Iain Sandoe gcc/c-family/ChangeLog: * c-pretty-print.cc (c_pretty_printer::storage_class_specifier): Check that we're looking at a PARM_DECL or VAR_DECL before looking at DECL_REGISTER. gcc/cp/ChangeLog: * coroutines.cc (dump_record_fields): New helper. Iterates a RECORD_TYPEs TYPE_FIELDS and pretty-prints them. (dmp_str): New. The lang-coro dump stream. (coro_dump_id): New. ID of the lang-coro dump. (coro_dump_flags): New. Flags passed to the lang-coro dump. (coro_maybe_dump_initial_function): New helper. Prints, if dumping is enabled, the fndecl passed to it as the original function. (coro_maybe_dump_ramp): New. Prints the ramp function passed to it, if dumping is enabled. (coro_maybe_dump_transformed_functions): New. Prints the actor and destroy functions passed to it, if dumping is enabled, as well as the frame type (inferred from the actor argument). (cp_coroutine_transform::apply_transforms): Initialize the lang-coro dump. Call coro_maybe_dump_initial_function on the original function, as well as coro_maybe_dump_ramp, after the transformation into the ramp is finished. (cp_coroutine_transform::finish_transforms): Call coro_maybe_dump_transformed_functions on the built actor and destroy. * cp-objcp-common.cc (cp_register_dumps): Register the coroutine dump. * cp-tree.h (coro_dump_id): Declare as extern. * cxx-pretty-print.cc (pp_cxx_template_parameter): Don't call TREE_TYPE on a TREE_LIST cell. (cxx_pretty_printer::declaration): Handle FIELD_DECL similar to VAR_DECL. gcc/ChangeLog: * dumpfile.cc (FIRST_ME_AUTO_NUMBERED_DUMP): Bump to 6 for sake of the coroutine dump. --- gcc/c-family/c-pretty-print.cc | 3 +- gcc/cp/coroutines.cc | 116 +++++++++++++++++++++++++++++++++ gcc/cp/cp-objcp-common.cc | 2 + gcc/cp/cp-tree.h | 1 + gcc/cp/cxx-pretty-print.cc | 3 +- gcc/dumpfile.cc | 2 +- 6 files changed, 124 insertions(+), 3 deletions(-) diff --git a/gcc/c-family/c-pretty-print.cc b/gcc/c-family/c-pretty-print.cc index 26038818d759..9be0154af7ac 100644 --- a/gcc/c-family/c-pretty-print.cc +++ b/gcc/c-family/c-pretty-print.cc @@ -748,7 +748,8 @@ c_pretty_printer::storage_class_specifier (tree t) pp_c_ws_string (this, "typedef"); else if (DECL_P (t)) { - if (DECL_REGISTER (t)) + if ((TREE_CODE (t) == PARM_DECL || VAR_P (t)) + && DECL_REGISTER (t)) pp_c_ws_string (this, "register"); else if (TREE_STATIC (t) && VAR_P (t)) pp_c_ws_string (this, "static"); diff --git a/gcc/cp/coroutines.cc b/gcc/cp/coroutines.cc index a3edaa842d9d..416202ed3e88 100644 --- a/gcc/cp/coroutines.cc +++ b/gcc/cp/coroutines.cc @@ -34,6 +34,115 @@ along with GCC; see the file COPYING3. If not see #include "hash-map.h" #include "coroutines.h" +/* ================= Debug. ================= */ + +#include "langhooks.h" +#include "cxx-pretty-print.h" + +static void +dump_record_fields (cxx_pretty_printer *pp, tree typ) +{ + pp->type_id (typ); + pp_newline_and_indent (pp, 2); + pp_left_brace (pp); + pp_indentation (pp) += 2; + + /* We'll be on a new line, we don't need padding. */ + pp->set_padding (pp_none); + + for (tree tmp = TYPE_FIELDS (typ); tmp; tmp = DECL_CHAIN (tmp)) + { + pp_newline_and_indent (pp, 0); + pp->declaration (tmp); + } + + pp_newline_and_indent (pp, -2); + pp_right_brace (pp); + pp_newline_and_indent (pp, -2); +} + +static FILE *dmp_str = NULL; +int coro_dump_id; +static dump_flags_t coro_dump_flags; + +/* Pretty print the function FNDECL, which ought to be a coroutine before + co_await expansion, into the lang-coro dump, if it is enabled. */ + +static void +coro_maybe_dump_initial_function (tree fndecl) +{ + if (!dmp_str) + return; + + bool lambda_p = LAMBDA_TYPE_P (DECL_CONTEXT (fndecl)); + fprintf (dmp_str, "%s %s original:\n", + (lambda_p ? "Lambda" : "Function"), + lang_hooks.decl_printable_name (fndecl, 2)); + + cxx_pretty_printer pp; + pp.set_output_stream (dmp_str); + pp.flags = coro_dump_flags; + pp.declaration (fndecl); + pp_newline_and_flush (&pp); +} + +/* Pretty print the RAMP function to the lang-coro dump, if it is enabled. */ + +static void +coro_maybe_dump_ramp (tree ramp) +{ + if (!dmp_str) + return; + + cxx_pretty_printer pp; + pp.set_output_stream (dmp_str); + pp.flags = coro_dump_flags; + + pp_string (&pp, "Ramp function:"); + pp_newline_and_indent (&pp, 0); + pp.declaration (ramp); + pp_newline_and_flush (&pp); +} + +/* For a given ACTOR, DESTROY and FRAME_TYPE, if lang-coro dumping is enabled, + pretty-print their contents to the lang-coro dump. */ + +static void +coro_maybe_dump_transformed_functions (tree actor, tree destroy) +{ + if (!dmp_str) + return; + + cxx_pretty_printer pp; + pp.set_output_stream (dmp_str); + pp.flags = coro_dump_flags; + + if (!actor || actor == error_mark_node) + { + pp_string (&pp, "Transform failed"); + pp_newline_and_flush (&pp); + return; + } + + tree frame = TREE_TYPE (TREE_TYPE (DECL_ARGUMENTS (actor))); + pp_string (&pp, "Frame type:"); + pp_newline (&pp); + dump_record_fields (&pp, frame); + pp_newline_and_flush (&pp); + + pp_string (&pp, "Actor/resumer:"); + pp_newline (&pp); + pp.declaration (actor); + pp_newline_and_flush (&pp); + + pp_string (&pp, "Destroyer:"); + pp_newline (&pp); + pp.declaration (destroy); + pp_newline_and_flush (&pp); +} + +/* ================= END Debug. ================= */ + static bool coro_promise_type_found_p (tree, location_t); /* GCC C++ coroutines implementation. @@ -5214,6 +5323,10 @@ cp_coroutine_transform::~cp_coroutine_transform () void cp_coroutine_transform::apply_transforms () { + if (dmp_str == NULL) + dmp_str = dump_begin (coro_dump_id, &coro_dump_flags); + + coro_maybe_dump_initial_function (orig_fn_decl); coroutine_body = split_coroutine_body_from_ramp (orig_fn_decl); @@ -5261,6 +5374,7 @@ cp_coroutine_transform::apply_transforms () frame_type = finish_struct (frame_type, NULL_TREE); valid_coroutine = build_ramp_function (); + coro_maybe_dump_ramp (orig_fn_decl); } /* Having analysed and collected the necessary data we are now in a position @@ -5279,6 +5393,8 @@ cp_coroutine_transform::finish_transforms () current_function_decl = destroyer; build_destroy_fn (fn_start, frame_type, destroyer, resumer, inline_p); + + coro_maybe_dump_transformed_functions (resumer, destroyer); } #include "gt-cp-coroutines.h" diff --git a/gcc/cp/cp-objcp-common.cc b/gcc/cp/cp-objcp-common.cc index cd379514991d..248119b05fe1 100644 --- a/gcc/cp/cp-objcp-common.cc +++ b/gcc/cp/cp-objcp-common.cc @@ -607,6 +607,8 @@ cp_register_dumps (gcc::dump_manager *dumps) raw_dump_id = dumps->dump_register (".raw", "lang-raw", "lang-raw", DK_lang, OPTGROUP_NONE, false); + coro_dump_id = dumps->dump_register + (".coro", "lang-coro", "lang-coro", DK_lang, OPTGROUP_NONE, false); } void diff --git a/gcc/cp/cp-tree.h b/gcc/cp/cp-tree.h index 72ed4f1a4741..886b5e2b2f99 100644 --- a/gcc/cp/cp-tree.h +++ b/gcc/cp/cp-tree.h @@ -6680,6 +6680,7 @@ extern cp_parameter_declarator *no_parameters; extern int class_dump_id; extern int module_dump_id; extern int raw_dump_id; +extern int coro_dump_id; /* Whether the current context is manifestly constant-evaluated. Used by the constexpr machinery to control folding of diff --git a/gcc/cp/cxx-pretty-print.cc b/gcc/cp/cxx-pretty-print.cc index e690354e08e9..4184bb87768e 100644 --- a/gcc/cp/cxx-pretty-print.cc +++ b/gcc/cp/cxx-pretty-print.cc @@ -2277,7 +2277,7 @@ pp_cxx_template_parameter (cxx_pretty_printer *pp, tree t) { case TYPE_DECL: pp_cxx_ws_string (pp, "class"); - if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (t))) + if (TEMPLATE_TYPE_PARAMETER_PACK (TREE_TYPE (parameter))) pp_cxx_ws_string (pp, "..."); if (DECL_NAME (parameter)) pp_cxx_tree_identifier (pp, DECL_NAME (parameter)); @@ -2463,6 +2463,7 @@ cxx_pretty_printer::declaration (tree t) } else switch (TREE_CODE (t)) { + case FIELD_DECL: case VAR_DECL: case TYPE_DECL: pp_cxx_simple_declaration (this, t); diff --git a/gcc/dumpfile.cc b/gcc/dumpfile.cc index 074da7df2169..5977e938b636 100644 --- a/gcc/dumpfile.cc +++ b/gcc/dumpfile.cc @@ -108,7 +108,7 @@ static struct dump_file_info dump_files[TDI_end] = DUMP_FILE_INFO (".lto-stream-out", "ipa-lto-stream-out", DK_ipa, 0), DUMP_FILE_INFO (".profile-report", "profile-report", DK_ipa, 0), #define FIRST_AUTO_NUMBERED_DUMP 1 -#define FIRST_ME_AUTO_NUMBERED_DUMP 5 +#define FIRST_ME_AUTO_NUMBERED_DUMP 6 DUMP_FILE_INFO (NULL, "lang-all", DK_lang, 0), DUMP_FILE_INFO (NULL, "tree-all", DK_tree, 0),