From patchwork Fri Aug 31 19:33:48 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "H.J. Lu" X-Patchwork-Id: 964661 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-484890-incoming=patchwork.ozlabs.org@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=gmail.com Authentication-Results: ozlabs.org; dkim=pass (1024-bit key; unprotected) header.d=gcc.gnu.org header.i=@gcc.gnu.org header.b="tzwOuG/s"; dkim=fail reason="signature verification failed" (2048-bit key; unprotected) header.d=gmail.com header.i=@gmail.com header.b="Ozua36nR"; 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 4228gF2Fjqz9s0n for ; Sat, 1 Sep 2018 05:34:00 +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 :mime-version:from:date:message-id:subject:to:cc:content-type; q=dns; s=default; b=HFinq/DAgxnEZbhZDvcTCsfiodI/Looc9RQvKcITC/A TC2hTlIV1HRg/MMYMzG+/iRhKeUm5s6F1rjhz2mJdxeDP7GsGA4+2pre7NmMKbwU IjU+XFFC4C7rWQ4qScq6Kxt4VWDXwg7BvBj3dvraotTUK35bcoilTVpPo76Av1rw = 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 :mime-version:from:date:message-id:subject:to:cc:content-type; s=default; bh=vgtRXT1OjBk3suG+PgHxzOfDMC0=; b=tzwOuG/sZceV2Xz+z uFf7VfH1yRqVdRN02AYw26cBx5RPnwEdzIpM76yl2n2QMHoUUdzjdLZ+6roxQmcy AhSco++qUkovEO3jms8BeqK1qCOnB5nNw/hQ/mYHlm5RwxJ3KWCkRUQAH+mB5KBm C5bx7balA3+liIexcUalX14+7I= Received: (qmail 67798 invoked by alias); 31 Aug 2018 19:33:52 -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 67787 invoked by uid 89); 31 Aug 2018 19:33:52 -0000 Authentication-Results: sourceware.org; auth=none X-Spam-SWARE-Status: No, score=-25.3 required=5.0 tests=AWL, BAYES_00, FREEMAIL_FROM, GIT_PATCH_0, GIT_PATCH_1, GIT_PATCH_2, GIT_PATCH_3, RCVD_IN_DNSWL_NONE, SPF_PASS autolearn=ham version=3.3.2 spammy=i386.c, i386c, UD:i386.c, hjl X-HELO: mail-oi0-f43.google.com Received: from mail-oi0-f43.google.com (HELO mail-oi0-f43.google.com) (209.85.218.43) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Fri, 31 Aug 2018 19:33:50 +0000 Received: by mail-oi0-f43.google.com with SMTP id 13-v6so23701942ois.1 for ; Fri, 31 Aug 2018 12:33:50 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20161025; h=mime-version:from:date:message-id:subject:to:cc; bh=Mq3iA4bGs912IPVNnaafdyNKvdLHOLX6VaWO1BB8slg=; b=Ozua36nR1ClSbL3PwRXmtDypIisaU4uYlVPTt5OT5u/9HE5T0r7C+l5NtX/hLG0lTc 9l2buy04JovkJrNJoPwz7GfmrCrYsD3R6UstMgTzJVVLfweY0gClEGr7ktyrCo+9Smw+ Rt6Jh2Zf+EK/NiIQHNitOp5LbelVWFii30WxXGPZ3LMuseXF5M8yNE9RFJ9cd50MES65 SM0SAOc/UgkjoIyFeheC/38PC4wpKQ83EKA3fG2Rq/0jNurlIrzSskYWnjZ7mAwBiZLN 007SrVxPHSAbkhMGtRySb+RElzRZT0pT8LcNPfXAoNoQuPZcBeb9sderTb+Fe59VvHy1 gAEA== MIME-Version: 1.0 Received: by 2002:a4a:3a41:0:0:0:0:0 with HTTP; Fri, 31 Aug 2018 12:33:48 -0700 (PDT) From: "H.J. Lu" Date: Fri, 31 Aug 2018 12:33:48 -0700 Message-ID: Subject: DWARF: Represent hard frame pointer as stack pointer + offset To: Jason Merrill , Uros Bizjak Cc: GCC Patches , Cary Coutant X-IsSubscribed: yes On Thu, Aug 30, 2018 at 10:21 AM, Jason Merrill wrote: > >> r138335 allowed arg_pointer_rtx to be eliminated by either FP or SP, >> but only when dynamic stack alignment is supported. In this case, >> arg_pointer_rtx is eliminated by FP even when frame_pointer_needed >> is false and there is no dynamic stack alignment at all. >> >>> gcc_assert (elim == stack_pointer_rtx || (frame_pointer_needed && elim >>> == hard_frame_pointer_rtx)); >>> >>> so as not to allow eliminating to an uninitialized FP. >> >> FP isn't uninitialized. It is initialized the same way as in the case of >> SUPPORTS_STACK_ALIGNMENT is true. > > How is that? Why would it be initialized when frame_pointer_needed is > false? What does it mean for frame_pointer_needed to be false, if > not, as in the documentation of -fomit-frame-pointer, > > "This avoids the instructions to save, set up and restore the frame > pointer; on many targets it also makes an extra register available." > > ? > A backend may not set up frame pointer even with -fno-omit-frame-pointer. In the case of x86, hard frame pointer can be represented by stack pointer - UNITS_PER_WORD. This patch adds hard_frame_pointer_from_stack_pointer_plus_offset and hard_frame_pointer_offset to rtl_data to allow a backend to represent hard frame pointer as stack pointer + offset. OK for trunk? From 6fc2b6ca9ca77afa2057d2d48ec8f8131036100e Mon Sep 17 00:00:00 2001 From: "H.J. Lu" Date: Wed, 8 Aug 2018 06:20:27 -0700 Subject: [PATCH] DWARF: Represent hard frame pointer as stack pointer + offset With commit cd557ff63f388ad27c376d0a225e74d3594a6f9d Author: hjl Date: Thu Aug 10 15:29:05 2017 +0000 i386: Don't use frame pointer without stack access When there is no stack access, there is no need to use frame pointer even if -fno-omit-frame-pointer is used and caller's frame pointer is unchanged. frame pointer may not be available even if -fno-omit-frame-pointer is used. When this happened, arg pointer and frame pointer may be eliminated by hard frame pointer. In this case, hard frame pointer may be represented by stack pointer + offset. This patch adds hard_frame_pointer_from_stack_pointer_plus_offset and hard_frame_pointer_offset to rtl_data to allow a backend to represent hard frame pointer as stack pointer + offset. gcc/ PR debug/86593 * dwarf2out.c (based_loc_descr): When frame pointer isn't used, if arg pointer or frame pointer are eliminated by hard frame pointer, use stack pointer + offset to access stack variables if possible. Update gcc_assert. * emit-rtl.h (rtl_data): Add hard_frame_pointer_offset and hard_frame_pointer_from_stack_pointer_plus_offset. * config/i386/i386.c (ix86_finalize_stack_frame_flags): Set hard_frame_pointer_from_stack_pointer_plus_offset and hard_frame_pointer_offset to represent hard frame pointer as stack pointer - UNITS_PER_WORD if frame pointer isn't used. gcc/testsuite/ PR debug/86593 * g++.dg/pr86593.C: New test. --- gcc/config/i386/i386.c | 6 ++++-- gcc/dwarf2out.c | 13 +++++++++++-- gcc/emit-rtl.h | 8 ++++++++ gcc/testsuite/g++.dg/pr86593.C | 11 +++++++++++ 4 files changed, 34 insertions(+), 4 deletions(-) create mode 100644 gcc/testsuite/g++.dg/pr86593.C diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c index 8672a666024..775b96473b1 100644 --- a/gcc/config/i386/i386.c +++ b/gcc/config/i386/i386.c @@ -13161,10 +13161,12 @@ ix86_finalize_stack_frame_flags (void) df_compute_regs_ever_live (true); df_analyze (); + /* Since frame pointer is no longer available, replace it with + stack pointer - UNITS_PER_WORD in debug insns. */ + crtl->hard_frame_pointer_from_stack_pointer_plus_offset = true; + crtl->hard_frame_pointer_offset = -UNITS_PER_WORD; if (flag_var_tracking) { - /* Since frame pointer is no longer available, replace it with - stack pointer - UNITS_PER_WORD in debug insns. */ df_ref ref, next; for (ref = DF_REG_USE_CHAIN (HARD_FRAME_POINTER_REGNUM); ref; ref = next) diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 77317ed2575..09f3c192129 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -14326,9 +14326,18 @@ based_loc_descr (rtx reg, poly_int64 offset, if (elim != reg) { elim = strip_offset_and_add (elim, &offset); + + if (!frame_pointer_needed + && elim == hard_frame_pointer_rtx + && crtl->hard_frame_pointer_from_stack_pointer_plus_offset) + { + int fp_offset = crtl->hard_frame_pointer_offset; + int base_reg = DWARF_FRAME_REGNUM (STACK_POINTER_REGNUM); + return new_reg_loc_descr (base_reg, offset + fp_offset); + } + gcc_assert ((SUPPORTS_STACK_ALIGNMENT - && (elim == hard_frame_pointer_rtx - || elim == stack_pointer_rtx)) + && elim == stack_pointer_rtx) || elim == (frame_pointer_needed ? hard_frame_pointer_rtx : stack_pointer_rtx)); diff --git a/gcc/emit-rtl.h b/gcc/emit-rtl.h index f089355aef7..c69730e2900 100644 --- a/gcc/emit-rtl.h +++ b/gcc/emit-rtl.h @@ -282,6 +282,14 @@ struct GTY(()) rtl_data { pass. */ bool bb_reorder_complete; + /* True if hard frame pointer can be represented as stack pointer + + offset in the current function. */ + bool hard_frame_pointer_from_stack_pointer_plus_offset; + + /* Offset from stack pointer if hard frame pointer can be represented + as stack pointer + offset in the current function. */ + int hard_frame_pointer_offset; + /* Like regs_ever_live, but 1 if a reg is set or clobbered from an asm. Unlike regs_ever_live, elements of this array corresponding to eliminable regs (like the frame pointer) are set if an asm diff --git a/gcc/testsuite/g++.dg/pr86593.C b/gcc/testsuite/g++.dg/pr86593.C new file mode 100644 index 00000000000..f4de0c1166a --- /dev/null +++ b/gcc/testsuite/g++.dg/pr86593.C @@ -0,0 +1,11 @@ +// { dg-options "-O -g -fno-omit-frame-pointer" } + +struct Foo +{ + int bar(int a, int b, int c, int i1, int i2, int i3, int d); +}; + +int Foo::bar(int a, int b, int c, int i1, int i2, int i3, int d) +{ + return 0; +} -- 2.17.1