[m-rev.] reading .opt files transitively

Fergus Henderson fjh at cs.mu.OZ.AU
Thu Nov 8 22:14:35 AEDT 2001


I just noticed that the files from /home/mars had been restored
(see /home/mars.*.tar.gz).

One of these was a diff that I created a while back which
was supposed to address some of the problems with abstract
equivalence types in the .NET back-end.  The idea was that
as a first cut we could just always enable intermodule optimization
when compiling for .NET, and then we could get the type definitions
from the .opt files.  Unfortunately that idea didn't work, because
we don't read .opt files transitively.  That is also a problem
for optimization in some cases (e.g. it caused a big slow-down
for Ralph's `compress' implementation, because a key function
didn't get inlined).  So the following diff was supposed
to modify the compiler so that it read in .opt files transitively.

IIRC there was some problem which meant that this patch didn't work,
but I don't remember exactly what the problem was.

Anyway I'm not likely to get time to work on this in the next week --
I want to instead work on accurate GC for the MLDS->C back-end,
using a shadow stack technique, in the increasingly faint hope of
having something useful in time for the PLDI deadline.
But I thought it might be useful for me to post it here,
in case trd, petdr, or stayl were interested in picking it up.

----------

Estimated hours taken: 12

Read in the `.opt' files transitively, so that we get all the definitions
of equivalence types.  This is needed to support --high-level-data
for the .NET / Java back-ends.

XXX Are the dependencies still correct?
    Does this change break `mmake depend' with intermodule optimization?

XXX Does this change break `--use-opt-files'?

compiler/intermod.m:
	Read in the `.opt' files transitively.

compiler/modules.m:
	If intermodule optimization is enabled, read in the `.int' files
	(rather than the `.int2' files) for indirectly imported modules,

compiler/make_hlds.m:
	Process `pragma termination_info' pragmas in pass 3,
	*after* we've handled default modes for functions.
	This avoids a problem where the compiler was reporting spurious errors
	for the `pragma termination_info' pragmas for functions, when the
	`.opt' file for that module was read in before the `.int' file. 
	I'm not sure if this problem was introduced by the changes above or
	whether the changes above just exposed an existing problem.

cvs diff: Diffing .
Index: intermod.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/intermod.m,v
retrieving revision 1.98
diff -u -d -u -r1.98 intermod.m
--- intermod.m	2001/04/18 07:29:31	1.98
+++ intermod.m	2001/04/18 07:30:16
@@ -2095,10 +2095,11 @@
 		% Read in the .opt files for imported and ancestor modules.
 		%
 	{ Module0 = module_imports(_, ModuleName, Ancestors0, InterfaceDeps0,
-					ImplementationDeps0, _, _, _, _, _, _) },
+				ImplementationDeps0, _, _, _, _, _, _) },
 	{ list__condense([Ancestors0, InterfaceDeps0, ImplementationDeps0],
 		OptFiles) },
-	read_optimization_interfaces(OptFiles, [], OptItems, no, OptError),
+	read_optimization_interfaces(yes, OptFiles, [ModuleName], [], OptItems,
+		no, OptError),
 
 		%
 		% Append the items to the current item list, using
@@ -2119,7 +2120,7 @@
 		%
 	globals__io_lookup_bool_option(intermod_unused_args, UnusedArgs),
 	( { UnusedArgs = yes } ->
-		read_optimization_interfaces([ModuleName], [],
+		read_optimization_interfaces(no, [ModuleName], [], [],
 				LocalItems, no, UAError),
 		{ IsPragmaUnusedArgs = lambda([Item::in] is semidet, (
 					Item = pragma(PragmaType) - _,
@@ -2149,13 +2150,11 @@
 	{ set__to_sorted_list(NewDepsSet, NewDeps) },
 
 		%
-		% Read in the .int, and .int2 files needed by the .opt files.
+		% Read in the .int files needed by the .opt files.
 		% (XXX do we also need to read in .int0 files here?)
 		%
-	process_module_long_interfaces(NewDeps, ".int", [], NewIndirectDeps,
-				Module2, Module3),
-	process_module_indirect_imports(NewIndirectDeps, ".int2",
-				Module3, Module),
+	process_module_indirect_imports(NewDeps, ".int",
+				Module2, Module),
 
 		%
 		% Figure out whether anything went wrong
@@ -2167,13 +2166,26 @@
 		FoundError = no
 	}.
 
-:- pred read_optimization_interfaces(list(module_name)::in, item_list::in,
-			item_list::out, bool::in, bool::out,
+	% read_optimization_interfaces(Transitive, ModulesToRead,
+	%	ModulesAlreadyRead, Items0, Items, Error0, Error):
+	% Read in the `.opt' files for the specified ModulesToRead.
+	% If Transitive = yes, also read in the `.opt' files for
+	% any modules imported by those modules.  But don't read
+	% in any of the ModulesAlreadyRead.
+	% Append the items for the modules that get read in
+	% to Items0 and return the result in Items.
+	% Error contains the combined result of Error0 and any errors
+	% that occur while reading in modules.
+	%
+:- pred read_optimization_interfaces(bool::in,
+			list(module_name)::in, list(module_name)::in,
+			item_list::in, item_list::out, bool::in, bool::out,
 			io__state::di, io__state::uo) is det.
 
-read_optimization_interfaces([], Items, Items, Error, Error) --> [].
-read_optimization_interfaces([Import | Imports],
+read_optimization_interfaces(_, [], _, Items, Items, Error, Error) --> [].
+read_optimization_interfaces(Transitive, ModulesToRead, ModulesAlreadyRead,
 		Items0, Items, Error0, Error) -->
+	{ ModulesToRead = [Import | Imports] },
 	( { Import = qualified(_, _) } ->
 		% XXX Don't read in optimization interfaces for
 		% nested modules, because we also need to read in
@@ -2182,7 +2194,8 @@
 		% `.int0' files duplicate information in the `.int'
 		% files.
 		{ Error1 = Error0 },
-		{ Items2 = Items0 }
+		{ Items1 = Items0 },
+		{ NewDeps = [] }
 	;
 		globals__io_lookup_bool_option(very_verbose, VeryVerbose),
 		maybe_write_string(VeryVerbose,
@@ -2195,13 +2208,32 @@
 
 		module_name_to_file_name(Import, ".opt", no, FileName),
 		prog_io__read_opt_file(FileName, Import, yes,
-				ModuleError, Messages, Items1),
+				ModuleError, Messages, OptItems),
+		( { Transitive = yes } ->
+			       % Get the rest of the trans_opt files to be read
+			{ get_dependencies(OptItems,
+				NewImportDeps0, NewUseDeps0) },
+			globals__io_get_globals(Globals),
+			{ get_implicit_dependencies(OptItems, Globals,
+				NewImplicitImportDeps0, NewImplicitUseDeps0) },
+			{ NewDeps0 = list__condense([NewImportDeps0,
+				NewUseDeps0, NewImplicitImportDeps0,
+				NewImplicitUseDeps0]) },
+			{ set__list_to_set(NewDeps0, NewDepsSet0) },
+			{ set__delete_list(NewDepsSet0,
+			       ModulesToRead ++ ModulesAlreadyRead,
+			       NewDepsSet) },
+			{ set__to_sorted_list(NewDepsSet, NewDeps) }
+		;
+			{ NewDeps = [] }
+		),
 		update_error_status(opt, FileName, ModuleError, Messages,
 				Error0, Error1),
-		{ list__append(Items0, Items1, Items2) },
+		{ Items1 = Items0 ++ OptItems },
 		maybe_write_string(VeryVerbose, "% done.\n")
 	),
-	read_optimization_interfaces(Imports, Items2, Items, Error1, Error).
+	read_optimization_interfaces(Transitive, NewDeps ++ Imports,
+		[Import | ModulesAlreadyRead], Items1, Items, Error1, Error).
 
 update_error_status(FileType, FileName, ModuleError, Messages,
 		Error0, Error1) -->
Index: make_hlds.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/make_hlds.m,v
retrieving revision 1.368
diff -u -d -u -r1.368 make_hlds.m
--- make_hlds.m	2001/04/07 14:04:45	1.368
+++ make_hlds.m	2001/04/18 08:27:19
@@ -521,11 +521,11 @@
 		add_pred_marker(Module0, "promise_semipure", Name, Arity,
 			ImportStatus, Context, promised_semipure, [], Module)
 	;
-		{ Pragma = termination_info(PredOrFunc, SymName, ModeList, 
-			MaybeArgSizeInfo, MaybeTerminationInfo) },
-		add_pragma_termination_info(PredOrFunc, SymName, ModeList,
-			MaybeArgSizeInfo, MaybeTerminationInfo, Context,
-			Module0, Module)
+		% Handle pragma termination_info decls later on, in pass 3 --
+		% we need to add function default modes before handling
+		% these pragmas
+		{ Pragma = termination_info(_, _, _, _, _) },
+		{ Module = Module0 }
 	;
 		{ Pragma = terminates(Name, Arity) },
 		add_pred_marker(Module0, "terminates", Name, Arity,
@@ -734,8 +734,18 @@
 		),
 		{ Info = Info0 }
 	;
-		% don't worry about any pragma decs but c_code, tabling
-		% and fact_table here
+		{ Pragma = termination_info(PredOrFunc, SymName, ModeList, 
+			MaybeArgSizeInfo, MaybeTerminationInfo) }
+	->
+		add_pragma_termination_info(PredOrFunc, SymName, ModeList,
+			MaybeArgSizeInfo, MaybeTerminationInfo, Context,
+			Module0, Module),
+		{ Info = Info0 }
+	;
+		% don't worry about any pragma declarations other than the
+		% clause-like pragmas (c_code, tabling and fact_table) and
+		% the termination_info pragma here, since they've already
+		% been handled earlier, in pass 2
 		{ Module = Module0 },
 		{ Info = Info0 }	
 	).
Index: modules.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/modules.m,v
retrieving revision 1.158
diff -u -d -u -r1.158 modules.m
--- modules.m	2001/04/08 08:59:21	1.158
+++ modules.m	2001/04/18 07:03:16
@@ -1279,15 +1279,31 @@
 	process_module_long_interfaces(ImpUsedModules, ".int",
 		ImpIndirectImports1, ImpIndirectImports, Module9, Module10),
 
-		% Process the short interfaces for indirectly imported modules.
-		% The short interfaces are treated as if
-		% they are imported using `use_module'.
+		% For indirectly imported modules,
+		% we need to read either the `.int2' files or the `.int' files,
+		% depending on whether intermodule optimization is enabled.
+		% Normally we read the `.int2' files, but if we're going to
+		% read the `.opt' files, then we need to read the `.int'
+		% files rather than the `.int2' files.
+	globals__io_lookup_bool_option(make_optimization_interface,
+						MakeOptInt),
+	globals__io_lookup_bool_option(intermodule_optimization, IntermodOpt),
+	% globals__io_lookup_bool_option(use_opt_files, UseOptInt),
+	% XXX what about --use-opt-int?
+	{ IntermodOpt = yes, MakeOptInt = no ->
+		IndirectExt = ".int"
+	;
+		IndirectExt = ".int2"
+	},
+		% Process the interfaces for indirectly imported modules.
+		% These interfaces are treated as if they are imported
+		% using `use_module'.
 	{ append_pseudo_decl(Module10, used(interface), Module11) },
 	process_module_short_interfaces_transitively(IntIndirectImports,
-		".int2", Module11, Module12),
+		IndirectExt, Module11, Module12),
 	{ append_pseudo_decl(Module12, used(implementation), Module13) },
 	process_module_short_interfaces_transitively(ImpIndirectImports,
-		".int2", Module13, Module),
+		IndirectExt, Module13, Module),
 
 	{ module_imports_get_error(Module, Error) }.
 
cvs diff: Diffing notes
-- 
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