[m-dev.] diff: MLDS back-end: various bug fixes

Fergus Henderson fjh at cs.mu.OZ.AU
Sat Dec 4 03:58:46 AEDT 1999


Estimated hours taken: 6

Fix some bugs in the MLDS back-end.

compiler/ml_code_gen.m:
	- Make sure that we module-qualify the base_type_infos for the
	  builtin types.
	- Make sure that we unbox (i.e. cast) the closure argument
	  when passing it to a closure wrapper function.
	- Fix a bug where we were generating references to undeclared
	  variables when calling higher-order procedures with arguments
	  of type `io__state' or when passing `io_state' arguments to
	  polymorphic procedures.
	- Export ml_gen_proc_params, for use by ml_base_type_info.m.

compiler/ml_base_type_info.m:
	- Make sure that we "box" (i.e. cast to a common type) the function
	  addresses that we store in base_type_infos, since their number
	  of parameters depends on the type's arity

compiler/mlds_to_c.m:
	- Output `extern' before forward declarations of variables.
	- For mem_addr values, output `&' before the variable name.
	- For mem_addr values, make sure to cast them to `(Word)';
	  this is needed for base_type_infos, which are currently the
	  only thing we use mem_addr values for.  (This code will probably
	  need to change later to accomodate other kinds of mem_addr values.)
	- Enclose header files in the standard `#ifndef ... #define ... ... #endif'
	  header guard, to avoid problems with mutually recursive module
	  interfaces.

Workspace: /d-drive/home/hg/fjh/mercury
Index: compiler/ml_base_type_info.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_base_type_info.m,v
retrieving revision 1.1
diff -u -d -r1.1 ml_base_type_info.m
--- compiler/ml_base_type_info.m	1999/12/02 05:42:25	1.1
+++ compiler/ml_base_type_info.m	1999/12/03 06:39:05
@@ -209,7 +209,15 @@
         pred_info_module(PredInfo, PredModule),
         MLDS_Module = mercury_module_name_to_mlds(PredModule),
         QualifiedProcLabel = qual(MLDS_Module, PredLabel - ProcId),
-        ProcAddrArg = const(code_addr_const(proc(QualifiedProcLabel))),
+        ProcAddrRval = const(code_addr_const(proc(QualifiedProcLabel))),
+	%
+	% Convert the procedure address to a generic type.
+	% We need to use a generic type because since the actual type
+	% for the procedure will depend on how many type_info parameters
+	% it takes, which will depend on the type's arity.
+	%
+        PredParams = ml_gen_proc_params(ModuleInfo, PredId, ProcId),
+        ProcAddrArg = unop(box(mlds__func_type(PredParams)), ProcAddrRval),
 	%
 	% recursively handle the remaining procedures
 	%
Index: compiler/ml_code_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_code_gen.m,v
retrieving revision 1.20
diff -u -d -r1.20 ml_code_gen.m
--- compiler/ml_code_gen.m	1999/12/02 05:42:25	1.20
+++ compiler/ml_code_gen.m	1999/12/03 13:24:18
@@ -597,6 +597,10 @@
 	%
 :- func ml_gen_pred_label(module_info, pred_id, proc_id) = mlds__pred_label.
 
+	% Generate the function prototype for a given procedure.
+	%
+:- func ml_gen_proc_params(module_info, pred_id, proc_id) = mlds__func_params.
+
 %-----------------------------------------------------------------------------%
 %-----------------------------------------------------------------------------%
 
@@ -1366,7 +1371,8 @@
 	%
 	% insert the `closure_arg' parameter
 	%
-	{ ClosureArg = data(var("closure_arg")) - mlds__generic_env_ptr_type },
+	{ ClosureArgType = mlds__generic_env_ptr_type },
+	{ ClosureArg = data(var("closure_arg")) - ClosureArgType },
 	{ Params0 = mlds__func_params(ArgParams0, RetParam) },
 	{ Params = mlds__func_params([ClosureArg | ArgParams0], RetParam) },
 	{ Signature = mlds__get_func_signature(Params) },
@@ -1400,6 +1406,7 @@
 	ml_gen_arg_list(ArgNames, ArgLvals, ActualArgTypes, BoxedArgTypes,
 		ArgModes, Context, InputRvals, OutputLvals, ConvArgDecls,
 		ConvOutputStatements),
+	{ ClosureRval = unop(unbox(ClosureArgType), lval(ClosureLval)) },
 
 	%
 	% Prepare to generate the call, passing the closure as the first
@@ -1411,7 +1418,7 @@
 	%
 	{ ObjectRval = no },
 	{ DoGenCall = ml_gen_mlds_call(Signature, ObjectRval, FuncRval,
-		[lval(ClosureLval) | InputRvals], OutputLvals,
+		[ClosureRval | InputRvals], OutputLvals,
 		CodeModel, Context) },
 
 	( { ConvArgDecls = [], ConvOutputStatements = [] } ->
@@ -1676,8 +1683,19 @@
 			%
 			% it's an input argument
 			%
+			{ type_util__is_dummy_argument_type(CallerType) ->
+				% The variable may not have been declared,
+				% so we need to generate a dummy value for it.
+				% Using `0' here is more efficient than
+				% using private_builtin__dummy_var, which is
+				% what ml_gen_var will have generated for this
+				% variable.
+				VarRval = const(int_const(0))
+			;
+				VarRval = lval(VarLval)
+			},
 			{ ml_gen_box_or_unbox_rval(CallerType, CalleeType,
-				lval(VarLval), ArgRval) },
+				VarRval, ArgRval) },
 			{ InputRvals = [ArgRval | InputRvals1] },
 			{ OutputLvals = OutputLvals1 },
 			{ ConvDecls = ConvDecls1 },
@@ -1792,18 +1810,24 @@
 		% argument lval
 		ml_qualify_var(ArgVarName, ArgLval),
 
-		% 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.
-		{ ml_gen_box_or_unbox_rval(CalleeType, CallerType,
-			lval(ArgLval), ConvertedArgRval) },
-		{ AssignStmt = assign(VarLval, ConvertedArgRval) },
-		{ AssignStatement = mlds__statement(atomic(AssignStmt),
-			mlds__make_context(Context)) },
-		{ ConvStatements = [AssignStatement] }
+		( { 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 = [] }
+		;
+			% 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.
+			{ ml_gen_box_or_unbox_rval(CalleeType, CallerType,
+				lval(ArgLval), ConvertedArgRval) },
+			{ AssignStmt = assign(VarLval, ConvertedArgRval) },
+			{ AssignStatement = mlds__statement(atomic(AssignStmt),
+				mlds__make_context(Context)) },
+			{ ConvStatements = [AssignStatement] }
+		)
 	).
 	
 %-----------------------------------------------------------------------------%
@@ -2871,7 +2895,7 @@
 		mkword(Bits1, unop(std_unop(mkbody), const(int_const(Num1)))),
 		Context) }.
 
-ml_gen_construct_rep(type_ctor_info_constant(ModuleName, TypeName, TypeArity),
+ml_gen_construct_rep(type_ctor_info_constant(ModuleName0, TypeName, TypeArity),
 		_ConsId, Var, Args, _ArgModes, Context,
 		[], [MLDS_Statement]) -->
 	( { Args = [] } ->
@@ -2880,6 +2904,17 @@
 		{ error("ml_code_gen: type-info constant has args") }
 	),
 	ml_gen_var(Var, VarLval),
+	%
+	% Although the builtin types `int', `float', etc. are treated as part
+	% of the `builtin' module, for historical reasons they don't have
+	% any qualifiers at this point, so we need to add the `builtin'
+	% qualifier now.
+	%
+	{ ModuleName0 = unqualified("") ->
+		mercury_public_builtin_module(ModuleName)
+	;
+		ModuleName = ModuleName0
+	},
 	{ MLDS_Module = mercury_module_name_to_mlds(ModuleName) },
 	{ DataAddr = data_addr(MLDS_Module,
 		type_ctor(info, TypeName, TypeArity)) },
@@ -4057,8 +4092,6 @@
 
 	% Generate the function prototype for a procedure.
 	%
-:- func ml_gen_proc_params(module_info, pred_id, proc_id) = mlds__func_params.
-
 ml_gen_proc_params(ModuleInfo, PredId, ProcId) = FuncParams :-
 	module_info_pred_proc_info(ModuleInfo, PredId, ProcId,
 		PredInfo, ProcInfo),
@@ -4213,19 +4246,30 @@
 :- mode ml_gen_var(in, out, in, out) is det.
 
 ml_gen_var(Var, Lval) -->
-	=(MLDSGenInfo),
-	{ ml_gen_info_get_output_vars(MLDSGenInfo, OutputVars) },
-	{ ml_gen_info_get_varset(MLDSGenInfo, VarSet) },
-	{ ml_gen_info_get_module_name(MLDSGenInfo, ModuleName) },
-	{ MLDS_Module = mercury_module_name_to_mlds(ModuleName) },
-	{ VarName = ml_gen_var_name(VarSet, Var) },
-	{ VarLval = var(qual(MLDS_Module, VarName)) },
-	% output variables are passed by reference...
-	{ list__member(Var, OutputVars) ->
-		Lval = mem_ref(lval(VarLval))
+	ml_variable_type(Var, Type),
+	( { type_util__is_dummy_argument_type(Type) } ->
+		%
+		% The variable won't have been declared, so
+		% we need to generate a dummy lval for this variable.
+		%
+		{ mercury_private_builtin_module(PrivateBuiltin) },
+		{ MLDS_Module = mercury_module_name_to_mlds(PrivateBuiltin) },
+		{ Lval = var(qual(MLDS_Module, "dummy_var")) }
 	;
-		Lval = VarLval
-	}.
+		=(MLDSGenInfo),
+		{ ml_gen_info_get_output_vars(MLDSGenInfo, OutputVars) },
+		{ ml_gen_info_get_varset(MLDSGenInfo, VarSet) },
+		{ ml_gen_info_get_module_name(MLDSGenInfo, ModuleName) },
+		{ MLDS_Module = mercury_module_name_to_mlds(ModuleName) },
+		{ VarName = ml_gen_var_name(VarSet, Var) },
+		{ VarLval = var(qual(MLDS_Module, VarName)) },
+		% output variables are passed by reference...
+		{ list__member(Var, OutputVars) ->
+			Lval = mem_ref(lval(VarLval))
+		;
+			Lval = VarLval
+		}
+	).
 
 	% Lookup the types of a list of variables.
 	%
Index: compiler/mlds_to_c.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds_to_c.m,v
retrieving revision 1.17
diff -u -d -r1.17 mlds_to_c.m
--- compiler/mlds_to_c.m	1999/12/02 05:42:26	1.17
+++ compiler/mlds_to_c.m	1999/12/03 06:06:09
@@ -32,6 +32,7 @@
 
 :- implementation.
 
+:- import_module llds_out. % XXX needed for llds_out__name_mangle.
 :- import_module globals, options, passes_aux.
 :- import_module builtin_ops, c_util, modules.
 :- import_module hlds_pred. % for `pred_proc_id'.
@@ -165,7 +166,16 @@
 	io__write_string("/* :- interface. */\n"),
 	io__nl,
 	mlds_indent(Indent),
-	io__write_string("#include ""mercury_imp.h""\n\n").
+	io__write_string("#ifndef MR_HEADER_GUARD_"),
+	prog_out__write_sym_name(ModuleName),
+	io__nl,
+	mlds_indent(Indent),
+	io__write_string("#define MR_HEADER_GUARD_"),
+	prog_out__write_sym_name(ModuleName),
+	io__nl,
+	io__nl,
+	mlds_indent(Indent),
+	io__write_string("#include ""mercury.h""\n").
 
 :- pred mlds_output_src_start(indent, mercury_module_name,
 		io__state, io__state).
@@ -176,7 +186,7 @@
 	mlds_indent(Indent),
 	io__write_string("/* :- module "),
 	prog_out__write_sym_name(ModuleName),
-	io__write_string(". */\n\n"),
+	io__write_string(". */\n"),
 	mlds_indent(Indent),
 	io__write_string("/* :- implementation. */\n"),
 	io__nl,
@@ -192,6 +202,11 @@
 
 mlds_output_hdr_end(Indent, ModuleName) -->
 	mlds_indent(Indent),
+	io__write_string("#endif /* MR_HEADER_GUARD_"),
+	prog_out__write_sym_name(ModuleName),
+	io__write_string(" */\n"),
+	io__nl,
+	mlds_indent(Indent),
 	io__write_string("/* :- end_interface "),
 	prog_out__write_sym_name(ModuleName),
 	io__write_string(". */\n").
@@ -271,6 +286,13 @@
 mlds_output_decl(Indent, ModuleName, Defn) -->
 	{ Defn = mlds__defn(Name, Context, Flags, DefnBody) },
 	mlds_indent(Context, Indent),
+	( { Name = data(_) } ->
+		% XXX for private data and private functions,
+		% we should use "static"
+		io__write_string("extern ")
+	;
+		[]
+	),
 	mlds_output_decl_flags(Flags),
 	mlds_output_decl_body(Indent, qual(ModuleName, Name), DefnBody).
 
@@ -589,30 +611,27 @@
 
 mlds_output_fully_qualified_name(qual(ModuleName, Name), OutputFunc) -->
 	{ SymName = mlds_module_name_to_sym_name(ModuleName) },
-	{ Separator = "__" },
-	{ sym_name_to_string(SymName, Separator, ModuleNameString) },
-	io__write_string(ModuleNameString),
-	io__write_string(Separator),
+	{ llds_out__sym_name_mangle(SymName, MangledModuleName) },
+	io__write_string(MangledModuleName),
+	io__write_string("__"),
 	OutputFunc(Name).
 
 :- pred mlds_output_module_name(mercury_module_name, io__state, io__state).
 :- mode mlds_output_module_name(in, di, uo) is det.
 
 mlds_output_module_name(ModuleName) -->
-	{ Separator = "__" },
-	{ sym_name_to_string(ModuleName, Separator, ModuleNameString) },
-	io__write_string(ModuleNameString).
+	{ llds_out__sym_name_mangle(ModuleName, MangledModuleName) },
+	io__write_string(MangledModuleName).
 
 :- pred mlds_output_name(mlds__entity_name, io__state, io__state).
 :- mode mlds_output_name(in, di, uo) is det.
 
-% XXX FIXME!
-% XXX we should escape special characters
 % XXX we should avoid appending the arity, modenum, and seqnum
 %     if they are not needed.
 
 mlds_output_name(type(Name, Arity)) -->
-	io__format("%s_%d", [s(Name), i(Arity)]).
+	{ llds_out__name_mangle(Name, MangledName) },
+	io__format("%s_%d", [s(MangledName), i(Arity)]).
 mlds_output_name(data(DataName)) -->
 	mlds_output_data_name(DataName).
 mlds_output_name(function(PredLabel, ProcId, MaybeSeqNum, _PredId)) -->
@@ -632,7 +651,8 @@
 	( { PredOrFunc = predicate, Suffix = "p" }
 	; { PredOrFunc = function, Suffix = "f" }
 	),
-	io__format("%s_%d_%s", [s(Name), i(Arity), s(Suffix)]),
+	{ llds_out__name_mangle(Name, MangledName) },
+	io__format("%s_%d_%s", [s(MangledName), i(Arity), s(Suffix)]),
 	( { MaybeDefiningModule = yes(DefiningModule) } ->
 		io__write_string("_in__"),
 		mlds_output_module_name(DefiningModule)
@@ -641,7 +661,9 @@
 	).
 mlds_output_pred_label(special_pred(PredName, MaybeTypeModule,
 		TypeName, TypeArity)) -->
-	io__write_string(PredName),
+	{ llds_out__name_mangle(PredName, MangledPredName) },
+	{ llds_out__name_mangle(TypeName, MangledTypeName) },
+	io__write_string(MangledPredName),
 	io__write_string("__"),
 	( { MaybeTypeModule = yes(TypeModule) } ->
 		mlds_output_module_name(TypeModule),
@@ -649,25 +671,25 @@
 	;
 		[]
 	),
-	io__write_string(TypeName),
+	io__write_string(MangledTypeName),
 	io__write_string("_"),
 	io__write_int(TypeArity).
 
 :- pred mlds_output_data_name(mlds__data_name, io__state, io__state).
 :- mode mlds_output_data_name(in, di, uo) is det.
 
-% XX some of these should probably be escaped
-
 mlds_output_data_name(var(Name)) -->
-	io__write_string(Name).
+	{ llds_out__name_mangle(Name, MangledName) },
+	io__write_string(MangledName).
 mlds_output_data_name(common(Num)) -->
 	io__write_string("common_"),
 	io__write_int(Num).
 mlds_output_data_name(type_ctor(BaseData, Name, Arity)) -->
+	{ llds_out__name_mangle(Name, MangledName) },
 	io__write_string("base_type_"),
 	io__write(BaseData),
 	io__write_string("_"),
-	io__write_string(Name),
+	io__write_string(MangledName),
 	io__write_string("_"),
 	io__write_int(Arity).
 mlds_output_data_name(base_typeclass_info(_ClassId, _InstanceId)) -->
@@ -1698,9 +1720,13 @@
 :- mode mlds_output_data_addr(in, di, uo) is det.
 
 mlds_output_data_addr(data_addr(ModuleName, DataName)) -->
+	% XXX the cast to (Word) is needed for base_type_infos,
+	% but it might not be right for other data_addr values.
+	io__write_string("((Word) &"),
 	mlds_output_module_name(mlds_module_name_to_sym_name(ModuleName)),
 	io__write_string("__"),
-	mlds_output_data_name(DataName).
+	mlds_output_data_name(DataName),
+	io__write_string(")").
 
 %-----------------------------------------------------------------------------%
 %

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