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]

2.95: Some additional patches


Unfortunately, some bugs showed up while testing the last 2.95.3 test
release, and a few additional patches are necessary.


Bernd

	* varasm.c (force_const_mem): When putting a LABEL_REF into the
	constant pool, also put it on forced_labels list so that it won't
	be deleted.

This fixes the hpux bootstrap problem when using the native assembler.
We'd end up with a constant pool referencing a label that got deleted.
This patch may be necessary for the mainline as well; I'm not entirely
sure.

	2000-05-25  Alexandre Oliva  <aoliva@cygnus.com>
	* emit-rtl.c (reset_used_decls): New function.
	(unshare_all_rtl_again): Call it.

	2000-05-24  Alexandre Oliva  <oliva@lsd.ic.unicamp.br>
	* emit-rtl.c (unshare_all_decls): New function.
	(unshare_all_rtl): Call it.

	2000-05-20  Alexandre Oliva  <aoliva@cygnus.com>
	* emit-rtl.c (unshare_all_rtl): Store the copied rtx.

	2000-04-15  Richard Earnshaw (rearnsah@arm.com)
	* emit-rtl.c (unshare_all_rtl_again): Unmark everything, then
	call unshare_all_rtl.

	2000-01-27  Geoffrey Keating  <geoffk@cygnus.com>
	* emit-rtl.c (unshare_all_rtl): Unshare virtual parameters too.
	Use unshare_all_rtl_1.
	(unshare_all_rtl_again): New function.
	(unshare_all_rtl_1): New function split out of unshare_all_rtl.
	* function.c (purge_addressof_1): Use unshare_all_rtl_again
	rather than resetting the 'used' flags ourself.
	* toplev.c (rest_of_compilation): Add current_function_decl
	to the unshare_all_rtl call.
	* tree.h: Prototype unshare_all_rtl.
	* rtl.h: Prototype unshare_all_rtl_again here.

This set is taken from Franz Sirl's patchkit.  I didn't apply it before
since it wasn't entirely clear what it fixed, and it seemed like a rather
large change.  Testing on m68k-linux has now revealed at least one problem:
the DECL_RTL of local variables can be shared with the rtl for the function,
and if the DECL_RTL is processed in instantiate_virtual_regs, some insn
patterns can suddenly cease to be valid.  We'd get compilation failures,
apparently whenever the m68k divmod pattern was used.
This problem was exposed by another bugfix installed on the branch.


Bernd

Index: emit-rtl.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/emit-rtl.c,v
retrieving revision 1.59.4.6
diff -u -p -r1.59.4.6 emit-rtl.c
--- emit-rtl.c	2000/12/18 14:37:37	1.59.4.6
+++ emit-rtl.c	2001/01/25 12:54:00
@@ -248,6 +248,9 @@ extern int emit_lineno;
 static rtx make_jump_insn_raw		PROTO((rtx));
 static rtx make_call_insn_raw		PROTO((rtx));
 static rtx find_line_note		PROTO((rtx));
+static void unshare_all_rtl_1		PROTO((rtx));
+static void unshare_all_decls		PROTO((tree));
+static void reset_used_decls		PROTO((tree));

 rtx
 gen_rtx_CONST_INT (mode, arg)
@@ -1767,23 +1770,29 @@ restore_emit_status (p)
   free_insn = 0;
 }

-/* Go through all the RTL insn bodies and copy any invalid shared structure.
-   It does not work to do this twice, because the mark bits set here
-   are not cleared afterwards.  */
+/* Go through all the RTL insn bodies and copy any invalid shared
+   structure.  This routine should only be called once.  */

 void
-unshare_all_rtl (insn)
-     register rtx insn;
+unshare_all_rtl (fndecl, insn)
+     tree fndecl;
+     rtx insn;
 {
-  for (; insn; insn = NEXT_INSN (insn))
-    if (GET_CODE (insn) == INSN || GET_CODE (insn) == JUMP_INSN
-	|| GET_CODE (insn) == CALL_INSN)
-      {
-	PATTERN (insn) = copy_rtx_if_shared (PATTERN (insn));
-	REG_NOTES (insn) = copy_rtx_if_shared (REG_NOTES (insn));
-	LOG_LINKS (insn) = copy_rtx_if_shared (LOG_LINKS (insn));
-      }
+  tree decl;

+  /* Make sure that virtual stack slots are not shared.  */
+  reset_used_decls (DECL_INITIAL (current_function_decl));
+
+  /* Make sure that virtual parameters are not shared.  */
+  for (decl = DECL_ARGUMENTS (fndecl); decl; decl = TREE_CHAIN (decl))
+    DECL_RTL (decl) = copy_rtx_if_shared (DECL_RTL (decl));
+
+  /* Make sure that virtual stack slots are not shared.  */
+  unshare_all_decls (DECL_INITIAL (fndecl));
+
+  /* Unshare just about everything else.  */
+  unshare_all_rtl_1 (insn);
+
   /* Make sure the addresses of stack slots found outside the insn chain
      (such as, in DECL_RTL of a variable) are not shared
      with the insn chain.
@@ -1791,8 +1800,76 @@ unshare_all_rtl (insn)
      This special care is necessary when the stack slot MEM does not
      actually appear in the insn chain.  If it does appear, its address
      is unshared from all else at that point.  */
+  stack_slot_list = copy_rtx_if_shared (stack_slot_list);
+}
+
+/* Go through all the RTL insn bodies and copy any invalid shared
+   structure, again.  This is a fairly expensive thing to do so it
+   should be done sparingly.  */
+
+void
+unshare_all_rtl_again (insn)
+     rtx insn;
+{
+  rtx p;
+  for (p = insn; p; p = NEXT_INSN (p))
+    if (GET_RTX_CLASS (GET_CODE (p)) == 'i')
+      {
+	reset_used_flags (PATTERN (p));
+	reset_used_flags (REG_NOTES (p));
+	reset_used_flags (LOG_LINKS (p));
+      }
+  unshare_all_rtl_1 (insn);
+}
+
+/* Go through all the RTL insn bodies and copy any invalid shared structure.
+   Assumes the mark bits are cleared at entry.  */
+
+static void
+unshare_all_rtl_1 (insn)
+     rtx insn;
+{
+  for (; insn; insn = NEXT_INSN (insn))
+    if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
+      {
+	PATTERN (insn) = copy_rtx_if_shared (PATTERN (insn));
+	REG_NOTES (insn) = copy_rtx_if_shared (REG_NOTES (insn));
+	LOG_LINKS (insn) = copy_rtx_if_shared (LOG_LINKS (insn));
+      }
+}

-  copy_rtx_if_shared (stack_slot_list);
+/* Go through all virtual stack slots of a function and copy any
+   shared structure.  */
+static void
+unshare_all_decls (blk)
+     tree blk;
+{
+  tree t;
+
+  /* Copy shared decls.  */
+  for (t = BLOCK_VARS (blk); t; t = TREE_CHAIN (t))
+    DECL_RTL (t)  = copy_rtx_if_shared (DECL_RTL (t));
+
+  /* Now process sub-blocks.  */
+  for (t = BLOCK_SUBBLOCKS (blk); t; t = TREE_CHAIN (t))
+    unshare_all_decls (t);
+}
+
+/* Go through all virtual stack slots of a function and mark them as
+   not shared. */
+static void
+reset_used_decls (blk)
+     tree blk;
+{
+  tree t;
+
+  /* Mark decls.  */
+  for (t = BLOCK_VARS (blk); t; t = TREE_CHAIN (t))
+    reset_used_flags (DECL_RTL (t));
+
+  /* Now process sub-blocks.  */
+  for (t = BLOCK_SUBBLOCKS (blk); t; t = TREE_CHAIN (t))
+    reset_used_decls (t);
 }

 /* Mark ORIG as in use, and return a copy of it if it was already in use.
Index: function.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/function.c,v
retrieving revision 1.90.4.4
diff -u -p -r1.90.4.4 function.c
--- function.c	2000/12/22 14:19:57	1.90.4.4
+++ function.c	2001/01/25 12:54:02
@@ -3221,13 +3221,7 @@ purge_addressof_1 (loc, insn, force, sto

 		  /* Make sure to unshare any shared rtl that store_bit_field
 		     might have created.  */
-		  for (p = get_insns(); p; p = NEXT_INSN (p))
-		    {
-		      reset_used_flags (PATTERN (p));
-		      reset_used_flags (REG_NOTES (p));
-		      reset_used_flags (LOG_LINKS (p));
-		    }
-		  unshare_all_rtl (get_insns ());
+		  unshare_all_rtl_again (get_insns ());

 		  seq = gen_sequence ();
 		  end_sequence ();
@@ -3479,6 +3473,20 @@ purge_addressof (insns)
   hash_table_free (&ht);
   purge_bitfield_addressof_replacements = 0;
   purge_addressof_replacements = 0;
+
+  /* REGs are shared.  purge_addressof will destructively replace a REG
+     with a MEM, which creates shared MEMs.
+
+     Unfortunately, the children of put_reg_into_stack assume that MEMs
+     referring to the same stack slot are shared (fixup_var_refs and
+     the associated hash table code).
+
+     So, we have to do another unsharing pass after we have flushed any
+     REGs that had their address taken into the stack.
+
+     It may be worth tracking whether or not we converted any REGs into
+     MEMs to avoid this overhead when it is not needed.  */
+  unshare_all_rtl_again (get_insns ());
 }

 /* Pass through the INSNS of function FNDECL and convert virtual register
Index: rtl.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/rtl.h,v
retrieving revision 1.105.4.1
diff -u -p -r1.105.4.1 rtl.h
--- rtl.h	2000/12/20 13:52:59	1.105.4.1
+++ rtl.h	2001/01/25 12:54:03
@@ -1391,7 +1391,7 @@ extern int subreg_realpart_p			PROTO ((r
 extern void reverse_comparison			PROTO ((rtx));
 extern void set_new_first_and_last_insn		PROTO ((rtx, rtx));
 extern void set_new_first_and_last_label_num	PROTO ((int, int));
-extern void unshare_all_rtl			PROTO ((rtx));
+extern void unshare_all_rtl_again		PROTO ((rtx));
 extern void set_last_insn			PROTO ((rtx));
 extern void link_cc0_insns			PROTO ((rtx));
 extern void add_insn				PROTO ((rtx));
Index: toplev.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/toplev.c,v
retrieving revision 1.185.4.5
diff -u -p -r1.185.4.5 toplev.c
--- toplev.c	2000/12/18 14:13:25	1.185.4.5
+++ toplev.c	2001/01/25 12:54:05
@@ -3816,7 +3816,7 @@ rest_of_compilation (decl)

   /* Copy any shared structure that should not be shared.  */

-  unshare_all_rtl (insns);
+  unshare_all_rtl (current_function_decl, insns);

 #ifdef SETJMP_VIA_SAVE_AREA
   /* This must be performed before virutal register instantiation.  */
Index: tree.h
===================================================================
RCS file: /cvs/gcc/egcs/gcc/tree.h,v
retrieving revision 1.71
diff -u -p -r1.71 tree.h
--- tree.h	1999/05/02 17:43:32	1.71
+++ tree.h	2001/01/25 12:54:06
@@ -2207,6 +2207,7 @@ extern tree reorder_blocks		PROTO ((tree
 						struct rtx_def *));
 extern void free_temps_for_rtl_expr	PROTO ((tree));
 extern void instantiate_virtual_regs	PROTO ((tree, struct rtx_def *));
+extern void unshare_all_rtl		PROTO ((tree, struct rtx_def *));
 extern int max_parm_reg_num		PROTO ((void));
 extern void push_function_context	PROTO ((void));
 extern void pop_function_context	PROTO ((void));
Index: varasm.c
===================================================================
RCS file: /cvs/gcc/egcs/gcc/varasm.c,v
retrieving revision 1.59.4.4
diff -u -p -r1.59.4.4 varasm.c
--- varasm.c	1999/06/09 12:13:49	1.59.4.4
+++ varasm.c	2001/01/25 12:54:07
@@ -3493,6 +3493,18 @@ force_const_mem (mode, x)

 	  pop_obstacks ();
 	}
+      if (GET_CODE (x) == LABEL_REF)
+	{
+	  extern rtx forced_labels;
+
+	  push_obstacks_nochange ();
+	  rtl_in_saveable_obstack ();
+
+	  forced_labels = gen_rtx_EXPR_LIST (VOIDmode,
+					     XEXP (x, 0),
+					     forced_labels);
+	  pop_obstacks ();
+	}

       /* Allocate a pool constant descriptor, fill it in, and chain it in.  */



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