i386: Replace frame pointer with stack pointer in debug insns
authorH.J. Lu <hjl@gcc.gnu.org>
Sun, 13 Aug 2017 18:31:39 +0000 (11:31 -0700)
committerH.J. Lu <hjl@gcc.gnu.org>
Sun, 13 Aug 2017 18:31:39 +0000 (11:31 -0700)
When we eliminate frame pointer, we should also replace frame pointer
with stack pointer - UNITS_PER_WORD in debug insns.  This patch fixed:

FAIL: gcc.dg/guality/pr58791-5.c   -Os  line pr58791-5.c:20 b1 == 9
FAIL: gcc.dg/guality/pr58791-5.c   -Os  line pr58791-5.c:20 b2 == 73
FAIL: gcc.dg/guality/pr58791-5.c   -Os  line pr58791-5.c:20 b3 == 585
FAIL: gcc.dg/guality/pr58791-5.c   -Os  line pr58791-5.c:20 b4 == 4681
FAIL: gcc.dg/guality/pr59776.c   -Os  line pr59776.c:17 s1.f == 5.0
FAIL: gcc.dg/guality/pr59776.c   -Os  line pr59776.c:17 s1.g == 6.0
FAIL: gcc.dg/guality/pr59776.c   -Os  line pr59776.c:17 s2.g == 6.0
FAIL: gcc.dg/guality/pr59776.c   -Os  line pr59776.c:20 s1.f == 5.0
FAIL: gcc.dg/guality/pr59776.c   -Os  line pr59776.c:20 s1.g == 6.0
FAIL: gcc.dg/guality/pr59776.c   -Os  line pr59776.c:20 s2.f == 5.0
FAIL: gcc.dg/guality/pr59776.c   -Os  line pr59776.c:20 s2.g == 6.0

on Linux/i386.

PR target/81820
* config/i386/i386.c (ix86_finalize_stack_frame_flags): Replace
frame pointer with stack pointer - UNITS_PER_WORD in debug insns.

From-SVN: r251076

gcc/config/i386/i386.c

index b04321a8d407f4e16f1f840744e2e5e10dec98f4..1d88e4f247add49ba9195f1dc8291b525b2a1d42 100644 (file)
@@ -14281,6 +14281,42 @@ ix86_finalize_stack_frame_flags (void)
       df_scan_blocks ();
       df_compute_regs_ever_live (true);
       df_analyze ();
+
+      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)
+           {
+             rtx_insn *insn = DF_REF_INSN (ref);
+             /* Make sure the next ref is for a different instruction,
+                so that we're not affected by the rescan.  */
+             next = DF_REF_NEXT_REG (ref);
+             while (next && DF_REF_INSN (next) == insn)
+               next = DF_REF_NEXT_REG (next);
+
+             if (DEBUG_INSN_P (insn))
+               {
+                 bool changed = false;
+                 for (; ref != next; ref = DF_REF_NEXT_REG (ref))
+                   {
+                     rtx *loc = DF_REF_LOC (ref);
+                     if (*loc == hard_frame_pointer_rtx)
+                       {
+                         *loc = plus_constant (Pmode,
+                                               stack_pointer_rtx,
+                                               -UNITS_PER_WORD);
+                         changed = true;
+                       }
+                   }
+                 if (changed)
+                   df_insn_rescan (insn);
+               }
+           }
+       }
+
       recompute_frame_layout_p = true;
     }