This is the mail archive of the gcc@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]

sjlj eh flow patch


The following patch generates more optimal basic block flows when
using sjlj by taking into account the fact that we know that longjmp
will go through a different path than the original call to setjmp.

It also gets rid of the stupid call to __dummy.  There is one backend
that needs to be fixed up because of this (MIPS); I'd been meaning to
do it but forgot.  If this patch is accepted for the post-1.00 release
I'll finish that bit.


r~


Mon Nov 10 18:48:02 1997  Richard Henderson  <rth@cygnus.com>

	* expr.c (expand_builtin_setjmp): Accept two new arguments for
	the labels to branch to on first and subsequent executions.  Don't
	play with __dummy.
	(expand_builtin) [BUILTIN_SETJMP]: Generate a label for use by setjmp.
	(expand_builtin) [BUILTIN_LONGJMP]: Don't play with __dummy.  Correct
	arguments to nonlocal_goto.
	* expr.h (expand_builtin_setjmp): Update prototype.
	* except.c (start_dynamic_handler): When using builtin_setjmp,
	generate correct flow information.
	
Index: except.c
===================================================================
RCS file: /cvs/cvsfiles/egcs/gcc/except.c,v
retrieving revision 1.10.2.1
diff -u -p -d -r1.10.2.1 except.c
--- except.c	1997/11/10 20:06:46	1.10.2.1
+++ except.c	1997/11/11 02:30:50
@@ -914,14 +914,17 @@ start_dynamic_handler ()
 #ifdef DONT_USE_BUILTIN_SETJMP
   x = emit_library_call_value (setjmp_libfunc, NULL_RTX, 1, SImode, 1,
 			       buf, Pmode);
+  /* If we come back here for a catch, transfer control to the handler.  */
+  jumpif_rtx (x, ehstack.top->entry->exception_handler_label);
 #else
-  x = expand_builtin_setjmp (buf, NULL_RTX);
+  {
+    /* A label to continue execution for the no exception case.  */
+    rtx noex = gen_label_rtx();
+    x = expand_builtin_setjmp (buf, NULL_RTX, noex,
+			       ehstack.top->entry->exception_handler_label);
+    emit_label (noex);
+  }
 #endif
-
-  /* If we come back here for a catch, transfer control to the
-     handler.  */
-
-  jumpif_rtx (x, ehstack.top->entry->exception_handler_label);
 
   /* We are committed to this, so update the handler chain.  */
 
Index: expr.c
===================================================================
RCS file: /cvs/cvsfiles/egcs/gcc/expr.c,v
retrieving revision 1.16
diff -u -p -d -r1.16 expr.c
--- expr.c	1997/11/02 05:15:13	1.16
+++ expr.c	1997/11/11 02:30:51
@@ -8072,20 +8072,16 @@ expand_builtin_return_addr (fndecl_code,
    them.  */
 
 rtx
-expand_builtin_setjmp (buf_addr, target)
+expand_builtin_setjmp (buf_addr, target, first_label, next_label)
      rtx buf_addr;
      rtx target;
+     rtx first_label, next_label;
 {
-  rtx lab1 = gen_label_rtx (), lab2 = gen_label_rtx ();
+  rtx lab1 = gen_label_rtx ();
   enum machine_mode sa_mode = Pmode, value_mode;
   rtx stack_save;
   int old_inhibit_defer_pop = inhibit_defer_pop;
-  int return_pops
-    =  RETURN_POPS_ARGS (get_identifier ("__dummy"),
-			 build_function_type (void_type_node, NULL_TREE),
-			 0);
   rtx next_arg_reg;
-  CUMULATIVE_ARGS args_so_far;
   rtx op0;
   int i;
 
@@ -8129,9 +8125,9 @@ expand_builtin_setjmp (buf_addr, target)
     emit_insn (gen_setjmp ());
 #endif
 
-  /* Set TARGET to zero and branch around the other case.  */
+  /* Set TARGET to zero and branch to the first-time-through label.  */
   emit_move_insn (target, const0_rtx);
-  emit_jump_insn (gen_jump (lab2));
+  emit_jump_insn (gen_jump (first_label));
   emit_barrier ();
   emit_label (lab1);
 
@@ -8151,12 +8147,7 @@ expand_builtin_setjmp (buf_addr, target)
 #endif
     emit_move_insn (virtual_stack_vars_rtx, hard_frame_pointer_rtx);
 
-  /* Do we need to do something like:
-     
-     current_function_has_nonlocal_label = 1;
-
-     here?  It seems like we might have to, or some subset of that
-     functionality, but I am unsure.  (mrs) */
+  current_function_has_nonlocal_label = 1;
 
 #if ARG_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
   if (fixed_regs[ARG_POINTER_REGNUM])
@@ -8189,39 +8180,12 @@ expand_builtin_setjmp (buf_addr, target)
   if (HAVE_nonlocal_goto_receiver)
     emit_insn (gen_nonlocal_goto_receiver ());
 #endif
-  /* The static chain pointer contains the address of dummy function.
-     We need to call it here to handle some PIC cases of restoring a
-     global pointer.  Then return 1.  */
-  op0 = copy_to_mode_reg (Pmode, static_chain_rtx);
-
-  /* We can't actually call emit_library_call here, so do everything
-     it does, which isn't much for a libfunc with no args.  */
-  op0 = memory_address (FUNCTION_MODE, op0);
-
-  INIT_CUMULATIVE_ARGS (args_so_far, NULL_TREE,
-			gen_rtx (SYMBOL_REF, Pmode, "__dummy"), 1);
-  next_arg_reg = FUNCTION_ARG (args_so_far, VOIDmode, void_type_node, 1);
-
-#ifndef ACCUMULATE_OUTGOING_ARGS
-#ifdef HAVE_call_pop
-  if (HAVE_call_pop)
-    emit_call_insn (gen_call_pop (gen_rtx (MEM, FUNCTION_MODE, op0),
-				  const0_rtx, next_arg_reg,
-				  GEN_INT (return_pops)));
-  else
-#endif
-#endif
-
-#ifdef HAVE_call
-    if (HAVE_call)
-      emit_call_insn (gen_call (gen_rtx (MEM, FUNCTION_MODE, op0),
-				const0_rtx, next_arg_reg, const0_rtx));
-    else
-#endif
-      abort ();
 
+  /* Set TARGET to one and branch to the next-time-through label.  */
   emit_move_insn (target, const1_rtx);
-  emit_label (lab2);
+  emit_jump_insn (gen_jump (next_label));
+  emit_barrier ();
+
   return target;
 }
 
@@ -9080,21 +9044,21 @@ expand_builtin (exp, target, subtarget, 
       {
 	rtx buf_addr = expand_expr (TREE_VALUE (arglist), subtarget,
 				    VOIDmode, 0);
-	return expand_builtin_setjmp (buf_addr, target);
+	rtx lab = gen_label_rtx ();
+	rtx ret = expand_builtin_setjmp (buf_addr, target, lab, lab);
+	emit_label (lab);
+	return ret;
       }
 
-      /* __builtin_longjmp is passed a pointer to an array of five words
-	 and a value, which is a dummy.  It's similar to the C library longjmp
-	 function but works with __builtin_setjmp above.  */
+      /* __builtin_longjmp is passed a pointer to an array of five words.
+	 It's similar to the C library longjmp function but works with
+	 __builtin_setjmp above.  */
     case BUILT_IN_LONGJMP:
       if (arglist == 0 || TREE_CHAIN (arglist) == 0
 	  || TREE_CODE (TREE_TYPE (TREE_VALUE (arglist))) != POINTER_TYPE)
 	break;
 
       {
-	tree dummy_id = get_identifier ("__dummy");
-	tree dummy_type = build_function_type (void_type_node, NULL_TREE);
-	tree dummy_decl = build_decl (FUNCTION_DECL, dummy_id, dummy_type); 
 #ifdef POINTERS_EXTEND_UNSIGNED
 	rtx buf_addr
 	  = force_reg (Pmode,
@@ -9123,35 +9087,24 @@ expand_builtin (exp, target, subtarget, 
 			     plus_constant (buf_addr,
 					    2 * GET_MODE_SIZE (Pmode)));
 
-	DECL_EXTERNAL (dummy_decl) = 1;
-	TREE_PUBLIC (dummy_decl) = 1;
-	make_decl_rtl (dummy_decl, NULL_PTR, 1);
-
 	/* Expand the second expression just for side-effects.  */
 	expand_expr (TREE_VALUE (TREE_CHAIN (arglist)),
 		     const0_rtx, VOIDmode, 0);
 
-	assemble_external (dummy_decl);
-
 	/* Pick up FP, label, and SP from the block and jump.  This code is
 	   from expand_goto in stmt.c; see there for detailed comments.  */
 #if HAVE_nonlocal_goto
 	if (HAVE_nonlocal_goto)
-	  emit_insn (gen_nonlocal_goto (fp, lab, stack,
-					XEXP (DECL_RTL (dummy_decl), 0)));
-      else
+	  emit_insn (gen_nonlocal_goto (fp, lab, stack, NULL_RTX));
+        else
 #endif
 	{
 	  lab = copy_to_reg (lab);
 	  emit_move_insn (hard_frame_pointer_rtx, fp);
 	  emit_stack_restore (SAVE_NONLOCAL, stack, NULL_RTX);
 
-	  /* Put in the static chain register the address of the dummy
-	     function.  */
-	  emit_move_insn (static_chain_rtx, XEXP (DECL_RTL (dummy_decl), 0));
 	  emit_insn (gen_rtx (USE, VOIDmode, hard_frame_pointer_rtx));
 	  emit_insn (gen_rtx (USE, VOIDmode, stack_pointer_rtx));
-	  emit_insn (gen_rtx (USE, VOIDmode, static_chain_rtx));
 	  emit_indirect_jump (lab);
 	}
 
Index: expr.h
===================================================================
RCS file: /cvs/cvsfiles/egcs/gcc/expr.h,v
retrieving revision 1.4
diff -u -p -d -r1.4 expr.h
--- expr.h	1997/08/29 15:02:03	1.4
+++ expr.h	1997/11/11 02:30:51
@@ -750,7 +750,7 @@ extern rtx store_expr PROTO((tree, rtx, 
    Useful after calling expand_expr with 1 as sum_ok.  */
 extern rtx force_operand PROTO((rtx, rtx));
 
-extern rtx expand_builtin_setjmp PROTO((rtx, rtx));
+extern rtx expand_builtin_setjmp PROTO((rtx, rtx, rtx, rtx));
 
 #ifdef TREE_CODE
 /* Generate code for computing expression EXP.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]