[m-rev.] diff: more hlc.agc fixes

Fergus Henderson fjh at cs.mu.OZ.AU
Mon Feb 4 18:01:12 AEDT 2002


Estimated hours taken: 2
Branches: main

Some more bug fixes for accurate GC with the MLDS->C back-end.

With these changes, and a few hacks (see http://www.cs.mu.oz.au/research/
mercury/mailing-lists/mercury-reviews/mercury-reviews.0201/0188.html),
I was able to build all of the programs in tests/benchmarks in grade hlc.agc,
with `EXTRA_MCFLAGS = -O5 --no-deforestation --no-reclaim-heap-on-failure'.

compiler/ml_elim_nested.m:
	- Use an assignment rather than an initializer when
	  saving the stack chain; this is needed because
	  the hoist_nested_funcs pass (which gets run next)
	  assumes that the MLDS doesn't have any initializers
	  for local variables.
	- Include a counter in the ml_elim_info, and use it to ensure that
	  all the saved stack chain variables get named differently;
	  this is needed because the hoist_nested_funcs pass doesn't
	  handle variables with overlapping scopes.
	- Move the code for generating the code to save/restore
	  the stack chain into a separate function.

compiler/notes/compiler_design.html:
	Mention the accurate GC pass in ml_elim_nested.m.

Workspace: /home/earth/fjh/ws-earth4/mercury
Index: compiler/ml_elim_nested.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_elim_nested.m,v
retrieving revision 1.48
diff -u -d -r1.48 ml_elim_nested.m
--- compiler/ml_elim_nested.m	1 Feb 2002 22:06:10 -0000	1.48
+++ compiler/ml_elim_nested.m	4 Feb 2002 06:34:11 -0000
@@ -166,6 +166,8 @@
 % There are also some things that could be done to improve efficiency,
 % e.g.
 %	- optimize away temporary variables
+%	- put stack_chain and/or heap pointer in global register variables
+%	- avoid linking stack chain unnecessarily?
 %
 %-----------------------------------------------------------------------------%
 %
@@ -357,7 +359,7 @@
 %-----------------------------------------------------------------------------%
 
 :- implementation.
-:- import_module bool, int, list, std_util, string, require.
+:- import_module bool, counter, int, list, std_util, string, require.
 
 :- import_module ml_code_util, ml_util.
 :- import_module prog_util, type_util.
@@ -1389,30 +1391,13 @@
 		fixup_lval(Ref0, Ref),
 		flatten_statement(Statement0, Statement1),
 		flatten_statement(Handler0, Handler1),
-		%
-		% add code to save/restore the stack chain pointer
-		%
+		{ Stmt1 = try_commit(Ref, Statement1, Handler1) },
 		Action =^ action,
-		ModuleName =^ module_name,
-		{ Action = chain_gc_stack_frames ->
-			Statement1 = mlds__statement(_, StatementContext),
-			Handler1 = mlds__statement(_, HandlerContext),
-			Handler = mlds__statement(
-				block(
-				    [],
-				    [gen_restore_stack_chain_var(ModuleName,
-						HandlerContext),
-				     Handler1]
-				),
-				HandlerContext),
-			TryCommit = try_commit(Ref, Statement1, Handler),
-			Stmt = block(
-				[gen_saved_stack_chain_var(StatementContext)],
-				[mlds__statement(TryCommit, StatementContext)]
-			)
+		( { Action = chain_gc_stack_frames } ->
+			save_and_restore_stack_chain(Stmt1, Stmt)
 		;
-			Stmt = try_commit(Ref, Statement1, Handler1)
-		}
+			{ Stmt = Stmt1 }
+		)
 	;
 		{ Stmt0 = atomic(AtomicStmt0) },
 		fixup_atomic_stmt(AtomicStmt0, AtomicStmt),
@@ -1438,6 +1423,58 @@
 	
 %-----------------------------------------------------------------------------%
 
+	%
+	% add code to save/restore the stack chain pointer:
+	% convert
+	%	try {
+	%	    Statement
+	%	} commit {
+	%	    Handler
+	%	}
+	% into
+	%	{
+	%	    void *saved_stack_chain;
+	%	    try {
+	%		saved_stack_chain = stack_chain;
+	%		Statement
+	%	    } commit {
+	%		stack_chain = saved_stack_chain;
+	%		Handler
+	%	    }
+	%	}
+	%
+:- inst try_commit ---> try_commit(ground, ground, ground).
+
+:- pred save_and_restore_stack_chain(mlds__stmt, mlds__stmt,
+		elim_info, elim_info).
+:- mode save_and_restore_stack_chain(in(try_commit), out, in, out) is det.
+
+save_and_restore_stack_chain(Stmt0, Stmt, ElimInfo0, ElimInfo) :-
+	ModuleName = ElimInfo0 ^ module_name,
+	counter__allocate(Id, ElimInfo0 ^ saved_stack_chain_counter, NextId),
+	ElimInfo = (ElimInfo0 ^ saved_stack_chain_counter := NextId),
+	Stmt0 = try_commit(Ref, Statement0, Handler0),
+	Statement0 = mlds__statement(_, StatementContext),
+	Handler0 = mlds__statement(_, HandlerContext),
+	SavedVarDecl = gen_saved_stack_chain_var(Id, StatementContext),
+	SaveStatement = gen_save_stack_chain_var(ModuleName, Id,
+		StatementContext),
+	RestoreStatement = gen_restore_stack_chain_var(ModuleName, Id,
+		HandlerContext),
+	Statement = mlds__statement(
+		block([], [SaveStatement, Statement0]),
+		HandlerContext),
+	Handler = mlds__statement(
+		block([], [RestoreStatement, Handler0]),
+		HandlerContext),
+	TryCommit = try_commit(Ref, Statement, Handler),
+	Stmt = block(
+		[SavedVarDecl],
+		[mlds__statement(TryCommit, StatementContext)]
+	).
+
+%-----------------------------------------------------------------------------%
+
 %
 % flatten_nested_defns:
 % flatten_nested_defn:
@@ -2442,32 +2479,42 @@
 	UnchainFrame = mlds__statement(atomic(Assignment), Context).
 
 	% Generate a local variable declaration
-	% to save the stack chain pointer:
-	%	void *saved_stack_chain = stack_chain;
-:- func gen_saved_stack_chain_var(mlds__context) = mlds__defn.
-gen_saved_stack_chain_var(Context) = Defn :-
-	Name = data(var(ml_saved_stack_chain_name)),
+	% to hold the saved stack chain pointer:
+	%	void *saved_stack_chain;
+:- func gen_saved_stack_chain_var(int, mlds__context) = mlds__defn.
+gen_saved_stack_chain_var(Id, Context) = Defn :-
+	Name = data(var(ml_saved_stack_chain_name(Id))),
 	Flags = ml_gen_local_var_decl_flags,
 	Type = ml_stack_chain_type,
-	Initializer = init_obj(lval(ml_stack_chain_var)),
+	Initializer = no_initializer,
 	% The saved stack chain never needs to be traced by the GC,
 	% since it will always point to the stack, not into the heap.
 	GCTraceCode = no,
 	DefnBody = mlds__data(Type, Initializer, GCTraceCode),
 	Defn = mlds__defn(Name, Context, Flags, DefnBody).
 
+	% Generate a statement to save the stack chain pointer:
+	%	saved_stack_chain = stack_chain;
+:- func gen_save_stack_chain_var(mlds_module_name, int, mlds__context) =
+	mlds__statement.
+gen_save_stack_chain_var(MLDS_Module, Id, Context) = SaveStatement :-
+	SavedStackChain = var(qual(MLDS_Module,
+		ml_saved_stack_chain_name(Id)), ml_stack_chain_type),
+	Assignment = assign(SavedStackChain, lval(ml_stack_chain_var)),
+	SaveStatement = mlds__statement(atomic(Assignment), Context).
+
 	% Generate a statement to restore the stack chain pointer:
 	%	stack_chain = saved_stack_chain;
-:- func gen_restore_stack_chain_var(mlds_module_name, mlds__context) =
+:- func gen_restore_stack_chain_var(mlds_module_name, int, mlds__context) =
 	mlds__statement.
-gen_restore_stack_chain_var(MLDS_Module, Context) = RestoreStatement :-
+gen_restore_stack_chain_var(MLDS_Module, Id, Context) = RestoreStatement :-
 	SavedStackChain = var(qual(MLDS_Module,
-		ml_saved_stack_chain_name), ml_stack_chain_type),
+		ml_saved_stack_chain_name(Id)), ml_stack_chain_type),
 	Assignment = assign(ml_stack_chain_var, lval(SavedStackChain)),
 	RestoreStatement = mlds__statement(atomic(Assignment), Context).
 
-:- func ml_saved_stack_chain_name = mlds__var_name.
-ml_saved_stack_chain_name = var_name("saved_stack_chain", no).
+:- func ml_saved_stack_chain_name(int) = mlds__var_name.
+ml_saved_stack_chain_name(Id) = var_name("saved_stack_chain", yes(Id)).
 
 %-----------------------------------------------------------------------------%
 
@@ -2515,7 +2562,11 @@
 				% a pointer to the env_type_name (in the
 				% IL backend we don't necessarily use a
 				% pointer).
-			env_ptr_type_name :: mlds__type
+			env_ptr_type_name :: mlds__type,
+
+				% A counter used to number the local variables
+				% used to save the stack chain
+			saved_stack_chain_counter :: counter
 	).
 
 	% The lists of local variables for
@@ -2527,7 +2578,7 @@
 		mlds__type, mlds__type) = elim_info.
 elim_info_init(Action, ModuleName, OuterVars, EnvTypeName, EnvPtrTypeName) =
 	elim_info(Action, ModuleName, OuterVars, [], [],
-		EnvTypeName, EnvPtrTypeName).
+		EnvTypeName, EnvPtrTypeName, counter__init(0)).
 
 :- func elim_info_get_module_name(elim_info) = mlds_module_name.
 elim_info_get_module_name(ElimInfo) = ElimInfo ^ module_name.
Index: compiler/notes/compiler_design.html
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/notes/compiler_design.html,v
retrieving revision 1.68
diff -u -d -r1.68 compiler_design.html
--- compiler/notes/compiler_design.html	31 Dec 2001 06:07:25 -0000	1.68
+++ compiler/notes/compiler_design.html	3 Feb 2002 06:28:53 -0000
@@ -937,7 +937,9 @@
 <ul>
 <li> ml_tailcall.m annotates the MLDS with information about tailcalls.
 <li> ml_optimize.m does MLDS->MLDS optimizations
-<li> ml_elim_nested.m transforms the MLDS to eliminate nested functions.
+<li> ml_elim_nested.m does two MLDS transformations that happen
+     to have a lot in common: (1) eliminating nested functions
+     and (2) adding code to handle accurate garbage collection.
 </ul>
 
 <h4> 6b. MLDS output </h4>

-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
The University of Melbourne         |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- the last words of T. S. Garp.
--------------------------------------------------------------------------
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