[m-dev.] diff: MLDS back-end: fix bug with nondet if-then-else

Fergus Henderson fjh at cs.mu.OZ.AU
Wed May 10 04:47:14 AEST 2000


Estimated hours taken: 2

Fix a bug in the MLDS back-end's code generation for
if-then-else goals with nondet conditions.

compiler/ml_code_gen.m:
	When generating code for if-then-elses with nondet conditions,
	allocate a fresh `cond_<N>' variable for each such
	if-then-else, rather than reusing the `succeeded' variable.
	This ensures that the boolean variable that we use to figure
	out if the condition succeeded won't be clobbered by the
	condition or the "then" part of the if-then-else.

compiler/ml_code_util.m:
	Add routines for generating `cond_<N>' variables.
	Add a new cond_var field to the ml_gen_info;
	this is a sequence number used to generate those
	variables.

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.38
diff -u -d -r1.38 ml_code_gen.m
--- compiler/ml_code_gen.m	2000/05/09 17:32:30	1.38
+++ compiler/ml_code_gen.m	2000/05/09 18:40:24
@@ -540,16 +539,16 @@
 %		<(Cond -> Then ; Else)>
 %	===>
 %	{
-%		bool succeeded;
+%		bool cond_<N>;
 %
 %		void then_func() {
-%			succeeded = TRUE;
+%			cond_<N> = TRUE;
 %			<Then>
 %		}
 %
-%		succeeded = FALSE;
+%		cond_<N> = FALSE;
 %		<Cond && then_func()>
-%		if (!succeeded) {
+%		if (!cond_<N>) {
 %			<Else>
 %		}
 %	}
@@ -2072,59 +2071,63 @@
 		%	**     achieve.
 		%	*/
 		%
-		% /* XXX Bug: Cond or Then might clobber the value of succeeded! */
-		%
 		%	model_non cond:
 		%		<(Cond -> Then ; Else)>
 		%	===>
 		%	{
-		%		bool succeeded;
+		%		bool cond_<N>;
 		%
 		%		void then_func() {
-		%			succeeded = TRUE;
+		%			cond_<N> = TRUE;
 		%			<Then>
 		%		}
 		%
-		%		succeeded = FALSE;
+		%		cond_<N> = FALSE;
 		%		<Cond && then_func()>
-		%		if (!succeeded) {
+		%		if (!cond_<N>) {
 		%			<Else>
 		%		}
 		%	}
 
 		{ CondCodeModel = model_non },
 
+		% generate the `cond_<N>' var
+		ml_gen_info_new_cond_var(CondVar),
+		{ MLDS_Context = mlds__make_context(Context) },
+		{ CondVarDecl = ml_gen_cond_var_decl(CondVar, MLDS_Context) },
+
 		% generate the `then_func'
 		ml_gen_new_func_label(ThenFuncLabel, ThenFuncLabelRval),
 		/* push nesting level */
 		{ Then = _ - ThenGoalInfo },
 		{ goal_info_get_context(ThenGoalInfo, ThenContext) },
-		ml_gen_set_success(const(true), ThenContext, SetSuccessTrue),
+		ml_gen_set_cond_var(CondVar, const(true), ThenContext,
+			SetCondTrue),
 		ml_gen_goal(CodeModel, Then, ThenStatement),
 		{ ThenFuncBody = ml_gen_block([],
-			[SetSuccessTrue, ThenStatement], ThenContext) },
+			[SetCondTrue, ThenStatement], ThenContext) },
 		/* pop nesting level */
 		ml_gen_nondet_label_func(ThenFuncLabel, ThenContext,
 			ThenFuncBody, ThenFunc),
 
 		% generate the main body
-		ml_gen_set_success(const(false), Context, SetSuccessFalse),
+		ml_gen_set_cond_var(CondVar, const(false), Context,
+			SetCondFalse),
 		ml_get_env_ptr(EnvPtrRval),
 		{ SuccessCont = success_cont(ThenFuncLabelRval, EnvPtrRval) },
 		ml_gen_info_push_success_cont(SuccessCont),
 		ml_gen_goal(model_non, Cond, CondDecls, CondStatements),
 		ml_gen_info_pop_success_cont,
-		ml_gen_test_success(Succeeded),
+		ml_gen_test_cond_var(CondVar, CondSucceeded),
 		ml_gen_goal(CodeModel, Else, ElseStatement),
-		{ IfStmt = if_then_else(unop(std_unop(not), Succeeded),
+		{ IfStmt = if_then_else(unop(std_unop(not), CondSucceeded),
 			ElseStatement, no) },
-		{ IfStatement = mlds__statement(IfStmt,
-			mlds__make_context(Context)) },
+		{ IfStatement = mlds__statement(IfStmt, MLDS_Context) },
 
 		% package it all up in the right order
-		{ MLDS_Decls = [ThenFunc | CondDecls] },
+		{ MLDS_Decls = [CondVarDecl, ThenFunc | CondDecls] },
 		{ MLDS_Statements = list__append(
-			[SetSuccessFalse | CondStatements], [IfStatement]) }
+			[SetCondFalse | CondStatements], [IfStatement]) }
 	).
 
 %-----------------------------------------------------------------------------%
Index: compiler/ml_code_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_code_util.m,v
retrieving revision 1.8
diff -u -d -r1.8 ml_code_util.m
--- compiler/ml_code_util.m	2000/05/09 16:33:44	1.8
+++ compiler/ml_code_util.m	2000/05/09 18:28:37
@@ -241,6 +241,38 @@
 				ml_gen_info, ml_gen_info).
 :- mode ml_gen_set_success(in, in, out, in, out) is det.
 
+	% Generate the declaration for the specified `cond'
+	% variable.
+	% (`cond' variables are boolean variables used to record
+	% the success or failure of model_non conditions of
+	% if-then-elses.)
+	%
+:- func ml_gen_cond_var_decl(cond_seq, mlds__context) = mlds__defn.
+
+	% Return the lval for the specified `cond' flag.
+	% (`cond' variables are boolean variables used to record
+	% the success or failure of model_non conditions of
+	% if-then-elses.)
+	%
+:- pred ml_cond_var_lval(cond_seq, mlds__lval, ml_gen_info, ml_gen_info).
+:- mode ml_cond_var_lval(in, out, in, out) is det.
+
+	% Return an rval which will test the value of the specified
+	% `cond' variable.
+	% (`cond' variables are boolean variables used to record
+	% the success or failure of model_non conditions of
+	% if-then-elses.)
+	%
+:- pred ml_gen_test_cond_var(cond_seq, mlds__rval, ml_gen_info, ml_gen_info).
+:- mode ml_gen_test_cond_var(in, out, in, out) is det.
+	
+	% Generate code to set the specified `cond' variable to the
+	% specified truth value.
+	%
+:- pred ml_gen_set_cond_var(cond_seq, mlds__rval, prog_context,
+		mlds__statement, ml_gen_info, ml_gen_info).
+:- mode ml_gen_set_cond_var(in, in, in, out, in, out) is det.
+
 	% Return rvals for the success continuation that was
 	% passed as the current function's argument(s).
 	% The success continuation consists of two parts, the
@@ -343,10 +375,19 @@
 		ml_gen_info, ml_gen_info).
 :- mode ml_gen_info_new_commit_label(out, in, out) is det.
 
+	% Generate a new `cond' variable number.
+	% This is used to give unique names to the local
+	% variables used to hold the results of 
+	% nondet conditions of if-then-elses.
+:- type cond_seq == int.
+:- pred ml_gen_info_new_cond_var(cond_seq,
+		ml_gen_info, ml_gen_info).
+:- mode ml_gen_info_new_cond_var(out, in, out) is det.
+
 	%
 	% A success continuation specifies the (rval for the variable
 	% holding the address of the) function that a nondet procedure
-	% should call if it succeeds, and possible also the
+	% should call if it succeeds, and possibly also the
 	% (rval for the variable holding) the environment pointer
 	% for that function.
 	%
@@ -1003,6 +1044,8 @@
 	%
 	{ MLDS_Statements = [] }.
 
+%-----------------------------------------------------------------------------%
+
 	% Generate the declaration for the built-in `succeeded' variable.
 	%
 ml_gen_succeeded_var_decl(Context) =
@@ -1036,6 +1079,37 @@
 	{ MLDS_Statement = mlds__statement(MLDS_Stmt,
 		mlds__make_context(Context)) }.
 
+%-----------------------------------------------------------------------------%
+
+	% Generate the name for the specified `cond_<N>' variable.
+	%
+:- func ml_gen_cond_var_name(cond_seq) = string.
+ml_gen_cond_var_name(CondVar) =
+	string__append("cond_", string__int_to_string(CondVar)).
+
+ml_gen_cond_var_decl(CondVar, Context) =
+	ml_gen_mlds_var_decl(var(ml_gen_cond_var_name(CondVar)),
+		mlds__native_bool_type, Context).
+
+ml_cond_var_lval(CondVar, CondVarLval) -->
+	=(MLDSGenInfo),
+	{ ml_gen_info_get_module_name(MLDSGenInfo, ModuleName) },
+	{ MLDS_Module = mercury_module_name_to_mlds(ModuleName) },
+	{ CondVarLval = var(qual(MLDS_Module, ml_gen_cond_var_name(CondVar))) }.
+
+ml_gen_test_cond_var(CondVar, CondVarRval) -->
+	ml_cond_var_lval(CondVar, CondVarLval),
+	{ CondVarRval = lval(CondVarLval) }.
+	
+ml_gen_set_cond_var(CondVar, Value, Context, MLDS_Statement) -->
+	ml_cond_var_lval(CondVar, CondVarLval),
+	{ Assign = assign(CondVarLval, Value) },
+	{ MLDS_Stmt = atomic(Assign) },
+	{ MLDS_Statement = mlds__statement(MLDS_Stmt,
+		mlds__make_context(Context)) }.
+
+%-----------------------------------------------------------------------------%
+
 	% Return rvals for the success continuation that was
 	% passed as the current function's argument(s).
 	% The success continuation consists of two parts, the
@@ -1113,9 +1187,9 @@
 % The `ml_gen_info' type holds information used during MLDS code generation
 % for a given procedure.
 %
-% Only the `func_sequence_num', `commit_sequence_num', and
-% `stack(success_cont)' fields are mutable; the others are set
-% when the `ml_gen_info' is created and then never modified.
+% Only the `func_label', `commit_label', `cond_var', `success_cont_stack',
+% and `extra_defns' fields are mutable; the others are set when the 
+% `ml_gen_info' is created and then never modified.
 % 
 
 :- type ml_gen_info
@@ -1138,6 +1212,7 @@
 
 			func_label :: mlds__func_sequence_num,
 			commit_label :: commit_sequence_num,
+			cond_var :: cond_seq,
 			success_cont_stack :: stack(success_cont),
 				% definitions of functions or global
 				% constants which should be inserted
@@ -1157,6 +1232,7 @@
 		VarTypes),
 	FuncLabelCounter = 0,
 	CommitLabelCounter = 0,
+	SucceededVarCounter = 0,
 	stack__init(SuccContStack),
 	ExtraDefns = [],
 	MLDSGenInfo = ml_gen_info(
@@ -1168,6 +1244,7 @@
 			OutputVars,
 			FuncLabelCounter,
 			CommitLabelCounter,
+			SucceededVarCounter,
 			SuccContStack,
 			ExtraDefns
 		).
@@ -1197,6 +1274,9 @@
 ml_gen_info_new_commit_label(CommitLabel, Info,
 		Info^commit_label := CommitLabel) :-
 	CommitLabel = Info^commit_label + 1.
+
+ml_gen_info_new_cond_var(CondVar, Info, Info^cond_var := CondVar) :-
+	CondVar = Info^cond_var + 1.
 
 ml_gen_info_push_success_cont(SuccCont, Info,
 	Info^success_cont_stack :=

-- 
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