Hi,

Would you please help on how to generate correct epilogue dwarf info?
Without correct dwarf info, when shrink-wrap is enabled, it tends to
ICE at dwarf2cfi.c: function maybe_record_trace_start.

      /* We ought to have the same state incoming to a given trace no
         matter how we arrive at the trace.  Anything else means we've
         got some kind of optimization error.  */
      gcc_checking_assert (cfi_row_equal_p (cur_row, ti->beg_row));

Issues:
1) pretend_args
The attached pretend_arg.c shows an example about pretend_args dwarf info

push    {r2, r3}
.cfi_def_cfa_offset 8
.cfi_offset 2, -8
.cfi_offset 3, -4
use r3
push    {r4, r5, lr}
...
pop     {r4, r5, lr}
add     sp, sp, #8
//No instruction here to restore r2 and r3

Can we RESTORE r2 and r3?
* If we notes to RESTORE r2 and r3, it might lead to wrong info for
GDB since no instruction restores them.
* If we do not RESTORE them, the reg_save dwarf info will not be
cleared. Then the dwarf check will fail when the function is
shrink-wrapped.

2) frame_pointer_needed
In prologue, we set fp like

fp = sp + INT
After this instruction, cfi_def_cfa_register is set to fp

In epilogue. we have

fp += INT
sp = fp

Can we reset cfi_def_cfa_register back to sp?
* If we set it back to sp, how to handle it in arm_unwind_emit_set,
which assumes sp can not be set from other register?
          /* A stack increment.  */
          if (GET_CODE (e1) != PLUS
              || !REG_P (XEXP (e1, 0))
              || REGNO (XEXP (e1, 0)) != SP_REGNUM
              || !CONST_INT_P (XEXP (e1, 1)))
            abort ();
* If we do not set it back, to get correct dwarf info for POP after
"sp = fp", we have to add notes " sp = fp + INT" for dwarf-info while
we have "sp = sp + INT" in the insn. Here is the workaround POP RTL
example for the attached alloca,c:

(insn/f 62 61 66 3 (parallel [
            (set/f (reg/f:SI 13 sp)   // sp = sp + 8
                (plus:SI (reg/f:SI 13 sp)
                    (const_int 8 [0x8])))
            (set/f (reg:SI 3 r3)
                (mem/c:SI (reg/f:SI 13 sp) [3 S4 A32]))
            (set/f (reg/f:SI 7 r7)
                (mem/c:SI (plus:SI (reg/f:SI 13 sp)
                        (const_int 4 [0x4])) [3 S4 A32]))
        ]) alloca.c:8 329 {*load_multiple_with_writeback}
     (expr_list:REG_UNUSED (reg:SI 3 r3)
        (expr_list:REG_CFA_ADJUST_CFA (set (reg/f:SI 13 sp)
                (plus:SI (reg/f:SI 7 r7)   // sp = fp + 8
                    (const_int 8 [0x8])))
            (expr_list:REG_CFA_RESTORE (reg/f:SI 7 r7)
                (expr_list:REG_CFA_RESTORE (reg:SI 3 r3)
                    (nil))))))

(3) No idea for
  if (crtl->calls_eh_return)
    emit_insn (gen_addsi3 (stack_pointer_rtx,
                    stack_pointer_rtx,
                    gen_rtx_REG (SImode, ARM_EH_STACKADJ_REGNUM)));

Currently I have no shrink-wrapped test case which
crtl->calls_eh_return is true.

Thanks!
-Zhenqiang
#include <stdlib.h>
#include <stdio.h>
#include <stdarg.h>

#define DEBUG_BUFFER_SIZE 80
int unifi_debug = 5;

void unifi_trace(void* ospriv, int level, const char *fmt, ...)
{
   
  static char s[DEBUG_BUFFER_SIZE];
  va_list args;
  unsigned int len;

  if (!ospriv) return;
   
  if(unifi_debug >= level) 
   {
	
     va_start(args, fmt);
     len = vsnprintf(&(s)[0], (DEBUG_BUFFER_SIZE), fmt, args);
	
     va_end(args);
     if (len >= DEBUG_BUFFER_SIZE) 
      {
	(s)[DEBUG_BUFFER_SIZE - 2] = '\n';
	(s)[DEBUG_BUFFER_SIZE - 1] = 0;
      }
      printf("%s", s);
   }
   
}

Attachment: pretend_arg.s
Description: Binary data

extern int * alloca(int);
int *p;
void test(int a)
{
  if (a > 0)
    p = alloca(4);
  
}
_______________________________________________
linaro-toolchain mailing list
linaro-toolchain@lists.linaro.org
http://lists.linaro.org/mailman/listinfo/linaro-toolchain

Reply via email to