[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