[m-dev.] diff: --high-level-data, part 4

Fergus Henderson fjh at cs.mu.OZ.AU
Mon Jun 5 10:13:42 AEST 2000


Estimated hours taken: 8

Mork work on implementing the `--high-level-data' option.  This change
fixes a problem with unify and compare procedures for equivalence types.

compiler/ml_code_gen.m:
	Generalize the code for boxing existentially typed output
	variables so that it now handles all cases where the procedure
	argument types don't match the types of the head variables in
	the body.  That can occur for unify and compare procedures
	for equivalence types too, not just for procedures with
	existentially typed outputs.

compiler/ml_code_util.m:
	Make several changes for use by ml_code_gen.m:
	- Add a new field to the ml_gen_info containing a map(prog_var, lval).
	- Change ml_gen_var so that it checks that map first, and if the
	  variable occurs in that map it uses the lval from the map.
	- Export a new procedure ml_gen_var_with_type.

compiler/ml_call_gen.m:
	Change ml_gen_box_or_unbox_lval so that it returns
	code to assign both to and from the lval, rather than
	just in one direction.
	

Workspace: /home/pgrad/fjh/ws/hg
Index: compiler/ml_call_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_call_gen.m,v
retrieving revision 1.12
diff -u -d -r1.12 ml_call_gen.m
--- compiler/ml_call_gen.m	2000/05/31 06:04:12	1.12
+++ compiler/ml_call_gen.m	2000/06/04 22:58:41
@@ -62,20 +62,25 @@
 		ml_gen_info, ml_gen_info).
 :- mode ml_gen_box_or_unbox_rval(in, in, in, out, in, out) is det.
 
+	% ml_gen_box_or_unbox_lval(CallerType, CalleeType, VarLval, VarName,
+	%	Context,
+	%	ArgLval, ConvDecls, ConvInputStatements, ConvOutputStatements):
+	%
 	% This is like `ml_gen_box_or_unbox_rval', except that it
 	% works on lvals rather than rvals.
 	% Given a source type and a destination type,
 	% a source lval holding a value of the source type,
 	% and a name to base the name of the local temporary variable on,
 	% this procedure produces an lval of the destination type,
-	% code to assign the destination lval (suitably converted)
-	% to the source lval, and the declaration for the local
-	% temporary used (if any).
+	% the declaration for the local temporary used (if any),
+	% code to assign from the source lval (suitable converted)
+	% to the destination lval, and code to assign from the
+	% destination lval (suitable converted) to the source lval.
 	%
 :- pred ml_gen_box_or_unbox_lval(prog_type, prog_type, mlds__lval, var_name,
 		prog_context, mlds__lval, mlds__defns, mlds__statements,
-		ml_gen_info, ml_gen_info).
-:- mode ml_gen_box_or_unbox_lval(in, in, in, in, in, out, out, out,
+		mlds__statements, ml_gen_info, ml_gen_info).
+:- mode ml_gen_box_or_unbox_lval(in, in, in, in, in, out, out, out, out,
 		in, out) is det.
 
 %-----------------------------------------------------------------------------%
@@ -475,7 +480,8 @@
 			%
 			ml_gen_box_or_unbox_lval(CallerType, CalleeType,
 				VarLval, VarName, Context, ArgLval,
-				ThisArgConvDecls, ThisArgConvOutput),
+				ThisArgConvDecls, _ThisArgConvInput,
+				ThisArgConvOutput),
 			{ ConvDecls = list__append(ThisArgConvDecls,
 				ConvDecls1) },
 			{ ConvOutputStatements = list__append(
@@ -556,7 +562,8 @@
 	).
 	
 ml_gen_box_or_unbox_lval(CallerType, CalleeType, VarLval, VarName, Context,
-		ArgLval, ConvDecls, ConvStatements) -->
+		ArgLval, ConvDecls, ConvInputStatements, ConvOutputStatements)
+		-->
 	%
 	% First see if we can just convert the lval as an rval;
 	% if no boxing/unboxing is required, then ml_box_or_unbox_rval
@@ -569,12 +576,13 @@
 	->
 		{ ArgLval = VarLval },
 		{ ConvDecls = [] },
-		{ ConvStatements = [] }
+		{ ConvInputStatements = [] },
+		{ ConvOutputStatements = [] }
 	;
 		%
 		% If that didn't work, then we need to declare a fresh variable
-		% to use as the arg, and to generate a statement to box/unbox
-		% that fresh arg variable and assign it to the output argument
+		% to use as the arg, and to generate statements to box/unbox
+		% that fresh arg variable and assign it to/from the output argument
 		% whose address we were passed.
 		%
 
@@ -595,19 +603,28 @@
 		( { type_util__is_dummy_argument_type(CallerType) } ->
 			% if it is a dummy argument type (e.g. io__state),
 			% then we don't need to bother assigning it
-			{ ConvStatements = [] }
+			{ ConvInputStatements = [] },
+			{ ConvOutputStatements = [] }
 		;
-			% generate a statement to box/unbox the fresh variable
-			% and assign it to the output argument whose address
-			% we were passed.  Note that we swap the caller type
-			% and the callee type, since this is an output not
-			% an input, so the callee type is the source type
-			% and the caller type is the destination type.
+			%
+			% generate statements to box/unbox the fresh variable
+			% and assign it to/from the output argument whose
+			% address we were passed.
+			%
+
+			% assign to the freshly generated arg variable
+			ml_gen_box_or_unbox_rval(CallerType, CalleeType,
+				lval(VarLval), ConvertedVarRval),
+			{ AssignInputStatement = ml_gen_assign(ArgLval,
+				ConvertedVarRval, Context) },
+			{ ConvInputStatements = [AssignInputStatement] },
+
+			% assign from the freshly generated arg variable
 			ml_gen_box_or_unbox_rval(CalleeType, CallerType,
 				lval(ArgLval), ConvertedArgRval),
-			{ AssignStatement = ml_gen_assign(VarLval,
+			{ AssignOutputStatement = ml_gen_assign(VarLval,
 				ConvertedArgRval, Context) },
-			{ ConvStatements = [AssignStatement] }
+			{ ConvOutputStatements = [AssignOutputStatement] }
 		)
 	).
 	
Index: compiler/ml_code_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_code_gen.m,v
retrieving revision 1.50
diff -u -d -r1.50 ml_code_gen.m
--- compiler/ml_code_gen.m	2000/06/01 08:55:32	1.50
+++ compiler/ml_code_gen.m	2000/06/04 23:07:17
@@ -881,7 +881,7 @@
 	goal_info_get_context(GoalInfo, Context),
 
 	MLDSGenInfo0 = ml_gen_info_init(ModuleInfo, PredId, ProcId),
-	MLDS_Params0 = ml_gen_proc_params(ModuleInfo, PredId, ProcId),
+	MLDS_Params = ml_gen_proc_params(ModuleInfo, PredId, ProcId),
 	( CodeModel = model_non ->
 		% set up the initial success continuation
 		ml_initial_cont(InitialCont, MLDSGenInfo0, MLDSGenInfo1),
@@ -903,7 +903,6 @@
 	MLDS_LocalVars = [ml_gen_succeeded_var_decl(MLDS_Context)],
 	ml_gen_proc_body(CodeModel, HeadVars, ArgTypes, Goal,
 			MLDS_Decls0, MLDS_Statements,
-			MLDS_Params0, MLDS_Params,
 			MLDSGenInfo2, MLDSGenInfo),
 	ml_gen_info_get_extra_defns(MLDSGenInfo, ExtraDefns),
 	MLDS_Decls = list__append(MLDS_LocalVars, MLDS_Decls0),
@@ -958,12 +957,11 @@
 	%
 :- pred ml_gen_proc_body(code_model, list(prog_var), list(prog_type),
 		hlds_goal, mlds__defns, mlds__statements,
-		mlds__func_params, mlds__func_params,
 		ml_gen_info, ml_gen_info).
-:- mode ml_gen_proc_body(in, in, in, in, out, out, in, out, in, out) is det.
+:- mode ml_gen_proc_body(in, in, in, in, out, out, in, out) is det.
 
 ml_gen_proc_body(CodeModel, HeadVars, ArgTypes, Goal,
-		MLDS_Decls, MLDS_Statements, MLDS_Params0, MLDS_Params) -->
+		MLDS_Decls, MLDS_Statements) -->
 	{ Goal = _ - GoalInfo },
 	{ goal_info_get_context(GoalInfo, Context) },
 
@@ -973,30 +971,38 @@
 	{ DoGenGoal = ml_gen_goal(CodeModel, Goal) },
 
 	%
-	% For existentially typed procedures, we may need to
-	% box the existentially typed output arguments.
+	% In certain cases -- for example existentially typed procedures,
+	% or unification/compare procedures for equivalence types --
+	% the parameters types may not match the types of the head variables.
+	% In such cases, we need to box/unbox/cast them to the right type.
 	%
-	ml_gen_box_existential_outputs(HeadVars, ArgTypes,
-		Context, MLDS_Params0, MLDS_Params, BoxDecls, BoxStatements),
-	( { BoxDecls = [], BoxStatements = [] } ->
-		% No boxing required.
-		DoGenGoal(MLDS_Decls, MLDS_Statements0)
+	ml_gen_convert_headvars(HeadVars, ArgTypes, Context,
+		ConvDecls, ConvInputStatements, ConvOutputStatements),
+	(
+		{ ConvDecls = [] },
+		{ ConvInputStatements = [] },
+		{ ConvOutputStatements = [] }
+	->
+		% No boxing/unboxing/casting required.
+		DoGenGoal(MLDS_Decls, MLDS_Statements1)
 	;
-		% Boxing required.
-		% We need to generate the goal,
-		% box the output arguments,
+		% Boxing/unboxing/casting required.
+		% We need to convert the input arguments,
+		% generate the goal, convert the output arguments,
 		% and then succeeed.
-		{ DoBoxOutputs = (pred(Decls::out, Statements::out, in, out)
+		{ DoConvOutputs = (pred(Decls::out, Statements::out, in, out)
 					is det -->
 			ml_gen_success(CodeModel, Context, SuccStatements),
 			{ Decls = [] },
-			{ Statements = list__append(BoxStatements,
+			{ Statements = list__append(ConvOutputStatements,
 				SuccStatements) }
 		) },
 		ml_combine_conj(CodeModel, Context,
-			DoGenGoal, DoBoxOutputs,
+			DoGenGoal, DoConvOutputs,
 			MLDS_Decls0, MLDS_Statements0),
-		{ MLDS_Decls = list__append(BoxDecls, MLDS_Decls0) }
+		{ MLDS_Statements1 = list__append(ConvInputStatements,
+			MLDS_Statements0) },
+		{ MLDS_Decls = list__append(ConvDecls, MLDS_Decls0) }
 	),
 
 	%
@@ -1007,143 +1013,90 @@
 		{ ReturnStmt = return([Succeeded]) },
 		{ ReturnStatement = mlds__statement(ReturnStmt,
 			mlds__make_context(Context)) },
-		{ MLDS_Statements = list__append(MLDS_Statements0,
+		{ MLDS_Statements = list__append(MLDS_Statements1,
 			[ReturnStatement]) }
 	;
-		{ MLDS_Statements = MLDS_Statements0 }
+		{ MLDS_Statements = MLDS_Statements1 }
 	).
 
 %
-% For existentially typed procedures, the type of each parameter
-% can be an existentially quantified type variable, and the type
-% of the corresponding actual variable in the procedure may be
-% some concrete type.  In such cases, we need to generate code
-% to box the argument, to convert from the concrete type to
-% the polymorphic type.  (Note: this can only happen for output
-% arguments, so it's always boxing, never unboxing, that we need to do.)
-% This procedure handles the boxing of such arguments.
+% In certain cases -- for example existentially typed procedures,
+% or unification/compare procedures for equivalence types --
+% the parameter types may not match the types of the head variables.
+% In such cases, we need to box/unbox/cast them to the right type.
+% This procedure handles that.
 %
-:- pred ml_gen_box_existential_outputs(list(prog_var), list(prog_type),
-		prog_context, mlds__func_params, mlds__func_params,
-		mlds__defns, mlds__statements, ml_gen_info, ml_gen_info).
-:- mode ml_gen_box_existential_outputs(in, in, in, in, out, out, out,
-		in, out) is det.
-
-ml_gen_box_existential_outputs(HeadVars, HeadTypes, Context,
-		Params0, Params, Decls, Statements) -->
-	ml_gen_box_existential_output_args(HeadVars, HeadTypes, Context,
-		BoxedExistentialVars, Decls, Statements),
-	{ Params0 = func_params(Arguments0, RetType) },
-	{ Arguments = list__map(ml_update_param(BoxedExistentialVars),
-		Arguments0) },
-	{ Params = func_params(Arguments, RetType) }.
+:- pred ml_gen_convert_headvars(list(prog_var), list(prog_type), prog_context,
+		mlds__defns, mlds__statements, mlds__statements,
+		ml_gen_info, ml_gen_info).
+:- mode ml_gen_convert_headvars(in, in, in, out, out, out, in, out) is det.
 
-:- pred ml_gen_box_existential_output_args(list(prog_var), list(prog_type),
-		prog_context, list(mlds__var_name),
-		mlds__defns, mlds__statements, ml_gen_info, ml_gen_info).
-:- mode ml_gen_box_existential_output_args(in, in, in, out, out, out, in, out)
-		is det.
-ml_gen_box_existential_output_args([], [], _, [], [], []) --> [].
-ml_gen_box_existential_output_args([Var|Vars], [ArgType|ArgTypes],
-		Context, BoxedExistentialVars, Decls, Statements) -->
-	ml_variable_type(Var, VarType),
+ml_gen_convert_headvars([], [], _, [], [], []) --> [].
+ml_gen_convert_headvars([Var|Vars], [HeadType|HeadTypes],
+		Context, Decls, InputStatements, OutputStatements) -->
+	ml_variable_type(Var, BodyType),
 	(
-                %
-                % If the ArgType from the pred decl is polymorphic,
-		% but the actual VarType from the procedure body
-		% is monomorphic, then this must be an existentially
-		% quantified output argument, and we'll need to box it.
-                %
-                { VarType = term__functor(_, _, _) },
-                { ArgType = term__variable(_) }
-        ->
 		%
-		% Instead of
+		% Check whether HeadType is the same as BodyType
+		% (modulo the term__contexts)
 		%
-		%	foo(..., ArgType *VarName, ...) {
-		%		... code that assigns to *VarName ...
-		%	}
+		{ map__init(Subst0) },
+		{ type_unify(HeadType, BodyType, [], Subst0, Subst) },
+		{ map__is_empty(Subst) }
+	->
+		% just recursively process the remaining arguments
+		ml_gen_convert_headvars(Vars, HeadTypes, Context,
+				Decls, InputStatements, OutputStatements)
+	;
 		%
-		% we generate
+		% generate the lval for the head variable
 		%
-		%	foo(..., ArgType *head_VarName, ...) {
-		%		VarType VarName;
-		%		... code that assigns to VarName ...
-		%		*head_VarName = box(VarName);
-		%	}
+		ml_gen_var_with_type(Var, HeadType, HeadVarLval),
+
 		%
-		% Note that select_output_vars in ml_code_util.m
-		% already ensures that the generated code for the
-		% body will assign to VarName rather than to *VarName.
-		% And ml_update_param will handle the renaming of
-		% the parameter.
-		% So all we need to do here is to declare VarName
-		% as a local and generate the assignment to *head_VarName.
+		% generate code to box or unbox that head variable,
+		% to convert its type from HeadType to BodyType
 		%
-
-		% create a fresh variable name for the boxed parameter
 		=(MLDSGenInfo),
 		{ ml_gen_info_get_varset(MLDSGenInfo, VarSet) },
 		{ VarName = ml_gen_var_name(VarSet, Var) },
-		{ string__append("head_", VarName, HeadVarName) },
+		ml_gen_box_or_unbox_lval(HeadType, BodyType, HeadVarLval,
+			VarName, Context, BodyLval, ConvDecls,
+			ConvInputStatements, ConvOutputStatements),
 
-		( { type_util__is_dummy_argument_type(VarType) } ->
-			% if it has a dummy argument type (e.g. io__state),
-			% then we don't need to bother declaring the
-			% variable or assigning from it
-			{ ConvStatements = [] },
-			{ LocalVarDecls = [] }
-		;
-			% generate a declaration for the variable (which
-			% will now become a local rather than a parameter)
-			{ ml_gen_info_get_module_info(MLDSGenInfo,
-				ModuleInfo) },
-			{ VarDecl = ml_gen_var_decl(VarName, VarType,
-				mlds__make_context(Context), ModuleInfo) },
-			{ LocalVarDecls = [VarDecl] },
+		%
+		% Ensure that for any uses of this variable in the procedure
+		% body, we use the BodyLval (which has type BodyType)
+		% rather than the HeadVarLval (which has type HeadType).
+		%
+		ml_gen_info_set_var_lval(Var, BodyLval),
 
-			% generate the assignment of the boxed variable
-			% to the dereferenced headvar
-			ml_qualify_var(VarName, VarLval),
-			ml_qualify_var(HeadVarName, HeadVarLval),
-			ml_gen_type(VarType, MLDS_VarType),
-			{ BoxedVarRval = unop(box(MLDS_VarType),
-				lval(VarLval)) },
-			{ AssignStatement = ml_gen_assign(
-				mem_ref(lval(HeadVarLval), MLDS_VarType),
-				BoxedVarRval, Context) },
-			{ ConvStatements = [AssignStatement] }
-		),
-		ml_gen_box_existential_output_args(Vars, ArgTypes, Context,
-				BoxedExistentialVars1, Decls1, Statements1),
-		{ BoxedExistentialVars = [VarName | BoxedExistentialVars1] },
-		{ list__append(LocalVarDecls, Decls1, Decls) },
-		{ list__append(ConvStatements, Statements1, Statements) }
-        ;
-		ml_gen_box_existential_output_args(Vars, ArgTypes, Context,
-				BoxedExistentialVars, Decls, Statements)
-	).
-ml_gen_box_existential_output_args([], [_|_], _, _, _, _) -->
-	{ error("ml_gen_box_existential_outputs: length mismatch") }.
-ml_gen_box_existential_output_args([_|_], [], _, _, _, _) -->
-	{ error("ml_gen_box_existential_outputs: length mismatch") }.
+		%
+		% Recursively process the remaining arguments
+		%
+		ml_gen_convert_headvars(Vars, HeadTypes, Context,
+				Decls1, InputStatements1, OutputStatements1),
 
-% 
-% If this parameter occurs in BoxedExistentialVars,
-% then prepend `head_' to its name.
-%
-:- type mlds_argument == pair(mlds__entity_name, mlds__type).
-:- func ml_update_param(list(mlds__var_name), mlds_argument) = mlds_argument.
-ml_update_param(BoxedExistentialVars, Arg0) = Arg :-
-	(
-		Arg0 = data(var(Name0)) - Type,
-		list__member(Name0, BoxedExistentialVars)
-	->
-		string__append("head_", Name0, Name),
-		Arg = data(var(Name)) - Type
-	;
-		Arg = Arg0
+		%
+		% Add the code to convert this input or output.
+		%
+		=(MLDSGenInfo2),
+		{ ml_gen_info_get_output_vars(MLDSGenInfo2, OutputVars) },
+		{ list__member(Var, OutputVars) ->
+			InputStatements = InputStatements1,
+			OutputStatements = list__append(OutputStatements1,
+				ConvOutputStatements)
+		;
+			InputStatements = list__append(ConvInputStatements,
+				InputStatements1),
+			OutputStatements = OutputStatements1
+		},
+		{ list__append(ConvDecls, Decls1, Decls) }
 	).
+ml_gen_convert_headvars([], [_|_], _, _, _, _) -->
+	{ error("ml_gen_convert_headvars: length mismatch") }.
+ml_gen_convert_headvars([_|_], [], _, _, _, _) -->
+	{ error("ml_gen_convert_headvars: length mismatch") }.
 
 %-----------------------------------------------------------------------------%
 %
@@ -2063,7 +2016,7 @@
 		ml_gen_info::in, ml_gen_info::out) is det.
 
 ml_gen_pragma_c_output_arg(ml_c_arg(Var, MaybeNameAndMode, OrigType),
-		Context, AssignOutput, ConvDecls, ConvStatements) -->
+		Context, AssignOutput, ConvDecls, ConvOutputStatements) -->
 	=(MLDSGenInfo),
 	{ ml_gen_info_get_module_info(MLDSGenInfo, ModuleInfo) },
 	(
@@ -2075,7 +2028,8 @@
 		ml_variable_type(Var, VarType),
 		ml_gen_var(Var, VarLval),
 		ml_gen_box_or_unbox_lval(VarType, OrigType, VarLval, ArgName,
-			Context, ArgLval, ConvDecls, ConvStatements),
+			Context, ArgLval, ConvDecls, _ConvInputStatements,
+			ConvOutputStatements),
 		{ module_info_globals(ModuleInfo, Globals) },
 		{ globals__lookup_bool_option(Globals, highlevel_data,
 			HighLevelData) },
@@ -2116,7 +2070,7 @@
 		% it can't be used, so we just ignore it
 		{ AssignOutput = [] },
 		{ ConvDecls = [] },
-		{ ConvStatements = [] }
+		{ ConvOutputStatements = [] }
 	).
 
 %-----------------------------------------------------------------------------%
Index: compiler/ml_code_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_code_util.m,v
retrieving revision 1.15
diff -u -d -r1.15 ml_code_util.m
--- compiler/ml_code_util.m	2000/05/31 06:04:02	1.15
+++ compiler/ml_code_util.m	2000/06/04 23:05:00
@@ -173,6 +173,13 @@
 :- pred ml_gen_var(prog_var, mlds__lval, ml_gen_info, ml_gen_info).
 :- mode ml_gen_var(in, out, in, out) is det.
 
+	% Generate the mlds__lval corresponding to a given prog_var,
+	% with a given type.
+	%
+:- pred ml_gen_var_with_type(prog_var, prog_type, mlds__lval,
+		ml_gen_info, ml_gen_info).
+:- mode ml_gen_var_with_type(in, in, out, in, out) is det.
+
 	% Lookup the types of a list of variables.
 	%
 :- pred ml_variable_types(list(prog_var), list(prog_type),
@@ -473,6 +480,24 @@
 :- mode ml_gen_info_current_success_cont(out, in, out) is det.
 
 	%
+	% We keep a partial mapping from vars to lvals.
+	% This is used in special cases to override the normal
+	% lval for a variable.  ml_gen_var will check this
+	% map first, and if the variable is not in this map,
+	% then it will go ahead and generate an lval for it
+	% as usual.
+	%
+
+	% Set the lval for a variable.
+:- pred ml_gen_info_set_var_lval(prog_var, mlds__lval,
+			ml_gen_info, ml_gen_info).
+:- mode ml_gen_info_set_var_lval(in, in, in, out) is det.
+
+	% Get the partial mapping from variables to lvals.
+:- pred ml_gen_info_get_var_lvals(ml_gen_info, map(prog_var, mlds__lval)).
+:- mode ml_gen_info_get_var_lvals(in, out) is det.
+
+	%
 	% The ml_gen_info contains a list of extra definitions
 	% of functions or global constants which should be inserted
 	% before the definition of the function for the current procedure.
@@ -963,7 +988,28 @@
 	% Generate the mlds__lval corresponding to a given prog_var.
 	%
 ml_gen_var(Var, Lval) -->
-	ml_variable_type(Var, Type),
+	%
+	% First check the var_lvals override mapping;
+	% if an lval has been set for this variable, use it
+	%
+	=(Info),
+	{ ml_gen_info_get_var_lvals(Info, VarLvals) },
+	( { map__search(VarLvals, Var, VarLval) } ->
+		{ Lval = VarLval }
+	;
+		%
+		% Otherwise just look up the variable's type
+		% and generate an lval for it using the ordinary
+		% algorithm.
+		%
+		ml_variable_type(Var, Type),
+		ml_gen_var_with_type(Var, Type, Lval)
+	).
+
+	% Generate the mlds__lval corresponding to a given prog_var,
+	% with a given type.
+	%
+ml_gen_var_with_type(Var, Type, Lval) -->
 	( { type_util__is_dummy_argument_type(Type) } ->
 		%
 		% The variable won't have been declared, so
@@ -1260,6 +1306,10 @@
 			cond_var :: cond_seq,
 			conv_var :: conv_seq,
 			success_cont_stack :: stack(success_cont),
+				% a partial mapping from vars to lvals,
+				% used to override the normal lval
+				% that we use for a variable
+			var_lvals :: map(prog_var, mlds__lval),
 				% definitions of functions or global
 				% constants which should be inserted
 				% before the definition of the function
@@ -1284,6 +1334,7 @@
 	CondVarCounter = 0,
 	ConvVarCounter = 0,
 	stack__init(SuccContStack),
+	map__init(VarLvals),
 	ExtraDefns = [],
 
 	MLDSGenInfo = ml_gen_info(
@@ -1298,6 +1349,7 @@
 			CondVarCounter,
 			ConvVarCounter,
 			SuccContStack,
+			VarLvals,
 			ExtraDefns
 		).
 
@@ -1347,6 +1399,11 @@
 
 ml_gen_info_current_success_cont(SuccCont, Info, Info) :-
 	stack__top_det(Info^success_cont_stack, SuccCont).
+
+ml_gen_info_get_var_lvals(Info, Info^var_lvals).
+
+ml_gen_info_set_var_lval(Var, Lval, Info,
+		Info^var_lvals := map__set(Info^var_lvals, Var, Lval)).
 
 ml_gen_info_add_extra_defn(ExtraDefn, Info,
 	Info^extra_defns := [ExtraDefn | Info^extra_defns]).

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