[m-rev.] for review: read `.opt' files transitively
Simon Taylor
stayl at cs.mu.OZ.AU
Sat Apr 27 17:53:06 AEST 2002
Estimated hours taken: 6 (+12 by fjh)
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.
compiler/options.m:
Add an option `--read-opt-files-transitively' (on by default).
compiler/intermod.m:
Read in the `.opt' files transitively.
compiler/modules.m:
`mmake depend' now assumes the target code for a module
depends on the `.opt', `.int' and `.int2' files for all
transitively imported modules.
compiler/make.dependencies.m:
Handle the extra dependencies.
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.
compiler/deep_profiling.m:
compiler/llds.m:
compiler/mercury_compile.m:
compiler/modes.m:
compiler/modules.m:
compiler/term_pass2.m:
Add module qualifiers to calls to `member' and `map'. These are
needed now that the equivalence `:- type set(T) == list(T)' is
exposed with inter-module optimization.
NEWS:
doc/user_guide.texi:
Document the change.
tests/invalid/Mmakefile:
Avoid reporting errors when creating the `.opt' file
for the `missing_parent_import' test case.
Index: NEWS
===================================================================
RCS file: /home/mercury1/repository/mercury/NEWS,v
retrieving revision 1.255
diff -u -u -r1.255 NEWS
--- NEWS 15 Apr 2002 05:03:58 -0000 1.255
+++ NEWS 27 Apr 2002 07:39:38 -0000
@@ -287,6 +287,13 @@
(or `--local-constraint-propagation' for a more restricted
version of the transformation).
+* The Mercury compiler can now perform inter-module optimization using
+ information from transitively imported modules. This is especially
+ useful for back-ends which do not support abstract equivalence types
+ properly (for example the .NET backend). To disable this behaviour and
+ only optimize using information from directly imported modules, use the
+ option `--no-read-opt-files-transitively'.
+
* The `--convert-to-goedel' option has been removed.
It never really worked anyway.
Index: compiler/deep_profiling.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/deep_profiling.m,v
retrieving revision 1.8
diff -u -u -r1.8 deep_profiling.m
--- compiler/deep_profiling.m 28 Mar 2002 03:42:51 -0000 1.8
+++ compiler/deep_profiling.m 26 Apr 2002 15:26:29 -0000
@@ -365,7 +365,7 @@
;
N = N0
),
- ( member(tailcall, Features) ->
+ ( set__member(tailcall, Features) ->
TailCallSites = [N0|TailCallSites0]
;
TailCallSites = TailCallSites0
@@ -1085,7 +1085,7 @@
classify_call(ModuleInfo, GoalExpr, CallKind),
(
CallKind = normal(PredProcId),
- ( member(tailcall, GoalFeatures) ->
+ ( set__member(tailcall, GoalFeatures) ->
generate_call(ModuleInfo, "prepare_for_tail_call", 1,
[SiteNumVar], [], PrepareGoal)
;
@@ -1175,7 +1175,7 @@
DeepInfo4 = DeepInfo3 ^ call_sites :=
(DeepInfo3 ^ call_sites ++ [CallSite]),
(
- member(tailcall, GoalFeatures),
+ set__member(tailcall, GoalFeatures),
DeepInfo4 ^ maybe_rec_info = yes(RecInfo),
RecInfo ^ role = outer_proc(_)
->
Index: compiler/intermod.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/intermod.m,v
retrieving revision 1.118
diff -u -u -r1.118 intermod.m
--- compiler/intermod.m 7 Apr 2002 10:22:33 -0000 1.118
+++ compiler/intermod.m 27 Apr 2002 07:48:16 -0000
@@ -2056,9 +2056,14 @@
{ Ancestors0 = Module0 ^ parent_deps },
{ InterfaceDeps0 = Module0 ^ int_deps },
{ ImplementationDeps0 = Module0 ^ impl_deps },
- { list__condense([Ancestors0, InterfaceDeps0, ImplementationDeps0],
- OptFiles) },
- read_optimization_interfaces(OptFiles, [], OptItems, no, OptError),
+ { OptFiles = list__sort_and_remove_dups(list__condense(
+ [Ancestors0, InterfaceDeps0, ImplementationDeps0])) },
+ globals__io_lookup_bool_option(read_opt_files_transitively,
+ Transitive),
+ { ModulesProcessed = set__insert(set__sorted_list_to_set(OptFiles),
+ ModuleName) },
+ read_optimization_interfaces(Transitive, ModuleName, OptFiles,
+ ModulesProcessed, [], OptItems, no, OptError),
%
% Append the items to the current item list, using
@@ -2079,8 +2084,8 @@
%
globals__io_lookup_bool_option(intermod_unused_args, UnusedArgs),
( { UnusedArgs = yes } ->
- read_optimization_interfaces([ModuleName], [],
- LocalItems, no, UAError),
+ read_optimization_interfaces(no, ModuleName, [ModuleName],
+ set__init, [], LocalItems, no, UAError),
{ IsPragmaUnusedArgs = lambda([Item::in] is semidet, (
Item = pragma(PragmaType) - _,
PragmaType = unused_args(_,_,_,_,_)
@@ -2112,12 +2117,10 @@
globals__io_get_globals(Globals),
{ get_implicit_dependencies(OptItems, Globals,
NewImplicitImportDeps0, NewImplicitUseDeps0) },
- { NewDeps0 = list__condense([NewImportDeps0, NewUseDeps0,
+ { NewDeps0 = list__sorted_and_remove_dups(list__condense(
+ [NewImportDeps0, NewUseDeps0,
NewImplicitImportDeps0, NewImplicitUseDeps0,
- AncestorImports1, AncestorImports2]) },
- { set__list_to_set(NewDeps0, NewDepsSet0) },
- { set__delete_list(NewDepsSet0, [ModuleName | OptFiles], NewDepsSet) },
- { set__to_sorted_list(NewDepsSet, NewDeps) },
+ AncestorImports1, AncestorImports2])) },
%
% Read in the .int, and .int2 files needed by the .opt files.
@@ -2143,30 +2146,51 @@
FoundError = no
}.
-:- pred read_optimization_interfaces(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],
+:- pred read_optimization_interfaces(bool::in, module_name::in,
+ list(module_name)::in, set(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(Transitive, ModuleName,
+ [ModuleToRead | ModulesToRead], ModulesProcessed0,
Items0, Items, Error0, Error) -->
globals__io_lookup_bool_option(very_verbose, VeryVerbose),
maybe_write_string(VeryVerbose,
"% Reading optimization interface for module"),
maybe_write_string(VeryVerbose, " `"),
- { prog_out__sym_name_to_string(Import, ImportString) },
- maybe_write_string(VeryVerbose, ImportString),
+ { prog_out__sym_name_to_string(ModuleToRead, ModuleToReadString) },
+ maybe_write_string(VeryVerbose, ModuleToReadString),
maybe_write_string(VeryVerbose, "'...\n"),
maybe_flush_output(VeryVerbose),
- module_name_to_file_name(Import, ".opt", no, FileName),
- prog_io__read_opt_file(FileName, Import,
- ModuleError, Messages, Items1),
+ module_name_to_file_name(ModuleToRead, ".opt", no, FileName),
+ prog_io__read_opt_file(FileName, ModuleToRead,
+ ModuleError, Messages, OptItems),
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).
+
+ globals__io_get_globals(Globals),
+ { Transitive = yes ->
+ get_dependencies(OptItems, NewImportDeps0, NewUseDeps0),
+ get_implicit_dependencies(OptItems, Globals,
+ NewImplicitImportDeps0, NewImplicitUseDeps0),
+ NewDeps0 = list__condense([NewImportDeps0,
+ NewUseDeps0, NewImplicitImportDeps0,
+ NewImplicitUseDeps0]),
+ set__list_to_set(NewDeps0, NewDepsSet0),
+ set__difference(NewDepsSet0, ModulesProcessed0, NewDepsSet),
+ set__union(ModulesProcessed0, NewDepsSet, ModulesProcessed),
+ set__to_sorted_list(NewDepsSet, NewDeps)
+ ;
+ ModulesProcessed = ModulesProcessed0,
+ NewDeps = []
+ },
+ read_optimization_interfaces(Transitive, ModuleName,
+ NewDeps ++ ModulesToRead, ModulesProcessed,
+ Items1, Items, Error1, Error).
update_error_status(FileType, FileName, ModuleError, Messages,
Error0, Error1) -->
Index: compiler/llds.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/llds.m,v
retrieving revision 1.284
diff -u -u -r1.284 llds.m
--- compiler/llds.m 28 Mar 2002 03:43:10 -0000 1.284
+++ compiler/llds.m 26 Apr 2002 15:32:59 -0000
@@ -1281,7 +1281,7 @@
global_data_init(LayoutData, GlobalData) :-
map__init(EmptyDataMap),
map__init(EmptyLayoutMap),
- NonCommon = map(wrap_layout_data, LayoutData),
+ NonCommon = list__map(wrap_layout_data, LayoutData),
GlobalData = global_data(EmptyDataMap, EmptyLayoutMap, [], NonCommon).
global_data_add_new_proc_var(GlobalData0, PredProcId, ProcVar, GlobalData) :-
Index: compiler/make.dependencies.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/make.dependencies.m,v
retrieving revision 1.2
diff -u -u -r1.2 make.dependencies.m
--- compiler/make.dependencies.m 7 Apr 2002 10:22:34 -0000 1.2
+++ compiler/make.dependencies.m 27 Apr 2002 07:51:12 -0000
@@ -337,8 +337,9 @@
{ Modules = set__init }
;
%
- % We also read `.int' files for modules imported
- % by `.opt' files.
+ % We also read `.int' files for the modules for
+ % which we read `.opt' files, and for the modules
+ % imported by those modules.
%
intermod_imports(ModuleName, Success1,
IntermodModules, Info1, Info2),
@@ -350,7 +351,8 @@
foldl3_maybe_stop_at_error(Info2 ^ keep_going,
union_deps(non_intermod_direct_imports),
set__to_sorted_list(IntermodModules), Success2,
- Modules0, Modules1, Info2, Info3),
+ set__union(Modules0, IntermodModules), Modules1,
+ Info2, Info3),
{ Success = Success0 `and` Success1 `and` Success2 },
{ Modules = set__delete(Modules1, ModuleName) }
)
@@ -464,9 +466,17 @@
globals__io_lookup_bool_option(intermodule_optimization, Intermod),
(
{ Intermod = yes },
- % XXX Read `.opt' files transitively.
- non_intermod_direct_imports(ModuleName, Success,
- Modules, Info0, Info)
+ globals__io_lookup_bool_option(read_opt_files_transitively,
+ Transitive),
+ (
+ { Transitive = yes },
+ find_transitive_implementation_imports(ModuleName,
+ Success, Modules, Info0, Info)
+ ;
+ { Transitive = no },
+ non_intermod_direct_imports(ModuleName, Success,
+ Modules, Info0, Info)
+ )
;
{ Intermod = no },
{ Info = Info0 },
@@ -591,6 +601,16 @@
find_reachable_local_modules(ModuleName, Success, Modules, Info0, Info) -->
find_transitive_module_dependencies(all_dependencies, local_module,
+ ModuleName, Success, Modules0, Info0, Info),
+ { Modules = set__insert(Modules0, ModuleName) }.
+
+:- pred find_transitive_implementation_imports(module_name::in, bool::out,
+ set(module_name)::out, make_info::in, make_info::out,
+ io__state::di, io__state::uo) is det.
+
+find_transitive_implementation_imports(ModuleName, Success, Modules,
+ Info0, Info) -->
+ find_transitive_module_dependencies(all_dependencies, any_module,
ModuleName, Success, Modules0, Info0, Info),
{ Modules = set__insert(Modules0, ModuleName) }.
Index: compiler/make_hlds.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/make_hlds.m,v
retrieving revision 1.408
diff -u -u -r1.408 make_hlds.m
--- compiler/make_hlds.m 7 Apr 2002 10:22:34 -0000 1.408
+++ compiler/make_hlds.m 26 Apr 2002 08:42:49 -0000
@@ -569,11 +569,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,
@@ -807,12 +807,22 @@
add_pragma_type_spec(Pragma, Context, Module0, Module,
Info0, Info)
;
- % don't worry about any pragma decs but c_code, tabling,
- % type_spec and fact_table here
- { Module = Module0 },
- { Info = Info0 }
- ).
-
+ { 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 }
+ ).
+
add_item_clause(promise(PromiseType, Goal, VarSet, UnivVars),
Status, Status, Context, Module0, Module, Info0, Info) -->
%
Index: compiler/mercury_compile.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/mercury_compile.m,v
retrieving revision 1.247
diff -u -u -r1.247 mercury_compile.m
--- compiler/mercury_compile.m 19 Apr 2002 12:14:06 -0000 1.247
+++ compiler/mercury_compile.m 26 Apr 2002 15:52:55 -0000
@@ -284,7 +284,7 @@
make_optimization_interface,
make_transitive_opt_interface,
typecheck_only, errorcheck_only],
- BoolList = map((func(Opt) = Bool :-
+ BoolList = list__map((func(Opt) = Bool :-
globals__lookup_bool_option(Globals, Opt, Bool)),
OptionList),
bool__or_list(BoolList) = no.
Index: compiler/modes.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/modes.m,v
retrieving revision 1.259
diff -u -u -r1.259 modes.m
--- compiler/modes.m 7 Apr 2002 10:22:44 -0000 1.259
+++ compiler/modes.m 26 Apr 2002 15:09:41 -0000
@@ -1593,9 +1593,9 @@
no_non_headvar_unification_goals([], _).
no_non_headvar_unification_goals([delayed_goal(_,_,Goal-_)|Goals], HeadVars) :-
Goal = unify(Var,Rhs,_,_,_),
- ( member(Var, HeadVars)
+ ( list__member(Var, HeadVars)
; Rhs = var(OtherVar),
- member(OtherVar, HeadVars)
+ list__member(OtherVar, HeadVars)
),
no_non_headvar_unification_goals(Goals, HeadVars).
Index: compiler/modules.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/modules.m,v
retrieving revision 1.228
diff -u -u -r1.228 modules.m
--- compiler/modules.m 15 Apr 2002 05:04:08 -0000 1.228
+++ compiler/modules.m 27 Apr 2002 07:43:07 -0000
@@ -2085,7 +2085,7 @@
[ModuleName | LongDeps], IntermodDirs,
OptDeps, TransOptDeps),
{ OptInt0Deps = sort_and_remove_dups(
- condense(map(get_ancestors,
+ condense(list__map(get_ancestors,
OptDeps))) },
write_dependencies_list(OptDeps,
".opt", DepStream),
@@ -2111,7 +2111,7 @@
[ModuleName | LongDeps],
IntermodDirs, ".opt", OptDeps),
{ OptInt0Deps = sort_and_remove_dups(
- condense(map(get_ancestors,
+ condense(list__map(get_ancestors,
OptDeps))) },
write_dependencies_list(OptDeps,
".opt", DepStream),
@@ -2983,12 +2983,25 @@
% and save them in the module_imports structure.
%
{ module_imports_get_module_name(Module0, ModuleName) },
- { get_dependencies_from_relation(IntDepsRel, ModuleName, IntDeps) },
- { get_dependencies_from_relation(ImplDepsRel, ModuleName, ImplDeps) },
- { get_dependencies_from_relation(IndirectDepsRel, ModuleName,
- IndirectDeps) },
{ get_dependencies_from_relation(IndirectOptDepsRel, ModuleName,
IndirectOptDeps) },
+ globals__io_lookup_bool_option(intermodule_optimization, Intermod),
+ { Intermod = yes ->
+ % Be conservative with inter-module optimization -- assume
+ % a module depends on the `.int', `.int2' and `.opt' files
+ % for all transitively imported modules.
+ IntDeps = IndirectOptDeps,
+ ImplDeps = IndirectOptDeps,
+ IndirectDeps = IndirectOptDeps
+ ;
+ get_dependencies_from_relation(IntDepsRel,
+ ModuleName, IntDeps),
+ get_dependencies_from_relation(ImplDepsRel,
+ ModuleName, ImplDeps),
+ get_dependencies_from_relation(IndirectDepsRel,
+ ModuleName, IndirectDeps)
+ },
+
{ module_imports_set_int_deps(Module0, IntDeps, Module1) },
{ module_imports_set_impl_deps(Module1, ImplDeps, Module2) },
{ module_imports_set_indirect_deps(Module2, IndirectDeps, Module) },
Index: compiler/options.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/options.m,v
retrieving revision 1.368
diff -u -u -r1.368 options.m
--- compiler/options.m 19 Apr 2002 14:59:24 -0000 1.368
+++ compiler/options.m 26 Apr 2002 16:56:30 -0000
@@ -362,6 +362,7 @@
; opt_level
; opt_space % default is to optimize time
; intermodule_optimization
+ ; read_opt_files_transitively
; use_opt_files
; use_trans_opt_files
; transitive_optimization
@@ -854,6 +855,7 @@
opt_level - int_special,
opt_space - special,
intermodule_optimization - bool(no),
+ read_opt_files_transitively - bool(yes),
use_opt_files - bool(no),
use_trans_opt_files - bool(no),
transitive_optimization - bool(no),
@@ -1392,6 +1394,7 @@
long_option("optimise-space", opt_space).
long_option("intermodule-optimization", intermodule_optimization).
long_option("intermodule-optimisation", intermodule_optimization).
+long_option("read-opt-files-transitively", read_opt_files_transitively).
long_option("use-opt-files", use_opt_files).
long_option("use-trans-opt-files", use_trans_opt_files).
long_option("transitive-intermodule-optimization",
@@ -2912,6 +2915,10 @@
"--transitive-intermodule-optimization",
"\tImport the transitive intermodule optimization data.",
"\tThis data is imported from `<module>.trans_opt' files.",
+ "--no-read-opt-files-transitively",
+ "\tOnly read the inter-module optimization information",
+ "\tfor directly imported modules, not the transitive",
+ "\tclosure of the imports.",
"--use-opt-files",
"\tPerform inter-module optimization using any",
"\t`.opt' files which are already built,",
Index: compiler/term_pass2.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/term_pass2.m,v
retrieving revision 1.9
diff -u -u -r1.9 term_pass2.m
--- compiler/term_pass2.m 20 Mar 2002 12:37:27 -0000 1.9
+++ compiler/term_pass2.m 26 Apr 2002 15:55:14 -0000
@@ -75,7 +75,7 @@
% Don't try single arg analysis if it cannot cure
% the reason for the failure of the main analysis.
\+ (
- member(Error, Errors),
+ list__member(Error, Errors),
Error = _ - imported_pred
),
prove_termination_in_scc_single_arg(SCC,
Index: doc/user_guide.texi
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/user_guide.texi,v
retrieving revision 1.307
diff -u -u -r1.307 user_guide.texi
--- doc/user_guide.texi 19 Apr 2002 14:59:29 -0000 1.307
+++ doc/user_guide.texi 26 Apr 2002 16:58:25 -0000
@@ -4999,6 +4999,13 @@
files may depend on other @samp{.trans_opt} files, whereas each
@samp{.opt} file may only depend on the corresponding @samp{.m} file.
+ at sp 1
+ at item --no-read-opt-files-transitively
+ at findex --no-read-opt-files-transitively
+Only read the inter-module optimization information
+for directly imported modules, not the transitive
+closure of the imports.
+
@item --use-opt-files
@findex --use-opt-files
Perform inter-module optimization using any @samp{.opt} files which are
Index: tests/invalid/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/invalid/Mmakefile,v
retrieving revision 1.108
diff -u -u -r1.108 Mmakefile
--- tests/invalid/Mmakefile 25 Mar 2002 21:13:29 -0000 1.108
+++ tests/invalid/Mmakefile 27 Apr 2002 07:17:16 -0000
@@ -166,11 +166,13 @@
# is reported correctly when building the `.opt' file.
MCFLAGS-assert_in_interface = --no-intermodule-optimization
+MCFLAGS-children = --no-intermodule-optimization
MCFLAGS-duplicate_modes = --verbose-error-messages
MCFLAGS-exported_mode = --infer-all --no-intermodule-optimization
MCFLAGS-imported_mode = --infer-all --no-intermodule-optimization
MCFLAGS-missing_det_decls = --no-infer-det
MCFLAGS-missing_interface_import = --make-interface
+MCFLAGS-missing_parent_import = --no-intermodule-optimization
MCFLAGS-multisoln_func = --infer-types
MCFLAGS-mode_inf = --infer-all
MCFLAGS-no_exports = --halt-at-warn
--------------------------------------------------------------------------
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