diff: bug fix

Simon TAYLOR stayl at students.cs.mu.oz.au
Wed Jul 16 18:51:09 AEST 1997


Hi Fergus,

Could you please review this one.

Simon.


Estimated hours taken: 2

Bug fix.

compiler/higher_order.m
	lambda.m reorders the argument variables of lambda
 	expressions so that inputs come before outputs.
	higher_order.m was not doing the reordering before
	replacing a higher_order_call with a call to the lambda
 	expression.

compiler/lambda.m
	Export lambda__permute_argvars for use by higher_order.m.

tests/hard_coded/Mmake
tests/hard_coded/ho_order.m
tests/hard_coded/ho_order.exp
	Regression test.



Index: higher_order.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/higher_order.m,v
retrieving revision 1.28
diff -u -r1.28 higher_order.m
--- higher_order.m	1997/06/27 04:01:23	1.28
+++ higher_order.m	1997/07/16 07:09:20
@@ -32,7 +32,7 @@
 
 :- import_module hlds_pred, hlds_goal, hlds_data, instmap.
 :- import_module code_util, globals, make_hlds, mode_util, goal_util.
-:- import_module type_util, options, prog_data, quantification.
+:- import_module type_util, options, prog_data, quantification, (lambda).
 :- import_module mercury_to_mercury.
 
 :- import_module assoc_list, bool, char, int, list, map, require, set.
@@ -532,9 +532,10 @@
 maybe_specialize_higher_order_call(Goal0 - GoalInfo, Goal - GoalInfo,
 		PredProcId, Changed, Info0, Info) :-
 	Info0 = info(PredVars, Requests0, NewPreds, Module),
-	( Goal0 = higher_order_call(PredVar0, Args0, _Types, _Modes, _Det) ->
+	( Goal0 = higher_order_call(PredVar0, Args0, _Types, Modes0, _Det) ->
 		PredVar = PredVar0,
-		Args = Args0
+		Args = Args0,
+		Modes = Modes0
 	;
 		error("higher_order.m: higher_order_call expected")
 	),
@@ -548,7 +549,13 @@
 		pred_info_module(PredInfo, ModuleName),
 		pred_info_name(PredInfo, PredName),
 		code_util__builtin_state(Module, PredId, ProcId, Builtin),
-		list__append(CurriedArgs, Args, AllArgs),
+
+		% We need to permute the arguments so that inputs come before
+		% outputs, since lambda.m will have done that to the arguments
+		% of the closure.
+		lambda__permute_argvars(Args, Modes, Module, PermutedArgs, _),
+
+		list__append(CurriedArgs, PermutedArgs, AllArgs),
 		MaybeContext = no,
 		Goal1 = call(PredId, ProcId, AllArgs,
 			Builtin, MaybeContext,
Index: lambda.m
===================================================================
RCS file: /home/staff/zs/imp/mercury/compiler/lambda.m,v
retrieving revision 1.28
diff -u -r1.28 lambda.m
--- lambda.m	1997/07/01 04:03:54	1.28
+++ lambda.m	1997/07/16 06:59:13
@@ -48,6 +48,11 @@
 :- mode lambda__transform_lambda(in, in, in, in, in, in, in, in, in, in, in,
 		in, out, out, out) is det.
 
+	% Permute the list of variables so that inputs come before outputs.
+:- pred lambda__permute_argvars(list(var), list(mode), module_info,
+			list(var), list(mode)).
+:- mode lambda__permute_argvars(in, in, in, out, out) is det.
+
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
 
@@ -338,7 +343,7 @@
 		% permute the argument variables so that all the inputs
 		% come before all the outputs.
 		
-		permute_argvars(AllArgVars, AllArgModes, ModuleInfo1,
+		lambda__permute_argvars(AllArgVars, AllArgModes, ModuleInfo1,
 			PermutedArgVars, PermutedArgModes),
 		map__apply_to_list(PermutedArgVars, VarTypes, ArgTypes),
 
@@ -401,21 +406,17 @@
 		)
 	).
 
-:- pred permute_argvars(list(var), list(mode), module_info,
-			list(var), list(mode)).
-:- mode permute_argvars(in, in, in, out, out) is det.
-
 	% permute a list of variables and a corresponding list of their modes
 	% so that all the input variables precede all the output variables.
 
-permute_argvars(AllArgVars, AllArgModes, ModuleInfo,
+lambda__permute_argvars(AllArgVars, AllArgModes, ModuleInfo,
 		PermutedArgVars, PermutedArgModes) :-
 	( split_argvars(AllArgVars, AllArgModes, ModuleInfo,
 		InArgVars, InArgModes, OutArgVars, OutArgModes) ->
 		list__append(InArgVars, OutArgVars, PermutedArgVars),
 		list__append(InArgModes, OutArgModes, PermutedArgModes)
 	;
-		error("lambda.m: permute_argvars: split_argvars failed")
+		error("lambda__permute_argvars: split_argvars failed")
 	).
 
 :- pred split_argvars(list(var), list(mode), module_info,




Index: Mmake
===================================================================
RCS file: /home/staff/zs/imp/tests/hard_coded/Mmake,v
retrieving revision 1.50
diff -u -r1.50 Mmake
--- Mmake	1997/07/09 08:21:08	1.50
+++ Mmake	1997/07/16 08:41:31
@@ -32,6 +32,7 @@
 	higher_order_func_test \
 	higher_order_syntax \
 	ho_func_reg \
+	ho_order \
 	ho_solns \
 	ho_univ_to_type \
 	name_mangling \
@@ -56,6 +57,7 @@
 
 MCFLAGS-boyer		=	--infer-all
 MCFLAGS-func_test	=	--infer-all
+MCFLAGS-ho_order	=	--optimize-higher-order
 MCFLAGS-no_fully_strict	=	--no-fully-strict
 
 # no_fully_strict is expected to fail (it calls error/1)


%-----------------------------------------------------------------------------%
% Regression test for a bug in higher_order.m
% Symptom: "Software Error: variable not found" during code generation.
% Cause: lambda.m reorders the argument variables of lambda
% 	expressions so that inputs come before outputs.
%	higher_order.m was not doing the reordering before
%	replacing a higher_order_call with a call to the lambda
% 	expression.
%-----------------------------------------------------------------------------%
:- module ho_order.

:- interface.

:- import_module io.


:- pred main(io__state, io__state).
:- mode main(di, uo) is det.

%-----------------------------------------------------------------------------%

:- implementation.
:- import_module int, list, map, std_util, string.

%-----------------------------------------------------------------------------%

		% information used during the elimination phase.

main(State0, State) :-
	map__from_assoc_list([0 - 1], Needed),
	map__from_assoc_list([0 - 1, 1 - 2, 2 - 4], ProcTable0),
	ProcIds = [1, 2],
	Keep = no,
	fldl2(ho_order__eliminate_proc(Keep, Needed),
		ProcIds, ProcTable0, _ProcTable, State0, State).

		% eliminate a procedure, if unused

:- pred ho_order__eliminate_proc(maybe(int), map(int, int),
	int, map(int, int), map(int, int), io__state, io__state).
:- mode ho_order__eliminate_proc(in, in, in, in, out, di, uo) is det.

ho_order__eliminate_proc(Keep, Needed, ProcId, 
		ProcTable0, ProcTable) -->
	(
		( { map__search(Needed, ProcId, _) }
		; { Keep = yes(_) }
		)
	->
		{ ProcTable = ProcTable0 }
	;
		io__format("Deleting %i\n", [i(ProcId)]),
		{ map__delete(ProcTable0, ProcId, ProcTable) }
	).

:- pred fldl2(pred(X, Y, Y, Z, Z), list(X), Y, Y, Z, Z).
:- mode fldl2(pred(in, in, out, in, out) is det,
		in, in, out, in, out) is det.
:- mode fldl2(pred(in, in, out, di, uo) is det,
		in, in, out, di, uo) is det.
:- mode fldl2(pred(in, di, uo, di, uo) is det,
		in, di, uo, di, uo) is det.

fldl2(_, [], FirstAcc, FirstAcc, SecAcc, SecAcc).
fldl2(P, [H|T], FirstAcc0, FirstAcc, SecAcc0, SecAcc) :-
	call(P, H, FirstAcc0, FirstAcc1, SecAcc0, SecAcc1),
	fldl2(P, T, FirstAcc1, FirstAcc, SecAcc1, SecAcc).

%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%

tests/hard_coded/ho_order.exp:
%=============================================================================%

Deleting 1
Deleting 2



More information about the developers mailing list