dwarf2: Extract cfi creation to a new pass.
* tree-pass.h (pass_dwarf2_frame): Declare. * passes.c (init_optimization_passes): Add it. * dwarf2cfi.c (dwarf2out_frame_debug): Make static. (create_cfi_notes): Rename from dwarf2out_frame_debug_after_prologue; make static, do not call add_cfis_to_fde. (dwarf2out_frame_debug_init, dwarf2cfi_function_init, dwarf2out_frame_init): Merge into... (execute_dwarf2_frame): ... here. New function. (dwarf2out_do_frame, dwarf2out_do_cfi_asm): Make boolean. Change saved_do_cfi_asm to a tri-state variable. (gate_dwarf2_frame, pass_dwarf2_frame): New. * dwarf2out.c (dwarf2out_begin_prologue): Only allocate the fde if it has yet to be done. Don't call dwarf2cfi_function_init. * dwarf2out.h, debug.h: Update decls. * final.c (final_start_function): Don't call dwarf2out_frame_debug_init or dwarf2out_frame_debug_after_prologue. * lto-streamer-in.c (lto_init_eh): Don't call dwarf2out_frame_init. * toplev.c (lang_dependent_init): Likewise. From-SVN: r176019
This commit is contained in:
parent
a518b99616
commit
7644b3c7f0
|
@ -1,3 +1,24 @@
|
|||
2011-07-07 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* tree-pass.h (pass_dwarf2_frame): Declare.
|
||||
* passes.c (init_optimization_passes): Add it.
|
||||
* dwarf2cfi.c (dwarf2out_frame_debug): Make static.
|
||||
(create_cfi_notes): Rename from dwarf2out_frame_debug_after_prologue;
|
||||
make static, do not call add_cfis_to_fde.
|
||||
(dwarf2out_frame_debug_init, dwarf2cfi_function_init,
|
||||
dwarf2out_frame_init): Merge into...
|
||||
(execute_dwarf2_frame): ... here. New function.
|
||||
(dwarf2out_do_frame, dwarf2out_do_cfi_asm): Make boolean. Change
|
||||
saved_do_cfi_asm to a tri-state variable.
|
||||
(gate_dwarf2_frame, pass_dwarf2_frame): New.
|
||||
* dwarf2out.c (dwarf2out_begin_prologue): Only allocate the fde
|
||||
if it has yet to be done. Don't call dwarf2cfi_function_init.
|
||||
* dwarf2out.h, debug.h: Update decls.
|
||||
* final.c (final_start_function): Don't call
|
||||
dwarf2out_frame_debug_init or dwarf2out_frame_debug_after_prologue.
|
||||
* lto-streamer-in.c (lto_init_eh): Don't call dwarf2out_frame_init.
|
||||
* toplev.c (lang_dependent_init): Likewise.
|
||||
|
||||
2011-07-07 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* dwarf2out.c (fde_table, fde_table_allocated, fde_table_in_use,
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2011-07-07 Richard Henderson <rth@redhat.com>
|
||||
|
||||
* gcc-interface/misc.c (gnat_init_gcc_eh): Don't call
|
||||
dwarf2out_frame_init.
|
||||
|
||||
2011-07-07 Eric Botcazou <ebotcazou@adacore.com>
|
||||
|
||||
* gcc-interface/misc.c (gnat_init): Tweak previous change.
|
||||
|
|
|
@ -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. */
|
||||
|
|
|
@ -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 *);
|
||||
|
|
169
gcc/dwarf2cfi.c
169
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)
|
||||
{
|
||||
/* The first time we're called, compute the incoming frame state. */
|
||||
if (cie_cfi_vec == NULL)
|
||||
{
|
||||
dw_cfa_location loc;
|
||||
|
||||
memset(&old_cfa, 0, sizeof (old_cfa));
|
||||
old_cfa.reg = INVALID_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);
|
||||
|
||||
if (targetm.debug_unwind_info () == UI_DWARF2
|
||||
|| targetm_common.except_unwind_info (&global_options) == UI_DWARF2)
|
||||
initial_return_save (INCOMING_RETURN_ADDR_RTX);
|
||||
}
|
||||
|
||||
/* 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;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
/* Run once. */
|
||||
|
||||
void
|
||||
dwarf2out_frame_init (void)
|
||||
{
|
||||
dw_cfa_location loc;
|
||||
|
||||
/* Generate the CFA instructions common to all FDE's. Do it now for the
|
||||
sake of lookup_cfa. */
|
||||
|
||||
memset(&old_cfa, 0, sizeof (old_cfa));
|
||||
old_cfa.reg = INVALID_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);
|
||||
|
||||
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"
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
|
|
10
gcc/final.c
10
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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue