Commit cd9c1ca8 by Richard Henderson Committed by Richard Henderson

cfgcleanup.c (try_crossjump_to_edge): Only skip past NOTE_INSN_BASIC_BLOCK.

	* cfgcleanup.c (try_crossjump_to_edge): Only skip past
	NOTE_INSN_BASIC_BLOCK.
	* cfglayout.c (duplicate_insn_chain): Copy epilogue insn marks.
	Duplicate NOTE_INSN_EPILOGUE_BEG notes.
	* cfgrtl.c (can_delete_note_p): Allow NOTE_INSN_EPILOGUE_BEG
	to be deleted.
	* dwarf2out.c (struct cfa_loc): Change indirect field to bitfield,
	add in_use field.
	(add_cfi): Disable check redefining cfa away from drap.
	(lookup_cfa_1): Add remember argument; handle remember/restore.
	(lookup_cfa): Pass remember argument.
	(cfa_remember): New.
	(compute_barrier_args_size_1): Remove sibcall check.
	(dwarf2out_frame_debug_def_cfa): New.
	(dwarf2out_frame_debug_adjust_cfa): New.
	(dwarf2out_frame_debug_cfa_offset): New.
	(dwarf2out_frame_debug_cfa_register): New.
	(dwarf2out_frame_debug_cfa_restore): New.
	(dwarf2out_frame_debug): Handle REG_CFA_* notes.
	(dwarf2out_begin_epilogue): New.
	(dwarf2out_frame_debug_restore_state): New.
	(dw_cfi_oprnd1_desc): Handle DW_CFA_remember_state,
	DW_CFA_restore_state.
	(output_cfi_directive): Likewise.
	(convert_cfa_to_fb_loc_list): Likewise.
	(dw_cfi_oprnd1_desc): Handle DW_CFA_restore.
	* dwarf2out.h: Update.
	* emit-rtl.c (try_split): Don't split RTX_FRAME_RELATED_P.
	(copy_insn_1): Early out for null.
	* final.c (final_scan_insn): Call dwarf2out_begin_epilogue
	and dwarf2out_frame_debug_restore_state.
	* function.c (prologue, epilogue, sibcall_epilogue): Remove.
	(prologue_insn_hash, epilogue_insn_hash): New.
	(free_after_compilation): Adjust freeing accordingly.
	(record_insns): Create hash table if needed; push insns into
	hash instead of array.
	(maybe_copy_epilogue_insn): New.
	(contains): Search hash table instead of array.
	(sibcall_epilogue_contains): Remove.
	(thread_prologue_and_epilogue_insns): Split eh_return insns
	and mark them as epilogues.
	(reposition_prologue_and_epilogue_notes): Rewrite epilogue
	scanning in terms of basic blocks.
	* insn-notes.def (CFA_RESTORE_STATE): New.
	* jump.c (returnjump_p_1): Accept EH_RETURN.
	(eh_returnjump_p_1, eh_returnjump_p): New.
	* reg-notes.def (CFA_DEF_CFA, CFA_ADJUST_CFA, CFA_OFFSET,
	CFA_REGISTER, CFA_RESTORE): New.
	* rtl.def (EH_RETURN): New.
	* rtl.h (eh_returnjump_p, maybe_copy_epilogue_insn): Declare.

	* config/bfin/bfin.md (UNSPEC_VOLATILE_EH_RETURN): Remove.
	(eh_return_internal): Use eh_return rtx; split w/ epilogue.

	* config/i386/i386.c (gen_push): Update cfa state.
	(pro_epilogue_adjust_stack): Add set_cfa argument.  When true,
	add a CFA_ADJUST_CFA note.
	(ix86_dwarf_handle_frame_unspec): Remove.
	(ix86_expand_prologue): Update cfa state.
	(ix86_emit_restore_reg_using_pop): New.
	(ix86_emit_restore_regs_using_pop): New.
	(ix86_emit_leave): New.
	(ix86_emit_restore_regs_using_mov): Add CFA_RESTORE notes.
	(ix86_expand_epilogue): Add notes for unwinding the epilogue.
	* config/i386/i386.h (struct machine_cfa_state): New.
	(ix86_cfa_state): New.
	* config/i386/i386.md (UNSPEC_EH_RETURN): Remove.
	(eh_return_internal): Merge from eh_return_<mode>,
	use eh_return rtx, split w/ epilogue.

From-SVN: r147995
parent 36bac386
2009-05-29 Richard Henderson <rth@redhat.com>
* cfgcleanup.c (try_crossjump_to_edge): Only skip past
NOTE_INSN_BASIC_BLOCK.
* cfglayout.c (duplicate_insn_chain): Copy epilogue insn marks.
Duplicate NOTE_INSN_EPILOGUE_BEG notes.
* cfgrtl.c (can_delete_note_p): Allow NOTE_INSN_EPILOGUE_BEG
to be deleted.
* dwarf2out.c (struct cfa_loc): Change indirect field to bitfield,
add in_use field.
(add_cfi): Disable check redefining cfa away from drap.
(lookup_cfa_1): Add remember argument; handle remember/restore.
(lookup_cfa): Pass remember argument.
(cfa_remember): New.
(compute_barrier_args_size_1): Remove sibcall check.
(dwarf2out_frame_debug_def_cfa): New.
(dwarf2out_frame_debug_adjust_cfa): New.
(dwarf2out_frame_debug_cfa_offset): New.
(dwarf2out_frame_debug_cfa_register): New.
(dwarf2out_frame_debug_cfa_restore): New.
(dwarf2out_frame_debug): Handle REG_CFA_* notes.
(dwarf2out_begin_epilogue): New.
(dwarf2out_frame_debug_restore_state): New.
(dw_cfi_oprnd1_desc): Handle DW_CFA_remember_state,
DW_CFA_restore_state.
(output_cfi_directive): Likewise.
(convert_cfa_to_fb_loc_list): Likewise.
(dw_cfi_oprnd1_desc): Handle DW_CFA_restore.
* dwarf2out.h: Update.
* emit-rtl.c (try_split): Don't split RTX_FRAME_RELATED_P.
(copy_insn_1): Early out for null.
* final.c (final_scan_insn): Call dwarf2out_begin_epilogue
and dwarf2out_frame_debug_restore_state.
* function.c (prologue, epilogue, sibcall_epilogue): Remove.
(prologue_insn_hash, epilogue_insn_hash): New.
(free_after_compilation): Adjust freeing accordingly.
(record_insns): Create hash table if needed; push insns into
hash instead of array.
(maybe_copy_epilogue_insn): New.
(contains): Search hash table instead of array.
(sibcall_epilogue_contains): Remove.
(thread_prologue_and_epilogue_insns): Split eh_return insns
and mark them as epilogues.
(reposition_prologue_and_epilogue_notes): Rewrite epilogue
scanning in terms of basic blocks.
* insn-notes.def (CFA_RESTORE_STATE): New.
* jump.c (returnjump_p_1): Accept EH_RETURN.
(eh_returnjump_p_1, eh_returnjump_p): New.
* reg-notes.def (CFA_DEF_CFA, CFA_ADJUST_CFA, CFA_OFFSET,
CFA_REGISTER, CFA_RESTORE): New.
* rtl.def (EH_RETURN): New.
* rtl.h (eh_returnjump_p, maybe_copy_epilogue_insn): Declare.
* config/bfin/bfin.md (UNSPEC_VOLATILE_EH_RETURN): Remove.
(eh_return_internal): Use eh_return rtx; split w/ epilogue.
* config/i386/i386.c (gen_push): Update cfa state.
(pro_epilogue_adjust_stack): Add set_cfa argument. When true,
add a CFA_ADJUST_CFA note.
(ix86_dwarf_handle_frame_unspec): Remove.
(ix86_expand_prologue): Update cfa state.
(ix86_emit_restore_reg_using_pop): New.
(ix86_emit_restore_regs_using_pop): New.
(ix86_emit_leave): New.
(ix86_emit_restore_regs_using_mov): Add CFA_RESTORE notes.
(ix86_expand_epilogue): Add notes for unwinding the epilogue.
* config/i386/i386.h (struct machine_cfa_state): New.
(ix86_cfa_state): New.
* config/i386/i386.md (UNSPEC_EH_RETURN): Remove.
(eh_return_internal): Merge from eh_return_<mode>,
use eh_return rtx, split w/ epilogue.
2009-05-29 Ian Lance Taylor <iant@google.com>
* builtins.c (validate_gimple_arglist): Don't use va_arg with
......
......@@ -1672,8 +1672,7 @@ try_crossjump_to_edge (int mode, edge e1, edge e2)
/* Skip possible basic block header. */
if (LABEL_P (newpos1))
newpos1 = NEXT_INSN (newpos1);
if (NOTE_P (newpos1))
if (NOTE_INSN_BASIC_BLOCK_P (newpos1))
newpos1 = NEXT_INSN (newpos1);
redirect_from = split_block (src1, PREV_INSN (newpos1))->src;
......
......@@ -1112,7 +1112,7 @@ cfg_layout_can_duplicate_bb_p (const_basic_block bb)
rtx
duplicate_insn_chain (rtx from, rtx to)
{
rtx insn, last;
rtx insn, last, copy;
/* Avoid updating of boundaries of previous basic block. The
note will get removed from insn stream in fixup. */
......@@ -1133,7 +1133,8 @@ duplicate_insn_chain (rtx from, rtx to)
if (GET_CODE (PATTERN (insn)) == ADDR_VEC
|| GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
break;
emit_copy_of_insn_after (insn, get_last_insn ());
copy = emit_copy_of_insn_after (insn, get_last_insn ());
maybe_copy_epilogue_insn (insn, copy);
break;
case CODE_LABEL:
......@@ -1153,23 +1154,18 @@ duplicate_insn_chain (rtx from, rtx to)
case NOTE_INSN_DELETED:
case NOTE_INSN_DELETED_LABEL:
/* No problem to strip these. */
case NOTE_INSN_EPILOGUE_BEG:
/* Debug code expect these notes to exist just once.
Keep them in the master copy.
??? It probably makes more sense to duplicate them for each
epilogue copy. */
case NOTE_INSN_FUNCTION_BEG:
/* There is always just single entry to function. */
case NOTE_INSN_BASIC_BLOCK:
break;
case NOTE_INSN_EPILOGUE_BEG:
case NOTE_INSN_SWITCH_TEXT_SECTIONS:
emit_note_copy (insn);
break;
default:
/* All other notes should have already been eliminated.
*/
/* All other notes should have already been eliminated. */
gcc_unreachable ();
}
break;
......
......@@ -86,8 +86,16 @@ static void rtl_make_forwarder_block (edge);
static int
can_delete_note_p (const_rtx note)
{
return (NOTE_KIND (note) == NOTE_INSN_DELETED
|| NOTE_KIND (note) == NOTE_INSN_BASIC_BLOCK);
switch (NOTE_KIND (note))
{
case NOTE_INSN_DELETED:
case NOTE_INSN_BASIC_BLOCK:
case NOTE_INSN_EPILOGUE_BEG:
return true;
default:
return false;
}
}
/* True if a given label can be deleted. */
......
......@@ -141,8 +141,7 @@
(UNSPEC_ONES 12)])
(define_constants
[(UNSPEC_VOLATILE_EH_RETURN 0)
(UNSPEC_VOLATILE_CSYNC 1)
[(UNSPEC_VOLATILE_CSYNC 1)
(UNSPEC_VOLATILE_SSYNC 2)
(UNSPEC_VOLATILE_LOAD_FUNCDESC 3)
(UNSPEC_VOLATILE_STORE_EH_HANDLER 4)
......@@ -2573,8 +2572,7 @@
"bfin_expand_epilogue (0, 0, 1); DONE;")
(define_expand "eh_return"
[(unspec_volatile [(match_operand:SI 0 "register_operand" "")]
UNSPEC_VOLATILE_EH_RETURN)]
[(use (match_operand:SI 0 "register_operand" ""))]
""
{
emit_insn (gen_eh_store_handler (EH_RETURN_HANDLER_RTX, operands[0]));
......@@ -2592,11 +2590,10 @@
[(set_attr "type" "mcst")])
(define_insn_and_split "eh_return_internal"
[(set (pc)
(unspec_volatile [(reg:SI REG_P2)] UNSPEC_VOLATILE_EH_RETURN))]
[(eh_return)]
""
"#"
"reload_completed"
"epilogue_completed"
[(const_int 1)]
"bfin_expand_epilogue (1, 1, 0); DONE;")
......
......@@ -2393,6 +2393,15 @@ enum ix86_stack_slot
#define FASTCALL_PREFIX '@'
/* Machine specific CFA tracking during prologue/epilogue generation. */
#if !defined(IN_LIBGCC2) && !defined(IN_TARGET_LIBS)
struct GTY(()) machine_cfa_state
{
rtx reg;
HOST_WIDE_INT offset;
};
struct GTY(()) machine_function {
struct stack_local_entry *stack_locals;
const char *some_ld_name;
......@@ -2419,8 +2428,10 @@ struct GTY(()) machine_function {
int tls_descriptor_call_expanded_p;
/* This value is used for amd64 targets and specifies the current abi
to be used. MS_ABI means ms abi. Otherwise SYSV_ABI means sysv abi. */
enum calling_abi call_abi;
enum calling_abi call_abi;
struct machine_cfa_state cfa;
};
#endif
#define ix86_stack_locals (cfun->machine->stack_locals)
#define ix86_varargs_gpr_size (cfun->machine->varargs_gpr_size)
......@@ -2436,6 +2447,7 @@ struct GTY(()) machine_function {
REG_SP is live. */
#define ix86_current_function_calls_tls_descriptor \
(ix86_tls_descriptor_calls_expanded_in_cfun && df_regs_ever_live_p (SP_REG))
#define ix86_cfa_state (&cfun->machine->cfa)
/* Control behavior of x86_file_start. */
#define X86_FILE_START_VERSION_DIRECTIVE false
......
......@@ -101,7 +101,6 @@
(UNSPEC_ADD_CARRY 34)
(UNSPEC_FLDCW 35)
(UNSPEC_REP 36)
(UNSPEC_EH_RETURN 37)
(UNSPEC_LD_MPIC 38) ; load_macho_picbase
(UNSPEC_TRUNC_NOOP 39)
......@@ -15982,21 +15981,16 @@
tmp = gen_rtx_MEM (Pmode, tmp);
emit_move_insn (tmp, ra);
if (Pmode == SImode)
emit_jump_insn (gen_eh_return_si (sa));
else
emit_jump_insn (gen_eh_return_di (sa));
emit_jump_insn (gen_eh_return_internal ());
emit_barrier ();
DONE;
})
(define_insn_and_split "eh_return_<mode>"
[(set (pc)
(unspec [(match_operand:P 0 "register_operand" "c")]
UNSPEC_EH_RETURN))]
(define_insn_and_split "eh_return_internal"
[(eh_return)]
""
"#"
"reload_completed"
"epilogue_completed"
[(const_int 0)]
"ix86_expand_epilogue (2); DONE;")
......
......@@ -20,6 +20,8 @@ along with GCC; see the file COPYING3. If not see
extern void dwarf2out_decl (tree);
extern void dwarf2out_frame_debug (rtx, bool);
extern void dwarf2out_begin_epilogue (rtx);
extern void dwarf2out_frame_debug_restore_state (void);
extern void debug_dwarf (void);
struct die_struct;
......
......@@ -3335,6 +3335,10 @@ try_split (rtx pat, rtx trial, int last)
rtx insn_last, insn;
int njumps = 0;
/* We're not good at redistributing frame information. */
if (RTX_FRAME_RELATED_P (trial))
return trial;
if (any_condjump_p (trial)
&& (note = find_reg_note (trial, REG_BR_PROB, 0)))
split_branch_probability = INTVAL (XEXP (note, 0));
......@@ -5050,6 +5054,9 @@ copy_insn_1 (rtx orig)
RTX_CODE code;
const char *format_ptr;
if (orig == NULL)
return NULL;
code = GET_CODE (orig);
switch (code)
......
......@@ -1879,9 +1879,19 @@ final_scan_insn (rtx insn, FILE *file, int optimize ATTRIBUTE_UNUSED,
break;
case NOTE_INSN_EPILOGUE_BEG:
#if defined (DWARF2_UNWIND_INFO) && defined (HAVE_epilogue)
if (dwarf2out_do_frame ())
dwarf2out_begin_epilogue (insn);
#endif
targetm.asm_out.function_begin_epilogue (file);
break;
case NOTE_INSN_CFA_RESTORE_STATE:
#if defined (DWARF2_UNWIND_INFO)
dwarf2out_frame_debug_restore_state ();
#endif
break;
case NOTE_INSN_FUNCTION_BEG:
app_disable ();
(*debug_hooks->end_prologue) (last_linenum, last_filename);
......
......@@ -70,4 +70,8 @@ INSN_NOTE (BASIC_BLOCK)
between hot and cold text sections. */
INSN_NOTE (SWITCH_TEXT_SECTIONS)
/* Mark the restore point after an epilogue changed CFI data. Used only
when an epilogue appears in the middle of a function. */
INSN_NOTE (CFA_RESTORE_STATE)
#undef INSN_NOTE
......@@ -869,8 +869,21 @@ returnjump_p_1 (rtx *loc, void *data ATTRIBUTE_UNUSED)
{
rtx x = *loc;
return x && (GET_CODE (x) == RETURN
|| (GET_CODE (x) == SET && SET_IS_RETURN_P (x)));
if (x == NULL)
return false;
switch (GET_CODE (x))
{
case RETURN:
case EH_RETURN:
return true;
case SET:
return SET_IS_RETURN_P (x);
default:
return false;
}
}
int
......@@ -881,6 +894,22 @@ returnjump_p (rtx insn)
return for_each_rtx (&PATTERN (insn), returnjump_p_1, NULL);
}
/* Return true if INSN is a (possibly conditional) return insn. */
static int
eh_returnjump_p_1 (rtx *loc, void *data ATTRIBUTE_UNUSED)
{
return *loc && GET_CODE (*loc) == EH_RETURN;
}
int
eh_returnjump_p (rtx insn)
{
if (!JUMP_P (insn))
return 0;
return for_each_rtx (&PATTERN (insn), eh_returnjump_p_1, NULL);
}
/* Return true if INSN is a jump that only transfers control and
nothing more. */
......
......@@ -118,6 +118,41 @@ REG_NOTE (BR_PRED)
instead of intuition. */
REG_NOTE (FRAME_RELATED_EXPR)
/* Attached to insns that are RTX_FRAME_RELATED_P, but are too complex
for FRAME_RELATED_EXPR intuition. The insn's first pattern must be
a SET, and the destination must be the CFA register. The attached
rtx is an expression that defines the CFA. In the simplest case, the
rtx could be just the stack_pointer_rtx; more common would be a PLUS
with a base register and a constant offset. In the most complicated
cases, this will result in a DW_CFA_def_cfa_expression with the rtx
expression rendered in a dwarf location expression. */
REG_NOTE (CFA_DEF_CFA)
/* Attached to insns that are RTX_FRAME_RELATED_P, but are too complex
for FRAME_RELATED_EXPR intuition. This note adjusts the expression
from which the CFA is computed. The attached rtx defines a new CFA
expression, relative to the old CFA expression. This rtx must be of
the form (SET new-cfa-reg (PLUS old-cfa-reg const_int)). If the note
rtx is NULL, we use the first SET of the insn. */
REG_NOTE (CFA_ADJUST_CFA)
/* Similar to FRAME_RELATED_EXPR, with the additional information that
this is a save to memory, i.e. will result in DW_CFA_offset or the
like. The pattern or the insn should be a simple store relative to
the CFA. */
REG_NOTE (CFA_OFFSET)
/* Similar to FRAME_RELATED_EXPR, with the additional information that this
is a save to a register, i.e. will result in DW_CFA_register. The insn
or the pattern should be simple reg-reg move. */
REG_NOTE (CFA_REGISTER)
/* Attached to insns that are RTX_FRAME_RELATED_P, with the information
that this is a restore operation, i.e. will result in DW_CFA_restore
or the like. Either the attached rtx, or the destination of the insn's
first pattern is the register to be restored. */
REG_NOTE (CFA_RESTORE)
/* 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. */
......
......@@ -281,6 +281,10 @@ DEF_RTL_EXPR(CALL, "call", "ee", RTX_EXTRA)
DEF_RTL_EXPR(RETURN, "return", "", RTX_EXTRA)
/* Special for EH return from subroutine. */
DEF_RTL_EXPR(EH_RETURN, "eh_return", "", RTX_EXTRA)
/* Conditional trap.
Operand 1 is the condition.
Operand 2 is the trap code.
......
......@@ -2086,6 +2086,7 @@ extern rtx pc_set (const_rtx);
extern rtx condjump_label (const_rtx);
extern int simplejump_p (const_rtx);
extern int returnjump_p (rtx);
extern int eh_returnjump_p (rtx);
extern int onlyjump_p (const_rtx);
extern int only_sets_cc0_p (const_rtx);
extern int sets_cc0_p (const_rtx);
......@@ -2198,6 +2199,7 @@ extern int prologue_epilogue_contains (const_rtx);
extern int sibcall_epilogue_contains (const_rtx);
extern void mark_temp_addr_taken (rtx);
extern void update_temp_slot_address (rtx, rtx);
extern void maybe_copy_epilogue_insn (rtx, rtx);
/* In stmt.c */
extern void expand_null_return (void);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment