[m-dev.] for review: clean up MLDS init functions

Fergus Henderson fjh at cs.mu.OZ.AU
Thu Nov 9 02:43:27 AEDT 2000


Zoltan, could you please review this one?

----------

Estimated hours taken: 1

Modify the MLDS back-end so that it generates more readable
code for the module initialization functions.

compiler/mlds_to_c.m:
	In the initialization functions, output calls to MR_init_entry()
	only if they are needed (i.e. if profiling is enabled).
	Likewise output the code that ensures that the initialization
	is only run once only if the initialization is non-empty.
	Use `bool', `TRUE', and `FALSE' rather than `int', 0, and 1
	for the `initialised' variable.

compiler/ml_code_gen.m:
	Document the principle that the MLDS back-end should avoid
	relying on macros and conditional compilation, to improve
	readability and to make it easier to target languages like Java.

runtime/mercury_conf_param.h:
runtime/mercury_goto.h:
	Add some comments about the MLDS back-end.

Workspace: /home/pgrad/fjh/ws/hg
Index: compiler/ml_code_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/ml_code_gen.m,v
retrieving revision 1.64
diff -u -d -r1.64 ml_code_gen.m
--- compiler/ml_code_gen.m	2000/11/08 07:23:06	1.64
+++ compiler/ml_code_gen.m	2000/11/08 08:47:54
@@ -14,8 +14,20 @@
 % very low-level code.  This code generator instead compiles to MLDS,
 % generating much higher-level code than the original code generator.
 
-% For nondeterministic predicates, we generate code using an explicit
-% continuation passing style.  Each nondeterministic predicate gets
+% One of the aims of the MLDS is to be able to generated human-readable
+% code in languages like C or Java.  This means that unlike the LLDS back-end,
+% we do not want to rely on macros or conditional compilation.  If the
+% final code is going to depend on the setting of some compilation option,
+% our philosophy is to reflect that change in the generated MLDS and C code
+% where possible, rather than generating C code which calls macros that do
+% different things in different grades.  This is important both for
+% readability of the generated code, and to make sure that we can easily
+% adapt the MLDS code generator to target languages like Java that don't
+% support macros or conditional compilation.
+
+% A big challenge in generating MLDS code is handling nondeterminism.
+% For nondeterministic procedures, we generate code using an explicit
+% continuation passing style.  Each nondeterministic procedures gets
 % translated into a function which takes an extra parameter which is a
 % function pointer that points to the success continuation.  On success,
 % the function calls its success continuation, and on failure it returns.
@@ -621,11 +633,11 @@
 %-----------------------------------------------------------------------------%
 
 
-% XXX This back-end is still not yet complete.
+% This back-end is still not yet 100% complete.
 %
 % Done:
 %	- function prototypes
-%	- code generation for det, semidet, and nondet predicates:
+%	- code generation for det, semidet, and nondet predicates/functions:
 %		- conjunctions
 %		- disjunctions
 %		- negation
Index: compiler/mlds_to_c.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mlds_to_c.m,v
retrieving revision 1.65
diff -u -d -r1.65 mlds_to_c.m
--- compiler/mlds_to_c.m	2000/11/08 07:23:08	1.65
+++ compiler/mlds_to_c.m	2000/11/08 12:40:08
@@ -164,6 +164,22 @@
 	Defn = mlds__defn(Name, _Context, _Flags, _Body),
 	Name = type(_, _).
 
+:- pred defn_is_function(mlds__defn).
+:- mode defn_is_function(in) is semidet.
+
+defn_is_function(Defn) :-
+	Defn = mlds__defn(Name, _Context, _Flags, _Body),
+	Name = function(_, _, _, _).
+
+:- pred defn_is_type_ctor_info(mlds__defn).
+:- mode defn_is_type_ctor_info(in) is semidet.
+
+defn_is_type_ctor_info(Defn) :-
+	Defn = mlds__defn(_Name, _Context, _Flags, Body),
+	Body = mlds__data(Type, _),
+	Type = mlds__rtti_type(RttiName),
+	RttiName = type_ctor_info.
+
 :- pred defn_is_commit_type_var(mlds__defn).
 :- mode defn_is_commit_type_var(in) is semidet.
 
@@ -237,13 +253,17 @@
 	{ list__filter(defn_is_type, PrivateDefns, PrivateTypeDefns,
 		PrivateNonTypeDefns) },
 	{ list__filter(defn_is_type, Defns, _TypeDefns, NonTypeDefns) },
+	{ list__filter(defn_is_function, NonTypeDefns, FuncDefns) },
+	{ list__filter(defn_is_type_ctor_info, NonTypeDefns,
+		TypeCtorInfoDefns) },
 	{ MLDS_ModuleName = mercury_module_name_to_mlds(ModuleName) },
 	mlds_output_defns(Indent, MLDS_ModuleName, PrivateTypeDefns), io__nl,
 	mlds_output_decls(Indent, MLDS_ModuleName, PrivateNonTypeDefns), io__nl,
 
 	mlds_output_c_defns(MLDS_ModuleName, Indent, ForeignCode), io__nl,
 	mlds_output_defns(Indent, MLDS_ModuleName, NonTypeDefns), io__nl,
-	mlds_output_init_fn_defns(MLDS_ModuleName, NonTypeDefns, Defns), io__nl,
+	mlds_output_init_fn_defns(MLDS_ModuleName, FuncDefns,
+		TypeCtorInfoDefns), io__nl,
 	mlds_output_src_end(Indent, ModuleName).
 
 :- pred mlds_output_hdr_start(indent, mercury_module_name,
@@ -345,28 +365,43 @@
 :- pred mlds_output_init_fn_defns(mlds_module_name::in, mlds__defns::in,
 		mlds__defns::in, io__state::di, io__state::uo) is det.
 
-mlds_output_init_fn_defns(ModuleName, NonTypeDefns, Defns) -->
+mlds_output_init_fn_defns(ModuleName, FuncDefns, TypeCtorInfoDefns) -->
 	output_init_fn_name(ModuleName, ""),
 	io__write_string("\n{\n"),
-	io__write_strings(["\tstatic int initialised = 0;\n",
-			"\tif (initialised) return;\n",
-			"\tinitialised = 1;\n\n"]),
-	mlds_output_init_main_fn(ModuleName, NonTypeDefns),
-	io__write_string("\n}\n"),
+	io_get_globals(Globals),
+	(
+		{ need_to_init_entries(Globals) },
+		{ FuncDefns \= [] }
+	->
+		io__write_strings(["\tstatic bool initialised = FALSE;\n",
+				"\tif (initialised) return;\n",
+				"\tinitialised = TRUE;\n\n"]),
+		mlds_output_calls_to_init_entry(ModuleName, FuncDefns)
+	;
+		[]
+	),
+	io__write_string("}\n\n"),
 
 	output_init_fn_name(ModuleName, "_type_tables"),
 	io__write_string("\n{\n"),
-	io__write_strings(["\tstatic int initialised = 0;\n",
-			"\tif (initialised) return;\n",
-			"\tinitialised = 1;\n\n"]),
-	mlds_output_init_type_table_fn(ModuleName, Defns),
-	io__write_string("\n}\n"),
+	(
+		{ TypeCtorInfoDefns \= [] }
+	->
+		io__write_strings(["\tstatic bool initialised = FALSE;\n",
+				"\tif (initialised) return;\n",
+				"\tinitialised = TRUE;\n\n"]),
+		mlds_output_calls_to_register_tci(ModuleName,
+			TypeCtorInfoDefns)
+	;
+		[]
+	),
+	io__write_string("}\n\n"),
 
 	output_init_fn_name(ModuleName, "_debugger"),
 	io__write_string("\n{\n"),
 	io__write_string(
 	    "\tMR_fatal_error(""debugger initialization in MLDS grade"");\n"),
-	io__write_string("\n}\n").
+	io__write_string("}\n").
 
 :- pred output_init_fn_name(mlds_module_name::in, string::in,
 		io__state::di, io__state::uo) is det.
@@ -391,43 +426,45 @@
 	io__write_string(Suffix),
 	io__write_string("(void)").
 
-:- pred mlds_output_init_main_fn(mlds_module_name::in, mlds__defns::in,
+:- pred need_to_init_entries(globals::in) is semidet.
+need_to_init_entries(Globals) :-
+	% We only need to output calls to MR_init_entry() if profiling is
+	% enabled.  (It would be OK to output the calls regardless, since
+	% they will macro-expand to nothing if profiling is not enabled,
+	% but for readability of the generated code we prefer not to.)
+	( Option = profile_calls
+	; Option = profile_time
+	; Option = profile_memory
+	),
+	globals__lookup_bool_option(Globals, Option, yes).
+
+	% Generate calls to MR_init_entry() for the specified functions.
+	%
+:- pred mlds_output_calls_to_init_entry(mlds_module_name::in, mlds__defns::in,
 		io__state::di, io__state::uo) is det.
 
-mlds_output_init_main_fn(_ModuleName, []) --> [].
-mlds_output_init_main_fn(ModuleName, [Defn | Defns]) --> 
-	{ Defn = mlds__defn(EntityName, _Context, _Flags, _EntityDefn) },
-	(
-		{ EntityName = mlds__function(_, _, _, _) }
-	->
-		{ QualName = qual(ModuleName, EntityName) },
-		io__write_string("\tMR_init_entry("),
-		mlds_output_fully_qualified_name(QualName),
-		io__write_string(");\n")
-	;
-		[]
-	),
-	mlds_output_init_main_fn(ModuleName, Defns).
+mlds_output_calls_to_init_entry(_ModuleName, []) --> [].
+mlds_output_calls_to_init_entry(ModuleName, [FuncDefn | FuncDefns]) --> 
+	{ FuncDefn = mlds__defn(EntityName, _, _, _) },
+	io__write_string("\tMR_init_entry("),
+	mlds_output_fully_qualified_name(qual(ModuleName, EntityName)),
+	io__write_string(");\n"),
+	mlds_output_calls_to_init_entry(ModuleName, FuncDefns).
 
-:- pred mlds_output_init_type_table_fn(mlds_module_name::in, mlds__defns::in,
+	% Generate calls to MR_register_type_ctor_info() for the specified
+	% type_ctor_infos.
+	%
+:- pred mlds_output_calls_to_register_tci(mlds_module_name::in, mlds__defns::in,
 		io__state::di, io__state::uo) is det.
 
-mlds_output_init_type_table_fn(_ModuleName, []) --> [].
-mlds_output_init_type_table_fn(ModuleName, [Defn | Defns]) --> 
-	{ Defn = mlds__defn(EntityName, _Context, _Flags, EntityDefn) },
-	(
-		{ EntityDefn = mlds__data(Type, _) },
-		{ Type = mlds__rtti_type(RttiName) },
-		{ RttiName = type_ctor_info }
-	->
-		{ QualName = qual(ModuleName, EntityName) },
-		io__write_string("\tMR_register_type_ctor_info(&"),
-		mlds_output_fully_qualified_name(QualName),
-		io__write_string(");\n")
-	;
-		[]
-	),
-	mlds_output_init_type_table_fn(ModuleName, Defns).
+mlds_output_calls_to_register_tci(_ModuleName, []) --> [].
+mlds_output_calls_to_register_tci(ModuleName,
+		[TypeCtorInfoDefn | TypeCtorInfoDefns]) --> 
+	{ TypeCtorInfoDefn = mlds__defn(EntityName, _, _, _) },
+	io__write_string("\tMR_register_type_ctor_info(&"),
+	mlds_output_fully_qualified_name(qual(ModuleName, EntityName)),
+	io__write_string(");\n"),
+	mlds_output_calls_to_register_tci(ModuleName, TypeCtorInfoDefns).
 
 %-----------------------------------------------------------------------------%
 %
Index: runtime/mercury_conf_param.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_conf_param.h,v
retrieving revision 1.40
diff -u -d -r1.40 mercury_conf_param.h
--- runtime/mercury_conf_param.h	2000/11/07 08:58:33	1.40
+++ runtime/mercury_conf_param.h	2000/11/08 08:18:09
@@ -252,6 +252,13 @@
 **			   (this also means the initialization code needs
 **			   to be run some time before the first use of the
 **			   label table).
+**
+** Note that for the MLDS back-end, the calls to MR_init_entry()
+** that insert the function addresses in the label table are only
+** output if the right compiler options are enabled.  So if you change
+** the condition of this `#ifdef', and you want your changes to apply
+** to the MLDS back-end too, you may also need to change the
+** `need_to_init_entries' predicate in compiler/mlds_to_c.m.
 */
 
 #ifdef MR_INSERT_LABELS
Index: runtime/mercury_goto.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_goto.h,v
retrieving revision 1.24
diff -u -d -r1.24 mercury_goto.h
--- runtime/mercury_goto.h	2000/10/09 02:07:51	1.24
+++ runtime/mercury_goto.h	2000/11/08 08:18:29
@@ -82,6 +82,14 @@
   #define make_local(n, a, l)		/* nothing */
 #endif
 
+/*
+** Note that for the MLDS back-end, the calls to MR_init_entry(),
+** which eventually expand to make_entry(), are only output if
+** the right compiler options are enabled.  So if you change the
+** condition of this `#ifdef', and you want your changes to apply
+** to the MLDS back-end too, you may also need to change the
+** `need_to_init_entries' predicate in compiler/mlds_to_c.m.
+*/
 #if defined(MR_INSERT_LABELS) || defined(PROFILE_CALLS)
   #define make_entry(n, a, l)		make_entry_ai(n, a, l)
 #else

-- 
Fergus Henderson <fjh at cs.mu.oz.au>  |  "I have always known that the pursuit
                                    |  of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh>  |     -- 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