* CFI for saved argument registers @ 2022-05-16 6:29 Andreas Krebbel 2022-05-16 13:25 ` Florian Weimer ` (2 more replies) 0 siblings, 3 replies; 5+ messages in thread From: Andreas Krebbel @ 2022-05-16 6:29 UTC (permalink / raw) To: gcc Hi, I'm trying to provide a simple dwarf unwinder with access to the argument register content. The goal is to make this information available for optimized code without having to access debug information for things like call site args. The extra overhead of saving the values to the stack is acceptable in that case. For that purpose I save the argument registers to the stack as we would do for a variable argument lists. But this time I also provide the CFI to allow the unwinder to locate the save slots. Since I never actually intend to restore the content there is no matching cfi_restore for the cfi_offset and dwarf2cfi complains about the traces being inconsistent because of that. I couldn't find a way to prevent this. The only way I see right now is adding a new reg note to invalidate the save information in the reg_save array in dwarf2cfi. Would this be acceptable? Is there perhaps an easier way to achieve that? Bye, Andreas ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: CFI for saved argument registers 2022-05-16 6:29 CFI for saved argument registers Andreas Krebbel @ 2022-05-16 13:25 ` Florian Weimer 2022-05-16 14:39 ` Andreas Schwab 2022-05-31 12:11 ` Andreas Krebbel 2 siblings, 0 replies; 5+ messages in thread From: Florian Weimer @ 2022-05-16 13:25 UTC (permalink / raw) To: Andreas Krebbel via Gcc * Andreas Krebbel via Gcc: > For that purpose I save the argument registers to the stack as we > would do for a variable argument lists. But this time I also provide > the CFI to allow the unwinder to locate the save slots. Since I never > actually intend to restore the content there is no matching > cfi_restore for the cfi_offset and dwarf2cfi complains about the > traces being inconsistent because of that. I couldn't find a way to > prevent this. > > The only way I see right now is adding a new reg note to invalidate > the save information in the reg_save array in dwarf2cfi. > > Would this be acceptable? Is there perhaps an easier way to achieve that? This is very interesting. I think we should do this in glibc for abort and __assert_fail for as many registers as possible, hopefully preserving more information for debuggers. Thanks, Florian ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: CFI for saved argument registers 2022-05-16 6:29 CFI for saved argument registers Andreas Krebbel 2022-05-16 13:25 ` Florian Weimer @ 2022-05-16 14:39 ` Andreas Schwab 2022-05-17 6:19 ` Andreas Krebbel 2022-05-31 12:11 ` Andreas Krebbel 2 siblings, 1 reply; 5+ messages in thread From: Andreas Schwab @ 2022-05-16 14:39 UTC (permalink / raw) To: Andreas Krebbel via Gcc On Mai 16 2022, Andreas Krebbel via Gcc wrote: > The only way I see right now is adding a new reg note to invalidate > the save information in the reg_save array in dwarf2cfi. > > Would this be acceptable? Is there perhaps an easier way to achieve that? Doesn't it work to use .cfi_remember_state/.cfi_restore_state? -- Andreas Schwab, schwab@linux-m68k.org GPG Key fingerprint = 7578 EB47 D4E5 4D69 2510 2552 DF73 E780 A9DA AEC1 "And now for something completely different." ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: CFI for saved argument registers 2022-05-16 14:39 ` Andreas Schwab @ 2022-05-17 6:19 ` Andreas Krebbel 0 siblings, 0 replies; 5+ messages in thread From: Andreas Krebbel @ 2022-05-17 6:19 UTC (permalink / raw) To: Andreas Schwab, Andreas Krebbel via Gcc On 5/16/22 16:39, Andreas Schwab wrote: > On Mai 16 2022, Andreas Krebbel via Gcc wrote: > >> The only way I see right now is adding a new reg note to invalidate >> the save information in the reg_save array in dwarf2cfi. >> >> Would this be acceptable? Is there perhaps an easier way to achieve that? > > Doesn't it work to use .cfi_remember_state/.cfi_restore_state? > This might work but I think also for that I would have to implement means to trigger it explicitely with an RTX somehow. Also I rather would avoid emitting special CFI for that purpose. I think the CFI I currently have (with more .cfi_offset's than .cfi_restore's) is valid. I only have to convince the validation step in dwarf2cfi to accept this. Therefore the idea was to introduce a new regnote to say that at a certain point it is intentional that there is no .cfi_restore for a register. The action in dwarf2cfi should only be to remove the reg from reg_save and be done with it. Bye, Andreas ^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: CFI for saved argument registers 2022-05-16 6:29 CFI for saved argument registers Andreas Krebbel 2022-05-16 13:25 ` Florian Weimer 2022-05-16 14:39 ` Andreas Schwab @ 2022-05-31 12:11 ` Andreas Krebbel 2 siblings, 0 replies; 5+ messages in thread From: Andreas Krebbel @ 2022-05-31 12:11 UTC (permalink / raw) To: gcc On 5/16/22 08:29, Andreas Krebbel via Gcc wrote: > Hi, > > I'm trying to provide a simple dwarf unwinder with access to the > argument register content. The goal is to make this information > available for optimized code without having to access debug > information for things like call site args. The extra overhead > of saving the values to the stack is acceptable in that case. > > For that purpose I save the argument registers to the stack as we > would do for a variable argument lists. But this time I also provide > the CFI to allow the unwinder to locate the save slots. Since I never > actually intend to restore the content there is no matching > cfi_restore for the cfi_offset and dwarf2cfi complains about the > traces being inconsistent because of that. I couldn't find a way to > prevent this. > > The only way I see right now is adding a new reg note to invalidate > the save information in the reg_save array in dwarf2cfi. > > Would this be acceptable? Is there perhaps an easier way to achieve that? Attached is a small patch adding a new reg note REG_CFA_NORESTORE. I would attach that new note to the register save insn to indicate that this register will not be restored. I'll have to emit the REG_CFA_OFFSET note as well then. An insn saving r2-r6 without restoring them would look like this then: (insn/f 31 21 32 2 (parallel [ (set/f (mem/c:DI (plus:DI (reg/f:DI 15 %r15) (const_int 16 [0x10])) [4 S8 A8]) (reg:DI 2 %r2)) (set/f (mem/c:DI (plus:DI (reg/f:DI 15 %r15) (const_int 24 [0x18])) [4 S8 A8]) (reg:DI 3 %r3)) (set/f (mem/c:DI (plus:DI (reg/f:DI 15 %r15) (const_int 32 [0x20])) [4 S8 A8]) (reg:DI 4 %r4)) (set/f (mem/c:DI (plus:DI (reg/f:DI 15 %r15) (const_int 40 [0x28])) [4 S8 A8]) (reg:DI 5 %r5)) (set/f (mem/c:DI (plus:DI (reg/f:DI 15 %r15) (const_int 48 [0x30])) [4 S8 A8]) (reg:DI 6 %r6)) ]) "/home/andreas/preserveargs/reduce2/t.c":2:51 -1 (expr_list:REG_CFA_OFFSET (set (mem/c:DI (plus:DI (reg/f:DI 15 %r15) (const_int 48 [0x30])) [4 S8 A8]) (reg:DI 6 %r6)) (expr_list:REG_CFA_NO_RESTORE (reg:DI 6 %r6) (expr_list:REG_CFA_OFFSET (set (mem/c:DI (plus:DI (reg/f:DI 15 %r15) (const_int 40 [0x28])) [4 S8 A8]) (reg:DI 5 %r5)) (expr_list:REG_CFA_NO_RESTORE (reg:DI 5 %r5) (expr_list:REG_CFA_OFFSET (set (mem/c:DI (plus:DI (reg/f:DI 15 %r15) (const_int 32 [0x20])) [4 S8 A8]) (reg:DI 4 %r4)) (expr_list:REG_CFA_NO_RESTORE (reg:DI 4 %r4) (expr_list:REG_CFA_OFFSET (set (mem/c:DI (plus:DI (reg/f:DI 15 %r15) (const_int 24 [0x18])) [4 S8 A8]) (reg:DI 3 %r3)) (expr_list:REG_CFA_NO_RESTORE (reg:DI 3 %r3) (expr_list:REG_CFA_OFFSET (set (mem/c:DI (plus:DI (reg/f:DI 15 %r15) (const_int 16 [0x10])) [4 S8 A8]) (reg:DI 2 %r2)) (expr_list:REG_CFA_NO_RESTORE (reg:DI 2 %r2) (nil)))))))))))) diff --git a/gcc/dwarf2cfi.c b/gcc/dwarf2cfi.c index 362ff3fdac27..2cbc2465c3a7 100644 --- a/gcc/dwarf2cfi.c +++ b/gcc/dwarf2cfi.c @@ -1346,7 +1346,7 @@ dwarf2out_frame_debug_cfa_val_expression (rtx set) /* A subroutine of dwarf2out_frame_debug, process a REG_CFA_RESTORE note. */ static void -dwarf2out_frame_debug_cfa_restore (rtx reg) +dwarf2out_frame_debug_cfa_restore (rtx reg, bool emit_cfi) { gcc_assert (REG_P (reg)); @@ -1354,7 +1354,8 @@ dwarf2out_frame_debug_cfa_restore (rtx reg) if (!span) { unsigned int regno = dwf_regno (reg); - add_cfi_restore (regno); + if (emit_cfi) + add_cfi_restore (regno); update_row_reg_save (cur_row, regno, NULL); } else @@ -1369,7 +1370,8 @@ dwarf2out_frame_debug_cfa_restore (rtx reg) reg = XVECEXP (span, 0, par_index); gcc_assert (REG_P (reg)); unsigned int regno = dwf_regno (reg); - add_cfi_restore (regno); + if (emit_cfi) + add_cfi_restore (regno); update_row_reg_save (cur_row, regno, NULL); } } @@ -2155,6 +2157,7 @@ dwarf2out_frame_debug (rtx_insn *insn) break; case REG_CFA_RESTORE: + case REG_CFA_NO_RESTORE: n = XEXP (note, 0); if (n == NULL) { @@ -2163,7 +2166,7 @@ dwarf2out_frame_debug (rtx_insn *insn) n = XVECEXP (n, 0, 0); n = XEXP (n, 0); } - dwarf2out_frame_debug_cfa_restore (n); + dwarf2out_frame_debug_cfa_restore (n, REG_NOTE_KIND (note) == REG_CFA_RESTORE); handled_one = true; break; diff --git a/gcc/reg-notes.def b/gcc/reg-notes.def index 995052ebc28e..3e8cc189301c 100644 --- a/gcc/reg-notes.def +++ b/gcc/reg-notes.def @@ -167,6 +167,8 @@ REG_CFA_NOTE (CFA_VAL_EXPRESSION) first pattern is the register to be restored. */ REG_CFA_NOTE (CFA_RESTORE) +REG_CFA_NOTE (CFA_NO_RESTORE) + /* Attached to insns that are RTX_FRAME_RELATED_P, marks insn that sets vDRAP from DRAP. If vDRAP is a register, vdrap_reg is initalized to the argument, if it is a MEM, it is ignored. */ ^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2022-05-31 12:11 UTC | newest] Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2022-05-16 6:29 CFI for saved argument registers Andreas Krebbel 2022-05-16 13:25 ` Florian Weimer 2022-05-16 14:39 ` Andreas Schwab 2022-05-17 6:19 ` Andreas Krebbel 2022-05-31 12:11 ` Andreas Krebbel
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox; as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).