From patchwork Mon Aug 19 15:15:21 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Richard Sandiford X-Patchwork-Id: 1149332 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=gcc.gnu.org (client-ip=209.132.180.131; helo=sourceware.org; envelope-from=gcc-patches-return-507262-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=arm.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="ANotWxvW"; dkim-atps=neutral Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46ByDQ07gvz9s3Z for ; Tue, 20 Aug 2019 01:15:49 +1000 (AEST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:references:date:in-reply-to:message-id:mime-version :content-type; q=dns; s=default; b=uT+V55VCWsMJ9O4/jHjIi7QChtm3t nKwzrR1LpMaD9zXtcpNJ9nDNBNzHJuO/6V5IyXBji3QRbutc+Rz+QI8LXIwcPhmB jC2UhLLskObqm+ZGHl5ZBsD0ckqMBoRff45ZHwP5zHdW6fyodAEg3D21JvhG87er nyGBVslojZkpj4= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:from :to:subject:references:date:in-reply-to:message-id:mime-version :content-type; s=default; bh=7pnhE3C+iuEq/Yg6S0MuFpizKzk=; b=ANo tWxvWJ4yOClK2/EsEkxAZzceuooYxAKqQGnSVX2gOQ6z4s06FVfi0EwsontYEcBS hGNzAx2TM2cblUxjnEClpCrRlwCWA+JLF0QAFcYGpc56ZUtPAks/udSMMw8JmYjb DE1tAGtsOua+y9kiUMZZCUkylnsg0mbwxrCn+bJM= Received: (qmail 8353 invoked by alias); 19 Aug 2019 15:15:40 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 8088 invoked by uid 89); 19 Aug 2019 15:15:37 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-8.5 required=5.0 tests=AWL, BAYES_00, GIT_PATCH_2, GIT_PATCH_3, KAM_ASCII_DIVIDERS, SPF_PASS autolearn=ham version=3.3.1 spammy=laid 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:15:30 +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 999CE344 for ; Mon, 19 Aug 2019 08:15:23 -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 08C6D3F718 for ; Mon, 19 Aug 2019 08:15:22 -0700 (PDT) From: Richard Sandiford To: gcc-patches@gcc.gnu.org Mail-Followup-To: gcc-patches@gcc.gnu.org, richard.sandiford@arm.com Subject: [04/13] Use function_arg_info for TARGET_PASS_BY_REFERENCE References: Date: Mon, 19 Aug 2019 16:15:21 +0100 In-Reply-To: (Richard Sandiford's message of "Mon, 19 Aug 2019 16:11:12 +0100") Message-ID: User-Agent: Gnus/5.13 (Gnus v5.13) Emacs/26.1 (gnu/linux) MIME-Version: 1.0 X-IsSubscribed: yes Use function_arg_info for TARGET_PASS_BY_REFERENCE. The hook is passed the unpromoted type mode instead of the promoted mode. 2019-08-19 Richard Sandiford gcc/ * target.def (pass_by_reference): Take a function_arg_info instead of a mode, type and named flag. * doc/tm.texi: Regenerate. * targhooks.h (hook_pass_by_reference_must_pass_in_stack): Update accordingly. (hook_bool_CUMULATIVE_ARGS_arg_info_false): Declare. * targhooks.c (hook_pass_by_reference_must_pass_in_stack): Take a function_arg_info instead of a mode, type and named flag. (hook_bool_CUMULATIVE_ARGS_arg_info_false): New function. * calls.h (pass_by_reference): Take a function_arg_info instead of a mode, type and named flag. * calls.c (pass_by_reference): Likewise. (pass_va_arg_by_reference): Update call accordingly. (initialize_argument_information): Likewise. (emit_library_call_value_1): Likewise. * function.c (assign_parm_find_data_types): Likewise. * var-tracking.c (prepare_call_arguments): Likewise. * stor-layout.c: Include calls.h. (compute_record_mode): Update call to targetm.calls.pass_by_reference. * config/aarch64/aarch64.c (aarch64_pass_by_reference): Take a function_arg_info instead of a mode, type and named flag. * config/alpha/alpha.c (alpha_pass_by_reference): Likewise. * config/arc/arc.c (arc_pass_by_reference): Likewise. * config/arm/arm.c (arm_pass_by_reference): Likewise. * config/bfin/bfin.c (bfin_pass_by_reference): Likewise. * config/c6x/c6x.c (c6x_pass_by_reference): Likewise. (c6x_call_saved_register_used): Update call to pass_by_reference. * config/cris/cris.c (cris_pass_by_reference): Take a function_arg_info instead of a mode, type and named flag. * config/epiphany/epiphany.c (epiphany_pass_by_reference): Take a function_arg_info instead of a mode, type and named flag. (epiphany_arg_partial_bytes): Update call accordingly. * config/ft32/ft32.c (ft32_pass_by_reference): Take a function_arg_info instead of a mode, type and named flag. (ft32_arg_partial_bytes): Update call accordingly. * config/i386/i386.c (ix86_pass_by_reference): Take a function_arg_info instead of a mode, type and named flag. * config/iq2000/iq2000.c (iq2000_pass_by_reference): Likewise. * config/m32c/m32c.c (m32c_pass_by_reference): Likewise. * config/m32r/m32r.c (m32r_pass_by_reference): Likewise. (m32r_return_in_memory): Update call accordingly. * config/mips/mips.c (mips_pass_by_reference): Take a function_arg_info instead of a mode, type and named flag. * config/mmix/mmix.c (mmix_pass_by_reference): Likewise. * config/mn10300/mn10300.c (mn10300_pass_by_reference): Likewise. * config/moxie/moxie.c (moxie_pass_by_reference): Likewise. (moxie_arg_partial_bytes): Update call accordingly. * config/msp430/msp430.c (msp430_pass_by_reference): Take a function_arg_info instead of a mode, type and named flag. * config/nvptx/nvptx.c (nvptx_pass_by_reference): Likewise. * config/or1k/or1k.c (or1k_pass_by_reference): Likewise. * config/pa/pa.c (pa_pass_by_reference): Likewise. * config/riscv/riscv.c (riscv_pass_by_reference): Likewise. (riscv_return_in_memory): Update call accordingly. * config/rs6000/rs6000-internal.h (rs6000_pass_by_reference): Take a function_arg_info instead of a mode, type and named flag. * config/rs6000/rs6000-call.c (rs6000_pass_by_reference): Likewise. (rs6000_parm_needs_stack): Update call to pass_by_reference. * config/s390/s390.c (s390_pass_by_reference): Take a function_arg_info instead of a mode, type and named flag. (s390_call_saved_register_used): Update call accordingly. * config/sh/sh.c (sh_pass_by_reference): Take a function_arg_info instead of a mode, type and named flag. * config/sparc/sparc.c (sparc_pass_by_reference): Likewise. * config/spu/spu.c (spu_pass_by_reference): Likewise. * config/tilegx/tilegx.c (tilegx_pass_by_reference): Likewise. * config/tilepro/tilepro.c (tilepro_pass_by_reference): Likewise. * config/v850/v850.c (v850_pass_by_reference): Likewise. * config/visium/visium.c (visium_pass_by_reference): Likewise. gcc/ada/ * gcc-interface/misc.c (default_pass_by_ref): Update call to pass_by_reference. Index: gcc/target.def =================================================================== --- gcc/target.def 2019-08-19 15:58:21.746125942 +0100 +++ gcc/target.def 2019-08-19 15:58:28.450077433 +0100 @@ -4450,18 +4450,18 @@ or 3-byte structure is returned at the m from __builtin_va_arg. */ DEFHOOK (pass_by_reference, - "This target hook should return @code{true} if an argument at the\n\ + "This target hook should return @code{true} if argument @var{arg} at the\n\ position indicated by @var{cum} should be passed by reference. This\n\ predicate is queried after target independent reasons for being\n\ -passed by reference, such as @code{TREE_ADDRESSABLE (type)}.\n\ +passed by reference, such as @code{TREE_ADDRESSABLE (@var{arg}.type)}.\n\ \n\ If the hook returns true, a copy of that argument is made in memory and a\n\ pointer to the argument is passed instead of the argument itself.\n\ The pointer is passed in whatever way is appropriate for passing a pointer\n\ to that type.", bool, - (cumulative_args_t cum, machine_mode mode, const_tree type, bool named), - hook_bool_CUMULATIVE_ARGS_mode_tree_bool_false) + (cumulative_args_t cum, const function_arg_info &arg), + hook_bool_CUMULATIVE_ARGS_arg_info_false) DEFHOOK (expand_builtin_saveregs, Index: gcc/doc/tm.texi =================================================================== --- gcc/doc/tm.texi 2019-08-19 15:58:21.746125942 +0100 +++ gcc/doc/tm.texi 2019-08-19 15:58:28.450077433 +0100 @@ -4076,11 +4076,11 @@ register to be used by the caller for th @code{TARGET_FUNCTION_INCOMING_ARG}, for the called function. @end deftypefn -@deftypefn {Target Hook} bool TARGET_PASS_BY_REFERENCE (cumulative_args_t @var{cum}, machine_mode @var{mode}, const_tree @var{type}, bool @var{named}) -This target hook should return @code{true} if an argument at the +@deftypefn {Target Hook} bool TARGET_PASS_BY_REFERENCE (cumulative_args_t @var{cum}, const function_arg_info @var{&arg}) +This target hook should return @code{true} if argument @var{arg} at the position indicated by @var{cum} should be passed by reference. This predicate is queried after target independent reasons for being -passed by reference, such as @code{TREE_ADDRESSABLE (type)}. +passed by reference, such as @code{TREE_ADDRESSABLE (@var{arg}.type)}. If the hook returns true, a copy of that argument is made in memory and a pointer to the argument is passed instead of the argument itself. Index: gcc/targhooks.h =================================================================== --- gcc/targhooks.h 2019-08-19 15:58:21.746125942 +0100 +++ gcc/targhooks.h 2019-08-19 15:58:28.450077433 +0100 @@ -63,7 +63,7 @@ extern tree default_cxx_guard_type (void extern tree default_cxx_get_cookie_size (tree); extern bool hook_pass_by_reference_must_pass_in_stack - (cumulative_args_t, machine_mode mode, const_tree, bool); + (cumulative_args_t, const function_arg_info &); extern bool hook_callee_copies_named (cumulative_args_t ca, machine_mode, const_tree, bool); @@ -137,6 +137,8 @@ extern bool hook_bool_CUMULATIVE_ARGS_tr (cumulative_args_t, machine_mode, const_tree, bool); extern bool hook_bool_CUMULATIVE_ARGS_mode_tree_bool_true (cumulative_args_t, machine_mode, const_tree, bool); +extern bool hook_bool_CUMULATIVE_ARGS_arg_info_false + (cumulative_args_t, const function_arg_info &); extern int hook_int_CUMULATIVE_ARGS_arg_info_0 (cumulative_args_t, const function_arg_info &); extern void hook_void_CUMULATIVE_ARGS_tree Index: gcc/targhooks.c =================================================================== --- gcc/targhooks.c 2019-08-19 15:58:21.746125942 +0100 +++ gcc/targhooks.c 2019-08-19 15:58:28.450077433 +0100 @@ -323,11 +323,10 @@ default_cxx_get_cookie_size (tree type) of the TARGET_PASS_BY_REFERENCE hook uses just MUST_PASS_IN_STACK. */ bool -hook_pass_by_reference_must_pass_in_stack (cumulative_args_t c ATTRIBUTE_UNUSED, - machine_mode mode ATTRIBUTE_UNUSED, const_tree type ATTRIBUTE_UNUSED, - bool named_arg ATTRIBUTE_UNUSED) +hook_pass_by_reference_must_pass_in_stack (cumulative_args_t, + const function_arg_info &arg) { - return targetm.calls.must_pass_in_stack (mode, type); + return targetm.calls.must_pass_in_stack (arg.mode, arg.type); } /* Return true if a parameter follows callee copies conventions. This @@ -767,6 +766,13 @@ hook_bool_CUMULATIVE_ARGS_mode_tree_bool return true; } +bool +hook_bool_CUMULATIVE_ARGS_arg_info_false (cumulative_args_t, + const function_arg_info &) +{ + return false; +} + int hook_int_CUMULATIVE_ARGS_arg_info_0 (cumulative_args_t, const function_arg_info &) Index: gcc/calls.h =================================================================== --- gcc/calls.h 2019-08-19 15:58:21.714126173 +0100 +++ gcc/calls.h 2019-08-19 15:58:28.418077667 +0100 @@ -105,8 +105,7 @@ extern bool shift_return_value (machine_ extern rtx expand_call (tree, rtx, int); extern void fixup_tail_calls (void); -extern bool pass_by_reference (CUMULATIVE_ARGS *, machine_mode, - tree, bool); +extern bool pass_by_reference (CUMULATIVE_ARGS *, function_arg_info); extern bool pass_va_arg_by_reference (tree); extern bool reference_callee_copied (CUMULATIVE_ARGS *, machine_mode, tree, bool); Index: gcc/calls.c =================================================================== --- gcc/calls.c 2019-08-19 15:58:21.714126173 +0100 +++ gcc/calls.c 2019-08-19 15:58:28.418077667 +0100 @@ -897,13 +897,12 @@ call_expr_flags (const_tree t) return flags; } -/* Return true if TYPE should be passed by invisible reference. */ +/* Return true if ARG should be passed by invisible reference. */ bool -pass_by_reference (CUMULATIVE_ARGS *ca, machine_mode mode, - tree type, bool named_arg) +pass_by_reference (CUMULATIVE_ARGS *ca, function_arg_info arg) { - if (type) + if (tree type = arg.type) { /* If this type contains non-trivial constructors, then it is forbidden for the middle-end to create any new copies. */ @@ -918,13 +917,12 @@ pass_by_reference (CUMULATIVE_ARGS *ca, member, use the type and mode of that member. */ if (TREE_CODE (type) == RECORD_TYPE && TYPE_TRANSPARENT_AGGR (type)) { - type = TREE_TYPE (first_field (type)); - mode = TYPE_MODE (type); + arg.type = TREE_TYPE (first_field (type)); + arg.mode = TYPE_MODE (arg.type); } } - return targetm.calls.pass_by_reference (pack_cumulative_args (ca), mode, - type, named_arg); + return targetm.calls.pass_by_reference (pack_cumulative_args (ca), arg); } /* Return true if TYPE should be passed by reference when passed to @@ -933,7 +931,7 @@ pass_by_reference (CUMULATIVE_ARGS *ca, bool pass_va_arg_by_reference (tree type) { - return pass_by_reference (NULL, TYPE_MODE (type), type, false); + return pass_by_reference (NULL, function_arg_info (type, /*named=*/false)); } /* Return true if TYPE, which is passed by reference, should be callee @@ -1997,8 +1995,8 @@ initialize_argument_information (int num with those made by function.c. */ /* See if this argument should be passed by invisible reference. */ - if (pass_by_reference (args_so_far_pnt, TYPE_MODE (type), - type, argpos < n_named_args)) + function_arg_info orig_arg (type, argpos < n_named_args); + if (pass_by_reference (args_so_far_pnt, orig_arg)) { bool callee_copies; tree base = NULL_TREE; @@ -4909,7 +4907,8 @@ emit_library_call_value_1 (int retval, r && !(CONSTANT_P (val) && targetm.legitimate_constant_p (mode, val))) val = force_operand (val, NULL_RTX); - if (pass_by_reference (&args_so_far_v, mode, NULL_TREE, 1)) + function_arg_info orig_arg (mode, /*named=*/true); + if (pass_by_reference (&args_so_far_v, orig_arg)) { rtx slot; int must_copy Index: gcc/function.c =================================================================== --- gcc/function.c 2019-08-19 15:58:21.746125942 +0100 +++ gcc/function.c 2019-08-19 15:58:28.450077433 +0100 @@ -2454,13 +2454,15 @@ assign_parm_find_data_types (struct assi passed_type = TREE_TYPE (first_field (passed_type)); /* See if this arg was passed by invisible reference. */ - if (pass_by_reference (&all->args_so_far_v, passed_mode, - passed_type, data->named_arg)) - { - passed_type = nominal_type = build_pointer_type (passed_type); - data->passed_pointer = true; - passed_mode = nominal_mode = TYPE_MODE (nominal_type); - } + { + function_arg_info arg (passed_type, passed_mode, data->named_arg); + if (pass_by_reference (&all->args_so_far_v, arg)) + { + passed_type = nominal_type = build_pointer_type (passed_type); + data->passed_pointer = true; + passed_mode = nominal_mode = TYPE_MODE (nominal_type); + } + } /* Find mode as it is passed by the ABI. */ unsignedp = TYPE_UNSIGNED (passed_type); Index: gcc/var-tracking.c =================================================================== --- gcc/var-tracking.c 2019-07-10 19:41:27.167891845 +0100 +++ gcc/var-tracking.c 2019-08-19 15:58:28.450077433 +0100 @@ -6431,13 +6431,11 @@ prepare_call_arguments (basic_block bb, if (t && t != void_list_node) { tree argtype = TREE_VALUE (t); - machine_mode mode = TYPE_MODE (argtype); rtx reg; - if (pass_by_reference (&args_so_far_v, mode, argtype, true)) - { - argtype = build_pointer_type (argtype); - mode = TYPE_MODE (argtype); - } + function_arg_info orig_arg (argtype, /*named=*/true); + if (pass_by_reference (&args_so_far_v, orig_arg)) + argtype = build_pointer_type (argtype); + machine_mode mode = TYPE_MODE (argtype); reg = targetm.calls.function_arg (args_so_far, mode, argtype, true); if (TREE_CODE (argtype) == REFERENCE_TYPE Index: gcc/stor-layout.c =================================================================== --- gcc/stor-layout.c 2019-07-01 09:37:05.772536611 +0100 +++ gcc/stor-layout.c 2019-08-19 15:58:28.450077433 +0100 @@ -42,6 +42,7 @@ Software Foundation; either version 3, o #include "gimplify.h" #include "attribs.h" #include "debug.h" +#include "calls.h" /* Data type for the expressions representing sizes of data types. It is the first integer type laid out. */ @@ -1859,8 +1860,9 @@ compute_record_mode (tree type) || (TREE_CODE (type) == UNION_TYPE && (GET_MODE_CLASS (mode) == MODE_INT || (GET_MODE_CLASS (mode) == MODE_PARTIAL_INT - && targetm.calls.pass_by_reference (pack_cumulative_args (0), - mode, type, 0))))) + && (targetm.calls.pass_by_reference + (pack_cumulative_args (0), + function_arg_info (type, mode, /*named=*/false))))))) && mode != VOIDmode && poly_int_tree_p (TYPE_SIZE (type), &type_size) && known_eq (GET_MODE_BITSIZE (mode), type_size)) Index: gcc/config/aarch64/aarch64.c =================================================================== --- gcc/config/aarch64/aarch64.c 2019-08-19 15:58:10.746205533 +0100 +++ gcc/config/aarch64/aarch64.c 2019-08-19 15:58:28.422077636 +0100 @@ -4409,35 +4409,30 @@ aarch64_function_ok_for_sibcall (tree de /* Implement TARGET_PASS_BY_REFERENCE. */ static bool -aarch64_pass_by_reference (cumulative_args_t pcum ATTRIBUTE_UNUSED, - machine_mode mode, - const_tree type, - bool named ATTRIBUTE_UNUSED) +aarch64_pass_by_reference (cumulative_args_t, const function_arg_info &arg) { HOST_WIDE_INT size; machine_mode dummymode; int nregs; /* GET_MODE_SIZE (BLKmode) is useless since it is 0. */ - if (mode == BLKmode && type) - size = int_size_in_bytes (type); + if (arg.mode == BLKmode && arg.type) + size = int_size_in_bytes (arg.type); else /* No frontends can create types with variable-sized modes, so we shouldn't be asked to pass or return them. */ - size = GET_MODE_SIZE (mode).to_constant (); + size = GET_MODE_SIZE (arg.mode).to_constant (); /* Aggregates are passed by reference based on their size. */ - if (type && AGGREGATE_TYPE_P (type)) - { - size = int_size_in_bytes (type); - } + if (arg.aggregate_type_p ()) + size = int_size_in_bytes (arg.type); /* Variable sized arguments are always returned by reference. */ if (size < 0) return true; /* Can this be a candidate to be passed in fp/simd register(s)? */ - if (aarch64_vfp_is_call_or_return_candidate (mode, type, + if (aarch64_vfp_is_call_or_return_candidate (arg.mode, arg.type, &dummymode, &nregs, NULL)) return false; Index: gcc/config/alpha/alpha.c =================================================================== --- gcc/config/alpha/alpha.c 2019-08-19 15:58:21.718126146 +0100 +++ gcc/config/alpha/alpha.c 2019-08-19 15:58:28.422077636 +0100 @@ -5710,13 +5710,10 @@ alpha_return_in_memory (const_tree type, return size > UNITS_PER_WORD; } -/* Return true if TYPE should be passed by invisible reference. */ +/* Return true if ARG should be passed by invisible reference. */ static bool -alpha_pass_by_reference (cumulative_args_t ca ATTRIBUTE_UNUSED, - machine_mode mode, - const_tree type ATTRIBUTE_UNUSED, - bool named) +alpha_pass_by_reference (cumulative_args_t, const function_arg_info &arg) { /* Pass float and _Complex float variable arguments by reference. This avoids 64-bit store from a FP register to a pretend args save area @@ -5736,10 +5733,10 @@ alpha_pass_by_reference (cumulative_args to worry about, and passing unpromoted _Float32 and _Complex float as a variable argument will actually work in the future. */ - if (mode == SFmode || mode == SCmode) - return !named; + if (arg.mode == SFmode || arg.mode == SCmode) + return !arg.named; - return mode == TFmode || mode == TCmode; + return arg.mode == TFmode || arg.mode == TCmode; } /* Define how to find the value returned by a function. VALTYPE is the Index: gcc/config/arc/arc.c =================================================================== --- gcc/config/arc/arc.c 2019-08-19 15:58:21.718126146 +0100 +++ gcc/config/arc/arc.c 2019-08-19 15:58:28.426077609 +0100 @@ -7566,14 +7566,11 @@ arc_return_in_memory (const_tree type, c } static bool -arc_pass_by_reference (cumulative_args_t ca_v ATTRIBUTE_UNUSED, - machine_mode mode ATTRIBUTE_UNUSED, - const_tree type, - bool named ATTRIBUTE_UNUSED) +arc_pass_by_reference (cumulative_args_t, const function_arg_info &arg) { - return (type != 0 - && (TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST - || TREE_ADDRESSABLE (type))); + return (arg.type != 0 + && (TREE_CODE (TYPE_SIZE (arg.type)) != INTEGER_CST + || TREE_ADDRESSABLE (arg.type))); } /* Implement TARGET_CAN_USE_DOLOOP_P. */ Index: gcc/config/arm/arm.c =================================================================== --- gcc/config/arm/arm.c 2019-08-19 15:58:21.726126086 +0100 +++ gcc/config/arm/arm.c 2019-08-19 15:58:28.430077578 +0100 @@ -215,7 +215,7 @@ static void arm_insert_attributes (tree, static void arm_setup_incoming_varargs (cumulative_args_t, machine_mode, tree, int *, int); static bool arm_pass_by_reference (cumulative_args_t, - machine_mode, const_tree, bool); + const function_arg_info &); static bool arm_promote_prototypes (const_tree); static bool arm_default_short_enums (void); static bool arm_align_anon_bitfield (void); @@ -6819,11 +6819,9 @@ arm_function_arg_advance (cumulative_arg extension to the ARM ABI. */ static bool -arm_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, - machine_mode mode ATTRIBUTE_UNUSED, - const_tree type, bool named ATTRIBUTE_UNUSED) +arm_pass_by_reference (cumulative_args_t, const function_arg_info &arg) { - return type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST; + return arg.type && TREE_CODE (TYPE_SIZE (arg.type)) != INTEGER_CST; } /* Encode the current state of the #pragma [no_]long_calls. */ Index: gcc/config/bfin/bfin.c =================================================================== --- gcc/config/bfin/bfin.c 2019-08-19 15:58:21.726126086 +0100 +++ gcc/config/bfin/bfin.c 2019-08-19 15:58:28.430077578 +0100 @@ -1741,11 +1741,9 @@ bfin_arg_partial_bytes (cumulative_args_ /* Variable sized types are passed by reference. */ static bool -bfin_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, - machine_mode mode ATTRIBUTE_UNUSED, - const_tree type, bool named ATTRIBUTE_UNUSED) +bfin_pass_by_reference (cumulative_args_t, const function_arg_info &arg) { - return type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST; + return arg.type && TREE_CODE (TYPE_SIZE (arg.type)) != INTEGER_CST; } /* Decide whether a type should be returned in memory (true) Index: gcc/config/c6x/c6x.c =================================================================== --- gcc/config/c6x/c6x.c 2019-08-13 22:35:11.729252254 +0100 +++ gcc/config/c6x/c6x.c 2019-08-19 15:58:28.430077578 +0100 @@ -642,15 +642,13 @@ c6x_function_value_regno_p (const unsign reference. The callee must copy them; see c6x_callee_copies. */ static bool -c6x_pass_by_reference (cumulative_args_t cum_v ATTRIBUTE_UNUSED, - machine_mode mode, const_tree type, - bool named ATTRIBUTE_UNUSED) +c6x_pass_by_reference (cumulative_args_t, const function_arg_info &arg) { int size = -1; - if (type) - size = int_size_in_bytes (type); - else if (mode != VOIDmode) - size = GET_MODE_SIZE (mode); + if (arg.type) + size = int_size_in_bytes (arg.type); + else if (arg.mode != VOIDmode) + size = GET_MODE_SIZE (arg.mode); return size > 2 * UNITS_PER_WORD || size == -1; } @@ -1130,7 +1128,7 @@ c6x_call_saved_register_used (tree call_ mode = TYPE_MODE (type); gcc_assert (mode); - if (pass_by_reference (&cum_v, mode, type, true)) + if (pass_by_reference (&cum_v, function_arg_info (type, /*named=*/true))) { mode = Pmode; type = build_pointer_type (type); Index: gcc/config/cris/cris.c =================================================================== --- gcc/config/cris/cris.c 2019-08-19 15:58:21.726126086 +0100 +++ gcc/config/cris/cris.c 2019-08-19 15:58:28.430077578 +0100 @@ -139,8 +139,8 @@ static int cris_register_move_cost (mach static int cris_memory_move_cost (machine_mode, reg_class_t, bool); static bool cris_rtx_costs (rtx, machine_mode, int, int, int *, bool); static int cris_address_cost (rtx, machine_mode, addr_space_t, bool); -static bool cris_pass_by_reference (cumulative_args_t, machine_mode, - const_tree, bool); +static bool cris_pass_by_reference (cumulative_args_t, + const function_arg_info &); static int cris_arg_partial_bytes (cumulative_args_t, const function_arg_info &); static rtx cris_function_arg (cumulative_args_t, machine_mode, @@ -4041,16 +4041,14 @@ cris_setup_incoming_varargs (cumulative_ ca->regs, *pretend_arg_size, second_time); } -/* Return true if TYPE must be passed by invisible reference. +/* Return true if ARG must be passed by invisible reference. For cris, we pass <= 8 bytes by value, others by reference. */ static bool -cris_pass_by_reference (cumulative_args_t ca ATTRIBUTE_UNUSED, - machine_mode mode, const_tree type, - bool named ATTRIBUTE_UNUSED) +cris_pass_by_reference (cumulative_args_t, const function_arg_info &arg) { - return (targetm.calls.must_pass_in_stack (mode, type) - || CRIS_FUNCTION_ARG_SIZE (mode, type) > 8); + return (targetm.calls.must_pass_in_stack (arg.mode, arg.type) + || CRIS_FUNCTION_ARG_SIZE (arg.mode, arg.type) > 8); } /* A combination of defining TARGET_PROMOTE_FUNCTION_MODE, promoting arguments Index: gcc/config/epiphany/epiphany.c =================================================================== --- gcc/config/epiphany/epiphany.c 2019-08-19 15:58:21.730126059 +0100 +++ gcc/config/epiphany/epiphany.c 2019-08-19 15:58:28.434077550 +0100 @@ -71,8 +71,8 @@ static int get_epiphany_condition_code ( static tree epiphany_handle_interrupt_attribute (tree *, tree, tree, int, bool *); static tree epiphany_handle_forwarder_attribute (tree *, tree, tree, int, bool *); -static bool epiphany_pass_by_reference (cumulative_args_t, machine_mode, - const_tree, bool); +static bool epiphany_pass_by_reference (cumulative_args_t, + const function_arg_info &); static rtx_insn *frame_insn (rtx); /* defines for the initialization of the GCC target structure. */ @@ -749,8 +749,7 @@ epiphany_arg_partial_bytes (cumulative_a { int words = 0, rounded_cum; - gcc_assert (!epiphany_pass_by_reference (cum, arg.mode, arg.type, - arg.named)); + gcc_assert (!epiphany_pass_by_reference (cum, arg)); rounded_cum = ROUND_ADVANCE_CUM (*get_cumulative_args (cum), arg.mode, arg.type); @@ -1487,14 +1486,12 @@ epiphany_return_in_memory (const_tree ty passed by reference. */ static bool -epiphany_pass_by_reference (cumulative_args_t ca ATTRIBUTE_UNUSED, - machine_mode mode, const_tree type, - bool named ATTRIBUTE_UNUSED) +epiphany_pass_by_reference (cumulative_args_t, const function_arg_info &arg) { - if (type) + if (tree type = arg.type) { if (AGGREGATE_TYPE_P (type) - && (mode == BLKmode || TYPE_NEEDS_CONSTRUCTING (type))) + && (arg.mode == BLKmode || TYPE_NEEDS_CONSTRUCTING (type))) return true; } return false; Index: gcc/config/ft32/ft32.c =================================================================== --- gcc/config/ft32/ft32.c 2019-08-19 15:58:21.730126059 +0100 +++ gcc/config/ft32/ft32.c 2019-08-19 15:58:28.434077550 +0100 @@ -684,25 +684,15 @@ ft32_function_arg_advance (cumulative_ar ? *cum + ((3 + FT32_FUNCTION_ARG_SIZE (mode, type)) / 4) : *cum); } -/* Return non-zero if the function argument described by TYPE is to be +/* Return non-zero if the function argument described by ARG is to be passed by reference. */ static bool -ft32_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, - machine_mode mode, const_tree type, - bool named ATTRIBUTE_UNUSED) +ft32_pass_by_reference (cumulative_args_t, const function_arg_info &arg) { - unsigned HOST_WIDE_INT size; - - if (type) - { - if (AGGREGATE_TYPE_P (type)) - return true; - size = int_size_in_bytes (type); - } - else - size = GET_MODE_SIZE (mode); - + if (arg.aggregate_type_p ()) + return true; + unsigned HOST_WIDE_INT size = arg.type_size_in_bytes (); return size > 4 * 6; } @@ -719,7 +709,7 @@ ft32_arg_partial_bytes (cumulative_args_ if (*cum >= 8) return 0; - if (ft32_pass_by_reference (cum_v, arg.mode, arg.type, arg.named)) + if (ft32_pass_by_reference (cum_v, arg)) size = 4; else if (arg.type) { Index: gcc/config/i386/i386.c =================================================================== --- gcc/config/i386/i386.c 2019-08-19 15:58:10.754205475 +0100 +++ gcc/config/i386/i386.c 2019-08-19 15:58:28.434077550 +0100 @@ -3286,8 +3286,7 @@ ix86_function_arg (cumulative_args_t cum appropriate for passing a pointer to that type. */ static bool -ix86_pass_by_reference (cumulative_args_t cum_v, machine_mode mode, - const_tree type, bool) +ix86_pass_by_reference (cumulative_args_t cum_v, const function_arg_info &arg) { CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); @@ -3298,9 +3297,9 @@ ix86_pass_by_reference (cumulative_args_ /* See Windows x64 Software Convention. */ if (call_abi == MS_ABI) { - HOST_WIDE_INT msize = GET_MODE_SIZE (mode); + HOST_WIDE_INT msize = GET_MODE_SIZE (arg.mode); - if (type) + if (tree type = arg.type) { /* Arrays are passed by reference. */ if (TREE_CODE (type) == ARRAY_TYPE) @@ -3317,7 +3316,7 @@ ix86_pass_by_reference (cumulative_args_ /* __m128 is passed by reference. */ return msize != 1 && msize != 2 && msize != 4 && msize != 8; } - else if (type && int_size_in_bytes (type) == -1) + else if (arg.type && int_size_in_bytes (arg.type) == -1) return true; } Index: gcc/config/iq2000/iq2000.c =================================================================== --- gcc/config/iq2000/iq2000.c 2019-08-19 15:58:21.734126028 +0100 +++ gcc/config/iq2000/iq2000.c 2019-08-19 15:58:28.434077550 +0100 @@ -159,8 +159,8 @@ static int iq2000_address_cost (r bool); static section *iq2000_select_section (tree, int, unsigned HOST_WIDE_INT); static rtx iq2000_legitimize_address (rtx, rtx, machine_mode); -static bool iq2000_pass_by_reference (cumulative_args_t, machine_mode, - const_tree, bool); +static bool iq2000_pass_by_reference (cumulative_args_t, + const function_arg_info &); static int iq2000_arg_partial_bytes (cumulative_args_t, const function_arg_info &arg); static rtx iq2000_function_arg (cumulative_args_t, @@ -2292,8 +2292,8 @@ iq2000_function_value_regno_p (const uns /* Return true when an argument must be passed by reference. */ static bool -iq2000_pass_by_reference (cumulative_args_t cum_v, machine_mode mode, - const_tree type, bool named ATTRIBUTE_UNUSED) +iq2000_pass_by_reference (cumulative_args_t cum_v, + const function_arg_info &arg) { CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); int size; @@ -2301,7 +2301,7 @@ iq2000_pass_by_reference (cumulative_arg /* We must pass by reference if we would be both passing in registers and the stack. This is because any subsequent partial arg would be handled incorrectly in this case. */ - if (cum && targetm.calls.must_pass_in_stack (mode, type)) + if (cum && targetm.calls.must_pass_in_stack (arg.mode, arg.type)) { /* Don't pass the actual CUM to FUNCTION_ARG, because we would get double copies of any offsets generated for small structs @@ -2309,15 +2309,15 @@ iq2000_pass_by_reference (cumulative_arg CUMULATIVE_ARGS temp; temp = *cum; - if (iq2000_function_arg (pack_cumulative_args (&temp), mode, type, named) - != 0) + if (iq2000_function_arg (pack_cumulative_args (&temp), arg.mode, + arg.type, arg.named) != 0) return 1; } - if (type == NULL_TREE || mode == DImode || mode == DFmode) + if (arg.type == NULL_TREE || arg.mode == DImode || arg.mode == DFmode) return 0; - size = int_size_in_bytes (type); + size = int_size_in_bytes (arg.type); return size == -1 || size > UNITS_PER_WORD; } Index: gcc/config/m32c/m32c.c =================================================================== --- gcc/config/m32c/m32c.c 2019-07-01 09:37:06.044534332 +0100 +++ gcc/config/m32c/m32c.c 2019-08-19 15:58:28.434077550 +0100 @@ -78,8 +78,8 @@ static bool m32c_legitimate_address_p (m static bool m32c_addr_space_legitimate_address_p (machine_mode, rtx, bool, addr_space_t); static rtx m32c_function_arg (cumulative_args_t, machine_mode, const_tree, bool); -static bool m32c_pass_by_reference (cumulative_args_t, machine_mode, - const_tree, bool); +static bool m32c_pass_by_reference (cumulative_args_t, + const function_arg_info &); static void m32c_function_arg_advance (cumulative_args_t, machine_mode, const_tree, bool); static unsigned int m32c_function_arg_boundary (machine_mode, const_tree); @@ -1373,10 +1373,7 @@ m32c_function_arg (cumulative_args_t ca_ #undef TARGET_PASS_BY_REFERENCE #define TARGET_PASS_BY_REFERENCE m32c_pass_by_reference static bool -m32c_pass_by_reference (cumulative_args_t ca ATTRIBUTE_UNUSED, - machine_mode mode ATTRIBUTE_UNUSED, - const_tree type ATTRIBUTE_UNUSED, - bool named ATTRIBUTE_UNUSED) +m32c_pass_by_reference (cumulative_args_t, const function_arg_info &) { return 0; } Index: gcc/config/m32r/m32r.c =================================================================== --- gcc/config/m32r/m32r.c 2019-08-19 15:58:21.734126028 +0100 +++ gcc/config/m32r/m32r.c 2019-08-19 15:58:28.434077550 +0100 @@ -91,8 +91,8 @@ static void m32r_setup_incoming_varargs static void init_idents (void); static bool m32r_rtx_costs (rtx, machine_mode, int, int, int *, bool speed); static int m32r_memory_move_cost (machine_mode, reg_class_t, bool); -static bool m32r_pass_by_reference (cumulative_args_t, machine_mode, - const_tree, bool); +static bool m32r_pass_by_reference (cumulative_args_t, + const function_arg_info &arg); static int m32r_arg_partial_bytes (cumulative_args_t, const function_arg_info &); static rtx m32r_function_arg (cumulative_args_t, machine_mode, @@ -680,20 +680,12 @@ memreg_operand (rtx op, machine_mode mod return MEM_P (op) && REG_P (XEXP (op, 0)); } -/* Return nonzero if TYPE must be passed by indirect reference. */ +/* Return nonzero if ARG must be passed by indirect reference. */ static bool -m32r_pass_by_reference (cumulative_args_t ca ATTRIBUTE_UNUSED, - machine_mode mode, const_tree type, - bool named ATTRIBUTE_UNUSED) +m32r_pass_by_reference (cumulative_args_t, const function_arg_info &arg) { - int size; - - if (type) - size = int_size_in_bytes (type); - else - size = GET_MODE_SIZE (mode); - + int size = arg.type_size_in_bytes (); return (size < 0 || size > 8); } @@ -1251,8 +1243,8 @@ m32r_function_arg_advance (cumulative_ar m32r_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED) { cumulative_args_t dummy = pack_cumulative_args (NULL); - - return m32r_pass_by_reference (dummy, TYPE_MODE (type), type, false); + function_arg_info arg (const_cast (type), /*named=*/false); + return m32r_pass_by_reference (dummy, arg); } /* Worker function for TARGET_FUNCTION_VALUE. */ Index: gcc/config/mips/mips.c =================================================================== --- gcc/config/mips/mips.c 2019-08-19 15:58:21.738126000 +0100 +++ gcc/config/mips/mips.c 2019-08-19 15:58:28.438077523 +0100 @@ -6235,27 +6235,25 @@ mips_pad_reg_upward (machine_mode mode, /* Return nonzero when an argument must be passed by reference. */ static bool -mips_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, - machine_mode mode, const_tree type, - bool named ATTRIBUTE_UNUSED) +mips_pass_by_reference (cumulative_args_t, const function_arg_info &arg) { if (mips_abi == ABI_EABI) { int size; /* ??? How should SCmode be handled? */ - if (mode == DImode || mode == DFmode - || mode == DQmode || mode == UDQmode - || mode == DAmode || mode == UDAmode) + if (arg.mode == DImode || arg.mode == DFmode + || arg.mode == DQmode || arg.mode == UDQmode + || arg.mode == DAmode || arg.mode == UDAmode) return 0; - size = type ? int_size_in_bytes (type) : GET_MODE_SIZE (mode); + size = arg.type_size_in_bytes (); return size == -1 || size > UNITS_PER_WORD; } else { /* If we have a variable-sized parameter, we have no choice. */ - return targetm.calls.must_pass_in_stack (mode, type); + return targetm.calls.must_pass_in_stack (arg.mode, arg.type); } } Index: gcc/config/mmix/mmix.c =================================================================== --- gcc/config/mmix/mmix.c 2019-05-29 10:49:36.972709373 +0100 +++ gcc/config/mmix/mmix.c 2019-08-19 15:58:28.438077523 +0100 @@ -161,7 +161,7 @@ static rtx mmix_function_value (const_tr static rtx mmix_libcall_value (machine_mode, const_rtx); static bool mmix_function_value_regno_p (const unsigned int); static bool mmix_pass_by_reference (cumulative_args_t, - machine_mode, const_tree, bool); + const function_arg_info &); static bool mmix_frame_pointer_required (void); static void mmix_asm_trampoline_template (FILE *); static void mmix_trampoline_init (rtx, tree, rtx); @@ -690,17 +690,17 @@ mmix_function_incoming_arg (cumulative_a everything that goes by value. */ static bool -mmix_pass_by_reference (cumulative_args_t argsp_v, machine_mode mode, - const_tree type, bool named ATTRIBUTE_UNUSED) +mmix_pass_by_reference (cumulative_args_t argsp_v, + const function_arg_info &arg) { CUMULATIVE_ARGS *argsp = get_cumulative_args (argsp_v); /* FIXME: Check: I'm not sure the must_pass_in_stack check is necessary. */ - if (targetm.calls.must_pass_in_stack (mode, type)) + if (targetm.calls.must_pass_in_stack (arg.mode, arg.type)) return true; - if (MMIX_FUNCTION_ARG_SIZE (mode, type) > 8 + if (MMIX_FUNCTION_ARG_SIZE (arg.mode, arg.type) > 8 && !TARGET_LIBFUNC && (!argsp || !argsp->lib)) return true; Index: gcc/config/mn10300/mn10300.c =================================================================== --- gcc/config/mn10300/mn10300.c 2019-08-19 15:58:21.738126000 +0100 +++ gcc/config/mn10300/mn10300.c 2019-08-19 15:58:28.438077523 +0100 @@ -1526,17 +1526,9 @@ mn10300_va_start (tree valist, rtx nexta /* Return true when a parameter should be passed by reference. */ static bool -mn10300_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, - machine_mode mode, const_tree type, - bool named ATTRIBUTE_UNUSED) +mn10300_pass_by_reference (cumulative_args_t, const function_arg_info &arg) { - unsigned HOST_WIDE_INT size; - - if (type) - size = int_size_in_bytes (type); - else - size = GET_MODE_SIZE (mode); - + unsigned HOST_WIDE_INT size = arg.type_size_in_bytes (); return (size > 8 || size == 0); } Index: gcc/config/moxie/moxie.c =================================================================== --- gcc/config/moxie/moxie.c 2019-08-19 15:58:21.738126000 +0100 +++ gcc/config/moxie/moxie.c 2019-08-19 15:58:28.438077523 +0100 @@ -451,25 +451,15 @@ moxie_function_arg_advance (cumulative_a : *cum); } -/* Return non-zero if the function argument described by TYPE is to be +/* Return non-zero if the function argument described by ARG is to be passed by reference. */ static bool -moxie_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, - machine_mode mode, const_tree type, - bool named ATTRIBUTE_UNUSED) +moxie_pass_by_reference (cumulative_args_t, const function_arg_info &arg) { - unsigned HOST_WIDE_INT size; - - if (type) - { - if (AGGREGATE_TYPE_P (type)) - return true; - size = int_size_in_bytes (type); - } - else - size = GET_MODE_SIZE (mode); - + if (arg.aggregate_type_p ()) + return true; + unsigned HOST_WIDE_INT size = arg.type_size_in_bytes (); return size > 4*6; } @@ -486,7 +476,7 @@ moxie_arg_partial_bytes (cumulative_args if (*cum >= 8) return 0; - if (moxie_pass_by_reference (cum_v, arg.mode, arg.type, arg.named)) + if (moxie_pass_by_reference (cum_v, arg)) size = 4; else if (arg.type) { Index: gcc/config/msp430/msp430.c =================================================================== --- gcc/config/msp430/msp430.c 2019-08-19 15:58:21.738126000 +0100 +++ gcc/config/msp430/msp430.c 2019-08-19 15:58:28.438077523 +0100 @@ -744,14 +744,11 @@ msp430_arg_partial_bytes (cumulative_arg #define TARGET_PASS_BY_REFERENCE msp430_pass_by_reference static bool -msp430_pass_by_reference (cumulative_args_t cap ATTRIBUTE_UNUSED, - machine_mode mode, - const_tree type, - bool named ATTRIBUTE_UNUSED) +msp430_pass_by_reference (cumulative_args_t, const function_arg_info &arg) { - return (mode == BLKmode - || (type && TREE_CODE (type) == RECORD_TYPE) - || (type && TREE_CODE (type) == UNION_TYPE)); + return (arg.mode == BLKmode + || (arg.type && TREE_CODE (arg.type) == RECORD_TYPE) + || (arg.type && TREE_CODE (arg.type) == UNION_TYPE)); } #undef TARGET_CALLEE_COPIES Index: gcc/config/nvptx/nvptx.c =================================================================== --- gcc/config/nvptx/nvptx.c 2019-08-13 22:35:11.749252108 +0100 +++ gcc/config/nvptx/nvptx.c 2019-08-19 15:58:28.438077523 +0100 @@ -633,11 +633,9 @@ nvptx_function_value_regno_p (const unsi reference in memory. */ static bool -nvptx_pass_by_reference (cumulative_args_t ARG_UNUSED (cum), - machine_mode mode, const_tree type, - bool ARG_UNUSED (named)) +nvptx_pass_by_reference (cumulative_args_t, const function_arg_info &arg) { - return pass_in_memory (mode, type, false); + return pass_in_memory (arg.mode, arg.type, false); } /* Implement TARGET_RETURN_IN_MEMORY. */ Index: gcc/config/or1k/or1k.c =================================================================== --- gcc/config/or1k/or1k.c 2019-07-29 09:39:47.294185050 +0100 +++ gcc/config/or1k/or1k.c 2019-08-19 15:58:28.442077491 +0100 @@ -928,23 +928,16 @@ or1k_legitimate_constant_p (machine_mode #define TARGET_LEGITIMATE_CONSTANT_P or1k_legitimate_constant_p /* Worker for TARGET_PASS_BY_REFERENCE. - Returns true if an argument of TYPE in MODE should be passed by reference - as required by the OpenRISC ABI. On OpenRISC structures, unions and + Returns true if an argument ARG should be passed by reference as + required by the OpenRISC ABI. On OpenRISC structures, unions and arguments larger than 64-bits are passed by reference. */ static bool -or1k_pass_by_reference (cumulative_args_t, machine_mode mode, - const_tree type, bool) +or1k_pass_by_reference (cumulative_args_t, const function_arg_info &arg) { - HOST_WIDE_INT size; - if (type) - { - if (AGGREGATE_TYPE_P (type)) - return true; - size = int_size_in_bytes (type); - } - else - size = GET_MODE_SIZE (mode); + if (arg.aggregate_type_p ()) + return true; + HOST_WIDE_INT size = arg.type_size_in_bytes (); return size < 0 || size > 8; } Index: gcc/config/pa/pa.c =================================================================== --- gcc/config/pa/pa.c 2019-08-19 15:58:21.738126000 +0100 +++ gcc/config/pa/pa.c 2019-08-19 15:58:28.442077491 +0100 @@ -164,8 +164,8 @@ static void output_deferred_profile_coun static void pa_file_end (void); static void pa_init_libfuncs (void); static rtx pa_struct_value_rtx (tree, int); -static bool pa_pass_by_reference (cumulative_args_t, machine_mode, - const_tree, bool); +static bool pa_pass_by_reference (cumulative_args_t, + const function_arg_info &); static int pa_arg_partial_bytes (cumulative_args_t, const function_arg_info &); static void pa_function_arg_advance (cumulative_args_t, machine_mode, const_tree, bool); @@ -6222,17 +6222,9 @@ pa_eh_return_handler_rtx (void) or updates the ABI. */ static bool -pa_pass_by_reference (cumulative_args_t ca ATTRIBUTE_UNUSED, - machine_mode mode, const_tree type, - bool named ATTRIBUTE_UNUSED) +pa_pass_by_reference (cumulative_args_t, const function_arg_info &arg) { - HOST_WIDE_INT size; - - if (type) - size = int_size_in_bytes (type); - else - size = GET_MODE_SIZE (mode); - + HOST_WIDE_INT size = arg.type_size_in_bytes (); if (TARGET_64BIT) return size <= 0; else Index: gcc/config/riscv/riscv.c =================================================================== --- gcc/config/riscv/riscv.c 2019-08-19 15:58:21.738126000 +0100 +++ gcc/config/riscv/riscv.c 2019-08-19 15:58:28.442077491 +0100 @@ -2815,10 +2815,9 @@ riscv_function_value (const_tree type, c /* Implement TARGET_PASS_BY_REFERENCE. */ static bool -riscv_pass_by_reference (cumulative_args_t cum_v, machine_mode mode, - const_tree type, bool named) +riscv_pass_by_reference (cumulative_args_t cum_v, const function_arg_info &arg) { - HOST_WIDE_INT size = type ? int_size_in_bytes (type) : GET_MODE_SIZE (mode); + HOST_WIDE_INT size = arg.type_size_in_bytes (); struct riscv_arg_info info; CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); @@ -2828,7 +2827,7 @@ riscv_pass_by_reference (cumulative_args if (cum != NULL) { /* Don't pass by reference if we can use a floating-point register. */ - riscv_get_arg_info (&info, cum, mode, type, named, false); + riscv_get_arg_info (&info, cum, arg.mode, arg.type, arg.named, false); if (info.num_fprs) return false; } @@ -2848,7 +2847,8 @@ riscv_return_in_memory (const_tree type, /* The rules for returning in memory are the same as for passing the first named argument by reference. */ memset (&args, 0, sizeof args); - return riscv_pass_by_reference (cum, TYPE_MODE (type), type, true); + function_arg_info arg (const_cast (type), /*named=*/true); + return riscv_pass_by_reference (cum, arg); } /* Implement TARGET_SETUP_INCOMING_VARARGS. */ Index: gcc/config/rs6000/rs6000-internal.h =================================================================== --- gcc/config/rs6000/rs6000-internal.h 2019-08-19 15:58:21.742125973 +0100 +++ gcc/config/rs6000/rs6000-internal.h 2019-08-19 15:58:28.442077491 +0100 @@ -150,9 +150,8 @@ extern machine_mode rs6000_promote_funct extern bool rs6000_return_in_memory (const_tree type, const_tree fntype ATTRIBUTE_UNUSED); extern bool rs6000_return_in_msb (const_tree valtype); -extern bool rs6000_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, - machine_mode mode, const_tree type, - bool named ATTRIBUTE_UNUSED); +extern bool rs6000_pass_by_reference (cumulative_args_t, + const function_arg_info &); extern void setup_incoming_varargs (cumulative_args_t cum, machine_mode mode, tree type, int *pretend_size ATTRIBUTE_UNUSED, int no_rtl); Index: gcc/config/rs6000/rs6000-call.c =================================================================== --- gcc/config/rs6000/rs6000-call.c 2019-08-19 15:58:21.742125973 +0100 +++ gcc/config/rs6000/rs6000-call.c 2019-08-19 15:58:28.442077491 +0100 @@ -2111,29 +2111,27 @@ rs6000_arg_partial_bytes (cumulative_arg reference. */ bool -rs6000_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, - machine_mode mode, const_tree type, - bool named ATTRIBUTE_UNUSED) +rs6000_pass_by_reference (cumulative_args_t, const function_arg_info &arg) { - if (!type) + if (!arg.type) return 0; if (DEFAULT_ABI == ABI_V4 && TARGET_IEEEQUAD - && FLOAT128_IEEE_P (TYPE_MODE (type))) + && FLOAT128_IEEE_P (TYPE_MODE (arg.type))) { if (TARGET_DEBUG_ARG) fprintf (stderr, "function_arg_pass_by_reference: V4 IEEE 128-bit\n"); return 1; } - if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (type)) + if (DEFAULT_ABI == ABI_V4 && AGGREGATE_TYPE_P (arg.type)) { if (TARGET_DEBUG_ARG) fprintf (stderr, "function_arg_pass_by_reference: V4 aggregate\n"); return 1; } - if (int_size_in_bytes (type) < 0) + if (int_size_in_bytes (arg.type) < 0) { if (TARGET_DEBUG_ARG) fprintf (stderr, "function_arg_pass_by_reference: variable size\n"); @@ -2142,7 +2140,7 @@ rs6000_pass_by_reference (cumulative_arg /* Allow -maltivec -mabi=no-altivec without warning. Altivec vector modes only exist for GCC vector types if -maltivec. */ - if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (mode)) + if (TARGET_32BIT && !TARGET_ALTIVEC_ABI && ALTIVEC_VECTOR_MODE (arg.mode)) { if (TARGET_DEBUG_ARG) fprintf (stderr, "function_arg_pass_by_reference: AltiVec\n"); @@ -2150,8 +2148,8 @@ rs6000_pass_by_reference (cumulative_arg } /* Pass synthetic vectors in memory. */ - if (TREE_CODE (type) == VECTOR_TYPE - && int_size_in_bytes (type) > (TARGET_ALTIVEC_ABI ? 16 : 8)) + if (TREE_CODE (arg.type) == VECTOR_TYPE + && int_size_in_bytes (arg.type) > (TARGET_ALTIVEC_ABI ? 16 : 8)) { static bool warned_for_pass_big_vectors = false; if (TARGET_DEBUG_ARG) @@ -2200,7 +2198,7 @@ rs6000_parm_needs_stack (cumulative_args /* See if this arg was passed by invisible reference. */ if (pass_by_reference (get_cumulative_args (args_so_far), - TYPE_MODE (type), type, true)) + function_arg_info (type, /*named=*/true))) type = build_pointer_type (type); /* Find mode as it is passed by the ABI. */ Index: gcc/config/s390/s390.c =================================================================== --- gcc/config/s390/s390.c 2019-08-19 15:58:10.762205420 +0100 +++ gcc/config/s390/s390.c 2019-08-19 15:58:28.442077491 +0100 @@ -11953,26 +11953,23 @@ s390_function_arg_integer (machine_mode return false; } -/* Return 1 if a function argument of type TYPE and mode MODE - is to be passed by reference. The ABI specifies that only - structures of size 1, 2, 4, or 8 bytes are passed by value, - all other structures (and complex numbers) are passed by - reference. */ +/* Return 1 if a function argument ARG is to be passed by reference. + The ABI specifies that only structures of size 1, 2, 4, or 8 bytes + are passed by value, all other structures (and complex numbers) are + passed by reference. */ static bool -s390_pass_by_reference (cumulative_args_t ca ATTRIBUTE_UNUSED, - machine_mode mode, const_tree type, - bool named ATTRIBUTE_UNUSED) +s390_pass_by_reference (cumulative_args_t, const function_arg_info &arg) { - int size = s390_function_arg_size (mode, type); + int size = s390_function_arg_size (arg.mode, arg.type); - if (s390_function_arg_vector (mode, type)) + if (s390_function_arg_vector (arg.mode, arg.type)) return false; if (size > 8) return true; - if (type) + if (tree type = arg.type) { if (AGGREGATE_TYPE_P (type) && exact_log2 (size) < 0) return true; @@ -13349,7 +13346,7 @@ s390_call_saved_register_used (tree call /* We assume that in the target function all parameters are named. This only has an impact on vector argument register usage none of which is call-saved. */ - if (pass_by_reference (&cum_v, mode, type, true)) + if (pass_by_reference (&cum_v, function_arg_info (type, /*named=*/true))) { mode = Pmode; type = build_pointer_type (type); Index: gcc/config/sh/sh.c =================================================================== --- gcc/config/sh/sh.c 2019-08-19 15:58:21.742125973 +0100 +++ gcc/config/sh/sh.c 2019-08-19 15:58:28.446077464 +0100 @@ -294,8 +294,8 @@ static machine_mode sh_promote_function_ int *punsignedp, const_tree funtype, int for_return); -static bool sh_pass_by_reference (cumulative_args_t, machine_mode, - const_tree, bool); +static bool sh_pass_by_reference (cumulative_args_t, + const function_arg_info &); static bool sh_callee_copies (cumulative_args_t, machine_mode, const_tree, bool); static int sh_arg_partial_bytes (cumulative_args_t, const function_arg_info &); @@ -7899,12 +7899,11 @@ sh_promote_prototypes (const_tree type) } static bool -sh_pass_by_reference (cumulative_args_t cum_v, machine_mode mode, - const_tree type, bool named ATTRIBUTE_UNUSED) +sh_pass_by_reference (cumulative_args_t cum_v, const function_arg_info &arg) { CUMULATIVE_ARGS *cum = get_cumulative_args (cum_v); - if (targetm.calls.must_pass_in_stack (mode, type)) + if (targetm.calls.must_pass_in_stack (arg.mode, arg.type)) return true; /* ??? std_gimplify_va_arg_expr passes NULL for cum. That function Index: gcc/config/sparc/sparc.c =================================================================== --- gcc/config/sparc/sparc.c 2019-08-19 15:58:21.742125973 +0100 +++ gcc/config/sparc/sparc.c 2019-08-19 15:58:28.446077464 +0100 @@ -655,7 +655,7 @@ static rtx sparc_legitimize_address (rtx static rtx sparc_delegitimize_address (rtx); static bool sparc_mode_dependent_address_p (const_rtx, addr_space_t); static bool sparc_pass_by_reference (cumulative_args_t, - machine_mode, const_tree, bool); + const function_arg_info &); static void sparc_function_arg_advance (cumulative_args_t, machine_mode, const_tree, bool); static rtx sparc_function_arg_1 (cumulative_args_t, @@ -6743,10 +6743,10 @@ sparc_strict_argument_naming (cumulative Specify whether to pass the argument by reference. */ static bool -sparc_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, - machine_mode mode, const_tree type, - bool named ATTRIBUTE_UNUSED) +sparc_pass_by_reference (cumulative_args_t, const function_arg_info &arg) { + tree type = arg.type; + machine_mode mode = arg.mode; if (TARGET_ARCH32) /* Original SPARC 32-bit ABI says that structures and unions, and quad-precision floats are passed by reference. Index: gcc/config/spu/spu.c =================================================================== --- gcc/config/spu/spu.c 2019-08-19 15:58:10.766205389 +0100 +++ gcc/config/spu/spu.c 2019-08-19 15:58:28.446077464 +0100 @@ -3902,11 +3902,9 @@ spu_function_arg_padding (machine_mode, /* Variable sized types are passed by reference. */ static bool -spu_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, - machine_mode mode ATTRIBUTE_UNUSED, - const_tree type, bool named ATTRIBUTE_UNUSED) +spu_pass_by_reference (cumulative_args_t, const function_arg_info &arg) { - return type && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST; + return arg.type && TREE_CODE (TYPE_SIZE (arg.type)) != INTEGER_CST; } Index: gcc/config/tilegx/tilegx.c =================================================================== --- gcc/config/tilegx/tilegx.c 2019-08-19 15:58:10.766205389 +0100 +++ gcc/config/tilegx/tilegx.c 2019-08-19 15:58:28.446077464 +0100 @@ -159,12 +159,11 @@ tilegx_function_ok_for_sibcall (tree dec /* Implement TARGET_PASS_BY_REFERENCE. Variable sized types are passed by reference. */ static bool -tilegx_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, - machine_mode mode ATTRIBUTE_UNUSED, - const_tree type, bool named ATTRIBUTE_UNUSED) +tilegx_pass_by_reference (cumulative_args_t, const function_arg_info &arg) { - return (type && TYPE_SIZE (type) - && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST); + return (arg.type + && TYPE_SIZE (arg.type) + && TREE_CODE (TYPE_SIZE (arg.type)) != INTEGER_CST); } Index: gcc/config/tilepro/tilepro.c =================================================================== --- gcc/config/tilepro/tilepro.c 2019-08-19 15:58:10.766205389 +0100 +++ gcc/config/tilepro/tilepro.c 2019-08-19 15:58:28.446077464 +0100 @@ -134,12 +134,11 @@ tilepro_function_ok_for_sibcall (tree de /* Implement TARGET_PASS_BY_REFERENCE. Variable sized types are passed by reference. */ static bool -tilepro_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, - machine_mode mode ATTRIBUTE_UNUSED, - const_tree type, bool named ATTRIBUTE_UNUSED) +tilepro_pass_by_reference (cumulative_args_t, const function_arg_info &arg) { - return (type && TYPE_SIZE (type) - && TREE_CODE (TYPE_SIZE (type)) != INTEGER_CST); + return (arg.type + && TYPE_SIZE (arg.type) + && TREE_CODE (TYPE_SIZE (arg.type)) != INTEGER_CST); } Index: gcc/config/v850/v850.c =================================================================== --- gcc/config/v850/v850.c 2019-08-19 15:58:21.742125973 +0100 +++ gcc/config/v850/v850.c 2019-08-19 15:58:28.446077464 +0100 @@ -110,20 +110,12 @@ v850_all_frame_related (rtx par) Specify whether to pass the argument by reference. */ static bool -v850_pass_by_reference (cumulative_args_t cum ATTRIBUTE_UNUSED, - machine_mode mode, const_tree type, - bool named ATTRIBUTE_UNUSED) +v850_pass_by_reference (cumulative_args_t, const function_arg_info &arg) { - unsigned HOST_WIDE_INT size; - if (!TARGET_GCC_ABI) return 0; - if (type) - size = int_size_in_bytes (type); - else - size = GET_MODE_SIZE (mode); - + unsigned HOST_WIDE_INT size = arg.type_size_in_bytes (); return size > 8; } Index: gcc/config/visium/visium.c =================================================================== --- gcc/config/visium/visium.c 2019-08-19 15:58:10.766205389 +0100 +++ gcc/config/visium/visium.c 2019-08-19 15:58:28.446077464 +0100 @@ -158,8 +158,8 @@ static struct machine_function *visium_i /* Target hooks and TARGET_INITIALIZER */ -static bool visium_pass_by_reference (cumulative_args_t, machine_mode, - const_tree, bool); +static bool visium_pass_by_reference (cumulative_args_t, + const function_arg_info &); static rtx visium_function_arg (cumulative_args_t, machine_mode, const_tree, bool); @@ -1310,11 +1310,9 @@ visium_reorg (void) /* Return true if an argument must be passed by indirect reference. */ static bool -visium_pass_by_reference (cumulative_args_t ca ATTRIBUTE_UNUSED, - machine_mode mode ATTRIBUTE_UNUSED, - const_tree type, - bool named ATTRIBUTE_UNUSED) +visium_pass_by_reference (cumulative_args_t, const function_arg_info &arg) { + tree type = arg.type; return type && (AGGREGATE_TYPE_P (type) || TREE_CODE (type) == VECTOR_TYPE); } Index: gcc/ada/gcc-interface/misc.c =================================================================== --- gcc/ada/gcc-interface/misc.c 2019-08-19 15:57:58.586293518 +0100 +++ gcc/ada/gcc-interface/misc.c 2019-08-19 15:58:28.414077694 +0100 @@ -1136,7 +1136,7 @@ default_pass_by_ref (tree gnu_type) TYPE_ALIGN (gnu_type)) > 0)) return true; - if (pass_by_reference (NULL, TYPE_MODE (gnu_type), gnu_type, true)) + if (pass_by_reference (NULL, function_arg_info (gnu_type, /*named=*/true))) return true; if (targetm.calls.return_in_memory (gnu_type, NULL_TREE))