mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-15 01:13:30 +00:00
compiler/add_heap_ops.m:
compiler/check_import_accessibility.m:
compiler/comp_unit_interface.m:
compiler/convert_import_use.m:
compiler/deforest.m:
compiler/dep_par_conj.m:
compiler/distance_granularity.m:
compiler/equiv_type.m:
compiler/generate_dep_d_files.m:
compiler/generate_mmakefile_fragments.m:
compiler/get_dependencies.m:
compiler/grab_modules.m:
compiler/higher_order.specialize_unify_compare.m:
compiler/jumpopt.m:
compiler/layout_out.m:
compiler/lco.m:
compiler/live_vars.m:
compiler/liveness.m:
compiler/llds_out_file.m:
compiler/make.build.m:
compiler/make.get_module_dep_info.m:
compiler/make.library_install.m:
compiler/make.module_target.m:
compiler/make.program_target.m:
compiler/make.track_flags.m:
compiler/make_hlds_passes.m:
compiler/make_module_file_names.m:
compiler/mercury_compile_front_end.m:
compiler/mercury_compile_llds_back_end.m:
compiler/mercury_compile_main.m:
compiler/mercury_compile_middle_passes.m:
compiler/ml_call_gen.m:
compiler/ml_closure_gen.m:
compiler/ml_code_gen.m:
compiler/ml_code_util.m:
compiler/ml_disj_gen.m:
compiler/ml_elim_nested.m:
compiler/ml_foreign_proc_gen.m:
compiler/ml_lookup_switch.m:
compiler/ml_switch_gen.m:
compiler/ml_unify_gen_deconstruct.m:
compiler/ml_unify_gen_test.m:
compiler/mlds_to_c_file.m:
compiler/mlds_to_target_util.m:
compiler/module_cmds.m:
compiler/opt_deps_spec.m:
compiler/optimize.m:
compiler/parse_dcg_goal.m:
compiler/parse_goal.m:
compiler/parse_item.m:
compiler/parse_module.m:
compiler/parse_string_format.m:
compiler/proc_gen.m:
compiler/prop_mode_constraints.m:
compiler/rbmm.points_to_analysis.m:
compiler/rbmm.region_analysis.m:
compiler/rbmm.region_transformation.m:
compiler/simplify_goal_disj.m:
compiler/ssdebug.m:
compiler/stack_opt.m:
compiler/string_switch.m:
compiler/switch_gen.m:
compiler/term_constr_build.m:
compiler/trace_gen.m:
compiler/tupling.m:
compiler/untupling.m:
compiler/write_deps_file.m:
deep_profiler/autopar_calc_overlap.m:
deep_profiler/autopar_find_best_par.m:
deep_profiler/html_format.m:
deep_profiler/startup.m:
profiler/mercury_profile.m:
profiler/propagate.m:
Act on the new warnings. In a few cases, conform to the changes
resulting from acting on the warnings in other modules.
browser/Mercury.options:
compiler/Mercury.options:
library/Mercury.options:
mdbcomp/Mercury.options:
ssdb/Mercury.options:
Specify options for disabling the new warnings for modules
where we (probably) won't want them.
configure.ac:
Require the installed compiler to understand the options that
we now reference in the Mercury.options files above.
tests/debugger/tailrec1.exp:
Expect variable names for the middle versions of state vars
using the new naming scheme.
tests/invalid/Mercury.options:
Fix references to obsolete test names.
tests/warnings/Mercury.options:
Avoid a test failure with intermodule optimization.
3447 lines
135 KiB
Mathematica
3447 lines
135 KiB
Mathematica
%-----------------------------------------------------------------------------%
|
|
% vim: ft=mercury ts=4 sw=4 et
|
|
%-----------------------------------------------------------------------------%
|
|
% Copyright (C) 2001-2012 The University of Melbourne.
|
|
% Copyright (C) 2013-2016, 2018-2022, 2024-2025 The Mercury team.
|
|
% This file may only be copied under the terms of the GNU General
|
|
% Public License - see the file COPYING in the Mercury distribution.
|
|
%-----------------------------------------------------------------------------%
|
|
%
|
|
% File: layout_out.m.
|
|
% Author: zs.
|
|
%
|
|
% This structure converts layout structures from the representation used
|
|
% within the compiler to the representation used by the runtime system.
|
|
% The types of the inputs are defined in layout.m. The types of the outputs
|
|
% are defined in runtime/mercury_stack_layout.h, where the documentation
|
|
% of the semantics of the various kinds of layout structures can also be found.
|
|
%
|
|
% This module should be, but as yet isn't, independent of whether we are
|
|
% compiling to LLDS or MLDS.
|
|
%
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- module ll_backend.layout_out.
|
|
:- interface.
|
|
|
|
:- import_module hlds.
|
|
:- import_module hlds.hlds_pred.
|
|
:- import_module ll_backend.layout.
|
|
:- import_module ll_backend.llds.
|
|
:- import_module ll_backend.llds_out.
|
|
:- import_module ll_backend.llds_out.llds_out_util.
|
|
:- import_module mdbcomp.
|
|
:- import_module mdbcomp.prim_data.
|
|
:- import_module mdbcomp.program_representation.
|
|
|
|
:- import_module bool.
|
|
:- import_module io.
|
|
:- import_module list.
|
|
:- import_module maybe.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- pred output_layout_array_decls(llds_out_info::in,
|
|
io.text_output_stream::in,
|
|
list(rval)::in, list(int)::in, list(int)::in, list(int)::in,
|
|
list(maybe(int))::in, list(user_event_data)::in,
|
|
list(label_layout_no_vars)::in,
|
|
list(label_layout_short_vars)::in, list(label_layout_long_vars)::in,
|
|
list(call_site_static_data)::in, list(coverage_point_info)::in,
|
|
list(proc_layout_proc_static)::in,
|
|
list(int)::in, list(int)::in, list(int)::in, list(table_io_entry_data)::in,
|
|
list(layout_slot_name)::in, list(proc_layout_exec_trace)::in,
|
|
list(alloc_site_info)::in, io::di, io::uo) is det.
|
|
|
|
:- pred output_layout_array_defns(llds_out_info::in,
|
|
io.text_output_stream::in,
|
|
list(rval)::in, list(int)::in, list(int)::in, list(int)::in,
|
|
list(maybe(int))::in, list(user_event_data)::in,
|
|
list(label_layout_no_vars)::in,
|
|
list(label_layout_short_vars)::in, list(label_layout_long_vars)::in,
|
|
list(call_site_static_data)::in, list(coverage_point_info)::in,
|
|
list(proc_layout_proc_static)::in,
|
|
list(int)::in, list(int)::in, list(int)::in, list(table_io_entry_data)::in,
|
|
list(layout_slot_name)::in, list(proc_layout_exec_trace)::in,
|
|
list(string)::in, list(alloc_site_info)::in,
|
|
decl_set::in, decl_set::out, io::di, io::uo) is det.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% Given the name of a layout structure, output the declaration
|
|
% of the C global variable which will hold it.
|
|
%
|
|
:- pred output_layout_name_decl(io.text_output_stream::in, layout_name::in,
|
|
io::di, io::uo) is det.
|
|
|
|
% Given the name of a layout structure, output the declaration of the C
|
|
% global variable which will hold it, if it has not already been declared.
|
|
%
|
|
:- pred output_maybe_layout_name_decl(io.text_output_stream::in,
|
|
layout_name::in,
|
|
decl_set::in, decl_set::out, io::di, io::uo) is det.
|
|
|
|
:- type use_layout_macro
|
|
---> do_not_use_layout_macro
|
|
; use_layout_macro.
|
|
|
|
% Given the mangled name of the module and a reference to a layout array,
|
|
% output the name of the global variable that will hold it. The first arg
|
|
% says whether we should use a macro to refer to the global. Using the
|
|
% macro generates shorter code, but is not valid in all contexts.
|
|
%
|
|
:- pred output_layout_array_name(io.text_output_stream::in,
|
|
use_layout_macro::in, string::in, layout_array_name::in,
|
|
io::di, io::uo) is det.
|
|
|
|
% Given the mangled name of the module, output the id of the given layout
|
|
% array slot.
|
|
%
|
|
:- pred output_layout_slot_id(io.text_output_stream::in, use_layout_macro::in,
|
|
string::in, layout_slot_name::in, io::di, io::uo) is det.
|
|
|
|
% Given the mangled name of the module, output a reference to the address
|
|
% of the given layout array slot.
|
|
%
|
|
:- pred output_layout_slot_addr(io.text_output_stream::in,
|
|
use_layout_macro::in, string::in, layout_slot_name::in,
|
|
io::di, io::uo) is det.
|
|
|
|
% Given a reference to a layout structure, output the name of the
|
|
% global variable that will hold it.
|
|
%
|
|
:- pred output_layout_name(io.text_output_stream::in, layout_name::in,
|
|
io::di, io::uo) is det.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- type being_defined
|
|
---> not_being_defined
|
|
; being_defined.
|
|
|
|
% Given a reference to a layout structure, output the storage class
|
|
% (e.g. static), type and name of the global variable that will hold it.
|
|
% The second arg says whether the output is part of the definition of that
|
|
% variable; this influences e.g. whether we output "extern" or not.
|
|
%
|
|
:- pred output_layout_name_storage_type_name(io.text_output_stream::in,
|
|
layout_name::in, being_defined::in, io::di, io::uo) is det.
|
|
|
|
% Given a mangled module name and a reference to a layout array, output
|
|
% the storage class (e.g. static), type and name of the global variable
|
|
% that will hold it. The bool says whether the output is part of the
|
|
% definition of that variable; this influences e.g. whether we output
|
|
% "extern" or not.
|
|
%
|
|
:- pred output_layout_array_name_storage_type_name(io.text_output_stream::in,
|
|
string::in, layout_array_name::in, being_defined::in,
|
|
io::di, io::uo) is det.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% Given a Mercury representation of a proc layout structure, output its
|
|
% definition in the appropriate C global variable.
|
|
%
|
|
:- pred output_proc_layout_data_defn(llds_out_info::in,
|
|
io.text_output_stream::in, proc_layout_data::in,
|
|
decl_set::in, decl_set::out, io::di, io::uo) is det.
|
|
|
|
% Given a Mercury representation of a closure layout structure, output its
|
|
% definition in the appropriate C global variable.
|
|
%
|
|
:- pred output_closure_layout_data_defn(llds_out_info::in,
|
|
io.text_output_stream::in, closure_proc_id_data::in,
|
|
decl_set::in, decl_set::out, io::di, io::uo) is det.
|
|
|
|
% Given a Mercury representation of a module layout structure, output its
|
|
% definition in the appropriate C global variable.
|
|
%
|
|
:- pred output_module_layout_data_defn(llds_out_info::in,
|
|
io.text_output_stream::in, module_layout_data::in,
|
|
decl_set::in, decl_set::out, io::di, io::uo) is det.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% Given a reference to a layout structure, return a bool that is true
|
|
% iff the layout structure contains code addresses.
|
|
%
|
|
:- func layout_name_would_include_code_addr(layout_name) = bool.
|
|
|
|
% For a given procedure label, return whether the procedure is
|
|
% user-defined or part of a compiler-generated unify, compare or index
|
|
% predicate.
|
|
%
|
|
:- func proc_label_user_or_uci(proc_label) = proc_layout_user_or_uci.
|
|
|
|
% Return a value of the C type MR_PredFunc corresponding to the argument.
|
|
%
|
|
:- func mr_pred_or_func_to_string(pred_or_func) = string.
|
|
|
|
% Return the name of the given port, as in the enum MR_Trace_Port
|
|
% in runtime/mercury_stack_layout.h.
|
|
%
|
|
:- func trace_port_to_string(trace_port) = string.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- implementation.
|
|
|
|
:- import_module backend_libs.
|
|
:- import_module backend_libs.c_util.
|
|
:- import_module backend_libs.name_mangle.
|
|
:- import_module backend_libs.proc_label.
|
|
:- import_module hlds.hlds_rtti.
|
|
:- import_module hlds.pred_name.
|
|
:- import_module libs.
|
|
:- import_module libs.trace_params.
|
|
:- import_module ll_backend.llds_out.llds_out_code_addr.
|
|
:- import_module ll_backend.llds_out.llds_out_data.
|
|
:- import_module mdbcomp.goal_path.
|
|
:- import_module mdbcomp.sym_name.
|
|
:- import_module parse_tree.
|
|
:- import_module parse_tree.parse_tree_output.
|
|
:- import_module parse_tree.prog_data.
|
|
:- import_module parse_tree.prog_data_event.
|
|
:- import_module parse_tree.prog_data_pragma.
|
|
:- import_module parse_tree.prog_foreign.
|
|
|
|
:- import_module assoc_list.
|
|
:- import_module char.
|
|
:- import_module int.
|
|
:- import_module map.
|
|
:- import_module pair.
|
|
:- import_module require.
|
|
:- import_module string.
|
|
:- import_module term_context.
|
|
:- import_module uint.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
output_layout_array_decls(Info, Stream, PseudoTypeInfos, HLDSVarNums,
|
|
ShortLocns, LongLocns, UserEventVarNums, UserEvents,
|
|
NoVarLabelLayouts, SVarLabelLayouts, LVarLabelLayouts,
|
|
CallSiteStatics, CoveragePoints, ProcStatics,
|
|
ProcHeadVarNums, ProcVarNames, ProcBodyBytecodes, TableIoEntries,
|
|
ProcEventLayouts, ExecTraces, AllocSites, !IO) :-
|
|
MangledModuleName = Info ^ lout_mangled_module_name,
|
|
(
|
|
PseudoTypeInfos = []
|
|
;
|
|
PseudoTypeInfos = [_ | _],
|
|
PseudoTypeInfoArrayName = pseudo_type_info_array,
|
|
output_layout_array_name_storage_type_name(Stream, MangledModuleName,
|
|
PseudoTypeInfoArrayName, not_being_defined, !IO),
|
|
io.write_string(Stream, "[];\n", !IO)
|
|
),
|
|
(
|
|
HLDSVarNums = []
|
|
;
|
|
HLDSVarNums = [_ | _],
|
|
HLDSVarNumArrayName = hlds_var_nums_array,
|
|
output_layout_array_name_storage_type_name(Stream, MangledModuleName,
|
|
HLDSVarNumArrayName, not_being_defined, !IO),
|
|
io.write_string(Stream, "[];\n", !IO)
|
|
),
|
|
(
|
|
ShortLocns = []
|
|
;
|
|
ShortLocns = [_ | _],
|
|
ShortLocnArrayName = short_locns_array,
|
|
output_layout_array_name_storage_type_name(Stream, MangledModuleName,
|
|
ShortLocnArrayName, not_being_defined, !IO),
|
|
io.write_string(Stream, "[];\n", !IO)
|
|
),
|
|
(
|
|
LongLocns = []
|
|
;
|
|
LongLocns = [_ | _],
|
|
LongLocnArrayName = long_locns_array,
|
|
output_layout_array_name_storage_type_name(Stream, MangledModuleName,
|
|
LongLocnArrayName, not_being_defined, !IO),
|
|
io.write_string(Stream, "[];\n", !IO)
|
|
),
|
|
(
|
|
UserEventVarNums = []
|
|
;
|
|
UserEventVarNums = [_ | _],
|
|
UserEventVarNumArrayName = user_event_var_nums_array,
|
|
output_layout_array_name_storage_type_name(Stream, MangledModuleName,
|
|
UserEventVarNumArrayName, not_being_defined, !IO),
|
|
io.write_string(Stream, "[];\n", !IO)
|
|
),
|
|
(
|
|
UserEvents = []
|
|
;
|
|
UserEvents = [_ | _],
|
|
UserEventsArrayName = user_event_layout_array,
|
|
output_layout_array_name_storage_type_name(Stream, MangledModuleName,
|
|
UserEventsArrayName, not_being_defined, !IO),
|
|
io.write_string(Stream, "[];\n", !IO)
|
|
),
|
|
(
|
|
NoVarLabelLayouts = []
|
|
;
|
|
NoVarLabelLayouts = [_ | _],
|
|
NoVarLabelLayoutArrayName = label_layout_array(label_has_no_var_info),
|
|
output_layout_array_name_storage_type_name(Stream, MangledModuleName,
|
|
NoVarLabelLayoutArrayName, not_being_defined, !IO),
|
|
io.write_string(Stream, "[];\n", !IO)
|
|
),
|
|
(
|
|
SVarLabelLayouts = []
|
|
;
|
|
SVarLabelLayouts = [_ | _],
|
|
SVarLabelLayoutArrayName =
|
|
label_layout_array(label_has_short_var_info),
|
|
output_layout_array_name_storage_type_name(Stream, MangledModuleName,
|
|
SVarLabelLayoutArrayName, not_being_defined, !IO),
|
|
io.write_string(Stream, "[];\n", !IO)
|
|
),
|
|
(
|
|
LVarLabelLayouts = []
|
|
;
|
|
LVarLabelLayouts = [_ | _],
|
|
LVarLabelLayoutArrayName =
|
|
label_layout_array(label_has_long_var_info),
|
|
output_layout_array_name_storage_type_name(Stream, MangledModuleName,
|
|
LVarLabelLayoutArrayName, not_being_defined, !IO),
|
|
io.write_string(Stream, "[];\n", !IO)
|
|
),
|
|
(
|
|
CallSiteStatics = []
|
|
;
|
|
CallSiteStatics = [_ | _],
|
|
CallSiteStaticsArrayName = proc_static_call_sites_array,
|
|
output_layout_array_name_storage_type_name(Stream, MangledModuleName,
|
|
CallSiteStaticsArrayName, not_being_defined, !IO),
|
|
io.write_string(Stream, "[];\n", !IO)
|
|
),
|
|
(
|
|
CoveragePoints = []
|
|
;
|
|
CoveragePoints = [_ | _],
|
|
CoveragePointsStaticArrayName = proc_static_cp_static_array,
|
|
CoveragePointsDynamicArrayName = proc_static_cp_dynamic_array,
|
|
output_layout_array_name_storage_type_name(Stream, MangledModuleName,
|
|
CoveragePointsStaticArrayName, not_being_defined, !IO),
|
|
io.write_string(Stream, "[];\n", !IO),
|
|
output_layout_array_name_storage_type_name(Stream, MangledModuleName,
|
|
CoveragePointsDynamicArrayName, not_being_defined, !IO),
|
|
io.write_string(Stream, "[];\n", !IO)
|
|
),
|
|
(
|
|
ProcStatics = []
|
|
;
|
|
ProcStatics = [_ | _],
|
|
ProcStaticArrayName = proc_static_array,
|
|
output_layout_array_name_storage_type_name(Stream, MangledModuleName,
|
|
ProcStaticArrayName, not_being_defined, !IO),
|
|
io.write_string(Stream, "[];\n", !IO)
|
|
),
|
|
(
|
|
ProcHeadVarNums = []
|
|
;
|
|
ProcHeadVarNums = [_ | _],
|
|
ProcHeadVarNumArrayName = proc_head_var_nums_array,
|
|
output_layout_array_name_storage_type_name(Stream, MangledModuleName,
|
|
ProcHeadVarNumArrayName, not_being_defined, !IO),
|
|
io.write_string(Stream, "[];\n", !IO)
|
|
),
|
|
(
|
|
ProcVarNames = []
|
|
;
|
|
ProcVarNames = [_ | _],
|
|
ProcVarNameArrayName = proc_var_names_array,
|
|
output_layout_array_name_storage_type_name(Stream, MangledModuleName,
|
|
ProcVarNameArrayName, not_being_defined, !IO),
|
|
io.write_string(Stream, "[];\n", !IO)
|
|
),
|
|
(
|
|
ProcBodyBytecodes = []
|
|
;
|
|
ProcBodyBytecodes = [_ | _],
|
|
ProcBodyBytecodeArrayName = proc_body_bytecodes_array,
|
|
output_layout_array_name_storage_type_name(Stream, MangledModuleName,
|
|
ProcBodyBytecodeArrayName, not_being_defined, !IO),
|
|
io.write_string(Stream, "[];\n", !IO)
|
|
),
|
|
(
|
|
TableIoEntries = []
|
|
;
|
|
TableIoEntries = [_ | _],
|
|
TableIoEntrieArrayName = proc_table_io_entry_array,
|
|
output_layout_array_name_storage_type_name(Stream, MangledModuleName,
|
|
TableIoEntrieArrayName, not_being_defined, !IO),
|
|
io.write_string(Stream, "[];\n", !IO)
|
|
),
|
|
(
|
|
ExecTraces = []
|
|
;
|
|
ExecTraces = [_ | _],
|
|
ExecTraceArrayName = proc_exec_trace_array,
|
|
output_layout_array_name_storage_type_name(Stream, MangledModuleName,
|
|
ExecTraceArrayName, not_being_defined, !IO),
|
|
io.write_string(Stream, "[];\n", !IO)
|
|
),
|
|
(
|
|
ProcEventLayouts = []
|
|
;
|
|
ProcEventLayouts = [_ | _],
|
|
ProcEventLayoutArrayName = proc_event_layouts_array,
|
|
output_layout_array_name_storage_type_name(Stream, MangledModuleName,
|
|
ProcEventLayoutArrayName, not_being_defined, !IO),
|
|
io.write_string(Stream, "[];\n", !IO)
|
|
),
|
|
(
|
|
AllocSites = []
|
|
;
|
|
AllocSites = [_ | _],
|
|
AllocSiteArrayName = alloc_site_array,
|
|
output_layout_array_name_storage_type_name(Stream, MangledModuleName,
|
|
AllocSiteArrayName, not_being_defined, !IO),
|
|
io.write_string(Stream, "[];\n", !IO)
|
|
).
|
|
|
|
output_layout_array_defns(Info, Stream, PseudoTypeInfos, HLDSVarNums,
|
|
ShortLocns, LongLocns, UserEventVarNums, UserEvents,
|
|
NoVarLabelLayouts, SVarLabelLayouts, LVarLabelLayouts,
|
|
CallSiteStatics, CoveragePoints, ProcStatics,
|
|
ProcHeadVarNums, ProcVarNames, ProcBodyBytecodes, TableIoEntries,
|
|
ProcEventLayouts, ExecTraces, TSStringTable, AllocSites,
|
|
!DeclSet, !IO) :-
|
|
(
|
|
PseudoTypeInfos = []
|
|
;
|
|
PseudoTypeInfos = [_ | _],
|
|
io.nl(Stream, !IO),
|
|
output_pseudo_type_info_array_defn(Info, Stream, PseudoTypeInfos, !IO)
|
|
),
|
|
(
|
|
HLDSVarNums = []
|
|
;
|
|
HLDSVarNums = [_ | _],
|
|
io.nl(Stream, !IO),
|
|
output_hlds_var_nums_array_defn(Info, Stream, HLDSVarNums, !IO)
|
|
),
|
|
(
|
|
ShortLocns = []
|
|
;
|
|
ShortLocns = [_ | _],
|
|
io.nl(Stream, !IO),
|
|
output_short_locns_array_defn(Info, Stream, ShortLocns, !IO)
|
|
),
|
|
(
|
|
LongLocns = []
|
|
;
|
|
LongLocns = [_ | _],
|
|
io.nl(Stream, !IO),
|
|
output_long_locns_array_defn(Info, Stream, LongLocns, !IO)
|
|
),
|
|
(
|
|
UserEventVarNums = []
|
|
;
|
|
UserEventVarNums = [_ | _],
|
|
io.nl(Stream, !IO),
|
|
output_user_event_var_nums_array_defn(Info, Stream,
|
|
UserEventVarNums, !IO)
|
|
),
|
|
(
|
|
UserEvents = []
|
|
;
|
|
UserEvents = [_ | _],
|
|
io.nl(Stream, !IO),
|
|
output_user_events_array_defn(Info, Stream, UserEvents, !IO)
|
|
),
|
|
(
|
|
NoVarLabelLayouts = []
|
|
;
|
|
NoVarLabelLayouts = [_ | _],
|
|
io.nl(Stream, !IO),
|
|
output_no_var_label_layouts_array_defn(Info, Stream,
|
|
NoVarLabelLayouts, !IO)
|
|
),
|
|
(
|
|
SVarLabelLayouts = []
|
|
;
|
|
SVarLabelLayouts = [_ | _],
|
|
io.nl(Stream, !IO),
|
|
output_short_var_label_layouts_array_defn(Info, Stream,
|
|
SVarLabelLayouts, !IO)
|
|
),
|
|
(
|
|
LVarLabelLayouts = []
|
|
;
|
|
LVarLabelLayouts = [_ | _],
|
|
io.nl(Stream, !IO),
|
|
output_long_var_label_layouts_array_defn(Info, Stream,
|
|
LVarLabelLayouts, !IO)
|
|
),
|
|
(
|
|
CallSiteStatics = []
|
|
;
|
|
CallSiteStatics = [_ | _],
|
|
io.nl(Stream, !IO),
|
|
output_call_site_static_array(Info, Stream, CallSiteStatics,
|
|
!DeclSet, !IO)
|
|
),
|
|
(
|
|
CoveragePoints = []
|
|
;
|
|
CoveragePoints = [_ | _],
|
|
io.nl(Stream, !IO),
|
|
list.length(CoveragePoints, NumCoveragePoints),
|
|
output_proc_static_cp_static_array(Info, Stream, CoveragePoints,
|
|
NumCoveragePoints, !IO),
|
|
output_proc_static_cp_dynamic_array(Info, Stream,
|
|
NumCoveragePoints, !IO)
|
|
),
|
|
(
|
|
ProcStatics = []
|
|
;
|
|
ProcStatics = [_ | _],
|
|
io.nl(Stream, !IO),
|
|
output_proc_statics_array_defn(Info, Stream, ProcStatics, !IO)
|
|
),
|
|
(
|
|
ProcHeadVarNums = []
|
|
;
|
|
ProcHeadVarNums = [_ | _],
|
|
io.nl(Stream, !IO),
|
|
output_proc_head_var_nums_array(Info, Stream, ProcHeadVarNums, !IO)
|
|
),
|
|
(
|
|
ProcVarNames = []
|
|
;
|
|
ProcVarNames = [_ | _],
|
|
io.nl(Stream, !IO),
|
|
output_proc_var_names_array(Info, Stream, ProcVarNames, !IO)
|
|
),
|
|
(
|
|
ProcBodyBytecodes = []
|
|
;
|
|
ProcBodyBytecodes = [_ | _],
|
|
io.nl(Stream, !IO),
|
|
output_proc_body_bytecodes_array(Info, Stream, ProcBodyBytecodes, !IO)
|
|
),
|
|
(
|
|
TableIoEntries = []
|
|
;
|
|
TableIoEntries = [_ | _],
|
|
io.nl(Stream, !IO),
|
|
output_table_io_entry_array(Info, Stream, TableIoEntries, !IO)
|
|
),
|
|
(
|
|
ProcEventLayouts = []
|
|
;
|
|
ProcEventLayouts = [_ | _],
|
|
io.nl(Stream, !IO),
|
|
output_proc_event_layout_array(Info, Stream, ProcEventLayouts, !IO)
|
|
),
|
|
(
|
|
ExecTraces = []
|
|
;
|
|
ExecTraces = [_ | _],
|
|
io.nl(Stream, !IO),
|
|
output_exec_traces_array(Info, Stream, ExecTraces, !IO)
|
|
),
|
|
(
|
|
TSStringTable = []
|
|
;
|
|
TSStringTable = [_ | _],
|
|
io.nl(Stream, !IO),
|
|
output_threadscope_string_table_array(Info, Stream, TSStringTable, !IO)
|
|
),
|
|
(
|
|
AllocSites = []
|
|
;
|
|
AllocSites = [_ | _],
|
|
io.nl(Stream, !IO),
|
|
output_alloc_sites_array(Info, Stream, AllocSites, !IO)
|
|
).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%
|
|
% Definition of array #1: pseudo_typeinfos.
|
|
%
|
|
|
|
:- pred output_pseudo_type_info_array_defn(llds_out_info::in,
|
|
io.text_output_stream::in, list(rval)::in, io::di, io::uo) is det.
|
|
|
|
output_pseudo_type_info_array_defn(Info, Stream, PTIs, !IO) :-
|
|
ModuleName = Info ^ lout_mangled_module_name,
|
|
long_length(PTIs, NumPTIs),
|
|
Name = pseudo_type_info_array,
|
|
output_layout_array_name_storage_type_name(Stream, ModuleName, Name,
|
|
being_defined, !IO),
|
|
io.format(Stream, "[%d] = {", [i(NumPTIs)], !IO),
|
|
AutoComments = Info ^ lout_auto_comments,
|
|
(
|
|
AutoComments = auto_comments,
|
|
output_ptis_outer_loop_ac(Info, Stream, PTIs, 0, _, !IO)
|
|
;
|
|
AutoComments = no_auto_comments,
|
|
output_ptis_outer_loop_noac(Info, Stream, PTIs, 0, _, !IO)
|
|
),
|
|
io.write_string(Stream, "\n};\n\n", !IO).
|
|
|
|
:- pred output_ptis_outer_loop_ac(llds_out_info::in, io.text_output_stream::in,
|
|
list(rval)::in, int::in, int::out, io::di, io::uo) is det.
|
|
|
|
output_ptis_outer_loop_ac(_Info, _Stream, [], !Slot, !IO).
|
|
output_ptis_outer_loop_ac(Info, Stream, PTIs @ [_ | _], !Slot, !IO) :-
|
|
list.split_upto(1000, PTIs, StartPTIs, LaterPTIs),
|
|
list.chunk(StartPTIs, 10, PTIChunks),
|
|
list.foldl2(output_pti_chunk_ac(Info, Stream), PTIChunks, !Slot, !IO),
|
|
output_ptis_outer_loop_ac(Info, Stream, LaterPTIs, !Slot, !IO).
|
|
|
|
:- pred output_ptis_outer_loop_noac(llds_out_info::in,
|
|
io.text_output_stream::in, list(rval)::in, int::in, int::out,
|
|
io::di, io::uo) is det.
|
|
|
|
output_ptis_outer_loop_noac(_Info, _Stream, [], !Slot, !IO).
|
|
output_ptis_outer_loop_noac(Info, Stream, PTIs @ [_ | _], !Slot, !IO) :-
|
|
list.split_upto(1000, PTIs, StartPTIs, LaterPTIs),
|
|
list.chunk(StartPTIs, 10, PTIChunks),
|
|
list.foldl2(output_pti_chunk_noac(Info, Stream), PTIChunks, !Slot, !IO),
|
|
output_ptis_outer_loop_noac(Info, Stream, LaterPTIs, !Slot, !IO).
|
|
|
|
:- pred output_pti_chunk_ac(llds_out_info::in,
|
|
io.text_output_stream::in, list(rval)::in, int::in, int::out,
|
|
io::di, io::uo) is det.
|
|
|
|
output_pti_chunk_ac(Info, Stream, ChunkPTIs, !Slot, !IO) :-
|
|
list.length(ChunkPTIs, NumChunkPTIs),
|
|
io.format(Stream, "\n/* slots %d+ */ MR_cast_to_pti%d(\n\t",
|
|
[i(!.Slot), i(NumChunkPTIs)], !IO),
|
|
write_out_list(output_rval(Info), ",\n\t", ChunkPTIs, Stream, !IO),
|
|
io.write_string(Stream, ")", !IO),
|
|
!:Slot = !.Slot + NumChunkPTIs.
|
|
|
|
:- pred output_pti_chunk_noac(llds_out_info::in,
|
|
io.text_output_stream::in, list(rval)::in, int::in, int::out,
|
|
io::di, io::uo) is det.
|
|
|
|
output_pti_chunk_noac(Info, Stream, ChunkPTIs, !Slot, !IO) :-
|
|
list.length(ChunkPTIs, NumChunkPTIs),
|
|
io.format(Stream, "\nMR_cast_to_pti%d(", [i(NumChunkPTIs)], !IO),
|
|
write_out_list(output_rval(Info), ",\n\t", ChunkPTIs, Stream, !IO),
|
|
io.write_string(Stream, ")", !IO),
|
|
!:Slot = !.Slot + NumChunkPTIs.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%
|
|
% Definition of array #2: HLDS var numbers.
|
|
%
|
|
|
|
:- pred output_hlds_var_nums_array_defn(llds_out_info::in,
|
|
io.text_output_stream::in, list(int)::in, io::di, io::uo) is det.
|
|
|
|
output_hlds_var_nums_array_defn(Info, Stream, VarNums, !IO) :-
|
|
ModuleName = Info ^ lout_mangled_module_name,
|
|
long_length(VarNums, NumVarNums),
|
|
Name = hlds_var_nums_array,
|
|
output_layout_array_name_storage_type_name(Stream, ModuleName, Name,
|
|
being_defined, !IO),
|
|
io.format(Stream, "[%d] = {", [i(NumVarNums)], !IO),
|
|
AutoComments = Info ^ lout_auto_comments,
|
|
(
|
|
AutoComments = auto_comments,
|
|
output_numbers_in_vector_ac(Stream, VarNums, 0, !IO)
|
|
;
|
|
AutoComments = no_auto_comments,
|
|
output_numbers_in_vector_noac(Stream, VarNums, 0, !IO)
|
|
),
|
|
io.write_string(Stream, "\n};\n\n", !IO).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%
|
|
% Definition of array #3: MR_ShortLvals.
|
|
%
|
|
|
|
:- pred output_short_locns_array_defn(llds_out_info::in,
|
|
io.text_output_stream::in, list(int)::in, io::di, io::uo) is det.
|
|
|
|
output_short_locns_array_defn(Info, Stream, ShortLocns, !IO) :-
|
|
ModuleName = Info ^ lout_mangled_module_name,
|
|
list.length(ShortLocns, NumShortLocns),
|
|
Name = short_locns_array,
|
|
output_layout_array_name_storage_type_name(Stream, ModuleName, Name,
|
|
being_defined, !IO),
|
|
io.format(Stream, "[%d] = {", [i(NumShortLocns)], !IO),
|
|
AutoComments = Info ^ lout_auto_comments,
|
|
(
|
|
AutoComments = auto_comments,
|
|
output_numbers_in_vector_ac(Stream, ShortLocns, 0, !IO)
|
|
;
|
|
AutoComments = no_auto_comments,
|
|
output_numbers_in_vector_noac(Stream, ShortLocns, 0, !IO)
|
|
),
|
|
io.write_string(Stream, "\n};\n\n", !IO).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%
|
|
% Definition of array #4: MR_LongLvals.
|
|
%
|
|
|
|
:- pred output_long_locns_array_defn(llds_out_info::in,
|
|
io.text_output_stream::in, list(int)::in, io::di, io::uo) is det.
|
|
|
|
output_long_locns_array_defn(Info, Stream, LongLocns, !IO) :-
|
|
ModuleName = Info ^ lout_mangled_module_name,
|
|
list.length(LongLocns, NumLongLocns),
|
|
Name = long_locns_array,
|
|
output_layout_array_name_storage_type_name(Stream, ModuleName, Name,
|
|
being_defined, !IO),
|
|
io.format(Stream, "[%d] = {", [i(NumLongLocns)], !IO),
|
|
AutoComments = Info ^ lout_auto_comments,
|
|
(
|
|
AutoComments = auto_comments,
|
|
output_numbers_in_vector_ac(Stream, LongLocns, 0, !IO)
|
|
;
|
|
AutoComments = no_auto_comments,
|
|
output_numbers_in_vector_noac(Stream, LongLocns, 0, !IO)
|
|
),
|
|
io.write_string(Stream, "\n};\n\n", !IO).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%
|
|
% Definition of array #5: user event variable numbers.
|
|
%
|
|
|
|
:- pred output_user_event_var_nums_array_defn(llds_out_info::in,
|
|
io.text_output_stream::in, list(maybe(int))::in, io::di, io::uo) is det.
|
|
|
|
output_user_event_var_nums_array_defn(Info, Stream, MaybeVarNums, !IO) :-
|
|
ModuleName = Info ^ lout_mangled_module_name,
|
|
list.length(MaybeVarNums, NumMaybeVarNums),
|
|
Name = user_event_var_nums_array,
|
|
output_layout_array_name_storage_type_name(Stream, ModuleName, Name,
|
|
being_defined, !IO),
|
|
io.format(Stream, "[%d] = {", [i(NumMaybeVarNums)], !IO),
|
|
list.foldl2(output_maybe_var_num_slot(Stream), MaybeVarNums, 0, _, !IO),
|
|
io.write_string(Stream, "};\n\n", !IO).
|
|
|
|
:- pred output_maybe_var_num_slot(io.text_output_stream::in, maybe(int)::in,
|
|
int::in, int::out, io::di, io::uo) is det.
|
|
|
|
output_maybe_var_num_slot(Stream, MaybeVarNum, !Slot, !IO) :-
|
|
(
|
|
MaybeVarNum = no,
|
|
% Zero means not a variable, which is what we want.
|
|
VarNum = 0
|
|
;
|
|
MaybeVarNum = yes(VarNum)
|
|
),
|
|
( if !.Slot mod 10 = 0 then
|
|
io.format(Stream, "\n/* slot %d */ ", [i(!.Slot)], !IO)
|
|
else
|
|
io.write_string(Stream, " ", !IO)
|
|
),
|
|
io.format(Stream, "%d,", [i(VarNum)], !IO),
|
|
!:Slot = !.Slot + 1.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%
|
|
% Definition of array #6: user events.
|
|
%
|
|
|
|
:- pred output_user_events_array_defn(llds_out_info::in,
|
|
io.text_output_stream::in, list(user_event_data)::in,
|
|
io::di, io::uo) is det.
|
|
|
|
output_user_events_array_defn(Info, Stream, UserEvents, !IO) :-
|
|
ModuleName = Info ^ lout_mangled_module_name,
|
|
list.length(UserEvents, NumUserEvents),
|
|
Name = user_event_layout_array,
|
|
output_layout_array_name_storage_type_name(Stream, ModuleName, Name,
|
|
being_defined, !IO),
|
|
io.format(Stream, "[%d] = {\n", [i(NumUserEvents)], !IO),
|
|
list.foldl2(output_user_event_slot(Info, Stream), UserEvents, 0, _, !IO),
|
|
io.write_string(Stream, "};\n\n", !IO).
|
|
|
|
:- pred output_user_event_slot(llds_out_info::in, io.text_output_stream::in,
|
|
user_event_data::in, int::in, int::out, io::di, io::uo) is det.
|
|
|
|
output_user_event_slot(Info, Stream, UserEvent, !Slot, !IO) :-
|
|
UserEvent = user_event_data(UserEventNumber, UserLocnsRval,
|
|
MaybeVarNumsSlot),
|
|
io.write_string(Stream, "{ ", !IO),
|
|
AutoComments = Info ^ lout_auto_comments,
|
|
(
|
|
AutoComments = auto_comments,
|
|
io.format(Stream, "/* slot %d */ ", [i(!.Slot)], !IO)
|
|
;
|
|
AutoComments = no_auto_comments
|
|
),
|
|
io.write_int(Stream, UserEventNumber, !IO),
|
|
io.write_string(Stream, ", (MR_LongLval *) ", !IO),
|
|
output_rval_as_addr(Info, Stream, UserLocnsRval, !IO),
|
|
io.write_string(Stream, ",\n ", !IO),
|
|
ModuleName = Info ^ lout_mangled_module_name,
|
|
output_layout_slot_addr(Stream, use_layout_macro, ModuleName,
|
|
MaybeVarNumsSlot, !IO),
|
|
io.write_string(Stream, " },\n", !IO),
|
|
!:Slot = !.Slot + 1.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%
|
|
% Definition of array #7: label layout structures for labels with
|
|
% no variable information.
|
|
%
|
|
|
|
:- pred output_no_var_label_layouts_array_defn(llds_out_info::in,
|
|
io.text_output_stream::in, list(label_layout_no_vars)::in,
|
|
io::di, io::uo) is det.
|
|
|
|
output_no_var_label_layouts_array_defn(Info, Stream, LabelLayouts, !IO) :-
|
|
ModuleName = Info ^ lout_mangled_module_name,
|
|
list.length(LabelLayouts, NumLabelLayouts),
|
|
Name = label_layout_array(label_has_no_var_info),
|
|
output_layout_array_name_storage_type_name(Stream, ModuleName, Name,
|
|
being_defined, !IO),
|
|
io.format(Stream, "[%d] = {\n", [i(NumLabelLayouts)], !IO),
|
|
list.foldl2(output_no_var_label_layout_slot(Info, Stream), LabelLayouts,
|
|
0, _, !IO),
|
|
io.write_string(Stream, "};\n\n", !IO).
|
|
|
|
:- pred output_no_var_label_layout_slot(llds_out_info::in,
|
|
io.text_output_stream::in, label_layout_no_vars::in,
|
|
int::in, int::out, io::di, io::uo) is det.
|
|
|
|
output_no_var_label_layout_slot(Info, Stream, LabelLayout, !Slot, !IO) :-
|
|
ModuleName = Info ^ lout_mangled_module_name,
|
|
LabelLayout = label_layout_no_vars(BasicLabelLayout),
|
|
BasicLabelLayout = basic_label_layout(_ProcLabel, LabelNum,
|
|
_, _, _, _, _, _),
|
|
% The procedure is given by the proc_label printed from the basic layout.
|
|
io.write_string(Stream, "{ ", !IO),
|
|
AutoComments = Info ^ lout_auto_comments,
|
|
(
|
|
AutoComments = auto_comments,
|
|
io.format(Stream, "/* %d, %d */\n ", [i(!.Slot), i(LabelNum)], !IO)
|
|
;
|
|
AutoComments = no_auto_comments
|
|
),
|
|
output_basic_label_layout_slot(Info, Stream, ModuleName,
|
|
BasicLabelLayout, !IO),
|
|
io.write_string(Stream, " },\n", !IO),
|
|
!:Slot = !.Slot + 1.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%
|
|
% Definition of array #8: label layout structures for labels with
|
|
% only short-descriptor variable information.
|
|
%
|
|
|
|
:- pred output_short_var_label_layouts_array_defn(llds_out_info::in,
|
|
io.text_output_stream::in, list(label_layout_short_vars)::in,
|
|
io::di, io::uo) is det.
|
|
|
|
output_short_var_label_layouts_array_defn(Info, Stream, LabelLayouts, !IO) :-
|
|
ModuleName = Info ^ lout_mangled_module_name,
|
|
list.length(LabelLayouts, NumLabelLayouts),
|
|
Name = label_layout_array(label_has_short_var_info),
|
|
output_layout_array_name_storage_type_name(Stream, ModuleName, Name,
|
|
being_defined, !IO),
|
|
io.format(Stream, "[%d] = {\n", [i(NumLabelLayouts)], !IO),
|
|
list.foldl2(output_short_var_label_layout_slot(Info, Stream), LabelLayouts,
|
|
0, _, !IO),
|
|
io.write_string(Stream, "};\n\n", !IO).
|
|
|
|
:- pred output_short_var_label_layout_slot(llds_out_info::in,
|
|
io.text_output_stream::in, label_layout_short_vars::in,
|
|
int::in, int::out, io::di, io::uo) is det.
|
|
|
|
output_short_var_label_layout_slot(Info, Stream, LabelLayout, !Slot, !IO) :-
|
|
ModuleName = Info ^ lout_mangled_module_name,
|
|
LabelLayout = label_layout_short_vars(BasicLabelLayout, LabelVarInfo),
|
|
BasicLabelLayout = basic_label_layout(_ProcLabel, LabelNum,
|
|
_, _, _, _, _, _),
|
|
% The procedure is given by the proc_label printed from the basic layout.
|
|
io.write_string(Stream, "{ ", !IO),
|
|
AutoComments = Info ^ lout_auto_comments,
|
|
(
|
|
AutoComments = auto_comments,
|
|
io.format(Stream, "/* %d, %d */\n ", [i(!.Slot), i(LabelNum)], !IO)
|
|
;
|
|
AutoComments = no_auto_comments
|
|
),
|
|
output_basic_label_layout_slot(Info, Stream, ModuleName,
|
|
BasicLabelLayout, !IO),
|
|
io.write_string(Stream, ",\n ", !IO),
|
|
|
|
LabelVarInfo = label_short_var_info(EncodedVarCount, TypeParams, PTIsSlot,
|
|
HLDSVarNumsSlot, ShortLocnsSlot),
|
|
io.write_int(Stream, EncodedVarCount, !IO),
|
|
io.write_string(Stream, ",", !IO),
|
|
( if
|
|
PTIsSlot >= 0,
|
|
HLDSVarNumsSlot >= 0,
|
|
ShortLocnsSlot >= 0
|
|
then
|
|
( if
|
|
TypeParams = const(llconst_int(0))
|
|
then
|
|
io.format(Stream, "MR_LLVS0(%s,%d,%d,%d)",
|
|
[s(ModuleName),
|
|
i(PTIsSlot), i(HLDSVarNumsSlot), i(ShortLocnsSlot)], !IO)
|
|
else if
|
|
TypeParams = const(llconst_data_addr(TPDataId)),
|
|
TPDataId = scalar_common_data_id(type_num(TPTypeNum), TPCellNum)
|
|
then
|
|
io.format(Stream, "MR_LLVSC(%s,%d,%d,%d,%d,%d)",
|
|
[s(ModuleName), i(TPTypeNum), i(TPCellNum),
|
|
i(PTIsSlot), i(HLDSVarNumsSlot), i(ShortLocnsSlot)], !IO)
|
|
else
|
|
output_rval_as_addr(Info, Stream, TypeParams, !IO),
|
|
io.format(Stream, ",MR_LLVS(%s,%d,%d,%d)",
|
|
[s(ModuleName),
|
|
i(PTIsSlot), i(HLDSVarNumsSlot), i(ShortLocnsSlot)], !IO)
|
|
)
|
|
else
|
|
io.write_string(Stream, "(const MR_TypeParamLocns *) ", !IO),
|
|
output_rval_as_addr(Info, Stream, TypeParams, !IO),
|
|
io.write_string(Stream, ",", !IO),
|
|
( if PTIsSlot >= 0 then
|
|
output_layout_slot_addr(Stream, use_layout_macro, ModuleName,
|
|
layout_slot(pseudo_type_info_array, PTIsSlot), !IO),
|
|
io.write_string(Stream, ",", !IO)
|
|
else
|
|
io.write_string(Stream, "0,", !IO)
|
|
),
|
|
( if HLDSVarNumsSlot >= 0 then
|
|
output_layout_slot_addr(Stream, use_layout_macro, ModuleName,
|
|
layout_slot(hlds_var_nums_array, HLDSVarNumsSlot), !IO),
|
|
io.write_string(Stream, ",", !IO)
|
|
else
|
|
io.write_string(Stream, "0,", !IO)
|
|
),
|
|
( if ShortLocnsSlot >= 0 then
|
|
output_layout_slot_addr(Stream, use_layout_macro, ModuleName,
|
|
layout_slot(short_locns_array, ShortLocnsSlot), !IO)
|
|
else
|
|
io.write_string(Stream, "0", !IO)
|
|
)
|
|
),
|
|
io.write_string(Stream, " },\n", !IO),
|
|
!:Slot = !.Slot + 1.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%
|
|
% Definition of array #9: label layout structures for labels with
|
|
% both short and long variable descriptors.
|
|
%
|
|
|
|
:- pred output_long_var_label_layouts_array_defn(llds_out_info::in,
|
|
io.text_output_stream::in, list(label_layout_long_vars)::in,
|
|
io::di, io::uo) is det.
|
|
|
|
output_long_var_label_layouts_array_defn(Info, Stream, LabelLayouts, !IO) :-
|
|
ModuleName = Info ^ lout_mangled_module_name,
|
|
list.length(LabelLayouts, NumLabelLayouts),
|
|
Name = label_layout_array(label_has_long_var_info),
|
|
output_layout_array_name_storage_type_name(Stream, ModuleName, Name,
|
|
being_defined, !IO),
|
|
io.format(Stream, "[%d] = {\n", [i(NumLabelLayouts)], !IO),
|
|
list.foldl2(output_long_var_label_layout_slot(Info, Stream), LabelLayouts,
|
|
0, _, !IO),
|
|
io.write_string(Stream, "};\n\n", !IO).
|
|
|
|
:- pred output_long_var_label_layout_slot(llds_out_info::in,
|
|
io.text_output_stream::in, label_layout_long_vars::in,
|
|
int::in, int::out, io::di, io::uo) is det.
|
|
|
|
output_long_var_label_layout_slot(Info, Stream, LabelLayout, !Slot, !IO) :-
|
|
ModuleName = Info ^ lout_mangled_module_name,
|
|
LabelLayout = label_layout_long_vars(BasicLabelLayout, LabelVarInfo),
|
|
BasicLabelLayout = basic_label_layout(_ProcLabel, LabelNum,
|
|
_, _, _, _, _, _),
|
|
% The procedure is given by the proc_label printed from the basic layout.
|
|
io.write_string(Stream, "{ ", !IO),
|
|
AutoComments = Info ^ lout_auto_comments,
|
|
(
|
|
AutoComments = auto_comments,
|
|
io.format(Stream, "/* %d, %d */\n ", [i(!.Slot), i(LabelNum)], !IO)
|
|
;
|
|
AutoComments = no_auto_comments
|
|
),
|
|
output_basic_label_layout_slot(Info, Stream, ModuleName,
|
|
BasicLabelLayout, !IO),
|
|
io.write_string(Stream, ",\n ", !IO),
|
|
|
|
LabelVarInfo = label_long_var_info(EncodedVarCount, TypeParams, PTIsSlot,
|
|
HLDSVarNumsSlot, ShortLocnsSlot, LongLocnsSlot),
|
|
( if LongLocnsSlot >= 0 then
|
|
true
|
|
else
|
|
unexpected($pred, "no long locn")
|
|
),
|
|
|
|
io.write_int(Stream, EncodedVarCount, !IO),
|
|
io.write_string(Stream, ",", !IO),
|
|
( if
|
|
PTIsSlot >= 0,
|
|
ShortLocnsSlot >= 0,
|
|
HLDSVarNumsSlot >= 0
|
|
then
|
|
( if
|
|
TypeParams = const(llconst_int(0))
|
|
then
|
|
io.format(Stream, "MR_LLVL0(%s,%d,%d,%d,%d)",
|
|
[s(ModuleName), i(PTIsSlot), i(HLDSVarNumsSlot),
|
|
i(ShortLocnsSlot), i(LongLocnsSlot)], !IO)
|
|
else if
|
|
TypeParams = const(llconst_data_addr(TPDataId)),
|
|
TPDataId = scalar_common_data_id(type_num(TPTypeNum), TPCellNum)
|
|
then
|
|
io.format(Stream, "MR_LLVLC(%s,%d,%d,%d,%d,%d,%d)",
|
|
[s(ModuleName), i(TPTypeNum), i(TPCellNum),
|
|
i(PTIsSlot), i(HLDSVarNumsSlot),
|
|
i(ShortLocnsSlot), i(LongLocnsSlot)], !IO)
|
|
else
|
|
output_rval_as_addr(Info, Stream, TypeParams, !IO),
|
|
io.format(Stream, ",MR_LLVL(%s,%d,%d,%d,%d)",
|
|
[s(ModuleName), i(PTIsSlot), i(HLDSVarNumsSlot),
|
|
i(ShortLocnsSlot), i(LongLocnsSlot)], !IO)
|
|
)
|
|
else
|
|
io.write_string(Stream, "(const MR_TypeParamLocns *) ", !IO),
|
|
output_rval_as_addr(Info, Stream, TypeParams, !IO),
|
|
io.write_string(Stream, ",", !IO),
|
|
( if PTIsSlot >= 0 then
|
|
output_layout_slot_addr(Stream, use_layout_macro, ModuleName,
|
|
layout_slot(pseudo_type_info_array, PTIsSlot), !IO),
|
|
io.write_string(Stream, ",", !IO)
|
|
else
|
|
io.write_string(Stream, "0,", !IO)
|
|
),
|
|
( if HLDSVarNumsSlot >= 0 then
|
|
output_layout_slot_addr(Stream, use_layout_macro, ModuleName,
|
|
layout_slot(hlds_var_nums_array, HLDSVarNumsSlot), !IO),
|
|
io.write_string(Stream, ",", !IO)
|
|
else
|
|
io.write_string(Stream, "0,", !IO)
|
|
),
|
|
( if ShortLocnsSlot >= 0 then
|
|
output_layout_slot_addr(Stream, use_layout_macro, ModuleName,
|
|
layout_slot(short_locns_array, ShortLocnsSlot), !IO),
|
|
io.write_string(Stream, ",", !IO)
|
|
else
|
|
io.write_string(Stream, "0,", !IO)
|
|
),
|
|
output_layout_slot_addr(Stream, use_layout_macro, ModuleName,
|
|
layout_slot(long_locns_array, LongLocnsSlot), !IO)
|
|
),
|
|
io.write_string(Stream, " },\n", !IO),
|
|
!:Slot = !.Slot + 1.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%
|
|
% Common code shared by arrays 7, 8 and 9.
|
|
%
|
|
|
|
:- pred output_basic_label_layout_slot(llds_out_info::in,
|
|
io.text_output_stream::in, string::in, basic_label_layout::in,
|
|
io::di, io::uo) is det.
|
|
|
|
output_basic_label_layout_slot(_Info, Stream, ModuleName,
|
|
BasicLabelLayout, !IO) :-
|
|
BasicLabelLayout = basic_label_layout(ProcLabel, _LabelNum,
|
|
_ProcLayoutName, MaybePort, MaybeIsHidden, LabelNumberInModule,
|
|
MaybeGoalPath, MaybeUserSlotName),
|
|
some [!MacroName] (
|
|
!:MacroName = "MR_LL",
|
|
% MaybeIsHidden = no means that the value of the hidden field shouldn't
|
|
% matter; we arbitrarily make this mean `not hidden'.
|
|
(
|
|
( MaybeIsHidden = no
|
|
; MaybeIsHidden = yes(no)
|
|
)
|
|
;
|
|
MaybeIsHidden = yes(yes),
|
|
!:MacroName = !.MacroName ++ "_H"
|
|
),
|
|
(
|
|
MaybeUserSlotName = no
|
|
;
|
|
MaybeUserSlotName = yes(_),
|
|
!:MacroName = !.MacroName ++ "_U"
|
|
),
|
|
MacroName = !.MacroName
|
|
),
|
|
|
|
(
|
|
MaybePort = yes(Port),
|
|
PortStr = trace_port_to_string(Port)
|
|
;
|
|
MaybePort = no,
|
|
PortStr = "NONE"
|
|
),
|
|
(
|
|
MaybeGoalPath = yes(GoalPath)
|
|
;
|
|
MaybeGoalPath = no,
|
|
GoalPath = 0
|
|
),
|
|
ProcLabelStr = proc_label_to_c_string(do_not_add_label_prefix, ProcLabel),
|
|
io.format(Stream, "%s(%s, %s,%d,%d",
|
|
[s(MacroName), s(ProcLabelStr), s(PortStr),
|
|
i(LabelNumberInModule), i(GoalPath)], !IO),
|
|
(
|
|
MaybeUserSlotName = no
|
|
;
|
|
MaybeUserSlotName = yes(UserSlotName),
|
|
io.write_string(Stream, ",", !IO),
|
|
output_layout_slot_addr(Stream, use_layout_macro, ModuleName,
|
|
UserSlotName, !IO)
|
|
),
|
|
io.write_string(Stream, ")", !IO).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%
|
|
% Definition of array #10: proc static call sites.
|
|
%
|
|
|
|
:- pred output_call_site_static_array(llds_out_info::in,
|
|
io.text_output_stream::in, list(call_site_static_data)::in,
|
|
decl_set::in, decl_set::out, io::di, io::uo) is det.
|
|
|
|
output_call_site_static_array(Info, Stream, CallSiteStatics, !DeclSet, !IO) :-
|
|
% At normal call sites, the call_site_static contains a pointer to
|
|
% the proc layout of the callee procedure. Regardless of whether
|
|
% the callee is in this module or not, we won't have declared its
|
|
% proc layout structure yet.
|
|
list.foldl2(output_call_site_static_slot_decls(Info, Stream),
|
|
CallSiteStatics, !DeclSet, !IO),
|
|
io.nl(Stream, !IO),
|
|
|
|
ModuleName = Info ^ lout_mangled_module_name,
|
|
Name = proc_static_call_sites_array,
|
|
output_layout_array_name_storage_type_name(Stream, ModuleName, Name,
|
|
being_defined, !IO),
|
|
list.length(CallSiteStatics, NumCallSiteStatics),
|
|
io.format(Stream, "[%d] = {\n", [i(NumCallSiteStatics)], !IO),
|
|
list.foldl2(output_call_site_static_slot(Info, Stream), CallSiteStatics,
|
|
0, _, !IO),
|
|
io.write_string(Stream, "};\n\n", !IO).
|
|
|
|
:- pred output_call_site_static_slot_decls(llds_out_info::in,
|
|
io.text_output_stream::in, call_site_static_data::in,
|
|
decl_set::in, decl_set::out, io::di, io::uo) is det.
|
|
|
|
output_call_site_static_slot_decls(Info, Stream, CallSiteStatic,
|
|
!DeclSet, !IO) :-
|
|
(
|
|
CallSiteStatic = normal_call(Callee, _, _, _, _),
|
|
CalleeProcLabel = make_proc_label_from_rtti(Callee),
|
|
CalleeUserOrUci = proc_label_user_or_uci(CalleeProcLabel),
|
|
CalleeProcLayoutName =
|
|
proc_layout(Callee, proc_layout_proc_id(CalleeUserOrUci)),
|
|
CalleProcLayoutDataId = layout_id(CalleeProcLayoutName),
|
|
output_record_data_id_decls(Info, Stream, CalleProcLayoutDataId,
|
|
!DeclSet, !IO)
|
|
;
|
|
( CallSiteStatic = special_call(_, _, _)
|
|
; CallSiteStatic = higher_order_call(_, _, _)
|
|
; CallSiteStatic = method_call(_, _, _)
|
|
; CallSiteStatic = callback(_, _, _)
|
|
)
|
|
).
|
|
|
|
:- pred output_call_site_static_slot(llds_out_info::in,
|
|
io.text_output_stream::in, call_site_static_data::in,
|
|
int::in, int::out, io::di, io::uo) is det.
|
|
|
|
output_call_site_static_slot(Info, Stream, CallSiteStatic, !Slot, !IO) :-
|
|
io.write_string(Stream, "{ ", !IO),
|
|
AutoComments = Info ^ lout_auto_comments,
|
|
(
|
|
AutoComments = auto_comments,
|
|
io.format(Stream, "/* %d */ ", [i(!.Slot)], !IO)
|
|
;
|
|
AutoComments = no_auto_comments
|
|
),
|
|
(
|
|
CallSiteStatic = normal_call(Callee, TypeSubst, FileName, LineNumber,
|
|
GoalPath),
|
|
io.write_string(Stream,
|
|
"MR_callsite_normal_call, (MR_ProcLayout *)\n&", !IO),
|
|
CalleeProcLabel = make_proc_label_from_rtti(Callee),
|
|
CalleeUserOrUci = proc_label_user_or_uci(CalleeProcLabel),
|
|
CalleeProcLayoutName =
|
|
proc_layout(Callee, proc_layout_proc_id(CalleeUserOrUci)),
|
|
output_layout_name(Stream, CalleeProcLayoutName, !IO),
|
|
io.write_string(Stream, ",\n", !IO),
|
|
( if TypeSubst = "" then
|
|
io.write_string(Stream, "NULL, ", !IO)
|
|
else
|
|
io.write_string(Stream, """", !IO),
|
|
io.write_string(Stream, TypeSubst, !IO),
|
|
io.write_string(Stream, """, ", !IO)
|
|
)
|
|
;
|
|
CallSiteStatic = special_call(FileName, LineNumber, GoalPath),
|
|
io.write_string(Stream,
|
|
"MR_callsite_special_call, NULL, NULL, ", !IO)
|
|
;
|
|
CallSiteStatic = higher_order_call(FileName, LineNumber, GoalPath),
|
|
io.write_string(Stream,
|
|
"MR_callsite_higher_order_call, NULL, NULL, ", !IO)
|
|
;
|
|
CallSiteStatic = method_call(FileName, LineNumber, GoalPath),
|
|
io.write_string(Stream,
|
|
"MR_callsite_method_call, NULL, NULL, ", !IO)
|
|
;
|
|
CallSiteStatic = callback(FileName, LineNumber, GoalPath),
|
|
io.write_string(Stream,
|
|
"MR_callsite_callback, NULL, NULL, ", !IO)
|
|
),
|
|
io.format(Stream, "\"%s\", %d, \"%s\" },\n",
|
|
[s(FileName), i(LineNumber), s(goal_path_to_string(GoalPath))], !IO),
|
|
!:Slot = !.Slot + 1.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%
|
|
% Definition of array #11: the static parts of coverage points
|
|
% (information about the coverage point).
|
|
%
|
|
|
|
:- pred output_proc_static_cp_static_array(llds_out_info::in,
|
|
io.text_output_stream::in, list(coverage_point_info)::in,
|
|
int::in, io::di, io::uo) is det.
|
|
|
|
output_proc_static_cp_static_array(Info, Stream, CoveragePoints,
|
|
NumCoveragePoints, !IO) :-
|
|
ModuleName = Info ^ lout_mangled_module_name,
|
|
Name = proc_static_cp_static_array,
|
|
output_layout_array_name_storage_type_name(Stream, ModuleName, Name,
|
|
being_defined, !IO),
|
|
io.format(Stream, "[%d] = {\n", [i(NumCoveragePoints)], !IO),
|
|
AutoComments = Info ^ lout_auto_comments,
|
|
list.foldl2(output_proc_static_cp_static_slot(Stream, AutoComments),
|
|
CoveragePoints, 0, _, !IO),
|
|
io.write_string(Stream, "};\n\n", !IO).
|
|
|
|
:- pred output_proc_static_cp_static_slot(io.text_output_stream::in,
|
|
maybe_auto_comments::in, coverage_point_info::in,
|
|
int::in, int::out, io::di, io::uo) is det.
|
|
|
|
output_proc_static_cp_static_slot(Stream, AutoComments, CoveragePoint,
|
|
!Slot, !IO) :-
|
|
CoveragePoint = coverage_point_info(RevGoalPath, CPType),
|
|
io.write_string(Stream, "{ ", !IO),
|
|
(
|
|
AutoComments = auto_comments,
|
|
io.format(Stream, "/* %d */ ", [i(!.Slot)], !IO)
|
|
;
|
|
AutoComments = no_auto_comments
|
|
),
|
|
GoalPathString = rev_goal_path_to_string(RevGoalPath),
|
|
coverage_point_type_c_value(CPType, CPTypeCValue),
|
|
io.format(Stream, "\"%s\", %s },\n",
|
|
[s(GoalPathString), s(CPTypeCValue)], !IO),
|
|
!:Slot = !.Slot + 1.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%
|
|
% Definition of array #12: the dynamic parts of coverage points (the counts).
|
|
%
|
|
|
|
:- pred output_proc_static_cp_dynamic_array(llds_out_info::in,
|
|
io.text_output_stream::in, int::in, io::di, io::uo) is det.
|
|
|
|
output_proc_static_cp_dynamic_array(Info, Stream, NumCoveragePoints, !IO) :-
|
|
ModuleName = Info ^ lout_mangled_module_name,
|
|
Name = proc_static_cp_dynamic_array,
|
|
output_layout_array_name_storage_type_name(Stream, ModuleName, Name,
|
|
being_defined, !IO),
|
|
% The C compiler will arrange for the array to be initialized to all zeros.
|
|
io.format(Stream, "[%d];\n", [i(NumCoveragePoints)], !IO).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%
|
|
% Definition of array #13: proc static structures.
|
|
%
|
|
|
|
:- pred output_proc_statics_array_defn(llds_out_info::in,
|
|
io.text_output_stream::in, list(proc_layout_proc_static)::in,
|
|
io::di, io::uo) is det.
|
|
|
|
output_proc_statics_array_defn(Info, Stream, ProcStatics, !IO) :-
|
|
ModuleName = Info ^ lout_mangled_module_name,
|
|
list.length(ProcStatics, NumProcStatics),
|
|
Name = proc_static_array,
|
|
output_layout_array_name_storage_type_name(Stream, ModuleName, Name,
|
|
being_defined, !IO),
|
|
io.format(Stream, "[%d] = {\n", [i(NumProcStatics)], !IO),
|
|
list.foldl2(output_proc_static_slot(Info, Stream), ProcStatics, 0, _, !IO),
|
|
io.write_string(Stream, "};\n\n", !IO).
|
|
|
|
:- pred output_proc_static_slot(llds_out_info::in, io.text_output_stream::in,
|
|
proc_layout_proc_static::in, int::in, int::out, io::di, io::uo) is det.
|
|
|
|
output_proc_static_slot(Info, Stream, ProcStatic, !Slot, !IO) :-
|
|
ProcStatic = proc_layout_proc_static(FileName, LineNumber,
|
|
IsInInterface, DeepExcpVars, MaybeCallSites, MaybeCoveragePoints),
|
|
io.write_string(Stream, "{ ", !IO),
|
|
AutoComments = Info ^ lout_auto_comments,
|
|
MangledModuleName = Info ^ lout_mangled_module_name,
|
|
(
|
|
AutoComments = auto_comments,
|
|
io.format(Stream, "/* %d */ ", [i(!.Slot)], !IO)
|
|
;
|
|
AutoComments = no_auto_comments
|
|
),
|
|
output_quoted_string_c(Stream, FileName, !IO),
|
|
io.write_string(Stream, ",", !IO),
|
|
io.write_int(Stream, LineNumber, !IO),
|
|
io.write_string(Stream, ",", !IO),
|
|
(
|
|
IsInInterface = yes,
|
|
io.write_string(Stream, "MR_TRUE", !IO)
|
|
;
|
|
IsInInterface = no,
|
|
io.write_string(Stream, "MR_FALSE", !IO)
|
|
),
|
|
io.write_string(Stream, ",\n ", !IO),
|
|
(
|
|
MaybeCallSites = yes({CallSitesSlot, NumCallSites}),
|
|
io.write_int(Stream, NumCallSites, !IO),
|
|
io.write_string(Stream, ",", !IO),
|
|
CallSitesSlotName =
|
|
layout_slot(proc_static_call_sites_array, CallSitesSlot),
|
|
output_layout_slot_addr(Stream, use_layout_macro, MangledModuleName,
|
|
CallSitesSlotName, !IO),
|
|
io.write_string(Stream, ",\n", !IO)
|
|
;
|
|
MaybeCallSites = no,
|
|
io.write_string(Stream, "0,NULL,\n", !IO)
|
|
),
|
|
io.write_string(Stream, "#ifdef MR_USE_ACTIVATION_COUNTS\n", !IO),
|
|
io.write_string(Stream, "0,\n", !IO),
|
|
io.write_string(Stream, "#endif\n", !IO),
|
|
io.write_string(Stream, "NULL,", !IO),
|
|
DeepExcpVars = deep_excp_slots(TopCSDSlot, MiddleCSDSlot,
|
|
OldOutermostSlot),
|
|
io.write_int(Stream, TopCSDSlot, !IO),
|
|
io.write_string(Stream, ",", !IO),
|
|
io.write_int(Stream, MiddleCSDSlot, !IO),
|
|
io.write_string(Stream, ",", !IO),
|
|
io.write_int(Stream, OldOutermostSlot, !IO),
|
|
io.write_string(Stream, ",", !IO),
|
|
io.write_string(Stream, "\n#ifdef MR_DEEP_PROFILING_COVERAGE\n", !IO),
|
|
(
|
|
MaybeCoveragePoints = yes({CoveragePointsSlot, NumCoveragePoints}),
|
|
% If MR_DEEP_PROFILING_COVERAGE is not defined but
|
|
% --deep-profiling-coverage is, this generated code will not compile,
|
|
% as these fields in this structure will not be present.
|
|
io.write_int(Stream, NumCoveragePoints, !IO),
|
|
io.write_string(Stream, ",\n", !IO),
|
|
CoveragePointsStaticSlotName =
|
|
layout_slot(proc_static_cp_static_array, CoveragePointsSlot),
|
|
output_layout_slot_addr(Stream, use_layout_macro, MangledModuleName,
|
|
CoveragePointsStaticSlotName, !IO),
|
|
io.write_string(Stream, ",\n", !IO),
|
|
io.write_string(Stream,
|
|
"#ifdef MR_DEEP_PROFILING_COVERAGE_STATIC\n", !IO),
|
|
CoveragePointsDynamicSlotName =
|
|
layout_slot(proc_static_cp_dynamic_array, CoveragePointsSlot),
|
|
output_layout_slot_addr(Stream, use_layout_macro, MangledModuleName,
|
|
CoveragePointsDynamicSlotName, !IO)
|
|
;
|
|
MaybeCoveragePoints = no,
|
|
io.write_string(Stream, "0,NULL,\n", !IO),
|
|
io.write_string(Stream,
|
|
"#ifdef MR_DEEP_PROFILING_COVERAGE_STATIC\n", !IO),
|
|
io.write_string(Stream, "NULL", !IO)
|
|
),
|
|
io.write_string(Stream, "\n#endif\n", !IO),
|
|
io.write_string(Stream, "#endif\n", !IO),
|
|
io.write_string(Stream, " },\n", !IO),
|
|
!:Slot = !.Slot + 1.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%
|
|
% Definition of array #14: proc head variable numbers.
|
|
%
|
|
|
|
:- pred output_proc_head_var_nums_array(llds_out_info::in,
|
|
io.text_output_stream::in, list(int)::in, io::di, io::uo) is det.
|
|
|
|
output_proc_head_var_nums_array(Info, Stream, HeadVarNums, !IO) :-
|
|
ModuleName = Info ^ lout_mangled_module_name,
|
|
list.length(HeadVarNums, NumHeadVarNums),
|
|
Name = proc_head_var_nums_array,
|
|
output_layout_array_name_storage_type_name(Stream, ModuleName, Name,
|
|
being_defined, !IO),
|
|
io.format(Stream, "[%d] = {", [i(NumHeadVarNums)], !IO),
|
|
AutoComments = Info ^ lout_auto_comments,
|
|
(
|
|
AutoComments = auto_comments,
|
|
output_numbers_in_vector_ac(Stream, HeadVarNums, 0, !IO)
|
|
;
|
|
AutoComments = no_auto_comments,
|
|
output_numbers_in_vector_noac(Stream, HeadVarNums, 0, !IO)
|
|
),
|
|
io.write_string(Stream, "\n};\n\n", !IO).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%
|
|
% Definition of array #15: proc variable names.
|
|
%
|
|
|
|
:- pred output_proc_var_names_array(llds_out_info::in,
|
|
io.text_output_stream::in, list(int)::in, io::di, io::uo) is det.
|
|
|
|
output_proc_var_names_array(Info, Stream, VarNames, !IO) :-
|
|
ModuleName = Info ^ lout_mangled_module_name,
|
|
list.length(VarNames, NumVarNames),
|
|
Name = proc_var_names_array,
|
|
output_layout_array_name_storage_type_name(Stream, ModuleName, Name,
|
|
being_defined, !IO),
|
|
io.format(Stream, "[%d] = {", [i(NumVarNames)], !IO),
|
|
AutoComments = Info ^ lout_auto_comments,
|
|
(
|
|
AutoComments = auto_comments,
|
|
output_numbers_in_vector_ac(Stream, VarNames, 0, !IO)
|
|
;
|
|
AutoComments = no_auto_comments,
|
|
output_numbers_in_vector_noac(Stream, VarNames, 0, !IO)
|
|
),
|
|
io.write_string(Stream, "\n};\n\n", !IO).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%
|
|
% Definition of array #16: proc body bytecodes names.
|
|
%
|
|
|
|
:- pred output_proc_body_bytecodes_array(llds_out_info::in,
|
|
io.text_output_stream::in, list(int)::in, io::di, io::uo) is det.
|
|
|
|
output_proc_body_bytecodes_array(Info, Stream, Bytecodes, !IO) :-
|
|
ModuleName = Info ^ lout_mangled_module_name,
|
|
list.length(Bytecodes, NumBytecodes),
|
|
Name = proc_body_bytecodes_array,
|
|
output_layout_array_name_storage_type_name(Stream, ModuleName, Name,
|
|
being_defined, !IO),
|
|
io.format(Stream, "[%d] = {\n", [i(NumBytecodes)], !IO),
|
|
AutoComments = Info ^ lout_auto_comments,
|
|
(
|
|
AutoComments = auto_comments,
|
|
output_numbers_in_vector_ac(Stream, Bytecodes, 0, !IO)
|
|
;
|
|
AutoComments = no_auto_comments,
|
|
output_numbers_in_vector_noac(Stream, Bytecodes, 0, !IO)
|
|
),
|
|
io.write_string(Stream, "};\n\n", !IO).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%
|
|
% Definition of array #17: table_io structures.
|
|
%
|
|
|
|
:- pred output_table_io_entry_array(llds_out_info::in,
|
|
io.text_output_stream::in, list(table_io_entry_data)::in,
|
|
io::di, io::uo) is det.
|
|
|
|
output_table_io_entry_array(Info, Stream, TableIoEntries, !IO) :-
|
|
ModuleName = Info ^ lout_mangled_module_name,
|
|
list.length(TableIoEntries, NumTableIoEntries),
|
|
Name = proc_table_io_entry_array,
|
|
output_layout_array_name_storage_type_name(Stream, ModuleName, Name,
|
|
being_defined, !IO),
|
|
io.format(Stream, "[%d] = {\n", [i(NumTableIoEntries)], !IO),
|
|
list.foldl2(output_table_io_entry_slot(Info, Stream),
|
|
TableIoEntries, 0, _, !IO),
|
|
io.write_string(Stream, "};\n\n", !IO).
|
|
|
|
:- pred output_table_io_entry_slot(llds_out_info::in,
|
|
io.text_output_stream::in, table_io_entry_data::in,
|
|
int::in, int::out, io::di, io::uo) is det.
|
|
|
|
output_table_io_entry_slot(Info, Stream, TableIoEntry, !Slot, !IO) :-
|
|
TableIoEntry = table_io_entry_data(ProcLayoutName, MaybeArgInfos),
|
|
io.write_string(Stream, "{ ", !IO),
|
|
AutoComments = Info ^ lout_auto_comments,
|
|
(
|
|
AutoComments = auto_comments,
|
|
io.format(Stream, "/* %d */\n ", [i(!.Slot)], !IO)
|
|
;
|
|
AutoComments = no_auto_comments
|
|
),
|
|
io.write_string(Stream, "(const MR_ProcLayout *) &", !IO),
|
|
output_layout_name(Stream, ProcLayoutName, !IO),
|
|
io.write_string(Stream, ",\n ", !IO),
|
|
(
|
|
MaybeArgInfos = no,
|
|
io.write_string(Stream, "MR_FALSE, 0, NULL, NULL", !IO)
|
|
;
|
|
MaybeArgInfos = yes(ArgInfos),
|
|
ArgInfos = table_io_args_data(NumPTIs, PTIVectorRval, TypeParamsRval),
|
|
io.write_string(Stream, "MR_TRUE,\n ", !IO),
|
|
io.write_int(Stream, NumPTIs, !IO),
|
|
io.write_string(Stream, ",\n (const MR_PseudoTypeInfo *) ", !IO),
|
|
output_rval(Info, PTIVectorRval, Stream, !IO),
|
|
io.write_string(Stream, ", (const MR_TypeParamLocns *) ", !IO),
|
|
output_rval(Info, TypeParamsRval, Stream, !IO)
|
|
),
|
|
io.write_string(Stream, " },\n", !IO),
|
|
!:Slot = !.Slot + 1.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%
|
|
% Definition of array #18: proc event layouts.
|
|
%
|
|
|
|
:- pred output_proc_event_layout_array(llds_out_info::in,
|
|
io.text_output_stream::in, list(layout_slot_name)::in,
|
|
io::di, io::uo) is det.
|
|
|
|
output_proc_event_layout_array(Info, Stream, ProcEventLayoutSlotNames, !IO) :-
|
|
ModuleName = Info ^ lout_mangled_module_name,
|
|
list.length(ProcEventLayoutSlotNames, NumProcEventLayoutSlotNames),
|
|
Name = proc_event_layouts_array,
|
|
output_layout_array_name_storage_type_name(Stream, ModuleName, Name,
|
|
being_defined, !IO),
|
|
io.format(Stream, "[%d] = {\n", [i(NumProcEventLayoutSlotNames)], !IO),
|
|
output_layout_slots_in_vector(Stream, ModuleName,
|
|
ProcEventLayoutSlotNames, !IO),
|
|
io.write_string(Stream, "};\n\n", !IO).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%
|
|
% Definition of array #19: execution tracing structures.
|
|
%
|
|
|
|
:- pred output_exec_traces_array(llds_out_info::in,
|
|
io.text_output_stream::in, list(proc_layout_exec_trace)::in,
|
|
io::di, io::uo) is det.
|
|
|
|
output_exec_traces_array(Info, Stream, ExecTraces, !IO) :-
|
|
ModuleName = Info ^ lout_mangled_module_name,
|
|
list.length(ExecTraces, NumExecTraces),
|
|
Name = proc_exec_trace_array,
|
|
output_layout_array_name_storage_type_name(Stream, ModuleName, Name,
|
|
being_defined, !IO),
|
|
io.format(Stream, "[%d] = {\n", [i(NumExecTraces)], !IO),
|
|
list.foldl2(output_exec_trace_slot(Info, Stream), ExecTraces, 0u, _, !IO),
|
|
io.write_string(Stream, "};\n\n", !IO).
|
|
|
|
:- pred output_exec_trace_slot(llds_out_info::in,
|
|
io.text_output_stream::in, proc_layout_exec_trace::in,
|
|
uint::in, uint::out, io::di, io::uo) is det.
|
|
|
|
output_exec_trace_slot(Info, Stream, ExecTrace, !Slot, !IO) :-
|
|
ExecTrace = proc_layout_exec_trace(MaybeCallLabelSlotName,
|
|
EventLayoutsSlotName, NumEventLayouts, MaybeTableInfo,
|
|
MaybeHeadVarsSlotName, NumHeadVarNums, MaybeVarNamesSlotName,
|
|
MaxVarNum, MaxRegR, MaxRegF, MaybeFromFullSlot, MaybeIoSeqSlot,
|
|
MaybeTrailSlot, MaybeMaxfrSlot, EvalMethod, MaybeCallTableSlot,
|
|
MaybeTailRecSlot, EffTraceLevel, Flags),
|
|
AutoComments = Info ^ lout_auto_comments,
|
|
io.write_string(Stream, "{ ", !IO),
|
|
(
|
|
AutoComments = auto_comments,
|
|
io.format(Stream, "/* %u */ ", [u(!.Slot)], !IO),
|
|
!:Slot = !.Slot + 1u
|
|
;
|
|
AutoComments = no_auto_comments
|
|
),
|
|
|
|
MangledModuleName = Info ^ lout_mangled_module_name,
|
|
(
|
|
MaybeCallLabelSlotName = yes(CallLabelSlotName),
|
|
io.write_string(Stream, "(MR_LabelLayout *) ", !IO),
|
|
output_layout_slot_addr(Stream, use_layout_macro, MangledModuleName,
|
|
CallLabelSlotName, !IO),
|
|
io.write_string(Stream, ",\n ", !IO)
|
|
;
|
|
MaybeCallLabelSlotName = no,
|
|
io.write_string(Stream, "NULL,\n ", !IO)
|
|
),
|
|
io.write_string(Stream, "(const MR_ModuleLayout *) &", !IO),
|
|
ModuleName = Info ^ lout_module_name,
|
|
output_layout_name(Stream, module_layout(ModuleName), !IO),
|
|
io.write_string(Stream, ",\n ", !IO),
|
|
output_layout_slot_addr(Stream, use_layout_macro, MangledModuleName,
|
|
EventLayoutsSlotName, !IO),
|
|
io.write_string(Stream, ",", !IO),
|
|
io.write_int(Stream, NumEventLayouts, !IO),
|
|
io.write_string(Stream, ",\n ", !IO),
|
|
io.write_string(Stream, "{ ", !IO),
|
|
(
|
|
MaybeTableInfo = yes(TableInfo),
|
|
(
|
|
TableInfo = data_or_slot_is_slot(TableSlotName),
|
|
io.write_string(Stream, "(const void *) ", !IO),
|
|
output_layout_slot_addr(Stream, use_layout_macro,
|
|
MangledModuleName, TableSlotName, !IO)
|
|
;
|
|
TableInfo = data_or_slot_is_data(TableDataId),
|
|
io.write_string(Stream, "(const void *) &", !IO),
|
|
output_data_id(Info, Stream, TableDataId, !IO)
|
|
)
|
|
;
|
|
MaybeTableInfo = no,
|
|
io.write_string(Stream, "NULL", !IO)
|
|
),
|
|
io.write_string(Stream, " },\n ", !IO),
|
|
(
|
|
MaybeHeadVarsSlotName = yes(HeadVarNumsSlotName),
|
|
output_layout_slot_addr(Stream, use_layout_macro, MangledModuleName,
|
|
HeadVarNumsSlotName, !IO)
|
|
;
|
|
MaybeHeadVarsSlotName = no,
|
|
io.write_string(Stream, "NULL", !IO)
|
|
),
|
|
io.write_string(Stream, ",", !IO),
|
|
(
|
|
MaybeVarNamesSlotName = yes(VarNamesSlotName),
|
|
output_layout_slot_addr(Stream, use_layout_macro, MangledModuleName,
|
|
VarNamesSlotName, !IO)
|
|
;
|
|
MaybeVarNamesSlotName = no,
|
|
io.write_string(Stream, "NULL", !IO)
|
|
),
|
|
io.write_string(Stream, ",\n ", !IO),
|
|
io.write_int(Stream, NumHeadVarNums, !IO),
|
|
io.write_string(Stream, ",", !IO),
|
|
io.write_int(Stream, MaxVarNum, !IO),
|
|
io.write_string(Stream, ",", !IO),
|
|
io.write_int(Stream, MaxRegR, !IO),
|
|
io.write_string(Stream, ",", !IO),
|
|
io.write_int(Stream, MaxRegF, !IO),
|
|
io.write_string(Stream, ",", !IO),
|
|
write_maybe_slot_num(Stream, MaybeFromFullSlot, !IO),
|
|
io.write_string(Stream, ",", !IO),
|
|
write_maybe_slot_num(Stream, MaybeIoSeqSlot, !IO),
|
|
io.write_string(Stream, ",", !IO),
|
|
write_maybe_slot_num(Stream, MaybeTrailSlot, !IO),
|
|
io.write_string(Stream, ",", !IO),
|
|
write_maybe_slot_num(Stream, MaybeMaxfrSlot, !IO),
|
|
io.write_string(Stream, ",", !IO),
|
|
io.write_string(Stream, eval_method_to_c_string(EvalMethod), !IO),
|
|
io.write_string(Stream, ",", !IO),
|
|
write_maybe_slot_num(Stream, MaybeCallTableSlot, !IO),
|
|
io.write_string(Stream, ",", !IO),
|
|
io.write_string(Stream, eff_trace_level_rep(EffTraceLevel), !IO),
|
|
io.write_string(Stream, ",\n ", !IO),
|
|
io.write_int(Stream, Flags, !IO),
|
|
io.write_string(Stream, ",", !IO),
|
|
write_maybe_slot_num(Stream, MaybeTailRecSlot, !IO),
|
|
io.write_string(Stream, " },\n", !IO).
|
|
|
|
:- pred write_maybe_slot_num(io.text_output_stream::in, maybe(int)::in,
|
|
io::di, io::uo) is det.
|
|
|
|
write_maybe_slot_num(Stream, yes(SlotNum), !IO) :-
|
|
io.write_int(Stream, SlotNum, !IO).
|
|
write_maybe_slot_num(Stream, no, !IO) :-
|
|
io.write_int(Stream, -1, !IO).
|
|
|
|
:- func eval_method_to_c_string(eval_method) = string.
|
|
|
|
eval_method_to_c_string(EvalMethod) = Str :-
|
|
(
|
|
EvalMethod = eval_normal,
|
|
Str = "MR_EVAL_METHOD_NORMAL"
|
|
;
|
|
EvalMethod = eval_tabled(TabledMethod),
|
|
(
|
|
TabledMethod = tabled_loop_check,
|
|
Str = "MR_EVAL_METHOD_LOOP_CHECK"
|
|
;
|
|
TabledMethod = tabled_memo(_),
|
|
Str = "MR_EVAL_METHOD_MEMO"
|
|
;
|
|
TabledMethod = tabled_minimal(MinimalMethod),
|
|
(
|
|
MinimalMethod = stack_copy,
|
|
Str = "MR_EVAL_METHOD_MINIMAL_STACK_COPY"
|
|
;
|
|
MinimalMethod = own_stacks_consumer,
|
|
Str = "MR_EVAL_METHOD_MINIMAL_OWN_STACKS_CONSUMER"
|
|
;
|
|
MinimalMethod = own_stacks_generator,
|
|
Str = "MR_EVAL_METHOD_MINIMAL_OWN_STACKS_GENERATOR"
|
|
)
|
|
;
|
|
TabledMethod = tabled_io(EntryKind, Unitize),
|
|
(
|
|
( EntryKind = entry_stores_outputs
|
|
; EntryKind = entry_stores_procid_outputs
|
|
),
|
|
Unitize = table_io_alone,
|
|
Str = "MR_EVAL_METHOD_TABLE_IO"
|
|
;
|
|
( EntryKind = entry_stores_outputs
|
|
; EntryKind = entry_stores_procid_outputs
|
|
),
|
|
Unitize = table_io_unitize,
|
|
Str = "MR_EVAL_METHOD_TABLE_IO_UNITIZE"
|
|
;
|
|
EntryKind = entry_stores_procid_inputs_outputs,
|
|
Unitize = table_io_alone,
|
|
Str = "MR_EVAL_METHOD_TABLE_IO_DECL"
|
|
;
|
|
EntryKind = entry_stores_procid_inputs_outputs,
|
|
Unitize = table_io_unitize,
|
|
Str = "MR_EVAL_METHOD_TABLE_IO_UNITIZE_DECL"
|
|
)
|
|
)
|
|
).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%
|
|
% Definition of array #20: threadscope string table.
|
|
%
|
|
|
|
:- pred output_threadscope_string_table_array(llds_out_info::in,
|
|
io.text_output_stream::in, list(string)::in, io::di, io::uo) is det.
|
|
|
|
output_threadscope_string_table_array(Info, Stream, TSStringTable, !IO) :-
|
|
ModuleName = Info ^ lout_mangled_module_name,
|
|
list.length(TSStringTable, NumStrings),
|
|
Name = threadscope_string_table_array,
|
|
io.write_string(Stream, "#ifdef MR_THREADSCOPE\n", !IO),
|
|
output_layout_array_name_storage_type_name(Stream, ModuleName, Name,
|
|
being_defined, !IO),
|
|
io.format(Stream, "[%d] = {\n", [i(NumStrings)], !IO),
|
|
list.foldl2(output_threadscope_string_table_slot(Info, Stream),
|
|
TSStringTable, 0u, _, !IO),
|
|
io.write_string(Stream, "};\n#endif\n\n", !IO).
|
|
|
|
:- pred output_threadscope_string_table_slot(llds_out_info::in,
|
|
io.text_output_stream::in, string::in,
|
|
uint::in, uint::out, io::di, io::uo) is det.
|
|
|
|
output_threadscope_string_table_slot(Info, Stream, String, !Slot, !IO) :-
|
|
AutoComments = Info ^ lout_auto_comments,
|
|
(
|
|
AutoComments = auto_comments,
|
|
io.format(Stream, "/* %u */ ", [u(!.Slot)], !IO),
|
|
!:Slot = !.Slot + 1u
|
|
;
|
|
AutoComments = no_auto_comments
|
|
),
|
|
io.write_string(Stream, "{ ", !IO),
|
|
output_quoted_string_c(Stream, String, !IO),
|
|
io.write_string(Stream, ", 0},\n", !IO).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%
|
|
% Definition of array #21: allocation site structures.
|
|
%
|
|
|
|
:- pred output_alloc_sites_array(llds_out_info::in, io.text_output_stream::in,
|
|
list(alloc_site_info)::in, io::di, io::uo) is det.
|
|
|
|
output_alloc_sites_array(Info, Stream, AllocSites, !IO) :-
|
|
ModuleName = Info ^ lout_mangled_module_name,
|
|
output_layout_array_name_storage_type_name(Stream, ModuleName,
|
|
alloc_site_array, being_defined, !IO),
|
|
list.length(AllocSites, NumAllocSitess),
|
|
io.format(Stream, "[%d] = {\n", [i(NumAllocSitess)], !IO),
|
|
list.foldl2(output_alloc_site_slot(Info, Stream), AllocSites, 0u, _, !IO),
|
|
io.write_string(Stream, "};\n\n", !IO).
|
|
|
|
:- pred output_alloc_site_slot(llds_out_info::in, io.text_output_stream::in,
|
|
alloc_site_info::in, uint::in, uint::out, io::di, io::uo) is det.
|
|
|
|
output_alloc_site_slot(_Info, Stream, AllocSite, !Slot, !IO) :-
|
|
AllocSite = alloc_site_info(ProcLabel, Context, TypeMsg, NumWords),
|
|
Context = context(FileName, LineNumber),
|
|
ProcLabelStr = proc_label_to_c_string(add_label_prefix, ProcLabel),
|
|
io.format(Stream, "\t/* slot %u */ {%s, ",
|
|
[u(!.Slot), s(ProcLabelStr)], !IO),
|
|
output_quoted_string_c(Stream, FileName, !IO),
|
|
io.format(Stream, ", %d, ", [i(LineNumber)], !IO),
|
|
output_quoted_string_c(Stream, TypeMsg, !IO),
|
|
io.format(Stream, ", %d},\n ", [i(NumWords)], !IO),
|
|
!:Slot = !.Slot + 1u.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
output_layout_name_decl(Stream, LayoutName, !IO) :-
|
|
output_layout_name_storage_type_name(Stream, LayoutName,
|
|
not_being_defined, !IO),
|
|
io.write_string(Stream, ";\n", !IO).
|
|
|
|
output_maybe_layout_name_decl(Stream, LayoutName, !DeclSet, !IO) :-
|
|
( if decl_set_insert_new(decl_layout_id(LayoutName), !DeclSet) then
|
|
output_layout_name_decl(Stream, LayoutName, !IO)
|
|
else
|
|
true
|
|
).
|
|
|
|
:- pred output_layout_decl(io.text_output_stream::in, layout_name::in,
|
|
decl_set::in, decl_set::out, io::di, io::uo) is det.
|
|
|
|
output_layout_decl(Stream, LayoutName, !DeclSet, !IO) :-
|
|
( if decl_set_insert_new(decl_layout_id(LayoutName), !DeclSet) then
|
|
output_layout_name_storage_type_name(Stream, LayoutName,
|
|
not_being_defined, !IO),
|
|
io.write_string(Stream, ";\n", !IO)
|
|
else
|
|
true
|
|
).
|
|
|
|
output_layout_array_name(Stream, UseMacro, ModuleName, ArrayName, !IO) :-
|
|
(
|
|
UseMacro = use_layout_macro,
|
|
(
|
|
ArrayName = label_layout_array(label_has_no_var_info),
|
|
Macro = "MR_no_var_label_layouts"
|
|
;
|
|
ArrayName = label_layout_array(label_has_short_var_info),
|
|
Macro = "MR_svar_label_layouts"
|
|
;
|
|
ArrayName = label_layout_array(label_has_long_var_info),
|
|
Macro = "MR_lvar_label_layouts"
|
|
;
|
|
ArrayName = pseudo_type_info_array,
|
|
Macro = "MR_pseudo_type_infos"
|
|
;
|
|
ArrayName = long_locns_array,
|
|
Macro = "MR_long_locns"
|
|
;
|
|
ArrayName = short_locns_array,
|
|
Macro = "MR_short_locns"
|
|
;
|
|
ArrayName = hlds_var_nums_array,
|
|
Macro = "MR_hlds_var_nums"
|
|
;
|
|
ArrayName = user_event_var_nums_array,
|
|
Macro = "MR_user_event_var_nums"
|
|
;
|
|
ArrayName = user_event_layout_array,
|
|
Macro = "MR_user_event_layouts"
|
|
;
|
|
ArrayName = proc_static_call_sites_array,
|
|
Macro = "MR_proc_call_sites"
|
|
;
|
|
ArrayName = proc_static_cp_static_array,
|
|
Macro = "MR_proc_cp_statics"
|
|
;
|
|
ArrayName = proc_static_cp_dynamic_array,
|
|
Macro = "MR_proc_cp_dynamics"
|
|
;
|
|
ArrayName = proc_static_array,
|
|
Macro = "MR_proc_statics"
|
|
;
|
|
ArrayName = proc_head_var_nums_array,
|
|
Macro = "MR_proc_head_var_nums"
|
|
;
|
|
ArrayName = proc_var_names_array,
|
|
Macro = "MR_proc_var_names"
|
|
;
|
|
ArrayName = proc_body_bytecodes_array,
|
|
Macro = "MR_proc_body_bytecodes"
|
|
;
|
|
ArrayName = proc_table_io_entry_array,
|
|
Macro = "MR_proc_table_io_entries"
|
|
;
|
|
ArrayName = proc_event_layouts_array,
|
|
Macro = "MR_proc_event_layouts"
|
|
;
|
|
ArrayName = proc_exec_trace_array,
|
|
Macro = "MR_proc_exec_traces"
|
|
;
|
|
ArrayName = threadscope_string_table_array,
|
|
Macro = "MR_threadscope_strings"
|
|
;
|
|
ArrayName = alloc_site_array,
|
|
Macro = "MR_alloc_sites"
|
|
),
|
|
io.format(Stream, "%s(%s)", [s(Macro), s(ModuleName)], !IO)
|
|
;
|
|
UseMacro = do_not_use_layout_macro,
|
|
(
|
|
ArrayName = label_layout_array(label_has_no_var_info),
|
|
Prefix = "mercury_data__no_var_label_layout_array__"
|
|
;
|
|
ArrayName = label_layout_array(label_has_short_var_info),
|
|
Prefix = "mercury_data__svar_label_layout_array__"
|
|
;
|
|
ArrayName = label_layout_array(label_has_long_var_info),
|
|
Prefix = "mercury_data__lvar_label_layout_array__"
|
|
;
|
|
ArrayName = pseudo_type_info_array,
|
|
Prefix = "mercury_data__pseudo_type_info_array__"
|
|
;
|
|
ArrayName = long_locns_array,
|
|
Prefix = "mercury_data__long_locns_array__"
|
|
;
|
|
ArrayName = short_locns_array,
|
|
Prefix = "mercury_data__short_locns_array__"
|
|
;
|
|
ArrayName = hlds_var_nums_array,
|
|
Prefix = "mercury_data__hlds_var_nums_array__"
|
|
;
|
|
ArrayName = user_event_var_nums_array,
|
|
Prefix = "mercury_data__user_event_var_nums_array__"
|
|
;
|
|
ArrayName = user_event_layout_array,
|
|
Prefix = "mercury_data__user_event_layouts_array__"
|
|
;
|
|
ArrayName = proc_static_call_sites_array,
|
|
Prefix = "mercury_data__proc_call_sites_array__"
|
|
;
|
|
ArrayName = proc_static_cp_static_array,
|
|
Prefix = "mercury_data__proc_cp_statics_array__"
|
|
;
|
|
ArrayName = proc_static_cp_dynamic_array,
|
|
Prefix = "mercury_data__proc_cp_dynamics_array__"
|
|
;
|
|
ArrayName = proc_static_array,
|
|
Prefix = "mercury_data__proc_statics_array__"
|
|
;
|
|
ArrayName = proc_head_var_nums_array,
|
|
Prefix = "mercury_data__proc_head_var_nums_array__"
|
|
;
|
|
ArrayName = proc_var_names_array,
|
|
Prefix = "mercury_data__proc_var_names_array__"
|
|
;
|
|
ArrayName = proc_body_bytecodes_array,
|
|
Prefix = "mercury_data__proc_body_bytecodes_array__"
|
|
;
|
|
ArrayName = proc_table_io_entry_array,
|
|
Prefix = "mercury_data__proc_table_io_entries_array__"
|
|
;
|
|
ArrayName = proc_event_layouts_array,
|
|
Prefix = "mercury_data__proc_event_layouts_array__"
|
|
;
|
|
ArrayName = proc_exec_trace_array,
|
|
Prefix = "mercury_data__proc_exec_traces_array__"
|
|
;
|
|
ArrayName = threadscope_string_table_array,
|
|
Prefix = "mercury_data__threadscope_string_table_array__"
|
|
;
|
|
ArrayName = alloc_site_array,
|
|
Prefix = "mercury_data__alloc_sites_array__"
|
|
),
|
|
io.format(Stream, "%s%s", [s(Prefix), s(ModuleName)], !IO)
|
|
).
|
|
|
|
output_layout_slot_id(Stream, UseMacro, ModuleName, SlotName, !IO) :-
|
|
SlotName = layout_slot(ArrayName, SlotNum),
|
|
output_layout_array_name(Stream, UseMacro, ModuleName, ArrayName, !IO),
|
|
io.format(Stream, "[%d]", [i(SlotNum)], !IO).
|
|
|
|
output_layout_slot_addr(Stream, UseMacro, ModuleName, SlotName, !IO) :-
|
|
SlotName = layout_slot(ArrayName, SlotNum),
|
|
io.write_string(Stream, "&", !IO),
|
|
output_layout_array_name(Stream, UseMacro, ModuleName, ArrayName, !IO),
|
|
io.format(Stream, "[%d]", [i(SlotNum)], !IO).
|
|
|
|
output_layout_name(Stream, Name, !IO) :-
|
|
(
|
|
Name = proc_layout(RttiProcLabel, _),
|
|
ProcLabel = make_proc_label_from_rtti(RttiProcLabel),
|
|
ProcLabelStr = proc_label_to_c_string(add_label_prefix, ProcLabel),
|
|
% We can't omit the mercury_ prefix on ProcLabel, even though the
|
|
% mercury_data_prefix duplicates it, because there is no simple way
|
|
% to make the MR_init_entryl_sl macro delete that prefix from the
|
|
% entry label's name to get the name of its layout structure.
|
|
io.format(Stream, "%s_proc_layout__%s",
|
|
[s(mercury_data_prefix), s(ProcLabelStr)], !IO)
|
|
;
|
|
Name = closure_proc_id(CallerProcLabel, SeqNo, _),
|
|
CallerProcLabelStr =
|
|
proc_label_to_c_string(do_not_add_label_prefix, CallerProcLabel),
|
|
io.format(Stream, "%s_closure_layout__%s_%d",
|
|
[s(mercury_data_prefix), s(CallerProcLabelStr), i(SeqNo)], !IO)
|
|
;
|
|
Name = file_layout(ModuleName, FileNum),
|
|
ModuleNameStr = sym_name_mangle(ModuleName),
|
|
io.format(Stream, "%s_file_layout__%s_%d",
|
|
[s(mercury_data_prefix), s(ModuleNameStr), i(FileNum)], !IO)
|
|
;
|
|
Name = file_layout_line_number_vector(ModuleName, FileNum),
|
|
ModuleNameStr = sym_name_mangle(ModuleName),
|
|
io.format(Stream, "%s_file_lines__%s_%d",
|
|
[s(mercury_data_prefix), s(ModuleNameStr), i(FileNum)], !IO)
|
|
;
|
|
Name = file_layout_label_layout_vector(ModuleName, FileNum),
|
|
ModuleNameStr = sym_name_mangle(ModuleName),
|
|
io.format(Stream, "%s_file_label_layouts__%s_%d",
|
|
[s(mercury_data_prefix), s(ModuleNameStr), i(FileNum)], !IO)
|
|
;
|
|
Name = module_layout_string_table(ModuleName),
|
|
ModuleNameStr = sym_name_mangle(ModuleName),
|
|
io.format(Stream, "%s_module_strings__%s",
|
|
[s(mercury_data_prefix), s(ModuleNameStr)], !IO)
|
|
;
|
|
Name = module_layout_file_vector(ModuleName),
|
|
ModuleNameStr = sym_name_mangle(ModuleName),
|
|
io.format(Stream, "%s_module_files__%s",
|
|
[s(mercury_data_prefix), s(ModuleNameStr)], !IO)
|
|
;
|
|
Name = module_layout_proc_vector(ModuleName),
|
|
ModuleNameStr = sym_name_mangle(ModuleName),
|
|
io.format(Stream, "%s_module_procs__%s",
|
|
[s(mercury_data_prefix), s(ModuleNameStr)], !IO)
|
|
;
|
|
Name = module_layout_label_exec_count(ModuleName, _),
|
|
ModuleNameStr = sym_name_mangle(ModuleName),
|
|
io.format(Stream, "%s_module_label_exec_counts__%s",
|
|
[s(mercury_data_prefix), s(ModuleNameStr)], !IO)
|
|
;
|
|
Name = module_layout_event_set_desc(ModuleName),
|
|
ModuleNameStr = sym_name_mangle(ModuleName),
|
|
io.format(Stream, "%s_module_layout_event_set_desc__%s",
|
|
[s(mercury_data_prefix), s(ModuleNameStr)], !IO)
|
|
;
|
|
Name = module_layout_event_arg_names(ModuleName, EventNumber),
|
|
ModuleNameStr = sym_name_mangle(ModuleName),
|
|
io.format(Stream, "%s_module_layout_event_arg_names__%s_%d",
|
|
[s(mercury_data_prefix), s(ModuleNameStr), i(EventNumber)], !IO)
|
|
;
|
|
Name = module_layout_event_synth_attrs(ModuleName, EventNumber),
|
|
ModuleNameStr = sym_name_mangle(ModuleName),
|
|
io.format(Stream, "%s_module_layout_event_synth_attrs__%s_%d",
|
|
[s(mercury_data_prefix), s(ModuleNameStr), i(EventNumber)], !IO)
|
|
;
|
|
Name = module_layout_event_synth_attr_args(ModuleName,
|
|
EventNumber, SynthCallArgNumber),
|
|
ModuleNameStr = sym_name_mangle(ModuleName),
|
|
io.format(Stream, "%s_module_layout_event_synth_attr_args__%s_%d_%d",
|
|
[s(mercury_data_prefix), s(ModuleNameStr),
|
|
i(EventNumber), i(SynthCallArgNumber)], !IO)
|
|
;
|
|
Name = module_layout_event_synth_attr_order(ModuleName,
|
|
EventNumber, SynthCallArgNumber),
|
|
ModuleNameStr = sym_name_mangle(ModuleName),
|
|
io.format(Stream, "%s_module_layout_event_synth_attr_order__%s_%d_%d",
|
|
[s(mercury_data_prefix), s(ModuleNameStr),
|
|
i(EventNumber), i(SynthCallArgNumber)], !IO)
|
|
;
|
|
Name = module_layout_event_synth_order(ModuleName, EventNumber),
|
|
ModuleNameStr = sym_name_mangle(ModuleName),
|
|
io.format(Stream, "%s_module_layout_event_synth_order__%s_%d",
|
|
[s(mercury_data_prefix), s(ModuleNameStr), i(EventNumber)], !IO)
|
|
;
|
|
Name = module_layout_event_specs(ModuleName),
|
|
ModuleNameStr = sym_name_mangle(ModuleName),
|
|
io.format(Stream, "%s_module_layout_event_specs__%s",
|
|
[s(mercury_data_prefix), s(ModuleNameStr)], !IO)
|
|
;
|
|
Name = module_layout_oisu_bytes(ModuleName),
|
|
ModuleNameStr = sym_name_mangle(ModuleName),
|
|
io.format(Stream, "%s_module_layout_oisu_bytes__%s",
|
|
[s(mercury_data_prefix), s(ModuleNameStr)], !IO)
|
|
;
|
|
Name = module_layout_type_table_bytes(ModuleName),
|
|
ModuleNameStr = sym_name_mangle(ModuleName),
|
|
io.format(Stream, "%s_module_layout_type_table_bytes__%s",
|
|
[s(mercury_data_prefix), s(ModuleNameStr)], !IO)
|
|
;
|
|
Name = module_layout(ModuleName),
|
|
ModuleNameStr = sym_name_mangle(ModuleName),
|
|
io.format(Stream, "%s_module_layout__%s",
|
|
[s(mercury_data_prefix), s(ModuleNameStr)], !IO)
|
|
).
|
|
|
|
output_layout_name_storage_type_name(Stream, Name, BeingDefined, !IO) :-
|
|
(
|
|
Name = proc_layout(RttiProcLabel, Kind),
|
|
ProcIsImported = RttiProcLabel ^ rpl_proc_is_imported,
|
|
ProcIsExported = RttiProcLabel ^ rpl_proc_is_exported,
|
|
( if
|
|
ProcIsImported = no,
|
|
ProcIsExported = no
|
|
then
|
|
io.write_string(Stream, "static ", !IO)
|
|
else
|
|
(
|
|
BeingDefined = being_defined
|
|
;
|
|
BeingDefined = not_being_defined,
|
|
io.write_string(Stream, "extern ", !IO)
|
|
)
|
|
),
|
|
io.write_string(Stream, "const ", !IO),
|
|
io.write_string(Stream, proc_layout_kind_to_type(Kind), !IO),
|
|
io.write_string(Stream, " ", !IO),
|
|
output_layout_name(Stream, Name, !IO)
|
|
;
|
|
Name = closure_proc_id(_CallerProcLabel, _SeqNo, ClosureProcLabel),
|
|
io.write_string(Stream, "static const ", !IO),
|
|
(
|
|
ClosureProcLabel = ordinary_proc_label(_, _, _, _, _, _),
|
|
io.write_string(Stream, "MR_UserClosureId\n", !IO)
|
|
;
|
|
ClosureProcLabel = special_proc_label(_, _, _, _, _, _),
|
|
io.write_string(Stream, "MR_UCIClosureId\n", !IO)
|
|
),
|
|
output_layout_name(Stream, Name, !IO)
|
|
;
|
|
Name = file_layout(_ModuleName, _FileNum),
|
|
io.write_string(Stream, "static const MR_ModuleFileLayout ", !IO),
|
|
output_layout_name(Stream, Name, !IO)
|
|
;
|
|
Name = file_layout_line_number_vector(_ModuleName, _FileNum),
|
|
io.write_string(Stream, "static const MR_int_least16_t ", !IO),
|
|
output_layout_name(Stream, Name, !IO),
|
|
io.write_string(Stream, "[]", !IO)
|
|
;
|
|
Name = file_layout_label_layout_vector(_ModuleName, _FileNum),
|
|
io.write_string(Stream, "static const MR_LabelLayout *", !IO),
|
|
output_layout_name(Stream, Name, !IO),
|
|
io.write_string(Stream, "[]", !IO)
|
|
;
|
|
Name = module_layout_string_table(_ModuleName),
|
|
io.write_string(Stream, "static const char ", !IO),
|
|
output_layout_name(Stream, Name, !IO),
|
|
io.write_string(Stream, "[]", !IO)
|
|
;
|
|
Name = module_layout_file_vector(_ModuleName),
|
|
io.write_string(Stream, "static const MR_ModuleFileLayout *", !IO),
|
|
output_layout_name(Stream, Name, !IO),
|
|
io.write_string(Stream, "[]", !IO)
|
|
;
|
|
Name = module_layout_label_exec_count(_ModuleName, NumElements),
|
|
io.write_string(Stream, "static MR_Unsigned ", !IO),
|
|
output_layout_name(Stream, Name, !IO),
|
|
io.write_string(Stream, "[", !IO),
|
|
io.write_int(Stream, NumElements, !IO),
|
|
io.write_string(Stream, "]", !IO)
|
|
;
|
|
Name = module_layout_proc_vector(_ModuleName),
|
|
io.write_string(Stream, "static const MR_ProcLayout *", !IO),
|
|
output_layout_name(Stream, Name, !IO),
|
|
io.write_string(Stream, "[]", !IO)
|
|
;
|
|
Name = module_layout_event_set_desc(_ModuleName),
|
|
io.write_string(Stream, "static const char ", !IO),
|
|
output_layout_name(Stream, Name, !IO),
|
|
io.write_string(Stream, "[]", !IO)
|
|
;
|
|
Name = module_layout_event_arg_names(_ModuleName, _EventNumber),
|
|
io.write_string(Stream, "static const char * ", !IO),
|
|
output_layout_name(Stream, Name, !IO),
|
|
io.write_string(Stream, "[]", !IO)
|
|
;
|
|
Name = module_layout_event_synth_attrs(_ModuleName, _EventNumber),
|
|
io.write_string(Stream, "static MR_SynthAttr ", !IO),
|
|
output_layout_name(Stream, Name, !IO),
|
|
io.write_string(Stream, "[]", !IO)
|
|
;
|
|
Name = module_layout_event_synth_attr_args(_ModuleName,
|
|
_EventNumber, _SynthCallArgNumber),
|
|
io.write_string(Stream, "static MR_uint_least16_t ", !IO),
|
|
output_layout_name(Stream, Name, !IO),
|
|
io.write_string(Stream, "[]", !IO)
|
|
;
|
|
Name = module_layout_event_synth_attr_order(_ModuleName,
|
|
_EventNumber, _SynthCallArgNumber),
|
|
io.write_string(Stream, "static MR_int_least16_t ", !IO),
|
|
output_layout_name(Stream, Name, !IO),
|
|
io.write_string(Stream, "[]", !IO)
|
|
;
|
|
Name = module_layout_event_synth_order(_ModuleName, _EventNumber),
|
|
io.write_string(Stream, "static MR_int_least16_t ", !IO),
|
|
output_layout_name(Stream, Name, !IO),
|
|
io.write_string(Stream, "[]", !IO)
|
|
;
|
|
Name = module_layout_event_specs(_ModuleName),
|
|
io.write_string(Stream, "static MR_UserEventSpec ", !IO),
|
|
output_layout_name(Stream, Name, !IO),
|
|
io.write_string(Stream, "[]", !IO)
|
|
;
|
|
Name = module_layout_oisu_bytes(_ModuleName),
|
|
io.write_string(Stream, "static const MR_uint_least8_t ", !IO),
|
|
output_layout_name(Stream, Name, !IO),
|
|
io.write_string(Stream, "[]", !IO)
|
|
;
|
|
Name = module_layout_type_table_bytes(_ModuleName),
|
|
io.write_string(Stream, "static const MR_uint_least8_t ", !IO),
|
|
output_layout_name(Stream, Name, !IO),
|
|
io.write_string(Stream, "[]", !IO)
|
|
;
|
|
Name = module_layout(_ModuleName),
|
|
io.write_string(Stream, "static const MR_ModuleLayout ", !IO),
|
|
output_layout_name(Stream, Name, !IO)
|
|
).
|
|
|
|
output_layout_array_name_storage_type_name(Stream, ModuleName, Name,
|
|
BeingDefined, !IO) :-
|
|
(
|
|
BeingDefined = being_defined,
|
|
io.write_string(Stream, "static ", !IO)
|
|
;
|
|
% Avoid problems with MS Visual C.
|
|
% See the comments in llds_out_file.output_static_linkage_define/2
|
|
% for a further explanation.
|
|
BeingDefined = not_being_defined,
|
|
io.write_string(Stream, "MR_STATIC_LINKAGE ", !IO)
|
|
),
|
|
(
|
|
Name = label_layout_array(label_has_no_var_info),
|
|
io.write_string(Stream, "const MR_LabelLayoutNoVarInfo ", !IO),
|
|
output_layout_array_name(Stream, do_not_use_layout_macro, ModuleName,
|
|
Name, !IO)
|
|
;
|
|
Name = label_layout_array(label_has_short_var_info),
|
|
io.write_string(Stream, "const MR_LabelLayoutShort ", !IO),
|
|
output_layout_array_name(Stream, do_not_use_layout_macro, ModuleName,
|
|
Name, !IO)
|
|
;
|
|
Name = label_layout_array(label_has_long_var_info),
|
|
io.write_string(Stream, "const MR_LabelLayout ", !IO),
|
|
output_layout_array_name(Stream, do_not_use_layout_macro, ModuleName,
|
|
Name, !IO)
|
|
;
|
|
Name = pseudo_type_info_array,
|
|
io.write_string(Stream, "const MR_PseudoTypeInfo ", !IO),
|
|
output_layout_array_name(Stream, do_not_use_layout_macro, ModuleName,
|
|
Name, !IO)
|
|
;
|
|
Name = long_locns_array,
|
|
io.write_string(Stream, "const MR_LongLval ", !IO),
|
|
output_layout_array_name(Stream, do_not_use_layout_macro, ModuleName,
|
|
Name, !IO)
|
|
;
|
|
Name = short_locns_array,
|
|
io.write_string(Stream, "const MR_ShortLval ", !IO),
|
|
output_layout_array_name(Stream, do_not_use_layout_macro, ModuleName,
|
|
Name, !IO)
|
|
;
|
|
Name = hlds_var_nums_array,
|
|
io.write_string(Stream, "const MR_HLDSVarNum ", !IO),
|
|
output_layout_array_name(Stream, do_not_use_layout_macro, ModuleName,
|
|
Name, !IO)
|
|
;
|
|
Name = user_event_var_nums_array,
|
|
io.write_string(Stream, "const MR_HLDSVarNum ", !IO),
|
|
output_layout_array_name(Stream, do_not_use_layout_macro, ModuleName,
|
|
Name, !IO)
|
|
;
|
|
Name = user_event_layout_array,
|
|
io.write_string(Stream, "const struct MR_UserEvent_Struct ", !IO),
|
|
output_layout_array_name(Stream, do_not_use_layout_macro, ModuleName,
|
|
Name, !IO)
|
|
;
|
|
Name = proc_static_call_sites_array,
|
|
io.write_string(Stream, "const MR_CallSiteStatic ", !IO),
|
|
output_layout_array_name(Stream, do_not_use_layout_macro, ModuleName,
|
|
Name, !IO)
|
|
;
|
|
Name = proc_static_cp_static_array,
|
|
io.write_string(Stream, "const MR_CoveragePointStatic ", !IO),
|
|
output_layout_array_name(Stream, do_not_use_layout_macro, ModuleName,
|
|
Name, !IO)
|
|
;
|
|
Name = proc_static_cp_dynamic_array,
|
|
io.write_string(Stream, "MR_Unsigned ", !IO),
|
|
output_layout_array_name(Stream, do_not_use_layout_macro, ModuleName,
|
|
Name, !IO)
|
|
;
|
|
Name = proc_static_array,
|
|
io.write_string(Stream, "MR_ProcStatic ", !IO),
|
|
output_layout_array_name(Stream, do_not_use_layout_macro, ModuleName,
|
|
Name, !IO)
|
|
;
|
|
Name = proc_head_var_nums_array,
|
|
io.write_string(Stream, "const MR_uint_least16_t ", !IO),
|
|
output_layout_array_name(Stream, do_not_use_layout_macro, ModuleName,
|
|
Name, !IO)
|
|
;
|
|
Name = proc_var_names_array,
|
|
io.write_string(Stream, "const MR_uint_least32_t ", !IO),
|
|
output_layout_array_name(Stream, do_not_use_layout_macro, ModuleName,
|
|
Name, !IO)
|
|
;
|
|
Name = proc_body_bytecodes_array,
|
|
io.write_string(Stream, "const MR_uint_least8_t ", !IO),
|
|
output_layout_array_name(Stream, do_not_use_layout_macro, ModuleName,
|
|
Name, !IO)
|
|
;
|
|
Name = proc_table_io_entry_array,
|
|
io.write_string(Stream, "const MR_TableIoEntry ", !IO),
|
|
output_layout_array_name(Stream, do_not_use_layout_macro, ModuleName,
|
|
Name, !IO)
|
|
;
|
|
Name = proc_event_layouts_array,
|
|
io.write_string(Stream, "const MR_LabelLayout *", !IO),
|
|
output_layout_array_name(Stream, do_not_use_layout_macro, ModuleName,
|
|
Name, !IO)
|
|
;
|
|
Name = proc_exec_trace_array,
|
|
io.write_string(Stream, "MR_STATIC_CODE_CONST MR_ExecTrace ", !IO),
|
|
output_layout_array_name(Stream, do_not_use_layout_macro, ModuleName,
|
|
Name, !IO)
|
|
;
|
|
Name = threadscope_string_table_array,
|
|
io.write_string(Stream, "MR_Threadscope_String ", !IO),
|
|
output_layout_array_name(Stream, do_not_use_layout_macro, ModuleName,
|
|
Name, !IO)
|
|
;
|
|
Name = alloc_site_array,
|
|
% The type field may be updated at runtime so this array is not const.
|
|
io.write_string(Stream, "MR_AllocSiteInfo ", !IO),
|
|
output_layout_array_name(Stream, do_not_use_layout_macro, ModuleName,
|
|
Name, !IO)
|
|
).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% Output the rval in a context in which it is immediately cast to an
|
|
% address.
|
|
%
|
|
:- pred output_rval_as_addr(llds_out_info::in, io.text_output_stream::in,
|
|
rval::in, io::di, io::uo) is det.
|
|
|
|
output_rval_as_addr(Info, Stream, Rval, !IO) :-
|
|
( if Rval = const(llconst_int(0)) then
|
|
io.write_string(Stream, "0", !IO)
|
|
else if Rval = const(llconst_data_addr(DataId)) then
|
|
output_data_id_addr(Info, Stream, DataId, !IO)
|
|
else
|
|
io.write_string(Stream, "\n", !IO),
|
|
output_rval(Info, Rval, Stream, !IO)
|
|
).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
output_proc_layout_data_defn(Info, Stream, ProcLayoutData, !DeclSet, !IO) :-
|
|
ProcLayoutData = proc_layout_data(RttiProcLabel, Traversal, MaybeRest),
|
|
ProcLabel = make_proc_label_from_rtti(RttiProcLabel),
|
|
Traversal = proc_layout_stack_traversal(MaybeEntryLabel, MaybeSuccipSlot,
|
|
StackSlotCount, Detism),
|
|
|
|
% Output the declarations needed by this definition.
|
|
(
|
|
MaybeEntryLabel = yes(EntryLabelDecl),
|
|
output_record_code_addr_decls(Info, Stream, code_label(EntryLabelDecl),
|
|
!DeclSet, !IO)
|
|
;
|
|
MaybeEntryLabel = no
|
|
),
|
|
(
|
|
MaybeRest = no_proc_id_and_more,
|
|
Kind = proc_layout_traversal
|
|
;
|
|
MaybeRest = proc_id_and_more(_, _, _, ModuleLayoutDecl),
|
|
Kind = proc_layout_proc_id(proc_label_user_or_uci(ProcLabel)),
|
|
output_layout_decl(Stream, ModuleLayoutDecl, !DeclSet, !IO)
|
|
),
|
|
|
|
io.write_string(Stream, "\n", !IO),
|
|
ProcLayoutName = proc_layout(RttiProcLabel, Kind),
|
|
output_layout_name_storage_type_name(Stream, ProcLayoutName,
|
|
being_defined, !IO),
|
|
io.write_string(Stream, " = {\n", !IO),
|
|
|
|
% Write out the traversal structure.
|
|
io.write_string(Stream, "{\n", !IO),
|
|
(
|
|
MaybeEntryLabel = yes(EntryLabel),
|
|
output_code_addr(Stream, code_label(EntryLabel), !IO)
|
|
;
|
|
MaybeEntryLabel = no,
|
|
% The actual code address will be put into the structure
|
|
% by module initialization code.
|
|
io.write_string(Stream, "NULL", !IO)
|
|
),
|
|
io.write_string(Stream, ", ", !IO),
|
|
(
|
|
MaybeSuccipSlot = yes(SuccipSlot),
|
|
io.write_int(Stream, SuccipSlot, !IO)
|
|
;
|
|
MaybeSuccipSlot = no,
|
|
io.write_int(Stream, -1, !IO)
|
|
),
|
|
io.write_string(Stream, ",\n", !IO),
|
|
io.write_int(Stream, StackSlotCount, !IO),
|
|
io.write_string(Stream, ",\n", !IO),
|
|
io.write_string(Stream, detism_to_c_detism(Detism), !IO),
|
|
io.write_string(Stream, "\n},\n", !IO),
|
|
|
|
(
|
|
MaybeRest = no_proc_id_and_more,
|
|
io.write_string(Stream, "-1\n", !IO)
|
|
;
|
|
MaybeRest = proc_id_and_more(MaybeProcStatic, MaybeExecTrace,
|
|
MaybeProcBodyBytes, ModuleLayout),
|
|
|
|
% Output the proc_id structure.
|
|
io.write_string(Stream, "{\n", !IO),
|
|
Origin = RttiProcLabel ^ rpl_pred_info_origin,
|
|
output_proc_id(Stream, ProcLabel, Origin, !IO),
|
|
io.write_string(Stream, "},\n", !IO),
|
|
|
|
MangledModuleName = Info ^ lout_mangled_module_name,
|
|
(
|
|
MaybeExecTrace = no,
|
|
io.write_string(Stream, "NULL,\n", !IO)
|
|
;
|
|
MaybeExecTrace = yes(ExecTraceSlotName),
|
|
output_layout_slot_addr(Stream, use_layout_macro,
|
|
MangledModuleName, ExecTraceSlotName, !IO),
|
|
io.write_string(Stream, ",\n", !IO)
|
|
),
|
|
(
|
|
MaybeProcStatic = no,
|
|
io.write_string(Stream, "NULL,\n", !IO)
|
|
;
|
|
MaybeProcStatic = yes(ProcStaticSlotName),
|
|
output_layout_slot_addr(Stream, use_layout_macro,
|
|
MangledModuleName, ProcStaticSlotName, !IO),
|
|
io.write_string(Stream, ",\n", !IO)
|
|
),
|
|
(
|
|
MaybeProcBodyBytes = no,
|
|
io.write_string(Stream, "NULL,\n", !IO)
|
|
;
|
|
MaybeProcBodyBytes = yes(ProcBodyBytesSlotName),
|
|
output_layout_slot_addr(Stream, use_layout_macro,
|
|
MangledModuleName, ProcBodyBytesSlotName, !IO),
|
|
io.write_string(Stream, ",\n", !IO)
|
|
),
|
|
io.write_string(Stream, "&", !IO),
|
|
output_layout_name(Stream, ModuleLayout, !IO)
|
|
),
|
|
io.write_string(Stream, "\n};\n", !IO),
|
|
DeclId = decl_layout_id(ProcLayoutName),
|
|
decl_set_insert(DeclId, !DeclSet).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% The job of this predicate is to minimize stack space consumption in
|
|
% grades that do not allow output_bytecodes to be tail recursive.
|
|
%
|
|
:- pred output_bytecodes_driver(io.text_output_stream::in, list(int)::in,
|
|
io::di, io::uo) is det.
|
|
|
|
output_bytecodes_driver(Stream, Bytes, !IO) :-
|
|
(
|
|
Bytes = []
|
|
;
|
|
Bytes = [_ | _],
|
|
output_bytecodes(Stream, Bytes, BytesLeft, 0, 256, !IO),
|
|
output_bytecodes_driver(Stream, BytesLeft, !IO)
|
|
).
|
|
|
|
:- pred output_bytecodes(io.text_output_stream::in,
|
|
list(int)::in, list(int)::out, int::in, int::in, io::di, io::uo) is det.
|
|
|
|
output_bytecodes(Stream, Bytes, BytesLeft, !.Seq, MaxSeq, !IO) :-
|
|
(
|
|
Bytes = [],
|
|
BytesLeft = []
|
|
;
|
|
Bytes = [Head | Tail],
|
|
( if !.Seq < MaxSeq then
|
|
io.write_int(Stream, Head, !IO),
|
|
io.write_char(Stream, ',', !IO),
|
|
!:Seq = !.Seq + 1,
|
|
( if unchecked_rem(!.Seq, 16) = 0 then
|
|
io.write_char(Stream, '\n', !IO)
|
|
else
|
|
true
|
|
),
|
|
output_bytecodes(Stream, Tail, BytesLeft, !.Seq, MaxSeq, !IO)
|
|
else
|
|
BytesLeft = Bytes
|
|
)
|
|
).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
output_closure_layout_data_defn(_Info, Stream, ClosureData, !DeclSet, !IO) :-
|
|
ClosureData = closure_proc_id_data(CallerProcLabel, SeqNo,
|
|
ClosureProcLabel, ModuleName, FileName, LineNumber, PredOrigin,
|
|
GoalPath),
|
|
io.write_string(Stream, "\n", !IO),
|
|
LayoutName = closure_proc_id(CallerProcLabel, SeqNo, ClosureProcLabel),
|
|
output_layout_name_storage_type_name(Stream, LayoutName,
|
|
being_defined, !IO),
|
|
io.write_string(Stream, " = {\n{\n", !IO),
|
|
output_proc_id(Stream, ClosureProcLabel, PredOrigin, !IO),
|
|
io.write_string(Stream, "},\n", !IO),
|
|
output_quoted_string_c(Stream, sym_name_to_string(ModuleName), !IO),
|
|
io.write_string(Stream, ",\n", !IO),
|
|
output_quoted_string_c(Stream, FileName, !IO),
|
|
io.write_string(Stream, ",\n", !IO),
|
|
io.write_int(Stream, LineNumber, !IO),
|
|
io.write_string(Stream, ",\n", !IO),
|
|
output_quoted_string_c(Stream, GoalPath, !IO),
|
|
io.write_string(Stream, "\n};\n", !IO),
|
|
decl_set_insert(decl_layout_id(LayoutName), !DeclSet).
|
|
|
|
:- pred output_proc_id(io.text_output_stream::in,
|
|
proc_label::in, pred_origin::in, io::di, io::uo) is det.
|
|
|
|
output_proc_id(Stream, ProcLabel, Origin, !IO) :-
|
|
(
|
|
ProcLabel = ordinary_proc_label(DefiningModule, PredOrFunc,
|
|
DeclaringModule, PredName0, Arity, ModeNum),
|
|
PredName = layout_origin_name(Origin, PredName0),
|
|
io.write_string(Stream, mr_pred_or_func_to_string(PredOrFunc), !IO),
|
|
io.write_string(Stream, ",\n", !IO),
|
|
output_quoted_string_c(Stream,
|
|
sym_name_to_string(DeclaringModule), !IO),
|
|
io.write_string(Stream, ",\n", !IO),
|
|
output_quoted_string_c(Stream,
|
|
sym_name_to_string(DefiningModule), !IO),
|
|
io.write_string(Stream, ",\n", !IO),
|
|
output_quoted_string_c(Stream, PredName, !IO),
|
|
io.write_string(Stream, ",\n", !IO),
|
|
io.write_int(Stream, Arity, !IO),
|
|
io.write_string(Stream, ",\n", !IO),
|
|
io.write_int(Stream, ModeNum, !IO),
|
|
io.write_string(Stream, "\n", !IO)
|
|
;
|
|
ProcLabel = special_proc_label(DefiningModule, SpecialPredId,
|
|
TypeModule, TypeName, TypeArity, ModeNum),
|
|
TypeCtor = type_ctor(qualified(TypeModule, TypeName), TypeArity),
|
|
PredName0 = uci_pred_name(SpecialPredId, TypeCtor),
|
|
PredName = layout_origin_name(Origin, PredName0),
|
|
output_quoted_string_c(Stream, TypeName, !IO),
|
|
io.write_string(Stream, ",\n", !IO),
|
|
output_quoted_string_c(Stream, sym_name_to_string(TypeModule), !IO),
|
|
io.write_string(Stream, ",\n", !IO),
|
|
output_quoted_string_c(Stream,
|
|
sym_name_to_string(DefiningModule), !IO),
|
|
io.write_string(Stream, ",\n", !IO),
|
|
output_quoted_string_c(Stream, PredName, !IO),
|
|
io.write_string(Stream, ",\n", !IO),
|
|
io.write_int(Stream, TypeArity, !IO),
|
|
io.write_string(Stream, ",\n", !IO),
|
|
io.write_int(Stream, ModeNum, !IO),
|
|
io.write_string(Stream, "\n", !IO)
|
|
).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% The version of the layout data structures -- useful for bootstrapping.
|
|
% If you write runtime code that checks this version number and can
|
|
% at least handle the previous version of the data structure,
|
|
% it makes it easier to bootstrap changes to these data structures.
|
|
%
|
|
% This number should be kept in sync with MR_LAYOUT_VERSION in
|
|
% runtime/mercury_stack_layout.h. This means you need to update
|
|
% the code in the runtime (including the trace directory) that uses
|
|
% layout structures to conform to whatever changes the new version
|
|
% introduces.
|
|
%
|
|
:- func layout_version_number = int.
|
|
|
|
layout_version_number = 5.
|
|
|
|
output_module_layout_data_defn(Info, Stream, Data, !DeclSet, !IO) :-
|
|
Data = module_layout_data(ModuleName, StringTableSize, StringTable,
|
|
MaybeDeepProfData, MaybeDebugData),
|
|
output_module_string_table(Stream, ModuleName,
|
|
StringTableSize, StringTable, !DeclSet, !IO),
|
|
(
|
|
MaybeDeepProfData = yes(DeepProfData),
|
|
DeepProfData = module_layout_deep_prof(NumOISUTypesA, OISUBytes,
|
|
NumTypesA, TypeTableBytes),
|
|
( if NumOISUTypesA = 0 then
|
|
MaybeOISUBytesLayoutNameA = no
|
|
else
|
|
OISUBytesLayoutNameA = module_layout_oisu_bytes(ModuleName),
|
|
io.write_string(Stream, "\n", !IO),
|
|
output_layout_name_storage_type_name(Stream, OISUBytesLayoutNameA,
|
|
being_defined, !IO),
|
|
io.write_string(Stream, " = {", !IO),
|
|
output_bytecodes_driver(Stream, OISUBytes, !IO),
|
|
io.write_string(Stream, "};\n", !IO),
|
|
decl_set_insert(decl_layout_id(OISUBytesLayoutNameA), !DeclSet),
|
|
MaybeOISUBytesLayoutNameA = yes(OISUBytesLayoutNameA)
|
|
),
|
|
(
|
|
TypeTableBytes = [],
|
|
MaybeTypeTableLayoutNameA = no
|
|
;
|
|
TypeTableBytes = [_ | _],
|
|
TypeTableLayoutNameA = module_layout_type_table_bytes(ModuleName),
|
|
io.write_string(Stream, "\n", !IO),
|
|
output_layout_name_storage_type_name(Stream, TypeTableLayoutNameA,
|
|
being_defined, !IO),
|
|
io.write_string(Stream, " = {", !IO),
|
|
output_bytecodes_driver(Stream, TypeTableBytes, !IO),
|
|
io.write_string(Stream, "};\n", !IO),
|
|
decl_set_insert(decl_layout_id(TypeTableLayoutNameA), !DeclSet),
|
|
MaybeTypeTableLayoutNameA = yes(TypeTableLayoutNameA)
|
|
),
|
|
OISUInfo = {NumOISUTypesA, MaybeOISUBytesLayoutNameA,
|
|
NumTypesA, MaybeTypeTableLayoutNameA}
|
|
;
|
|
MaybeDeepProfData = no,
|
|
OISUInfo = {0, no, 0, no}
|
|
),
|
|
|
|
(
|
|
MaybeDebugData = yes(DebugData),
|
|
DebugData = module_layout_debug(ProcLayoutNames, FileLayouts,
|
|
TraceLevelA, SuppressedEventsA, NumLabelsA, MaybeEventSetA),
|
|
|
|
output_module_layout_proc_vector_defn(Stream, ModuleName,
|
|
ProcLayoutNames, ProcLayoutVectorNameA, !DeclSet, !IO),
|
|
list.length(ProcLayoutNames, ProcLayoutVectorLengthA),
|
|
output_file_layout_data_defns(Info, Stream, ModuleName,
|
|
0, FileLayouts, FileLayoutNames, !DeclSet, !IO),
|
|
list.length(FileLayouts, FileLayoutVectorLengthA),
|
|
output_file_layout_vector_data_defn(Stream, ModuleName,
|
|
FileLayoutNames, FileLayoutVectorNameA, !DeclSet, !IO),
|
|
|
|
io.write_string(Stream, "\n", !IO),
|
|
LabelExecCountNameA = module_layout_label_exec_count(ModuleName,
|
|
NumLabelsA),
|
|
output_layout_name_storage_type_name(Stream, LabelExecCountNameA,
|
|
being_defined, !IO),
|
|
io.write_string(Stream, ";\n", !IO),
|
|
decl_set_insert(decl_layout_id(LabelExecCountNameA), !DeclSet),
|
|
|
|
(
|
|
MaybeEventSetA = no,
|
|
MaybeEventInfoA = no
|
|
;
|
|
MaybeEventSetA = yes(EventSetDataLayout),
|
|
EventSetDataLayout =
|
|
event_set_layout_data(EventSetDataA, TypesRvalMap),
|
|
EventSetDataA = event_set_data(EventSetNameA, EventSetDesc,
|
|
EventSpecs, MaxNumAttrA),
|
|
output_event_set_desc_defn(Stream, ModuleName, EventSetDesc,
|
|
EventSetDescLayoutNameA, !DeclSet, !IO),
|
|
output_event_specs_and_components(Info, Stream,
|
|
EventSpecs, ModuleName, TypesRvalMap, EventSpecsLayoutNameA,
|
|
!DeclSet, !IO),
|
|
list.length(EventSpecs, NumEventSpecsA),
|
|
MaybeEventInfoA = yes({EventSetNameA, MaxNumAttrA, NumEventSpecsA,
|
|
EventSetDescLayoutNameA, EventSpecsLayoutNameA})
|
|
),
|
|
|
|
MaybeDebugInfo = yes({ProcLayoutVectorLengthA, ProcLayoutVectorNameA,
|
|
FileLayoutVectorLengthA, FileLayoutVectorNameA,
|
|
TraceLevelA, SuppressedEventsA, NumLabelsA, LabelExecCountNameA,
|
|
MaybeEventInfoA})
|
|
;
|
|
MaybeDebugData = no,
|
|
MaybeDebugInfo = no
|
|
),
|
|
|
|
ModuleLayoutName = module_layout(ModuleName),
|
|
io.write_string(Stream, "\n", !IO),
|
|
output_layout_name_storage_type_name(Stream, ModuleLayoutName,
|
|
being_defined, !IO),
|
|
io.write_string(Stream, " = {\n", !IO),
|
|
io.write_int(Stream, layout_version_number, !IO),
|
|
io.write_string(Stream, ",\n", !IO),
|
|
output_quoted_string_c(Stream, sym_name_to_string(ModuleName), !IO),
|
|
io.write_string(Stream, ",\n", !IO),
|
|
io.write_int(Stream, StringTableSize, !IO),
|
|
io.write_string(Stream, ",\n", !IO),
|
|
ModuleStringTableName = module_layout_string_table(ModuleName),
|
|
output_layout_name(Stream, ModuleStringTableName, !IO),
|
|
io.write_string(Stream, ",\n", !IO),
|
|
|
|
OISUInfo = {NumOISUTypesB, MaybeOISUBytesLayoutNameB,
|
|
NumTypesB, MaybeTypeTableLayoutNameB},
|
|
io.write_int(Stream, NumOISUTypesB, !IO),
|
|
io.write_string(Stream, ",\n", !IO),
|
|
(
|
|
MaybeOISUBytesLayoutNameB = yes(OISUBytesLayoutNameB),
|
|
output_layout_name(Stream, OISUBytesLayoutNameB, !IO),
|
|
io.write_string(Stream, ",\n", !IO)
|
|
;
|
|
MaybeOISUBytesLayoutNameB = no,
|
|
io.write_string(Stream, "NULL,\n", !IO)
|
|
),
|
|
io.write_int(Stream, NumTypesB, !IO),
|
|
io.write_string(Stream, ",\n", !IO),
|
|
(
|
|
MaybeTypeTableLayoutNameB = yes(TypeTableLayoutNameB),
|
|
output_layout_name(Stream, TypeTableLayoutNameB, !IO),
|
|
io.write_string(Stream, ",\n", !IO)
|
|
;
|
|
MaybeTypeTableLayoutNameB = no,
|
|
io.write_string(Stream, "NULL,\n", !IO)
|
|
),
|
|
|
|
(
|
|
MaybeDebugInfo = yes({ProcLayoutVectorLengthB, ProcLayoutVectorNameB,
|
|
FileLayoutVectorLengthB, FileLayoutVectorNameB,
|
|
TraceLevelB, SuppressedEventsB, NumLabelsB, LabelExecCountNameB,
|
|
MaybeEventInfoB}),
|
|
|
|
io.write_int(Stream, ProcLayoutVectorLengthB, !IO),
|
|
io.write_string(Stream, ",\n", !IO),
|
|
output_layout_name(Stream, ProcLayoutVectorNameB, !IO),
|
|
io.write_string(Stream, ",\n", !IO),
|
|
io.write_int(Stream, FileLayoutVectorLengthB, !IO),
|
|
io.write_string(Stream, ",\n", !IO),
|
|
output_layout_name(Stream, FileLayoutVectorNameB, !IO),
|
|
io.write_string(Stream, ",\n", !IO),
|
|
io.write_string(Stream, trace_level_rep(TraceLevelB), !IO),
|
|
io.write_string(Stream, ",\n", !IO),
|
|
io.write_int(Stream, SuppressedEventsB, !IO),
|
|
io.write_string(Stream, ",\n", !IO),
|
|
io.write_int(Stream, NumLabelsB, !IO),
|
|
io.write_string(Stream, ",\n", !IO),
|
|
output_layout_name(Stream, LabelExecCountNameB, !IO),
|
|
io.write_string(Stream, ",\n", !IO),
|
|
|
|
(
|
|
MaybeEventInfoB = no,
|
|
io.write_string(Stream, "NULL,\n", !IO),
|
|
io.write_string(Stream, "NULL,\n", !IO),
|
|
io.write_string(Stream, "0,\n", !IO),
|
|
io.write_string(Stream, "0,\n", !IO),
|
|
io.write_string(Stream, "NULL\n", !IO)
|
|
;
|
|
MaybeEventInfoB = yes({EventSetNameB, MaxNumAttrB, NumEventSpecsB,
|
|
EventSetDescLayoutNameB, EventSpecsLayoutNameB}),
|
|
output_quoted_string_c(Stream, EventSetNameB, !IO),
|
|
io.write_string(Stream, ",\n", !IO),
|
|
output_layout_name(Stream, EventSetDescLayoutNameB, !IO),
|
|
io.write_string(Stream, ",\n", !IO),
|
|
io.write_int(Stream, MaxNumAttrB, !IO),
|
|
io.write_string(Stream, ",\n", !IO),
|
|
io.write_int(Stream, NumEventSpecsB, !IO),
|
|
io.write_string(Stream, ",\n", !IO),
|
|
output_layout_name(Stream, EventSpecsLayoutNameB, !IO),
|
|
io.write_string(Stream, "\n", !IO)
|
|
)
|
|
;
|
|
MaybeDebugInfo = no,
|
|
|
|
io.write_string(Stream, "0,\n", !IO),
|
|
io.write_string(Stream, "NULL,\n", !IO),
|
|
io.write_string(Stream, "0,\n", !IO),
|
|
io.write_string(Stream, "NULL,\n", !IO),
|
|
io.write_string(Stream, "MR_TRACE_LEVEL_NONE,\n", !IO),
|
|
io.write_string(Stream, "0,\n", !IO),
|
|
io.write_string(Stream, "0,\n", !IO),
|
|
io.write_string(Stream, "NULL,\n", !IO),
|
|
|
|
io.write_string(Stream, "NULL,\n", !IO),
|
|
io.write_string(Stream, "NULL,\n", !IO),
|
|
io.write_string(Stream, "0,\n", !IO),
|
|
io.write_string(Stream, "0,\n", !IO),
|
|
io.write_string(Stream, "NULL\n", !IO)
|
|
),
|
|
|
|
io.write_string(Stream, "};\n", !IO),
|
|
decl_set_insert(decl_layout_id(ModuleLayoutName), !DeclSet).
|
|
|
|
:- pred output_event_specs_and_components(llds_out_info::in,
|
|
io.text_output_stream::in, list(event_spec)::in, module_name::in,
|
|
map(int, rval)::in, layout_name::out,
|
|
decl_set::in, decl_set::out, io::di, io::uo) is det.
|
|
|
|
output_event_specs_and_components(Info, Stream, EventSpecs, ModuleName,
|
|
TypesRvalMap, LayoutName, !DeclSet, !IO) :-
|
|
list.foldl2(output_event_spec_components(Stream, ModuleName), EventSpecs,
|
|
!DeclSet, !IO),
|
|
|
|
LayoutName = module_layout_event_specs(ModuleName),
|
|
decl_set_insert(decl_layout_id(LayoutName), !DeclSet),
|
|
output_layout_name_storage_type_name(Stream, LayoutName,
|
|
being_defined, !IO),
|
|
io.write_string(Stream, " = {\n", !IO),
|
|
write_out_list(output_event_spec(Info, ModuleName, TypesRvalMap),
|
|
",\n", EventSpecs, Stream, !IO),
|
|
io.write_string(Stream, "\n};\n\n", !IO).
|
|
|
|
:- pred output_event_spec_components(io.text_output_stream::in,
|
|
module_name::in, event_spec::in,
|
|
decl_set::in, decl_set::out, io::di, io::uo) is det.
|
|
|
|
output_event_spec_components(Stream, ModuleName, EventSpec, !DeclSet, !IO) :-
|
|
EventSpec = event_spec(EventNumber, _EventName, _EventLineNumber,
|
|
Attrs, SynthOrder),
|
|
|
|
AttrNamesLayoutName =
|
|
module_layout_event_arg_names(ModuleName, EventNumber),
|
|
decl_set_insert(decl_layout_id(AttrNamesLayoutName), !DeclSet),
|
|
output_layout_name_storage_type_name(Stream, AttrNamesLayoutName,
|
|
being_defined, !IO),
|
|
io.write_string(Stream, " = {\n", !IO),
|
|
write_out_list(output_attr_name, ", ", Attrs, Stream, !IO),
|
|
io.write_string(Stream, "\n};\n\n", !IO),
|
|
|
|
(
|
|
SynthOrder = []
|
|
;
|
|
SynthOrder = [_ | _],
|
|
|
|
list.foldl2(output_synth_attr_args(Stream, ModuleName, EventNumber),
|
|
Attrs, !DeclSet, !IO),
|
|
|
|
SynthAttrsLayoutName =
|
|
module_layout_event_synth_attrs(ModuleName, EventNumber),
|
|
decl_set_insert(decl_layout_id(SynthAttrsLayoutName), !DeclSet),
|
|
output_layout_name_storage_type_name(Stream, SynthAttrsLayoutName,
|
|
being_defined, !IO),
|
|
io.write_string(Stream, " = {\n", !IO),
|
|
write_out_list(output_synth_attr(ModuleName, EventNumber),
|
|
",\n", Attrs, Stream, !IO),
|
|
io.write_string(Stream, "\n};\n\n", !IO),
|
|
|
|
SynthOrderLayoutName =
|
|
module_layout_event_synth_order(ModuleName, EventNumber),
|
|
decl_set_insert(decl_layout_id(SynthOrderLayoutName), !DeclSet),
|
|
output_layout_name_storage_type_name(Stream, SynthOrderLayoutName,
|
|
being_defined, !IO),
|
|
io.write_string(Stream, " = {\n", !IO),
|
|
% The -1 acts as sentinel.
|
|
write_out_list(add_int, ", ", SynthOrder ++ [-1], Stream, !IO),
|
|
io.write_string(Stream, "\n};\n\n", !IO)
|
|
).
|
|
|
|
:- pred output_attr_name(event_attribute::in, io.text_output_stream::in,
|
|
io::di, io::uo) is det.
|
|
|
|
output_attr_name(Attr, Stream, !IO) :-
|
|
io.write_string(Stream, """", !IO),
|
|
io.write_string(Stream, Attr ^ attr_name, !IO),
|
|
io.write_string(Stream, """", !IO).
|
|
|
|
:- pred output_synth_attr_args(io.text_output_stream::in, module_name::in,
|
|
int::in, event_attribute::in,
|
|
decl_set::in, decl_set::out, io::di, io::uo) is det.
|
|
|
|
output_synth_attr_args(Stream, ModuleName, EventNumber, Attr, !DeclSet, !IO) :-
|
|
MaybeSynthCall = Attr ^ attr_maybe_synth_call,
|
|
(
|
|
MaybeSynthCall = yes(SynthCall),
|
|
SynthCall = event_attr_synth_call(_FuncAttrNameNum, ArgAttrNameNums,
|
|
Order),
|
|
assoc_list.values(ArgAttrNameNums, ArgAttrNums),
|
|
AttrNumber = Attr ^ attr_num,
|
|
|
|
ArgsLayoutName = module_layout_event_synth_attr_args(ModuleName,
|
|
EventNumber, AttrNumber),
|
|
decl_set_insert(decl_layout_id(ArgsLayoutName), !DeclSet),
|
|
output_layout_name_storage_type_name(Stream, ArgsLayoutName,
|
|
being_defined, !IO),
|
|
io.write_string(Stream, " =\n{ ", !IO),
|
|
write_out_list(add_int, ", ", ArgAttrNums, Stream, !IO),
|
|
io.write_string(Stream, " };\n\n", !IO),
|
|
|
|
OrderLayoutName = module_layout_event_synth_attr_order(ModuleName,
|
|
EventNumber, AttrNumber),
|
|
decl_set_insert(decl_layout_id(OrderLayoutName), !DeclSet),
|
|
output_layout_name_storage_type_name(Stream, OrderLayoutName,
|
|
being_defined, !IO),
|
|
io.write_string(Stream, " =\n{ ", !IO),
|
|
OrderSentinel = Order ++ [-1],
|
|
write_out_list(add_int, ", ", OrderSentinel, Stream, !IO),
|
|
io.write_string(Stream, " };\n\n", !IO)
|
|
;
|
|
MaybeSynthCall = no
|
|
).
|
|
|
|
:- pred output_synth_attr(module_name::in, int::in, event_attribute::in,
|
|
io.text_output_stream::in, io::di, io::uo) is det.
|
|
|
|
output_synth_attr(ModuleName, EventNumber, Attr, Stream, !IO) :-
|
|
io.write_string(Stream, "{ ", !IO),
|
|
MaybeSynthCall = Attr ^ attr_maybe_synth_call,
|
|
(
|
|
MaybeSynthCall = yes(SynthCall),
|
|
SynthCall = event_attr_synth_call(_FuncAttrName - FuncAttrNum,
|
|
ArgAttrNameNums, _EvalOrder),
|
|
io.write_int(Stream, FuncAttrNum, !IO),
|
|
io.write_string(Stream, ", ", !IO),
|
|
io.write_int(Stream, list.length(ArgAttrNameNums), !IO),
|
|
io.write_string(Stream, ",\n ", !IO),
|
|
|
|
AttrNumber = Attr ^ attr_num,
|
|
ArgsLayoutName = module_layout_event_synth_attr_args(ModuleName,
|
|
EventNumber, AttrNumber),
|
|
output_layout_name(Stream, ArgsLayoutName, !IO),
|
|
io.write_string(Stream, ",\n ", !IO),
|
|
OrderLayoutName = module_layout_event_synth_attr_order(ModuleName,
|
|
EventNumber, AttrNumber),
|
|
output_layout_name(Stream, OrderLayoutName, !IO)
|
|
;
|
|
MaybeSynthCall = no,
|
|
io.write_string(Stream, "-1, -1, NULL, NULL", !IO)
|
|
),
|
|
io.write_string(Stream, " }", !IO).
|
|
|
|
:- pred output_event_spec(llds_out_info::in,
|
|
module_name::in, map(int, rval)::in, event_spec::in,
|
|
io.text_output_stream::in, io::di, io::uo) is det.
|
|
|
|
output_event_spec(Info, ModuleName, TypesRvalMap, EventSpec, Stream, !IO) :-
|
|
EventSpec = event_spec(EventNumber, EventName, _EventLineNumber, Attrs,
|
|
SynthOrder),
|
|
map.lookup(TypesRvalMap, EventNumber, TypesRval),
|
|
|
|
io.write_string(Stream, "{ """, !IO),
|
|
io.write_string(Stream, EventName, !IO),
|
|
io.write_string(Stream, """, ", !IO),
|
|
io.write_int(Stream, list.length(Attrs), !IO),
|
|
io.write_string(Stream, ",\n\t", !IO),
|
|
|
|
AttrNamesLayoutName =
|
|
module_layout_event_arg_names(ModuleName, EventNumber),
|
|
output_layout_name(Stream, AttrNamesLayoutName, !IO),
|
|
io.write_string(Stream, ",\n\t(MR_TypeInfo *) ", !IO),
|
|
output_rval_as_addr(Info, Stream, TypesRval, !IO),
|
|
io.write_string(Stream, ",\n\t", !IO),
|
|
|
|
(
|
|
SynthOrder = [],
|
|
io.write_string(Stream, "NULL, NULL }", !IO)
|
|
;
|
|
SynthOrder = [_ | _],
|
|
SynthAttrsLayoutName =
|
|
module_layout_event_synth_attrs(ModuleName, EventNumber),
|
|
SynthOrderLayoutName =
|
|
module_layout_event_synth_order(ModuleName, EventNumber),
|
|
output_layout_name(Stream, SynthAttrsLayoutName, !IO),
|
|
io.write_string(Stream, ",\n\t", !IO),
|
|
output_layout_name(Stream, SynthOrderLayoutName, !IO),
|
|
io.write_string(Stream, " }", !IO)
|
|
).
|
|
|
|
:- pred output_module_layout_proc_vector_defn(io.text_output_stream::in,
|
|
module_name::in, list(layout_name)::in, layout_name::out,
|
|
decl_set::in, decl_set::out, io::di, io::uo) is det.
|
|
|
|
output_module_layout_proc_vector_defn(Stream, ModuleName, ProcLayoutNames,
|
|
VectorName, !DeclSet, !IO) :-
|
|
list.foldl2(output_layout_decl(Stream), ProcLayoutNames, !DeclSet, !IO),
|
|
VectorName = module_layout_proc_vector(ModuleName),
|
|
io.write_string(Stream, "\n", !IO),
|
|
output_layout_name_storage_type_name(Stream, VectorName,
|
|
being_defined, !IO),
|
|
io.write_string(Stream, " = {\n", !IO),
|
|
(
|
|
ProcLayoutNames = [],
|
|
% ANSI/ISO C doesn't allow empty arrays, so place a dummy value
|
|
% in the array.
|
|
io.write_string(Stream, "NULL\n", !IO)
|
|
;
|
|
ProcLayoutNames = [_ | _],
|
|
list.foldl(output_proc_layout_name_in_vector(Stream),
|
|
ProcLayoutNames, !IO)
|
|
),
|
|
io.write_string(Stream, "};\n", !IO),
|
|
decl_set_insert(decl_layout_id(VectorName), !DeclSet).
|
|
|
|
:- pred output_proc_layout_name_in_vector(io.text_output_stream::in,
|
|
layout_name::in, io::di, io::uo) is det.
|
|
|
|
output_proc_layout_name_in_vector(Stream, LayoutName, !IO) :-
|
|
( if LayoutName = proc_layout(RttiProcLabel, _) then
|
|
ProcLabel = make_proc_label_from_rtti(RttiProcLabel),
|
|
io.write_string(Stream, "MR_PROC_LAYOUT1(", !IO),
|
|
io.write_string(Stream,
|
|
proc_label_to_c_string(do_not_add_label_prefix, ProcLabel), !IO),
|
|
io.write_string(Stream, ")\n", !IO)
|
|
else
|
|
unexpected($pred, "not proc layout")
|
|
).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- pred output_event_set_desc_defn(io.text_output_stream::in, module_name::in,
|
|
string::in, layout_name::out,
|
|
decl_set::in, decl_set::out, io::di, io::uo) is det.
|
|
|
|
output_event_set_desc_defn(Stream, ModuleName, EventSetDesc, LayoutName,
|
|
!DeclSet, !IO) :-
|
|
LayoutName = module_layout_event_set_desc(ModuleName),
|
|
io.write_string(Stream, "\n", !IO),
|
|
output_layout_name_storage_type_name(Stream, LayoutName,
|
|
being_defined, !IO),
|
|
io.write_string(Stream, " = {", !IO),
|
|
output_module_string_table_strings(Stream, EventSetDesc, [], !IO),
|
|
io.write_string(Stream, "};\n", !IO),
|
|
decl_set_insert(decl_layout_id(LayoutName), !DeclSet).
|
|
|
|
:- pred output_module_string_table(io.text_output_stream::in, module_name::in,
|
|
int::in, string_with_0s::in, decl_set::in, decl_set::out,
|
|
io::di, io::uo) is det.
|
|
|
|
output_module_string_table(Stream, ModuleName, _StringTableSize,
|
|
string_with_0s(StringTable0), !DeclSet, !IO) :-
|
|
TableName = module_layout_string_table(ModuleName),
|
|
io.write_string(Stream, "\n", !IO),
|
|
output_layout_name_storage_type_name(Stream, TableName,
|
|
being_defined, !IO),
|
|
io.write_string(Stream, " = {", !IO),
|
|
|
|
% The string table cannot be zero size; it must contain at least an
|
|
% empty string.
|
|
( StringTable0 = [], FirstString = "", Rest = []
|
|
; StringTable0 = [FirstString | Rest]
|
|
),
|
|
output_module_string_table_strings(Stream, FirstString, Rest, !IO),
|
|
io.write_string(Stream, "};\n", !IO),
|
|
decl_set_insert(decl_layout_id(TableName), !DeclSet).
|
|
|
|
:- pred output_module_string_table_strings(io.text_output_stream::in,
|
|
string::in, list(string)::in, io::di, io::uo) is det.
|
|
|
|
output_module_string_table_strings(Stream, String, [], !IO) :-
|
|
output_module_string_table_chars(Stream, 0, 0, String, !IO).
|
|
output_module_string_table_strings(Stream, String, [Next | Rest], !IO) :-
|
|
output_module_string_table_chars(Stream, 0, 0, String, !IO),
|
|
io.write_string(Stream, ",\n", !IO),
|
|
output_module_string_table_strings(Stream, Next, Rest, !IO).
|
|
|
|
:- pred output_module_string_table_chars(io.text_output_stream::in,
|
|
int::in, int::in, string::in, io::di, io::uo) is det.
|
|
|
|
output_module_string_table_chars(Stream, CurIndex, Count, String, !IO) :-
|
|
( if string.unsafe_index_next(String, CurIndex, NextIndex, Char) then
|
|
( if
|
|
char.to_int(Char, Int),
|
|
Int =< 0x7f
|
|
then
|
|
output_quoted_char_c(Stream, Char, !IO),
|
|
io.write_string(Stream, ", ", !IO)
|
|
else if
|
|
char.to_utf8(Char, Codes)
|
|
then
|
|
output_multi_byte_char_codes(Stream, Codes, !IO)
|
|
else
|
|
unexpected($pred, "invalid code point")
|
|
),
|
|
( if Count = 10 then
|
|
io.nl(Stream, !IO),
|
|
output_module_string_table_chars(Stream, NextIndex,
|
|
0, String, !IO)
|
|
else
|
|
output_module_string_table_chars(Stream, NextIndex,
|
|
Count + 1, String, !IO)
|
|
)
|
|
else
|
|
output_quoted_char_c(Stream, char.det_from_int(0), !IO)
|
|
).
|
|
|
|
:- pred output_multi_byte_char_codes(io.text_output_stream::in, list(int)::in,
|
|
io::di, io::uo) is det.
|
|
|
|
output_multi_byte_char_codes(_, [], !IO).
|
|
output_multi_byte_char_codes(Stream, [C | Cs], !IO) :-
|
|
io.write_int(Stream, C, !IO),
|
|
io.write_string(Stream, ", ", !IO),
|
|
output_multi_byte_char_codes(Stream, Cs, !IO).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- pred output_file_layout_vector_data_defn(io.text_output_stream::in,
|
|
module_name::in, list(layout_name)::in, layout_name::out,
|
|
decl_set::in, decl_set::out, io::di, io::uo) is det.
|
|
|
|
output_file_layout_vector_data_defn(Stream, ModuleName, FileLayoutNames,
|
|
VectorName, !DeclSet, !IO) :-
|
|
list.foldl2(output_layout_decl(Stream), FileLayoutNames, !DeclSet, !IO),
|
|
VectorName = module_layout_file_vector(ModuleName),
|
|
io.write_string(Stream, "\n", !IO),
|
|
output_layout_name_storage_type_name(Stream, VectorName,
|
|
being_defined, !IO),
|
|
io.write_string(Stream, " = {\n", !IO),
|
|
(
|
|
FileLayoutNames = [],
|
|
% ANSI/ISO C doesn't allow empty arrays, so place a dummy value
|
|
% in the array.
|
|
io.write_string(Stream, "NULL\n", !IO)
|
|
;
|
|
FileLayoutNames = [_ | _],
|
|
list.foldl(output_layout_name_in_vector(Stream, "&"),
|
|
FileLayoutNames, !IO)
|
|
),
|
|
io.write_string(Stream, "};\n", !IO),
|
|
decl_set_insert(decl_layout_id(VectorName), !DeclSet).
|
|
|
|
:- pred output_file_layout_data_defns(llds_out_info::in,
|
|
io.text_output_stream::in, module_name::in, int::in,
|
|
list(file_layout_data)::in, list(layout_name)::out,
|
|
decl_set::in, decl_set::out, io::di, io::uo) is det.
|
|
|
|
output_file_layout_data_defns(_, _, _, _, [], [], !DeclSet, !IO).
|
|
output_file_layout_data_defns(Info, Stream, ModuleName, FileNum,
|
|
[FileLayout | FileLayouts], [FileLayoutName | FileLayoutNames],
|
|
!DeclSet, !IO) :-
|
|
output_file_layout_data_defn(Info, Stream, ModuleName,
|
|
FileNum, FileLayout, FileLayoutName, !DeclSet, !IO),
|
|
output_file_layout_data_defns(Info, Stream, ModuleName,
|
|
FileNum + 1, FileLayouts, FileLayoutNames, !DeclSet, !IO).
|
|
|
|
:- pred output_file_layout_data_defn(llds_out_info::in,
|
|
io.text_output_stream::in, module_name::in, int::in,
|
|
file_layout_data::in, layout_name::out,
|
|
decl_set::in, decl_set::out, io::di, io::uo) is det.
|
|
|
|
output_file_layout_data_defn(Info, Stream, ModuleName, FileNum, FileLayout,
|
|
FileLayoutName, !DeclSet, !IO) :-
|
|
MangledModuleName = Info ^ lout_mangled_module_name,
|
|
FileLayout = file_layout_data(FileName, LineNoLabelList),
|
|
assoc_list.keys_and_values(LineNoLabelList, LineNos, LabelLayoutSlots),
|
|
|
|
list.length(LineNoLabelList, VectorLengths),
|
|
output_file_layout_line_number_vector_defn(Info, Stream, ModuleName,
|
|
FileNum, LineNos, LineNumberVectorName, !DeclSet, !IO),
|
|
output_file_layout_label_layout_vector_defn(Stream, MangledModuleName,
|
|
ModuleName, FileNum, LabelLayoutSlots, LabelVectorName, !DeclSet, !IO),
|
|
|
|
FileLayoutName = file_layout(ModuleName, FileNum),
|
|
io.write_string(Stream, "\n", !IO),
|
|
output_layout_name_storage_type_name(Stream, FileLayoutName,
|
|
being_defined, !IO),
|
|
io.write_string(Stream, " = {\n", !IO),
|
|
output_quoted_string_c(Stream, FileName, !IO),
|
|
io.write_string(Stream, ",\n", !IO),
|
|
io.write_int(Stream, VectorLengths, !IO),
|
|
io.write_string(Stream, ",\n", !IO),
|
|
output_layout_name(Stream, LineNumberVectorName, !IO),
|
|
io.write_string(Stream, ",\n", !IO),
|
|
output_layout_name(Stream, LabelVectorName, !IO),
|
|
io.write_string(Stream, "\n};\n", !IO),
|
|
decl_set_insert(decl_layout_id(FileLayoutName), !DeclSet).
|
|
|
|
:- pred output_file_layout_line_number_vector_defn(llds_out_info::in,
|
|
io.text_output_stream::in, module_name::in, int::in, list(int)::in,
|
|
layout_name::out, decl_set::in, decl_set::out, io::di, io::uo) is det.
|
|
|
|
output_file_layout_line_number_vector_defn(Info, Stream, ModuleName, FileNum,
|
|
LineNumbers, LayoutName, !DeclSet, !IO) :-
|
|
LayoutName = file_layout_line_number_vector(ModuleName, FileNum),
|
|
io.write_string(Stream, "\n", !IO),
|
|
output_layout_name_storage_type_name(Stream, LayoutName,
|
|
being_defined, !IO),
|
|
io.write_string(Stream, " = {", !IO),
|
|
(
|
|
LineNumbers = [],
|
|
% ANSI/ISO C doesn't allow empty arrays, so place a dummy value
|
|
% in the array.
|
|
io.write_string(Stream, "\n0", !IO)
|
|
;
|
|
LineNumbers = [_ | _],
|
|
AutoComments = Info ^ lout_auto_comments,
|
|
(
|
|
AutoComments = auto_comments,
|
|
output_numbers_in_vector_ac(Stream, LineNumbers, 0, !IO)
|
|
;
|
|
AutoComments = no_auto_comments,
|
|
output_numbers_in_vector_noac(Stream, LineNumbers, 0, !IO)
|
|
)
|
|
),
|
|
io.write_string(Stream, "\n};\n", !IO),
|
|
decl_set_insert(decl_layout_id(LayoutName), !DeclSet).
|
|
|
|
:- pred output_file_layout_label_layout_vector_defn(io.text_output_stream::in,
|
|
string::in, module_name::in, int::in, list(layout_slot_name)::in,
|
|
layout_name::out, decl_set::in, decl_set::out, io::di, io::uo) is det.
|
|
|
|
output_file_layout_label_layout_vector_defn(Stream, MangledModuleName,
|
|
ModuleName, FileNum, LabelSlots, LayoutName, !DeclSet, !IO) :-
|
|
LayoutName = file_layout_label_layout_vector(ModuleName, FileNum),
|
|
io.write_string(Stream, "\n", !IO),
|
|
output_layout_name_storage_type_name(Stream, LayoutName,
|
|
being_defined, !IO),
|
|
io.write_string(Stream, " = {\n", !IO),
|
|
(
|
|
LabelSlots = [],
|
|
% ANSI/ISO C doesn't allow empty arrays, so place a dummy value
|
|
% in the array.
|
|
io.write_string(Stream, "NULL\n", !IO)
|
|
;
|
|
LabelSlots = [_ | _],
|
|
output_layout_slots_in_vector(Stream, MangledModuleName,
|
|
LabelSlots, !IO)
|
|
),
|
|
io.write_string(Stream, "};\n", !IO),
|
|
decl_set_insert(decl_layout_id(LayoutName), !DeclSet).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- pred output_layout_slots_in_vector(io.text_output_stream::in, string::in,
|
|
list(layout_slot_name)::in, io::di, io::uo) is det.
|
|
|
|
output_layout_slots_in_vector(_, _, [], !IO).
|
|
output_layout_slots_in_vector(Stream, ModuleName,
|
|
[SlotName | SlotNames], !IO) :-
|
|
SlotName = layout_slot(ArrayName, SlotNum),
|
|
(
|
|
(
|
|
ArrayName = label_layout_array(label_has_no_var_info),
|
|
Macro = "MR_no_var_label_layout_refs"
|
|
;
|
|
ArrayName = label_layout_array(label_has_short_var_info),
|
|
Macro = "MR_svar_label_layout_refs"
|
|
;
|
|
ArrayName = label_layout_array(label_has_long_var_info),
|
|
Macro = "MR_lvar_label_layout_refs"
|
|
),
|
|
find_slots_in_same_array(ArrayName, SlotNames, [], RevTailSlotNums,
|
|
OtherArraySlotNames),
|
|
list.reverse(RevTailSlotNums, TailSlotNums),
|
|
SlotNums = [SlotNum | TailSlotNums],
|
|
% There must be a macro of the form Macro<n> for all values of <n>
|
|
% between 1 and ChunkSize.
|
|
ChunkSize = 10,
|
|
list.chunk(SlotNums, ChunkSize, SlotNumChunks),
|
|
list.foldl(output_layout_slot_chunk(Stream, Macro, ModuleName),
|
|
SlotNumChunks, !IO),
|
|
output_layout_slots_in_vector(Stream, ModuleName,
|
|
OtherArraySlotNames, !IO)
|
|
;
|
|
( ArrayName = pseudo_type_info_array
|
|
; ArrayName = long_locns_array
|
|
; ArrayName = short_locns_array
|
|
; ArrayName = hlds_var_nums_array
|
|
; ArrayName = user_event_var_nums_array
|
|
; ArrayName = user_event_layout_array
|
|
; ArrayName = proc_static_call_sites_array
|
|
; ArrayName = proc_static_cp_static_array
|
|
; ArrayName = proc_static_cp_dynamic_array
|
|
; ArrayName = proc_static_array
|
|
; ArrayName = proc_var_names_array
|
|
; ArrayName = proc_head_var_nums_array
|
|
; ArrayName = proc_body_bytecodes_array
|
|
; ArrayName = proc_table_io_entry_array
|
|
; ArrayName = proc_event_layouts_array
|
|
; ArrayName = proc_exec_trace_array
|
|
; ArrayName = threadscope_string_table_array
|
|
; ArrayName = alloc_site_array
|
|
),
|
|
output_layout_slot_addr(Stream, use_layout_macro, ModuleName,
|
|
SlotName, !IO),
|
|
io.write_string(Stream, ",\n", !IO),
|
|
output_layout_slots_in_vector(Stream, ModuleName, SlotNames, !IO)
|
|
).
|
|
|
|
:- pred find_slots_in_same_array(layout_array_name::in,
|
|
list(layout_slot_name)::in, list(int)::in, list(int)::out,
|
|
list(layout_slot_name)::out) is det.
|
|
|
|
find_slots_in_same_array(_ArrayName, [], !RevSlotNums, []).
|
|
find_slots_in_same_array(ArrayName, [SlotName | SlotNames], !RevSlotNums,
|
|
OtherArraySlotNames) :-
|
|
SlotName = layout_slot(SlotArrayName, SlotNum),
|
|
( if SlotArrayName = ArrayName then
|
|
!:RevSlotNums = [SlotNum | !.RevSlotNums],
|
|
find_slots_in_same_array(ArrayName, SlotNames, !RevSlotNums,
|
|
OtherArraySlotNames)
|
|
else
|
|
OtherArraySlotNames = [SlotName | SlotNames]
|
|
).
|
|
|
|
:- pred output_layout_slot_chunk(io.text_output_stream::in,
|
|
string::in, string::in, list(int)::in, io::di, io::uo) is det.
|
|
|
|
output_layout_slot_chunk(Stream, Macro, ModuleName, SlotNums, !IO) :-
|
|
list.length(SlotNums, Length),
|
|
io.write_string(Stream, Macro, !IO),
|
|
io.write_int(Stream, Length, !IO),
|
|
io.write_string(Stream, "(", !IO),
|
|
io.write_string(Stream, ModuleName, !IO),
|
|
io.write_string(Stream, ", ", !IO),
|
|
write_out_list(add_int, ",", SlotNums, Stream, !IO),
|
|
io.write_string(Stream, ")\n", !IO).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%
|
|
% Print out vectors of numbers.
|
|
%
|
|
% We print ten numbers per line to make it easy to locate a particular element
|
|
% in a vector.
|
|
%
|
|
% We do a two level loop to limit the number of stack frames we consume
|
|
% in grades that do not permit tail recursion. The idea is that after printing
|
|
% 1000 numbers, we free up all the stack space that printing consumed.
|
|
% When printing N numbers, we use only about (N / 1000) + (N mod 1000) frames.
|
|
%
|
|
% Each predicate has two versions. The _ac version assumes auto-comment,
|
|
% the _noac version assumes no auto-comment.
|
|
%
|
|
|
|
:- pred output_numbers_in_vector_ac(io.text_output_stream::in,
|
|
list(int)::in, int::in, io::di, io::uo) is det.
|
|
|
|
output_numbers_in_vector_ac(_, [], _, !IO).
|
|
output_numbers_in_vector_ac(Stream, VarNums @ [_ | _], !.Slot, !IO) :-
|
|
output_upto_n_numbers_in_vector_ac(Stream, VarNums, 1000,
|
|
LeftOverVarNums, !Slot, !IO),
|
|
output_numbers_in_vector_ac(Stream, LeftOverVarNums, !.Slot, !IO).
|
|
|
|
:- pred output_numbers_in_vector_noac(io.text_output_stream::in,
|
|
list(int)::in, int::in, io::di, io::uo) is det.
|
|
|
|
output_numbers_in_vector_noac(_, [], _, !IO).
|
|
output_numbers_in_vector_noac(Stream, VarNums @ [_ | _], !.Slot, !IO) :-
|
|
output_upto_n_numbers_in_vector_noac(Stream, VarNums, 1000,
|
|
LeftOverVarNums, !Slot, !IO),
|
|
output_numbers_in_vector_noac(Stream, LeftOverVarNums, !.Slot, !IO).
|
|
|
|
:- pred output_upto_n_numbers_in_vector_ac(io.text_output_stream::in,
|
|
list(int)::in, int::in, list(int)::out, int::in, int::out,
|
|
io::di, io::uo) is det.
|
|
|
|
output_upto_n_numbers_in_vector_ac(_, [], _, [], !Slot, !IO).
|
|
output_upto_n_numbers_in_vector_ac(Stream, [VarNum | VarNums], N,
|
|
LeftOverVarNums, !Slot, !IO) :-
|
|
( if N > 0 then
|
|
output_number_in_vector_ac(Stream, VarNum, !Slot, !IO),
|
|
output_upto_n_numbers_in_vector_ac(Stream, VarNums, N - 1,
|
|
LeftOverVarNums, !Slot, !IO)
|
|
else
|
|
LeftOverVarNums = [VarNum | VarNums]
|
|
).
|
|
|
|
:- pred output_upto_n_numbers_in_vector_noac(io.text_output_stream::in,
|
|
list(int)::in, int::in, list(int)::out, int::in, int::out,
|
|
io::di, io::uo) is det.
|
|
|
|
output_upto_n_numbers_in_vector_noac(_, [], _, [], !Slot, !IO).
|
|
output_upto_n_numbers_in_vector_noac(Stream, [VarNum | VarNums], N,
|
|
LeftOverVarNums, !Slot, !IO) :-
|
|
( if N > 0 then
|
|
output_number_in_vector_noac(Stream, VarNum, !Slot, !IO),
|
|
output_upto_n_numbers_in_vector_noac(Stream, VarNums, N - 1,
|
|
LeftOverVarNums, !Slot, !IO)
|
|
else
|
|
LeftOverVarNums = [VarNum | VarNums]
|
|
).
|
|
|
|
:- pred output_number_in_vector_ac(io.text_output_stream::in,
|
|
int::in, int::in, int::out, io::di, io::uo) is det.
|
|
|
|
output_number_in_vector_ac(Stream, VarNum, !Slot, !IO) :-
|
|
( if !.Slot mod 10 = 0 then
|
|
io.format(Stream, "\n/* slots %d+ */ ", [i(!.Slot)], !IO)
|
|
else
|
|
io.write_string(Stream, " ", !IO)
|
|
),
|
|
io.format(Stream, "%d,", [i(VarNum)], !IO),
|
|
!:Slot = !.Slot + 1.
|
|
|
|
:- pred output_number_in_vector_noac(io.text_output_stream::in,
|
|
int::in, int::in, int::out, io::di, io::uo) is det.
|
|
|
|
output_number_in_vector_noac(Stream, VarNum, !Slot, !IO) :-
|
|
( if !.Slot mod 10 = 0 then
|
|
io.nl(Stream, !IO)
|
|
else
|
|
io.write_string(Stream, " ", !IO)
|
|
),
|
|
io.format(Stream, "%d,", [i(VarNum)], !IO),
|
|
!:Slot = !.Slot + 1.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
%
|
|
% Utility predicates.
|
|
%
|
|
|
|
:- pred output_layout_name_in_vector(io.text_output_stream::in, string::in,
|
|
layout_name::in, io::di, io::uo) is det.
|
|
|
|
output_layout_name_in_vector(Stream, Prefix, Name, !IO) :-
|
|
io.write_string(Stream, Prefix, !IO),
|
|
output_layout_name(Stream, Name, !IO),
|
|
io.write_string(Stream, ",\n", !IO).
|
|
|
|
:- pred long_length(list(T)::in, int::out) is det.
|
|
|
|
long_length(List, Length) :-
|
|
long_length_outer_loop(List, 0, Length).
|
|
|
|
:- pred long_length_outer_loop(list(T)::in, int::in, int::out) is det.
|
|
|
|
long_length_outer_loop([], !Length).
|
|
long_length_outer_loop(List @ [_ | _], !Length) :-
|
|
long_length_inner_loop(List, 5000, LeftOver, !Length),
|
|
long_length_outer_loop(LeftOver, !Length).
|
|
|
|
:- pred long_length_inner_loop(list(T)::in, int::in, list(T)::out,
|
|
int::in, int::out) is det.
|
|
|
|
long_length_inner_loop([], _, [], !Length).
|
|
long_length_inner_loop([H | T], Count, LeftOver, !Length) :-
|
|
( if Count > 0 then
|
|
!:Length = !.Length + 1,
|
|
long_length_inner_loop(T, Count - 1, LeftOver, !Length)
|
|
else
|
|
LeftOver = [H | T]
|
|
).
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
layout_name_would_include_code_addr(LayoutName) = InclCodeAddr :-
|
|
(
|
|
( LayoutName = proc_layout(_, _)
|
|
; LayoutName = closure_proc_id(_, _, _)
|
|
; LayoutName = file_layout(_, _)
|
|
; LayoutName = file_layout_line_number_vector(_, _)
|
|
; LayoutName = file_layout_label_layout_vector(_, _)
|
|
; LayoutName = module_layout_string_table(_)
|
|
; LayoutName = module_layout_file_vector(_)
|
|
; LayoutName = module_layout_proc_vector(_)
|
|
; LayoutName = module_layout_label_exec_count(_, _)
|
|
; LayoutName = module_layout_event_set_desc(_)
|
|
; LayoutName = module_layout_event_arg_names(_, _)
|
|
; LayoutName = module_layout_event_synth_attrs(_, _)
|
|
; LayoutName = module_layout_event_synth_attr_args(_, _, _)
|
|
; LayoutName = module_layout_event_synth_attr_order(_, _, _)
|
|
; LayoutName = module_layout_event_synth_order(_, _)
|
|
; LayoutName = module_layout_event_specs(_)
|
|
; LayoutName = module_layout_oisu_bytes(_)
|
|
; LayoutName = module_layout_type_table_bytes(_)
|
|
; LayoutName = module_layout(_)
|
|
),
|
|
InclCodeAddr = no
|
|
).
|
|
|
|
:- func proc_layout_kind_to_type(proc_layout_kind) = string.
|
|
|
|
proc_layout_kind_to_type(proc_layout_traversal) = "MR_ProcLayout_Traversal".
|
|
proc_layout_kind_to_type(proc_layout_proc_id(user)) = "MR_ProcLayoutUser".
|
|
proc_layout_kind_to_type(proc_layout_proc_id(uci)) = "MR_ProcLayoutUCI".
|
|
|
|
proc_label_user_or_uci(ordinary_proc_label(_, _, _, _, _, _)) = user.
|
|
proc_label_user_or_uci(special_proc_label(_, _, _, _, _, _)) = uci.
|
|
|
|
mr_pred_or_func_to_string(PredOrFunc) = Str :-
|
|
(
|
|
PredOrFunc = pf_predicate,
|
|
Str = "MR_PREDICATE"
|
|
;
|
|
PredOrFunc = pf_function,
|
|
Str = "MR_FUNCTION"
|
|
).
|
|
|
|
:- func detism_to_c_detism(determinism) = string.
|
|
|
|
detism_to_c_detism(detism_det) = "MR_DETISM_DET".
|
|
detism_to_c_detism(detism_semi) = "MR_DETISM_SEMI".
|
|
detism_to_c_detism(detism_non) = "MR_DETISM_NON".
|
|
detism_to_c_detism(detism_multi) = "MR_DETISM_MULTI".
|
|
detism_to_c_detism(detism_erroneous) = "MR_DETISM_ERRONEOUS".
|
|
detism_to_c_detism(detism_failure) = "MR_DETISM_FAILURE".
|
|
detism_to_c_detism(detism_cc_non) = "MR_DETISM_CCNON".
|
|
detism_to_c_detism(detism_cc_multi) = "MR_DETISM_CCMULTI".
|
|
|
|
trace_port_to_string(port_call) = "CALL".
|
|
trace_port_to_string(port_exit) = "EXIT".
|
|
trace_port_to_string(port_redo) = "REDO".
|
|
trace_port_to_string(port_fail) = "FAIL".
|
|
trace_port_to_string(port_tailrec_call) = "TAILREC_CALL".
|
|
trace_port_to_string(port_exception) = "EXCEPTION".
|
|
trace_port_to_string(port_ite_cond) = "COND".
|
|
trace_port_to_string(port_ite_then) = "THEN".
|
|
trace_port_to_string(port_ite_else) = "ELSE".
|
|
trace_port_to_string(port_neg_enter) = "NEG_ENTER".
|
|
trace_port_to_string(port_neg_success) = "NEG_SUCCESS".
|
|
trace_port_to_string(port_neg_failure) = "NEG_FAILURE".
|
|
trace_port_to_string(port_disj_first) = "DISJ_FIRST".
|
|
trace_port_to_string(port_disj_later) = "DISJ_LATER".
|
|
trace_port_to_string(port_switch) = "SWITCH".
|
|
trace_port_to_string(port_user) = "USER".
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
:- end_module ll_backend.layout_out.
|
|
%-----------------------------------------------------------------------------%
|