From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 78957 invoked by alias); 19 Aug 2019 15:11:18 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Received: (qmail 78948 invoked by uid 89); 19 Aug 2019 15:11:18 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-3.9 required=5.0 tests=AWL,BAYES_00,SPF_PASS autolearn=ham version=3.3.1 spammy=slip, areas, sk:promote, traditionally X-HELO: foss.arm.com Received: from foss.arm.com (HELO foss.arm.com) (217.140.110.172) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 19 Aug 2019 15:11:15 +0000 Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 0A10328 for ; Mon, 19 Aug 2019 08:11:14 -0700 (PDT) Received: from localhost (e121540-lin.manchester.arm.com [10.32.99.62]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id A56093F718 for ; Mon, 19 Aug 2019 08:11:13 -0700 (PDT) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard.sandiford@arm.com Subject: [00/13] Pass an argument descriptor to target hooks Date: Mon, 19 Aug 2019 15:15:00 -0000 Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.1 (gnu/linux) MIME-Version: 1.0 Content-Type: text/plain X-IsSubscribed: yes X-SW-Source: 2019-08/txt/msg01303.txt.bz2 For the SVE calling conventions, function_arg and function_arg_advance need to know whether an argument is being passed by reference or not. The simplest way of providing that information would have been to add a new parameter, or convert the "named" parameter into a bitmask. But it seemed cleaner to wrap the argument information in a struct/class instead. The bulk of this series therefore adds a function_arg_info that initially records the type, mode and named flag. The final patch then adds the pass-by-reference information as well, which becomes a small change on its own. The new struct/class inherits a couple of non-obvious points of the current interface: (a) For some hooks the mode is the mode of the type. For others it's the mode after promotion. On targets that use argument promotion, this affects the choice between the mode and the type when both pieces of information are specified. (a) Traditionally the type is null when calling libgcc support functions. But I think the argument conceptually still has a type (most of the functions are written in C after all). It's just that the type is inferred from the unpromoted mode rather than being specified directly. So when we have access to the unpromoted mode, we can still query some properties of the type even if we don't have access to the type itself. (I remember it was said years ago that we should clean this up and call libgcc functions like any other function. But TBH I can't see that ever happening.) Of course, the ABI support is one of the most sensitive areas of the compiler and it would be very easy to introduce a silent ABI break. I've therefore tried to be conservative and stick to the following changes: (1) Replace uses of the old parameters with the corresponding fields of the function_arg_info (which hold the same values as before). (2) In cases where the mode is the unpromoted mode, replace the calculation: type ? int_size_in_bytes (type) : GET_MODE_SIZE (mode) with a new type_size_in_bytes (), which computes the same thing in the same way. [The name is based on (b) above -- every argument has a type, even if we aren't given it explicitly.] (3) In cases where the mode is the promoted mode, replace the calculation: mode == BLKmode ? int_size_in_bytes (type) : GET_MODE_SIZE (mode) with a new promoted_size_in_bytes (), which computes the same thing in the same way. Not all the affected targets use argument promotion, but that's what the calculation is logically providing in the affected contexts. [The only case I found in which the calculation was used for an unpromoted mode was aarch64_pass_by_reference. Other targets use the expression in (2) here, and the later: /* Aggregates are passed by reference based on their size. */ if (type && AGGREGATE_TYPE_P (type)) { size = int_size_in_bytes (type); } suggests that that might have been the intention for aarch64 too. The series just leaves the aarch64 calculation as-is.] (4) In cases where the mode is the promoted mode, replace the calculation: mode == BLKmode && type ? int_size_in_bytes (type) : GET_MODE_SIZE (mode) with promoted_size_in_bytes (), as for (3). This means that the compiler will now ICE (via a segfault) on the invalid combination: mode == BLKmode && !type which I think is preferable to letting the error slip past. (5) Replace the common test: type && AGGREGRATE_TYPE_P (type) with a new aggregate_type_p (), which computes the same thing in the same way. This is again based on point (b) above. (6) In function_arg only, replace: mode == VOIDmode and type == void_type_node (or both) with end_marker_p (). Bootstrapped & regression-tested on aarch64-linux-gnu and x86_64-linux-gnu (all languages for the latter). I also tested each individual patch in the series by compiling at least one target per CPU directory, checking for no new warnings, and checking that there were no changes in assembly output for gcc.c-torture, gcc.dg and g++.dg at -O0. diffstat for series: 66 files changed, 1676 insertions(+), 2246 deletions(-) although admittedly a lot of that comes from culling out-of-date comments. Richard