[m-rev.] for review: work around GCC bug

Simon Taylor stayl at cs.mu.OZ.AU
Fri Nov 22 15:17:29 AEDT 2002


On 22-Nov-2002, Fergus Henderson <fjh at cs.mu.OZ.AU> wrote:
> On 22-Nov-2002, Simon Taylor <stayl at cs.mu.OZ.AU> wrote:
> > 
> > Fix another occurrence of the GCC "fixed or forbidden register was spilled"
> > bug, this time caused by foreign types.
> > 
> > runtime/mercury_heap.h:
> > 	In the code to copy, box or unbox foreign type arguments of
> > 	a foreign_proc, use MR_memcpy rather than direct structure
> > 	assignment on platforms where the GCC bug occurs.
> 
> The log message doesn't correspond with the code -- the code uses
> MR_memcpy() on all platforms.
> 
> Probably it would be better to do what the log message says.

Done.

> > Index: runtime/mercury_reg_workarounds.h
> > +#ifdef MR_CANNOT_USE_STRUCTURE_ASSIGNMENT
> > +
> > +#define MR_assign_structure(dest, src) \
> > +		MR_memcpy((void *) &(dest), (void *) &(src), sizeof((dest)))
> > +
> > +#else /* !MR_CANNOT_USE_STRUCTURE_ASSIGNMENT */
> > +
> > +#define MR_assign_structure(dest, src)	((dest) = (src))
> > +
> > +#endif /* !MR_CANNOT_USE_STRUCTURE_ASSIGNMENT */
> 
> The #defines should be indented two spaces.
> 
> The casts to `(void *)' are not be needed, I'm pretty sure.

Fixed.

> > +++ tests/valid/reg_bug.m	21 Nov 2002 15:49:31 -0000
> > @@ -0,0 +1,21 @@
> > +% Add a test case for yet another instance of the
> > +% GCC 
> > +:- module reg_bug.
> 
> The comment there is incomplete.

Done.


Estimated hours taken: 2
Branches: main, release

Fix another occurrence of the GCC "fixed or forbidden register was spilled"
bug, this time caused by foreign types.

runtime/mercury_heap.h:
	In the code to copy, box or unbox foreign type arguments of
	a foreign_proc, use MR_memcpy rather than direct structure
	assignment on platforms where the GCC bug occurs.

runtime/mercury_reg_workarounds.{c,h}:
	Add a macro MR_assign_structure() to assign structures 
	without triggering the GCC bug.

	Define MR_memcpy to call memcpy if the GCC bug won't be
	triggered.

runtime/mercury_array_macros.h:
	Use MR_assign_structure() rather than a specialized
	version for assigning between two elements of an array.

tests/valid/Mmakefile:
tests/valid/Mercury.options:
tests/valid/reg_bug.m:
	Test case.


diff -u runtime/mercury_reg_workarounds.h runtime/mercury_reg_workarounds.h
--- runtime/mercury_reg_workarounds.h
+++ runtime/mercury_reg_workarounds.h
@@ -27,27 +27,29 @@
 ** "fixed or forbidden register was spilled."
 */
 
-#ifdef MR_CANNOT_USE_STRUCTURE_ASSIGNMENT
+#if defined(MR_CANNOT_USE_STRUCTURE_ASSIGNMENT) && \
+	defined(MR_USE_GCC_GLOBAL_REGISTERS)
 
-#define MR_assign_structure(dest, src) \
-		MR_memcpy((void *) &(dest), (void *) &(src), sizeof((dest)))
+  #define MR_assign_structure(dest, src) \
+			MR_memcpy(&(dest), &(src), sizeof((dest)))
 
-#else /* !MR_CANNOT_USE_STRUCTURE_ASSIGNMENT */
+  /*
+  ** We use our own version of memcpy because gcc recognises calls to the
+  ** standard memcpy (even in things that do not mention memcpy by name, e.g.
+  ** structure assignments) and generates inline code for them. Unfortunately
+  ** this causes gcc to abort because it tries to use a register that we have
+  ** already reserved.
+  ** XXX We should fix this eventually by using -fno-builtin since pragma
+  ** c_code may call the builtin functions.
+  */
+  extern	void	MR_memcpy(void *dest, const void *src, size_t nbytes);
 
-#define MR_assign_structure(dest, src)	((dest) = (src))
+#else /* !MR_CANNOT_USE_STRUCTURE_ASSIGNMENT || !MR_USE_GCC_GLOBAL_REGISTERS */
 
-#endif /* !MR_CANNOT_USE_STRUCTURE_ASSIGNMENT */
+  #define MR_assign_structure(dest, src)	((dest) = (src))
+  #define MR_memcpy(dest, src, nbytes)		memcpy((dest), (src), (nbytes))
 
-/*
-** We use our own version of memcpy because gcc recognises calls to the
-** standard memcpy (even in things that do not mention memcpy by name, e.g.
-** structure assignments) and generates inline code for them. Unfortunately
-** this causes gcc to abort because it tries to use a register that we have
-** already reserved.
-** XXX We should fix this eventually by using -fno-builtin since pragma
-** c_code may call the builtin functions.
-*/
-extern	void	MR_memcpy(void *dest, const void *src, size_t nbytes);
+#endif /* !MR_CANNOT_USE_STRUCTURE_ASSIGNMENT || !MR_USE_GCC_GLOBAL_REGISTERS */
 
 /*
 ** We use a forwarding function to FD_ZERO because the Linux headers
diff -u tests/valid/reg_bug.m tests/valid/reg_bug.m
--- tests/valid/reg_bug.m
+++ tests/valid/reg_bug.m
@@ -1,5 +1,6 @@
-% Add a test case for yet another instance of the
-% GCC 
+% Add a test case for yet another instance of the GCC global
+% register bug, which causes a GCC abort with message
+% "fixed or forbidden register was spilled"
 :- module reg_bug.
 
 :- interface.
only in patch2:
--- runtime/mercury_reg_workarounds.c	13 Feb 2002 09:56:41 -0000	1.5
+++ runtime/mercury_reg_workarounds.c	22 Nov 2002 02:32:22 -0000
@@ -35,6 +35,9 @@
 ** See the header file for documentation on why we need this function.
 */
 
+#if defined(MR_CANNOT_USE_STRUCTURE_ASSIGNMENT) && \
+        defined(MR_USE_GCC_GLOBAL_REGISTERS)
+
 void
 MR_memcpy(void *dest, const void *src, size_t nbytes)
 {
@@ -44,3 +47,5 @@
 	while (nbytes-- > 0)
 		*d++ = *s++;
 }
+
+#endif /* MR_CANNOT_USE_STRUCTURE_ASSIGNMENT && MR_USE_GCC_GLOBAL_REGISTERS */
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list