mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-14 21:35:49 +00:00
... by eliminating the grade component that calls for the use of gcc nested
functions.
runtime/mercury_grade.h:
compiler/compute_grade.m:
Delete the gcc_nested_functions grade component, and the C macro
that specifies its presence, MR_USE_GCC_NESTED_FUNCTIONS.
scripts/canonical_grade.sh-subr:
scripts/init_grade_options.sh-subr:
scripts/mgnuc.in:
scripts/parse_grade_options.sh-subr:
Delete the code that parses the deleted grade component,
and delete the code that signals its absence in other grades.
compiler/options.m:
Delete the gcc_nested_functions grade option.
Delete also the gcc_local_labels option, since it was useful
only if gcc_nested_functions was set.
configure.ac:
Delete the code that sometimes added hl*_nest grades to the list of grades
to be installed.
Fix a bunch of comments.
compiler/compile_target_code.m:
compiler/handle_options.m:
compiler/mercury_compile_mlds_back_end.m:
compiler/ml_args_util.m:
compiler/ml_call_gen.m:
compiler/ml_code_util.m:
compiler/ml_commit_gen.m:
compiler/ml_gen_info.m:
compiler/mlds_to_c.m:
library/backjump.m:
library/exception.m:
runtime/mercury_hlc_types.h:
runtime/mercury_tabling.c:
runtime/mercury_tabling.h:
Delete code that was active only in grades with the deleted grade
component.
compiler/ml_accurate_gc.m:
compiler/notes/grade_library.html:
runtime/mercury_conf_param.h:
Delete mentions of the deleted grade component.
compiler/ml_code_gen.m:
Delete mentions of the deleted grade component, and a bunch of other
obsolete comments.
doc/user_guide.texi:
Fix a line break.
357 lines
13 KiB
HTML
357 lines
13 KiB
HTML
<html>
|
|
<head>
|
|
<title>
|
|
The grade library
|
|
</title>
|
|
</head>
|
|
|
|
<body bgcolor="#ffffff" text="#000000">
|
|
|
|
<hr>
|
|
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
|
|
|
This documents work in progress.
|
|
|
|
<h2> What grades are </h2>
|
|
|
|
<p>
|
|
This section is for users and novice implementors,
|
|
as well as background for the next section.
|
|
|
|
<p>
|
|
Compiler options affect what code the compiler generates
|
|
for the modules it is asked to generate code for.
|
|
For some compiler options (such as --inlining),
|
|
it is ok for the component modules of a program
|
|
to be compiled with different values of the option
|
|
(e.g. some modules compiled with inlining and some without inlining).
|
|
However, for some other options, such combinations do not work.
|
|
This is typically because the option governs some aspect of the contract
|
|
between a predicate A on the one hand and another predicate B that it calls.
|
|
Some of these aspects are obvious:
|
|
compiling the predicates to different target languages (e.g. Java and Erlang)
|
|
makes linking them together effectively impossible.
|
|
Some other aspects are not obvious:
|
|
if predicate A expects B to use the trail to record the bindings it makes,
|
|
but B does not do so,
|
|
that fact sets up a time bomb that will go off sometime later,
|
|
after a backtrack that should have undone those bindings,
|
|
but does not (due those bindings not having entries in the trail).
|
|
If the user is lucky, the resulting data corruption will crash the program;
|
|
if the user is unlucky, there will be no crash,
|
|
and the program will just generate output that is effectively random.
|
|
|
|
<p>
|
|
To prevent such problems, the Mercury compiler requires
|
|
that all modules in a program (including the ones embedded in libraries)
|
|
be compiled with consistent values of all the compiler options
|
|
that affect how the compiled codes of the modules communicate with each other.
|
|
(We call these options the <em>compilation model</em> options.)
|
|
A <em>grade</em> is a specification of a value
|
|
for each and every one of these options.
|
|
The above requirement can thus be restated both as
|
|
<em>all modules in a program must be compiled
|
|
with the same compilation model</em>
|
|
and as <em>all modules in a program must be compiled in the same grade</em>.
|
|
|
|
<hr>
|
|
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
|
|
|
<h2> The different representations of grades </h2>
|
|
|
|
<p>
|
|
This section is for implementors,
|
|
though some parts may be useful for users as well.
|
|
|
|
<p>
|
|
Traditionally, the Mercury compiler had two representations of grades:
|
|
(a) grade strings, and (b) the values of the compilation model options.
|
|
|
|
<p>
|
|
Most compilation model options are boolean options (such as use_trail),
|
|
some integer options (such as num_tag_bits),
|
|
and some are string options (such as target).
|
|
The compiler looks up the boolean compilation model options
|
|
in the option table part of the globals structure (in compiler/globals.m),
|
|
but it converts the compilation model options that are integers or strings
|
|
into enums of purpose-specific types,
|
|
which it stores separately from the option table,
|
|
in other parts of the globals structure.
|
|
This is so that the sanity checking that is required
|
|
to accept e.g. --target=java but reject e.g. --target=xyzzy
|
|
can be done once, when the globals structure is set up,
|
|
instead of having to be repeated in every part of the in the compiler
|
|
that needs to know the identity of the target language.
|
|
|
|
<p>
|
|
A grade string is the only representation of grades
|
|
that most Mercury users ever see.
|
|
|
|
<p>
|
|
A grade string consists of a sequence of grade components separated by dots;
|
|
for example, "hlc.gc.tr" consists of the components "hlc", "gc" and "tr".
|
|
Each grade component specifies either
|
|
the value of one compiler option
|
|
(for example, "tr" specifies use_trail=yes),
|
|
or the values of two or more compiler options
|
|
(for example, "hlc" specifies target=c and highlevel_data=no).
|
|
|
|
<p>
|
|
A typical grade string does <em>not</em> specify a value
|
|
for <em>every</em> compilation model option.
|
|
For example, "hlc.gc.tr" does not <em>explicitly</em> specify
|
|
a value for the thread_safe option.
|
|
The values of such options are then set to a default value.
|
|
That default may depend on the values of the compilation model options
|
|
that <em>are</em> specified.
|
|
|
|
<p>
|
|
The different components of a grade string can be inconsistent.
|
|
This can happen by having two grade components
|
|
directly assign different values to the same compilation model option,
|
|
as with the grade "hlc.java".
|
|
It can also happen indirectly,
|
|
because even if two or more grade components assign values
|
|
to disjoint sets of compilation model options,
|
|
the resulting assignments may not be compatible.
|
|
For example, "hlc.debug" is inconsistent,
|
|
because "hlc" selects the use of the MLDS backend,
|
|
but "debug" is implemented only for the LLDS backend.
|
|
A grade is valid only if satisfies a set of constraints,
|
|
of which "debug is implemented only for the LLDS backend" is only one.
|
|
These constraints arise because not all combinations of options make sense,
|
|
and of the combinations that do make sense,
|
|
not all have been implemented, or are even worth implementing.
|
|
|
|
<p>
|
|
compiler/handle_options.m has traditionally been the place
|
|
where we tried to implement these constraints.
|
|
The constraints are of the form
|
|
if compilation model option A has value Ai,
|
|
then compilation model option B must have one of the values Bjs.
|
|
If Bjs is a singleton set, then this constraint is effectively an implication.
|
|
Such implications can be used in either direction:
|
|
if we know that A=Ai, then we can set B=Bj,
|
|
while if we know that B is not in Bjs, then we can rule out A=Ai.
|
|
|
|
<p>
|
|
The code in compiler/handle_options.m has several problems:
|
|
|
|
<ul>
|
|
<li>
|
|
The code that does this is totally ad-hoc.
|
|
It is far from understandable,
|
|
and effectively impossible to check for completeness.
|
|
<li>
|
|
When looking at the initial values of the compilation model options,
|
|
it does not actually know
|
|
which options were explicitly specified, and which have their default values.
|
|
In the process of checking these options and handling their implications
|
|
(such as target=java implying gc=gc_automatic),
|
|
it overrides the old values of some compilation model options,
|
|
after which it does not know
|
|
which options were explicitly specified, which have their default values,
|
|
and which were set earlier by its own code.
|
|
This can lead to misleading error messages,
|
|
which attribute to the user a setting of a compilation model option
|
|
that was actually set by handle_options.m itself.
|
|
<li>
|
|
Because of this problem of being unable to distinguish
|
|
between an option value specified by a user
|
|
and the default value of that option,
|
|
it cannot implement feature requests.
|
|
Some parts of the grade, such as the identity of the target language,
|
|
had to be explicitly specified by the user,
|
|
and couldn't be inferred from the values of other
|
|
explicitly-given compilation model options
|
|
or grade string components.
|
|
</ul>
|
|
|
|
<p>
|
|
The grade library is intended to fix this situation.
|
|
It should allow users to specify what features they want
|
|
(e.g. trailing and debugging)
|
|
and have the grade library select
|
|
the best grade that has all the requested features,
|
|
either from the global space of all possible grades,
|
|
or from the much, much more restricted set
|
|
of all the grades currently installed on the system.
|
|
(In this context, "best" means fastest,
|
|
which typically means that the best grade will have
|
|
no features except the features that were explicitly requested,
|
|
and the features that are implied by them either directly or indirectly.)
|
|
|
|
<p>
|
|
The grade library works with four representations of grades:
|
|
|
|
<p>
|
|
<ul>
|
|
<li> grade strings
|
|
<li> grade structure (discussed last)
|
|
<li> grade variables
|
|
<li> solver variables
|
|
</ul>
|
|
|
|
<p>
|
|
The grade strings have the same form as before:
|
|
a list of components separated by dots,
|
|
with each component specifying
|
|
the values of one or more compilation model options.
|
|
The meaning can be subtly different:
|
|
if a user-specified grade implicitly implies some other grade components
|
|
that the user-specified grade does not contain,
|
|
then the grade library will always implicitly add it to the grade,
|
|
while the old grade-handling code in compiler/compute_grade.m
|
|
added it to the grade only <em>sometimes</em>.
|
|
For example, since target=java implies thread_safe=yes,
|
|
the grade library canonicalizes grade "java" to "java.par";
|
|
before the grade library, we did not do that.
|
|
|
|
<p>
|
|
The grade var representation of a grade
|
|
is very similar to the old representation of compilation model options,
|
|
with the only difference being that it represents
|
|
that value of every compilation model option using a grade variable,
|
|
with each grade variable being of a separate, purpose-specific enum type.
|
|
This means that e.g. we replace the bool option named use_trail
|
|
with a grade variable whose value is
|
|
either grade_var_trail_no or grade_var_trail_yes.
|
|
There is one grade variable for most compilation model options,
|
|
though a few grade variables, such as grade_var_merc_float below,
|
|
encode the values of two compilation model options
|
|
(unboxed_float and single_prec_float).
|
|
The grade_vars structure collects all the grade variables in one structure.
|
|
The whole setup looks like this:
|
|
|
|
<p>
|
|
<pre>
|
|
:- type grade_var_trail
|
|
---> grade_var_trail_no
|
|
; grade_var_trail_yes.
|
|
|
|
:- type grade_var_merc_float
|
|
---> grade_var_merc_float_is_boxed_c_double
|
|
; grade_var_merc_float_is_unboxed_c_double
|
|
; grade_var_merc_float_is_unboxed_c_float.
|
|
|
|
:- type grade_vars
|
|
---> grade_vars(
|
|
...
|
|
grade_var_trail,
|
|
...
|
|
grade_var_merc_float,
|
|
...
|
|
).
|
|
</pre>
|
|
|
|
<p>
|
|
The grade var representation of a grade
|
|
allows the parts of the compiler
|
|
that need to make simple decisions
|
|
(such as "should the generated high level C code use nested functions?")
|
|
make them a bit more safely,
|
|
since mixing up two purpose-specific enums will generate a compiler error
|
|
while mixing up two booleans will not.
|
|
However, the main reason
|
|
for using this representation instead of compiler options
|
|
is to allow the grade library to be usable
|
|
by programs other than the compiler.
|
|
|
|
<p>
|
|
While having each grade variable being of a different type
|
|
is good for type safety in code that deals with only a few grade variables,
|
|
it does not allow the processing of all grade variables using generic code.
|
|
The only sensible way to implement a solver
|
|
for the constraints we have on grade variables is using such generic code.
|
|
We therefore have a representation of grades that uses just two types:
|
|
one (solver_var_id) to represent the identities of all the grade variables,
|
|
and another type (solver_var_value_id)
|
|
to represent all their possible values.
|
|
Like this:
|
|
|
|
<p>
|
|
<pre>
|
|
:- type solver_var_id
|
|
---> ...
|
|
; svar_trail
|
|
; ...
|
|
; svar_merc_float
|
|
; ...
|
|
|
|
:- type solver_var_value_id
|
|
---> ...
|
|
; svalue_trail_no
|
|
; svalue_trail_yes
|
|
; ...
|
|
; svalue_merc_float_is_boxed_c_double
|
|
; svalue_merc_float_is_unboxed_c_double
|
|
; svalue_merc_float_is_unboxed_c_float
|
|
|
|
; ...
|
|
|
|
</pre>
|
|
|
|
<p>
|
|
The solver works with a data structure (the solver_var_map)
|
|
that maps each grade var
|
|
(represented by the corresponding value of the solver_var_id type)
|
|
to the set of its possible values
|
|
(each represented by a value of the solver_var_value_id type)
|
|
For each grade var,
|
|
the set of its possible values
|
|
starts out as the set of solver_var_value_id values
|
|
that correspond to the values of the grade var
|
|
(so that for svar_trail,
|
|
the initial set will be {svalue_trail_no, svalue_trail_yes}).
|
|
As the constraint solver processes constraints,
|
|
it rules out some values in the range of some variables.
|
|
If the map ever maps a grade variable to the empty set of possible values,
|
|
then the solver fails, which means that
|
|
the initially posed set of constraints must have been inconsistent.
|
|
On the other hand, a successful solution
|
|
maps each grade variable to just a single value.
|
|
Such a successful solution can be converted into a grade vars structure.
|
|
|
|
<p>
|
|
The fourth and last representation of grades in the grade library
|
|
is the grade structure (the type name is "grade_structure").
|
|
The purpose of the grade structure is to make it impossible to express grades
|
|
that violate any of the constraints that we require grades to meet.
|
|
|
|
While the grade var representation can represent a grade
|
|
which has both grade_var_target=grade_var_target_java and
|
|
grade_var_deep_prof=grade_var_deep_prof_yes,
|
|
the grade structure cannot,
|
|
because it can record "the grade supports deep profiling"
|
|
only in an argument of the grade_llds function symbol,
|
|
while it can record "the target language is Java"
|
|
only in an argument of the grade_mlds function symbol,
|
|
and a variable of type grade_structure cannot be bound
|
|
to both function symbols at the same time.
|
|
|
|
<p>
|
|
The grade structure has two main uses.
|
|
|
|
<p>
|
|
<ul>
|
|
<li>
|
|
Converting a solver solution to a grade string
|
|
starts by converting that solution to a set of grade vars,
|
|
but converting that set to the grade string
|
|
is easier to do via the grade structure,
|
|
because the grade structure makes it much easier to figure out
|
|
which grade string components can be left out
|
|
as being implied by the values of other grade string components.
|
|
<li>
|
|
The grade structure type is effectively a template
|
|
that can be instantiated to any valid grade, and to no invalid grade.
|
|
This should make useful in documenting the set of valid grades
|
|
in the user manual.
|
|
</ul>
|
|
|
|
<hr>
|
|
<!-- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -->
|
|
|
|
</body>
|
|
</html>
|