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

Simon Taylor stayl at cs.mu.OZ.AU
Fri Nov 22 03:20:01 AEDT 2002


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.h:
	Add a macro MR_assign_structure() to assign structures 
	without triggering the GCC bug.

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.

Index: runtime/mercury_array_macros.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_array_macros.h,v
retrieving revision 1.11
diff -u -u -r1.11 mercury_array_macros.h
--- runtime/mercury_array_macros.h	11 Oct 2002 06:23:02 -0000	1.11
+++ runtime/mercury_array_macros.h	21 Nov 2002 15:04:14 -0000
@@ -11,32 +11,7 @@
 #ifndef MERCURY_ARRAY_MACROS_H
 #define MERCURY_ARRAY_MACROS_H
 
-#include	"mercury_reg_workarounds.h"	/* for MR_memcpy */
-
-/*
-** This macro defines a safe way to perform assignment between
-** array elements that are structures. The obvious way can cause
-** gcc 2.7.2.3 to abort on x86 processors with the message 
-** "fixed or forbidden register was spilled."
-*/
-
-#ifdef	MR_CANNOT_USE_STRUCTURE_ASSIGNMENT
-
-  #define MR_copy_array_element(array, to_index, from_index)		\
-	do {								\
-		MR_memcpy((void *) &array[to_index],			\
-			(const void *) &array[from_index],		\
-			sizeof(array[to_index]));			\
-	} while(0)
-
-#else
-
-  #define MR_copy_array_element(array, to_index, from_index)		\
-	do {								\
-		array[to_index] = array[from_index];			\
-	} while(0)
-
-#endif /* ! MR_CANNOT_USE_STRUCTURE_ASSIGNMENT */
+#include	"mercury_reg_workarounds.h"	/* for MR_assign_structure */
 
 /*
 ** The MR_ensure_room_for_next macro works with a group of three variables
@@ -214,8 +189,8 @@
 	do {								\
 		(element) = (next) - 1;					\
 		while ((element) >= 0 && (COMPARE) > 0) {		\
-			MR_copy_array_element(items, element + 1,	\
-				element);				\
+			MR_assign_structure(items[element + 1],		\
+				items[element]);			\
 			(element) -= 1;					\
 		}							\
 		(element) += 1;						\
Index: runtime/mercury_heap.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_heap.h,v
retrieving revision 1.26
diff -u -u -r1.26 mercury_heap.h
--- runtime/mercury_heap.h	21 Aug 2002 11:27:42 -0000	1.26
+++ runtime/mercury_heap.h	21 Nov 2002 14:46:30 -0000
@@ -15,6 +15,7 @@
 #include "mercury_heap_profile.h"	/* for MR_record_allocation() */
 #include "mercury_deep_profiling.h"	/* for MR_current_call_site_dynamic */
 #include "mercury_std.h"		/* for MR_EXTERN_INLINE */
+#include "mercury_reg_workarounds.h" 	/* for MR_memcpy */
 #ifdef MR_HIGHLEVEL_CODE
   #include "mercury.h"			/* for MR_new_object() */
 #endif
@@ -370,7 +371,7 @@
 			MR_make_hp_float_aligned();			\
 			MR_incr_hp(MR_LVALUE_CAST(MR_Word, (box)),	\
 					size_in_words);			\
-			*(T *)(box) = (value);				\
+			MR_assign_structure(*(T *)(box), (value));	\
 			MR_maybe_record_allocation(size_in_words,	\
 				"", "foreign type: " MR_STRINGIFY(T));	\
 		} else {						\
@@ -383,7 +384,7 @@
 				/* part of it uninitialized */		\
 				box_copy = 0;				\
 			}						\
-			memcpy(&box_copy, &(value), sizeof(T));		\
+			MR_memcpy(&box_copy, &(value), sizeof(T));	\
 			(box) = box_copy;				\
 		}							\
 	} while (0)
@@ -398,13 +399,13 @@
 		MR_CHECK_EXPR_TYPE((value), T);				\
 		MR_CHECK_EXPR_TYPE((box), MR_Box);			\
 		if (sizeof(T) > sizeof(MR_Word)) {			\
-			(value) = *(T *)(box);				\
+			MR_assign_structure((value), *(T *)(box));	\
 		} else {						\
 			/* We can't take the address of `box' here, */	\
 			/* since it might be a global register. */	\
 			/* Hence we need to use a temporary copy. */	\
 			MR_Box box_copy = (box);			\
-			memcpy(&(value), &box_copy, sizeof(T));		\
+			MR_memcpy(&(value), &box_copy, sizeof(T));	\
 		}							\
 	} while (0)
    
Index: runtime/mercury_reg_workarounds.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_reg_workarounds.h,v
retrieving revision 1.4
diff -u -u -r1.4 mercury_reg_workarounds.h
--- runtime/mercury_reg_workarounds.h	8 Jun 2000 07:59:05 -0000	1.4
+++ runtime/mercury_reg_workarounds.h	21 Nov 2002 16:17:15 -0000
@@ -5,7 +5,7 @@
 */
 
 /*
-** mercury_reg_workarounds.h -	MR_memcpy(), MR_fd_zero()
+** mercury_reg_workarounds.h - MR_assign_structure(), MR_memcpy(), MR_fd_zero()
 */
 
 #ifndef	MERCURY_REG_WORKAROUNDS_H
@@ -19,6 +19,24 @@
 #endif
 
 #include <stdlib.h>			/* for size_t */
+
+/*
+** This macro defines a safe way to perform assignment between
+** structures. The obvious way can cause some versions of
+** gcc to abort on x86 processors with the message
+** "fixed or forbidden register was spilled."
+*/
+
+#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 */
 
 /*
 ** We use our own version of memcpy because gcc recognises calls to the
Index: tests/valid/Mercury.options
===================================================================
RCS file: /home/mercury1/repository/tests/valid/Mercury.options,v
retrieving revision 1.2
diff -u -u -r1.2 Mercury.options
--- tests/valid/Mercury.options	1 Nov 2002 02:16:35 -0000	1.2
+++ tests/valid/Mercury.options	21 Nov 2002 15:50:17 -0000
@@ -73,6 +73,7 @@
 MCFLAGS-mostly_uniq_mode_inf	= --infer-all
 MCFLAGS-pred_with_no_modes	= --infer-all
 MCFLAGS-quantifier_warning	= --halt-at-warn
+MGNUCFLAGS-reg_bug		= --no-ansi
 MCFLAGS-simplify_bug		= -O-1
 MCFLAGS-simplify_bug2		= -O3
 MCFLAGS-spurious_purity_warning	= --halt-at-warn
Index: tests/valid/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/valid/Mmakefile,v
retrieving revision 1.118
diff -u -u -r1.118 Mmakefile
--- tests/valid/Mmakefile	5 Nov 2002 10:46:03 -0000	1.118
+++ tests/valid/Mmakefile	21 Nov 2002 15:48:44 -0000
@@ -147,6 +147,7 @@
 	record_syntax_bug_4 \
 	record_syntax_bug_5 \
 	recursive_no_tag_type \
+	reg_bug \
 	same_length_2 \
 	semidet_disj \
 	shape_type \
Index: tests/valid/reg_bug.m
===================================================================
RCS file: tests/valid/reg_bug.m
diff -N tests/valid/reg_bug.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ 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.
+
+:- interface.
+
+:- type signal_action ---> signal_action.
+:- pragma foreign_type("C", signal_action, "MR_signal_action").
+
+:- func sig_dfl = signal_action.
+
+:- implementation.
+
+:- pragma foreign_decl("C", "#include ""mercury_signal.h""").
+
+sig_dfl = (signal_action::out).
+
+:- pragma foreign_proc("C", sig_dfl = (Result::out),
+		[will_not_call_mercury, promise_pure],
+	"MR_init_signal_action(&Result, SIG_DFL, MR_FALSE, MR_TRUE);").
+
--------------------------------------------------------------------------
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