[m-rev.] for review: read .opt files transitively

Fergus Henderson fjh at cs.mu.OZ.AU
Wed Apr 18 23:41:23 AEST 2001


Here's (a first draft of) a change to read in the `.opt' files transitively.
See my post to mercury-developers for detailed rationale.

With this change, `tools/bootcheck --grade il' gets as far as building all
the `.opt' and `.trans_opt' files, but dies when compiling benchmarking.m;
the problem there is an unrelated one, namely that the IL back-end doesn't
support nested classes.

This change is probably not quite ready for prime-time yet.
There are a couple of XXXs that need to be investigated.
I'm also not quite sure whether this is a good thing to do
for grades other than .NET/Java.  On the one hand, it may well
improve optimization.  On the other hand, it will increase
compilation time.  (Presuming intermodule optimization is enabled,
that is; otherwise this change will have no effect.)

Do you think we should just read `.opt' files transitively all the time,
as is done in this patch?
Or do you think it is worth adding yet another compilation option to
control it?

----------

Estimated hours taken: 10
Branches: main

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.

Workspace: /home/mars/fjh/ws1/mercury
Index: compiler/intermod.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/intermod.m,v
retrieving revision 1.98
diff -u -d -r1.98 intermod.m
--- compiler/intermod.m	2001/04/18 07:29:31	1.98
+++ compiler/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: compiler/make_hlds.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/make_hlds.m,v
retrieving revision 1.368
diff -u -d -r1.368 make_hlds.m
--- compiler/make_hlds.m	2001/04/07 14:04:45	1.368
+++ compiler/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: compiler/modules.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/modules.m,v
retrieving revision 1.158
diff -u -d -r1.158 modules.m
--- compiler/modules.m	2001/04/08 08:59:21	1.158
+++ compiler/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) }.
 
-- 
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-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