From patchwork Wed May 27 18:34:38 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: David Malcolm X-Patchwork-Id: 1299158 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=gcc.gnu.org Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.a=rsa-sha256 header.s=default header.b=ClzDRb8A; dkim-atps=neutral Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (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 ozlabs.org (Postfix) with ESMTPS id 49XKHq47ySz9sSF for ; Thu, 28 May 2020 04:34:47 +1000 (AEST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 91F203959C66; Wed, 27 May 2020 18:34:45 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 91F203959C66 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gcc.gnu.org; s=default; t=1590604485; bh=gUguQZoCcGcyAdLI+0etBIMxjLH9MpKvTP3oi3D6MEI=; h=To:Subject:Date:List-Id:List-Unsubscribe:List-Archive:List-Post: List-Help:List-Subscribe:From:Reply-To:From; b=ClzDRb8AMN2gVdvh9wvk06R8+fvuwptHL2H36MOTbGSksxJnPuc+0K2Le9d9CDugD C6b2tNYMV8BF1dwsyAGbaApqGYYmHWNPKN5QxjJIpTJQ8xMyaMG21k61EHL2SSQ+F9 TXYtlZ/qIlH69VszOTdfafznajq51DHKXjsNoJO0= X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from us-smtp-1.mimecast.com (us-smtp-1.mimecast.com [205.139.110.61]) by sourceware.org (Postfix) with ESMTP id 5B487383E82C for ; Wed, 27 May 2020 18:34:43 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 5B487383E82C Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-6-KIzGU9jqMZyn8OG57xLCJg-1; Wed, 27 May 2020 14:34:41 -0400 X-MC-Unique: KIzGU9jqMZyn8OG57xLCJg-1 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id BE7021005512; Wed, 27 May 2020 18:34:40 +0000 (UTC) Received: from t470.redhat.com (ovpn-112-12.phx2.redhat.com [10.3.112.12]) by smtp.corp.redhat.com (Postfix) with ESMTP id 3E5785C1B0; Wed, 27 May 2020 18:34:40 +0000 (UTC) To: gcc-patches@gcc.gnu.org, jit@gcc.gnu.org Subject: [committed] jit: use deep unsharing of trees [PR 95314] Date: Wed, 27 May 2020 14:34:38 -0400 Message-Id: <20200527183438.24437-1-dmalcolm@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Mimecast-Spam-Score: 0 X-Mimecast-Originator: redhat.com X-Spam-Status: No, score=-15.7 required=5.0 tests=BAYES_00, DKIMWL_WL_HIGH, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, DKIM_VALID_EF, GIT_PATCH_0, RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-Patchwork-Original-From: David Malcolm via Gcc-patches From: David Malcolm Reply-To: David Malcolm Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "Gcc-patches" PR jit/95314 reports a internal error inside verify_gimple, which turned out to be due to reusing the result of gcc_jit_lvalue_get_address in several functions, leading to tree nodes shared between multiple function bodies. This patch fixes the issue by adopting the "Deep unsharing" strategy described in the comment in gimplify.c preceding mostly_copy_tree_r: to mark all of the jit "frontend"'s expression tree nodes with TREE_VISITED, and to set LANG_HOOKS_DEEP_UNSHARING, so that "they are unshared on the first reference within functions when the regular unsharing algorithm runs". Successfully bootstrapped & regrtested on x86_64-pc-linux-gnu. Pushed to master as r11-668-gc98bd673ef93836f03491201f1c63929ea429cd6. gcc/jit/ChangeLog: PR jit/95314 * dummy-frontend.c (LANG_HOOKS_DEEP_UNSHARING): Define to be true. * jit-playback.h (gcc::jit::playback::rvalue): Mark tree node with TREE_VISITED. gcc/testsuite/ChangeLog: PR jit/95314 * jit.dg/all-non-failing-tests.h: Add test-pr95314-rvalue-reuse.c. * jit.dg/test-pr95314-rvalue-reuse.c: New test. --- gcc/jit/dummy-frontend.c | 3 + gcc/jit/jit-playback.h | 7 ++- gcc/testsuite/jit.dg/all-non-failing-tests.h | 10 ++++ .../jit.dg/test-pr95314-rvalue-reuse.c | 56 +++++++++++++++++++ 4 files changed, 75 insertions(+), 1 deletion(-) create mode 100644 gcc/testsuite/jit.dg/test-pr95314-rvalue-reuse.c diff --git a/gcc/jit/dummy-frontend.c b/gcc/jit/dummy-frontend.c index 27fe9d3db96..6c7b7992a4d 100644 --- a/gcc/jit/dummy-frontend.c +++ b/gcc/jit/dummy-frontend.c @@ -269,6 +269,9 @@ jit_langhook_getdecls (void) #undef LANG_HOOKS_GETDECLS #define LANG_HOOKS_GETDECLS jit_langhook_getdecls +#undef LANG_HOOKS_DEEP_UNSHARING +#define LANG_HOOKS_DEEP_UNSHARING true + struct lang_hooks lang_hooks = LANG_HOOKS_INITIALIZER; #include "gt-jit-dummy-frontend.h" diff --git a/gcc/jit/jit-playback.h b/gcc/jit/jit-playback.h index 074434a9f6b..f9b3e675368 100644 --- a/gcc/jit/jit-playback.h +++ b/gcc/jit/jit-playback.h @@ -576,7 +576,12 @@ public: rvalue (context *ctxt, tree inner) : m_ctxt (ctxt), m_inner (inner) - {} + { + /* Pre-mark tree nodes with TREE_VISITED so that they can be + deeply unshared during gimplification (including across + functions); this requires LANG_HOOKS_DEEP_UNSHARING to be true. */ + TREE_VISITED (inner) = 1; + } rvalue * as_rvalue () { return this; } diff --git a/gcc/testsuite/jit.dg/all-non-failing-tests.h b/gcc/testsuite/jit.dg/all-non-failing-tests.h index babcd3979b7..ca8d3df4193 100644 --- a/gcc/testsuite/jit.dg/all-non-failing-tests.h +++ b/gcc/testsuite/jit.dg/all-non-failing-tests.h @@ -234,6 +234,13 @@ #undef create_code #undef verify_code +/* test-pr95314-rvalue-reuse.c. */ +#define create_code create_code_pr95314_rvalue_reuse +#define verify_code verify_code_pr95314_rvalue_reuse +#include "test-pr95314-rvalue-reuse.c" +#undef create_code +#undef verify_code + /* test-reading-struct.c */ #define create_code create_code_reading_struct #define verify_code verify_code_reading_struct @@ -401,6 +408,9 @@ const struct testcase testcases[] = { {"pr95306_builtin_types", create_code_pr95306_builtin_types, verify_code_pr95306_builtin_types}, + {"pr95314_rvalue_reuse", + create_code_pr95314_rvalue_reuse, + verify_code_pr95314_rvalue_reuse}, {"reading_struct ", create_code_reading_struct , verify_code_reading_struct }, diff --git a/gcc/testsuite/jit.dg/test-pr95314-rvalue-reuse.c b/gcc/testsuite/jit.dg/test-pr95314-rvalue-reuse.c new file mode 100644 index 00000000000..6bed0bc52a4 --- /dev/null +++ b/gcc/testsuite/jit.dg/test-pr95314-rvalue-reuse.c @@ -0,0 +1,56 @@ +#include +#include "harness.h" + +void create_code (gcc_jit_context *ctxt, void *user_data) +{ + gcc_jit_type *t_int = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_INT); + gcc_jit_type *t_void = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_VOID); + gcc_jit_type *t_const_char_ptr + = gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_CONST_CHAR_PTR); + gcc_jit_lvalue *global + = gcc_jit_context_new_global (ctxt, NULL, GCC_JIT_GLOBAL_INTERNAL, + t_const_char_ptr, "pr95314_global"); + + gcc_jit_rvalue *global_ref = gcc_jit_lvalue_get_address(global, NULL); + + gcc_jit_param *param_string + = gcc_jit_context_new_param (ctxt, NULL, t_const_char_ptr, "string"); + gcc_jit_function *puts_func + = gcc_jit_context_new_function (ctxt, NULL, GCC_JIT_FUNCTION_IMPORTED, + t_int, "puts", 1, ¶m_string, 0); + +#define NUM_INNER_FNS 3 + gcc_jit_function *inner_fns[NUM_INNER_FNS]; + for (int i = 0; i < NUM_INNER_FNS; i++) + { + char fnname[128]; + sprintf (fnname, "pr95314_inner_%i", i); + inner_fns[i] + = gcc_jit_context_new_function (ctxt, NULL, GCC_JIT_FUNCTION_INTERNAL, + t_void, fnname, 0, NULL, 0); + gcc_jit_block *block = gcc_jit_function_new_block (inner_fns[i], NULL); + gcc_jit_rvalue *arg + = gcc_jit_context_new_cast (ctxt, NULL, global_ref, t_const_char_ptr); + gcc_jit_block_add_eval (block, NULL, + gcc_jit_context_new_call (ctxt, NULL, puts_func, + 1, &arg)); + gcc_jit_block_end_with_void_return (block, NULL); + } + + gcc_jit_function *outer_func + = gcc_jit_context_new_function (ctxt, NULL, GCC_JIT_FUNCTION_EXPORTED, + t_void, "pr95314_outer", 0, NULL, 0); + gcc_jit_block *block = gcc_jit_function_new_block (outer_func, NULL); + for (int i = 0; i < NUM_INNER_FNS; i++) + gcc_jit_block_add_eval (block, NULL, + gcc_jit_context_new_call (ctxt, NULL, inner_fns[i], + 0, NULL)); + gcc_jit_block_end_with_void_return (block, NULL); +} + +void +verify_code (gcc_jit_context *ctxt, gcc_jit_result *result) +{ + CHECK_NON_NULL (result); + (void)gcc_jit_result_get_code (result, "pr95314_outer"); +}