From d33606c30678cbccf0e95840e7dc48918ff1e21e Mon Sep 17 00:00:00 2001 From: Eric Botcazou Date: Tue, 19 May 2015 09:33:27 +0000 Subject: [PATCH] insn-notes.def (UPDATE_SJLJ_CONTEXT): New note. * insn-notes.def (UPDATE_SJLJ_CONTEXT): New note. * builtins.c (expand_builtin_update_setjmp_buf): Make global. (expand_stack_restore): Call record_new_stack_level. (expand_stack_save): Do not call do_pending_stack_adjust. * builtins.h (expand_builtin_update_setjmp_buf): Declare. * calls.c (expand_call): Call record_new_stack_level for alloca. * except.c (sjlj_mark_call_sites): Expand builtin_update_setjmp_buf wherever a NOTE_INSN_UPDATE_SJLJ_CONTEXT note is present. (update_sjlj_context): New global function. * except.h (update_sjlj_context): Declare. * explow.c (record_new_stack_level): New global function. (allocate_dynamic_stack_space): Call record_new_stack_level. * explow.h (record_new_stack_level): Declare. * final.c (final_scan_insn): Deal with NOTE_INSN_UPDATE_SJLJ_CONTEXT. * cfgrtl.c (duplicate_insn_chain): Likewise. Co-Authored-By: Tristan Gingold From-SVN: r223348 --- gcc/ChangeLog | 19 +++++++++++++++++++ gcc/builtins.c | 12 ++++++------ gcc/builtins.h | 1 + gcc/calls.c | 9 +++------ gcc/cfgrtl.c | 1 + gcc/except.c | 27 +++++++++++++++++++++++++++ gcc/except.h | 1 + gcc/explow.c | 24 +++++++++++++++++++----- gcc/explow.h | 3 +++ gcc/final.c | 1 + gcc/insn-notes.def | 4 ++++ 11 files changed, 85 insertions(+), 17 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 66b01411ce8..46a45d4c15b 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,22 @@ +2015-05-19 Eric Botcazou + Tristan Gingold + + * insn-notes.def (UPDATE_SJLJ_CONTEXT): New note. + * builtins.c (expand_builtin_update_setjmp_buf): Make global. + (expand_stack_restore): Call record_new_stack_level. + (expand_stack_save): Do not call do_pending_stack_adjust. + * builtins.h (expand_builtin_update_setjmp_buf): Declare. + * calls.c (expand_call): Call record_new_stack_level for alloca. + * except.c (sjlj_mark_call_sites): Expand builtin_update_setjmp_buf + wherever a NOTE_INSN_UPDATE_SJLJ_CONTEXT note is present. + (update_sjlj_context): New global function. + * except.h (update_sjlj_context): Declare. + * explow.c (record_new_stack_level): New global function. + (allocate_dynamic_stack_space): Call record_new_stack_level. + * explow.h (record_new_stack_level): Declare. + * final.c (final_scan_insn): Deal with NOTE_INSN_UPDATE_SJLJ_CONTEXT. + * cfgrtl.c (duplicate_insn_chain): Likewise. + 2015-05-19 Kyrylo Tkachov * calls.c: Always define STACK_GROWS_DOWNWARD as 0 or 1. diff --git a/gcc/builtins.c b/gcc/builtins.c index 95445247c12..030cc35f074 100644 --- a/gcc/builtins.c +++ b/gcc/builtins.c @@ -120,7 +120,6 @@ static int apply_result_size (void); #if defined (HAVE_untyped_call) || defined (HAVE_untyped_return) static rtx result_vector (int, rtx); #endif -static void expand_builtin_update_setjmp_buf (rtx); static void expand_builtin_prefetch (tree); static rtx expand_builtin_apply_args (void); static rtx expand_builtin_apply_args_1 (void); @@ -1213,10 +1212,10 @@ expand_builtin_nonlocal_goto (tree exp) /* __builtin_update_setjmp_buf is passed a pointer to an array of five words (not all will be used on all machines) that was passed to __builtin_setjmp. - It updates the stack pointer in that block to correspond to the current - stack pointer. */ + It updates the stack pointer in that block to the current value. This is + also called directly by the SJLJ exception handling code. */ -static void +void expand_builtin_update_setjmp_buf (rtx buf_addr) { machine_mode sa_mode = STACK_SAVEAREA_MODE (SAVE_NONLOCAL); @@ -5887,10 +5886,12 @@ expand_stack_restore (tree var) prev = get_last_insn (); emit_stack_restore (SAVE_BLOCK, sa); + + record_new_stack_level (); + fixup_args_size_notes (prev, get_last_insn (), 0); } - /* Emit code to save the current value of stack. */ static rtx @@ -5898,7 +5899,6 @@ expand_stack_save (void) { rtx ret = NULL_RTX; - do_pending_stack_adjust (); emit_stack_save (SAVE_BLOCK, &ret); return ret; } diff --git a/gcc/builtins.h b/gcc/builtins.h index cf2ddb49482..5a0b57d2658 100644 --- a/gcc/builtins.h +++ b/gcc/builtins.h @@ -59,6 +59,7 @@ extern unsigned int get_pointer_alignment (tree); extern tree c_strlen (tree, int); extern void expand_builtin_setjmp_setup (rtx, rtx); extern void expand_builtin_setjmp_receiver (rtx); +extern void expand_builtin_update_setjmp_buf (rtx); extern tree mathfn_built_in (tree, enum built_in_function fn); extern rtx builtin_strncpy_read_str (void *, HOST_WIDE_INT, machine_mode); extern rtx builtin_memset_read_str (void *, HOST_WIDE_INT, machine_mode); diff --git a/gcc/calls.c b/gcc/calls.c index d631cc0165e..9cd488d175d 100644 --- a/gcc/calls.c +++ b/gcc/calls.c @@ -3649,12 +3649,9 @@ expand_call (tree exp, rtx target, int ignore) stack_usage_map = initial_stack_usage_map; } - /* If this was alloca, record the new stack level for nonlocal gotos. - Check for the handler slots since we might not have a save area - for non-local gotos. */ - - if ((flags & ECF_MAY_BE_ALLOCA) && cfun->nonlocal_goto_save_area != 0) - update_nonlocal_goto_save_area (); + /* If this was alloca, record the new stack level. */ + if (flags & ECF_MAY_BE_ALLOCA) + record_new_stack_level (); /* Free up storage we no longer need. */ for (i = 0; i < num_actuals; ++i) diff --git a/gcc/cfgrtl.c b/gcc/cfgrtl.c index 390d7185b46..466c6dace42 100644 --- a/gcc/cfgrtl.c +++ b/gcc/cfgrtl.c @@ -4209,6 +4209,7 @@ duplicate_insn_chain (rtx_insn *from, rtx_insn *to) break; case NOTE_INSN_EPILOGUE_BEG: + case NOTE_INSN_UPDATE_SJLJ_CONTEXT: emit_note_copy (as_a (insn)); break; diff --git a/gcc/except.c b/gcc/except.c index 770ab98ee54..673e9c3adcb 100644 --- a/gcc/except.c +++ b/gcc/except.c @@ -1126,6 +1126,21 @@ sjlj_mark_call_sites (void) if (LABEL_P (insn)) last_call_site = -2; + /* If the function allocates dynamic stack space, the context must + be updated after every allocation/deallocation accordingly. */ + if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_UPDATE_SJLJ_CONTEXT) + { + rtx buf_addr; + + start_sequence (); + buf_addr = plus_constant (Pmode, XEXP (crtl->eh.sjlj_fc, 0), + sjlj_fc_jbuf_ofs); + expand_builtin_update_setjmp_buf (buf_addr); + p = get_insns (); + end_sequence (); + emit_insn_before (p, insn); + } + if (! INSN_P (insn)) continue; @@ -1495,6 +1510,18 @@ sjlj_build_landing_pads (void) sjlj_lp_call_site_index.release (); } +/* Update the sjlj function context. This function should be called + whenever we allocate or deallocate dynamic stack space. */ + +void +update_sjlj_context (void) +{ + if (!flag_exceptions) + return; + + emit_note (NOTE_INSN_UPDATE_SJLJ_CONTEXT); +} + /* After initial rtl generation, call back to finish generating exception support code. */ diff --git a/gcc/except.h b/gcc/except.h index 504b4bde135..ca26c4cb338 100644 --- a/gcc/except.h +++ b/gcc/except.h @@ -252,6 +252,7 @@ extern hash_map *duplicate_eh_regions (struct function *, eh_region, int, duplicate_eh_regions_map, void *); extern void sjlj_emit_function_exit_after (rtx_insn *); +extern void update_sjlj_context (void); extern eh_region gen_eh_region_cleanup (eh_region); extern eh_region gen_eh_region_try (eh_region); diff --git a/gcc/explow.c b/gcc/explow.c index de446a903fd..e7768aeb77d 100644 --- a/gcc/explow.c +++ b/gcc/explow.c @@ -1096,8 +1096,8 @@ emit_stack_restore (enum save_level save_level, rtx sa) } /* Invoke emit_stack_save on the nonlocal_goto_save_area for the current - function. This function should be called whenever we allocate or - deallocate dynamic stack space. */ + function. This should be called whenever we allocate or deallocate + dynamic stack space. */ void update_nonlocal_goto_save_area (void) @@ -1117,6 +1117,21 @@ update_nonlocal_goto_save_area (void) emit_stack_save (SAVE_NONLOCAL, &r_save); } + +/* Record a new stack level for the current function. This should be called + whenever we allocate or deallocate dynamic stack space. */ + +void +record_new_stack_level (void) +{ + /* Record the new stack level for nonlocal gotos. */ + if (cfun->nonlocal_goto_save_area) + update_nonlocal_goto_save_area (); + + /* Record the new stack level for SJLJ exceptions. */ + if (targetm_common.except_unwind_info (&global_options) == UI_SJLJ) + update_sjlj_context (); +} /* Return an rtx representing the address of an area of memory dynamically pushed on the stack. @@ -1479,9 +1494,8 @@ allocate_dynamic_stack_space (rtx size, unsigned size_align, /* Now that we've committed to a return value, mark its alignment. */ mark_reg_pointer (target, required_align); - /* Record the new stack level for nonlocal gotos. */ - if (cfun->nonlocal_goto_save_area != 0) - update_nonlocal_goto_save_area (); + /* Record the new stack level. */ + record_new_stack_level (); return target; } diff --git a/gcc/explow.h b/gcc/explow.h index 48f18599122..94613de5ab2 100644 --- a/gcc/explow.h +++ b/gcc/explow.h @@ -78,6 +78,9 @@ extern void emit_stack_restore (enum save_level, rtx); /* Invoke emit_stack_save for the nonlocal_goto_save_area. */ extern void update_nonlocal_goto_save_area (void); +/* Record a new stack level. */ +extern void record_new_stack_level (void); + /* Allocate some space on the stack dynamically and return its address. */ extern rtx allocate_dynamic_stack_space (rtx, unsigned, unsigned, bool); diff --git a/gcc/final.c b/gcc/final.c index e145f6d9feb..f0585ca8ecf 100644 --- a/gcc/final.c +++ b/gcc/final.c @@ -2215,6 +2215,7 @@ final_scan_insn (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED, switch (NOTE_KIND (insn)) { case NOTE_INSN_DELETED: + case NOTE_INSN_UPDATE_SJLJ_CONTEXT: break; case NOTE_INSN_SWITCH_TEXT_SECTIONS: diff --git a/gcc/insn-notes.def b/gcc/insn-notes.def index 210890d87bd..9e86ce5063d 100644 --- a/gcc/insn-notes.def +++ b/gcc/insn-notes.def @@ -87,4 +87,8 @@ INSN_NOTE (CFI) label that should be emitted. */ INSN_NOTE (CFI_LABEL) +/* This note indicates that the function context must be updated if + the Setjmp/Longjmp exception mechanism is used. */ +INSN_NOTE (UPDATE_SJLJ_CONTEXT) + #undef INSN_NOTE -- 2.30.2