[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