[m-dev.] diff: improve comments in ml_code_gen.m

Fergus Henderson fjh at cs.mu.OZ.AU
Wed May 10 03:31:53 AEST 2000


Estimated hours taken: 0.5

compiler/ml_code_gen.m:
	Improve the documentation a little, particularly with regard
	to the declaration of the `succeeded' variable.

Workspace: /home/pgrad/fjh/ws/hg
Index: compiler/ml_code_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_code_gen.m,v
retrieving revision 1.37
diff -u -d -r1.37 ml_code_gen.m
--- compiler/ml_code_gen.m	2000/05/09 10:05:32	1.37
+++ compiler/ml_code_gen.m	2000/05/09 17:26:59
@@ -36,6 +36,14 @@
 % CODE GENERATION SUMMARY
 %-----------------------------------------------------------------------------%
 %
+% In each procedure, we declare a local variable `bool succeeded'.
+% This is used to hold the success status of semidet sub-goals.
+% Note that the comments below show local declarations for the
+% `succeeded' variable in all the places where they would be
+% needed if we were generating them locally, but currently
+% we actually just generate a single `succeeded' variable for
+% each procedure.
+%
 % The calling convention for sub-goals is as follows.
 %
 %	model_det goal:
@@ -86,12 +94,8 @@
 %	det goal in semidet context:
 %		<succeeded = Goal>
 %	===>
-%	{
-%		bool succeeded;
-%
 %		<do Goal>
 %		succeeded = TRUE;
-%	}
 
 %	det goal in nondet context:
 %		<Goal && SUCCEED()>
@@ -137,7 +141,6 @@
 %	model_non in semi context: (using try_commit/do_commit)
 %		<succeeded = Goal>
 % 	===>
-%		bool succeeded;
 %		MR_COMMIT_TYPE ref;
 %		void success() {
 %			succeeded = TRUE;
@@ -153,7 +156,6 @@
 %	model_non in semi context: (using catch/throw)
 %		<succeeded = Goal>
 % 	===>
-%		bool succeeded;
 %		void success() {
 %			throw COMMIT;
 %		}
@@ -167,7 +169,6 @@
 %	model_non in semi context: (using setjmp/longjmp)
 %		<succeeded = Goal>
 % 	===>
-%		bool succeeded;
 %		jmp_buf buf;
 %		void success() {
 %			longjmp(buf, 1);
@@ -185,7 +186,6 @@
 %				to a label in the containing function)
 %		<succeeded = Goal>
 % 	===>
-%		bool succeeded;
 %		__label__ commit;
 %		void success() {
 %			goto commit;
@@ -272,20 +272,39 @@
 
 % We need to handle the case where the first goal cannot succeed
 % specially:
+%
 %	at_most_zero Goal:
 %		<Goal, Goals>
 %	===>
 %		<Goal>
+%
+% The remaining cases for conjunction all assume that the first
+% goal's determinism is not `erroneous' or `failure'.
 
+% If the first goal is model_det, it is straight-forward:
+%
 %	model_det Goal:
 %		<Goal, Goals>
 % 	===>
 %		<do Goal>
 %		<Goals>
-%	
 
-%	model_semi Goal:
-%		<Goal, Goals>
+% If the first goal is model_semidet, then there are two cases:
+% if the disj as a whole is semidet, things are simple, and
+% if the disj as a whole is model_non, then we do the same as
+% for the semidet case, except that we also (ought to) declare
+% a local `succeeded' variable.
+%
+%	model_semi Goal in model_semi disj:
+%		<succeeded = (Goal, Goals)>
+% 	===>
+%		<succeeded = Goal>;
+%		if (succeeded) {
+%			<Goals>;
+%		}
+%
+%	model_semi Goal in model_non disj:
+%		<Goal && Goals>
 % 	===>
 %	{
 %		bool succeeded;
@@ -296,6 +315,14 @@
 %		}
 %	}
 
+% For model_non goals, there are a couple of different
+% ways that we could generate code, depending on whether
+% we are aiming to maximize readability, or whether we
+% prefer to generate code that may be more efficient
+% but is a little less readabile.  The more readable method
+% puts the generated goals in the same order that
+% they occur in the source code:
+%
 %	model_non Goal (optimized for readability)
 %		<Goal, Goals>
 % 	===>
@@ -310,6 +337,11 @@
 %		entry_func();
 %	}
 %
+% The more efficient method generates the goals in
+% reverse order, so its less readable, but it has fewer
+% function calls and can make it easier for the C compiler
+% to inline things:
+%
 %	model_non Goal (optimized for efficiency):
 %		<Goal, Goals>
 % 	===>
@@ -320,7 +352,12 @@
 %
 %		<Goal && succ_func()>;
 %	}
-
+%
+% The more efficient method is the one we actually use.
+%
+% Here's how those two methods look on longer
+% conjunctions of nondet goals:
+%
 %	model_non goals (optimized for readability):
 %		<Goal1, Goal2, Goal3, Goals>
 % 	===>
@@ -340,11 +377,30 @@
 %
 %		label0_func();
 %	}
-
+%
 %	model_non goals (optimized for efficiency):
 %		<Goal1, Goal2, Goal3, Goals>
 % 	===>
 %	{
+%		label1_func() {
+%			label2_func() {
+%				label3_func() {
+%					<Goals && SUCCEED()>;
+%				}
+%				<Goal3 && label3_func()>;
+%			}
+%			<Goal2 && label2_func()>;
+%		}
+%		<Goal1 && label1_func()>;
+%	}
+%
+% Note that it might actually make more sense to generate
+% conjunctions of nondet goals like this:
+%
+%	model_non goals (optimized for efficiency, alternative version):
+%		<Goal1, Goal2, Goal3, Goals>
+% 	===>
+%	{
 %		label3_func() {
 %			<Goals && SUCCEED()>;
 %		}
@@ -357,6 +413,12 @@
 %
 %		<Goal1 && label1_func()>;
 %	}
+%
+% This would avoid the undesirable deep nesting that we sometimes get
+% with our current scheme.  However, if we're eliminating nested
+% functions, as is normally the case, then after the ml_elim_nested
+% transformation all the functions and variables have been hoisted
+% to the top level, so there is no difference between these two.
 
 %-----------------------------------------------------------------------------%
 %
@@ -510,20 +572,14 @@
 % model_semi negation, model_det Goal:
 %		<succeeded = not(Goal)>
 %	===>
-%	{
-%		bool succeeded;
-%		<succeeded = Goal>
+%		<do Goal>
 %		succeeded = FALSE;
-%	}
 
 % model_semi negation, model_semi Goal:
 %		<succeeded = not(Goal)>
 %	===>
-%	{
-%		bool succeeded;
 %		<succeeded = Goal>
 %		succeeded = !succeeded;
-%	}
 
 %-----------------------------------------------------------------------------%
 %
@@ -1064,12 +1120,8 @@
 	% det goal in semidet context:
 	%	<succeeded = Goal>
 	% ===>
-	% {
-	%	bool succeeded;
-	%
 	%	<do Goal>
 	%	succeeded = TRUE
-	% }
 	%
 	ml_gen_set_success(const(true), Context, SetSuccessTrue),
 	{ MLDS_Statements = list__append(MLDS_Statements0, [SetSuccessTrue]) }.
@@ -2020,7 +2072,7 @@
 		%	**     achieve.
 		%	*/
 		%
-		% /* XXX Bug: Cond might clobber the value of succeeded! */
+		% /* XXX Bug: Cond or Then might clobber the value of succeeded! */
 		%
 		%	model_non cond:
 		%		<(Cond -> Then ; Else)>
@@ -2104,11 +2156,8 @@
 		% model_semi negation, model_det goal:
 		%		<succeeded = not(Goal)>
 		%	===>
-		%	{
-		%		bool succeeded;
-		%		<succeeded = Goal>
+		%		<do Goal>
 		%		succeeded = FALSE;
-		%	}
 		{ CodeModel = model_semi, CondCodeModel = model_det },
 		ml_gen_goal(model_det, Cond, CondDecls, CondStatements),
 		ml_gen_set_success(const(false), Context, SetSuccessFalse),
@@ -2119,11 +2168,8 @@
 		% model_semi negation, model_semi goal:
 		%		<succeeded = not(Goal)>
 		%	===>
-		%	{
-		%		bool succeeded;
 		%		<succeeded = Goal>
 		%		succeeded = !succeeded;
-		%	}
 		{ CodeModel = model_semi, CondCodeModel = model_semi },
 		ml_gen_goal(model_semi, Cond, CondDecls, CondStatements),
 		ml_gen_test_success(Succeeded),

-- 
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.
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to:       mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions:          mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------



More information about the developers mailing list