[m-rev.] MLDS back-end and `top_unused'

Fergus Henderson fjh at cs.mu.OZ.AU
Wed Feb 12 03:41:47 AEDT 2003


This fixes a problem reported by Michael Wybrow.
Currently bootstrapping.

Estimated hours taken: 3
Branches: main

Ensure that in MLDS grades, arguments with arg_mode `top_unused' do not
get passed. 

Previously, different parts of the compiler had different and inconsistent
ideas about if/how they should get passed, which caused problems,
including an internal error for tests/hard_coded/foreign_type2.m in grade
`java'.  The comments in mlds.m said they should not get passed, the
code in ml_call_gen.m passed them as if they were output arguments, and
the code in ml_code_util declared them as if they were input arguments.

compiler/hlds_pred.m:
	Add some detailed comments about the meaning of the `arg_mode' type.

compiler/ml_call_gen.m:
compiler/ml_code_util.m:
compiler/ml_code_gen.m:
	Ensure that arguments with arg_mode `unused' do not get passed,
	declared, or converted (respectively).

runtime/mercury_grade.h:
	Bump the binary compatibility version number for MLDS grades.
	This is needed because the calling convention for procedures
	with `unused' mode arguments has changed.

Workspace: /home/ceres/fjh/mercury
Index: compiler/hlds_pred.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_pred.m,v
retrieving revision 1.114
diff -u -d -r1.114 hlds_pred.m
--- compiler/hlds_pred.m	27 Jan 2003 09:20:46 -0000	1.114
+++ compiler/hlds_pred.m	11 Feb 2003 15:15:51 -0000
@@ -259,6 +259,32 @@
 					arg_mode	% mode of top functor
 				).
 
+	% The `arg_mode' specifies the mode of the top-level functor
+	% (excluding `no_tag' functors, since those have no representation).
+	% It is used by the code generators for determining how to
+	% pass the argument.
+	%
+	% For the LLDS back-end, top_in arguments are passed in registers,
+	% and top_out values are returned in registers; top_unused
+	% values are not passed at all, but they are treated as if
+	% they were top_out for the purpose of assigning arguments
+	% to registers.  (So e.g. if a det procedure has three arguments
+	% with arg_modes top_out, top_unused, and top_out respectively,
+	% the last argument will be returned in register r3, not r2.)
+	%
+	% For the MLDS back-end, top_in values are passed as arguments;
+	% top_out values are normally passed by reference, except that
+	%	- if the procedure is model_nondet, and the --nondet-copy-out
+	%	  option is set, top_out values are passed by value to
+	%	  the continuation function
+	%	- if the procedure is model_det or model_semi,
+	%	  and the --det-copy-out option is set,
+	%	  top_out arguments in the HLDS are mapped to (multiple)
+	%	  return values in the MLDS
+	%	- if the HLDS function return value for a det function has
+	%	  mode `top_out', it is mapped to an MLDS return value.
+	% top_unused arguments are not passed at all.
+	%
 :- type arg_mode	--->	top_in
 			;	top_out
 			;	top_unused.
Index: compiler/ml_call_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_call_gen.m,v
retrieving revision 1.36
diff -u -d -r1.36 ml_call_gen.m
--- compiler/ml_call_gen.m	27 Jan 2003 09:20:48 -0000	1.36
+++ compiler/ml_call_gen.m	11 Feb 2003 14:37:00 -0000
@@ -654,10 +654,13 @@
 		{ ml_gen_info_get_module_info(MLDSGenInfo, ModuleInfo) },
 		{ mode_to_arg_mode(ModuleInfo, Mode, CalleeType, ArgMode) },
 		(
-			{ type_util__is_dummy_argument_type(CalleeType) }
+			{ type_util__is_dummy_argument_type(CalleeType)
+			; ArgMode = top_unused
+			}
 		->
 			%
-			% exclude arguments of type io__state etc.
+			% Exclude arguments of type io__state etc.
+			% Also exclude those with arg_mode `top_unused'.
 			%
 			{ InputRvals = InputRvals1 },
 			{ OutputLvals = OutputLvals1 },
@@ -688,21 +691,14 @@
 			{ ConvOutputStatements = ConvOutputStatements1 }
 		;
 			%
-			% it's an output argument, or an unused argument
+			% it's an output argument
 			%
 			ml_gen_box_or_unbox_lval(CallerType, CalleeType,
 				VarLval, VarName, Context, ForClosureWrapper,
 				ArgNum, ArgLval, ThisArgConvDecls,
 				_ThisArgConvInput, ThisArgConvOutput),
 			{ ConvDecls = ThisArgConvDecls ++ ConvDecls1 },
-			{ ConvOutputStatements =
-				(if ArgMode = top_out then
-					ThisArgConvOutput
-				else
-					% don't unbox arguments
-					% with mode `top_unused'
-					[]
-				)
+			{ ConvOutputStatements = ThisArgConvOutput
 				++ ConvOutputStatements1 },
 
 			ml_gen_info_get_globals(Globals),
@@ -712,10 +708,6 @@
 					%
 					% if the target language allows
 					% multiple return values, then use them
-					%
-					% XXX for top_unused argument modes,
-					% the generated code will copy an
-					% uninitialized value
 					%
 					{ CopyOut = yes }
 				;
Index: compiler/ml_code_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_code_gen.m,v
retrieving revision 1.122
diff -u -d -r1.122 ml_code_gen.m
--- compiler/ml_code_gen.m	23 Dec 2002 12:32:57 -0000	1.122
+++ compiler/ml_code_gen.m	11 Feb 2003 15:28:31 -0000
@@ -1100,6 +1100,7 @@
 	pred_info_arg_types(PredInfo, ArgTypes),
 	proc_info_interface_code_model(ProcInfo, CodeModel),
 	proc_info_headvars(ProcInfo, HeadVars),
+	proc_info_argmodes(ProcInfo, Modes),
 	proc_info_goal(ProcInfo, Goal0),
 
 	%
@@ -1177,7 +1178,8 @@
 		MLDS_Context = mlds__make_context(Context),
 		MLDS_LocalVars = [ml_gen_succeeded_var_decl(MLDS_Context) |
 				OutputVarLocals],
-		ml_gen_proc_body(CodeModel, HeadVars, ArgTypes,
+		modes_to_arg_modes(ModuleInfo, Modes, ArgTypes, ArgModes),
+		ml_gen_proc_body(CodeModel, HeadVars, ArgTypes, ArgModes,
 				CopiedOutputVars, Goal,
 				MLDS_Decls0, MLDS_Statements,
 				MLDSGenInfo2, MLDSGenInfo3),
@@ -1313,12 +1315,13 @@
 	% Generate the code for a procedure body.
 	%
 :- pred ml_gen_proc_body(code_model, list(prog_var), list(prog_type),
-		list(prog_var), hlds_goal, mlds__defns, mlds__statements,
+		list(arg_mode), list(prog_var), hlds_goal,
+		mlds__defns, mlds__statements,
 		ml_gen_info, ml_gen_info).
-:- mode ml_gen_proc_body(in, in, in, in, in, out, out, in, out) is det.
+:- mode ml_gen_proc_body(in, in, in, in, in, in, out, out, in, out) is det.
 
-ml_gen_proc_body(CodeModel, HeadVars, ArgTypes, CopiedOutputVars, Goal,
-		MLDS_Decls, MLDS_Statements) -->
+ml_gen_proc_body(CodeModel, HeadVars, ArgTypes, ArgModes, CopiedOutputVars,
+		Goal, MLDS_Decls, MLDS_Statements) -->
 	{ Goal = _ - GoalInfo },
 	{ goal_info_get_context(GoalInfo, Context) },
 
@@ -1337,8 +1340,8 @@
 	% we append below, we want the original vars, not their cast versions.
 	%
 	ml_gen_var_list(CopiedOutputVars, CopiedOutputVarOriginalLvals),
-	ml_gen_convert_headvars(HeadVars, ArgTypes, CopiedOutputVars, Context,
-		ConvDecls, ConvInputStatements, ConvOutputStatements),
+	ml_gen_convert_headvars(HeadVars, ArgTypes, ArgModes, CopiedOutputVars,
+		Context, ConvDecls, ConvInputStatements, ConvOutputStatements),
 	(
 		{ ConvDecls = [] },
 		{ ConvInputStatements = [] },
@@ -1380,28 +1383,51 @@
 % This procedure handles that.
 %
 :- pred ml_gen_convert_headvars(list(prog_var), list(prog_type),
-		list(prog_var), prog_context,
+		list(arg_mode), list(prog_var), prog_context,
 		mlds__defns, mlds__statements, mlds__statements,
 		ml_gen_info, ml_gen_info).
-:- mode ml_gen_convert_headvars(in, in, in, in, out, out, out, in, out) is det.
+:- mode ml_gen_convert_headvars(in, in, in, in, in, out, out, out, in, out)
+	is det.
 
-ml_gen_convert_headvars([], [], _, _, [], [], []) --> [].
-ml_gen_convert_headvars([Var|Vars], [HeadType|HeadTypes], CopiedOutputVars,
-		Context, Decls, InputStatements, OutputStatements) -->
-	ml_variable_type(Var, BodyType),
+ml_gen_convert_headvars(Vars, HeadTypes, ArgModes, CopiedOutputVars, Context,
+		Decls, InputStatements, OutputStatements) -->
 	(
+	    % base case
+	    { Vars = [], HeadTypes = [], ArgModes = [] }
+	->
+	    { Decls = [], InputStatements = [], OutputStatements = [] }
+	;
+	    % recursive case
+	    { Vars = [Var | Vars1] },
+	    { HeadTypes = [HeadType | HeadTypes1] },
+	    { ArgModes = [ArgMode | ArgModes1] }
+	->
+	    ml_variable_type(Var, BodyType),
+	    (
+		%
+		% Arguments with mode `top_unused' do not need to be converted
+		%
+	    	{ ArgMode = top_unused }
+	    ->
+		% just recursively process the remaining arguments
+		ml_gen_convert_headvars(Vars1, HeadTypes1, ArgModes1,
+			CopiedOutputVars, Context, Decls,
+			InputStatements, OutputStatements)
+	    ;
 		%
 		% Check whether HeadType is the same as BodyType
-		% (modulo the term__contexts)
+		% (modulo the term__contexts).
+		% If so, no conversion is needed.
 		%
 		{ 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, CopiedOutputVars,
-			Context, Decls, InputStatements, OutputStatements)
-	;
+		ml_gen_convert_headvars(Vars1, HeadTypes1, ArgModes1,
+			CopiedOutputVars, Context, Decls,
+			InputStatements, OutputStatements)
+	    ;
 		%
 		% generate the lval for the head variable
 		%
@@ -1428,8 +1454,9 @@
 		%
 		% Recursively process the remaining arguments
 		%
-		ml_gen_convert_headvars(Vars, HeadTypes, CopiedOutputVars,
-			Context, Decls1, InputStatements1, OutputStatements1),
+		ml_gen_convert_headvars(Vars1, HeadTypes1, ArgModes1,
+			CopiedOutputVars, Context, Decls1, InputStatements1,
+			OutputStatements1),
 
 		%
 		% Add the code to convert this input or output.
@@ -1451,11 +1478,12 @@
 			OutputStatements = OutputStatements1
 		},
 		{ list__append(ConvDecls, Decls1, Decls) }
+	    )
+	;
+	    % neither base case nor recursive case matched
+	    { unexpected(this_file,
+	    	"ml_gen_convert_headvars: length mismatch") }
 	).
-ml_gen_convert_headvars([], [_|_], _, _, _, _, _) -->
-	{ error("ml_gen_convert_headvars: length mismatch") }.
-ml_gen_convert_headvars([_|_], [], _, _, _, _, _) -->
-	{ error("ml_gen_convert_headvars: length mismatch") }.
 
 %-----------------------------------------------------------------------------%
 %
Index: compiler/ml_code_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_code_util.m,v
retrieving revision 1.65
diff -u -d -r1.65 ml_code_util.m
--- compiler/ml_code_util.m	1 Nov 2002 09:56:54 -0000	1.65
+++ compiler/ml_code_util.m	11 Feb 2003 14:33:00 -0000
@@ -1287,9 +1287,12 @@
 			MaybeMLGenInfo0, MaybeMLGenInfo1),
 		(
 			%
-			% exclude types such as io__state, etc.
+			% Exclude types such as io__state, etc.
+			% Also exclude values with arg_mode `top_unused'.
 			%
-			type_util__is_dummy_argument_type(Type)
+			( type_util__is_dummy_argument_type(Type)
+			; Mode = top_unused
+			)
 		->
 			FuncArgs = FuncArgs0,
 			RetTypes = RetTypes0,
Index: runtime/mercury_grade.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_grade.h,v
retrieving revision 1.45
diff -u -d -r1.45 ml_code_util.m
--- mercury_grade.h	1 Nov 2002 09:56:54 -0000	1.45
+++ mercury_grade.h	11 Feb 2003 14:33:00 -0000
@@ -54,7 +54,11 @@
 ** RTTI version number.
 */
 
-#define MR_GRADE_PART_0	v9_
+#ifdef MR_HIGHLEVEL_CODE
+  #define MR_GRADE_PART_0	v10_
+#else
+  #define MR_GRADE_PART_0	v9_
+#endif
 
 #ifdef MR_HIGHLEVEL_CODE
 

-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
The University of Melbourne         |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- the last words of T. S. Garp.
--------------------------------------------------------------------------
mercury-reviews mailing list
post:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list