This is the mail archive of the gcc-patches@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]

Patch to fix incorrect hard register life information


In my previous reload patch, I had to disable dwarf2 unwind information in
i386.h, since otherwise flow.c would compute incorrect hard register life
information while compiling __throw in libgcc2.a. The code generated by
expand_builtin_eh_stub uses two hard registers to receive information, and
the compiler thinks these are in use throughout most of the function, which
leads to a spill failure with the reload patch.
Here's an attempt to fix the problem.

Bernd

	* except.h (current_function_eh_stub_label): Declare.
	(current_function_eh_old_stub_label): Declare.
	* function.h (struct function): New members eh_stub_label and
	eh_old_stub_label.
	* except.c (current_function_eh_stub_label): New variable.
	(current_function_eh_old_stub_label): New variable.
	(init_eh_for_function): Clear them.
	(save_eh_status): Save them.
	(restore_eh_status): Restore them.
	(expand_builtin_eh_stub): Set current_function_eh_stub_label.
	(expand_builtin_eh_stub_old): Set current_function_eh_old_stub_label.
	* flow.c (life_analysis_1): When merging the set of live registers
	at the start of one block into the sets of live registers at the end
	of its predecessors, check whether the current block starts with one
	of the eh_stub labels. If so, don't mark any additional hard registers
	as live at the end of the predecessors.

Index: except.c
===================================================================
RCS file: /usr/local/cvs/gcs/gcc/except.c,v
retrieving revision 1.1.1.35
diff -u -r1.1.1.35 except.c
--- except.c	1998/07/12 18:35:12	1.1.1.35
+++ except.c	1998/08/30 10:56:11
@@ -431,6 +431,12 @@
 
 rtx current_function_ehc;
 
+/* The labels generated by expand_builtin_eh_stub and
+   expand_builtin_eh_stub_old.  */
+
+rtx current_function_eh_stub_label;
+rtx current_function_eh_old_stub_label;
+
 /* A stack used for keeping track of the currently active exception
    handling region.  As each exception region is started, an entry
    describing the region is pushed onto this stack.  The current
@@ -2146,6 +2152,8 @@
   caught_return_label_stack = 0;
   protect_list = NULL_TREE;
   current_function_ehc = NULL_RTX;
+  current_function_eh_stub_label = NULL_RTX;
+  current_function_eh_old_stub_label = NULL_RTX;
 }
 
 /* Save some of the per-function EH info into the save area denoted by
@@ -2168,6 +2176,8 @@
   p->caught_return_label_stack = caught_return_label_stack;
   p->protect_list = protect_list;
   p->ehc = current_function_ehc;
+  p->eh_stub_label = current_function_eh_stub_label;
+  p->eh_old_stub_label = current_function_eh_old_stub_label;
 
   init_eh_for_function ();
 }
@@ -2191,6 +2201,8 @@
   ehstack = p->ehstack;
   catchstack = p->catchstack;
   current_function_ehc = p->ehc;
+  current_function_eh_stub_label = p->eh_stub_label;
+  current_function_eh_old_stub_label = p->eh_old_stub_label;
 }
 
 /* This section is for the exception handling specific optimization
@@ -2500,6 +2512,8 @@
   rtx after_stub = gen_label_rtx ();
   rtx handler, offset;
 
+  current_function_eh_old_stub_label = stub_start;
+
   emit_jump (after_stub);
   emit_label (stub_start);
 
@@ -2518,6 +2532,8 @@
   rtx after_stub = gen_label_rtx ();
   rtx handler, offset;
   rtx temp;
+
+  current_function_eh_stub_label = stub_start;
 
   emit_jump (after_stub);
   emit_label (stub_start);
Index: except.h
===================================================================
RCS file: /usr/local/cvs/gcs/gcc/except.h,v
retrieving revision 1.1.1.17
diff -u -r1.1.1.17 except.h
--- except.h	1998/06/29 18:05:03	1.1.1.17
+++ except.h	1998/08/30 10:55:37
@@ -24,6 +24,12 @@
 #define rtx _except_rtx
 #endif
 
+/* The labels generated by expand_builtin_eh_stub and
+   expand_builtin_eh_stub_old.  */
+
+extern rtx current_function_eh_stub_label;
+extern rtx current_function_eh_old_stub_label;
+
 #ifdef TREE_CODE
 
 /* A stack of labels. CHAIN points to the next entry in the stack.  */
@@ -81,7 +87,6 @@
   struct eh_node *head;
   struct eh_node *tail;
 };
-
 
 /* Start an exception handling region.  All instructions emitted after
    this point are considered to be part of the region until
Index: flow.c
===================================================================
RCS file: /usr/local/cvs/gcs/gcc/flow.c,v
retrieving revision 1.1.1.35
diff -u -r1.1.1.35 flow.c
--- flow.c	1998/07/17 14:39:48	1.1.1.35
+++ flow.c	1998/08/30 10:54:08
@@ -1078,6 +1078,7 @@
 {
   int first_pass;
   int changed;
+  regset tmp_reg_set;
   /* For each basic block, a bitmask of regs
      live on exit from the block.  */
   regset *basic_block_live_at_end;
@@ -1284,6 +1285,7 @@
      of all the blocks that can transfer control to that block.
      The process continues until it reaches a fixed point.  */
 
+  tmp_reg_set = ALLOCA_REG_SET ();
   first_pass = 1;
   changed = 1;
   while (changed)
@@ -1367,14 +1369,32 @@
 	    /* Update the basic_block_new_live_at_end's of
 	       all the blocks that jump to this one.  */
 	    if (GET_CODE (head) == CODE_LABEL)
-	      for (jump = LABEL_REFS (head);
-		   jump != head;
-		   jump = LABEL_NEXTREF (jump))
-		{
-		  register int from_block = BLOCK_NUM (CONTAINING_INSN (jump));
-		  IOR_REG_SET (basic_block_new_live_at_end[from_block],
-			       basic_block_live_at_start[i]);
-		}
+	      {
+		regset *regset_in = basic_block_live_at_start + i;
+		/* If this is one of the blocks generated by
+		   __builtin_eh_stub or __builtin_eh_stub_old, there will
+		   be some hard registers live at the start of this block.
+		   We must avoid marking them as live throughout most of
+		   the function.  */
+		if (head == current_function_eh_stub_label
+		    || head == current_function_eh_old_stub_label)
+		  {
+		    int i;
+		    COPY_REG_SET (tmp_reg_set, *regset_in);
+		    regset_in = &tmp_reg_set;
+		    for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
+		      CLEAR_REGNO_REG_SET (tmp_reg_set, i);
+		  }
+
+		for (jump = LABEL_REFS (head);
+		     jump != head;
+		     jump = LABEL_NEXTREF (jump))
+		  {
+		    register int from_block = BLOCK_NUM (CONTAINING_INSN (jump));
+		    IOR_REG_SET (basic_block_new_live_at_end[from_block],
+				 *regset_in);
+		  }
+	      }
 	  }
 #ifdef USE_C_ALLOCA
 	  alloca (0);
Index: function.h
===================================================================
RCS file: /usr/local/cvs/gcs/gcc/function.h,v
retrieving revision 1.1.1.9
diff -u -r1.1.1.9 function.h
--- function.h	1998/06/24 11:24:54	1.1.1.9
+++ function.h	1998/08/30 10:38:58
@@ -141,6 +141,8 @@
   rtx catch_clauses;
   struct label_node *false_label_stack;
   struct label_node *caught_return_label_stack;
+  rtx eh_stub_label;
+  rtx eh_old_stub_label;
   tree protect_list;
   rtx ehc;
 



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