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