[m-dev.] clueless -- overloaded functor
Nancy Mazur
Nancy.Mazur at cs.kuleuven.ac.be
Mon Aug 26 19:02:09 AEST 2002
Hi,
while trying to bring in sync the reuse-branch of the compiler with the
main branch, I've now obtained a very bizarre error when compiling
handle_options.m.
This is my setting:
- an "update"-workspace containing the reuse-branch, synchronised with
the main-branch (trunk_snapshot_20020823093831, last friday).
- a "main-branch" workspace, which is a clean cvs-version, also from
friday.
Both workspaces are being compiled with the rotd from the 1st of July.
The differences between both workspaces are:
- in library/: extra aliasing-pragma's, but nothing more.
- in compiler/: some changes to the hlds, some extra
predicates, some extra options, but nothing which might be
related to the error obtained. (and of course extra files)
- in runtime/...
The strange thing is that in the "main-branch" handle_options (and
all the rest) can be compiled without a problem, but not in the "update"
workspace. And diffing the compiler-files doesn't give me any clue.
Any ideas are welcome, because for the moment, I'm a bit stuck on this.
In attachment I'm sending handle_options.m (from the update-branch),
handle_options.err, + a diff between the update-workspace file, and the
plain main-branch file.
Many thanks in advance!
Nancy
-------------- next part --------------
handle_options.m:940: In clause for predicate `libs:handle_options:postprocess_options_2/10':
handle_options.m:940: in function result term of clause head:
handle_options.m:940: in unification of argument
handle_options.m:940: and term `(V_406 / FullArch)':
handle_options.m:940: type error in argument(s) of functor `//2'.
handle_options.m:940: argument has overloaded type {
handle_options.m:940: ((parse_tree:prog_data):sym_name_and_arity),
handle_options.m:940: int
handle_options.m:940: },
handle_options.m:940: functor `//2' has overloaded type
handle_options.m:940: { (((parse_tree:prog_data):sym_name) / int) :: ((parse_tree:prog_data):sym_name_and_arity),
handle_options.m:940: (int / int) :: int },
handle_options.m:940: argument has type `'<any>'',
handle_options.m:940: variable `FullArch' has type `string'.
handle_options.m:942: In clause for predicate `libs:handle_options:postprocess_options_2/10':
handle_options.m:942: in function result term of clause head:
handle_options.m:942: in argument 1 of functor `//2':
handle_options.m:942: in unification of argument
handle_options.m:942: and term `(V_407 / GradeString)':
handle_options.m:942: type error in argument(s) of functor `//2'.
handle_options.m:942: argument has overloaded type {
handle_options.m:942: ((parse_tree:prog_data):sym_name_and_arity),
handle_options.m:942: int
handle_options.m:942: },
handle_options.m:942: functor `//2' has overloaded type
handle_options.m:942: { (((parse_tree:prog_data):sym_name) / int) :: ((parse_tree:prog_data):sym_name_and_arity),
handle_options.m:942: (int / int) :: int },
handle_options.m:942: argument has type `'<any>'',
handle_options.m:942: variable `GradeString' has type `string'.
handle_options.m:942: In clause for predicate `libs:handle_options:postprocess_options_2/10':
handle_options.m:942: in function result term of clause head:
handle_options.m:942: in argument 1 of functor `//2':
handle_options.m:942: in argument 1 of functor `//2':
handle_options.m:942: in unification of argument
handle_options.m:942: and term `(MercuryLibDir / V_408)':
handle_options.m:942: type error in argument(s) of functor `//2'.
handle_options.m:942: argument has overloaded type {
handle_options.m:942: ((parse_tree:prog_data):sym_name_and_arity),
handle_options.m:942: int
handle_options.m:942: },
handle_options.m:942: functor `//2' has overloaded type
handle_options.m:942: { (((parse_tree:prog_data):sym_name) / int) :: ((parse_tree:prog_data):sym_name_and_arity),
handle_options.m:942: (int / int) :: int },
handle_options.m:942: variable `MercuryLibDir' has type `string',
handle_options.m:942: argument has type `'<any>''.
handle_options.m:951: In clause for predicate `libs:handle_options:postprocess_options_2/10':
handle_options.m:951: in function result term of clause head:
handle_options.m:951: in argument 1 of functor `//2':
handle_options.m:951: in unification of argument
handle_options.m:951: and term `(V_396 / FullArch)':
handle_options.m:951: type error in argument(s) of functor `//2'.
handle_options.m:951: Argument 2 (FullArch) has type `string',
handle_options.m:951: expected type was `int'.
handle_options.m:951: In clause for predicate `libs:handle_options:postprocess_options_2/10':
handle_options.m:951: in function result term of clause head:
handle_options.m:951: in argument 1 of functor `//2':
handle_options.m:951: in argument 1 of functor `//2':
handle_options.m:951: in unification of argument
handle_options.m:951: and term `(V_397 / GradeString)':
handle_options.m:951: type error in argument(s) of functor `//2'.
handle_options.m:951: argument has overloaded type {
handle_options.m:951: ((parse_tree:prog_data):sym_name_and_arity),
handle_options.m:951: int
handle_options.m:951: },
handle_options.m:951: functor `//2' has overloaded type
handle_options.m:951: { (((parse_tree:prog_data):sym_name) / int) :: ((parse_tree:prog_data):sym_name_and_arity),
handle_options.m:951: (int / int) :: int },
handle_options.m:951: argument has type `'<any>'',
handle_options.m:951: variable `GradeString' has type `string'.
handle_options.m:951: In clause for predicate `libs:handle_options:postprocess_options_2/10':
handle_options.m:951: in function result term of clause head:
handle_options.m:951: in argument 1 of functor `//2':
handle_options.m:951: in argument 1 of functor `//2':
handle_options.m:951: in argument 1 of functor `//2':
handle_options.m:951: in unification of argument
handle_options.m:951: and term `(MercuryLibDir / V_398)':
handle_options.m:951: type error in argument(s) of functor `//2'.
handle_options.m:951: argument has overloaded type {
handle_options.m:951: ((parse_tree:prog_data):sym_name_and_arity),
handle_options.m:951: int
handle_options.m:951: },
handle_options.m:951: functor `//2' has overloaded type
handle_options.m:951: { (((parse_tree:prog_data):sym_name) / int) :: ((parse_tree:prog_data):sym_name_and_arity),
handle_options.m:951: (int / int) :: int },
handle_options.m:951: variable `MercuryLibDir' has type `string',
handle_options.m:951: argument has type `'<any>''.
handle_options.m:951: In clause for predicate `libs:handle_options:postprocess_options_2/10':
handle_options.m:951: in function result term of clause head:
handle_options.m:951: in argument 2 of functor `//2':
handle_options.m:951: type error in unification of argument
handle_options.m:951: and constant `"inc"'.
handle_options.m:951: argument has type `int',
handle_options.m:951: constant `"inc"' has type `string'.
handle_options.m:956: In clause for predicate `libs:handle_options:postprocess_options_2/10':
handle_options.m:956: in argument 2 of call to predicate `globals:io_set_option/4':
handle_options.m:956: in argument 1 of functor `accumulating/1':
handle_options.m:956: in unification of argument
handle_options.m:956: and term `(ExtraCIncludeDirs ++ CIncludeDirs)':
handle_options.m:956: type error in argument(s) of functor `++/2'.
handle_options.m:956: argument has type `(list:list(string))',
handle_options.m:956: functor `++/2' has overloaded type
handle_options.m:956: { ((list:list(T)) ++ (list:list(T))) :: (list:list(T)),
handle_options.m:956: (string ++ string) :: string },
handle_options.m:956: variable `ExtraCIncludeDirs' has overloaded type {
handle_options.m:956: (list:list(((parse_tree:prog_data):sym_name_and_arity))),
handle_options.m:956: (list:list(int))
handle_options.m:956: },
handle_options.m:956: variable `CIncludeDirs' has type `(list:list(string))'.
handle_options.m:1004: In clause for predicate `libs:handle_options:postprocess_options_2/10':
handle_options.m:1004: in argument 1 of functor `[|]/2':
handle_options.m:1004: in unification of argument
handle_options.m:1004: and term `(V_365 / FullArch)':
handle_options.m:1004: type error in argument(s) of functor `//2'.
handle_options.m:1004: argument has overloaded type {
handle_options.m:1004: ((parse_tree:prog_data):sym_name_and_arity),
handle_options.m:1004: int
handle_options.m:1004: },
handle_options.m:1004: functor `//2' has overloaded type
handle_options.m:1004: { (((parse_tree:prog_data):sym_name) / int) :: ((parse_tree:prog_data):sym_name_and_arity),
handle_options.m:1004: (int / int) :: int },
handle_options.m:1004: argument has type `'<any>'',
handle_options.m:1004: variable `FullArch' has type `string'.
handle_options.m:1004: In clause for predicate `libs:handle_options:postprocess_options_2/10':
handle_options.m:1004: in argument 1 of functor `[|]/2':
handle_options.m:1004: in argument 1 of functor `//2':
handle_options.m:1004: in unification of argument
handle_options.m:1004: and term `(V_366 / GradeString)':
handle_options.m:1004: type error in argument(s) of functor `//2'.
handle_options.m:1004: argument has overloaded type {
handle_options.m:1004: ((parse_tree:prog_data):sym_name_and_arity),
handle_options.m:1004: int
handle_options.m:1004: },
handle_options.m:1004: functor `//2' has overloaded type
handle_options.m:1004: { (((parse_tree:prog_data):sym_name) / int) :: ((parse_tree:prog_data):sym_name_and_arity),
handle_options.m:1004: (int / int) :: int },
handle_options.m:1004: argument has type `'<any>'',
handle_options.m:1004: variable `GradeString' has type `string'.
handle_options.m:1023: In clause for predicate `libs:handle_options:postprocess_options_2/10':
handle_options.m:1023: in argument 1 of functor `//2':
handle_options.m:1023: in argument 1 of functor `//2':
handle_options.m:1023: in unification of argument
handle_options.m:1023: and term `(V_351 / FullArch)':
handle_options.m:1023: type error in argument(s) of functor `//2'.
handle_options.m:1023: argument has type `int',
handle_options.m:1023: functor `//2' has overloaded type
handle_options.m:1023: { (((parse_tree:prog_data):sym_name) / int) :: ((parse_tree:prog_data):sym_name_and_arity),
handle_options.m:1023: (int / int) :: int },
handle_options.m:1023: argument has type `'<any>'',
handle_options.m:1023: variable `FullArch' has type `string'.
handle_options.m:1023: In clause for predicate `libs:handle_options:postprocess_options_2/10':
handle_options.m:1023: in argument 1 of functor `//2':
handle_options.m:1023: in argument 1 of functor `//2':
handle_options.m:1023: in argument 1 of functor `//2':
handle_options.m:1023: in unification of argument
handle_options.m:1023: and term `(V_352 / GradeString)':
handle_options.m:1023: type error in argument(s) of functor `//2'.
handle_options.m:1023: argument has overloaded type {
handle_options.m:1023: ((parse_tree:prog_data):sym_name_and_arity),
handle_options.m:1023: int
handle_options.m:1023: },
handle_options.m:1023: functor `//2' has overloaded type
handle_options.m:1023: { (((parse_tree:prog_data):sym_name) / int) :: ((parse_tree:prog_data):sym_name_and_arity),
handle_options.m:1023: (int / int) :: int },
handle_options.m:1023: argument has type `'<any>'',
handle_options.m:1023: variable `GradeString' has type `string'.
handle_options.m:1023: In clause for predicate `libs:handle_options:postprocess_options_2/10':
handle_options.m:1023: in argument 1 of functor `//2':
handle_options.m:1023: in argument 2 of functor `//2':
handle_options.m:1023: type error in unification of argument
handle_options.m:1023: and constant `"Mercury"'.
handle_options.m:1023: argument has type `int',
handle_options.m:1023: constant `"Mercury"' has type `string'.
handle_options.m:1023: In clause for predicate `libs:handle_options:postprocess_options_2/10':
handle_options.m:1023: in argument 2 of functor `//2':
handle_options.m:1023: type error in unification of argument
handle_options.m:1023: and constant `"mihs"'.
handle_options.m:1023: argument has type `int',
handle_options.m:1023: constant `"mihs"' has type `string'.
handle_options.m:1025: In clause for predicate `libs:handle_options:postprocess_options_2/10':
handle_options.m:1025: in argument 1 of functor `//2':
handle_options.m:1025: type error in unification of argument
handle_options.m:1025: and constant `"Mercury"'.
handle_options.m:1025: argument has type `int',
handle_options.m:1025: constant `"Mercury"' has type `string'.
handle_options.m:1025: In clause for predicate `libs:handle_options:postprocess_options_2/10':
handle_options.m:1025: in argument 2 of functor `//2':
handle_options.m:1025: type error in unification of argument
handle_options.m:1025: and constant `"mihs"'.
handle_options.m:1025: argument has type `int',
handle_options.m:1025: constant `"mihs"' has type `string'.
handle_options.m:1033: In clause for predicate `libs:handle_options:postprocess_options_2/10':
handle_options.m:1033: in argument 2 of functor `[|]/2':
handle_options.m:1033: in unification of argument
handle_options.m:1033: and term `[MihsSubdir | CIncludeDirs1]':
handle_options.m:1033: type error in argument(s) of functor `[|]/2'.
handle_options.m:1033: argument has overloaded type {
handle_options.m:1033: (list:list((pred string))),
handle_options.m:1033: (list:list(string))
handle_options.m:1033: },
handle_options.m:1033: functor `[|]/2' has type
handle_options.m:1033: `[T | (list:list(T))] :: (list:list(T))',
handle_options.m:1033: variable `MihsSubdir' has type `int',
handle_options.m:1033: variable `CIncludeDirs1' has type `(list:list(string))'.
For more information, try recompiling with `-E'.
-------------- next part --------------
--- update/compiler/handle_options.m Fri Aug 23 16:53:17 2002
+++ main-branch/compiler/handle_options.m Thu Aug 22 04:34:10 2002
@@ -459,14 +459,6 @@
option_implies(check_termination, termination, bool(yes)),
option_implies(check_termination, warn_missing_trans_opt_files,
bool(yes)),
- option_implies(infer_structure_reuse, infer_possible_aliases,
- bool(yes)),
- option_implies(infer_possible_aliases, warn_missing_trans_opt_files,
- bool(yes)),
- option_implies(infer_possible_aliases, transitive_optimization,
- bool(yes)),
- option_implies(infer_possible_aliases, read_opt_files_transitively,
- bool(yes)),
option_implies(make_transitive_opt_interface, transitive_optimization,
bool(yes)),
option_implies(transitive_optimization, intermodule_optimization,
@@ -477,21 +469,7 @@
% we need to build all `.opt' or `.trans_opt' files.
option_implies(intermodule_optimization, use_opt_files, bool(no)),
option_implies(transitive_optimization, use_trans_opt_files, bool(no)),
-% option_implies(make_optimization_interface, use_trans_opt_files, bool(no)),
- % XXX This should be checked in the near future or a merge
- % towards using smart_recompilation should be done.
-
- % when doing possible alias analysis, for the moment we
- % don't want everything to be rebuild each time -- so let's
- % put those use_*opt_files back to yes.
- % possible aliases does not use opt_files, but it does use
- % trans_opt files ! This is also to avoid some bizar problems
- % where when Mmake-ing modules, the modules are in fact compiled
- % twice, std-err is sent to std-out etc...
- % option_implies(infer_possible_aliases, use_opt_files, bool(yes)),
- % option_implies(infer_possible_aliases, use_trans_opt_files, bool(yes)),
-
% XXX `--use-opt-files' is broken.
% When inter-module optimization is enabled, error checking
% without the extra information from the `.opt' files
@@ -1629,14 +1607,11 @@
:- pred convert_dump_alias(string, string).
:- mode convert_dump_alias(in, out) is semidet.
-convert_dump_alias("ALL", "aAbcdfgilmnprstuvCIMPTU").
-convert_dump_alias("all", "aAbcdfgilmnprstuvCMPT").
+convert_dump_alias("ALL", "abcdfgilmnprstuvCIMPTU").
+convert_dump_alias("all", "abcdfgilmnprstuvCMPT").
convert_dump_alias("codegen", "dfnprsu").
convert_dump_alias("vanessa", "ltuCIU").
convert_dump_alias("paths", "cP").
convert_dump_alias("petdr", "din").
-convert_dump_alias("palias", "A").
-convert_dump_alias("sr", "Ap").
-
convert_dump_alias("osv", "bcdglmnpruvP"). % for debugging
% --optimize-saved-vars-cell
-------------- next part --------------
%-----------------------------------------------------------------------------%
% Copyright (C) 1994-2002 The University of Melbourne.
% This file may only be copied under the terms of the GNU General
% Public License - see the file COPYING in the Mercury distribution.
%-----------------------------------------------------------------------------%
% File: handle_options.m.
% Main authors: fjh, zs.
% This module does post-procesing on the command-line options, after
% getopt has done its stuff.
% It also contains code for handling the --grade option.
%-----------------------------------------------------------------------------%
:- module libs__handle_options.
:- interface.
:- import_module list, bool, getopt, std_util, io.
:- import_module libs__globals, libs__options.
% handle_options(Args, MaybeError, OptionArgs, NonOptionArgs, Link).
:- pred handle_options(list(string), maybe(string), list(string),
list(string), bool, io__state, io__state).
:- mode handle_options(in, out, out, out, out, di, uo) is det.
% process_options(Args, OptionArgs, NonOptionArgs, MaybeOptionTable).
%
% Process the options, but don't do any post-processing or
% modify the globals. This is mainly useful for separating
% the list of arguments into option and non-option arguments.
:- pred process_options(list(string), list(string), list(string),
maybe_option_table(option)).
:- mode process_options(in, out, out, out) is det.
% usage_error(Descr, Message)
%
% Display the description of the error location, the error message
% and then a usage message.
:- pred usage_error(string::in, string::in,
io__state::di, io__state::uo) is det.
% usage_error(Message)
%
% Display error message and then usage message
:- pred usage_error(string::in, io__state::di, io__state::uo) is det.
% Display usage message.
:- pred usage(io__state::di, io__state::uo) is det.
% Display long usage message for help
:- pred long_usage(io__state::di, io__state::uo) is det.
% Given the current set of options, figure out
% which grade to use.
:- pred compute_grade(globals::in, string::out) is det.
% The inverse of compute_grade: given a grade,
% set the appropriate options.
:- pred convert_grade_option(string::in, option_table::in, option_table::out)
is semidet.
% Produce the grade component of grade-specific
% installation directories.
:- pred grade_directory_component(globals::in, string::out) is det.
%-----------------------------------------------------------------------------%
:- implementation.
:- import_module libs__options, libs__globals, parse_tree__prog_io_util.
:- import_module libs__trace_params, check_hlds__unify_proc.
:- import_module parse_tree__prog_data, backend_libs__foreign.
:- import_module char, dir, int, string, map, set, library.
handle_options(Args0, MaybeError, OptionArgs, Args, Link) -->
% io__write_string("original arguments\n"),
% dump_arguments(Args0),
{ process_options(Args0, OptionArgs, Args, Result) },
% io__write_string("final arguments\n"),
% dump_arguments(Args),
postprocess_options(Result, MaybeError),
( { MaybeError = yes(_) } ->
{ Link = no }
;
globals__io_lookup_bool_option(generate_dependencies,
GenerateDependencies),
globals__io_lookup_bool_option(make_interface, MakeInterface),
globals__io_lookup_bool_option(make_private_interface,
MakePrivateInterface),
globals__io_lookup_bool_option(make_short_interface,
MakeShortInterface),
globals__io_lookup_bool_option(make_optimization_interface,
MakeOptimizationInt),
globals__io_lookup_bool_option(make_transitive_opt_interface,
MakeTransOptInt),
globals__io_lookup_bool_option(convert_to_mercury,
ConvertToMercury),
globals__io_lookup_bool_option(typecheck_only, TypecheckOnly),
globals__io_lookup_bool_option(errorcheck_only, ErrorcheckOnly),
globals__io_lookup_bool_option(target_code_only,
TargetCodeOnly),
globals__io_get_target(Target),
{ GenerateIL = (if Target = il then yes else no) },
{ GenerateJava = (if Target = java then yes else no) },
globals__io_lookup_bool_option(compile_only, CompileOnly),
globals__io_lookup_bool_option(aditi_only, AditiOnly),
{ bool__or_list([GenerateDependencies, MakeInterface,
MakePrivateInterface, MakeShortInterface,
MakeOptimizationInt, MakeTransOptInt,
ConvertToMercury, TypecheckOnly,
ErrorcheckOnly, TargetCodeOnly,
GenerateIL, GenerateJava,
CompileOnly, AditiOnly],
NotLink) },
{ bool__not(NotLink, Link) },
globals__io_lookup_bool_option(smart_recompilation, Smart),
( { Smart = yes, Link = yes } ->
% XXX Currently smart recompilation doesn't check
% that all the files needed to link are present
% and up-to-date, so disable it.
disable_smart_recompilation("linking")
;
[]
)
).
process_options(Args0, OptionArgs, Args, Result) :-
OptionOps = option_ops(short_option, long_option,
option_defaults, special_handler),
getopt__process_options(OptionOps, Args0,
OptionArgs, Args, Result).
:- pred dump_arguments(list(string), io__state, io__state).
:- mode dump_arguments(in, di, uo) is det.
dump_arguments([]) --> [].
dump_arguments([Arg | Args]) -->
io__write_string("<"),
io__write_string(Arg),
io__write_string(">\n"),
dump_arguments(Args).
%-----------------------------------------------------------------------------%
% Convert string-valued options into the appropriate enumeration types,
% and process implications among the options (i.e. situations where setting
% one option implies setting/unsetting another one).
:- pred postprocess_options(maybe_option_table(option), maybe(string),
io__state, io__state).
:- mode postprocess_options(in, out, di, uo) is det.
postprocess_options(error(ErrorMessage), yes(ErrorMessage)) --> [].
postprocess_options(ok(OptionTable), Error) -->
{ map__lookup(OptionTable, target, Target0) },
(
{ Target0 = string(TargetStr) },
{ convert_target(TargetStr, Target) }
->
{ map__lookup(OptionTable, gc, GC_Method0) },
(
{ GC_Method0 = string(GC_MethodStr) },
{ convert_gc_method(GC_MethodStr, GC_Method) }
->
{ map__lookup(OptionTable, tags, TagsMethod0) },
(
{ TagsMethod0 = string(TagsMethodStr) },
{ convert_tags_method(TagsMethodStr, TagsMethod) }
->
{ map__lookup(OptionTable,
fact_table_hash_percent_full, PercentFull) },
(
{ PercentFull = int(Percent) },
{ Percent >= 1 },
{ Percent =< 100 }
->
{ map__lookup(OptionTable, termination_norm,
TermNorm0) },
(
{ TermNorm0 = string(TermNormStr) },
{ convert_termination_norm(TermNormStr, TermNorm) }
->
{ map__lookup(OptionTable, trace, Trace) },
{ map__lookup(OptionTable, require_tracing,
RequireTracingOpt) },
(
{ Trace = string(TraceStr) },
{ RequireTracingOpt = bool(RequireTracing) },
{ convert_trace_level(TraceStr, RequireTracing,
TraceLevel) }
->
{ map__lookup(OptionTable, suppress_trace,
Suppress) },
(
{ Suppress = string(SuppressStr) },
{ convert_trace_suppress(SuppressStr,
TraceSuppress) }
->
{ map__lookup(OptionTable, dump_hlds_alias,
DumpAliasOption) },
(
{ DumpAliasOption = string(DumpAlias) },
{ DumpAlias = "" }
->
postprocess_options_2(OptionTable,
Target, GC_Method, TagsMethod,
TermNorm, TraceLevel,
TraceSuppress, Error)
;
{ DumpAliasOption = string(DumpAlias) },
{ convert_dump_alias(DumpAlias,
DumpOptions) }
->
{ map__set(OptionTable,
dump_hlds_options,
string(DumpOptions),
NewOptionTable) },
postprocess_options_2(NewOptionTable,
Target, GC_Method, TagsMethod,
TermNorm, TraceLevel,
TraceSuppress, Error)
;
{ Error = yes("Invalid argument to option `--hlds-dump-alias'.") }
)
;
{ Error = yes("Invalid argument to option `--suppress-trace'.") }
)
;
{ Error = yes("Invalid argument to option `--trace'\n\t(must be `minimum', `shallow', `deep', or `default').") }
)
;
{ Error = yes("Invalid argument to option `--termination-norm'\n\t(must be `simple', `total' or `num-data-elems').") }
)
;
{ Error = yes("Invalid argument to option `--fact-table-hash-percent-full'\n\t(must be an integer between 1 and 100)") }
)
;
{ Error = yes("Invalid tags option (must be `none', `low' or `high')") }
)
;
{ Error = yes("Invalid GC option (must be `none', `conservative', `boehm', `mps' or `accurate')") }
)
;
{ Error = yes("Invalid target option (must be `c', `asm', `il', or `java')") }
).
:- pred postprocess_options_2(option_table::in, compilation_target::in,
gc_method::in, tags_method::in, termination_norm::in,
trace_level::in, trace_suppress_items::in, maybe(string)::out,
io__state::di, io__state::uo) is det.
postprocess_options_2(OptionTable0, Target, GC_Method, TagsMethod,
TermNorm, TraceLevel, TraceSuppress, Error) -->
{ unsafe_promise_unique(OptionTable0, OptionTable1) }, % XXX
globals__io_init(OptionTable1, Target, GC_Method, TagsMethod,
TermNorm, TraceLevel, TraceSuppress),
% Conservative GC implies --no-reclaim-heap-*
( { gc_is_conservative(GC_Method) = yes } ->
globals__io_set_option(
reclaim_heap_on_semidet_failure, bool(no)),
globals__io_set_option(
reclaim_heap_on_nondet_failure, bool(no))
;
[]
),
% --tags none implies --num-tag-bits 0.
( { TagsMethod = none } ->
{ NumTagBits0 = 0 }
;
globals__io_lookup_int_option(num_tag_bits, NumTagBits0)
),
% if --tags low but --num-tag-bits not specified,
% use the autoconf-determined value for --num-tag-bits
% (the autoconf-determined value is passed from the `mc' script
% using the undocumented --conf-low-tag-bits option)
(
{ TagsMethod = low },
{ NumTagBits0 = -1 }
->
globals__io_lookup_int_option(conf_low_tag_bits, NumTagBits1)
;
{ NumTagBits1 = NumTagBits0 }
),
% if --num-tag-bits negative or unspecified, issue a warning
% and assume --num-tag-bits 0
( { NumTagBits1 < 0 } ->
io__progname_base("mercury_compile", ProgName),
report_warning(ProgName),
report_warning(
": warning: --num-tag-bits invalid or unspecified\n"),
io__write_string(ProgName),
report_warning(": using --num-tag-bits 0 (tags disabled)\n"),
{ NumTagBits = 0 }
;
{ NumTagBits = NumTagBits1 }
),
globals__io_set_option(num_tag_bits, int(NumTagBits)),
% Generating IL implies:
% - gc_method `none' and no heap reclamation on failure
% Because GC is handled automatically by the .NET CLR
% implementation.
% - high-level code
% Because only the MLDS back-end supports
% compiling to IL, not the LLDS back-end.
% - turning off nested functions
% Because IL doesn't support nested functions.
% - using copy-out for nondet output arguments
% For reasons explained in the paper "Compiling Mercury
% to the .NET Common Language Runtime"
% - using no tags
% Because IL doesn't provide any mechanism for tagging
% pointers.
% - boxing enums and disabling no_tag_types
% These are both required to ensure that we have a uniform
% representation (`object[]') for all data types,
% which is required to avoid type errors for code using
% abstract data types.
% XXX It should not be needed once we have a general solution
% to the abstract equivalence type problem.
% - no static ground terms
% XXX Previously static ground terms used to not work with
% --high-level-data. But this has been (mostly?) fixed now.
% So we should investigate re-enabling static ground terms.
% - intermodule optimization
% This is only required for high-level data and is needed
% so that abstract equivalence types can be expanded. They
% need to be expanded because .NET requires that the structural
% representation of a type is known at all times.
( { Target = il } ->
globals__io_set_gc_method(none),
globals__io_set_option(reclaim_heap_on_nondet_failure,
bool(no)),
globals__io_set_option(reclaim_heap_on_semidet_failure,
bool(no)),
globals__io_set_option(highlevel_code, bool(yes)),
globals__io_set_option(gcc_nested_functions, bool(no)),
globals__io_set_option(nondet_copy_out, bool(yes)),
globals__io_set_option(num_tag_bits, int(0)),
globals__io_set_option(unboxed_enums, bool(no)),
globals__io_set_option(unboxed_no_tag_types, bool(no)),
globals__io_set_option(static_ground_terms, bool(no)),
globals__io_lookup_bool_option(highlevel_data, HighLevelData),
( { HighLevelData = yes } ->
globals__io_set_option(intermodule_optimization,
bool(yes))
;
[]
)
;
[]
),
% Set --put-nondet-env-on-heap if --verifiable-code is specified,
% unless both --il-funcptr-types and --il-refany-fields
% are specified.
globals__io_lookup_bool_option(il_funcptr_types, ILFuncPtrTypes),
globals__io_lookup_bool_option(il_refany_fields, ILRefAnyFields),
( { ILFuncPtrTypes = yes, ILRefAnyFields = yes } ->
[]
;
option_implies(verifiable_code, put_nondet_env_on_heap,
bool(yes))
),
% Generating Java implies
% - gc_method `none' and no heap reclamation on failure
% Because GC is handled automatically by the Java
% implementation.
% - high-level code
% Because only the MLDS back-end supports
% compiling to Java, not the LLDS back-end.
% - high-level data
% Because it is more efficient,
% and better for interoperability.
% (In theory --low-level-data should work too,
% but there's no reason to bother supporting it.)
% - turning off nested functions
% Because Java doesn't support nested functions.
% - using copy-out for both det and nondet output arguments
% Because Java doesn't support pass-by-reference.
% - using no tags
% Because Java doesn't provide any mechanism for tagging
% pointers.
% - store nondet environments on the heap
% Because Java has no way of allocating structs on the stack.
% - no static ground terms
% XXX Previously static ground terms used to not work with
% --high-level-data. But this has been (mostly?) fixed now.
% So we should investigate re-enabling static ground terms.
( { Target = java } ->
globals__io_set_gc_method(none),
globals__io_set_option(reclaim_heap_on_nondet_failure,
bool(no)),
globals__io_set_option(reclaim_heap_on_semidet_failure,
bool(no)),
globals__io_set_option(highlevel_code, bool(yes)),
globals__io_set_option(highlevel_data, bool(yes)),
globals__io_set_option(gcc_nested_functions, bool(no)),
globals__io_set_option(nondet_copy_out, bool(yes)),
globals__io_set_option(det_copy_out, bool(yes)),
globals__io_set_option(num_tag_bits, int(0)),
globals__io_set_option(static_ground_terms, bool(no)),
globals__io_set_option(put_nondet_env_on_heap, bool(yes))
;
[]
),
% Generating assembler via the gcc back-end requires
% using high-level code.
( { Target = asm } ->
globals__io_set_option(highlevel_code, bool(yes))
;
[]
),
% Generating high-level C or asm code requires putting each commit
% in its own function, to avoid problems with setjmp() and
% non-volatile local variables.
( { Target = c ; Target = asm } ->
option_implies(highlevel_code, put_commit_in_own_func,
bool(yes))
;
[]
),
% --high-level-code disables the use of low-level gcc extensions
option_implies(highlevel_code, gcc_non_local_gotos, bool(no)),
option_implies(highlevel_code, gcc_global_registers, bool(no)),
option_implies(highlevel_code, asm_labels, bool(no)),
% --no-gcc-nested-functions implies --no-gcc-local-labels
option_neg_implies(gcc_nested_functions, gcc_local_labels, bool(no)),
% --no-mlds-optimize implies --no-optimize-tailcalls
option_neg_implies(optimize, optimize_tailcalls, bool(no)),
% make.m controls generating object code and linking itself,
% so mercury_compile.m should only generate target code when
% given a module to process.
option_implies(make, compile_only, bool(yes)),
option_implies(make, target_code_only, bool(yes)),
% This is needed for library installation (the library grades
% are built using `--use-grade-subdirs', and assume that
% the interface files were built using `--use-subdirs').
option_implies(make, use_subdirs, bool(yes)),
option_implies(invoked_by_mmc_make, use_subdirs, bool(yes)),
option_implies(verbose_check_termination, check_termination,bool(yes)),
option_implies(check_termination, termination, bool(yes)),
option_implies(check_termination, warn_missing_trans_opt_files,
bool(yes)),
option_implies(infer_structure_reuse, infer_possible_aliases,
bool(yes)),
option_implies(infer_possible_aliases, warn_missing_trans_opt_files,
bool(yes)),
option_implies(infer_possible_aliases, transitive_optimization,
bool(yes)),
option_implies(infer_possible_aliases, read_opt_files_transitively,
bool(yes)),
option_implies(make_transitive_opt_interface, transitive_optimization,
bool(yes)),
option_implies(transitive_optimization, intermodule_optimization,
bool(yes)),
option_implies(use_trans_opt_files, use_opt_files, bool(yes)),
% If we are doing full inter-module or transitive optimization,
% we need to build all `.opt' or `.trans_opt' files.
option_implies(intermodule_optimization, use_opt_files, bool(no)),
option_implies(transitive_optimization, use_trans_opt_files, bool(no)),
% option_implies(make_optimization_interface, use_trans_opt_files, bool(no)),
% XXX This should be checked in the near future or a merge
% towards using smart_recompilation should be done.
% when doing possible alias analysis, for the moment we
% don't want everything to be rebuild each time -- so let's
% put those use_*opt_files back to yes.
% possible aliases does not use opt_files, but it does use
% trans_opt files ! This is also to avoid some bizar problems
% where when Mmake-ing modules, the modules are in fact compiled
% twice, std-err is sent to std-out etc...
% option_implies(infer_possible_aliases, use_opt_files, bool(yes)),
% option_implies(infer_possible_aliases, use_trans_opt_files, bool(yes)),
% XXX `--use-opt-files' is broken.
% When inter-module optimization is enabled, error checking
% without the extra information from the `.opt' files
% is done when making the `.opt' file. With `--use-opt-files',
% that doesn't happen.
globals__io_set_option(use_opt_files, bool(no)),
option_implies(smart_recompilation, generate_item_version_numbers,
bool(yes)),
option_implies(find_all_recompilation_reasons, verbose_recompilation,
bool(yes)),
%
% Disable `--smart-recompilation' for compilation options
% which either do not produce a compiled output file or
% for which smart recompilation will not work.
%
option_implies(generate_dependencies, smart_recompilation, bool(no)),
option_implies(convert_to_mercury, smart_recompilation, bool(no)),
option_implies(make_private_interface, smart_recompilation, bool(no)),
option_implies(make_interface, smart_recompilation, bool(no)),
option_implies(make_short_interface, smart_recompilation, bool(no)),
option_implies(output_grade_string, smart_recompilation, bool(no)),
option_implies(make_optimization_interface,
smart_recompilation, bool(no)),
option_implies(make_transitive_opt_interface,
smart_recompilation, bool(no)),
option_implies(errorcheck_only, smart_recompilation, bool(no)),
option_implies(typecheck_only, smart_recompilation, bool(no)),
% disable --line-numbers when building the `.int', `.opt', etc. files,
% since including line numbers in those would cause unnecessary
% recompilation
option_implies(make_private_interface, line_numbers, bool(no)),
option_implies(make_interface, line_numbers, bool(no)),
option_implies(make_short_interface, line_numbers, bool(no)),
option_implies(make_optimization_interface, line_numbers, bool(no)),
option_implies(make_transitive_opt_interface, line_numbers, bool(no)),
% `--aditi-only' is only used by the Aditi query shell,
% for queries which should only be compiled once.
% recompilation_check.m currently doesn't check whether
% the `.rlo' file is up to date (with `--no-aditi-only' the
% Aditi-RL bytecode is embedded in the `.c' file.
option_implies(aditi_only, smart_recompilation, bool(no)),
% We never use version number information in `.int3',
% `.opt' or `.trans_opt' files.
option_implies(make_short_interface, generate_item_version_numbers,
bool(no)),
% XXX Smart recompilation does not yet work with inter-module
% optimization, but we still want to generate version numbers
% in interface files for users of a library compiled with
% inter-module optimization but not using inter-module
% optimization themselves.
globals__io_lookup_bool_option(smart_recompilation, Smart),
maybe_disable_smart_recompilation(Smart, intermodule_optimization, yes,
"`--intermodule-optimization'"),
maybe_disable_smart_recompilation(Smart, use_opt_files, yes,
"`--use-opt-files'"),
% XXX Smart recompilation does not yet work with
% `--no-target-code-only'. With `--no-target-code-only'
% it becomes difficult to work out what all the target
% files are and check whether they are up-to-date.
% By default, mmake always enables `--target-code-only' and
% processes the target code file itself, so this isn't a problem.
maybe_disable_smart_recompilation(Smart, target_code_only, no,
"`--no-target-code-only'"),
% --rebuild is just like --make but always rebuilds the files
% without checking timestamps.
option_implies(rebuild, make, bool(yes)),
option_implies(use_grade_subdirs, use_subdirs, bool(yes)),
% --make handles creation of the module dependencies itself,
% and they don't need to be recreated when compiling to C.
option_implies(invoked_by_mmc_make,
generate_mmc_make_module_dependencies, bool(no)),
option_implies(invoked_by_mmc_make, make, bool(no)),
option_implies(invoked_by_mmc_make, rebuild, bool(no)),
% --make does not handle --transitive-intermodule-optimization.
% --transitive-intermodule-optimization is in the process of
% being rewritten anyway.
option_implies(make, transitive_optimization, bool(no)),
option_implies(very_verbose, verbose, bool(yes)),
option_implies(verbose, verbose_commands, bool(yes)),
globals__io_lookup_int_option(debug_liveness, DebugLiveness),
(
{ DebugLiveness >= 0 },
{ convert_dump_alias("all", AllDumpOptions) }
->
% Programmers only enable --debug-liveness if they are
% interested in the goal annotations put on goals by
% the various phases of the liveness pass. The default
% dump options do not print these annotations.
globals__io_lookup_string_option(dump_hlds_options,
DumpOptions0),
{ string__append(DumpOptions0, AllDumpOptions, DumpOptions) },
globals__io_set_option(dump_hlds_options, string(DumpOptions))
;
[]
),
% --split-c-files is not supported by the high-level C code generator.
option_implies(highlevel_code, split_c_files, bool(no)),
% --split-c-files implies --procs-per-c-function 1
option_implies(split_c_files, procs_per_c_function, int(1)),
% Minimal model tabling is not compatible with trailing;
% see the comment in runtime/mercury_tabling.c.
globals__io_lookup_bool_option(use_trail, UseTrail),
globals__io_lookup_bool_option(use_minimal_model, UseMinimalModel),
{ UseTrail = yes, UseMinimalModel = yes ->
Error = yes("trailing and minimal model tabling are not compatible")
;
Error = no
},
% The `.debug' grade (i.e. --stack-trace plus --require-tracing)
% implies --use-trail, except with --use-minimal-model, which is
% not compatible with --use-trail.
%
% The reason for this is to avoid unnecessary proliferation in
% the number of different grades. If you're using --debug,
% you've already taken a major performance hit, so you should
% be able to afford the minor performance hit caused by
% --use-trail.
globals__io_lookup_bool_option(stack_trace, StackTrace),
globals__io_lookup_bool_option(require_tracing, RequireTracing),
( { StackTrace = yes, RequireTracing = yes, UseMinimalModel = no } ->
globals__io_set_option(use_trail, bool(yes))
;
[]
),
% --trace-table-io-decl is an extension of --trace-table-io
option_implies(trace_table_io_decl, trace_table_io, bool(yes)),
% --trace-table-io-require is compulsory application of --trace-table-io
option_implies(trace_table_io_require, trace_table_io, bool(yes)),
% Execution tracing requires
% - disabling optimizations that would change
% the trace being generated (except with --trace-optimized)
% - enabling some low level optimizations to ensure consistent
% paths across optimization levels
% - enabling stack layouts
% - enabling typeinfo liveness
globals__io_lookup_bool_option(trace_optimized, TraceOptimized),
( { given_trace_level_is_none(TraceLevel) = no } ->
( { TraceOptimized = no } ->
% The following options modify the structure
% of the program, which makes it difficult to
% relate the trace to the source code (although
% it can be easily related to the transformed HLDS).
globals__io_set_option(inline_simple, bool(no)),
globals__io_set_option(inline_single_use, bool(no)),
globals__io_set_option(inline_compound_threshold,
int(0)),
globals__io_set_option(optimize_unused_args, bool(no)),
globals__io_set_option(optimize_higher_order, bool(no)),
globals__io_set_option(type_specialization, bool(no)),
globals__io_set_option(user_guided_type_specialization,
bool(no)),
globals__io_set_option(deforestation, bool(no)),
globals__io_set_option(constraint_propagation,
bool(no)),
globals__io_set_option(local_constraint_propagation,
bool(no)),
globals__io_set_option(optimize_duplicate_calls,
bool(no)),
globals__io_set_option(optimize_constructor_last_call,
bool(no)),
globals__io_set_option(optimize_saved_vars_cell,
bool(no))
;
[]
),
% Disable hijacks if debugging is enabled. The
% code we now use to restore the stacks for
% direct retries works only if the retry does not
% "backtrack" over a hijacked nondet stack frame
% whose hijack has not been undone. Note that
% code compiled without debugging may still hijack
% nondet stack frames. Execution may reemerge from
% the nondebugged region in one of two ways. If
% the nondebugged code returns, then it will have
% undone hijack, and the retry code will work. If
% the nondebugged code calls debugged code, there
% will be a region on the stacks containing no
% debugging information, and the retry command will
% refuse to perform retries that go into or beyond
% this region. Both cases preserve correctness.
%
% An alternative solution would be to store everything
% on the nondet stack that may be hijacked in ordinary
% stack slots on entry to every procedure, but that
% would be not only more complex than simply disabling
% hijacks, it would be slower as well, except in
% procedures that would have many nested hijacks,
% and such code is extremely rare.
globals__io_set_option(allow_hijacks, bool(no)),
% The following option prevents useless variables
% from cluttering the trace. Its explicit setting
% removes a source of variability in the goal paths
% reported by tracing.
globals__io_set_option(excess_assign, bool(yes)),
% The explicit setting of the following option
% removes a source of variability in the goal paths
% reported by tracing.
globals__io_set_option(follow_code, bool(yes)),
% The following option selects a special-case
% code generator that cannot (yet) implement tracing.
globals__io_set_option(middle_rec, bool(no)),
% The following options cause the info required
% by tracing to be generated.
globals__io_set_option(trace_stack_layout, bool(yes)),
globals__io_set_option(body_typeinfo_liveness, bool(yes)),
% To support up-level printing, we need to save
% variables across a call even if the call cannot
% succeed.
globals__io_set_option(opt_no_return_calls, bool(no))
;
[]
),
% Deep profiling will eventually use `procid' stack layouts,
% but for now, we use a separate copy of each MR_Proc_Id structure.
% option_implies(profile_deep, procid_stack_layout, bool(yes)),
globals__io_lookup_bool_option(profile_deep, ProfileDeep),
globals__io_lookup_bool_option(highlevel_code, HighLevel),
( { ProfileDeep = yes } ->
(
{ HighLevel = no },
{ Target = c }
->
[]
;
usage_error("deep profiling is incompatible with high level code")
),
globals__io_lookup_bool_option(
use_lots_of_ho_specialization, LotsOfHOSpec),
( { LotsOfHOSpec = yes } ->
{ True = bool(yes) },
globals__io_set_option(optimize_higher_order, True),
globals__io_set_option(higher_order_size_limit,
int(999999))
;
[]
)
;
[]
),
% --no-reorder-conj implies --no-deforestation,
% --no-constraint-propagation and --no-local-constraint-propagation.
option_neg_implies(reorder_conj, deforestation, bool(no)),
option_neg_implies(reorder_conj, constraint_propagation, bool(no)),
option_neg_implies(reorder_conj, local_constraint_propagation,
bool(no)),
% --stack-trace requires `procid' stack layouts
option_implies(stack_trace, procid_stack_layout, bool(yes)),
% `trace' stack layouts need `procid' stack layouts
option_implies(trace_stack_layout, procid_stack_layout, bool(yes)),
% --gc accurate requires `agc' stack layouts, typeinfo liveness,
% and needs hijacks and frameopt to be switched off.
( { GC_Method = accurate } ->
globals__io_set_option(agc_stack_layout, bool(yes)),
globals__io_set_option(body_typeinfo_liveness, bool(yes)),
globals__io_set_option(allow_hijacks, bool(no)),
globals__io_set_option(optimize_frames, bool(no))
;
[]
),
% ml_gen_params_base and ml_declare_env_ptr_arg, in ml_code_util.m,
% both assume (for accurate GC) that continuation environments
% are always allocated on the stack, which means that things won't
% if --gc accurate and --put-nondet-env-on-heap are both enabled.
globals__io_lookup_bool_option(put_nondet_env_on_heap,
PutNondetEnvOnHeap),
(
{ HighLevel = yes },
{ GC_Method = accurate },
{ PutNondetEnvOnHeap = yes }
->
usage_error("--gc accurate is incompatible with " ++
"--put-nondet-env-on-heap")
;
[]
),
% ml_gen_cont_params in ml_call_gen.m will call sorry/1
% if --gc accurate and --nondet-copy-out are both enabled.
globals__io_lookup_bool_option(nondet_copy_out, NondetCopyOut),
(
{ HighLevel = yes },
{ GC_Method = accurate },
{ NondetCopyOut = yes }
->
usage_error("--gc accurate is incompatible with " ++
"--nondet-copy-out")
;
[]
),
% `procid' and `agc' stack layouts need `basic' stack layouts
option_implies(procid_stack_layout, basic_stack_layout, bool(yes)),
option_implies(agc_stack_layout, basic_stack_layout, bool(yes)),
% dupelim.m doesn't preserve label layout structures
% (e.g. it can change the return address in a call
% to a different label whose code is the same but
% which has a different label layout structure),
% so we need to disable it when tracing.
option_implies(procid_stack_layout, optimize_dups, bool(no)),
% XXX deforestation and constraint propagation do not perform
% folding on polymorphic predicates correctly with
% --body-typeinfo-liveness.
option_implies(body_typeinfo_liveness, deforestation, bool(no)),
option_implies(body_typeinfo_liveness, constraint_propagation,
bool(no)),
% XXX if trailing is enabled, middle recursion optimization
% can generate code which does not allocate a stack frame
% even though stack slots are used to save and restore the
% trail, if the code being optimized contains a construct which
% might save/restore the trail state, i.e. an if-then-else,
% negation, disjunction, or commit.
option_implies(use_trail, middle_rec, bool(no)),
% Minimal model tabling needs to be able to rewrite all the redoips
% in a given nondet stack segments. If we allow hijacks, some of these
% redoips may have been saved in ordinary framevars, which means that
% tabling can't find them without label layout info. Since we want
% to allow tabling in grades that do not have label layout info,
% we disable hijacks instead.
option_implies(use_minimal_model, allow_hijacks, bool(no)),
% --dump-hlds and --statistics require compilation by phases
globals__io_lookup_accumulating_option(dump_hlds, DumpStages),
globals__io_lookup_bool_option(statistics, Statistics),
( { DumpStages \= [] ; Statistics = yes } ->
globals__io_set_option(trad_passes, bool(no))
;
[]
),
% If we are doing type-specialization, we may as well take
% advantage of the declarations supplied by the programmer.
option_implies(type_specialization, user_guided_type_specialization,
bool(yes)),
% The local constraint propagation transformation (constraint.m)
% is a required part of the constraint propagation transformation
% performed by deforest.m.
option_implies(constraint_propagation, local_constraint_propagation,
bool(yes)),
% --intermod-unused-args implies --intermodule-optimization and
% --optimize-unused-args.
option_implies(intermod_unused_args, intermodule_optimization,
bool(yes)),
option_implies(intermod_unused_args, optimize_unused_args, bool(yes)),
% --introduce-accumulators implies --excess-assign and
% --common-struct.
option_implies(introduce_accumulators, excess_assign, bool(yes)),
option_implies(introduce_accumulators, common_struct, bool(yes)),
% Don't do the unused_args optimization when making the
% optimization interface.
option_implies(make_optimization_interface, optimize_unused_args,
bool(no)),
% The information needed for generating the module ordering
% is only available while generating the dependencies.
option_implies(generate_module_order, generate_dependencies,
bool(yes)),
% We only generate the source file mapping if the module name
% doesn't match the file name.
option_implies(generate_source_file_mapping, warn_wrong_module_name,
bool(no)),
% --aditi-only implies --aditi.
option_implies(aditi_only, aditi, bool(yes)),
% Set --aditi-user to the value of $USER if it is not set already.
% If $USER is not set, use the string "guest".
globals__io_lookup_string_option(aditi_user, User0),
( { User0 = "" } ->
io__get_environment_var("USER", MaybeUser),
( { MaybeUser = yes(User1) } ->
{ User = User1 }
;
{ User = "guest" }
),
globals__io_set_option(aditi_user, string(User))
;
[]
),
%
% Add the standard library directory.
%
globals__io_lookup_maybe_string_option(
mercury_standard_library_directory, MaybeStdLibDir),
( { MaybeStdLibDir = yes(StdLibDir) } ->
globals__io_get_globals(Globals2),
{ globals__get_options(Globals2, OptionTable2) },
{ globals__set_options(Globals2,
option_table_add_mercury_library_directory(
OptionTable2, StdLibDir),
Globals3) },
{ unsafe_promise_unique(Globals3, Globals4) },
globals__io_set_globals(Globals4)
;
[]
),
%
% Handle the `.opt', C header and library search directories.
% These couldn't be handled by options.m because they are grade
% dependent.
%
globals__io_lookup_accumulating_option(mercury_library_directories,
MercuryLibDirs),
globals__io_lookup_string_option(fullarch, FullArch),
globals__io_get_globals(Globals),
{ grade_directory_component(Globals, GradeString) },
(
{ MercuryLibDirs = [_|_] },
{ ExtraLinkLibDirs = list__map(
(func(MercuryLibDir) =
MercuryLibDir/"lib"/GradeString/FullArch
), MercuryLibDirs) },
globals__io_lookup_accumulating_option(
link_library_directories, LinkLibDirs),
globals__io_set_option(link_library_directories,
accumulating(LinkLibDirs ++ ExtraLinkLibDirs)),
{ ExtraCIncludeDirs = list__map(
(func(MercuryLibDir) =
MercuryLibDir/"lib"/GradeString/FullArch/"inc"
), MercuryLibDirs) },
globals__io_lookup_accumulating_option(c_include_directory,
CIncludeDirs),
globals__io_set_option(c_include_directory,
accumulating(ExtraCIncludeDirs ++ CIncludeDirs)),
{ ExtraIntermodDirs = list__map(
(func(MercuryLibDir) =
dir__make_path_name(MercuryLibDir,
dir__make_path_name("ints",
GradeString
))
), MercuryLibDirs) },
globals__io_lookup_accumulating_option(intermod_directories,
IntermodDirs0),
globals__io_set_option(intermod_directories,
accumulating(ExtraIntermodDirs ++ IntermodDirs0))
;
{ MercuryLibDirs = [] }
),
% If --use-search-directories-for-intermod is true, append the
% search directories to the list of directories to search for
% .opt files.
globals__io_lookup_bool_option(use_search_directories_for_intermod,
UseSearchDirs),
( { UseSearchDirs = yes } ->
globals__io_lookup_accumulating_option(intermod_directories,
IntermodDirs1),
globals__io_lookup_accumulating_option(search_directories,
SearchDirs),
globals__io_set_option(intermod_directories,
accumulating(IntermodDirs1 ++ SearchDirs))
;
[]
),
globals__io_lookup_bool_option(use_grade_subdirs, UseGradeSubdirs),
( { UseGradeSubdirs = yes } ->
%
% With `--use-grade-subdirs', `.opt', `.trans_opt' and
% `.mih' files are placed in a directory named
% `Mercury/<grade>/<fullarch>/Mercury/<ext>s'.
% When searching for a `.opt' file, module_name_to_file_name
% produces `Mercury/<ext>/<module>.ext' so that searches
% for installed files work, so we need to add
% `--intermod-directory Mercury/<grade>/<fullarch>'
% to find the `.opt' files in the current directory.
%
globals__io_lookup_accumulating_option(intermod_directories,
IntermodDirs2),
{ GradeSubdirIntermodDirs =
["Mercury"/GradeString/FullArch |
list__filter(isnt(unify(dir__this_directory)),
IntermodDirs2)] },
globals__io_set_option(intermod_directories,
accumulating(GradeSubdirIntermodDirs))
;
[]
),
%
% When searching for a header (.mh or .mih) file,
% module_name_to_file_name uses the plain header
% name, so we need to add the full path to the
% header files in the current directory.
%
globals__io_lookup_bool_option(use_subdirs, UseSubdirs),
(
{ UseGradeSubdirs = yes ->
MihsSubdir =
"Mercury"/GradeString/FullArch/"Mercury"/"mihs"
; UseSubdirs = yes ->
MihsSubdir = "Mercury"/"mihs"
;
fail
}
->
globals__io_lookup_accumulating_option(c_include_directory,
CIncludeDirs1),
{ SubdirCIncludeDirs =
[dir__this_directory, MihsSubdir | CIncludeDirs1] },
globals__io_set_option(c_include_directory,
accumulating(SubdirCIncludeDirs))
;
[]
),
% --use-opt-files implies --no-warn-missing-opt-files since
% we are expecting some to be missing.
option_implies(use_opt_files, warn_missing_opt_files, bool(no)),
% --warn-non-tail-recursion requires both --high-level-code
% and --optimize-tailcalls. It also doesn't work if you use
% --errorcheck-only.
option_requires(warn_non_tail_recursion, highlevel_code, bool(yes),
"--warn-non-tail-recursion requires --high-level-code"),
option_requires(warn_non_tail_recursion, optimize_tailcalls, bool(yes),
"--warn-non-tail-recursion requires --optimize-tailcalls"),
option_requires(warn_non_tail_recursion, errorcheck_only, bool(no),
"--warn-non-tail-recursion is incompatible with --errorcheck-only"),
% The backend foreign languages depend on the target.
(
{ Target = c },
{ BackendForeignLanguages = ["c"] }
;
{ Target = il },
{ BackendForeignLanguages = ["il", "csharp", "mc++"] }
;
{ Target = asm },
% XXX This is wrong! It should be asm.
{ BackendForeignLanguages = ["c"] }
;
% XXX We don't generate java or handle it as a foreign
% language just yet, but if we did, we should fix this
{ Target = java },
{ BackendForeignLanguages = [] }
),
% only set the backend foreign languages if they are unset
globals__io_lookup_accumulating_option(backend_foreign_languages,
CurrentBackendForeignLanguage),
(
{ CurrentBackendForeignLanguage = [] }
->
globals__io_set_option(backend_foreign_languages,
accumulating(BackendForeignLanguages))
;
[]
),
globals__io_lookup_int_option(compare_specialization, CompareSpec),
( { CompareSpec < 0 } ->
% This indicates that the option was not set by the user;
% we should set the option to the default value. This value
% may be back end specific, since different back ends have
% different performance tradeoffs.
(
{ HighLevel = no },
globals__io_set_option(compare_specialization, int(13))
;
{ HighLevel = yes },
globals__io_set_option(compare_specialization, int(14))
)
;
[]
),
( { HighLevel = no } ->
postprocess_options_lowlevel
;
[]
).
% These option implications only affect the low-level (LLDS) code
% generator. They may in fact be harmful if set for the high-level
% code generator, because sometimes the same option has different
% meanings and implications in the two backends.
%
:- pred postprocess_options_lowlevel(io__state::di, io__state::uo) is det.
postprocess_options_lowlevel -->
% --no-lazy-code assumes that const(_) rvals are really
% constant, and that create(_) rvals with constant arguments
% can be materialized in an assignable rval without further
% code. For float_consts, the former is true only if either
% static_ground_terms or unboxed_floats is true, and the latter
% cannot be true without static_ground_terms.
option_neg_implies(lazy_code, static_ground_terms, bool(yes)),
% --no-lazy-code requires --follow-vars for acceptable
% performance.
option_neg_implies(lazy_code, follow_vars, bool(yes)),
% --optimize-saved-vars-cell requires --use-local-vars for
% acceptable performance.
option_implies(optimize_saved_vars_cell, use_local_vars, bool(yes)),
% --optimize-frames requires --optimize-labels and
% --optimize-jumps
option_implies(optimize_frames, optimize_labels, bool(yes)),
option_implies(optimize_frames, optimize_jumps, bool(yes)).
% option_implies(SourceBoolOption, ImpliedOption, ImpliedOptionValue, IO0, IO).
% If the SourceBoolOption is set to yes, then the ImpliedOption is set
% to ImpliedOptionValue.
:- pred option_implies(option::in, option::in, option_data::in,
io__state::di, io__state::uo) is det.
option_implies(SourceOption, ImpliedOption, ImpliedOptionValue) -->
globals__io_lookup_bool_option(SourceOption, SourceOptionValue),
( { SourceOptionValue = yes } ->
globals__io_set_option(ImpliedOption, ImpliedOptionValue)
;
[]
).
% option_neg_implies(SourceBoolOption, ImpliedOption,
% ImpliedOptionValue, IO0, IO).
% If the SourceBoolOption is set to no, then the ImpliedOption is set
% to ImpliedOptionValue.
:- pred option_neg_implies(option::in, option::in, option_data::in,
io__state::di, io__state::uo) is det.
option_neg_implies(SourceOption, ImpliedOption, ImpliedOptionValue) -->
globals__io_lookup_bool_option(SourceOption, SourceOptionValue),
( { SourceOptionValue = no } ->
globals__io_set_option(ImpliedOption, ImpliedOptionValue)
;
[]
).
% option_requires(SourceBoolOption, RequiredOption, RequiredOptionValue,
% ErrorMsg):
% If the SourceBoolOption is set to yes, and RequiredOption is not set
% to RequiredOptionValue, then report a usage error.
:- pred option_requires(option::in, option::in, option_data::in,
string::in, io__state::di, io__state::uo) is det.
option_requires(SourceOption, RequiredOption, RequiredOptionValue,
ErrorMessage) -->
globals__io_lookup_bool_option(SourceOption, SourceOptionValue),
globals__io_lookup_option(RequiredOption, OptionValue),
( { SourceOptionValue = yes, OptionValue \= RequiredOptionValue } ->
usage_error(ErrorMessage)
;
[]
).
% Smart recompilation does not yet work with all
% options (in particular `--intermodule-optimization'
% and `--no-target-code-only'). Disable smart recompilation
% if such an option is set, maybe issuing a warning.
:- pred maybe_disable_smart_recompilation(bool::in, option::in, bool::in,
string::in, io__state::di, io__state::uo) is det.
maybe_disable_smart_recompilation(Smart, ConflictingOption,
ValueToDisableSmart, OptionDescr) -->
globals__io_lookup_bool_option(ConflictingOption, Value),
(
{ Smart = yes },
{ Value = ValueToDisableSmart }
->
disable_smart_recompilation(OptionDescr)
;
[]
).
:- pred disable_smart_recompilation(string::in,
io__state::di, io__state::uo) is det.
disable_smart_recompilation(OptionDescr) -->
globals__io_set_option(smart_recompilation, bool(no)),
globals__io_lookup_bool_option(warn_smart_recompilation,
WarnSmart),
( { WarnSmart = yes } ->
io__write_string(
"Warning: smart recompilation does not yet work with "),
io__write_string(OptionDescr),
io__write_string(".\n"),
globals__io_lookup_bool_option(halt_at_warn, Halt),
( { Halt = yes } ->
io__set_exit_status(1)
;
[]
)
;
[]
).
usage_error(ErrorDescr, ErrorMessage) -->
write_program_name,
io__write_string(ErrorDescr),
io__nl,
usage_error(ErrorMessage).
usage_error(ErrorMessage) -->
write_program_name,
io__write_string(ErrorMessage),
io__write_string("\n"),
io__set_exit_status(1),
usage.
:- pred write_program_name(io__state::di, io__state::uo) is det.
write_program_name -->
io__progname_base("mercury_compile", ProgName),
io__write_string(ProgName),
io__write_string(": ").
usage -->
{ library__version(Version) },
io__write_strings([
"Mercury Compiler, version ", Version, "\n",
"Copyright (C) 1993-2000 The University of Melbourne\n",
"Usage: mmc [<options>] <arguments>\n",
"Use `mmc --help' for more information.\n"
]).
long_usage -->
{ library__version(Version) },
io__write_strings(["Mercury Compiler, version ", Version, "\n"]),
io__write_string("Copyright (C) 1993-2000 The University of Melbourne\n"),
io__write_string("Usage: mmc [<options>] <arguments>\n"),
io__write_string("Arguments:\n"),
io__write_string("\tArguments ending in `.m' are assumed to be source file names.\n"),
io__write_string("\tArguments that do not end in `.m' are assumed to be module names.\n"),
io__write_string("Options:\n"),
options_help.
%-----------------------------------------------------------------------------%
% IMPORTANT: any changes here may require similar changes to
% runtime/mercury_grade.h
% scripts/parse_grade_options.sh-subr
% scripts/canonical_grade.sh-subr
%
% The grade_component type should have one constructor for each
% dimension of the grade. It is used when converting the components
% of the grade string to make sure the grade string doesn't contain
% more than one value for each dimension (eg *.gc.agc).
% Adding a value here will require adding clauses to the
% grade_component_table.
%
% A --grade option causes all the grade dependent options to be
% reset, and only those described by the grade string to be set.
% The value to which a grade option should be reset should be given
% in the grade_start_values table below.
%
% The ordering of the components here is the same as the order
% used in scripts/ml.in, and any change here will require a
% corresponding change there. The only place where the ordering
% actually matters is for constructing the pathname for the
% grade of the library, etc for linking (and installation).
:- type grade_component
---> gcc_ext % gcc extensions etc. -- see
% grade_component_table
; par % parallelism / multithreading
; gc % the kind of GC to use
; prof % what profiling options to use
; trail % whether or not to use trailing
; tag % whether or not to reserve a tag
; minimal_model % whether we set up for minimal model tabling
; pic % Do we need to reserve a register for
% PIC (position independent code)?
; trace % tracing/debugging options
.
convert_grade_option(GradeString, Options0, Options) :-
reset_grade_options(Options0, Options1),
split_grade_string(GradeString, Components),
set__init(NoComps),
list__foldl2(lambda([CompStr::in, Opts0::in, Opts::out,
CompSet0::in, CompSet::out] is semidet, (
grade_component_table(CompStr, Comp, CompOpts),
% Check that the component isn't mentioned
% more than once.
\+ set__member(Comp, CompSet0),
set__insert(CompSet0, Comp, CompSet),
add_option_list(CompOpts, Opts0, Opts)
)), Components, Options1, Options, NoComps, _FinalComps).
:- pred add_option_list(list(pair(option, option_data)), option_table,
option_table).
:- mode add_option_list(in, in, out) is det.
add_option_list(CompOpts, Opts0, Opts) :-
list__foldl(lambda([Opt::in, Opts1::in, Opts2::out] is det, (
Opt = Option - Data,
map__set(Opts1, Option, Data, Opts2)
)), CompOpts, Opts0, Opts).
grade_directory_component(Globals, Grade) :-
compute_grade(Globals, Grade0),
%
% Strip out the `.picreg' part of the grade -- `.picreg' is
% implied by the file names (.pic_o vs .o, `.a' vs `.so').
%
(
string__sub_string_search(Grade0,
".picreg", PicRegIndex),
string__split(Grade0, PicRegIndex,
LeftPart, RightPart0),
string__append(".picreg", RightPart, RightPart0)
->
Grade = LeftPart ++ RightPart
;
Grade = Grade0
).
compute_grade(Globals, Grade) :-
globals__get_options(Globals, Options),
compute_grade_components(Options, Components),
(
Components = [],
Grade = "none"
;
Components = [_|_],
construct_string(Components, Grade)
).
:- pred construct_string(list(pair(grade_component, string)), string).
:- mode construct_string(in, out) is det.
construct_string([], "").
construct_string([_ - Bit|Bits], Grade) :-
(
Bits = [_|_],
construct_string(Bits, Grade0),
string__append_list([Bit, ".", Grade0], Grade)
;
Bits = [],
Grade = Bit
).
:- pred compute_grade_components(option_table,
list(pair(grade_component, string))).
:- mode compute_grade_components(in, out) is det.
compute_grade_components(Options, GradeComponents) :-
solutions(lambda([CompData::out] is nondet, (
grade_component_table(Name, Comp, CompOpts),
% For possible component of the grade string
% include it in the actual grade string if all
% the option setting that it implies are true.
% ie
% all [Opt, Value] (
% member(Opt - Value, CompOpts) =>
% map__search(Options, Opt, Value)
% )
\+ (
list__member(Opt - Value, CompOpts),
\+ map__search(Options, Opt, Value)
),
CompData = Comp - Name
)), GradeComponents).
:- pred grade_component_table(string, grade_component,
list(pair(option, option_data))).
:- mode grade_component_table(in, out, out) is semidet.
:- mode grade_component_table(out, in, out) is multi.
:- mode grade_component_table(out, out, out) is multi.
% Base components
% These specify the basic compilation model we use,
% including the choice of back-end and the use of gcc extensions.
grade_component_table("none", gcc_ext, [
asm_labels - bool(no),
gcc_non_local_gotos - bool(no),
gcc_global_registers - bool(no),
highlevel_code - bool(no),
gcc_nested_functions - bool(no),
highlevel_data - bool(no),
target - string("c")]).
grade_component_table("reg", gcc_ext, [
asm_labels - bool(no),
gcc_non_local_gotos - bool(no),
gcc_global_registers - bool(yes),
highlevel_code - bool(no),
gcc_nested_functions - bool(no),
highlevel_data - bool(no),
target - string("c")]).
grade_component_table("jump", gcc_ext, [
asm_labels - bool(no),
gcc_non_local_gotos - bool(yes),
gcc_global_registers - bool(no),
highlevel_code - bool(no),
gcc_nested_functions - bool(no),
highlevel_data - bool(no),
target - string("c")]).
grade_component_table("asm_jump", gcc_ext, [
asm_labels - bool(yes),
gcc_non_local_gotos - bool(yes),
gcc_global_registers - bool(no),
highlevel_code - bool(no),
gcc_nested_functions - bool(no),
highlevel_data - bool(no),
target - string("c")]).
grade_component_table("fast", gcc_ext, [
asm_labels - bool(no),
gcc_non_local_gotos - bool(yes),
gcc_global_registers - bool(yes),
highlevel_code - bool(no),
gcc_nested_functions - bool(no),
highlevel_data - bool(no),
target - string("c")]).
grade_component_table("asm_fast", gcc_ext, [
asm_labels - bool(yes),
gcc_non_local_gotos - bool(yes),
gcc_global_registers - bool(yes),
highlevel_code - bool(no),
gcc_nested_functions - bool(no),
highlevel_data - bool(no),
target - string("c")]).
grade_component_table("hl", gcc_ext, [
asm_labels - bool(no),
gcc_non_local_gotos - bool(no),
gcc_global_registers - bool(no),
highlevel_code - bool(yes),
gcc_nested_functions - bool(no),
highlevel_data - bool(yes)
% target can be either c or asm
]).
grade_component_table("hlc", gcc_ext, [
asm_labels - bool(no),
gcc_non_local_gotos - bool(no),
gcc_global_registers - bool(no),
highlevel_code - bool(yes),
gcc_nested_functions - bool(no),
highlevel_data - bool(no)
% target can be either c or asm
]).
grade_component_table("hl_nest", gcc_ext, [
asm_labels - bool(no),
gcc_non_local_gotos - bool(no),
gcc_global_registers - bool(no),
highlevel_code - bool(yes),
gcc_nested_functions - bool(yes),
highlevel_data - bool(yes)
% target can be either c or asm
]).
grade_component_table("hlc_nest", gcc_ext, [
asm_labels - bool(no),
gcc_non_local_gotos - bool(no),
gcc_global_registers - bool(no),
highlevel_code - bool(yes),
gcc_nested_functions - bool(yes),
highlevel_data - bool(no)
% target can be either c or asm
]).
grade_component_table("il", gcc_ext, [
asm_labels - bool(no),
gcc_non_local_gotos - bool(no),
gcc_global_registers - bool(no),
highlevel_code - bool(yes),
gcc_nested_functions - bool(no),
highlevel_data - bool(yes),
target - string("il")]).
grade_component_table("ilc", gcc_ext, [
asm_labels - bool(no),
gcc_non_local_gotos - bool(no),
gcc_global_registers - bool(no),
highlevel_code - bool(yes),
gcc_nested_functions - bool(no),
highlevel_data - bool(no),
target - string("il")]).
grade_component_table("java", gcc_ext, [
asm_labels - bool(no),
gcc_non_local_gotos - bool(no),
gcc_global_registers - bool(no),
gcc_nested_functions - bool(no),
highlevel_code - bool(yes),
highlevel_data - bool(yes),
target - string("java")]).
% Parallelism/multithreading components.
grade_component_table("par", par, [parallel - bool(yes)]).
% GC components
grade_component_table("gc", gc, [gc - string("boehm")]).
grade_component_table("mps", gc, [gc - string("mps")]).
grade_component_table("agc", gc, [gc - string("accurate")]).
% Profiling components
grade_component_table("prof", prof,
[profile_time - bool(yes), profile_calls - bool(yes),
profile_memory - bool(no), profile_deep - bool(no)]).
grade_component_table("proftime", prof,
[profile_time - bool(yes), profile_calls - bool(no),
profile_memory - bool(no), profile_deep - bool(no)]).
grade_component_table("profcalls", prof,
[profile_time - bool(no), profile_calls - bool(yes),
profile_memory - bool(no), profile_deep - bool(no)]).
grade_component_table("memprof", prof,
[profile_time - bool(no), profile_calls - bool(yes),
profile_memory - bool(yes), profile_deep - bool(no)]).
grade_component_table("profall", prof,
[profile_time - bool(yes), profile_calls - bool(yes),
profile_memory - bool(yes), profile_deep - bool(no)]).
grade_component_table("profdeep", prof,
[profile_time - bool(no), profile_calls - bool(no),
profile_memory - bool(no), profile_deep - bool(yes)]).
% Trailing components
grade_component_table("tr", trail, [use_trail - bool(yes)]).
% Tag reservation components
grade_component_table("rt", tag, [reserve_tag - bool(yes)]).
% Mimimal model tabling components
grade_component_table("mm", minimal_model, [use_minimal_model - bool(yes)]).
% Pic reg components
grade_component_table("picreg", pic, [pic_reg - bool(yes)]).
% Debugging/Tracing components
grade_component_table("debug", trace,
[stack_trace - bool(yes), require_tracing - bool(yes)]).
grade_component_table("trace", trace,
[stack_trace - bool(no), require_tracing - bool(yes)]).
grade_component_table("strce", trace,
[stack_trace - bool(yes), require_tracing - bool(no)]).
:- pred reset_grade_options(option_table, option_table).
:- mode reset_grade_options(in, out) is det.
reset_grade_options(Options0, Options) :-
aggregate(grade_start_values, lambda([Pair::in, Opts0::in, Opts::out]
is det, (
Pair = Option - Value,
map__set(Opts0, Option, Value, Opts)
)), Options0, Options).
:- pred grade_start_values(pair(option, option_data)).
:- mode grade_start_values(out) is multi.
grade_start_values(asm_labels - bool(no)).
grade_start_values(gcc_non_local_gotos - bool(no)).
grade_start_values(gcc_global_registers - bool(no)).
grade_start_values(highlevel_code - bool(no)).
grade_start_values(highlevel_data - bool(no)).
grade_start_values(gcc_nested_functions - bool(no)).
grade_start_values(parallel - bool(no)).
grade_start_values(gc - string("none")).
grade_start_values(profile_deep - bool(no)).
grade_start_values(profile_time - bool(no)).
grade_start_values(profile_calls - bool(no)).
grade_start_values(profile_memory - bool(no)).
grade_start_values(use_trail - bool(no)).
grade_start_values(reserve_tag - bool(no)).
grade_start_values(use_minimal_model - bool(no)).
grade_start_values(pic_reg - bool(no)).
grade_start_values(stack_trace - bool(no)).
grade_start_values(require_tracing - bool(no)).
:- pred split_grade_string(string, list(string)).
:- mode split_grade_string(in, out) is semidet.
split_grade_string(GradeStr, Components) :-
string__to_char_list(GradeStr, Chars),
split_grade_string_2(Chars, Components).
:- pred split_grade_string_2(list(char), list(string)).
:- mode split_grade_string_2(in, out) is semidet.
split_grade_string_2([], []).
split_grade_string_2(Chars, Components) :-
Chars = [_|_],
list__takewhile(char_is_not('.'), Chars, ThisChars, RestChars0),
string__from_char_list(ThisChars, ThisComponent),
Components = [ThisComponent|RestComponents],
(
RestChars0 = [_|RestChars], % discard the `.'
split_grade_string_2(RestChars, RestComponents)
;
RestChars0 = [],
RestComponents = []
).
:- pred char_is_not(char, char).
:- mode char_is_not(in, in) is semidet.
char_is_not(A, B) :-
A \= B.
%-----------------------------------------------------------------------------%
% This predicate converts a symbolic name for a set of verbosity options
% (a "dump alias") into the string consisting of those options' characters.
%
% The meanings of the option characters are documented by doc/user_guide.texi
% and by compiler/hlds_out.m. The latter is more authoritative :-)
%
% You are welcome to add more aliases.
:- pred convert_dump_alias(string, string).
:- mode convert_dump_alias(in, out) is semidet.
convert_dump_alias("ALL", "aAbcdfgilmnprstuvCIMPTU").
convert_dump_alias("all", "aAbcdfgilmnprstuvCMPT").
convert_dump_alias("codegen", "dfnprsu").
convert_dump_alias("vanessa", "ltuCIU").
convert_dump_alias("paths", "cP").
convert_dump_alias("petdr", "din").
convert_dump_alias("palias", "A").
convert_dump_alias("sr", "Ap").
convert_dump_alias("osv", "bcdglmnpruvP"). % for debugging
% --optimize-saved-vars-cell
More information about the developers
mailing list