for review: add MR_virtual_hp, MR_virtual_sp, etc.

Fergus Henderson fjh at cs.mu.OZ.AU
Wed Apr 15 18:59:19 AEST 1998


Zoltan, can you please review this one?

Estimated hours taken: 2

runtime/mercury_regorder.h:
	Add definitions for MR_virtual_sp, MR_virtual_hp, etc.
	which access the underlying fake_reg slot rather than the
	real machine register.

runtime/mercury_regs.h:
	Add some more comments and move some code around, so as to
	clearly delineate between the different abstraction layers.

runtime/mercury_heap.h:
	Implement incr_saved_hp() and incr_saved_hp_atomic()
	more efficiently, using MR_virtual_hp.

runtime/mercury_overflow.h:
	Add saved_heap_overflow_check(), for use by incr_saved_hp().

cvs diff  runtime/mercury_heap.h runtime/mercury_overflow.h runtime/mercury_regorder.h runtime/mercury_regs.h
Index: runtime/mercury_heap.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_heap.h,v
retrieving revision 1.4
diff -u -r1.4 mercury_heap.h
--- mercury_heap.h	1997/12/10 02:07:35	1.4
+++ mercury_heap.h	1998/04/15 08:56:30
@@ -224,18 +224,20 @@
 ** restore_transient_registers() after.
 */
 
-#define incr_saved_hp(A, B)					\
-	do { 							\
-		restore_transient_registers();			\
-		incr_hp((A), (B));				\
-		save_transient_registers();			\
-	} while (0)
-
-#define incr_saved_hp_atomic(A, B) 				\
-	do { 							\
-		restore_transient_registers();			\
-		incr_hp_atomic((A), (B));			\
-		save_transient_registers();			\
-	} while (0)
+#ifdef USE_CONSERVATIVE_GC
+  #define incr_saved_hp(A, B) incr_hp(A, B)
+  #define incr_saved_hp_atomic(A, B) incr_hp_atomic(A, B)
+#else
+  /* same as tag_incr_hp except we use MR_virtual_hp instead of MR_hp */
+  #define incr_saved_hp(dest, count)				\
+	(							\
+		(dest) = (Word) mkword(0, (Word) MR_virtual_hp),\
+		debugincrhp(count, MR_virtual_hp),		\
+		MR_virtual_hp += (count),			\
+		saved_heap_overflow_check(),			\
+		(void)0						\
+	)
+  #define incr_saved_hp_atomic(A, B) incr_saved_hp(A, B)
+#endif
 
 #endif /* not MERCURY_HEAP_H */
Index: runtime/mercury_overflow.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_overflow.h,v
retrieving revision 1.3
diff -u -r1.3 mercury_overflow.h
--- mercury_overflow.h	1998/03/16 12:23:35	1.3
+++ mercury_overflow.h	1998/04/15 08:54:58
@@ -14,6 +14,7 @@
 #ifndef MR_CHECK_FOR_OVERFLOW
 
 #define	heap_overflow_check()		((void)0)
+#define	saved_heap_overflow_check()	((void)0)
 #define	detstack_overflow_check()	((void)0)
 #define	detstack_underflow_check()	((void)0)
 #define	nondstack_overflow_check()	((void)0)
@@ -31,6 +32,17 @@
 				)),				\
 				IF (MR_hp > heap_zone->max,(	\
 					heap_zone->max = MR_hp	\
+				)),				\
+				(void)0				\
+			)
+
+#define	saved_heap_overflow_check()				\
+			(					\
+				IF (MR_virtual_hp >= heap_zone->top,(	\
+					fatal_error("heap overflow") \
+				)),				\
+				IF (MR_virtual_hp > heap_zone->max,(	\
+					heap_zone->max = MR_virtual_hp	\
 				)),				\
 				(void)0				\
 			)
Index: runtime/mercury_regorder.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_regorder.h,v
retrieving revision 1.3
diff -u -r1.3 mercury_regorder.h
--- mercury_regorder.h	1998/04/08 11:34:01	1.3
+++ mercury_regorder.h	1998/04/15 08:45:51
@@ -22,6 +22,10 @@
 #ifndef MERCURY_REGORDER_H
 #define MERCURY_REGORDER_H
 
+/*
+** If you modify the r<N> to mr<N> mapping, make sure that you update
+** the definition of MR_VIRTUAL_REG_MAP_BODY below.
+*/
 #define r1		count_usage(R_RN(1), mr2)
 #define r2		count_usage(R_RN(2), mr3)
 #define r3		count_usage(R_RN(3), mr4)
@@ -57,33 +61,49 @@
 
 /*
 ** If you modify the following block, make sure that you update
-** the definitions of MR_NUM_SPECIAL_REG and MR_MAX_SPECIAL_REG_MR.
+** the definitions of MR_NUM_SPECIAL_REG, MR_MAX_SPECIAL_REG_MR,
+** and MR_virtual_*.
 */
-
-#define MR_succip	LVALUE_CAST(Code *, count_usage(MR_SI_RN, mr1))
-#define succip		MR_succip
-#define MR_hp		LVALUE_CAST(Word *, count_usage(MR_HP_RN, mr5))
-#define hp		MR_hp
-#define MR_sp		LVALUE_CAST(Word *, count_usage(MR_SP_RN, mr0))
-#define sp		MR_sp
-#define MR_curfr	LVALUE_CAST(Word *, count_usage(MR_CF_RN, mr8))
-#define curfr		MR_curfr
-#define MR_maxfr	LVALUE_CAST(Word *, count_usage(MR_MF_RN, mr9))
-#define maxfr		MR_maxfr
+#define MR_succip		LVALUE_CAST(Code *, count_usage(MR_SI_RN, mr1))
+#define MR_hp			LVALUE_CAST(Word *, count_usage(MR_HP_RN, mr5))
+#define MR_sp			LVALUE_CAST(Word *, count_usage(MR_SP_RN, mr0))
+#define MR_curfr		LVALUE_CAST(Word *, count_usage(MR_CF_RN, mr8))
+#define MR_maxfr		LVALUE_CAST(Word *, count_usage(MR_MF_RN, mr9))
 #define MR_sol_hp	LVALUE_CAST(Word *, count_usage(MR_SOL_HP_RN, mr(37)))
 #define MR_min_hp_rec	LVALUE_CAST(Word *, count_usage(MR_MIN_HP_REC, mr(38)))
 #define MR_min_sol_hp_rec	LVALUE_CAST(Word *,	\
 			count_usage(MR_MIN_HP_REC, mr39))
-
 #define MR_trail_ptr	count_usage(MR_TRAIL_PTR_RN, MR_trail_ptr_var)
 #define MR_ticket_counter	 \
 		count_usage(MR_TICKET_COUNTER_RN, MR_ticket_counter_var)
 
+/* for backwards compatibility */
+#define succip		MR_succip
+#define hp		MR_hp
+#define sp		MR_sp
+#define curfr		MR_curfr
+#define maxfr		MR_maxfr
+
 /* the number of special, non rN registers */
 #define MR_NUM_SPECIAL_REG	10
 
 /* the maximum mrN number of special, non rN registers */
 #define	MR_MAX_SPECIAL_REG_MR	39
+
+/*
+** The MR_virtual_foo macros are like MR_foo except that
+** they access the underlying fake_reg slot rather than
+** the real machine register.
+*/
+
+#define MR_virtual_succip	LVALUE_CAST(Code *, fake_reg[1])
+#define MR_virtual_hp		LVALUE_CAST(Word *, fake_reg[5])
+#define MR_virtual_sp		LVALUE_CAST(Word *, fake_reg[0])
+#define MR_virtual_curfr	LVALUE_CAST(Word *, fake_reg[8])
+#define MR_virtual_maxfr	LVALUE_CAST(Word *, fake_reg[9])
+#define MR_virtual_sol_hp	LVALUE_CAST(Word *, fake_reg[37])
+#define MR_virtual_min_hp_rec	LVALUE_CAST(Word *, fake_reg[38])
+#define MR_virtual_min_sol_hp_rec	LVALUE_CAST(Word *, fake_reg[39])
 
 #define VIRTUAL_REG_MAP_BODY	{ \
 	2, \
Index: runtime/mercury_regs.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_regs.h,v
retrieving revision 1.5
diff -u -r1.5 mercury_regs.h
--- mercury_regs.h	1998/02/04 03:55:27	1.5
+++ mercury_regs.h	1998/04/15 08:41:57
@@ -10,6 +10,7 @@
 #include "mercury_conf.h"
 #include "mercury_types.h"
 
+/*---------------------------------------------------------------------------*/
 /*
 ** GNU C allows lvalue casts, so if we have gcc, use them.
 ** If we don't have gcc, then we can use *(type *)&lval,
@@ -28,33 +29,59 @@
   #define LVALUE_COND(expr, x, y)	(*((expr)?&(x):&(y)))
 #endif
 
+/*---------------------------------------------------------------------------*/
 /*
 ** The registers of the Mercury virtual machine are built up using
 ** three levels of abstraction.
 **
-** The first level defines the first NUM_REAL_REGS register variables
-** mr0, mr1, etc. as the physical machine registers, and defines an
-** array fake_regs[n] of pseudo registers.
+** The bottom level is the hardware description layer.
+** This layer is defined seperately for each architecture, in machdeps/*.h.
+** The hardware description layer defines the first NUM_REAL_REGS register
+** variables mr0, mr1, etc. as the physical machine registers, and defines an
+** array fake_regs[n] of pseudo registers, with the remaining "registers"
+** mr<NUM_REAL_REGS>, ..., mr36 defined as corresponding slots in
+** this fake_reg array. 
+** This level also provides the macros save_regs_to_mem(),
+** save_transient_regs_to_mem(), restore_regs_from_mem(),
+** and restore_transient_regs_from_mem().
+**
+** The next level is the hardware abstraction layer.
+** The hardware abstraction layer is at a similar level to the
+** 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().
+** This layer is defined here in mercury_regs.h.
 **
-** The next level defines macros mr0 through mr36 and also mr(n) for
-** n>36.  The lower the number,
+** The hardware abstraction layer thus provides a very large number
+** of registers, which may be either real or fake.  The lower the number,
 ** the greater the probability that the storage referred to will be
 ** a real machine register, and not a simulated one. The number of
 ** real machine registers is given by the macro NUM_REAL_REGS.
 **
-** The final level maps the Mercury virtual machine registers
+** The final level is the Mercury abstract machine registers layer.
+** This layer maps the Mercury virtual machine registers
 **
-**	succip, hp, sp, curfr, maxfr and
+**	MR_succip, MR_hp, MR_sp, MR_curfr, MR_maxfr and
 **	r1, ..., r32, r(33), ..., r(MAX_VIRTUAL_REG)
 **
 ** to the set mr0..mr36, mr(37), mr(38), ..., mr(MAX_FAKE_REG-1)
+** which were provided by the hardware abstraction layer.
+** It also provides MR_virtual_r(), MR_virtual_succip, MR_virtual_hp, etc.,
+** which are similar to mr<N>, MR_succip, MR_hp, etc. except that they
+** always map to the underlying fake_reg rather than to the physical register.
 **
 ** Since the set of most frequently used Mercury virtual machine
-** registers can be different for each program, we want to make
+** registers can be different for each program or grade, we want to make
 ** this mapping as easy to change as possible. This is why the
 ** map is in a minimal header file, mercury_regorder.h.
 */
 
+/*---------------------------------------------------------------------------*/
+/*
+** The hardware description layer
+*/
 #if defined(USE_GCC_GLOBAL_REGISTERS)
   #ifndef __GNUC__
     #error "You must use gcc if you define USE_GCC_GLOBAL_REGISTERS."
@@ -79,24 +106,17 @@
     #include "machdeps/no_regs.h"
 #endif
 
+/*---------------------------------------------------------------------------*/
+/*
+** Extra stuff for the hardware abstraction layer
+*/
+
 /* The machdeps header defines mr0 .. mr36; now define mr(n) for n > 36 */
 
 #define mr(n) LVALUE_SEQ(MR_assert((n) >= MAX_REAL_REG + NUM_SPECIAL_REG && \
-				(n) < MAX_FAKE_REG),\
+				(n) < MAX_FAKE_REG), \
 		fake_reg[n])
 
-#ifdef MEASURE_REGISTER_USAGE
-  #define count_usage(num,reg)		LVALUE_SEQ(num_uses[num]++, reg)
-#else
-  #define count_usage(num,reg)		(reg)
-#endif
-
-#include	"mercury_regorder.h"
-
-/* mercury_regorder.h defines r1 .. r32; now define r(n) for n > 32 */
-
-#define r(n) mr((n) + NUM_SPECIAL_REG - 1)
-
 /* 
 ** the save_registers() macro copies the physical machine registers
 ** to their corresponding slots in the fake_reg array 
@@ -122,15 +142,29 @@
 #define save_transient_registers()    save_transient_regs_to_mem(fake_reg)
 #define restore_transient_registers() restore_transient_regs_from_mem(fake_reg)
 
+/*---------------------------------------------------------------------------*/
+/*
+** The Mercury abstract machine registers layer
+*/
+
+#ifdef MEASURE_REGISTER_USAGE
+  #define count_usage(num,reg)		LVALUE_SEQ(num_uses[num]++, reg)
+#else
+  #define count_usage(num,reg)		(reg)
+#endif
+
+#include	"mercury_regorder.h"
+
+/* mercury_regorder.h defines r1 .. r32; now define r(n) for n > 32 */
+
+#define r(n) mr((n) + NUM_SPECIAL_REG - 1)
+
 /* virtual_reg(n) accesses the underlying fake_reg for register n */
 
-#define virtual_reg(n)	\
-	LVALUE_COND((n) > MAX_REAL_REG, \
-		r(n), \
-		fake_reg[virtual_reg_map[(n) - 1]])
+#define virtual_reg(n) saved_reg(fake_reg, n)
 
 /* saved_reg(save_area, n) is like virtual_reg, except in that */
-/* it accesses the given save area instead of the machine regs and fake_reg */
+/* it accesses the given save area instead of fake_reg */
 
 #define saved_reg(save_area, n)	\
 	LVALUE_COND((n) > MAX_REAL_REG, \
-- 
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