From patchwork Sun Nov 22 13:49:28 2015 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 547325 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org 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 2A5021402A8 for ; Mon, 23 Nov 2015 00:49:44 +1100 (AEDT) Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b=Bx8vbHfs; dkim-atps=neutral DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:subject:message-id:references:mime-version:content-type :in-reply-to; q=dns; s=default; b=Akwz2+RSdILKYgRGrqTcFe+aB+vPoQ CMI5PqP1FD+MFsCsxknPdJgsZpII3mAYmDJ0ejy41ZDPXK4eDmdbbu+ii8gV1sMR tKpOjJKJy7dU5iceRWeY2HuPSGnU4pfBBRBIKr5MhL3Jho1Lko2j1uzvHFjWhamK OuZ3YBZFk+9g0= 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:date :from:to:subject:message-id:references:mime-version:content-type :in-reply-to; s=default; bh=mjZ2JJYyI+Zmc4gXjzKP44PLMDE=; b=Bx8v bHfsjQdnVHJs6T4sfUWQAO9LEVnryTMWn5evKZTSTkJBGbKpp0BbTMOr1ecznA+D OrlhF4dxg5izBejonm3Elc3YX0ri11rl6n3c5D5Q7zXY0eNew3TxyN5ARfmpJMAd 3uwmru6xm03odUW8tX9r4avMGF5gKoEGyctRGsQ= Received: (qmail 68678 invoked by alias); 22 Nov 2015 13:49:35 -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 68663 invoked by uid 89); 22 Nov 2015 13:49:34 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-2.6 required=5.0 tests=BAYES_00, FREEMAIL_FROM, RCVD_IN_DNSWL_LOW, SPF_PASS autolearn=ham version=3.3.2 X-HELO: mail-pa0-f47.google.com Received: from mail-pa0-f47.google.com (HELO mail-pa0-f47.google.com) (209.85.220.47) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (AES128-GCM-SHA256 encrypted) ESMTPS; Sun, 22 Nov 2015 13:49:31 +0000 Received: by pacej9 with SMTP id ej9so164366923pac.2 for ; Sun, 22 Nov 2015 05:49:29 -0800 (PST) X-Received: by 10.68.220.3 with SMTP id ps3mr30097194pbc.153.1448200169733; Sun, 22 Nov 2015 05:49:29 -0800 (PST) Received: from gnu-tools-1.localdomain (c-50-136-206-211.hsd1.ca.comcast.net. [50.136.206.211]) by smtp.gmail.com with ESMTPSA id h28sm6308419pfd.70.2015.11.22.05.49.29 (version=TLS1_2 cipher=ECDHE-RSA-AES128-GCM-SHA256 bits=128/128); Sun, 22 Nov 2015 05:49:29 -0800 (PST) Received: by gnu-tools-1.localdomain (Postfix, from userid 1000) id 465EE1C5A09; Sun, 22 Nov 2015 05:49:28 -0800 (PST) Date: Sun, 22 Nov 2015 05:49:28 -0800 From: "H.J. Lu" To: gcc-patches@gcc.gnu.org, Jeffrey Law , Richard Biener Subject: [PATCH] Add TARGET_FUNCTION_INCOMING_ARG_RTL Message-ID: <20151122134928.GA8596@gmail.com> References: MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.24 (2015-08-30) X-IsSubscribed: yes On Sat, Nov 21, 2015 at 11:19:57AM -0800, H.J. Lu wrote: > When implementing interrupt attribute for x86 interrupt handlers, we > have a difficult time to access interrupt data passed down by x86 > processors. On x86, interrupt handlers are only called by processors > which push interrupt data onto stack at the address where the normal > return address is. Interrupt handlers must access interrupt data via > pointers so that they can update interrupt data. > > TARGET_FUNCTION_ARG_ADVANCE is skipped by interrupt handlers since they > are only called by processors. Since interrupt data is at one word > below the normal argument location on stack and must be accessed via > pointer, we changed TARGET_FUNCTION_ARG to return a fake hard register > for interrupt handlers and updated expander to covert the fake register > to its address on stack. > > However, we run into problems with > > /* For PARM_DECL, holds an RTL for the stack slot or register > where the data was actually passed. */ > #define DECL_INCOMING_RTL(NODE) \ > (PARM_DECL_CHECK (NODE)->parm_decl.incoming_rtl) > > >From what I can tell, DECL_INCOMING_RTL is a constant after it is set up. > For interrupt handlers, DECL_INCOMING_RTL contains a fake register, > which isn't a problem in codegen since it is covered by expander. But > DECL_INCOMING_RTL is also used to generate debug information and debug > output never expects a fake register in DECL_INCOMING_RTL. To work around > it, we changed x86 prologue expander to update DECL_INCOMING_RTL with the > fake register in interrupt handlers to its address on stack. > > We are asking middle-end maintainers, is this a correct solution? If not, > what other approaches should we try? > > A target machine may have a special DECL_INCOMING_RTL which must be converted for the correct location. This patch adds a target hook to get the location where the argument will appear to the callee. The default is DECL_INCOMING_RTL. It replaces DECL_INCOMING_RTL with get_decl_incoming_rtl when DECL_INCOMING_RTL is used to get the location. Only DWARF debug output is updated since DBX and SDB debug formats can't handle "(plus:DI (reg/f:DI 16 argp) (const_int -8))" for a pointer argument. Does it make sense? Thanks. H.J. ---- * combine.c (setup_incoming_promotions): Replace DECL_INCOMING_RTL with get_decl_incoming_rtl. * dwarf2out.c (add_var_loc_to_decl): Likewise. (rtl_for_decl_location): Likewise. * var-tracking.c (add_stores): Likewise. (vt_add_function_parameter): Likewise. * emit-rtl.c (get_decl_incoming_rtl): New function. * targhooks.c (default_function_incoming_arg_rtl): Likewise. * emit-rtl.h (get_decl_incoming_rtl): New prototype. * targhooks.h (default_function_incoming_arg_rtl): Likewise. * target.def (function_incoming_arg_rtl): New hook. * doc/tm.texi.in: Add TARGET_FUNCTION_INCOMING_ARG_RTL. * doc/tm.texi: Updated. --- gcc/combine.c | 2 +- gcc/doc/tm.texi | 8 ++++++++ gcc/doc/tm.texi.in | 2 ++ gcc/dwarf2out.c | 21 ++++++++++++--------- gcc/emit-rtl.c | 8 ++++++++ gcc/emit-rtl.h | 1 + gcc/target.def | 12 ++++++++++++ gcc/targhooks.c | 6 ++++++ gcc/targhooks.h | 1 + gcc/var-tracking.c | 19 +++++++++++-------- 10 files changed, 62 insertions(+), 18 deletions(-) diff --git a/gcc/combine.c b/gcc/combine.c index 2a66fd5..01c43a2 100644 --- a/gcc/combine.c +++ b/gcc/combine.c @@ -1543,7 +1543,7 @@ setup_incoming_promotions (rtx_insn *first) for (arg = DECL_ARGUMENTS (current_function_decl); arg; arg = DECL_CHAIN (arg)) { - rtx x, reg = DECL_INCOMING_RTL (arg); + rtx x, reg = get_decl_incoming_rtl (arg); int uns1, uns3; machine_mode mode1, mode2, mode3, mode4; diff --git a/gcc/doc/tm.texi b/gcc/doc/tm.texi index bde808b..b727f20 100644 --- a/gcc/doc/tm.texi +++ b/gcc/doc/tm.texi @@ -3953,6 +3953,14 @@ If @code{TARGET_FUNCTION_INCOMING_ARG} is not defined, @code{TARGET_FUNCTION_ARG} serves both purposes. @end deftypefn +@deftypefn {Target Hook} rtx TARGET_FUNCTION_INCOMING_ARG_RTL (const_tree @var{parmdecl}) +Define this hook if the target machine has a special @code{DECL_INCOMING_RTL} +which must be converted for the correct location. + +If @code{TARGET_FUNCTION_INCOMING_ARG_RTL} is not defined, +@code{DECL_INCOMING_RTL} of the input @var{parmdecl} will be used. +@end deftypefn + @deftypefn {Target Hook} bool TARGET_USE_PSEUDO_PIC_REG (void) This hook should return 1 in case pseudo register should be created for pic_offset_table_rtx during function expand. diff --git a/gcc/doc/tm.texi.in b/gcc/doc/tm.texi.in index 0677fc1..dbd1f0b 100644 --- a/gcc/doc/tm.texi.in +++ b/gcc/doc/tm.texi.in @@ -3369,6 +3369,8 @@ the stack. @hook TARGET_FUNCTION_INCOMING_ARG +@hook TARGET_FUNCTION_INCOMING_ARG_RTL + @hook TARGET_USE_PSEUDO_PIC_REG @hook TARGET_INIT_PIC_REG diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index f184750..1b8b7b2 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -5300,6 +5300,7 @@ add_var_loc_to_decl (tree decl, rtx loc_note, const char *label) else temp = *slot; + rtx incoming_rtl; /* For PARM_DECLs try to keep around the original incoming value, even if that means we'll emit a zero-range .debug_loc entry. */ if (temp->last @@ -5307,10 +5308,10 @@ add_var_loc_to_decl (tree decl, rtx loc_note, const char *label) && TREE_CODE (decl) == PARM_DECL && NOTE_P (temp->first->loc) && NOTE_VAR_LOCATION_DECL (temp->first->loc) == decl - && DECL_INCOMING_RTL (decl) + && (incoming_rtl = get_decl_incoming_rtl (decl)) && NOTE_VAR_LOCATION_LOC (temp->first->loc) && GET_CODE (NOTE_VAR_LOCATION_LOC (temp->first->loc)) - == GET_CODE (DECL_INCOMING_RTL (decl)) + == GET_CODE (incoming_rtl) && prev_real_insn (temp->first->loc) == NULL_RTX && (bitsize != -1 || !rtx_equal_p (NOTE_VAR_LOCATION_LOC (temp->first->loc), @@ -15972,13 +15973,15 @@ rtl_for_decl_location (tree decl) } else if (TREE_CODE (decl) == PARM_DECL) { + rtx incoming_rtl = get_decl_incoming_rtl (decl); + if (rtl == NULL_RTX || is_pseudo_reg (rtl) || (MEM_P (rtl) && is_pseudo_reg (XEXP (rtl, 0)) - && DECL_INCOMING_RTL (decl) - && MEM_P (DECL_INCOMING_RTL (decl)) - && GET_MODE (rtl) == GET_MODE (DECL_INCOMING_RTL (decl)))) + && incoming_rtl + && MEM_P (incoming_rtl) + && GET_MODE (rtl) == GET_MODE (incoming_rtl))) { tree declared_type = TREE_TYPE (decl); tree passed_type = DECL_ARG_TYPE (decl); @@ -15989,13 +15992,13 @@ rtl_for_decl_location (tree decl) Note that DECL_INCOMING_RTL may be NULL in here, but we handle all cases where (rtl == NULL_RTX) just below. */ if (dmode == pmode) - rtl = DECL_INCOMING_RTL (decl); + rtl = incoming_rtl; else if ((rtl == NULL_RTX || is_pseudo_reg (rtl)) && SCALAR_INT_MODE_P (dmode) && GET_MODE_SIZE (dmode) <= GET_MODE_SIZE (pmode) - && DECL_INCOMING_RTL (decl)) + && incoming_rtl) { - rtx inc = DECL_INCOMING_RTL (decl); + rtx inc = incoming_rtl; if (REG_P (inc)) rtl = inc; else if (MEM_P (inc)) @@ -16021,7 +16024,7 @@ rtl_for_decl_location (tree decl) && XEXP (rtl, 0) != const0_rtx && ! CONSTANT_P (XEXP (rtl, 0)) /* Not passed in memory. */ - && !MEM_P (DECL_INCOMING_RTL (decl)) + && !MEM_P (incoming_rtl) /* Not passed by invisible reference. */ && (!REG_P (XEXP (rtl, 0)) || REGNO (XEXP (rtl, 0)) == HARD_FRAME_POINTER_REGNUM diff --git a/gcc/emit-rtl.c b/gcc/emit-rtl.c index c6a37e1..53ae12b 100644 --- a/gcc/emit-rtl.c +++ b/gcc/emit-rtl.c @@ -1290,6 +1290,14 @@ set_decl_incoming_rtl (tree t, rtx x, bool by_reference_p) set_reg_attrs_for_decl_rtl (t, x); } +/* Return the location where the argument appears to the callee. */ + +rtx +get_decl_incoming_rtl (const_tree parmdecl) +{ + return targetm.calls.function_incoming_arg_rtl (parmdecl); +} + /* Identify REG (which may be a CONCAT) as a user register. */ void diff --git a/gcc/emit-rtl.h b/gcc/emit-rtl.h index f52c335..b48c721 100644 --- a/gcc/emit-rtl.h +++ b/gcc/emit-rtl.h @@ -430,6 +430,7 @@ get_max_uid (void) } extern void set_decl_incoming_rtl (tree, rtx, bool); +extern rtx get_decl_incoming_rtl (const_tree); /* Return a memory reference like MEMREF, but with its mode changed to MODE and its address changed to ADDR. diff --git a/gcc/target.def b/gcc/target.def index b0ad09e..979bd5f 100644 --- a/gcc/target.def +++ b/gcc/target.def @@ -4493,6 +4493,18 @@ If @code{TARGET_FUNCTION_INCOMING_ARG} is not defined,\n\ bool named), default_function_incoming_arg) +/* Return the location where the argument will appear to the callee. */ +DEFHOOK +(function_incoming_arg_rtl, + "Define this hook if the target machine has a special\ + @code{DECL_INCOMING_RTL}\n\ +which must be converted for the correct location.\n\ +\n\ +If @code{TARGET_FUNCTION_INCOMING_ARG_RTL} is not defined,\n\ +@code{DECL_INCOMING_RTL} of the input @var{parmdecl} will be used.", + rtx, (const_tree parmdecl), + default_function_incoming_arg_rtl) + DEFHOOK (function_arg_boundary, "This hook returns the alignment boundary, in bits, of an argument\n\ diff --git a/gcc/targhooks.c b/gcc/targhooks.c index 01d3686..7449b36 100644 --- a/gcc/targhooks.c +++ b/gcc/targhooks.c @@ -661,6 +661,12 @@ default_function_incoming_arg (cumulative_args_t ca ATTRIBUTE_UNUSED, gcc_unreachable (); } +rtx +default_function_incoming_arg_rtl (const_tree parmdecl) +{ + return DECL_INCOMING_RTL (parmdecl); +} + unsigned int default_function_arg_boundary (machine_mode mode ATTRIBUTE_UNUSED, const_tree type ATTRIBUTE_UNUSED) diff --git a/gcc/targhooks.h b/gcc/targhooks.h index f5d04e6..ca5bf48 100644 --- a/gcc/targhooks.h +++ b/gcc/targhooks.h @@ -135,6 +135,7 @@ extern rtx default_function_arg (cumulative_args_t, machine_mode, const_tree, bool); extern rtx default_function_incoming_arg (cumulative_args_t, machine_mode, const_tree, bool); +extern rtx default_function_incoming_arg_rtl (const_tree); extern unsigned int default_function_arg_boundary (machine_mode, const_tree); extern unsigned int default_function_arg_round_boundary (machine_mode, diff --git a/gcc/var-tracking.c b/gcc/var-tracking.c index 9185bfd..9dde705 100644 --- a/gcc/var-tracking.c +++ b/gcc/var-tracking.c @@ -5809,9 +5809,13 @@ add_stores (rtx loc, const_rtx expr, void *cuip) mode2 = mode; + rtx incoming_rtl = NULL; + if (REG_P (loc)) { gcc_assert (loc != cfa_base_rtx); + if (REG_EXPR (loc) && TREE_CODE (REG_EXPR (loc)) == PARM_DECL) + incoming_rtl = get_decl_incoming_rtl (REG_EXPR (loc)); if ((GET_CODE (expr) == CLOBBER && type != MO_VAL_SET) || !(track_p = use_type (loc, NULL, &mode2) == MO_USE) || GET_CODE (expr) == CLOBBER) @@ -5855,9 +5859,8 @@ add_stores (rtx loc, const_rtx expr, void *cuip) && REG_EXPR (loc) && TREE_CODE (REG_EXPR (loc)) == PARM_DECL && DECL_MODE (REG_EXPR (loc)) != BLKmode - && MEM_P (DECL_INCOMING_RTL (REG_EXPR (loc))) - && XEXP (DECL_INCOMING_RTL (REG_EXPR (loc)), 0) - != arg_pointer_rtx) + && MEM_P (incoming_rtl) + && XEXP (incoming_rtl, 0) != arg_pointer_rtx) mo.type = MO_SET; else mo.type = MO_COPY; @@ -5941,10 +5944,10 @@ add_stores (rtx loc, const_rtx expr, void *cuip) && TREE_CODE (REG_EXPR (loc)) == PARM_DECL && DECL_MODE (REG_EXPR (loc)) != BLKmode && TREE_CODE (TREE_TYPE (REG_EXPR (loc))) != UNION_TYPE - && ((MEM_P (DECL_INCOMING_RTL (REG_EXPR (loc))) - && XEXP (DECL_INCOMING_RTL (REG_EXPR (loc)), 0) != arg_pointer_rtx) - || (GET_CODE (DECL_INCOMING_RTL (REG_EXPR (loc))) == PARALLEL - && XVECLEN (DECL_INCOMING_RTL (REG_EXPR (loc)), 0) > 1))) + && ((MEM_P (incoming_rtl) + && XEXP (incoming_rtl, 0) != arg_pointer_rtx) + || (GET_CODE (incoming_rtl) == PARALLEL + && XVECLEN (incoming_rtl, 0) > 1))) { /* Although we don't use the value here, it could be used later by the mere virtue of its existence as the operand of the reverse operation @@ -9506,7 +9509,7 @@ static void vt_add_function_parameter (tree parm) { rtx decl_rtl = DECL_RTL_IF_SET (parm); - rtx incoming = DECL_INCOMING_RTL (parm); + rtx incoming = get_decl_incoming_rtl (parm); tree decl; machine_mode mode; HOST_WIDE_INT offset;