* insn-notes.def (UPDATE_SJLJ_CONTEXT): New note.
authorebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 19 May 2015 09:33:27 +0000 (09:33 +0000)
committerebotcazou <ebotcazou@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 19 May 2015 09:33:27 +0000 (09:33 +0000)
* 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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@223348 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/builtins.c
gcc/builtins.h
gcc/calls.c
gcc/cfgrtl.c
gcc/except.c
gcc/except.h
gcc/explow.c
gcc/explow.h
gcc/final.c
gcc/insn-notes.def

index 66b0141..46a45d4 100644 (file)
@@ -1,3 +1,22 @@
+2015-05-19  Eric Botcazou  <ebotcazou@adacore.com>
+           Tristan Gingold  <gingold@adacore.com>
+
+       * 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  <kyrylo.tkachov@arm.com>
 
        * calls.c: Always define STACK_GROWS_DOWNWARD as 0 or 1.
index 9544524..030cc35 100644 (file)
@@ -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;
 }
index cf2ddb4..5a0b57d 100644 (file)
@@ -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);
index d631cc0..9cd488d 100644 (file)
@@ -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)
index 390d718..466c6da 100644 (file)
@@ -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 <rtx_note *> (insn));
              break;
 
index 770ab98..673e9c3 100644 (file)
@@ -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.  */
 
index 504b4bd..ca26c4c 100644 (file)
@@ -252,6 +252,7 @@ extern hash_map<void *, void *> *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);
index de446a9..e7768ae 100644 (file)
@@ -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 ();
+}
 \f
 /* 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;
 }
index 48f1859..94613de 100644 (file)
@@ -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);
 
index e145f6d..f0585ca 100644 (file)
@@ -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:
index 210890d..9e86ce5 100644 (file)
@@ -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