On Thu, Aug 30, 2018 at 10:21 AM, Jason Merrill <ja...@redhat.com> 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? -- H.J.
From 6fc2b6ca9ca77afa2057d2d48ec8f8131036100e Mon Sep 17 00:00:00 2001 From: "H.J. Lu" <hjl.to...@gmail.com> 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 <hjl@138bc75d-0d04-0410-961f-82ee72b054a4> 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