From patchwork Wed Sep 22 22:03:32 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit Subject: PATCH RFA: Split stack [4/7]: REF_CFA_TEMPORARY Date: Wed, 22 Sep 2010 12:03:32 -0000 From: Ian Taylor X-Patchwork-Id: 65465 Message-Id: To: gcc-patches@gcc.gnu.org This is the fourth of the -fsplit-stack patches. This patch adds a new feature to the DWARF frame note. If an insn has a new REG_CFA_TEMPORARY note, then the CFA is set to the value of the note only for that insn. The i386 backend uses this new feature to set the unwind information for a special ret instruction that it uses to permit the processor to do call/return prediction. This patch is in the middle-end and as such does not require approval, but as it is somewhat unrelated to the rest of the patches I am separating it out for possible comment. Ian 2010-09-21 Ian Lance Taylor * reg-notes.def (CFA_TEMPORARY): New note. * dwarf2out.c (dwarf2out_frame_debug): Handle REG_CFA_TEMPORARY. (dwarf2out_cfi_begin_epilogue): Call dwarf2out_frame_debug_remember_state. (dwarf2out_frame_debug_remember_state): New static function, broken out of dwarf2out_cfi_begin_epilogue. Index: gcc/reg-notes.def =================================================================== --- gcc/reg-notes.def (revision 164490) +++ gcc/reg-notes.def (working copy) @@ -165,6 +165,13 @@ REG_NOTE (CFA_RESTORE) to the argument, if it is a MEM, it is ignored. */ REG_NOTE (CFA_SET_VDRAP) +/* Temporarily set the CFA for just one insn. This saves the old + state, sets the CFA, and then restores the state after the insn. + The pattern for this note is the new CFA value. This is used by + the split stack code to support unwinding through the call into the + split stack routine. */ +REG_NOTE (CFA_TEMPORARY) + /* Indicates that REG holds the exception context for the function. This context is shared by inline functions, so the code to acquire the real exception context is delayed until after inlining. */ Index: gcc/dwarf2out.c =================================================================== --- gcc/dwarf2out.c (revision 164490) +++ gcc/dwarf2out.c (working copy) @@ -473,6 +473,7 @@ static void output_call_frame_info (int) static void dwarf2out_note_section_used (void); static bool clobbers_queued_reg_save (const_rtx); static void dwarf2out_frame_debug_expr (rtx, const char *); +static void dwarf2out_frame_debug_remember_state (void); /* Support for complex CFA locations. */ static void output_cfa_loc (dw_cfi_ref); @@ -2832,6 +2833,17 @@ dwarf2out_frame_debug (rtx insn, bool af handled_one = true; break; + case REG_CFA_TEMPORARY: + if (!after_p) + { + dwarf2out_frame_debug_remember_state (); + dwarf2out_frame_debug_def_cfa (XEXP (note, 0), label); + } + else + dwarf2out_frame_debug_restore_state (); + handled_one = true; + break; + default: break; } @@ -2924,9 +2936,17 @@ dwarf2out_cfi_begin_epilogue (rtx insn) } emit_note_before (NOTE_INSN_CFA_RESTORE_STATE, i); + dwarf2out_frame_debug_remember_state (); +} + +/* Remember the current state. */ + +static void +dwarf2out_frame_debug_remember_state (void) +{ emit_cfa_remember = true; - /* And emulate the state save. */ + /* Emulate the state save. */ gcc_assert (!cfa_remember.in_use); cfa_remember = cfa; cfa_remember.in_use = 1;