diff: add save_transient_hp()
Fergus Henderson
fjh at cs.mu.OZ.AU
Thu Mar 11 09:01:08 AEDT 1999
Estimated hours taken: 1
Improve efficiency on SPARCs, by replacing calls to save_transient_registers()
with calls to save_transient_hp() where appropriate -- the latter is defined
to do nothing for conservative GC.
runtime/mercury_regs.h:
Add save_transient_hp() and restore_transient_hp() macros
which only guarantee to save/restore the heap pointer.
runtime/mercury_deep_copy.c:
runtime/mercury_deep_copy.h:
runtime/mercury_heap.h:
runtime/mercury_layout_util.c:
runtime/mercury_string.h:
runtime/mercury_tabling.h:
runtime/mercury_type_info.c:
Use save_transient_hp() instead of save_transient_regs()
and restore_transient_hp() instead of restore_transient_regs().
runtime/mercury_trail.c:
runtime/mercury_trail.h:
Comment out a pair of calls to save/restore_transient_regs(),
add a similar pair, also commented out, and document why
neither pair is needed.
runtime/mercury_type_info.c:
Add some comments.
Index: runtime/mercury_deep_copy.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_deep_copy.c,v
retrieving revision 1.11
diff -u -r1.11 mercury_deep_copy.c
--- mercury_deep_copy.c 1998/07/22 07:52:30 1.11
+++ mercury_deep_copy.c 1998/11/06 08:25:39
@@ -110,7 +110,7 @@
{
Word result;
- restore_transient_registers(); /* Because we play with MR_hp */
+ restore_transient_hp(); /* Because we play with MR_hp */
if (lower_limit < MR_heap_zone->bottom ||
lower_limit > MR_heap_zone->top) {
@@ -122,16 +122,16 @@
SWAP(MR_hp, MR_global_hp, Word *);
/* copy values from the heap to the global heap */
- save_transient_registers();
+ save_transient_hp();
result = deep_copy(&term, type_info, lower_limit,
MR_global_heap_zone->top);
- restore_transient_registers();
+ restore_transient_hp();
/* swap the heap and global heap back again */
SWAP(MR_heap_zone, MR_global_heap_zone, MemoryZone *);
SWAP(MR_hp, MR_global_hp, Word *);
- save_transient_registers(); /* Because we played with MR_hp */
+ save_transient_hp(); /* Because we played with MR_hp */
return result;
}
Index: runtime/mercury_deep_copy.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_deep_copy.h,v
retrieving revision 1.6
diff -u -r1.6 mercury_deep_copy.h
--- mercury_deep_copy.h 1998/07/22 07:52:33 1.6
+++ mercury_deep_copy.h 1998/11/06 08:27:38
@@ -39,22 +39,20 @@
** however on some platforms (notably, SPARCs) the
** register-windows mean the transient Mercury registers
** may be lost. So before calling deep_copy, call
-** save_transient_registers();
+** save_transient_hp();
**
-** deep_copy will use restore_transient_registers()
-** to restore the registers and modify the heap pointer, and
-** then call save_transient_registers() to save them again.
-** (This behaviour may change in future - it may be more
-** efficient to just change the saved register - so do not rely on
-** it).
+** deep_copy will use restore_transient_hp()
+** to restore and modify the heap pointer, and
+** then call save_transient_hp() to save it again.
+** (This may also restore/save other registers in the process.)
**
** After calling deep_copy, be sure to do a
-** restore_transient_registers();
+** restore_transient_hp();
** so that the registers are restored.
**
** If writing a C function that calls deep_copy, make sure
** you document that around your function,
-** save_transient_registers()/restore_transient_registers()
+** save_transient_hp()/restore_transient_hp()
** need to be used.
**
** Deep copy does not preserve sharing of subterms. Each
@@ -105,9 +103,10 @@
** Note that in conservative GC grades nothing needs to be done, and
** hence the term is just returned.
**
-** When not using a conservative GC grade, save_transient_registers()
-** and restore_transient_registers() need to be used around this
-** function.
+** When not using a conservative GC grade, save_transient_hp()
+** and restore_transient_hp() need to be used around this
+** function. (When using a conservative GC grade, these macros
+** are harmless, so they can be used then too.)
*/
#define MR_make_permanent(term, type_info) \
Index: runtime/mercury_heap.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_heap.h,v
retrieving revision 1.9
diff -u -r1.9 mercury_heap.h
--- mercury_heap.h 1998/08/04 00:33:19 1.9
+++ mercury_heap.h 1998/11/06 08:24:27
@@ -230,22 +230,22 @@
** Indended for use in handwritten C code where the Mercury registers
** may have been clobbered due to C function calls (eg, on the SPARC due
** to sliding register windows).
-** Remember to save_transient_registers() before calls to such code, and
-** restore_transient_registers() after.
+** Remember to save_transient_hp() before calls to such code, and
+** restore_transient_hp() after.
*/
#define incr_saved_hp(A, B) \
do { \
- restore_transient_registers(); \
+ restore_transient_hp(); \
incr_hp((A), (B)); \
- save_transient_registers(); \
+ save_transient_hp(); \
} while (0)
#define incr_saved_hp_atomic(A, B) \
do { \
- restore_transient_registers(); \
+ restore_transient_hp(); \
incr_hp_atomic((A), (B)); \
- save_transient_registers(); \
+ save_transient_hp(); \
} while (0)
#endif /* not MERCURY_HEAP_H */
Index: runtime/mercury_layout_util.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_layout_util.c,v
retrieving revision 1.2
diff -u -r1.2 mercury_layout_util.c
--- mercury_layout_util.c 1998/10/23 00:41:28 1.2
+++ mercury_layout_util.c 1998/11/06 08:51:15
@@ -124,9 +124,9 @@
vars = &layout->MR_sll_var_info;
/* build up the live variable list, starting from the end */
- restore_transient_registers();
+ restore_transient_hp();
univ_list = list_empty();
- save_transient_registers();
+ save_transient_hp();
for (i = var_count - 1; i >= 0; i--) {
/*
** Look up the name, the type and value
@@ -154,19 +154,19 @@
/*
** Create a term of type `univ' to hold the type & value,
** and cons it onto the list.
- ** Note that the calls to save/restore transient registers
+ ** Note that the calls to save/restore_transient_hp()
** can't be hoisted out of the loop, because
** MR_get_type_and_value() calls MR_create_type_info()
** which may allocate memory using incr_saved_hp.
*/
- restore_transient_registers();
+ restore_transient_hp();
incr_hp(univ, 2);
field(mktag(0), univ, UNIV_OFFSET_FOR_TYPEINFO) = type_info;
field(mktag(0), univ, UNIV_OFFSET_FOR_DATA) = value;
univ_list = list_cons(univ, univ_list);
- save_transient_registers();
+ save_transient_hp();
}
return univ_list;
Index: runtime/mercury_regs.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_regs.h,v
retrieving revision 1.11
diff -u -r1.11 mercury_regs.h
--- mercury_regs.h 1998/11/09 14:35:37 1.11
+++ mercury_regs.h 1998/11/18 08:44:36
@@ -53,8 +53,9 @@
** hardware description layer, and includes that as a subset,
** but in addition it provides a few more conveniences.
** This layer defines macros mr(n) for n>36, and the macros
-** save_registers(), restore_registers(), save_transient_registers(),
-** and restore_transient_registers().
+** save_registers(), restore_registers(),
+** save_transient_registers(), restore_transient_registers(),
+** save_transient_hp(), and restore_transient_hp().
** This layer is defined here in mercury_regs.h.
**
** The hardware abstraction layer thus provides a very large number
@@ -165,6 +166,25 @@
#else
#define restore_transient_registers() \
restore_transient_regs_from_mem(MR_fake_reg)
+#endif
+
+/*
+** The save_transient_hp() and restore_transient_hp() macros
+** are similar to save/restore_transient_regs(), except
+** that they only guarantee to save/restore the heap pointer,
+** if any. (They might save/restore other regs too, though.)
+*/
+#ifdef CONSERVATIVE_GC
+ #define save_transient_hp() /* nothing */
+ #define restore_transient_hp() /* nothing */
+#else
+ /*
+ ** This code is suboptimal -- it would be more efficient to
+ ** save/restore just a single register rather than all the
+ ** transient registers.
+ */
+ #define save_transient_hp() save_transient_registers()
+ #define restore_transient_hp() restore_transient_registers()
#endif
/*---------------------------------------------------------------------------*/
Index: runtime/mercury_string.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_string.h,v
retrieving revision 1.10
diff -u -r1.10 mercury_string.h
--- mercury_string.h 1998/10/19 01:20:00 1.10
+++ mercury_string.h 1998/11/06 08:35:21
@@ -55,7 +55,7 @@
** BEWARE: this may modify `hp', so it must only be called from
** places where `hp' is valid. If calling it from inside a C function,
** rather than inside Mercury code, you may need to call
-** save/restore_transient_regs().
+** save/restore_transient_hp().
**
** Algorithm: if the string is aligned, just set ptr equal to it.
** Otherwise, allocate space on the heap and copy the C string to
@@ -78,7 +78,7 @@
** BEWARE: this may modify `hp', so it must only be called from
** places where `hp' is valid. If calling it from inside a C function,
** rather than inside Mercury code, you may need to call
-** save/restore_transient_regs().
+** save/restore_transient_hp().
*/
#define make_aligned_string_copy(ptr, string) \
do { \
Index: runtime/mercury_tabling.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_tabling.h,v
retrieving revision 1.10
diff -u -r1.10 mercury_tabling.h
--- mercury_tabling.h 1998/11/09 10:24:40 1.10
+++ mercury_tabling.h 1998/11/18 08:44:39
@@ -413,13 +413,13 @@
#define MR_TABLE_SAVE_ANSWER(Offset, ABlock, Value, TypeInfo) \
do { \
- save_transient_registers(); \
+ save_transient_hp(); \
{ Word local_val = Value; \
(* ((AnswerBlock) ABlock))[Offset] = \
deep_copy(&local_val, (Word *) (Word) &TypeInfo,\
NULL, NULL); \
} \
- restore_transient_registers(); \
+ restore_transient_hp(); \
} while(0)
#endif /* CONSERVATIVE_GC */
Index: runtime/mercury_trail.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_trail.c,v
retrieving revision 1.6
diff -u -r1.6 mercury_trail.c
--- mercury_trail.c 1997/11/23 07:21:40 1.6
+++ mercury_trail.c 1998/11/06 08:40:57
@@ -27,7 +27,10 @@
void
MR_untrail_to(MR_TrailEntry *old_trail_ptr, MR_untrail_reason reason)
{
- MR_TrailEntry *tr_ptr = MR_trail_ptr;
+ MR_TrailEntry *tr_ptr;
+ /* not needed, since MR_trail_ptr is never a real reg: */
+ /* restore_transient_registers(); */
+ tr_ptr = MR_trail_ptr;
switch (reason) {
case MR_solve:
@@ -64,6 +67,8 @@
}
}
MR_trail_ptr = tr_ptr;
+ /* not needed, since MR_trail_ptr is never a real reg: */
+ /* save_transient_registers(); */
break;
default:
Index: runtime/mercury_trail.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_trail.h,v
retrieving revision 1.13
diff -u -r1.13 mercury_trail.h
--- mercury_trail.h 1997/11/23 07:21:41 1.13
+++ mercury_trail.h 1998/11/06 08:42:44
@@ -79,6 +79,10 @@
/*
** Unwind restoration info back to `old'. `kind' indicates
** whether we are restoring or just discarding the info.
+ **
+ ** Note that the commented out calls to save/restore
+ ** transient registers are not needed because
+ ** MR_trail_ptr is never a real register.
*/
/* void MR_reset_ticket(Word, MR_untrail_reason); */
#define MR_reset_ticket(old, kind) \
@@ -86,9 +90,9 @@
MR_TrailEntry *old_trail_ptr = \
(MR_TrailEntry *)old; \
if (MR_trail_ptr != old_trail_ptr) { \
- save_transient_registers(); \
+ /* save_transient_registers(); */ \
MR_untrail_to(old_trail_ptr, kind); \
- restore_transient_registers(); \
+ /* restore_transient_registers(); */ \
} \
} while(0)
Index: runtime/mercury_type_info.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_type_info.c,v
retrieving revision 1.15
diff -u -r1.15 mercury_type_info.c
--- mercury_type_info.c 1999/01/28 11:46:29 1.15
+++ mercury_type_info.c 1999/02/07 15:37:30
@@ -146,6 +146,8 @@
END_MODULE
/*
+ ** MR_create_type_info():
+ **
** Given a type_info (term_type_info) which contains a
** base_type_info pointer and possibly other type_infos
** giving the values of the type parameters of this type,
@@ -161,7 +163,8 @@
**
** We allocate memory for a new type_info on the Mercury heap,
** copy the necessary information, and return a pointer to the
- ** new type_info.
+ ** new type_info. You need to wrap save_transient_hp()
+ ** and restore_transient_hp() around calls to this function.
**
** In the case where the argument's pseudo_type_info is a
** base_type_info with no arguments, we don't copy the
@@ -259,7 +262,7 @@
** (based on the addresses of the base_type_infos, or in
** the case of higher order types, the arity).
**
-** You need to save and restore transient registers around
+** You need to wrap save/restore_transient_hp() around
** calls to this function.
*/
@@ -372,7 +375,7 @@
** This only looks past equivalences of the top level type, not
** the argument typeinfos.
**
- ** You need to save and restore transient registers around
+ ** You need to wrap save/restore_transient_hp() around
** calls to this function.
*/
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3 | -- the last words of T. S. Garp.
More information about the developers
mailing list