This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |
Other format: | [Raw text] |
This patch adds epilogue handling capabilities to the DWARF2 unwind information emission. It also contains tweaks to the x86/x86-64 backend to smooth out the generation of such information. Background: here at Rice, we have developed a low-overhead callstack profiler for optimized code that can also record edge count information at low cost (see our ICS'05 paper for details). The basic idea is to take callstack samples at timer interrupts; massaging the return address at sample times ensures that the amount of unwinding is small and provides edge count data as a bonus. Our prototype was written for the Alpha platform and made extensive use of the compiler-generated unwind information. When porting our profiler to the x86-64, we found that compilers did not generate enough unwind information for our purposes. In particular, samples taken in the middle of epilogues would result in bogus callstacks being collected. We therefore needed to add two pieces of infrastructure to GCC: 1) The ability to generate unwind information for procedure epilogues; 2) The ability to generate DWARF2_{remember,restore}_state pairs when appropriate. As an example of each of these requirements, consider the following x86-64 code: ... A: add $0x48, %rsp [pop registers] retq B: ... ... C: add $x048, %rsp [pop registers] retq Prior to our patch, if a sample was taken between 'C' and the following 'retq', the stack could not be properly unwound, as the adjustments to the stack pointer were not recorded. This motivates requirement 1). Additionally, even with the adjustments recorded, taking a sample between 'B' and 'C' would unwind the stack too much, since the effects of the duplicated epilogue between 'A' and 'B' would not be discarded. This motivates requirement 2). This patch, therefore, adds the necessary bits to GCC. At a high level, we had to: 1) Add support in the DWARF2 generator; 2) Teach various parts of GCC to play nicely with multiple epilogues (there was always a single EPILOGUE_BEG note prior to our efforts and several functions relied on this); 3) Teach the x86 backend to mark instructions as RTX_FRAME_RELATED_P. For proper functioning, this patch requires an earlier patch we sent to the list ("PATCH: correctly handle the CFA in DWARF2 unwinding") last month. Otherwise, many tests in the test suite that require unwinding will fail. We haven't done extensive measurements on the increased disk space necessary for binaries compiled with this patch. As a data point, the total size of the executables in gcc/ (cc1, jc1, g++, cpp, etc.)-- excluding the '-dummy' variants--after a full bootstrap was 146,234,914 bytes without our patch and 148,685,043 bytes with our patch--an increase of ~1.7%. We feel this is a small price to pay for on-demand callstack profiles from optimized code--no recompilation necessary. Tested with a bootstrap and `make -k check' on x86_64-pc-linux-gnu. No regressions. OK for mainline? 2006-02-14 Nathan Froyd <froydnj@cs.rice.edu> * gcc/rtl.h: Export record_epilogue_insn and forget_epilogue_insn. * gcc/cfglayout.c (duplicate_insn_chain): Recognize when we're duplicating epilogues and record the duplicated instructions as being part of the epilogue. Don't strip EPILOGUE_BEG notes. * gcc/cfgrtl.c (can_delete_note_p): Delete EPILOGUE_BEG notes. * gcc/final.c (final_scan_insn): Pass BASIC_BLOCK and EPILOGUE_BEG notes to dwarf2_out_process_note. * gcc/dwarf2out.c (dwarf2out_state_label): New. (lookup_cfa): Don't consider entries between remember/restore state pairs. (reg_restore): New. (dwarf2out_remember_state): New. (dwarf2out_restore_state): New. (dwarf2out_frame_debug_expr): Cases to handle epilogue code. Essentially mirror images of what was already there. (dwarf2out_process_note): New. (dwarf2out_frame_debug): Initialize last_block and need_restore_state. (dw_cfi_oprnd1_desc): Handle DW_CFA_{remember_state,restore_state,restore}. (dwarf2out_being_prologue): Initialize fde->remember_restore_pairs. (convert_cfa_to_loc_list): Skip code bracketed between remember/restore state pairs. * gcc/dwarf2out.h: Export dwarf2out_process_note. * gcc/function.c (record_epilogue_insn,forget_epilogue_insn): New. (thread_prologue_and_epilogue_insns): Emit EPILOGUE_BEG note for sibcall epilogue sequences. (reposition_prologue_and_epilogue_notes): Shuffle EPILOGUE_BEG notes to appropriate places based on epilogue-ness of insns. * gcc/config/i386/i386.md (leave,leave_rex64): Tweak into something the DWARF2 unwind information generator understands. * gcc/config/i386/i386.c (pro_epilogue_adjust_stack): Mark insns as RTX_FRAME_RELATED_P as appropriate. (ix86_restore_moves_use_sp): New. (ix86_expand_prologue): Mark insns as RTX_FRAME_RELATED_P as appropriate. (ix86_mark_parallel_rtx_as_frame_related): New. (ix86_epilogue_restores_use_mov): New. (ix86_expand_epilogue): Mark insns as RTX_FRAME_RELATED_P as appropriate. -- Nathan | From Man's effeminate slackness it begins. --Paradise Lost The last good thing written in C was Franz Schubert's Symphony Number 9. --Erwin Dieterich
Attachment:
dwarf2-unwind.patch
Description: Text document
Index Nav: | [Date Index] [Subject Index] [Author Index] [Thread Index] | |
---|---|---|
Message Nav: | [Date Prev] [Date Next] | [Thread Prev] [Thread Next] |