Files
mercury/compiler/parse_tree.m
Zoltan Somogyi 9cbe5d2caf Put type_repn items for complex types into .int files.
compiler/decide_type_repn.m:
    Previously, this module computed type_repn items to put into .int3 files
    for a subset of the type constructors defined in the current module:
    the direct_dummy, enum and notag types (the *simple* types),
    and the du types whose representation is guaranteed to be
    a word-aligned pointer when targeting C. (We care about pointers
    being word-aligned only when applying the direct arg optimization.
    This optimization is applicable only with the low level data
    representation, which we use only when targeting C.)

    This diff adds code to decide the representations of *all* the
    type constructors defined in the current module.

    This code is based on the existing code in du_type_layout.m,
    which it is intended to eventually replace, but its job is more general,
    because it decides the representation of each type not just for
    one platform (the one we want to generate code), but for all possible
    platforms. This is because we want to put the descriptions of type
    representations into the module's .int file to serve as a single source
    of truth for all modules that use the types defined in this module,
    and the contents of .int files should be platform-independent.
    For our purposes, there are six kinds of platforms, which are
    distinguished along three axes: 64 vs 32 bit machines, spf vs non-spf
    grades, and direct arg optimization enabled vs disabled. That is eight
    combinations, but on 64 bit machines, a float takes up one word whether
    that float is single or double precision, so two combinations aren't valid.

    Some of the change to this module consists of generalizing the existing
    code so that it can decide simple types not just when targeting .int3 files
    but .int files as well. However, the bulk of it is code for deciding
    the representations of non-simple types. The code is not lifted straight
    from du_type_layout.m. There are two main kinds of changes.

    First, I took the opportunity to simplify the algorithms used.
    For example, while du_type_layout.m passes over each function symbol
    in the most general kind of type twice: once to assign it a cons_tag,
    and once to decide how to pack its arguments, the code here does both jobs
    in one pass. Another example is that for historical reasons,
    du_type_layout.m computed the amount of space needed for an argument
    in one place for sub-word-sized arguments, and in another place
    for more-than-word-sized arguments; decide_type_repn.m does it all
    in one place.

    Second, since we compute a representation for each type six times,
    I tried to avoid obvious inefficiencies, but only if the code
    remained simple. In the future, we may want to use an approach
    based on the idea that in the process of computing the first
    representation, we look out for any indication that the representation
    may be different on any of the other five platforms, and if not,
    we just reuse the first representation on the other five platforms as well.
    However, that would be appropriate only *after* we have a simpler
    system that has proven to work in practice.

    There is a third, smaller change: when deciding whether an argument
    is packable, we take into account not just equivalence type
    definitions, but the definitions of notag types as well.
    This takes advantage of the fact that if a notag type is abstract
    exported, its representation is put into the relevant .int3 file
    even though its definition isn't. (This is why du_type_layout.m
    couldn't "see through" notag types: it couldn't depend on knowing
    which types were notags.)

compiler/prog_item.m:
    Change the types we use for type representation information.
    Their previous definitions baked in the assumption that the only
    distinction between platforms that mattered was the 64 vs 32 bit
    distinction, which is not the case.

    Use a more consistent naming scheme for the types we use
    to represent type representation information.

    Include the "dereferenced" types of the arguments in functors'
    representations. (I use "dereferencing" here to mean expanding
    equivalence types and throwing away any notag wrappers.).
    We don't need it when generating C code using the low level
    data representation, but we do need it to create constructors
    when generating e.g. Java code that uses the high level data
    representation.

compiler/parse_type_repn.m:
    Rewrite most of this module due to the changes in prog_item.m.

compiler/parse_tree_out_type_repn.m:
    A new module containing the code for writing out type representations.
    The original code used to be in parse_tree_out.m, but it has been
    mostly rewritten. Partly this is due the changes in prog_item.m,
    but partly it is to provide much more structured output for humans,
    since this makes debugging so much easier.

compiler/parse_tree.m:
    Add the new module to the parse_tree package.

compiler/parse_tree_out.m:
    Delete the code moved to parse_tree_out_type_repn.m.

compiler/parse_tree_out_info.m:
    Provide a mechanism for selecting between output for machines
    (the default) and output for humans.

compiler/hlds_data.m:
compiler/prog_data.m:
    Move the ptag type from hlds_data.m to prog_data.m, to make it
    accessible in prog_item.m.

    Add some documentation in prog_data.m.

compiler/comp_unit_interface.m:
    If the experiment1 option is enabled, invoke decide_type_repn.m
    to decide what type_repn items to put into the .int file we are
    generating. Otherwise, maintain the status quo.

compiler/write_module_interface_files.m:
    Pass the globals to comp_unit_interface.m so it can look up experiment1.

compiler/equiv_type.m:
    Add a predicate for expanding equivalence types for use by
    decide_type_repn.m. This predicate expands just one type,
    but reports any use of circular equivalence types in that type.

    Improve the error message for circular equivalence types by *naming*
    the type constructors involved. To make this possible, pass around
    sets of such type constructors instead of just a boolean saying
    *whether* we have found *some* circular equivalence type.

    Replace bools used as changed/unchanged flag with a bespoke type.

    Standardize some variable names.

compiler/options.m:
    Add the developer-only option --pack-everything, which, if set,
    tells decide_type_repn.m to turn on all the packing options
    that currently work. This is to allow the testing of decide_type_repn.m
    in the eventual intended mode of operation, even if the various
    allow-packing-... options used by du_type_layout.m are set to "no".

compiler/disj_gen.m:
compiler/equiv_type_hlds.m:
compiler/llds_out_data.m:
compiler/lookup_util.m:
compiler/ml_call_gen.m:
compiler/ml_closure_gen.m:
compiler/mlds_to_c_data.m:
compiler/rtti.m:
compiler/rtti_out.m:
compiler/rtti_to_mlds.m:
compiler/tag_switch.m:
    Conform to the changes above (mostly the move of ptag to prog_data.m.)

compiler/parse_pragma.m:
    Improve indentation.

tests/valid_make_int/test_repn.m:
tests/valid_make_int/test_repn_sub.m:
    A fairly comprehensive test case of the new functionality.
    test_repn_sub.m defines one ore more simple type constructors
    of each possible kind, and test_repn.m uses them to define types
    that use each possible kind of complex type representation.

tests/valid_make_int/Mmakefile:
tests/valid_make_int/Mercury.options:
    Enable the new test case.
2020-05-28 07:41:44 +10:00

125 lines
4.2 KiB
Mathematica

%-----------------------------------------------------------------------------%
% vim: ft=mercury ts=4 sw=4 et
%-----------------------------------------------------------------------------%
% Copyright (C) 2002-2011 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.
%-----------------------------------------------------------------------------%
%
% This package contains the parse tree data structure,
% and modules for parsing and for manipulating parse trees.
%
% It corresponds to the parts of "Phase 1: Parsing"
% in notes/compiler_design.html up to (but not including) make_hlds.m.
%
:- module parse_tree.
:- interface.
% The parse tree data type itself.
% The parse tree is split in two. The parts defined in prog_item are needed
% only by the frontend of the compiler, the parts in prog_data* are needed
% throughout.
:- include_module prog_item.
:- include_module prog_data.
:- include_module prog_data_event.
:- include_module prog_data_foreign.
:- include_module prog_data_pragma.
:- include_module prog_data_used_modules.
:- include_module file_kind.
% The parser.
:- include_module parse_module.
:- include_module parse_dcg_goal.
:- include_module parse_error.
:- include_module parse_goal.
:- include_module parse_inst_mode_defn.
:- include_module parse_inst_mode_name.
:- include_module parse_item.
:- include_module parse_mutable.
:- include_module parse_pragma.
:- include_module parse_sym_name.
:- include_module parse_type_defn.
:- include_module parse_type_name.
:- include_module parse_type_repn.
:- include_module parse_class.
:- include_module parse_vars.
:- include_module find_module.
:- include_module parse_types.
:- include_module parse_util.
% Parser/pretty-printer/utility routines for the ctgc related types.
:- include_module prog_ctgc.
% Pretty-printers.
:- include_module mercury_to_mercury.
:- include_module parse_tree_out.
:- include_module parse_tree_out_clause.
:- include_module parse_tree_out_inst.
:- include_module parse_tree_out_pragma.
:- include_module parse_tree_out_pred_decl.
:- include_module parse_tree_out_term.
:- include_module parse_tree_out_type_repn.
:- include_module parse_tree_out_info.
:- include_module prog_out.
:- include_module parse_tree_to_term.
% Utility data structures.
:- include_module set_of_var.
% Utility routines.
:- include_module builtin_lib_types.
:- include_module error_util.
:- include_module item_util.
:- include_module maybe_error.
:- include_module prog_detism.
:- include_module prog_event.
:- include_module prog_foreign.
:- include_module prog_item_stats.
:- include_module prog_mode.
:- include_module prog_mutable.
:- include_module prog_rename.
:- include_module prog_type.
:- include_module prog_type_subst.
:- include_module prog_util.
% Type representation.
:- include_module check_parse_tree_type_defns.
:- include_module decide_type_repn.
% Transformations that act on the parse tree,
% and stuff relating to the module system.
:- include_module canonicalize_interface.
:- include_module check_raw_comp_unit.
:- include_module comp_unit_interface.
:- include_module convert_parse_tree.
:- include_module deps_map.
:- include_module equiv_type.
:- include_module file_names.
:- include_module generate_dep_d_files.
:- include_module get_dependencies.
:- include_module grab_modules.
:- include_module module_cmds.
:- include_module module_deps_graph.
:- include_module module_imports.
:- include_module module_qual.
:- include_module read_modules.
:- include_module source_file_map.
:- include_module split_parse_tree_src.
:- include_module write_deps_file.
:- include_module write_module_interface_files.
% Java and C# related utilities.
:- include_module java_names.
% (Note that intermod and trans_opt also contain routines that
% act on the parse tree, but those modules are considered part
% of the HLDS transformations package.)
% :- include_module intermod.
% :- include_module trans_opt.
%-----------------------------------------------------------------------------%
:- end_module parse_tree.
%-----------------------------------------------------------------------------%