diff: fix bug with nested modules & intermod opt

Fergus Henderson fjh at cs.mu.OZ.AU
Mon Nov 2 18:17:03 AEDT 1998


As usual, if anyone wants to review this one, please go ahead...

--------------------

Estimated hours taken: 20

Fix a bug with intermodule optimization of nested modules.

Previously, the compiler used to just label any
predicates defined in a module containing sub-modules
as `exported', since they may be needed by the separately-compiled
sub-modules.  However, this is a little bit of a lie,
and it turns out that it doesn't work.  The fix is
to use a new status `exported_to_submodules' for this case.

compiler/prog_data.m:
	Add a new pseudo-declaration ":- private_interface",
	used to mark items in an ":- implementation" section
	that will be exported to submodules.

compiler/modules.m:
	Put declarations from modules containing sub-modules into
	`private_interface' sections rather than into `interface' sections.

compiler/hlds_pred.m:
	Add a new alternative `exported_to_submodules' to the
	`import_status' data type.  Add several new procedures
	for testing particular aspects of this type.

compiler/module_qual.m:
	Set the import_status of items in a `private_interface'
	section to `exported_to_submodules'.

compiler/intermod.m:
	Handle procedures with status `exported_to_submodules'
	specially.  Also reorganize the code here a bit to make
	it more maintainable.

compiler/base_type_info.m:
compiler/base_type_info.m:
compiler/base_typeclass_info.m:
compiler/code_util.m:
compiler/dead_proc_elim.m:
compiler/hlds_out.m:
compiler/make_hlds.m:
compiler/termination.m:
compiler/unused_args.m:
	Minor changes to reflect the above changes to data-structures;
	in particular, use the new procedures defined in hlds_pred.m
	instead of hard-coded tests.

tests/hard_coded/Mmakefile:
tests/hard_coded/nested_intermod.m:
tests/hard_coded/nested_intermod_main.m:
tests/hard_coded/nested_intermod_main.exp:
	Add a regression test for the bug mentioned above.

Index: compiler/base_type_info.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/base_type_info.m,v
retrieving revision 1.19
diff -u -r1.19 base_type_info.m
--- base_type_info.m	1998/09/03 11:13:23	1.19
+++ base_type_info.m	1998/10/27 17:39:57
@@ -148,13 +148,7 @@
 but linkage/2 in llds_out.m requires that we make them all exported
 if any of them are exported, so that we can compute the linkage
 from the data_name, for use in forward declarations.
-	( 	
-		( Status = exported ; Status = abstract_exported )
-	->
-		Exported = yes
-	;
-		Exported = no
-	),
+	status_is_exported(Status, Exported),
 ******/
 	Exported = yes,
 
Index: compiler/base_typeclass_info.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/base_typeclass_info.m,v
retrieving revision 1.6
diff -u -r1.6 base_typeclass_info.m
--- base_typeclass_info.m	1998/09/22 16:12:35	1.6
+++ base_typeclass_info.m	1998/10/27 16:32:11
@@ -78,15 +78,7 @@
 	(
 			% Only make the base_typeclass_info if the instance
 			% declaration originally came from _this_ module.
-		(
-			ImportStatus = exported
-		;
-			ImportStatus = abstract_exported 
-		;
-			ImportStatus = pseudo_exported
-		;
-			ImportStatus = local
-		)
+		status_defined_in_this_module(ImportStatus, yes)
 	->
 
 		base_typeclass_info__make_instance_string(InstanceTypes, 
Index: compiler/code_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/code_util.m,v
retrieving revision 1.101
diff -u -r1.101 code_util.m
--- code_util.m	1998/09/10 06:50:58	1.101
+++ code_util.m	1998/10/27 16:32:14
@@ -198,13 +198,7 @@
 	module_info_preds(ModuleInfo, Preds),
 	map__lookup(Preds, PredId, PredInfo),
 	(
-		(
-			pred_info_is_exported(PredInfo)
-		;
-			pred_info_is_pseudo_exported(PredInfo),
-			% only the (in, in) mode of a unification is exported
-			hlds_pred__in_in_unification_proc_id(ProcId)
-		)
+		procedure_is_exported(PredInfo, ProcId)
 	->
 		(
 			Immed = no,
Index: compiler/dead_proc_elim.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/dead_proc_elim.m,v
retrieving revision 1.42
diff -u -r1.42 dead_proc_elim.m
--- dead_proc_elim.m	1998/09/22 16:12:48	1.42
+++ dead_proc_elim.m	1998/10/27 16:32:16
@@ -179,9 +179,8 @@
 		Arity, _Status, _Elim, _Procs),
 	(
 		% XXX: We'd like to do this, but there are problems.
-		% ( Status = exported
-		% ; Status = abstract_exported
-		% )
+		% status_is_exported(Status, yes)
+		%
 		% We need to do more thorough analysis of the
 		% reachability of the special predicates, in general,
 		% because using arg/3 allows us to get at base_type_info
@@ -228,11 +227,7 @@
 	(
 			% We only need the instance declarations which were
 			% made in this module.
-		( ImportStatus = exported
-		; ImportStatus = abstract_exported 
-		; ImportStatus = pseudo_exported
-		; ImportStatus = local
-		)
+		status_defined_in_this_module(ImportStatus, yes)
 	->
 		get_instance_pred_procs2(PredProcIds, Queue0, Queue, 
 			Needed0, Needed)
Index: compiler/hlds_out.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_out.m,v
retrieving revision 1.207
diff -u -r1.207 hlds_out.m
--- hlds_out.m	1998/10/16 10:37:29	1.207
+++ hlds_out.m	1998/10/27 16:32:23
@@ -1729,6 +1729,8 @@
 	io__write_string("opt_imported").
 hlds_out__write_import_status(pseudo_imported) -->
 	io__write_string("pseudo_imported").
+hlds_out__write_import_status(exported_to_submodules) -->
+	io__write_string("exported_to_submodules").
 
 :- pred hlds_out__write_var_types(int, varset, bool, map(var, type), varset,
 	io__state, io__state).
Index: compiler/hlds_pred.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/hlds_pred.m,v
retrieving revision 1.54
diff -u -r1.54 hlds_pred.m
--- hlds_pred.m	1998/10/23 00:40:06	1.54
+++ hlds_pred.m	1998/10/30 06:00:30
@@ -170,7 +170,31 @@
 	;	pseudo_exported % the converse of pseudo_imported
 				% this means that only the (in, in) mode
 				% of a unification is exported
-	;	local.		% defined in the implementation of this module
+	;	exported_to_submodules
+				% defined in the implementation of this module,
+				% and thus in a sense local,
+				% but the module contains sub-modules,
+				% so the entity needs to be exported
+				% to those sub-modules
+	;	local.		% defined in the implementation of this module,
+				% and the module does not contain any
+				% sub-modules.
+
+	% returns yes if the status indicates that the item was
+	% in any way exported -- that is, if it could be used
+	% by any other module, or by sub-modules of this module.
+:- pred status_is_exported(import_status::in, bool::out) is det.
+
+	% returns yes if the status indicates that the item was
+	% in any way imported -- that is, if it was defined in
+	% some other module, or in a sub-module of this module.
+	% This is the opposite of status_defined_in_this_module.
+:- pred status_is_imported(import_status::in, bool::out) is det.
+
+	% returns yes if the status indicates that the item was
+	% defined in this module.  This is the opposite of
+	% status_is_imported.
+:- pred status_defined_in_this_module(import_status::in, bool::out) is det.
 
 	% N-ary functions are converted into N+1-ary predicates.
 	% (Clauses are converted in make_hlds, but calls to functions
@@ -388,10 +412,19 @@
 
 :- pred pred_info_is_pseudo_imported(pred_info::in) is semidet.
 
+	% pred_info_is_exported does *not* include predicates which are
+	% exported_to_submodules or pseudo_exported
 :- pred pred_info_is_exported(pred_info::in) is semidet.
 
+:- pred pred_info_is_exported_to_submodules(pred_info::in) is semidet.
+
 :- pred pred_info_is_pseudo_exported(pred_info::in) is semidet.
 
+	% procedure_is_exported includes all modes of exported or
+	% exported_to_submodules predicates, plus the in-in mode
+	% for pseudo_exported unification predicates.
+:- pred procedure_is_exported(pred_info::in, proc_id::in) is semidet.
+
 	% Set the import_status of the predicate to `imported'.
 	% This is used for `:- external(foo/2).' declarations.
 
@@ -503,6 +536,30 @@
 
 invalid_proc_id(-1).
 
+status_is_exported(imported,			no).
+status_is_exported(abstract_imported,		no).
+status_is_exported(pseudo_imported,		no).
+status_is_exported(opt_imported,		no).
+status_is_exported(exported,			yes).
+status_is_exported(abstract_exported,		yes).
+status_is_exported(pseudo_exported,		yes).
+status_is_exported(exported_to_submodules,	yes).
+status_is_exported(local,			no).
+
+status_is_imported(Status, Imported) :-
+	status_defined_in_this_module(Status, InThisModule),
+	bool__not(InThisModule, Imported).
+
+status_defined_in_this_module(imported,			no).
+status_defined_in_this_module(abstract_imported,	no).
+status_defined_in_this_module(pseudo_imported,		no).
+status_defined_in_this_module(opt_imported,		no).
+status_defined_in_this_module(exported,			yes).
+status_defined_in_this_module(abstract_exported,	yes).
+status_defined_in_this_module(pseudo_exported,		yes).
+status_defined_in_this_module(exported_to_submodules,	yes).
+status_defined_in_this_module(local,			yes).
+
 	% The information specific to a predicate, as opposed to a procedure.
 	% (Functions count as predicates.)
 
@@ -626,9 +683,15 @@
 
 pred_info_exported_procids(PredInfo, ProcIds) :-
 	pred_info_import_status(PredInfo, ImportStatus),
-	( ImportStatus = exported ->
+	(
+		( ImportStatus = exported
+		; ImportStatus = exported_to_submodules
+		)
+	->
 		pred_info_procids(PredInfo, ProcIds)
-	; ImportStatus = pseudo_exported ->
+	;
+		ImportStatus = pseudo_exported
+	->
 		ProcIds = [0]
 	;
 		ProcIds = []
@@ -699,9 +762,23 @@
 	pred_info_import_status(PredInfo, ImportStatus),
 	ImportStatus = exported.
 
+pred_info_is_exported_to_submodules(PredInfo) :-
+	pred_info_import_status(PredInfo, ImportStatus),
+	ImportStatus = exported_to_submodules.
+
 pred_info_is_pseudo_exported(PredInfo) :-
 	pred_info_import_status(PredInfo, ImportStatus),
 	ImportStatus = pseudo_exported.
+
+procedure_is_exported(PredInfo, ProcId) :-
+	(
+		pred_info_is_exported(PredInfo)
+	;
+		pred_info_is_exported_to_submodules(PredInfo)
+	;
+		pred_info_is_pseudo_exported(PredInfo),
+		hlds_pred__in_in_unification_proc_id(ProcId)
+	).
 
 pred_info_mark_as_external(PredInfo0, PredInfo) :-
 	PredInfo0 = predicate(A, B, C, D, E, F, G, H, I, _, K, L, M, N, O, P,
Index: compiler/intermod.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/intermod.m,v
retrieving revision 1.60
diff -u -r1.60 intermod.m
--- intermod.m	1998/09/24 06:00:29	1.60
+++ intermod.m	1998/11/02 06:26:36
@@ -168,6 +168,11 @@
 	{ module_info_preds(ModuleInfo0, PredTable0) },
 	{ map__lookup(PredTable0, PredId, PredInfo0) },
 	(
+		%
+		% note: we can't include exported_to_submodules predicates
+		% in the `.opt' file, for reasons explained in
+		% the comments for intermod_info_add_proc
+		%
 		{ pred_info_is_exported(PredInfo0) },
 		{ pred_info_procids(PredInfo0, [ProcId | _ProcIds]) },
 		{ pred_info_procedures(PredInfo0, Procs) },
@@ -323,7 +328,7 @@
 		{ map__search(TypeTable, TypeId, TypeDefn) }
 	->
 		{ hlds_data__get_type_defn_status(TypeDefn, Status) },
-		( { Status = imported ; Status = abstract_imported } ->
+		( { status_is_imported(Status, yes) } ->
 			{ type_util__type_id_module(ModuleInfo,
 						TypeId, Module) },
 			intermod_info_get_modules(Modules0),
@@ -481,8 +486,19 @@
 		{ Cases = Cases0 }
 	).
 
-	% If a proc called within an exported proc is non-local, we need
-	% to include an :- import_module declaration.
+	%
+	% intermod_info_add_proc/4 tries to do what ever is necessary to
+	% ensure that the specified predicate will be exported,
+	% so that it can be called from clauses in the `.opt' file.
+	% If it can't, then it returns DoWrite = no, which will
+	% prevent the caller from being included in the `.opt' file.
+	%
+	% If a proc called within an exported proc is local, we need
+	% to add a declaration for the called proc to the .opt file.
+	% If a proc called within an exported proc is from a different
+	% module, we need to include an `:- import_module' declaration
+	% to import that module in the `.opt' file.
+	%
 :- pred intermod_info_add_proc(pred_id::in, bool::out,
 		intermod_info::in, intermod_info::out) is det.
 
@@ -493,52 +509,107 @@
 	{ pred_info_procids(PredInfo, ProcIds) },
 	{ pred_info_get_markers(PredInfo, Markers) },
 	(
-		{ check_marker(Markers, infer_modes) }
-	->
-		% Don't write this pred if it calls preds without mode decls.
-		{ DoWrite = no }
-	;
-		% Don't output declarations for compiler generated procedures,
-		% since they will be recreated in the calling module.
+		%
+		% Calling compiler-generated procedures is fine;
+		% we don't need to output declarations for them to
+		% the `.opt' file, since they will be recreated every
+		% time anyway.
+		%
 		{ code_util__compiler_generated(PredInfo) }
 	->
 		{ DoWrite = yes }
 	;
+		%
+		% Don't write the caller to the `.opt' file if it calls
+		% a pred without mode or determinism decls, because we'd
+		% need to include the mode decls for the callee in the `.opt'
+		% file and (since writing the `.opt' file happens before mode
+		% inference) we can't do that because we don't know what
+		% the modes are.
+		%
+		% XXX This prevents intermodule optimizations in such cases,
+		% which is a pity.
+		%
 		{
-		pred_info_procedures(PredInfo, Procs),
-		list__member(ProcId, ProcIds),
-		map__lookup(Procs, ProcId, ProcInfo),
-		proc_info_declared_determinism(ProcInfo, no)
+			check_marker(Markers, infer_modes)
+		;
+			pred_info_procedures(PredInfo, Procs),
+			list__member(ProcId, ProcIds),
+			map__lookup(Procs, ProcId, ProcInfo),
+			proc_info_declared_determinism(ProcInfo, no)
 		}
 	->
-		% Don't write this pred if it calls preds
-		% without determinism decls.
 		{ DoWrite = no }
 	;
+		%
+		% Don't write this pred if it is exported to submodules,
+		% because we don't know whether or not to write out the
+		% pred decl to the .opt file -- if we write it out, you
+		% can get spurious "duplicate declaration" errors when
+		% compiling the submodules, and if we don't, then you
+		% can get spurious "undeclared predicate" errors when
+		% compiling other modules which import the parent module.
+		%
+		% XXX This prevents intermodule optimization in those
+		% cases, which is a pity.
+		%
+		{ Status = exported_to_submodules }
+	->
+		{ DoWrite = no }
+	;
+		%
+		% If a pred whose code we're going to put in the `.opt' file
+		% calls a predicate which is local to that module, then
+		% we need to put the declaration for the called predicate
+		% in the `.opt' file.
+		%
 		{ Status = local }
 	->
+		{ DoWrite = yes },
 		intermod_info_get_pred_decls(PredDecls0),
 		{ set__insert(PredDecls0, PredId, PredDecls) },
-		intermod_info_set_pred_decls(PredDecls),
-		{ DoWrite = yes }
+		intermod_info_set_pred_decls(PredDecls)
 	;
-		{ Status = imported }
+		{ Status = imported
+		; Status = opt_imported
+		}
 	->
 		{ DoWrite = yes },
-		{ pred_info_module(PredInfo, Module) },
-		( { module_info_name(ModuleInfo, Module) } ->
-			% :- external pred - add decl 
+		{ module_info_name(ModuleInfo, ThisModule) },
+		{ pred_info_module(PredInfo, PredModule) },
+		(
+			{ PredModule = ThisModule }
+		->
+			%
+			% This can happen in the case of a local predicate
+			% which has been declared as external using a
+			% `:- external(Name/Arity)' declaration, e.g.
+			% because it is implemented as low-level C code.
+			%
+			% We treat these the same as local predicates.
+			%
 			intermod_info_get_pred_decls(PredDecls0),
 			{ set__insert(PredDecls0, PredId, PredDecls) },
 			intermod_info_set_pred_decls(PredDecls)
 		;	
+			%
 			% imported pred - add import for module
+			%
 			intermod_info_get_modules(Modules0),
-			{ set__insert(Modules0, Module, Modules) },
+			{ set__insert(Modules0, PredModule, Modules) },
 			intermod_info_set_modules(Modules)
 		)
 	;
+		%
+		% if a pred whose code we're going to put in the .opt file
+		% calls a predicate which is exported, then we don't
+		% need to do anything special
+		%
+		{ Status = exported }
+	->
 		{ DoWrite = yes }
+	;
+		{ error("intermod_info_add_proc: unexpected status") }
 	).
 
 	% Resolve overloading and module qualify everything in a unify_rhs.
Index: compiler/make_hlds.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/make_hlds.m,v
retrieving revision 1.275
diff -u -r1.275 make_hlds.m
--- make_hlds.m	1998/09/24 09:44:36	1.275
+++ make_hlds.m	1998/10/29 12:41:37
@@ -464,6 +464,8 @@
 		item_status(exported, may_be_unqualified)).
 module_defn_update_import_status(implementation,
 		item_status(local, may_be_unqualified)).
+module_defn_update_import_status(private_interface,
+		item_status(exported_to_submodules, may_be_unqualified)).
 module_defn_update_import_status(imported, 
 		item_status(imported, may_be_unqualified)).
 module_defn_update_import_status(used, 
@@ -1858,7 +1860,8 @@
 	(
 		{ MaybeDet = no }
 	->
-		( { pred_info_is_exported(PredInfo0) } ->
+		{ pred_info_import_status(PredInfo0, ImportStatus) },
+		( { status_is_exported(ImportStatus, yes) } ->
 			unspecified_det_for_exported(PredName, Arity,
 				PredOrFunc, MContext)
 		;
Index: compiler/module_qual.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/module_qual.m,v
retrieving revision 1.39
diff -u -r1.39 module_qual.m
--- module_qual.m	1998/08/07 00:49:17	1.39
+++ module_qual.m	1998/10/27 16:32:34
@@ -205,6 +205,8 @@
 process_module_defn(include_module(_), Info, Info).
 process_module_defn(interface, Info0, Info) :-
 	mq_info_set_import_status(Info0, exported, Info).
+process_module_defn(private_interface, Info0, Info) :-
+	mq_info_set_import_status(Info0, exported_to_submodules, Info).
 process_module_defn(implementation, Info0, Info) :-
 	mq_info_set_import_status(Info0, local, Info).
 process_module_defn(imported, Info0, Info) :-
@@ -363,6 +365,8 @@
 	mq_info_set_import_status(Info0, exported, Info).
 update_import_status(implementation, Info0, Info, yes) :-
 	mq_info_set_import_status(Info0, local, Info).
+update_import_status(private_interface, Info0, Info, yes) :-
+	mq_info_set_import_status(Info0, exported_to_submodules, Info).
 update_import_status(imported, Info, Info, no).
 update_import_status(used, Info, Info, no).
 update_import_status(external(_), Info, Info, yes).
Index: compiler/modules.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/modules.m,v
retrieving revision 1.87
diff -u -r1.87 modules.m
--- modules.m	1998/09/29 05:10:27	1.87
+++ modules.m	1998/10/28 09:23:07
@@ -991,15 +991,18 @@
 		PublicChildren, FactDeps, Module0) },
 
 		% If this module has any seperately-compiled sub-modules,
-		% then we need to make everything in this module exported.
+		% then we need to make everything in this module
+		% exported_to_submodules.  We do that by splitting
+		% out the declarations and putting them in a special
+		% `:- private_interface' section.
 	{ get_children(Items0, Children) },
 	{ Children = [] ->
 		Module1 = Module0
 	;
 		split_clauses_and_decls(Items0, Clauses, Decls),
-		make_pseudo_decl(interface, InterfaceDecl),
+		make_pseudo_decl(private_interface, PrivateInterfaceDecl),
 		make_pseudo_decl(implementation, ImplementationDecl),
-		list__append([InterfaceDecl | Decls],
+		list__append([PrivateInterfaceDecl | Decls],
 			[ImplementationDecl | Clauses], Items1),
 		module_imports_set_items(Module0, Items1, Module1)
 	},
Index: compiler/prog_data.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/prog_data.m,v
retrieving revision 1.40
diff -u -r1.40 prog_data.m
--- prog_data.m	1998/08/18 10:00:41	1.40
+++ prog_data.m	1998/10/27 16:32:38
@@ -543,6 +543,14 @@
 	;	interface
 	;	implementation
 
+	;	private_interface
+		% This is used internally by the compiler,
+		% to identify items which originally
+		% came from an implementation section
+		% for a module that contains sub-modules;
+		% such items need to be exported to the
+		% sub-modules.
+
 	;	imported
 		% This is used internally by the compiler,
 		% to identify declarations which originally
Index: compiler/termination.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/termination.m,v
retrieving revision 1.16
diff -u -r1.16 termination.m
--- termination.m	1998/10/02 20:12:22	1.16
+++ termination.m	1998/10/27 16:32:44
@@ -390,10 +390,7 @@
 	->
 		ProcTable2 = ProcTable1
 	;
-		( ImportStatus = exported
-		; ImportStatus = local
-		; ImportStatus = pseudo_exported
-		)
+		status_defined_in_this_module(ImportStatus, yes)
 	->
 		( check_marker(Markers, terminates) ->
 			change_procs_termination_info(ProcIds, yes,
@@ -402,11 +399,8 @@
 			ProcTable2 = ProcTable0
 		)
 	;
-		( ImportStatus = imported
-		; ImportStatus = opt_imported
-		; ImportStatus = pseudo_imported  % should this be here?
-		)
-	->
+		% Not defined in this module.
+
 		% All of the predicates that are processed in this section
 		% are imported in some way.
 		% With imported predicates, any 'check_termination'
@@ -435,13 +429,6 @@
 		ArgSizeInfo = infinite([Context - ArgSizeError]),
 		change_procs_arg_size_info(ProcIds, no, ArgSizeInfo,
 			ProcTable1, ProcTable2)
-	;
-%		( ImportStatus = abstract_imported
-%		; ImportStatus = abstract_exported
-%		),
-		% This should not happen, as procedures are being processed
-		% here, and these import_status' refer to abstract types.
-		error("termination__check_preds: Unexpected import status")
 	),
 	( check_marker(Markers, does_not_terminate) ->
 		RequestError = Context - does_not_term_pragma(PredId),
Index: compiler/unused_args.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/unused_args.m,v
retrieving revision 1.53
diff -u -r1.53 unused_args.m
--- unused_args.m	1998/09/10 06:51:44	1.53
+++ unused_args.m	1998/10/29 13:13:54
@@ -1505,7 +1505,9 @@
 write_unused_args_to_opt_file(no, _, _, _) --> [].
 write_unused_args_to_opt_file(yes(OptStream), PredInfo, ProcId, UnusedArgs) -->
 	(
-		{ pred_info_is_exported(PredInfo) },
+		( { pred_info_is_exported(PredInfo) }
+		; { pred_info_is_exported_to_submodules(PredInfo) }
+		),
 		{ UnusedArgs \= [] }
 	->
 		{ pred_info_module(PredInfo, Module) },
Index: tests/hard_coded/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/Mmakefile,v
retrieving revision 1.45
diff -u -r1.45 Mmakefile
--- Mmakefile	1998/10/23 18:40:39	1.45
+++ Mmakefile	1998/11/02 07:01:56
@@ -61,6 +61,7 @@
 	nested \
 	nested2 \
 	nested3 \
+	nested_intermod_main \
 	no_fully_strict \
 	no_inline \
 	nondet_ctrl_vn \
@@ -110,6 +111,8 @@
 MCFLAGS-nondet_ctrl_vn	=	--optimize-value-number
 MCFLAGS-rnd		=	-O6
 MCFLAGS-bigtest		=	--intermodule-optimization -O3
+MCFLAGS-nested_intermod	=	--intermodule-optimization
+MCFLAGS-nested_intermod_main =	--intermodule-optimization
 
 # In grade `none' with options `-O1 --opt-space' on kryten
 # (a sparc-sun-solaris2.5 system), mode_choice needs to be linked
Index: tests/hard_coded/nested_intermod.m
===================================================================
RCS file: nested_intermod.m
diff -N nested_intermod.m
--- /dev/null	Mon Nov  2 18:14:52 1998
+++ nested_intermod.m	Mon Nov  2 18:15:27 1998
@@ -0,0 +1,39 @@
+:- module nested_intermod.
+
+:- interface.
+
+:- import_module int.
+
+:- pred foo(int).
+:- mode foo(in) is semidet.
+
+	:- module sub.
+
+	:- interface.
+
+	:- pred fu(int).
+	:- mode fu(in) is semidet.
+	:- end_module sub.
+
+:- implementation.
+
+	:- module sub.
+	:- implementation.
+
+	fu(X) :-
+		X < 4.
+
+	:- end_module sub.
+
+:- pragma inline(foo/1).
+
+foo(X) :-
+	bar(X).
+
+:- pred bar(int).
+:- mode bar(in) is semidet.
+
+bar(X) :-
+	X > 3.
+
+:- end_module nested_intermod.
Index: tests/hard_coded/nested_intermod_main.exp
===================================================================
RCS file: nested_intermod_main.exp
diff -N nested_intermod_main.exp
--- /dev/null	Mon Nov  2 18:14:52 1998
+++ nested_intermod_main.exp	Mon Nov  2 18:04:07 1998
@@ -0,0 +1,5 @@
+X = 1: no
+X = 2: no
+X = 3: no
+X = 4: yes
+X = 5: yes
Index: tests/hard_coded/nested_intermod_main.m
===================================================================
RCS file: nested_intermod_main.m
diff -N nested_intermod_main.m
--- /dev/null	Mon Nov  2 18:14:52 1998
+++ nested_intermod_main.m	Mon Nov  2 18:00:31 1998
@@ -0,0 +1,34 @@
+:- module nested_intermod_main.
+:- interface.
+:- import_module io.
+
+:- pred xyzzy(int).
+:- mode xyzzy(in) is semidet.
+
+:- pred main(io__state::di, io__state::uo) is det.
+
+:- implementation.
+:- import_module nested_intermod.
+
+main -->
+	test(1),
+	test(2),
+	test(3),
+	test(4),
+	test(5).
+
+:- pred test(int::in, io__state::di, io__state::uo) is det.
+
+test(X) -->
+	print("X = "), print(X), print(": "),
+	( { xyzzy(X) } ->
+		print("yes")
+	;
+		print("no")
+	),
+	nl.
+
+xyzzy(X) :-
+	foo(X).
+
+:- end_module nested_intermod_main.

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



More information about the developers mailing list