[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