Files
mercury/compiler/globals.m
Zoltan Somogyi e854a5f9d9 Major improvements to tabling, of two types.
Estimated hours taken: 32
Branches: main

Major improvements to tabling, of two types. The first is the implementation
of the loopcheck and memo forms of tabling for model_non procedures, and the
second is a start on the implementation of a new method of implementing
minimal model tabling, one that has the potential for a proper fix of the
problem that we currently merely detect with the pneg stack (the detection
is followed by a runtime abort). Since this new method relies on giving each
own generator its own stack, the grade component denoting it is "mmos"
(minimal model own stack). The true name of the existing method is changed
from "mm" to "mmsc" (minimal model stack copy). The grade component "mm"
is now a shorthand for "mmsc"; when the new method works, "mm" will be changed
to be a shorthand for "mmos".

configure.in:
scripts/canonical_grade.sh-subr:
scripts/init_grade_options.sh-subr:
scripts/parse_grade_options.sh-subr:
scripts/final_grade_options.sh-subr:
compiler/options.m:
	Handle the new way of handling minimal model grades.

scripts/mgnuc.in:
compiler/compile_target_code.m:
	Conform to the changes in minimal model grade options.

compiler/table_gen.m:
	Implement the transformations required by the loopcheck and memo
	tabling of model_non procedures, and the minimal model own stack
	transformation.

	The new implementation transformations use foreign_procs with extra
	args, since there is no point in implementing them both that way and
	with separate calls to library predicates. This required making the
	choice of which method to use at the top level of each transformation.

	Fix an oversight that hasn't caused problems yet but may in the future:
	mark goals wrapping the original goals as not impure for determinism
	computations.

compiler/handle_options.m:
	Handle the new arrangement of the options for minimal model tabling.
	Detect simultaneous calls for both forms of minimal model tabling,
	and generate an error message. Allow for more than one error message
	generated at once; report them all once rather than separately.

compiler/globals.m:
	Add a mechanism to allow a fix a problem detected by the changes
	to handle_options: the fact that we currently may generate a usage
	message more than once for invocations with more than one error.

compiler/mercury_compile.m:
compiler/make.program_target.m:
compiler/make.util.m:
	Use the new mechanism in handle_options to avoid generating duplicate
	usage messages.

compiler/error_util.m:
	Add a utility predicate for use by handle_options.

compiler/hlds_pred.m:
	Allow memo tabling for model_non predicates, and handle own stack
	tabling.

compiler/hlds_out.m:
	Print information about the modes of the arguments of foreign_procs,
	since this is useful in debugging transformations such as tabling
	that generate them.

compiler/prog_data.m:
compiler/layout_out.m:
compiler/prog_out.m:
runtime/mercury_stack_layout.h:
	Mention the new evaluation method.

compiler/goal_util.m:
	Change the predicates for creating calls and foreign_procs to allow
	more than one goal feature to be attached to the new goal. table_gen.m
	now uses this capability.

compiler/add_heap_ops.m:
compiler/add_trail_ops.m:
compiler/polymorphism.m:
compiler/simplify.m:
compiler/size_prof.m:
compiler/typecheck.m:
compiler/unify_proc.m:
	Conform to the changes in goal_util.

compiler/code_info.m:
compiler/make_hlds.m:
compiler/modules.m:
compiler/prog_io_pragma.m:
	Conform to the new the options controlling minimal model
	tabling.

compiler/prog_util.m:
	Add a utility predicate for use by table_gen.m.

library/std_util.m:
	Conform to the changes in the macros for minimal model tabling grades.

library/table_builtin.m:
	Add the types and predicates required by the new transformations.

	Delete an obsolete comment.

runtime/mercury_grade.h:
	Handle the new minimal model grade component.

runtime/mercury_conf_param.h:
	List macros controlling minimal model grades.

runtime/mercury_tabling.[ch]:
	Define the types needed by the new transformations,

	Implement the performance-critical predicates that need to be
	hand-written for memo tabling of model_non predicates.

	Add utility predicates for debugging.

runtime/mercury_tabling_preds.h:
	Add the implementations of the predicates required by the new
	transformations.

runtime/mercury_mm_own_stacks.[ch]:
	This new module contains the first draft of the implementation
	of the own stack implementation of minimal model tabling.

runtime/mercury_imp.h:
	Include the new file if the grade needs it.

runtime/Mmakefile:
	Mention the new files, and sort the lists of filenames.

runtime/mercury_tabling_macros.h:
	Add a macro for allocating answer blocks without requiring them to be
	pointed to directly by trie nodes.

runtime/mercury_minimal_model.[ch]:
	The structure type holding answer lists is now in mercury_tabling.h,
	since it is now also needed by memo tabling of model_non predicates.
	It no longer has a field for an answer num, because while it is ok
	to require a separate grade for debugging minimal model tabling,
	it is not ok to require a separate grade for debugging memo tabling
	of model_non predicates. Instead of printing the answer numbers,
	print the answers themselves when we need to identify solutions
	for debugging.

	Change function names, macro names, error messages etc where this is
	useful to distinguish the two kinds of minimal model tabling.

	Fix some oversights wrt transient registers.

runtime/mercury_context.[ch]:
runtime/mercury_engine.[ch]:
runtime/mercury_memory.[ch]:
runtime/mercury_wrapper.[ch]:
	With own stack tabling, each subgoal has its own context, so record
	the identity of the subgoal owning a context in the context itself.
	The main computation's context is the exception: it has no owner.

	Record not just the main context, but also the contexts of subgoals
	in the engine.

	Add variables for holding the sizes of the det and nondet stacks
	of the contexts of subgoals (which should in general be smaller
	than the sizes of the corresponding stacks of the main context),
	and initialize them as needed.

	Initialize the variables holding the sizes of the gen, cut and pneg
	stacks, even in grades where the stacks are not used, for safety.

	Fix some out-of-date documentation, and conform to our coding
	guidelines.

runtime/mercury_memory_zones.[ch]:
	Add a function to test whether a pointer is in a zone, to help
	debugging.

runtime/mercury_debug.[ch]:
	Add some functions to help debugging in the presence of multiple
	contexts, and factor out some common code to help with this.

	Delete the obsolete, unused function MR_printdetslot_as_label.

runtime/mercury_context.h:
runtime/mercury_bootstrap.h:
	Move a bootstrapping #define from mercury_context.h to
	mercury_bootstrap.h.

runtime/mercury_context.h:
runtime/mercury_bootstrap.h:
	Move a bootstrapping #define from mercury_context.h to
	mercury_bootstrap.h.

runtime/mercury_types.h:
	Add some more forward declarations of type names.

runtime/mercury_dlist.[ch]:
	Rename a field to avoid assignments that dereference NULL.

runtime/mercury_debug.c:
runtime/mercury_memory.c:
runtime/mercury_ml_expand_body.h:
runtime/mercury_stack_trace.c:
runtime/mercury_stacks.[ch]:
trace/mercury_trace_util.c
	Update uses of the macros that control minimal model tabling.

runtime/mercury_stack_trace.c:
	Provide a mechanism to allow stack traces to be suppressed entirely.
	The intention is that by using this mechanism, by the testing system
	won't have to provide separate .exp files for hlc grades, nondebug
	LLDS grades and debug LLDS grades, as we do currently. The mechanism
	is the environment variable MERCURY_SUPPRESS_STACK_TRACE.

tools/bootcheck:
tools/test_mercury:
	Specify MERCURY_SUPPRESS_STACK_TRACE.

trace/mercury_trace.c:
	When performing retries across tabled calls, handle memo tabled
	model_non predicates, for which the call table tip variable holds
	a record with a back pointer to a trie node, instead of the trie node
	itself.

trace/mercury_trace_internal.c:
	When printing tables, handle memo tabled model_non predicates. Delete
	the code now moved to runtime/mercury_tabling.c.

	Add functions for printing the data structures for own stack minimal
	model tabling.

tests/debugger/print_table.{m,inp,exp}:
	Update this test case to also test the printing of tables for
	memo tabled model_non predicates.

tests/debugger/retry.{m,inp,exp}:
	Update this test case to also test retries across memo tabled
	model_non predicates.

tests/tabling/loopcheck_nondet.{m,exp}:
tests/tabling/loopcheck_nondet_non_loop.{m,exp}:
	New test cases to test loopcheck tabled model_non predicates.
	One test case has a loop to detect, one doesn't.

tests/tabling/memo_non.{m,exp}:
tests/tabling/tc_memo.{m,exp}:
tests/tabling/tc_memo2.{m,exp}:
	New test cases to test memo tabled model_non predicates.
	One test case has a loop to detect, one has a need for minimal model
	tabling to detect, and the third doesn't have either.

tests/tabling/Mmakefile:
	Add the new test cases, and reenable the existing tc_loop test case.

	Rename some make variables and targets to make them better reflect
	their meaning.

tests/tabling/test_mercury:
	Conform to the change in the name of the make target.
2004-07-20 04:41:55 +00:00

604 lines
21 KiB
Mathematica

%-----------------------------------------------------------------------------%
% Copyright (C) 1994-2004 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.
%-----------------------------------------------------------------------------%
:- module libs__globals.
% Main author: fjh.
% This module exports the `globals' type and associated access predicates.
% The globals type is used to collect together all the various data
% that would be global variables in an imperative language.
% This global data is stored in the io__state.
%-----------------------------------------------------------------------------%
:- interface.
:- import_module libs__options.
:- import_module libs__trace_params.
:- import_module parse_tree.
:- import_module parse_tree__prog_data. % for module_name.
:- import_module bool, getopt, list, map, io, std_util.
:- type globals.
:- type compilation_target
---> c % Generate C code (including GNU C)
; il % Generate IL assembler code
% IL is the Microsoft .NET Intermediate Language
; java % Generate Java
% (Work in progress)
; asm. % Compile directly to assembler via the GCC back-end.
% Do not go via C, instead generate GCC's internal
% `tree' data structure.
% (Work in progress.)
:- type foreign_language
---> c
% ; cplusplus
; csharp
; managed_cplusplus
; java
; il.
% A string representation of the foreign language suitable
% for use in human-readable error messages
:- func foreign_language_string(foreign_language) = string.
% A string representation of the foreign language suitable
% for use in machine-readable name mangling.
:- func simple_foreign_language_string(foreign_language) = string.
% The GC method specifies how we do garbage collection.
% The last four alternatives are for the C and asm back-ends;
% the first alternative is for compiling to IL or Java,
% where the target language implementation handles garbage
% collection automatically.
%
:- type gc_method
---> automatic % It is the responsibility of the target language
% that we are compiling to to handle GC.
; none % No garbage collection.
% But memory may be recovered on backtracking,
% if the --reclaim-heap-on-*failure options are set.
; boehm % The Boehm et al conservative collector.
; mps % A different conservative collector, based on
% Ravenbrook Limited's MPS (Memory Pool System) kit.
% Benchmarking indicated that this one performed worse
% than the Boehm collector, so we don't really
% support this option anymore.
; accurate.
% Our own home-grown copying collector.
% See runtime/mercury_accurate_gc.c
% and compiler/ml_elim_nested.m.
% Returns yes if the GC method is conservative,
% i.e. if it is `boehm' or `mps'.
% Conservative GC methods don't support heap
% reclamation on failure.
:- func gc_is_conservative(gc_method) = bool.
:- type tags_method
---> none
; low
; high.
:- type termination_norm
---> simple
; total
; num_data_elems
; size_data_elems.
% Map from module name to file name.
:- type source_file_map == map(module_name, string).
:- pred convert_target(string::in, compilation_target::out) is semidet.
:- pred convert_foreign_language(string::in, foreign_language::out) is semidet.
:- pred convert_gc_method(string::in, gc_method::out) is semidet.
:- pred convert_tags_method(string::in, tags_method::out) is semidet.
:- pred convert_termination_norm(string::in, termination_norm::out) is semidet.
%-----------------------------------------------------------------------------%
% Access predicates for the `globals' structure.
:- pred globals__init(option_table::di, compilation_target::di, gc_method::di,
tags_method::di, termination_norm::di,
trace_level::di, trace_suppress_items::di, globals::uo) is det.
:- pred globals__get_options(globals::in, option_table::out) is det.
:- pred globals__get_target(globals::in, compilation_target::out) is det.
:- pred globals__get_backend_foreign_languages(globals::in,
list(foreign_language)::out) is det.
:- pred globals__get_gc_method(globals::in, gc_method::out) is det.
:- pred globals__get_tags_method(globals::in, tags_method::out) is det.
:- pred globals__get_termination_norm(globals::in, termination_norm::out)
is det.
:- pred globals__get_trace_level(globals::in, trace_level::out) is det.
:- pred globals__get_trace_suppress(globals::in, trace_suppress_items::out)
is det.
:- pred globals__get_source_file_map(globals::in, maybe(source_file_map)::out)
is det.
:- pred globals__set_options(option_table::in, globals::in, globals::out)
is det.
:- pred globals__set_gc_method(gc_method::in, globals::in, globals::out)
is det.
:- pred globals__set_tags_method(tags_method::in, globals::in, globals::out)
is det.
:- pred globals__set_trace_level(trace_level::in, globals::in, globals::out)
is det.
:- pred globals__set_trace_level_none(globals::in, globals::out) is det.
:- pred globals__set_source_file_map(maybe(source_file_map)::in,
globals::in, globals::out) is det.
:- pred globals__lookup_option(globals::in, option::in, option_data::out)
is det.
:- pred globals__lookup_bool_option(globals, option, bool).
:- mode globals__lookup_bool_option(in, in, out) is det.
:- mode globals__lookup_bool_option(in, in, in) is semidet. % implied
:- pred globals__lookup_int_option(globals::in, option::in, int::out) is det.
:- pred globals__lookup_string_option(globals::in, option::in, string::out)
is det.
:- pred globals__lookup_maybe_string_option(globals::in, option::in,
maybe(string)::out) is det.
:- pred globals__lookup_accumulating_option(globals::in, option::in,
list(string)::out) is det.
%-----------------------------------------------------------------------------%
% More complex options
% Check if static code addresses are available in the
% current grade of compilation.
:- pred globals__have_static_code_addresses(globals::in, bool::out) is det.
% Check if we should include variable information in the layout
% structures of call return sites.
:- pred globals__want_return_var_layouts(globals::in, bool::out) is det.
% globals__imported_is_constant(NonLocalGotos, AsmLabels, IsConst)
% figures out whether an imported label address is a constant.
% This depends on how we treat labels.
:- pred globals__imported_is_constant(bool::in, bool::in, bool::out) is det.
%-----------------------------------------------------------------------------%
% Access predicates for storing a `globals' structure in the
% io__state using io__set_globals and io__get_globals.
:- pred globals__io_init(option_table::di, compilation_target::in,
gc_method::in, tags_method::in,
termination_norm::in, trace_level::in, trace_suppress_items::in,
io::di, io::uo) is det.
:- pred globals__io_get_target(compilation_target::out, io::di, io::uo) is det.
:- pred globals__io_get_backend_foreign_languages(list(foreign_language)::out,
io::di, io::uo) is det.
:- pred globals__io_lookup_foreign_language_option(option::in,
foreign_language::out, io::di, io::uo) is det.
:- pred globals__io_get_gc_method(gc_method::out, io::di, io::uo) is det.
:- pred globals__io_get_tags_method(tags_method::out, io::di, io::uo) is det.
:- pred globals__io_get_termination_norm(termination_norm::out,
io::di, io::uo) is det.
:- pred globals__io_get_trace_level(trace_level::out, io::di, io::uo) is det.
:- pred globals__io_get_trace_suppress(trace_suppress_items::out,
io::di, io::uo) is det.
:- pred globals__io_get_globals(globals::out, io::di, io::uo) is det.
:- pred globals__io_set_globals(globals::di, io::di, io::uo) is det.
:- pred globals__io_set_option(option::in, option_data::in,
io::di, io::uo) is det.
:- pred globals__io_set_gc_method(gc_method::in, io::di, io::uo) is det.
:- pred globals__io_set_tags_method(tags_method::in, io::di, io::uo) is det.
:- pred globals__io_set_trace_level(trace_level::in, io::di, io::uo) is det.
:- pred globals__io_set_trace_level_none(io::di, io::uo) is det.
:- pred globals__io_lookup_option(option::in, option_data::out,
io::di, io::uo) is det.
:- pred globals__io_lookup_bool_option(option::in, bool::out,
io::di, io::uo) is det.
:- pred globals__io_lookup_int_option(option::in, int::out,
io::di, io::uo) is det.
:- pred globals__io_lookup_string_option(option::in, string::out,
io::di, io::uo) is det.
:- pred globals__io_lookup_maybe_string_option(option::in, maybe(string)::out,
io::di, io::uo) is det.
:- pred globals__io_lookup_accumulating_option(option::in, list(string)::out,
io::di, io::uo) is det.
:- pred globals__io_printing_usage(bool::out, io::di, io::uo) is det.
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
:- implementation.
:- import_module map, std_util, require, string.
convert_target(String, Target) :-
convert_target_2(string__to_lower(String), Target).
:- pred convert_target_2(string::in, compilation_target::out) is semidet.
convert_target_2("java", java).
convert_target_2("asm", asm).
convert_target_2("il", il).
convert_target_2("c", c).
convert_foreign_language(String, ForeignLanguage) :-
convert_foreign_language_2(string__to_lower(String), ForeignLanguage).
:- pred convert_foreign_language_2(string::in, foreign_language::out)
is semidet.
convert_foreign_language_2("c", c).
convert_foreign_language_2("mc++", managed_cplusplus).
convert_foreign_language_2("managedc++", managed_cplusplus).
convert_foreign_language_2("managed c++", managed_cplusplus).
convert_foreign_language_2("c#", csharp).
convert_foreign_language_2("csharp", csharp).
convert_foreign_language_2("c sharp", csharp).
convert_foreign_language_2("il", il).
convert_foreign_language_2("java", java).
convert_gc_method("none", none).
convert_gc_method("conservative", boehm).
convert_gc_method("boehm", boehm).
convert_gc_method("mps", mps).
convert_gc_method("accurate", accurate).
convert_gc_method("automatic", automatic).
convert_tags_method("none", none).
convert_tags_method("low", low).
convert_tags_method("high", high).
convert_termination_norm("simple", simple).
convert_termination_norm("total", total).
convert_termination_norm("num-data-elems", num_data_elems).
convert_termination_norm("size-data-elems", size_data_elems).
foreign_language_string(c) = "C".
foreign_language_string(managed_cplusplus) = "Managed C++".
foreign_language_string(csharp) = "C#".
foreign_language_string(il) = "IL".
foreign_language_string(java) = "Java".
simple_foreign_language_string(c) = "c".
simple_foreign_language_string(managed_cplusplus) = "cpp". % XXX mcpp is better
simple_foreign_language_string(csharp) = "csharp".
simple_foreign_language_string(il) = "il".
simple_foreign_language_string(java) = "java".
gc_is_conservative(boehm) = yes.
gc_is_conservative(mps) = yes.
gc_is_conservative(none) = no.
gc_is_conservative(accurate) = no.
gc_is_conservative(automatic) = no.
%-----------------------------------------------------------------------------%
:- type globals
---> globals(
options :: option_table,
target :: compilation_target,
gc_method :: gc_method,
tags_method :: tags_method,
termination_norm :: termination_norm,
trace_level :: trace_level,
trace_suppress_items :: trace_suppress_items,
source_file_map :: maybe(source_file_map),
have_printed_usage :: bool
).
globals__init(Options, Target, GC_Method, TagsMethod,
TerminationNorm, TraceLevel, TraceSuppress,
globals(Options, Target, GC_Method, TagsMethod,
TerminationNorm, TraceLevel, TraceSuppress, no, no)).
globals__get_options(Globals, Globals ^ options).
globals__get_target(Globals, Globals ^ target).
globals__get_gc_method(Globals, Globals ^ gc_method).
globals__get_tags_method(Globals, Globals ^ tags_method).
globals__get_termination_norm(Globals, Globals ^ termination_norm).
globals__get_trace_level(Globals, Globals ^ trace_level).
globals__get_trace_suppress(Globals, Globals ^ trace_suppress_items).
globals__get_source_file_map(Globals, Globals ^ source_file_map).
globals__get_backend_foreign_languages(Globals, ForeignLangs) :-
globals__lookup_accumulating_option(Globals, backend_foreign_languages,
LangStrs),
ForeignLangs = list__map(func(String) = ForeignLang :-
( convert_foreign_language(String, ForeignLang0) ->
ForeignLang = ForeignLang0
;
error("globals__io_get_backend_foreign_languages: " ++
"invalid foreign_language string")
), LangStrs).
globals__set_options(Options, Globals, Globals ^ options := Options).
globals__set_gc_method(GC_Method, Globals, Globals ^ gc_method := GC_Method).
globals__set_tags_method(Tags_Method, Globals,
Globals ^ tags_method := Tags_Method).
globals__set_trace_level(TraceLevel, Globals,
Globals ^ trace_level := TraceLevel).
globals__set_trace_level_none(Globals,
Globals ^ trace_level := trace_level_none).
globals__set_source_file_map(SourceFileMap, Globals,
Globals ^ source_file_map := SourceFileMap).
globals__lookup_option(Globals, Option, OptionData) :-
globals__get_options(Globals, OptionTable),
map__lookup(OptionTable, Option, OptionData).
%-----------------------------------------------------------------------------%
globals__lookup_bool_option(Globals, Option, Value) :-
globals__lookup_option(Globals, Option, OptionData),
( OptionData = bool(Bool) ->
Value = Bool
;
error("globals__lookup_bool_option: invalid bool option")
).
globals__lookup_string_option(Globals, Option, Value) :-
globals__lookup_option(Globals, Option, OptionData),
( OptionData = string(String) ->
Value = String
;
error("globals__lookup_string_option: invalid string option")
).
globals__lookup_int_option(Globals, Option, Value) :-
globals__lookup_option(Globals, Option, OptionData),
( OptionData = int(Int) ->
Value = Int
;
error("globals__lookup_int_option: invalid int option")
).
globals__lookup_maybe_string_option(Globals, Option, Value) :-
globals__lookup_option(Globals, Option, OptionData),
( OptionData = maybe_string(MaybeString) ->
Value = MaybeString
;
error(
"globals__lookup_string_option: invalid maybe_string option")
).
globals__lookup_accumulating_option(Globals, Option, Value) :-
globals__lookup_option(Globals, Option, OptionData),
( OptionData = accumulating(Accumulating) ->
Value = Accumulating
;
error("globals__lookup_accumulating_option: "
++ "invalid accumulating option")
).
%-----------------------------------------------------------------------------%
globals__have_static_code_addresses(Globals, IsConst) :-
globals__get_options(Globals, OptionTable),
globals__have_static_code_addresses_2(OptionTable, IsConst).
:- pred globals__have_static_code_addresses_2(option_table::in,
bool::out) is det.
globals__have_static_code_addresses_2(OptionTable, IsConst) :-
getopt__lookup_bool_option(OptionTable, gcc_non_local_gotos,
NonLocalGotos),
getopt__lookup_bool_option(OptionTable, asm_labels, AsmLabels),
globals__imported_is_constant(NonLocalGotos, AsmLabels, IsConst).
globals__want_return_var_layouts(Globals, WantReturnLayouts) :-
% We need to generate layout info for call return labels
% if we are using accurate gc or if the user wants uplevel printing.
(
(
globals__get_gc_method(Globals, GC_Method),
GC_Method = accurate
;
globals__get_trace_level(Globals, TraceLevel),
globals__get_trace_suppress(Globals, TraceSuppress),
trace_needs_return_info(TraceLevel, TraceSuppress)
= yes
)
->
WantReturnLayouts = yes
;
WantReturnLayouts = no
).
% The logic of this function and how it is used to select the default
% type_info method must agree with the code in runtime/typeinfo.h.
globals__imported_is_constant(NonLocalGotos, AsmLabels, IsConst) :-
(
NonLocalGotos = yes,
AsmLabels = no
->
%
% with non-local gotos but no asm labels, jumps to code
% addresses in different c_modules must be done via global
% variables; the value of these global variables is not
% constant (i.e. not computable at load time), since they
% can't be initialized until we call init_modules().
%
IsConst = no
;
IsConst = yes
).
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
globals__io_init(Options, Target, GC_Method, TagsMethod,
TerminationNorm, TraceLevel, TraceSuppress) -->
{ copy(Target, Target1) },
{ copy(GC_Method, GC_Method1) },
{ copy(TagsMethod, TagsMethod1) },
{ copy(TerminationNorm, TerminationNorm1) },
{ copy(TraceLevel, TraceLevel1) },
{ copy(TraceSuppress, TraceSuppress1) },
{ globals__init(Options, Target1, GC_Method1, TagsMethod1,
TerminationNorm1, TraceLevel1, TraceSuppress1, Globals) },
globals__io_set_globals(Globals).
globals__io_get_target(Target) -->
globals__io_get_globals(Globals),
{ globals__get_target(Globals, Target) }.
globals__io_get_gc_method(GC_Method) -->
globals__io_get_globals(Globals),
{ globals__get_gc_method(Globals, GC_Method) }.
globals__io_get_tags_method(Tags_Method) -->
globals__io_get_globals(Globals),
{ globals__get_tags_method(Globals, Tags_Method) }.
globals__io_get_termination_norm(TerminationNorm) -->
globals__io_get_globals(Globals),
{ globals__get_termination_norm(Globals, TerminationNorm) }.
globals__io_get_trace_level(TraceLevel) -->
globals__io_get_globals(Globals),
{ globals__get_trace_level(Globals, TraceLevel) }.
globals__io_get_trace_suppress(TraceSuppress) -->
globals__io_get_globals(Globals),
{ globals__get_trace_suppress(Globals, TraceSuppress) }.
globals__io_get_globals(Globals) -->
io__get_globals(UnivGlobals),
{
univ_to_type(UnivGlobals, Globals0)
->
Globals = Globals0
;
error("globals__io_get_globals: univ_to_type failed")
}.
globals__io_set_globals(Globals) -->
{ type_to_univ(Globals, UnivGlobals) },
io__set_globals(UnivGlobals).
%-----------------------------------------------------------------------------%
globals__io_lookup_option(Option, OptionData) -->
globals__io_get_globals(Globals),
{ globals__get_options(Globals, OptionTable) },
{ map__lookup(OptionTable, Option, OptionData) }.
globals__io_set_option(Option, OptionData) -->
globals__io_get_globals(Globals0),
{ globals__get_options(Globals0, OptionTable0) },
{ map__set(OptionTable0, Option, OptionData, OptionTable) },
{ globals__set_options(OptionTable, Globals0, Globals1) },
% XXX there is a bit of a design flaw with regard to
% uniqueness and io__set_globals
{ unsafe_promise_unique(Globals1, Globals) },
globals__io_set_globals(Globals).
globals__io_set_gc_method(GC_Method) -->
globals__io_get_globals(Globals0),
{ globals__set_gc_method(GC_Method, Globals0, Globals1) },
{ unsafe_promise_unique(Globals1, Globals) },
% XXX there is a bit of a design flaw with regard to
% uniqueness and io__set_globals
globals__io_set_globals(Globals).
globals__io_set_tags_method(Tags_Method) -->
globals__io_get_globals(Globals0),
{ globals__set_tags_method(Tags_Method, Globals0, Globals1) },
{ unsafe_promise_unique(Globals1, Globals) },
% XXX there is a bit of a design flaw with regard to
% uniqueness and io__set_globals
globals__io_set_globals(Globals).
globals__io_set_trace_level(TraceLevel) -->
globals__io_get_globals(Globals0),
{ globals__set_trace_level(TraceLevel, Globals0, Globals1) },
{ unsafe_promise_unique(Globals1, Globals) },
% XXX there is a bit of a design flaw with regard to
% uniqueness and io__set_globals
globals__io_set_globals(Globals).
% This predicate is needed because mercury_compile.m doesn't know
% anything about type trace_level.
globals__io_set_trace_level_none -->
globals__io_set_trace_level(trace_level_none).
%-----------------------------------------------------------------------------%
globals__io_lookup_foreign_language_option(Option, ForeignLang) -->
globals__io_lookup_string_option(Option, String),
{ convert_foreign_language(String, ForeignLang0) ->
ForeignLang = ForeignLang0
;
error("globals__io_lookup_foreign_language_option: "
++ "invalid foreign_language option")
}.
globals__io_get_backend_foreign_languages(ForeignLangs) -->
globals__io_get_globals(Globals),
{ globals__get_backend_foreign_languages(Globals, ForeignLangs) }.
globals__io_lookup_bool_option(Option, Value) -->
globals__io_get_globals(Globals),
{ globals__lookup_bool_option(Globals, Option, Value) }.
globals__io_lookup_int_option(Option, Value) -->
globals__io_get_globals(Globals),
{ globals__lookup_int_option(Globals, Option, Value) }.
globals__io_lookup_string_option(Option, Value) -->
globals__io_get_globals(Globals),
{ globals__lookup_string_option(Globals, Option, Value) }.
globals__io_lookup_maybe_string_option(Option, Value) -->
globals__io_get_globals(Globals),
{ globals__lookup_maybe_string_option(Globals, Option, Value) }.
globals__io_lookup_accumulating_option(Option, Value) -->
globals__io_get_globals(Globals),
{ globals__lookup_accumulating_option(Globals, Option, Value) }.
%-----------------------------------------------------------------------------%
globals__io_printing_usage(AlreadyPrinted, !IO) :-
globals__io_get_globals(Globals0, !IO),
AlreadyPrinted = Globals0 ^ have_printed_usage,
Globals1 = Globals0 ^ have_printed_usage := yes,
unsafe_promise_unique(Globals1, Globals),
% XXX there is a bit of a design flaw with regard to
% uniqueness and io__set_globals
globals__io_set_globals(Globals, !IO).
%-----------------------------------------------------------------------------%