From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 9476 invoked by alias); 3 Jul 2011 20:03:42 -0000 Received: (qmail 8984 invoked by uid 22791); 3 Jul 2011 20:03:37 -0000 X-SWARE-Spam-Status: No, hits=-1.4 required=5.0 tests=AWL,BAYES_00,DKIM_SIGNED,DKIM_VALID,FREEMAIL_ENVFROM_END_DIGIT,FREEMAIL_FROM,SPF_NEUTRAL,TW_FN,T_TO_NO_BRKTS_FREEMAIL X-Spam-Check-By: sourceware.org Received: from eggs.gnu.org (HELO eggs.gnu.org) (140.186.70.92) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Sun, 03 Jul 2011 20:03:17 +0000 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QdSss-0004uB-6r for gcc-patches@gcc.gnu.org; Sun, 03 Jul 2011 16:03:16 -0400 Received: from mail-vx0-f175.google.com ([209.85.220.175]:51288) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QdSsr-0004tv-IQ for gcc-patches@gcc.gnu.org; Sun, 03 Jul 2011 16:03:14 -0400 Received: by mail-vx0-f175.google.com with SMTP id 37so3896954vxa.20 for ; Sun, 03 Jul 2011 13:03:13 -0700 (PDT) Received: by 10.220.183.71 with SMTP id cf7mr1174629vcb.160.1309723392929; Sun, 03 Jul 2011 13:03:12 -0700 (PDT) Received: from localhost.localdomain (c-71-227-161-214.hsd1.wa.comcast.net [71.227.161.214]) by mx.google.com with ESMTPS id n2sm579268vcb.13.2011.07.03.13.03.11 (version=TLSv1/SSLv3 cipher=OTHER); Sun, 03 Jul 2011 13:03:12 -0700 (PDT) From: Richard Henderson To: gcc-patches@gcc.gnu.org Cc: bernds@codesourcery.com Subject: [PATCH 5/6] dwarf2: Extract cfi creation to a new pass. Date: Sun, 03 Jul 2011 20:03:00 -0000 Message-Id: <1309723308-26667-6-git-send-email-rth@redhat.com> In-Reply-To: <1309723308-26667-1-git-send-email-rth@redhat.com> References: <1309723308-26667-1-git-send-email-rth@redhat.com> X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.6 (newer, 2) X-Received-From: 209.85.220.175 X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2011-07/txt/msg00153.txt.bz2 --- gcc/ada/gcc-interface/misc.c | 10 --- gcc/debug.h | 5 +- gcc/dwarf2cfi.c | 161 +++++++++++++++++++++++++----------------- gcc/dwarf2out.c | 11 ++- gcc/dwarf2out.h | 4 - gcc/final.c | 10 --- gcc/lto-streamer-in.c | 8 -- gcc/passes.c | 1 + gcc/toplev.c | 5 -- gcc/tree-pass.h | 1 + 10 files changed, 109 insertions(+), 107 deletions(-) diff --git a/gcc/ada/gcc-interface/misc.c b/gcc/ada/gcc-interface/misc.c index e69668a..bdba7ed 100644 --- a/gcc/ada/gcc-interface/misc.c +++ b/gcc/ada/gcc-interface/misc.c @@ -339,11 +339,6 @@ gnat_init (void) void gnat_init_gcc_eh (void) { -#ifdef DWARF2_UNWIND_INFO - /* lang_dependent_init already called dwarf2out_frame_init if true. */ - int dwarf2out_frame_initialized = dwarf2out_do_frame (); -#endif - /* We shouldn't do anything if the No_Exceptions_Handler pragma is set, though. This could for instance lead to the emission of tables with references to symbols (such as the Ada eh personality routine) within @@ -370,11 +365,6 @@ gnat_init_gcc_eh (void) flag_non_call_exceptions = 1; init_eh (); - -#ifdef DWARF2_UNWIND_INFO - if (!dwarf2out_frame_initialized && dwarf2out_do_frame ()) - dwarf2out_frame_init (); -#endif } /* Print language-specific items in declaration NODE. */ diff --git a/gcc/debug.h b/gcc/debug.h index efdffe1..828ede2 100644 --- a/gcc/debug.h +++ b/gcc/debug.h @@ -178,12 +178,11 @@ extern void dwarf2out_begin_prologue (unsigned int, const char *); extern void dwarf2out_vms_end_prologue (unsigned int, const char *); extern void dwarf2out_vms_begin_epilogue (unsigned int, const char *); extern void dwarf2out_end_epilogue (unsigned int, const char *); -extern void dwarf2out_frame_init (void); extern void dwarf2out_frame_finish (void); /* Decide whether we want to emit frame unwind information for the current translation unit. */ -extern int dwarf2out_do_frame (void); -extern int dwarf2out_do_cfi_asm (void); +extern bool dwarf2out_do_frame (void); +extern bool dwarf2out_do_cfi_asm (void); extern void dwarf2out_switch_text_section (void); const char *remap_debug_filename (const char *); diff --git a/gcc/dwarf2cfi.c b/gcc/dwarf2cfi.c index 3e63299..44655bb 100644 --- a/gcc/dwarf2cfi.c +++ b/gcc/dwarf2cfi.c @@ -2173,7 +2173,7 @@ dwarf2out_frame_debug_expr (rtx expr) If AFTER_P is false, we're being called before the insn is emitted, otherwise after. Call instructions get invoked twice. */ -void +static void dwarf2out_frame_debug (rtx insn, bool after_p) { rtx note, n; @@ -2318,33 +2318,6 @@ dwarf2out_frame_debug (rtx insn, bool after_p) cfi_insn = NULL; } -/* Called once at the start of final to initialize some data for the - current function. */ - -void -dwarf2out_frame_debug_init (void) -{ - regs_saved_in_regs = NULL; - queued_reg_saves = NULL; - - if (barrier_args_size) - { - XDELETEVEC (barrier_args_size); - barrier_args_size = NULL; - } - - /* Set up state for generating call frame debug info. */ - lookup_cfa (&cfa); - gcc_assert (cfa.reg - == (unsigned long)DWARF_FRAME_REGNUM (STACK_POINTER_REGNUM)); - - old_cfa = cfa; - cfa.reg = STACK_POINTER_REGNUM; - cfa_store = cfa; - cfa_temp.reg = -1; - cfa_temp.offset = 0; -} - /* Examine CFI and return true if a cfi label and set_loc is needed beforehand. Even when generating CFI assembler instructions, we still have to add the cfi to the list so that lookup_cfa works @@ -2440,11 +2413,10 @@ add_cfis_to_fde (void) } } -/* After the (optional) text prologue has been written, emit CFI insns - and update the FDE for frame-related instructions. */ +/* Scan the function and create the initial set of CFI notes. */ -void -dwarf2out_frame_debug_after_prologue (void) +static void +create_cfi_notes (void) { rtx insn; @@ -2499,8 +2471,6 @@ dwarf2out_frame_debug_after_prologue (void) dwarf2out_frame_debug (insn, true); } - - add_cfis_to_fde (); } /* Determine if we need to save and restore CFI information around this @@ -2599,47 +2569,70 @@ dwarf2out_frame_debug_restore_state (void) old_cfa = old_cfa_remember; cfa_remember.in_use = 0; } + -/* Run once per function. */ +/* Annotate the function with NOTE_INSN_CFI notes to record the CFI + state at each location within the function. These notes will be + emitted during pass_final. */ -void -dwarf2cfi_function_init (void) +static unsigned int +execute_dwarf2_frame (void) { - args_size = old_args_size = 0; -} + /* The first time we're called, compute the incoming frame state. */ + if (cie_cfi_vec == NULL) + { + dw_cfa_location loc; -/* Run once. */ + memset(&old_cfa, 0, sizeof (old_cfa)); + old_cfa.reg = INVALID_REGNUM; -void -dwarf2out_frame_init (void) -{ - dw_cfa_location loc; + /* On entry, the Canonical Frame Address is at SP. */ + memset(&loc, 0, sizeof (loc)); + loc.reg = STACK_POINTER_REGNUM; + loc.offset = INCOMING_FRAME_SP_OFFSET; + def_cfa_1 (true, &loc); - /* Generate the CFA instructions common to all FDE's. Do it now for the - sake of lookup_cfa. */ + if (targetm.debug_unwind_info () == UI_DWARF2 + || targetm_common.except_unwind_info (&global_options) == UI_DWARF2) + initial_return_save (INCOMING_RETURN_ADDR_RTX); + } - memset(&old_cfa, 0, sizeof (old_cfa)); - old_cfa.reg = INVALID_REGNUM; + /* Set up state for generating call frame debug info. */ + lookup_cfa (&cfa); + gcc_assert (cfa.reg + == (unsigned long)DWARF_FRAME_REGNUM (STACK_POINTER_REGNUM)); - /* On entry, the Canonical Frame Address is at SP. */ - memset(&loc, 0, sizeof (loc)); - loc.reg = STACK_POINTER_REGNUM; - loc.offset = INCOMING_FRAME_SP_OFFSET; - def_cfa_1 (true, &loc); + old_cfa = cfa; + cfa.reg = STACK_POINTER_REGNUM; + cfa_store = cfa; + cfa_temp.reg = -1; + cfa_temp.offset = 0; + + dwarf2out_alloc_current_fde (); + + /* Do the work. */ + create_cfi_notes (); + add_cfis_to_fde (); + + /* Reset all function-specific information, particularly for GC. */ + XDELETEVEC (barrier_args_size); + barrier_args_size = NULL; + regs_saved_in_regs = NULL; + queued_reg_saves = NULL; + args_size = old_args_size = 0; - if (targetm.debug_unwind_info () == UI_DWARF2 - || targetm_common.except_unwind_info (&global_options) == UI_DWARF2) - initial_return_save (INCOMING_RETURN_ADDR_RTX); + return 0; } -/* Save the result of dwarf2out_do_frame across PCH. */ -static GTY(()) bool saved_do_cfi_asm = 0; +/* Save the result of dwarf2out_do_frame across PCH. + This variable is tri-state, with 0 unset, >0 true, <0 false. */ +static GTY(()) signed char saved_do_cfi_asm = 0; /* Decide whether we want to emit frame unwind information for the current translation unit. */ -int +bool dwarf2out_do_frame (void) { /* We want to emit correct CFA location expressions or lists, so we @@ -2648,7 +2641,7 @@ dwarf2out_do_frame (void) if (write_symbols == DWARF2_DEBUG || write_symbols == VMS_AND_DWARF2_DEBUG) return true; - if (saved_do_cfi_asm) + if (saved_do_cfi_asm > 0) return true; if (targetm.debug_unwind_info () == UI_DWARF2) @@ -2663,7 +2656,7 @@ dwarf2out_do_frame (void) /* Decide whether to emit frame unwind via assembler directives. */ -int +bool dwarf2out_do_cfi_asm (void) { int enc; @@ -2671,8 +2664,13 @@ dwarf2out_do_cfi_asm (void) #ifdef MIPS_DEBUGGING_INFO return false; #endif - if (saved_do_cfi_asm) - return true; + + if (saved_do_cfi_asm != 0) + return saved_do_cfi_asm > 0; + + /* Assume failure for a moment. */ + saved_do_cfi_asm = -1; + if (!flag_dwarf2_cfi_asm || !dwarf2out_do_frame ()) return false; if (!HAVE_GAS_CFI_PERSONALITY_DIRECTIVE) @@ -2694,8 +2692,43 @@ dwarf2out_do_cfi_asm (void) && targetm_common.except_unwind_info (&global_options) != UI_DWARF2) return false; - saved_do_cfi_asm = true; + /* Success! */ + saved_do_cfi_asm = 1; return true; } +static bool +gate_dwarf2_frame (void) +{ +#ifndef HAVE_prologue + /* Targets which still implement the prologue in assembler text + cannot use the generic dwarf2 unwinding. */ + return false; +#endif + + /* ??? What to do for UI_TARGET unwinding? They might be able to benefit + from the optimized shrink-wrapping annotations that we will compute. + For now, only produce the CFI notes for dwarf2. */ + return dwarf2out_do_frame (); +} + +struct rtl_opt_pass pass_dwarf2_frame = +{ + { + RTL_PASS, + "dwarf2", /* name */ + gate_dwarf2_frame, /* gate */ + execute_dwarf2_frame, /* execute */ + NULL, /* sub */ + NULL, /* next */ + 0, /* static_pass_number */ + TV_FINAL, /* tv_id */ + 0, /* properties_required */ + 0, /* properties_provided */ + 0, /* properties_destroyed */ + 0, /* todo_flags_start */ + 0 /* todo_flags_finish */ + } +}; + #include "gt-dwarf2cfi.h" diff --git a/gcc/dwarf2out.c b/gcc/dwarf2out.c index 0f93964..097e57f 100644 --- a/gcc/dwarf2out.c +++ b/gcc/dwarf2out.c @@ -1605,15 +1605,20 @@ dwarf2out_begin_prologue (unsigned int line ATTRIBUTE_UNUSED, if (!do_frame) return; + /* Cater to the various TARGET_ASM_OUTPUT_MI_THUNK implementations that + emit insns as rtx but bypass the bulk of rest_of_compilation, which + would include pass_dwarf2_frame. If we've not created the FDE yet, + do so now. */ + fde = cfun->fde; + if (fde == NULL) + fde = dwarf2out_alloc_current_fde (); + /* Initialize the bits of CURRENT_FDE that were not available earlier. */ - fde = dwarf2out_alloc_current_fde (); fde->dw_fde_begin = dup_label; fde->dw_fde_current_label = dup_label; fde->in_std_section = (fnsec == text_section || (cold_text_section && fnsec == cold_text_section)); - dwarf2cfi_function_init (); - /* We only want to output line number information for the genuine dwarf2 prologue case, not the eh frame case. */ #ifdef DWARF2_DEBUGGING_INFO diff --git a/gcc/dwarf2out.h b/gcc/dwarf2out.h index abc2208..7122dee 100644 --- a/gcc/dwarf2out.h +++ b/gcc/dwarf2out.h @@ -229,7 +229,6 @@ extern enum machine_mode get_address_mode (rtx mem); extern dw_fde_ref dwarf2out_alloc_current_fde (void); /* Interface from dwarf2cfi.c to dwarf2out.c. */ -extern void dwarf2cfi_function_init (void); extern void lookup_cfa_1 (dw_cfi_ref cfi, dw_cfa_location *loc, dw_cfa_location *remember); extern bool cfa_equal_p (const dw_cfa_location *, const dw_cfa_location *); @@ -243,9 +242,6 @@ extern enum dw_cfi_oprnd_type dw_cfi_oprnd2_desc (enum dwarf_call_frame_info cfi); extern void dwarf2out_decl (tree); -extern void dwarf2out_frame_debug (rtx, bool); -extern void dwarf2out_frame_debug_init (void); -extern void dwarf2out_frame_debug_after_prologue (void); extern void dwarf2out_emit_cfi (dw_cfi_ref cfi); extern void debug_dwarf (void); diff --git a/gcc/final.c b/gcc/final.c index 319d238..483a645 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -1560,11 +1560,6 @@ final_start_function (rtx first ATTRIBUTE_UNUSED, FILE *file, if (targetm.profile_before_prologue () && crtl->profile) profile_function (file); -#if defined (HAVE_prologue) - if (dwarf2out_do_frame ()) - dwarf2out_frame_debug_init (); -#endif - /* If debugging, assign block numbers to all of the blocks in this function. */ if (write_symbols) @@ -1589,11 +1584,6 @@ final_start_function (rtx first ATTRIBUTE_UNUSED, FILE *file, /* First output the function prologue: code to set up the stack frame. */ targetm.asm_out.function_prologue (file, get_frame_size ()); -#if defined (HAVE_prologue) - if (dwarf2out_do_frame ()) - dwarf2out_frame_debug_after_prologue (); -#endif - /* If the machine represents the prologue as RTL, the profiling code must be emitted when NOTE_INSN_PROLOGUE_END is scanned. */ #ifdef HAVE_prologue diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c index 25ccb24..468c630 100644 --- a/gcc/lto-streamer-in.c +++ b/gcc/lto-streamer-in.c @@ -657,14 +657,6 @@ lto_init_eh (void) flag_exceptions = 1; init_eh (); - /* Initialize dwarf2 tables. Since dwarf2out_do_frame() returns - true only when exceptions are enabled, this initialization is - never done during lang_dependent_init. */ -#if defined DWARF2_DEBUGGING_INFO || defined DWARF2_UNWIND_INFO - if (dwarf2out_do_frame ()) - dwarf2out_frame_init (); -#endif - eh_initialized_p = true; } diff --git a/gcc/passes.c b/gcc/passes.c index fc9767e..c7e77cb 100644 --- a/gcc/passes.c +++ b/gcc/passes.c @@ -1506,6 +1506,7 @@ init_optimization_passes (void) NEXT_PASS (pass_convert_to_eh_region_ranges); NEXT_PASS (pass_shorten_branches); NEXT_PASS (pass_set_nothrow_function_flags); + NEXT_PASS (pass_dwarf2_frame); NEXT_PASS (pass_final); } NEXT_PASS (pass_df_finish); diff --git a/gcc/toplev.c b/gcc/toplev.c index 884994c..4591c30 100644 --- a/gcc/toplev.c +++ b/gcc/toplev.c @@ -1741,11 +1741,6 @@ lang_dependent_init (const char *name) predefined types. */ timevar_push (TV_SYMOUT); -#if defined DWARF2_DEBUGGING_INFO || defined DWARF2_UNWIND_INFO - if (dwarf2out_do_frame ()) - dwarf2out_frame_init (); -#endif - /* Now we have the correct original filename, we can initialize debug output. */ (*debug_hooks->init) (name); diff --git a/gcc/tree-pass.h b/gcc/tree-pass.h index 2d277ed..f5de1f6 100644 --- a/gcc/tree-pass.h +++ b/gcc/tree-pass.h @@ -567,6 +567,7 @@ extern struct rtl_opt_pass pass_split_before_regstack; extern struct rtl_opt_pass pass_convert_to_eh_region_ranges; extern struct rtl_opt_pass pass_shorten_branches; extern struct rtl_opt_pass pass_set_nothrow_function_flags; +extern struct rtl_opt_pass pass_dwarf2_frame; extern struct rtl_opt_pass pass_final; extern struct rtl_opt_pass pass_rtl_seqabstr; extern struct gimple_opt_pass pass_release_ssa_names; -- 1.7.5.4