From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from EUR02-HE1-obe.outbound.protection.outlook.com (mail-eopbgr10086.outbound.protection.outlook.com [40.107.1.86]) by sourceware.org (Postfix) with ESMTPS id 810663858D35; Mon, 3 Aug 2020 08:08:06 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 810663858D35 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=Andrea.Corallo@arm.com DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=armh.onmicrosoft.com; s=selector2-armh-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=OYB9NsieMuR7QW3qPURLQMzawrujCxhPe74P6y3CMvo=; b=0FdKjLAv7wen7BTEcekBe9TwDy87vTFOodAIQnSKSfJrlKn6WsfH8GwduET4J/XVAetI7RYSx/cinC5D79lhF6ZTbsaUkZWt6p6wyYctJoabfr4sod6OvbzWJI8b3s0uo1jfaEk9ZvLx9bDC1Pkk6Bs6xndrjAF4gxFij+Uztlg= Received: from AM6P191CA0092.EURP191.PROD.OUTLOOK.COM (2603:10a6:209:8a::33) by AM5PR0801MB1940.eurprd08.prod.outlook.com (2603:10a6:203:48::12) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3239.18; Mon, 3 Aug 2020 08:08:03 +0000 Received: from VE1EUR03FT020.eop-EUR03.prod.protection.outlook.com (2603:10a6:209:8a:cafe::b7) by AM6P191CA0092.outlook.office365.com (2603:10a6:209:8a::33) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3239.17 via Frontend Transport; Mon, 3 Aug 2020 08:08:03 +0000 X-MS-Exchange-Authentication-Results: spf=pass (sender IP is 63.35.35.123) smtp.mailfrom=arm.com; gcc.gnu.org; dkim=pass (signature was verified) header.d=armh.onmicrosoft.com;gcc.gnu.org; dmarc=bestguesspass action=none header.from=arm.com; Received-SPF: Pass (protection.outlook.com: domain of arm.com designates 63.35.35.123 as permitted sender) receiver=protection.outlook.com; client-ip=63.35.35.123; helo=64aa7808-outbound-1.mta.getcheckrecipient.com; Received: from 64aa7808-outbound-1.mta.getcheckrecipient.com (63.35.35.123) by VE1EUR03FT020.mail.protection.outlook.com (10.152.18.242) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3239.17 via Frontend Transport; Mon, 3 Aug 2020 08:08:03 +0000 Received: ("Tessian outbound 7de93d801f24:v62"); Mon, 03 Aug 2020 08:08:03 +0000 X-CheckRecipientChecked: true X-CR-MTA-CID: 67e12b919baf5ea6 X-CR-MTA-TID: 64aa7808 Received: from 246c41cce64a.1 by 64aa7808-outbound-1.mta.getcheckrecipient.com id DAD76232-CC6B-4E46-87B7-6D2C463254C7.1; Mon, 03 Aug 2020 08:07:57 +0000 Received: from EUR01-HE1-obe.outbound.protection.outlook.com by 64aa7808-outbound-1.mta.getcheckrecipient.com with ESMTPS id 246c41cce64a.1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384); Mon, 03 Aug 2020 08:07:57 +0000 ARC-Seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=e6hkUPSsta8CmmMeqEu4kqCXzlQpn/PHXMf5wo1p0tvjP6tvrcbmT1HQJ/9t6uMlgGQ9hOhTyalRsBkFuEDzjZQV3Bbkr3Brg+2DYT75bk/P8+KvWi3DQQP6e92pfERYO0vmsgSVp7iys7w37XHdplgiJTkqkMGHbzP0Rr7xsAkJQTqwFI/LFDc2UtkOjLnvAgqGc9RioiXIxVoimycUOcRYSa/tdYvQ4BbKcMmCZI5ezahmGTt3u8cDm+NWrnSGy2NXV3zCWBTpcymekGMDkDux3Rp4Tjer4m/JQ4gFwrlxQdIS7hz/0UsbTO4tFqemlulAgs0vwW/1Tg6NA2bfZQ== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=OYB9NsieMuR7QW3qPURLQMzawrujCxhPe74P6y3CMvo=; b=ME6kl8JOHw1bJi1KCfT14HNGe6oGPpVb8paKjLPvIVNvytQcroCj2qKyjsGFyzty027wCC7kHyUC0c/JQuo4Kjc2/nXiZhCuMoW0IqSS2Y3iQYOAtnvoMnPMWlSgJ3ZzzRnIXpARf/qiSHQvonzztgAjSgXInMYdAfPCYKNpSHQmA8n6xAk7iyhLVZQ/cPu3Sibac2Ho/1Dv06PKuwPCSZwh582J28CjqC9sbCspT4+Mzi6MIFA/a0Yq7PeNzerzKRRXC/C/gCrGzrh7au2O4chtOMw4tTNDNmL6x6dpFzD6vi+DoMVuU5+2UvBodeCxpNiYYNefE7IR+he3R0Wd3w== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=arm.com; dmarc=pass action=none header.from=arm.com; dkim=pass header.d=arm.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=armh.onmicrosoft.com; s=selector2-armh-onmicrosoft-com; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=OYB9NsieMuR7QW3qPURLQMzawrujCxhPe74P6y3CMvo=; b=0FdKjLAv7wen7BTEcekBe9TwDy87vTFOodAIQnSKSfJrlKn6WsfH8GwduET4J/XVAetI7RYSx/cinC5D79lhF6ZTbsaUkZWt6p6wyYctJoabfr4sod6OvbzWJI8b3s0uo1jfaEk9ZvLx9bDC1Pkk6Bs6xndrjAF4gxFij+Uztlg= Authentication-Results-Original: gcc.gnu.org; dkim=none (message not signed) header.d=none;gcc.gnu.org; dmarc=none action=none header.from=arm.com; Received: from DB7PR08MB3594.eurprd08.prod.outlook.com (2603:10a6:10:4e::11) by DBAPR08MB5605.eurprd08.prod.outlook.com (2603:10a6:10:1af::24) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3239.21; Mon, 3 Aug 2020 08:07:55 +0000 Received: from DB7PR08MB3594.eurprd08.prod.outlook.com ([fe80::b84b:231a:56a1:f0ae]) by DB7PR08MB3594.eurprd08.prod.outlook.com ([fe80::b84b:231a:56a1:f0ae%6]) with mapi id 15.20.3239.021; Mon, 3 Aug 2020 08:07:55 +0000 From: Andrea Corallo To: David Malcolm Cc: jit@gcc.gnu.org, nd@arm.com, gcc-patches@gcc.gnu.org Subject: Re: [PATCH] libgccjit: Add new gcc_jit_context_new_blob entry point References: <59a8d345c642d49281a601278946e087a4bbe3e2.camel@redhat.com> <87zh9kumwi.fsf@arm.com> <93e3d65a0b04b13a5d5c9970a2058d167357ed6c.camel@redhat.com> <22479e6a6a1e27df07a3d2c2cfb8c6c8420a7d3d.camel@redhat.com> Date: Mon, 03 Aug 2020 10:07:53 +0200 In-Reply-To: <22479e6a6a1e27df07a3d2c2cfb8c6c8420a7d3d.camel@redhat.com> (David Malcolm's message of "Fri, 24 Jul 2020 18:12:22 -0400") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/28.0.50 (gnu/linux) Content-Type: multipart/mixed; boundary="=-=-=" X-ClientProxiedBy: LO2P265CA0368.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:a3::20) To DB7PR08MB3594.eurprd08.prod.outlook.com (2603:10a6:10:4e::11) MIME-Version: 1.0 X-MS-Exchange-MessageSentRepresentingType: 1 Received: from e112547 (217.140.99.251) by LO2P265CA0368.GBRP265.PROD.OUTLOOK.COM (2603:10a6:600:a3::20) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.3239.16 via Frontend Transport; Mon, 3 Aug 2020 08:07:54 +0000 X-Originating-IP: [217.140.99.251] X-MS-PublicTrafficType: Email X-MS-Office365-Filtering-HT: Tenant X-MS-Office365-Filtering-Correlation-Id: c002c091-c8af-4f18-376d-08d8378458b9 X-MS-TrafficTypeDiagnostic: DBAPR08MB5605:|AM5PR0801MB1940: X-Microsoft-Antispam-PRVS: x-checkrecipientrouted: true NoDisclaimer: true X-MS-Oob-TLC-OOBClassifiers: OLM:6790;OLM:6790; X-MS-Exchange-SenderADCheck: 1 X-Microsoft-Antispam-Untrusted: BCL:0; X-Microsoft-Antispam-Message-Info-Original: BG8YegTE+hl9BWRbqT1FC/nxL4BMwD0XkgY0E3PtS4/IG5HxredwWFVkAL7xKdSW5sy1GmNLtqAby09TRyhfzQlZpcr/8637bvh0S6qKubugraRbayAFVm+V/bAfv8dJpSpQ+OLrD8TJBp7y7pz3khoGffSyWg7CB2sdmCmUG0gzfUOVm301AhmV15m5d9C0PVsW3bJ2VrV4o2o1bXUi6HBwhHhGKSacpIphcnbHH0ipt7GXn47RLhT+ezz04rLLdqkwil1moFGKUPcMW6U8fTZydD/kOPtit4YgOmPS1Tzxf23T4Q4fXmZkoGcMkWQpa5tsmDduLBhpVQmM11oZoQ== X-Forefront-Antispam-Report-Untrusted: CIP:255.255.255.255; CTRY:; LANG:en; SCL:1; SRV:; IPV:NLI; SFV:NSPM; H:DB7PR08MB3594.eurprd08.prod.outlook.com; PTR:; CAT:NONE; SFTY:; SFS:(4636009)(39860400002)(346002)(366004)(376002)(136003)(396003)(316002)(44832011)(6486002)(2616005)(52116002)(83380400001)(2906002)(33964004)(16526019)(235185007)(6916009)(186003)(8936002)(4326008)(956004)(66616009)(66556008)(66946007)(86362001)(478600001)(8676002)(6496006)(66476007)(36756003)(26005)(5660300002); DIR:OUT; SFP:1101; X-MS-Exchange-AntiSpam-MessageData: 2i7XUo0ABgeqq6xHOxvx+8aHOh6X5zwEImZyOMD0gulDRNZFzg7vpThtUtfh6naoplpOyStEOCYpTAt2I2699SnHSxDurYXqNeZjty8g4FxgoBQjCrM1Y7AhrIwoFIlfPZGfmfJvoAodPH07LC6MQ9tdKD9p8dc45pnmlkI42/6R3643Q/iDovPZPN17ny6bdKXSkH6QM6v1eJB2X/k7AzDHwj+qduk9zdoOGAXIIeEKwS+D7VrdykbMz7UpsulSWciNbi7/OMkW6zs8D1/oSNXGtLHSxoHsfsqDj3kcUW9bpJOD60XgEK68MdcXvSZxKsGM7rKo9hEquoPK180o7X9xMqKGdv3fluQ+t5yPgVYIg76Ezv/qJ0SUCLtERwJXnbnHn3RyX+GruSKkMvQNmssgfcCMzVU/wLrIniX3jseUL/0L1+zwWETXy6RzOjVYbuY8AfptH5HrTiAVXwd1pcW/7Nt0HBu6EwKuwWi/kPMVZJ+MMWKMQgX35CW6XM5yxwF1/04ZR/TD4MKiz72JdO/4i/NZ28Y5pC00dp/c3WAvYXtswP1ShXGlMR6wcON67HzKwedNW0DUJ66A9H4gV9TK5eCjzGZM8Sw2V16CGvWLMZ/IF28/UOGyfujI10KMFhFJKrl0Ucau7cg329fgrg== X-MS-Exchange-Transport-Forked: True X-MS-Exchange-Transport-CrossTenantHeadersStamped: DBAPR08MB5605 Original-Authentication-Results: gcc.gnu.org; dkim=none (message not signed) header.d=none;gcc.gnu.org; dmarc=none action=none header.from=arm.com; X-EOPAttributedMessage: 0 X-MS-Exchange-Transport-CrossTenantHeadersStripped: VE1EUR03FT020.eop-EUR03.prod.protection.outlook.com X-MS-Office365-Filtering-Correlation-Id-Prvs: f3d0d20d-a06e-4e5f-2fcf-08d8378453bc X-Microsoft-Antispam: BCL:0; X-Microsoft-Antispam-Message-Info: T4jejq48k70WfOBmqRMSqtKjOWTUPxJ1g/EewM3Kg+lpmYur0O6zSEXKcWm2sROPcAa8SKG7K8J8vR9q9ZmtY5PSKpYJ8sByHPFZn53SFkL9jW3U97dIIDu65Eh19PEB0eLov9kBdLwtJmbrldUfmSyfRaBHnTz+e3HC9q2xxeqXv+V/g2FUzl1JRn5+ir9G0akoeLc/dSzspQWiEVdixCc/Y/SbC/QVrT4GmEdqYleuWbLI/K+oHHC57YncCItFrp8Vx7jrCubdXVm8n+VsJDylU6SBIxfgK7qjiunL2grhiYcANc9I/pDUa9nR1lsOI5FSLoHMJtYD/pNXfeiQE18FJPytP4yg99kz+rW2agHh7htbaG3bjteb5Y716SxspX+1CwQdD2H1fOJDznJ4ow== X-Forefront-Antispam-Report: CIP:63.35.35.123; CTRY:IE; LANG:en; SCL:1; SRV:; IPV:CAL; SFV:NSPM; H:64aa7808-outbound-1.mta.getcheckrecipient.com; PTR:ec2-63-35-35-123.eu-west-1.compute.amazonaws.com; CAT:NONE; SFTY:; SFS:(4636009)(136003)(396003)(376002)(346002)(39860400002)(46966005)(316002)(66616009)(478600001)(83380400001)(36906005)(2616005)(336012)(82740400003)(956004)(16526019)(8936002)(356005)(186003)(8676002)(86362001)(4326008)(6486002)(47076004)(235185007)(82310400002)(450100002)(70586007)(70206006)(6862004)(26005)(5660300002)(2906002)(44832011)(81166007)(33964004)(36756003)(6496006); DIR:OUT; SFP:1101; X-OriginatorOrg: arm.com X-MS-Exchange-CrossTenant-OriginalArrivalTime: 03 Aug 2020 08:08:03.4767 (UTC) X-MS-Exchange-CrossTenant-Network-Message-Id: c002c091-c8af-4f18-376d-08d8378458b9 X-MS-Exchange-CrossTenant-Id: f34e5979-57d9-4aaa-ad4d-b122a662184d X-MS-Exchange-CrossTenant-OriginalAttributedTenantConnectingIp: TenantId=f34e5979-57d9-4aaa-ad4d-b122a662184d; Ip=[63.35.35.123]; Helo=[64aa7808-outbound-1.mta.getcheckrecipient.com] X-MS-Exchange-CrossTenant-AuthSource: VE1EUR03FT020.eop-EUR03.prod.protection.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Anonymous X-MS-Exchange-CrossTenant-FromEntityHeader: HybridOnPrem X-MS-Exchange-Transport-CrossTenantHeadersStamped: AM5PR0801MB1940 X-Spam-Status: No, score=-15.4 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, GIT_PATCH_0, MSGID_FROM_MTA_HEADER, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2, SPF_HELO_PASS, SPF_PASS, TXREP, T_FILL_THIS_FORM_SHORT, UNPARSEABLE_RELAY 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: jit@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Jit mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Mon, 03 Aug 2020 08:08:11 -0000 --=-=-= Content-Type: text/plain David Malcolm writes: > On Fri, 2020-07-24 at 18:05 -0400, David Malcolm via Gcc-patches wrote: > > [...] > >> I haven't thought this through in detail, and I'm not sure exactly >> how >> it would work for arbitrary types, but I thought it worth sharing. >> (For example I can think of nasty issues if we ever want to support >> cross-compilation, e.g. where sizeof types or endianness differs >> between host and target). > > ...which is an argument in favor of retaining the name "blob", perhaps > as the name of the argument in the header file e.g.: > > extern void > gcc_jit_global_set_initializer (gcc_jit_lvalue *global, > const void *blob, > size_t num_bytes); > > > as a subtle hint to the user that they need to be wary about binary > layouts ("here be dragons"). > > [...] Hi Dave & all, following up this is my take on the implementation of: gcc_jit_global_set_initializer (gcc_jit_lvalue *global, const void *blob, size_t num_bytes); 'global' must be an array but in the seek of generality it now supports all the various integral types and is not limited to char[]. As you anticipated the implementation I came up is currently not safe for cross-compilation, not sure is requirement tho. make check-jit is clean Feedback very welcome Thanks! Andrea gcc/jit/ChangeLog 2020-08-01 Andrea Corallo * docs/topics/compatibility.rst (LIBGCCJIT_ABI_14): New ABI tag. * docs/topics/expressions.rst (gcc_jit_global_set_initializer): Document new entry point in section 'Global variables'. * jit-playback.c (global_new_decl, global_finalize_lvalue): New method. (playback::context::new_global): Make use of global_new_decl, global_finalize_lvalue. (load_blob_in_ctor): New template function in use by the following. (playback::context::new_global_initialized): New method. * jit-playback.h (class context): Decl 'new_global_initialized', 'global_new_decl', 'global_finalize_lvalue'. (lvalue::set_initializer): Add implementation. * jit-recording.c (recording::memento_of_get_pointer::get_size) (recording::memento_of_get_type::get_size): Add implementation. (recording::global::write_initializer_reproducer): New function in use by 'recording::global::write_reproducer'. (recording::global::replay_into) (recording::global::write_to_dump) (recording::global::write_reproducer): Handle initialized case. * jit-recording.h (class type): Decl 'get_size' and 'num_elements'. * libgccjit++.h (class lvalue): Declare new 'set_initializer' method. (class lvalue): Decl 'is_global' and 'set_initializer'. (class class global) Decl 'write_initializer_reproducer'. Add 'm_initializer', 'm_initializer_num_bytes' fields. Implement 'set_initializer'. * libgccjit.c (gcc_jit_global_set_initializer): New function. * libgccjit.h (gcc_jit_global_set_initializer): New function declaration. * libgccjit.map (LIBGCCJIT_ABI_14): New ABI tag. gcc/testsuite/ChangeLog 2020-08-01 Andrea Corallo * jit.dg/all-non-failing-tests.h: Add test-blob.c. * jit.dg/test-global-set-initializer.c: New testcase. --=-=-= Content-Type: text/plain; charset=utf-8 Content-Disposition: attachment; filename=0001-Add-new-gcc_jit_global_set_initializer-entry-point.patch >From 74bd96fde6d4baed978555279d17898b989c00ad Mon Sep 17 00:00:00 2001 From: Andrea Corallo Date: Sat, 30 May 2020 10:33:08 +0100 Subject: [PATCH] Add new gcc_jit_global_set_initializer entry point gcc/jit/ChangeLog 2020-08-01 Andrea Corallo * docs/topics/compatibility.rst (LIBGCCJIT_ABI_14): New ABI tag. * docs/topics/expressions.rst (gcc_jit_global_set_initializer): Document new entry point in section 'Global variables'. * jit-playback.c (global_new_decl, global_finalize_lvalue): New method. (playback::context::new_global): Make use of global_new_decl, global_finalize_lvalue. (load_blob_in_ctor): New template function in use by the following. (playback::context::new_global_initialized): New method. * jit-playback.h (class context): Decl 'new_global_initialized', 'global_new_decl', 'global_finalize_lvalue'. (lvalue::set_initializer): Add implementation. * jit-recording.c (recording::memento_of_get_pointer::get_size) (recording::memento_of_get_type::get_size): Add implementation. (recording::global::write_initializer_reproducer): New function in use by 'recording::global::write_reproducer'. (recording::global::replay_into) (recording::global::write_to_dump) (recording::global::write_reproducer): Handle initialized case. * jit-recording.h (class type): Decl 'get_size' and 'num_elements'. * libgccjit++.h (class lvalue): Declare new 'set_initializer' method. (class lvalue): Decl 'is_global' and 'set_initializer'. (class class global) Decl 'write_initializer_reproducer'. Add 'm_initializer', 'm_initializer_num_bytes' fields. Implement 'set_initializer'. * libgccjit.c (gcc_jit_global_set_initializer): New function. * libgccjit.h (gcc_jit_global_set_initializer): New function declaration. * libgccjit.map (LIBGCCJIT_ABI_14): New ABI tag. gcc/testsuite/ChangeLog 2020-08-01 Andrea Corallo * jit.dg/all-non-failing-tests.h: Add test-blob.c. * jit.dg/test-global-set-initializer.c: New testcase. --- gcc/jit/docs/topics/compatibility.rst | 7 + gcc/jit/docs/topics/expressions.rst | 21 +++ gcc/jit/jit-playback.c | 105 +++++++++++++- gcc/jit/jit-playback.h | 17 +++ gcc/jit/jit-recording.c | 137 +++++++++++++++++- gcc/jit/jit-recording.h | 26 ++++ gcc/jit/libgccjit++.h | 10 ++ gcc/jit/libgccjit.c | 36 +++++ gcc/jit/libgccjit.h | 14 ++ gcc/jit/libgccjit.map | 7 +- gcc/testsuite/jit.dg/all-non-failing-tests.h | 7 + .../jit.dg/test-global-set-initializer.c | 78 ++++++++++ 12 files changed, 453 insertions(+), 12 deletions(-) create mode 100644 gcc/testsuite/jit.dg/test-global-set-initializer.c diff --git a/gcc/jit/docs/topics/compatibility.rst b/gcc/jit/docs/topics/compatibility.rst index bb3387fa583b..6bfa101ed718 100644 --- a/gcc/jit/docs/topics/compatibility.rst +++ b/gcc/jit/docs/topics/compatibility.rst @@ -219,3 +219,10 @@ entrypoints: * :func:`gcc_jit_version_minor` * :func:`gcc_jit_version_patchlevel` + +.. _LIBGCCJIT_ABI_14: + +``LIBGCCJIT_ABI_14`` +-------------------- +``LIBGCCJIT_ABI_14`` covers the addition of +:func:`gcc_jit_global_set_initializer` diff --git a/gcc/jit/docs/topics/expressions.rst b/gcc/jit/docs/topics/expressions.rst index d783ceea51a8..7699dcfd27be 100644 --- a/gcc/jit/docs/topics/expressions.rst +++ b/gcc/jit/docs/topics/expressions.rst @@ -582,6 +582,27 @@ Global variables referring to it. Analogous to using an "extern" global from a header file. +.. function:: gcc_jit_lvalue *\ + gcc_jit_global_set_initializer (gcc_jit_lvalue *global,\ + const void *blob,\ + size_t num_bytes) + + Set an initializer for an object using the memory content pointed + by ``blob`` for ``num_bytes``. ``global`` must be an arrays of an + integral type. + + The parameter ``blob`` must be non-NULL. The call copies the memory + pointed by ``blob`` for ``num_bytes`` bytes, so it is valid to pass + in a pointer to an on-stack buffer. The content will be stored in + the compilation unit and used as initialization value of the array. + + This entrypoint was added in :ref:`LIBGCCJIT_ABI_14`; you can test for + its presence using + + .. code-block:: c + + #ifdef LIBGCCJIT_HAVE_global_set_initializer + Working with pointers, structs and unions ----------------------------------------- diff --git a/gcc/jit/jit-playback.h b/gcc/jit/jit-playback.h index f9b3e675368c..50b69753bb42 100644 --- a/gcc/jit/jit-playback.h +++ b/gcc/jit/jit-playback.h @@ -111,6 +111,15 @@ public: type *type, const char *name); + lvalue * + new_global_initialized (location *loc, + enum gcc_jit_global_kind kind, + type *type, + size_t element_size, + size_t initializer_num_elem, + const void *initializer, + const char *name); + template rvalue * new_rvalue_from_const (type *type, @@ -266,6 +275,14 @@ private: const char * get_path_s_file () const; const char * get_path_so_file () const; + tree + global_new_decl (location *loc, + enum gcc_jit_global_kind kind, + type *type, + const char *name); + lvalue * + global_finalize_lvalue (tree inner); + private: /* Functions for implementing "compile". */ diff --git a/gcc/jit/jit-playback.c b/gcc/jit/jit-playback.c index 0fddf04da873..52fc92f5928c 100644 --- a/gcc/jit/jit-playback.c +++ b/gcc/jit/jit-playback.c @@ -510,14 +510,14 @@ new_function (location *loc, return func; } -/* Construct a playback::lvalue instance (wrapping a tree). */ +/* In use by new_global and new_global_initialized. */ -playback::lvalue * +tree playback::context:: -new_global (location *loc, - enum gcc_jit_global_kind kind, - type *type, - const char *name) +global_new_decl (location *loc, + enum gcc_jit_global_kind kind, + type *type, + const char *name) { gcc_assert (type); gcc_assert (name); @@ -547,6 +547,15 @@ new_global (location *loc, if (loc) set_tree_location (inner, loc); + return inner; +} + +/* In use by new_global and new_global_initialized. */ + +playback::lvalue * +playback::context:: +global_finalize_lvalue (tree inner) +{ varpool_node::get_create (inner); varpool_node::finalize_decl (inner); @@ -556,6 +565,90 @@ new_global (location *loc, return new lvalue (this, inner); } +/* Construct a playback::lvalue instance (wrapping a tree). */ + +playback::lvalue * +playback::context:: +new_global (location *loc, + enum gcc_jit_global_kind kind, + type *type, + const char *name) +{ + tree inner = global_new_decl (loc, kind, type, name); + + return global_finalize_lvalue (inner); +} + +/* Fill 'constructor_elements' with the memory content of + 'initializer'. Each element of the initializer is of the size of + type T. In use by new_global_initialized.*/ + +template +static void +load_blob_in_ctor (vec *&constructor_elements, + size_t num_elem, + const void *initializer) +{ + /* Loosely based on 'output_init_element' c-typeck.c:9691. */ + const T *p = (const T *)initializer; + tree node = make_unsigned_type (BITS_PER_UNIT * sizeof (T)); + for (size_t i = 0; i < num_elem; i++) + { + constructor_elt celt = + { build_int_cst (long_unsigned_type_node, i), + build_int_cst (node, p[i]) }; + vec_safe_push (constructor_elements, celt); + } +} + +/* Construct an initialized playback::lvalue instance (wrapping a + tree). */ + +playback::lvalue * +playback::context:: +new_global_initialized (location *loc, + enum gcc_jit_global_kind kind, + type *type, + size_t element_size, + size_t initializer_num_elem, + const void *initializer, + const char *name) +{ + tree inner = global_new_decl (loc, kind, type, name); + + static vec *constructor_elements; + + switch (element_size) + { + case 1: + load_blob_in_ctor (constructor_elements, initializer_num_elem, + initializer); + break; + case 2: + load_blob_in_ctor (constructor_elements, initializer_num_elem, + initializer); + break; + case 4: + load_blob_in_ctor (constructor_elements, initializer_num_elem, + initializer); + break; + case 8: + load_blob_in_ctor (constructor_elements, initializer_num_elem, + initializer); + break; + default: + gcc_unreachable (); + } + /* Compare with 'pop_init_level' c-typeck.c:8780. */ + tree ctor = build_constructor (type->as_tree (), constructor_elements); + constructor_elements = NULL; + + /* Compare with 'store_init_value' c-typeck.c:7555. */ + DECL_INITIAL (inner) = ctor; + + return global_finalize_lvalue (inner); +} + /* Implementation of the various gcc::jit::playback::context::new_rvalue_from_const methods. diff --git a/gcc/jit/jit-recording.h b/gcc/jit/jit-recording.h index 726b9c4b8371..7a7a61a0e126 100644 --- a/gcc/jit/jit-recording.h +++ b/gcc/jit/jit-recording.h @@ -502,6 +502,7 @@ public: This will return NULL if it's not valid to dereference this type. The caller is responsible for setting an error. */ virtual type *dereference () = 0; + virtual size_t get_size () { gcc_unreachable (); } /* Dynamic casts. */ virtual function_type *dyn_cast_function_type () { return NULL; } @@ -534,6 +535,7 @@ public: virtual type *is_array () = 0; virtual bool is_void () const { return false; } virtual bool has_known_size () const { return true; } + virtual int num_elements () { gcc_unreachable (); } bool is_numeric () const { @@ -569,6 +571,8 @@ public: type *dereference () FINAL OVERRIDE; + size_t get_size () FINAL OVERRIDE; + bool accepts_writes_from (type *rtype) FINAL OVERRIDE { if (m_kind == GCC_JIT_TYPE_VOID_PTR) @@ -610,6 +614,8 @@ public: type *dereference () FINAL OVERRIDE { return m_other_type; } + size_t get_size () FINAL OVERRIDE; + bool accepts_writes_from (type *rtype) FINAL OVERRIDE; void replay_into (replayer *r) FINAL OVERRIDE; @@ -755,6 +761,7 @@ class array_type : public type bool is_bool () const FINAL OVERRIDE { return false; } type *is_pointer () FINAL OVERRIDE { return NULL; } type *is_array () FINAL OVERRIDE { return m_element_type; } + int num_elements () FINAL OVERRIDE { return m_num_elements; } void replay_into (replayer *) FINAL OVERRIDE; @@ -1107,6 +1114,8 @@ public: const char *access_as_rvalue (reproducer &r) OVERRIDE; virtual const char *access_as_lvalue (reproducer &r); + virtual bool is_global () const { return false; } + virtual void set_initializer (const void *, size_t) { gcc_unreachable (); } }; class param : public lvalue @@ -1335,8 +1344,23 @@ public: void write_to_dump (dump &d) FINAL OVERRIDE; + virtual bool is_global () const FINAL OVERRIDE { return true; } + + virtual void + set_initializer (const void *initializer, + size_t num_bytes) FINAL OVERRIDE + { + if (m_initializer) + free (m_initializer); + m_initializer = xmalloc (num_bytes); + memcpy (m_initializer, initializer, num_bytes); + m_initializer_num_bytes = num_bytes; + } + private: string * make_debug_string () FINAL OVERRIDE { return m_name; } + template + void write_initializer_reproducer (const char *id, reproducer &r); void write_reproducer (reproducer &r) FINAL OVERRIDE; enum precedence get_precedence () const FINAL OVERRIDE { @@ -1346,6 +1370,8 @@ private: private: enum gcc_jit_global_kind m_kind; string *m_name; + void *m_initializer = NULL; + size_t m_initializer_num_bytes = 0; }; template diff --git a/gcc/jit/jit-recording.c b/gcc/jit/jit-recording.c index b73cd76a0a02..f97de00f63c3 100644 --- a/gcc/jit/jit-recording.c +++ b/gcc/jit/jit-recording.c @@ -2175,6 +2175,57 @@ recording::type::access_as_type (reproducer &r) return r.get_identifier (this); } +/* Override of default implementation of + recording::type::get_size. + + Return the size in bytes. This is in use for global + initialization. */ + +size_t +recording::memento_of_get_type::get_size () +{ + int size; + switch (m_kind) + { + case GCC_JIT_TYPE_VOID: + return 0; + case GCC_JIT_TYPE_BOOL: + case GCC_JIT_TYPE_CHAR: + case GCC_JIT_TYPE_SIGNED_CHAR: + case GCC_JIT_TYPE_UNSIGNED_CHAR: + return 1; + case GCC_JIT_TYPE_SHORT: + case GCC_JIT_TYPE_UNSIGNED_SHORT: + size = SHORT_TYPE_SIZE; + break; + case GCC_JIT_TYPE_INT: + case GCC_JIT_TYPE_UNSIGNED_INT: + size = INT_TYPE_SIZE; + break; + case GCC_JIT_TYPE_LONG: + case GCC_JIT_TYPE_UNSIGNED_LONG: + size = LONG_TYPE_SIZE; + break; + case GCC_JIT_TYPE_LONG_LONG: + case GCC_JIT_TYPE_UNSIGNED_LONG_LONG: + size = LONG_LONG_TYPE_SIZE; + break; + case GCC_JIT_TYPE_FLOAT: + size = FLOAT_TYPE_SIZE; + break; + case GCC_JIT_TYPE_DOUBLE: + size = DOUBLE_TYPE_SIZE; + break; + case GCC_JIT_TYPE_LONG_DOUBLE: + size = LONG_DOUBLE_TYPE_SIZE; + break; + default: + gcc_unreachable (); + } + + return size / BITS_PER_UNIT; +} + /* Implementation of pure virtual hook recording::type::dereference for recording::memento_of_get_type. */ @@ -2482,6 +2533,15 @@ recording::memento_of_get_type::write_reproducer (reproducer &r) /* The implementation of class gcc::jit::recording::memento_of_get_pointer. */ +/* Override of default implementation of + recording::type::get_size for get_pointer. */ + +size_t +recording::memento_of_get_pointer::get_size () +{ + return POINTER_SIZE / BITS_PER_UNIT; +} + /* Override of default implementation of recording::type::accepts_writes_from for get_pointer. @@ -4393,10 +4453,20 @@ recording::block::dump_edges_to_dot (pretty_printer *pp) void recording::global::replay_into (replayer *r) { - set_playback_obj (r->new_global (playback_location (r, m_loc), - m_kind, - m_type->playback_type (), - playback_string (m_name))); + set_playback_obj ( + m_initializer + ? r->new_global_initialized (playback_location (r, m_loc), + m_kind, + m_type->playback_type (), + m_type->dereference ()->get_size (), + m_initializer_num_bytes + / m_type->dereference ()->get_size (), + m_initializer, + playback_string (m_name)) + : r->new_global (playback_location (r, m_loc), + m_kind, + m_type->playback_type (), + playback_string (m_name))); } /* Override the default implementation of @@ -4440,9 +4510,26 @@ recording::global::write_to_dump (dump &d) d.write ("extern "); break; } - d.write ("%s %s;\n", + + d.write ("%s %s", m_type->get_debug_string (), get_debug_string ()); + + if (!m_initializer) + { + d.write (";\n"); + return; + } + + d.write ("=\n { "); + const char *p = (const char *)m_initializer; + for (size_t i = 0; i < m_initializer_num_bytes; i++) + { + d.write ("0x%x, ", p[i]); + if (i && !(i % 64)) + d.write ("\n "); + } + d.write ("};\n"); } /* A table of enum gcc_jit_global_kind values expressed in string @@ -4454,6 +4541,27 @@ static const char * const global_kind_reproducer_strings[] = { "GCC_JIT_GLOBAL_IMPORTED" }; +template +void +recording::global::write_initializer_reproducer (const char *id, reproducer &r) +{ + const char *init_id = r.make_tmp_identifier ("init_for", this); + r.write (" %s %s[] =\n {", + m_type->dereference ()->get_debug_string (), + init_id); + + const T *p = (const T *)m_initializer; + for (size_t i = 0; i < m_initializer_num_bytes / sizeof (T); i++) + { + r.write ("%lu, ", (uint64_t)p[i]); + if (i && !(i % 64)) + r.write ("\n "); + } + r.write ("};\n"); + r.write (" gcc_jit_global_set_initializer (%s, %s, sizeof (%s));\n", + id, init_id, init_id); +} + /* Implementation of recording::memento::write_reproducer for globals. */ void @@ -4472,6 +4580,25 @@ recording::global::write_reproducer (reproducer &r) global_kind_reproducer_strings[m_kind], r.get_identifier_as_type (get_type ()), m_name->get_debug_string ()); + + if (m_initializer) + switch (m_type->dereference ()->get_size ()) + { + case 1: + write_initializer_reproducer (id, r); + break; + case 2: + write_initializer_reproducer (id, r); + break; + case 4: + write_initializer_reproducer (id, r); + break; + case 8: + write_initializer_reproducer (id, r); + break; + default: + gcc_unreachable (); + } } /* The implementation of the various const-handling classes: diff --git a/gcc/jit/libgccjit++.h b/gcc/jit/libgccjit++.h index 69e67766640c..1b9ef1a5db98 100644 --- a/gcc/jit/libgccjit++.h +++ b/gcc/jit/libgccjit++.h @@ -488,6 +488,7 @@ namespace gccjit location loc = location ()); rvalue get_address (location loc = location ()); + lvalue set_initializer (const void *blob, size_t num_bytes); }; class param : public lvalue @@ -1737,6 +1738,15 @@ lvalue::get_address (location loc) loc.get_inner_location ())); } +inline lvalue +lvalue::set_initializer (const void *blob, size_t num_bytes) +{ + gcc_jit_global_set_initializer (get_inner_lvalue (), + blob, + num_bytes); + return *this; +} + // class param : public lvalue inline param::param () : lvalue () {} inline param::param (gcc_jit_param *inner) diff --git a/gcc/jit/libgccjit.h b/gcc/jit/libgccjit.h index 1c5a12e9c015..08b855230f6a 100644 --- a/gcc/jit/libgccjit.h +++ b/gcc/jit/libgccjit.h @@ -788,6 +788,20 @@ gcc_jit_context_new_global (gcc_jit_context *ctxt, gcc_jit_type *type, const char *name); +#define LIBGCCJIT_HAVE_global_set_initializer + +/* Set a static initializer for a global return the global itself. + + This API entrypoint was added in LIBGCCJIT_ABI_14; you can test for its + presence using + #ifdef LIBGCCJIT_HAVE_gcc_jit_global_set_initializer +*/ + +extern gcc_jit_lvalue * +gcc_jit_global_set_initializer (gcc_jit_lvalue *global, + const void *blob, + size_t num_bytes); + /* Upcasting. */ extern gcc_jit_object * gcc_jit_lvalue_as_object (gcc_jit_lvalue *lvalue); diff --git a/gcc/jit/libgccjit.c b/gcc/jit/libgccjit.c index 3d04f6db3aff..80c5aa6ac115 100644 --- a/gcc/jit/libgccjit.c +++ b/gcc/jit/libgccjit.c @@ -1117,6 +1117,42 @@ gcc_jit_context_new_global (gcc_jit_context *ctxt, return (gcc_jit_lvalue *)ctxt->new_global (loc, kind, type, name); } +/* Public entrypoint. See description in libgccjit.h. + + After error-checking, the real work is done by the + gcc::jit::recording::global::set_initializer method, in + jit-recording.c. */ + +extern gcc_jit_lvalue * +gcc_jit_global_set_initializer (gcc_jit_lvalue *global, + const void *blob, + size_t num_bytes) +{ + RETURN_NULL_IF_FAIL (global, NULL, NULL, "NULL global"); + RETURN_NULL_IF_FAIL (blob, NULL, NULL, "NULL blob"); + RETURN_NULL_IF_FAIL_PRINTF1 (global->is_global (), NULL, NULL, + "global \"%s\" not a global", + global->get_debug_string ()); + + gcc::jit::recording::type *lval_type = global->get_type (); + RETURN_NULL_IF_FAIL_PRINTF1 (lval_type->is_array (), NULL, NULL, + "global \"%s\" not an array", + global->get_debug_string ()); + RETURN_NULL_IF_FAIL_PRINTF1 (lval_type->dereference ()->is_int (), NULL, NULL, + "global \"%s\" not an array of integral type", + global->get_debug_string ()); + RETURN_NULL_IF_FAIL_PRINTF1 ( + lval_type->dereference ()->get_size() * lval_type->num_elements () + == num_bytes, + NULL, NULL, + "global \"%s\" and initializer don't match size", + global->get_debug_string ()); + + global->set_initializer (blob, num_bytes); + + return global; +} + /* Public entrypoint. See description in libgccjit.h. After error-checking, this calls the trivial diff --git a/gcc/jit/libgccjit.map b/gcc/jit/libgccjit.map index 6137dd4b4b03..a6e67e781a4b 100644 --- a/gcc/jit/libgccjit.map +++ b/gcc/jit/libgccjit.map @@ -186,4 +186,9 @@ LIBGCCJIT_ABI_13 { gcc_jit_version_major; gcc_jit_version_minor; gcc_jit_version_patchlevel; -} LIBGCCJIT_ABI_12; \ No newline at end of file +} LIBGCCJIT_ABI_12; + +LIBGCCJIT_ABI_14 { + global: + gcc_jit_global_set_initializer; +} LIBGCCJIT_ABI_13; diff --git a/gcc/testsuite/jit.dg/all-non-failing-tests.h b/gcc/testsuite/jit.dg/all-non-failing-tests.h index 632ab8cfb2e4..4202eb7798b7 100644 --- a/gcc/testsuite/jit.dg/all-non-failing-tests.h +++ b/gcc/testsuite/jit.dg/all-non-failing-tests.h @@ -174,6 +174,13 @@ #undef create_code #undef verify_code +/* test-global-set-initializer.c */ +#define create_code create_code_global_set_initializer +#define verify_code verify_code_global_set_initializer +#include "test-global-set-initializer.c" +#undef create_code +#undef verify_code + /* test-hello-world.c */ #define create_code create_code_hello_world #define verify_code verify_code_hello_world diff --git a/gcc/testsuite/jit.dg/test-global-set-initializer.c b/gcc/testsuite/jit.dg/test-global-set-initializer.c new file mode 100644 index 000000000000..d38aba7d73f5 --- /dev/null +++ b/gcc/testsuite/jit.dg/test-global-set-initializer.c @@ -0,0 +1,78 @@ +#include +#include +#include +#include + +#include "libgccjit.h" + +#include "harness.h" + +#define BIG_BLOB_SIZE (1 << 12) /* 4KB. */ + +static signed char test_blob1[] = { 0xc, 0xa, 0xf, 0xf, 0xe }; +static unsigned test_blob2[] = { 0x3, 0x2, 0x1, 0x0, 0x1, 0x2, 0x3 }; +static unsigned char test_blob3[BIG_BLOB_SIZE]; + +void +create_code (gcc_jit_context *ctxt, void *user_data) +{ + /* Let's try to inject the equivalent of: + + signed char bin_blob1[] = { 0xc, 0xa, 0xf, 0xf, 0xe }; + unsigned bin_blob2[] = { 0x3, 0x2, 0x1, 0x0, 0x1, 0x2, 0x3 }; + unsigned char bin_blob3[4096]... + */ + gcc_jit_type *unsigned_char_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_UNSIGNED_CHAR); + gcc_jit_type *signed_char_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_SIGNED_CHAR); + gcc_jit_type *unsigned_type = + gcc_jit_context_get_type (ctxt, GCC_JIT_TYPE_UNSIGNED_INT); + + gcc_jit_lvalue *glob = + gcc_jit_context_new_global ( + ctxt, NULL, GCC_JIT_GLOBAL_EXPORTED, + gcc_jit_context_new_array_type (ctxt, NULL, signed_char_type, + sizeof (test_blob1)), + "bin_blob1"); + gcc_jit_global_set_initializer (glob, test_blob1, sizeof (test_blob1)); + + glob = + gcc_jit_context_new_global ( + ctxt, NULL, GCC_JIT_GLOBAL_EXPORTED, + gcc_jit_context_new_array_type ( + ctxt, NULL, unsigned_type, + sizeof (test_blob2) / sizeof (*test_blob2)), + "bin_blob2"); + gcc_jit_global_set_initializer (glob, test_blob2, + sizeof (test_blob2)); + + for (size_t i = 0; i < BIG_BLOB_SIZE; i++) + test_blob3[i] = i * i + i; + glob = + gcc_jit_context_new_global ( + ctxt, NULL, GCC_JIT_GLOBAL_EXPORTED, + gcc_jit_context_new_array_type (ctxt, NULL, unsigned_char_type, + sizeof (test_blob3)), + "bin_blob3"); + gcc_jit_global_set_initializer (glob, test_blob3, sizeof (test_blob3)); +} + +void +verify_code (gcc_jit_context *ctxt, gcc_jit_result *result) +{ + CHECK_NON_NULL (result); + void *glob = gcc_jit_result_get_global (result, "bin_blob1"); + CHECK_NON_NULL (glob); + CHECK_VALUE (memcmp (test_blob1, glob, sizeof (test_blob1)), 0); + + glob = gcc_jit_result_get_global (result, "bin_blob2"); + CHECK_NON_NULL (glob); + CHECK_VALUE (memcmp (test_blob2, glob, + sizeof (test_blob2)), 0); + + glob = gcc_jit_result_get_global (result, "bin_blob3"); + CHECK_NON_NULL (glob); + CHECK_VALUE (memcmp (test_blob3, glob, sizeof (test_blob3)), 0); + +} -- 2.17.1 --=-=-=--