Files
mercury/compiler/layout_out.m
Zoltan Somogyi 3dd0f2e03b Act on all remaining warnings about unused state vars.
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.
2025-05-19 00:33:06 +10:00

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.
%-----------------------------------------------------------------------------%