Files
mercury/compiler/layout_out.m
Zoltan Somogyi 2dc982cfe4 Make a representation of the program available to the deep profiler.
Estimated hours taken: 50
Branches: main

Make a representation of the program available to the deep profiler. We do
this by letting the user request, via the option "--deep-procrep-file"
in MERCURY_OPTIONS, that when the Deep.data file is written, a Deep.procrep
file should be written alongside it.

The intended use of this information is the discovery of profitable
parallelism. When a conjunction contains two expensive calls, e.g. p(...) and
q(...) connected by some shared variables, the potential gain from executing
them in parallel is limited by how early p produces those variables and how
late q consumes them, and knowing this requires access to the code of p and q.

Since the debugger and the deep profiler both need access to program
representations, put the relevant data structures and the operations on them
in mdbcomp. The data structures are significantly expanded, since the deep
profiler deals with the whole program, while the debugger was interested only
in one procedure at a time.

The layout structures have to change as well. In a previous change, I changed
proc layout structures to make room for the procedure representation even in
non-debugging grades, but this isn't enough, since the procedure representation
refers to the module's string table. This diff therefore makes some parts of
the module layout structure, including of course the string table, also
available in non-debugging grades.

configure.in:
	Check whether the installed compiler can process switches on foreign
	enums correctly, since this diff depends on that.

runtime/mercury_stack_layout.[ch]:
runtime/mercury_types.h:
	Add a new structure, MR_ModuleCommonLayout, that holds the part of
	the module layout that is common to deep profiling and debugging.

runtime/mercury_deep_profiling.[ch]:
	The old "deep profiling token" enum type was error prone, since at
	each point in the data file, only a subset was applicable. This diff
	breaks up the this enum into several enums, each consisting of the
	choice applicable at a given point.

	This also allows some of the resulting enums to be used in procrep
	files.

	Rename some enums and functions to avoid ambiguities, and in one case
	to conform to our naming scheme.

	Make write_out_proc_statics take a second argument. This is a FILE *
	that (if not NULL) asks write_out_proc_statics to write the
	representation of the current module to specified stream.

	These module representations go into the middle part of the program
	representation file. Add functions to write out the prologue and
	epilogue of this file.

	Write out procedure representations if this is requested.

	Factor out some code that is now used in more than one place.

runtime/mercury_deep_profiling_hand.h:
	Conform to the changes to mercury_deep_profiling.h.

runtime/mercury_builtin_types.c:
	Pass the extra argument in the argument lists of invocations of
	write_out_proc_statics.

runtime/mercury_trace_base.[ch]:
	Conform to the name change from proc_rep to proc_defn_rep in mdbcomp.

runtime/mercury_grade.h:
	Due to the change to layout structures, increment the binary
	compatibility version numbers for both debug and deep profiling grades.

runtime/mercury_wrapper.[ch]:
	Provide two new MERCURY_OPTION options. The first --deep-procrep-file,
	allows the user to ask for the program representation to be generated.
	The second, --deep-random-write, allows tools/bootcheck to request that
	only a fraction of all program invocations should generate any deep
	profiling output.

	The first option will be documented once it is tested much more fully.
	The second option is deliberately not documented.

	Update the type of the variable that holds the address of the
	(mkinit-generated) write_out_proc_statics function to accept the second
	argument.

util/mkinit.c:
	Pass the extra argument in the argument list of write_out_proc_statics.

mdbcomp/program_representation.m:
	Extend the existing data structures for representing a procedure body
	to represent a procedure (complete with name), a module and a program.
	The name is implemented as string_proc_label, a form of proc_label that
	can be written out to files. This replaces the old proc_id type the
	deep profiler.

	Extend the representation of switches to record the identity of the
	variable being switched on, and the cons_ids of the arms. Without the
	former, we cannot be sure when a variable is first used, and the latter
	is needed for meaningful prettyprinting of procedure bodies.

	Add code for reading in files of bytecodes, and for making sense of the
	bytecodes themselves. (It is this code that uses foreign enums.)

mdbcomp/prim_data.m:
	Note the relationship of proc_label with string_proc_label.

mdbcomp/rtti_access.m:
	Add the access operations needed to find module string tables with the
	new organization of layout structures.

	Provide operations on bytecodes and string tables generally.

trace/mercury_trace_cmd_browsing.c:
	Conform to the change to mdbcomp/program_representation.m.

compiler/layout.m:
	Add support for a MR_ModuleCommonLayout.

	Rename some function symbols to avoid ambiguities.

compiler/layout_out.m:
	Handle the new structure.

compiler/stack_layout.m:
	Generate the new structure and the procedure representation bytecode
	in deep profiling grades.

compiler/llds_out.m:
	Generate the code required to write out the prologue and epilogue
	of program representation files.

	Pass the extra argument in the argument lists of invocations of
	write_out_proc_statics that tells those invocations to write out
	the module representations between the prologue and the epilogue.

compiler/prog_rep.m:
	When generating bytecodes, include the new information for switches.

compiler/continuation_info.m:
	Replace a bool with a more expressive type.

compiler/proc_rep.m:
	Conform to the change to continuation_info.m.

compiler/opt_debug.m:
	Conform to the change to layout.m.

deep_profiler/mdprof_procrep.m:
	A new test program to test the reading of program representations.

deep_profiler/DEEP_FLAGS.in:
deep_profiler/Mmakefile:
	Copy the contents of the mdbcomp module to this directory on demand,
	instead of linking to it. This is necessary now that the deep profiler
	depends directly on mdbcomp even if it is compiled in a non-debugging
	grade.

	The arrangements for doing this were copied from the slice directory,
	which has long done the same.

	Avoid a duplicate include of Mmake.deep.params.

	Add the new test program to the list of programs in this directory.

Mmakefile:
	Go through deep_profiler/Mmakefile when deciding whether to do "mmake
	depend" in the deep_profiler directory. The old actions won't work
	correctly now that we need to copy some files from mdbcomp before we
	can run "mmake depend".

deep_profiler/profile.m:
	Remove the code that was moved (in cleaned-up form) to mdbcomp.

deep_profiler/dump.m:
deep_profiler/profile.m:
	Conform to the changes above.

browser/declarative_execution.m:
browser/declarative_tree.m:
	Conform to the changes in mdbcomp.

doc/user_guide.texi:
	Add commented out documentation of the two new options.

slice/Mmakefile:
	Fix formatting, and a bug.

library/exception.m:
library/par_builtin.m:
library/thread.m:
library/thread.semaphore.m:
	Update all the handwritten modules to pass the extra argument now
	required by write_out_proc_statics.

tests/debugger/declarative/dependency.exp:
	Conform to the change from proc_rep to proc_defn_rep.

tools/bootcheck:
	Write out deep profiling data only from every 25th invocation, since
	otherwise the time for a bootcheck takes six times as long in deep
	profiling grades than in asm_fast.gc.

	However, do test the ability to write out program representations.

	Use the mkinit from the workspace, not the installed one.

	Don't disable line wrapping.
2007-09-12 06:21:20 +00:00

2256 lines
88 KiB
Mathematica

%-----------------------------------------------------------------------------%
% vim: ft=mercury ts=4 sw=4 et
%-----------------------------------------------------------------------------%
% Copyright (C) 2001-2007 The University of Melbourne.
% This file may only be copied under the terms of the GNU General
% Public License - see the file COPYING in the Mercury distribution.
%-----------------------------------------------------------------------------%
%
% 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 ll_backend.layout.
:- import_module ll_backend.llds.
:- import_module ll_backend.llds_out.
:- import_module mdbcomp.prim_data.
:- import_module bool.
:- import_module io.
%-----------------------------------------------------------------------------%
% Given a Mercury representation of a layout structure, output its
% definition in the appropriate C global variable.
%
:- pred output_layout_data_defn(layout_data::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(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(layout_name::in,
decl_set::in, decl_set::out, io::di, io::uo) is det.
% Given a Mercury representation 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_data_decl(layout_data::in,
decl_set::in, decl_set::out, io::di, io::uo) is det.
% 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 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_name_storage_type_name(layout_name::in, bool::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(layout_name::in, 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.
% Given a label, return a string giving the name of the global variable
% containing the label layout structure that would be associated with it.
% Make_label_layout_name does not guarantee that the label *has* an
% associated label layout structure.
%
:- func make_label_layout_name(label) = string.
% 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.
% Output a value of C type MR_PredFunc corrresponding to the argument.
%
:- pred output_pred_or_func(pred_or_func::in, io::di, io::uo) is det.
% 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.c_util.
:- import_module backend_libs.name_mangle.
:- import_module backend_libs.proc_label.
:- import_module hlds.hlds_goal.
:- import_module hlds.hlds_pred.
:- import_module hlds.hlds_rtti.
:- import_module hlds.special_pred.
:- import_module libs.compiler_util.
:- import_module libs.trace_params.
:- import_module mdbcomp.program_representation.
:- import_module parse_tree.mercury_to_mercury.
:- import_module parse_tree.prog_data.
:- import_module parse_tree.prog_foreign.
:- import_module assoc_list.
:- import_module char.
:- import_module int.
:- import_module list.
:- import_module map.
:- import_module maybe.
:- import_module pair.
:- import_module string.
:- import_module varset.
%-----------------------------------------------------------------------------%
output_layout_data_defn(Data, !DeclSet, !IO) :-
(
Data = label_layout_data(ProcLabel, LabelNum, ProcLayoutAddr,
MaybePort, MaybeIsHidden, LabelNumber, MaybeGoalPath,
MaybeUserData, MaybeVarInfo),
output_label_layout_data_defn(ProcLabel, LabelNum, ProcLayoutAddr,
MaybePort, MaybeIsHidden, LabelNumber, MaybeGoalPath,
MaybeUserData, MaybeVarInfo, !DeclSet, !IO)
;
Data = proc_layout_data(ProcLabel, Traversal, MaybeRest),
output_proc_layout_data_defn(ProcLabel, Traversal, MaybeRest,
!DeclSet, !IO)
;
Data = closure_proc_id_data(CallerProcLabel, SeqNo, ProcLabel,
ModuleName, FileName, LineNumber, PredOrigin, GoalPath),
output_closure_proc_id_data_defn(CallerProcLabel, SeqNo, ProcLabel,
ModuleName, FileName, LineNumber, PredOrigin, GoalPath,
!DeclSet, !IO)
;
Data = module_layout_common_data(ModuleName,
StringTableSize, StringTable),
output_module_common_layout_data_defn(ModuleName, StringTableSize,
StringTable, !DeclSet, !IO)
;
Data = module_layout_data(ModuleName, ModuleCommonLayoutName,
ProcLayoutNames, FileLayouts, TraceLevel,
SuppressedEvents, NumLabels, MaybeEventSet),
output_module_layout_data_defn(ModuleName, ModuleCommonLayoutName,
ProcLayoutNames, FileLayouts, TraceLevel,
SuppressedEvents, NumLabels, MaybeEventSet, !DeclSet, !IO)
;
Data = table_io_decl_data(RttiProcLabel, Kind, NumPTIs,
PTIVectorRval, TypeParamsRval),
output_table_io_decl(RttiProcLabel, Kind, NumPTIs,
PTIVectorRval, TypeParamsRval, !DeclSet, !IO)
).
%-----------------------------------------------------------------------------%
output_layout_name_decl(LayoutName, !IO) :-
output_layout_name_storage_type_name(LayoutName, no, !IO),
io.write_string(";\n", !IO).
output_maybe_layout_name_decl(LayoutName, !DeclSet, !IO) :-
( decl_set_is_member(decl_data_addr(layout_addr(LayoutName)), !.DeclSet) ->
true
;
output_layout_name_decl(LayoutName, !IO),
decl_set_insert(decl_data_addr(layout_addr(LayoutName)), !DeclSet)
).
output_maybe_layout_data_decl(LayoutData, !DeclSet, !IO) :-
extract_layout_name(LayoutData, LayoutName),
output_maybe_layout_name_decl(LayoutName, !DeclSet, !IO).
:- pred extract_layout_name(layout_data::in, layout_name::out) is det.
extract_layout_name(Data, LayoutName) :-
(
Data = label_layout_data(ProcLabel, LabelNum, _, _, _, _, _, _,
MaybeVarInfo),
(
MaybeVarInfo = yes(_),
LabelVars = label_has_var_info
;
MaybeVarInfo = no,
LabelVars = label_has_no_var_info
),
LayoutName = label_layout(ProcLabel, LabelNum, LabelVars)
;
Data = proc_layout_data(RttiProcLabel, _, MaybeRest),
ProcLabel = make_proc_label_from_rtti(RttiProcLabel),
Kind = maybe_proc_layout_and_more_kind(MaybeRest, ProcLabel),
LayoutName = proc_layout(RttiProcLabel, Kind)
;
Data = closure_proc_id_data(CallerProcLabel, SeqNo, ClosureProcLabel,
_, _, _, _, _),
LayoutName = closure_proc_id(CallerProcLabel, SeqNo, ClosureProcLabel)
;
Data = module_layout_common_data(ModuleName, _, _),
LayoutName = module_common_layout(ModuleName)
;
Data = module_layout_data(ModuleName, _, _, _, _, _, _, _),
LayoutName = module_layout(ModuleName)
;
Data = table_io_decl_data(RttiProcLabel, _, _, _, _),
LayoutName = table_io_decl(RttiProcLabel)
).
:- pred output_layout_decl(layout_name::in, decl_set::in, decl_set::out,
io::di, io::uo) is det.
output_layout_decl(LayoutName, !DeclSet, !IO) :-
( decl_set_is_member(decl_data_addr(layout_addr(LayoutName)), !.DeclSet) ->
true
;
output_layout_name_storage_type_name(LayoutName, no, !IO),
io.write_string(";\n", !IO),
decl_set_insert(decl_data_addr(layout_addr(LayoutName)), !DeclSet)
).
% This code should be kept in sync with output_layout_name/3 below.
make_label_layout_name(Label) = Name :-
% We can't omit the mercury_ prefix on LabelName, even though the
% mercury_data_prefix duplicates it, because there is no simple way
% to make the MR_init_label_sl macro delete that prefix from the
% label's name to get the name of its layout structure.
LabelName = label_to_c_string(Label, yes),
string.append_list([
mercury_data_prefix,
"_label_layout__",
LabelName
], Name).
output_layout_name(Data, !IO) :-
(
Data = label_layout(ProcLabel, LabelNum, _),
% This code should be kept in sync with make_label_layout_name/1 above.
io.write_string(mercury_data_prefix, !IO),
io.write_string("_label_layout__", !IO),
io.write_string(
label_to_c_string(internal_label(LabelNum, ProcLabel), yes), !IO)
;
Data = user_event_layout(ProcLabel, LabelNum),
io.write_string(mercury_data_prefix, !IO),
io.write_string("_user_event_layout__", !IO),
io.write_string(
label_to_c_string(internal_label(LabelNum, ProcLabel), yes), !IO)
;
Data = user_event_attr_var_nums(ProcLabel, LabelNum),
io.write_string(mercury_data_prefix, !IO),
io.write_string("_user_event_attr_var_nums__", !IO),
io.write_string(
label_to_c_string(internal_label(LabelNum, ProcLabel), yes), !IO)
;
Data = proc_layout(RttiProcLabel, _),
io.write_string(mercury_data_prefix, !IO),
io.write_string("_proc_layout__", !IO),
% We can't omit the mercury_ prefix on ProcLabel, even though the
% mercury_data_prefix duplicates it, because there is no simply 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.
output_proc_label(make_proc_label_from_rtti(RttiProcLabel), !IO)
;
Data = proc_layout_exec_trace(RttiProcLabel),
io.write_string(mercury_data_prefix, !IO),
io.write_string("_proc_layout_exec_trace__", !IO),
output_proc_label_no_prefix(make_proc_label_from_rtti(RttiProcLabel),
!IO)
;
Data = proc_layout_label_layouts(RttiProcLabel),
io.write_string(mercury_data_prefix, !IO),
io.write_string("_proc_label_layouts__", !IO),
output_proc_label_no_prefix(make_proc_label_from_rtti(RttiProcLabel),
!IO)
;
Data = proc_layout_head_var_nums(RttiProcLabel),
io.write_string(mercury_data_prefix, !IO),
io.write_string("_head_var_nums__", !IO),
output_proc_label_no_prefix(make_proc_label_from_rtti(RttiProcLabel),
!IO)
;
Data = proc_layout_var_names(RttiProcLabel),
io.write_string(mercury_data_prefix, !IO),
io.write_string("_var_names__", !IO),
output_proc_label_no_prefix(make_proc_label_from_rtti(RttiProcLabel),
!IO)
;
Data = proc_layout_body_bytecode(RttiProcLabel),
io.write_string(mercury_data_prefix, !IO),
io.write_string("_body_bytecode__", !IO),
output_proc_label_no_prefix(make_proc_label_from_rtti(RttiProcLabel),
!IO)
;
Data = closure_proc_id(CallerProcLabel, SeqNo, _),
io.write_string(mercury_data_prefix, !IO),
io.write_string("_closure_layout__", !IO),
output_proc_label_no_prefix(CallerProcLabel, !IO),
io.write_string("_", !IO),
io.write_int(SeqNo, !IO)
;
Data = file_layout(ModuleName, FileNum),
io.write_string(mercury_data_prefix, !IO),
io.write_string("_file_layout__", !IO),
ModuleNameStr = sym_name_mangle(ModuleName),
io.write_string(ModuleNameStr, !IO),
io.write_string("_", !IO),
io.write_int(FileNum, !IO)
;
Data = file_layout_line_number_vector(ModuleName, FileNum),
io.write_string(mercury_data_prefix, !IO),
io.write_string("_file_lines__", !IO),
ModuleNameStr = sym_name_mangle(ModuleName),
io.write_string(ModuleNameStr, !IO),
io.write_string("_", !IO),
io.write_int(FileNum, !IO)
;
Data = file_layout_label_layout_vector(ModuleName, FileNum),
io.write_string(mercury_data_prefix, !IO),
io.write_string("_file_label_layouts__", !IO),
ModuleNameStr = sym_name_mangle(ModuleName),
io.write_string(ModuleNameStr, !IO),
io.write_string("_", !IO),
io.write_int(FileNum, !IO)
;
Data = module_layout_string_table(ModuleName),
io.write_string(mercury_data_prefix, !IO),
io.write_string("_module_strings__", !IO),
ModuleNameStr = sym_name_mangle(ModuleName),
io.write_string(ModuleNameStr, !IO)
;
Data = module_layout_file_vector(ModuleName),
io.write_string(mercury_data_prefix, !IO),
io.write_string("_module_files__", !IO),
ModuleNameStr = sym_name_mangle(ModuleName),
io.write_string(ModuleNameStr, !IO)
;
Data = module_layout_proc_vector(ModuleName),
io.write_string(mercury_data_prefix, !IO),
io.write_string("_module_procs__", !IO),
ModuleNameStr = sym_name_mangle(ModuleName),
io.write_string(ModuleNameStr, !IO)
;
Data = module_layout_label_exec_count(ModuleName, _),
io.write_string(mercury_data_prefix, !IO),
io.write_string("_module_label_exec_counts__", !IO),
ModuleNameStr = sym_name_mangle(ModuleName),
io.write_string(ModuleNameStr, !IO)
;
Data = module_layout_event_set_desc(ModuleName),
io.write_string(mercury_data_prefix, !IO),
io.write_string("_module_layout_event_set_desc__", !IO),
ModuleNameStr = sym_name_mangle(ModuleName),
io.write_string(ModuleNameStr, !IO)
;
Data = module_layout_event_arg_names(ModuleName, EventNumber),
io.write_string(mercury_data_prefix, !IO),
io.write_string("_module_layout_event_arg_names__", !IO),
ModuleNameStr = sym_name_mangle(ModuleName),
io.write_string(ModuleNameStr, !IO),
io.write_string("_", !IO),
io.write_int(EventNumber, !IO)
;
Data = module_layout_event_synth_attrs(ModuleName, EventNumber),
io.write_string(mercury_data_prefix, !IO),
io.write_string("_module_layout_event_synth_attrs__", !IO),
ModuleNameStr = sym_name_mangle(ModuleName),
io.write_string(ModuleNameStr, !IO),
io.write_string("_", !IO),
io.write_int(EventNumber, !IO)
;
Data = module_layout_event_synth_attr_args(ModuleName,
EventNumber, SynthCallArgNumber),
io.write_string(mercury_data_prefix, !IO),
io.write_string("_module_layout_event_synth_attr_args__", !IO),
ModuleNameStr = sym_name_mangle(ModuleName),
io.write_string(ModuleNameStr, !IO),
io.write_string("_", !IO),
io.write_int(EventNumber, !IO),
io.write_string("_", !IO),
io.write_int(SynthCallArgNumber, !IO)
;
Data = module_layout_event_synth_attr_order(ModuleName,
EventNumber, SynthCallArgNumber),
io.write_string(mercury_data_prefix, !IO),
io.write_string("_module_layout_event_synth_attr_order__", !IO),
ModuleNameStr = sym_name_mangle(ModuleName),
io.write_string(ModuleNameStr, !IO),
io.write_string("_", !IO),
io.write_int(EventNumber, !IO),
io.write_string("_", !IO),
io.write_int(SynthCallArgNumber, !IO)
;
Data = module_layout_event_synth_order(ModuleName, EventNumber),
io.write_string(mercury_data_prefix, !IO),
io.write_string("_module_layout_event_synth_order__", !IO),
ModuleNameStr = sym_name_mangle(ModuleName),
io.write_string(ModuleNameStr, !IO),
io.write_string("_", !IO),
io.write_int(EventNumber, !IO)
;
Data = module_layout_event_specs(ModuleName),
io.write_string(mercury_data_prefix, !IO),
io.write_string("_module_layout_event_specs__", !IO),
ModuleNameStr = sym_name_mangle(ModuleName),
io.write_string(ModuleNameStr, !IO)
;
Data = module_common_layout(ModuleName),
io.write_string(mercury_data_prefix, !IO),
io.write_string("_module_common_layout__", !IO),
ModuleNameStr = sym_name_mangle(ModuleName),
io.write_string(ModuleNameStr, !IO)
;
Data = module_layout(ModuleName),
io.write_string(mercury_data_prefix, !IO),
io.write_string("_module_layout__", !IO),
ModuleNameStr = sym_name_mangle(ModuleName),
io.write_string(ModuleNameStr, !IO)
;
Data = proc_static(RttiProcLabel),
io.write_string(mercury_data_prefix, !IO),
io.write_string("_proc_static__", !IO),
ProcLabel = make_proc_label_from_rtti(RttiProcLabel),
output_proc_label_no_prefix(ProcLabel, !IO)
;
Data = proc_static_call_sites(RttiProcLabel),
io.write_string(mercury_data_prefix, !IO),
io.write_string("_proc_static_call_sites__", !IO),
ProcLabel = make_proc_label_from_rtti(RttiProcLabel),
output_proc_label_no_prefix(ProcLabel, !IO)
;
Data = table_io_decl(RttiProcLabel),
io.write_string(mercury_data_prefix, !IO),
io.write_string("_table_io_decl__", !IO),
ProcLabel = make_proc_label_from_rtti(RttiProcLabel),
output_proc_label_no_prefix(ProcLabel, !IO)
).
output_layout_name_storage_type_name(Name, BeingDefined, !IO) :-
(
Name = label_layout(_ProcLabel, _LabelNum, LabelVars),
io.write_string("static const ", !IO),
io.write_string(label_vars_to_type(LabelVars), !IO),
io.write_string(" ", !IO),
output_layout_name(Name, !IO)
;
Name = user_event_layout(_ProcLabel, _LabelNum),
io.write_string("static const struct MR_UserEvent_Struct ", !IO),
output_layout_name(Name, !IO)
;
Name = user_event_attr_var_nums(_ProcLabel, _LabelNum),
io.write_string("static const MR_HLDSVarNum ", !IO),
output_layout_name(Name, !IO),
io.write_string("[]", !IO)
;
Name = proc_layout(ProcLabel, Kind),
ProcIsImported = ProcLabel ^ proc_is_imported,
ProcIsExported = ProcLabel ^ proc_is_exported,
(
ProcIsImported = no,
ProcIsExported = no
->
io.write_string("static ", !IO)
;
(
BeingDefined = yes
;
BeingDefined = no,
io.write_string("extern ", !IO)
)
),
io.write_string("const ", !IO),
io.write_string(proc_layout_kind_to_type(Kind), !IO),
io.write_string(" ", !IO),
output_layout_name(Name, !IO)
;
Name = proc_layout_exec_trace(_ProcLabel),
io.write_string("static MR_STATIC_CODE_CONST MR_ExecTrace\n\t", !IO),
output_layout_name(Name, !IO)
;
Name = proc_layout_label_layouts(_ProcLabel),
io.write_string("static const MR_LabelLayout *", !IO),
output_layout_name(Name, !IO),
io.write_string("[]", !IO)
;
Name = proc_layout_head_var_nums(_ProcLabel),
io.write_string("static const ", !IO),
io.write_string("MR_uint_least16_t ", !IO),
output_layout_name(Name, !IO),
io.write_string("[]", !IO)
;
Name = proc_layout_var_names(_ProcLabel),
io.write_string("static const ", !IO),
io.write_string("MR_uint_least32_t ", !IO),
output_layout_name(Name, !IO),
io.write_string("[]", !IO)
;
Name = proc_layout_body_bytecode(_ProcLabel),
io.write_string("static const ", !IO),
io.write_string("MR_uint_least8_t ", !IO),
output_layout_name(Name, !IO),
io.write_string("[]", !IO)
;
Name = closure_proc_id(_CallerProcLabel, _SeqNo, ClosureProcLabel),
io.write_string("static const ", !IO),
(
ClosureProcLabel = ordinary_proc_label(_, _, _, _, _, _),
io.write_string("MR_UserClosureId\n", !IO)
;
ClosureProcLabel = special_proc_label(_, _, _, _, _, _),
io.write_string("MR_UCIClosureId\n", !IO)
),
output_layout_name(Name, !IO)
;
Name = file_layout(_ModuleName, _FileNum),
io.write_string("static const MR_ModuleFileLayout ", !IO),
output_layout_name(Name, !IO)
;
Name = file_layout_line_number_vector(_ModuleName, _FileNum),
io.write_string("static const MR_int_least16_t ", !IO),
output_layout_name(Name, !IO),
io.write_string("[]", !IO)
;
Name = file_layout_label_layout_vector(_ModuleName, _FileNum),
io.write_string("static const MR_LabelLayout *", !IO),
output_layout_name(Name, !IO),
io.write_string("[]", !IO)
;
Name = module_layout_string_table(_ModuleName),
io.write_string("static const char ", !IO),
output_layout_name(Name, !IO),
io.write_string("[]", !IO)
;
Name = module_layout_file_vector(_ModuleName),
io.write_string("static const MR_ModuleFileLayout *", !IO),
output_layout_name(Name, !IO),
io.write_string("[]", !IO)
;
Name = module_layout_label_exec_count(_ModuleName, NumElements),
io.write_string("static MR_Unsigned ", !IO),
output_layout_name(Name, !IO),
io.write_string("[", !IO),
io.write_int(NumElements, !IO),
io.write_string("]", !IO)
;
Name = module_layout_proc_vector(_ModuleName),
io.write_string("static const MR_ProcLayout *", !IO),
output_layout_name(Name, !IO),
io.write_string("[]", !IO)
;
Name = module_layout_event_set_desc(_ModuleName),
io.write_string("static const char ", !IO),
output_layout_name(Name, !IO),
io.write_string("[]", !IO)
;
Name = module_layout_event_arg_names(_ModuleName, _EventNumber),
io.write_string("static const char * ", !IO),
output_layout_name(Name, !IO),
io.write_string("[]", !IO)
;
Name = module_layout_event_synth_attrs(_ModuleName, _EventNumber),
io.write_string("static MR_SynthAttr ", !IO),
output_layout_name(Name, !IO),
io.write_string("[]", !IO)
;
Name = module_layout_event_synth_attr_args(_ModuleName,
_EventNumber, _SynthCallArgNumber),
io.write_string("static MR_uint_least16_t ", !IO),
output_layout_name(Name, !IO),
io.write_string("[]", !IO)
;
Name = module_layout_event_synth_attr_order(_ModuleName,
_EventNumber, _SynthCallArgNumber),
io.write_string("static MR_uint_least16_t ", !IO),
output_layout_name(Name, !IO),
io.write_string("[]", !IO)
;
Name = module_layout_event_synth_order(_ModuleName, _EventNumber),
io.write_string("static MR_int_least16_t ", !IO),
output_layout_name(Name, !IO),
io.write_string("[]", !IO)
;
Name = module_layout_event_specs(_ModuleName),
io.write_string("static MR_UserEventSpec ", !IO),
output_layout_name(Name, !IO),
io.write_string("[]", !IO)
;
Name = module_common_layout(_ModuleName),
io.write_string("static const MR_ModuleCommonLayout ", !IO),
output_layout_name(Name, !IO)
;
Name = module_layout(_ModuleName),
io.write_string("static const MR_ModuleLayout ", !IO),
output_layout_name(Name, !IO)
;
Name = proc_static(_RttiProcLabel),
io.write_string("static MR_ProcStatic ", !IO),
output_layout_name(Name, !IO)
;
Name = proc_static_call_sites(_RttiProcLabel),
io.write_string("static const MR_CallSiteStatic ", !IO),
output_layout_name(Name, !IO),
io.write_string("[]", !IO)
;
Name = table_io_decl(_RttiProcLabel),
io.write_string("static const MR_TableIoDecl ", !IO),
output_layout_name(Name, !IO)
).
layout_name_would_include_code_addr(label_layout(_, _, _)) = no.
layout_name_would_include_code_addr(user_event_layout(_, _)) = no.
layout_name_would_include_code_addr(user_event_attr_var_nums(_, _)) = no.
layout_name_would_include_code_addr(proc_layout(_, _)) = no.
layout_name_would_include_code_addr(proc_layout_exec_trace(_)) = yes.
layout_name_would_include_code_addr(proc_layout_label_layouts(_)) = no.
layout_name_would_include_code_addr(proc_layout_head_var_nums(_)) = no.
layout_name_would_include_code_addr(proc_layout_var_names(_)) = no.
layout_name_would_include_code_addr(proc_layout_body_bytecode(_)) = no.
layout_name_would_include_code_addr(closure_proc_id(_, _, _)) = no.
layout_name_would_include_code_addr(file_layout(_, _)) = no.
layout_name_would_include_code_addr(file_layout_line_number_vector(_, _)) = no.
layout_name_would_include_code_addr(file_layout_label_layout_vector(_, _))
= no.
layout_name_would_include_code_addr(module_layout_string_table(_)) = no.
layout_name_would_include_code_addr(module_layout_file_vector(_)) = no.
layout_name_would_include_code_addr(module_layout_proc_vector(_)) = no.
layout_name_would_include_code_addr(module_layout_label_exec_count(_, _)) = no.
layout_name_would_include_code_addr(module_layout_event_set_desc(_)) = no.
layout_name_would_include_code_addr(module_layout_event_arg_names(_, _)) = no.
layout_name_would_include_code_addr(module_layout_event_synth_attrs(_, _))
= no.
layout_name_would_include_code_addr(
module_layout_event_synth_attr_args(_, _, _)) = no.
layout_name_would_include_code_addr(
module_layout_event_synth_attr_order(_, _, _)) = no.
layout_name_would_include_code_addr(module_layout_event_synth_order(_, _))
= no.
layout_name_would_include_code_addr(module_layout_event_specs(_)) = no.
layout_name_would_include_code_addr(module_common_layout(_)) = no.
layout_name_would_include_code_addr(module_layout(_)) = no.
layout_name_would_include_code_addr(proc_static(_)) = no.
layout_name_would_include_code_addr(proc_static_call_sites(_)) = no.
layout_name_would_include_code_addr(table_io_decl(_)) = no.
:- func label_vars_to_type(label_vars) = string.
label_vars_to_type(label_has_var_info) = "MR_LabelLayout".
label_vars_to_type(label_has_no_var_info) = "MR_LabelLayoutNoVarInfo".
:- 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".
%-----------------------------------------------------------------------------%
:- type rval_or_numpair_or_none
---> kind_rval(rval)
; kind_num_pair(type_num, int)
; kind_none.
:- pred output_rval_or_numpair_or_none(rval_or_numpair_or_none::in,
io::di, io::uo) is det.
output_rval_or_numpair_or_none(kind_rval(Rval), !IO) :-
io.write_string(", ", !IO),
output_rval_as_addr(Rval, !IO).
output_rval_or_numpair_or_none(kind_num_pair(type_num(Num1), Num2), !IO) :-
io.write_string(", ", !IO),
io.write_int(Num1, !IO),
io.write_string(", ", !IO),
io.write_int(Num2, !IO).
output_rval_or_numpair_or_none(kind_none, !IO).
:- pred output_label_layout_data_defn(proc_label::in, int::in, layout_name::in,
maybe(trace_port)::in, maybe(bool)::in, int::in, maybe(int)::in,
maybe(user_event_data)::in, maybe(label_var_info)::in,
decl_set::in, decl_set::out, io::di, io::uo) is det.
output_label_layout_data_defn(ProcLabel, LabelNum, ProcLayoutAddr, MaybePort,
MaybeIsHidden, LabelNumberInModule, MaybeGoalPath, MaybeUserData,
MaybeVarInfo, !DeclSet, !IO) :-
output_layout_decl(ProcLayoutAddr, !DeclSet, !IO),
(
MaybeUserData = no,
UserChars = ""
;
MaybeUserData = yes(UserData),
UserChars = "_U",
UserData = user_event_data(UserEventNumber, UserLocnsRval,
UserAttrMaybeVarNums),
AttrVarNumsLayoutName = user_event_attr_var_nums(ProcLabel, LabelNum),
AttrVarNumsDataAddr = layout_addr(AttrVarNumsLayoutName),
decl_set_insert(decl_data_addr(AttrVarNumsDataAddr), !DeclSet),
output_layout_name_storage_type_name(AttrVarNumsLayoutName, no, !IO),
io.write_string(" = {\n", !IO),
io.write_list(UserAttrMaybeVarNums, ", ", output_maybe_var_num, !IO),
io.write_string("\n};\n\n", !IO),
UserLayoutName = user_event_layout(ProcLabel, LabelNum),
UserDataAddr = layout_addr(UserLayoutName),
decl_set_insert(decl_data_addr(UserDataAddr), !DeclSet),
output_layout_name_storage_type_name(UserLayoutName, no, !IO),
io.write_string(" = {\n", !IO),
io.write_int(UserEventNumber, !IO),
io.write_string(",\n(MR_LongLval *) ", !IO),
output_rval_as_addr(UserLocnsRval, !IO),
io.write_string(",\n", !IO),
output_layout_name(AttrVarNumsLayoutName, !IO),
io.write_string("\n};\n\n", !IO)
),
(
MaybeIsHidden = yes(yes),
HiddenChars = "T"
;
MaybeIsHidden = yes(no),
HiddenChars = ""
;
MaybeIsHidden = no,
% The value of the hidden field shouldn't matter here.
HiddenChars = ""
),
(
MaybeVarInfo = yes(VarInfo0),
VarInfo0 = label_var_info(EncodedVarCount1, LocnsTypes0, VarNums0,
TypeParams0),
output_rval_decls(LocnsTypes0, !DeclSet, !IO),
output_rval_decls(VarNums0, !DeclSet, !IO),
output_rval_decls(TypeParams0, !DeclSet, !IO),
LabelVars = label_has_var_info,
(
LocnsTypes0 = const(llconst_data_addr(LTDataAddr, no)),
LTDataAddr = data_addr(_, scalar_common_ref(LTTypeNum, LTCellNum)),
VarNums0 = const(llconst_data_addr(VNDataAddr, no)),
VNDataAddr = data_addr(_, scalar_common_ref(VNTypeNum, VNCellNum))
->
(
TypeParams0 = const(llconst_data_addr(TPDataAddr, no)),
TPDataAddr = data_addr(_,
scalar_common_ref(TPTypeNum, TPCellNum))
->
CommonChars = "XCCC",
LocnsTypes1 = kind_num_pair(LTTypeNum, LTCellNum),
VarNums1 = kind_num_pair(VNTypeNum, VNCellNum),
TypeParams1 = kind_num_pair(TPTypeNum, TPCellNum)
;
TypeParams0 = const(llconst_int(0))
->
CommonChars = "XCC0",
LocnsTypes1 = kind_num_pair(LTTypeNum, LTCellNum),
VarNums1 = kind_num_pair(VNTypeNum, VNCellNum),
TypeParams1 = kind_none
;
CommonChars = "",
LocnsTypes1 = kind_rval(LocnsTypes0),
VarNums1 = kind_rval(VarNums0),
TypeParams1 = kind_rval(TypeParams0)
)
;
CommonChars = "",
LocnsTypes1 = kind_rval(LocnsTypes0),
VarNums1 = kind_rval(VarNums0),
TypeParams1 = kind_rval(TypeParams0)
),
Macro0 = "MR_DEF_LL" ++ HiddenChars ++ CommonChars,
MaybeVarInfoTuple = yes({EncodedVarCount1, LocnsTypes1, VarNums1,
TypeParams1})
;
MaybeVarInfo = no,
LabelVars = label_has_no_var_info,
Macro0 = "MR_DEF_LLNVI" ++ HiddenChars,
MaybeVarInfoTuple = no
),
Macro = Macro0 ++ UserChars,
LayoutName = label_layout(ProcLabel, LabelNum, LabelVars),
io.write_string("\n", !IO),
io.write_string(Macro, !IO),
io.write_string("(", !IO),
output_proc_label_no_prefix(ProcLabel, !IO),
io.write_string(",\n", !IO),
io.write_int(LabelNum, !IO),
io.write_string(", ", !IO),
(
MaybePort = yes(Port),
io.write_string(trace_port_to_string(Port), !IO)
;
MaybePort = no,
io.write_string("NONE", !IO)
),
io.write_string(", ", !IO),
io.write_int(LabelNumberInModule, !IO),
io.write_string(", ", !IO),
(
MaybeGoalPath = yes(GoalPath),
io.write_int(GoalPath, !IO)
;
MaybeGoalPath = no,
io.write_string("0", !IO)
),
(
MaybeVarInfoTuple = yes({EncodedVarCount,
LocnsTypes, VarNums, TypeParams}),
io.write_string(", ", !IO),
io.write_int(EncodedVarCount, !IO),
output_rval_or_numpair_or_none(LocnsTypes, !IO),
output_rval_or_numpair_or_none(VarNums, !IO),
output_rval_or_numpair_or_none(TypeParams, !IO)
;
MaybeVarInfoTuple = no
),
io.write_string(");\n", !IO),
decl_set_insert(decl_data_addr(layout_addr(LayoutName)), !DeclSet).
:- pred output_maybe_var_num(maybe(int)::in, io::di, io::uo) is det.
output_maybe_var_num(no, !IO) :-
% Zero means not a variable, which is what we want.
io.write_int(0, !IO).
output_maybe_var_num(yes(VarNum), !IO) :-
io.write_int(VarNum, !IO).
% Output the rval in a context in which it is immediately cast to an
% address.
%
:- pred output_rval_as_addr(rval::in, io::di, io::uo) is det.
output_rval_as_addr(Rval, !IO) :-
( Rval = const(llconst_int(0)) ->
io.write_string(" 0", !IO)
; Rval = const(llconst_data_addr(DataAddr, no)) ->
( DataAddr = data_addr(_, scalar_common_ref(_TypeNum, _CellNum)) ->
output_data_addr(DataAddr, !IO)
;
io.write_string("&", !IO),
output_data_addr(DataAddr, !IO)
)
;
io.write_string("\n", !IO),
output_rval(Rval, !IO)
).
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_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_nondet_foreign_proc_first) = "FOREIGN_PROC_FIRST".
trace_port_to_string(port_nondet_foreign_proc_later) = "FOREIGN_PROC_LATER".
trace_port_to_string(port_user) = "USER".
%-----------------------------------------------------------------------------%
:- pred output_proc_layout_data_defn(rtti_proc_label::in,
proc_layout_stack_traversal::in, maybe_proc_id_and_more::in,
decl_set::in, decl_set::out, io::di, io::uo) is det.
output_proc_layout_data_defn(RttiProcLabel, Traversal, MaybeRest,
!DeclSet, !IO) :-
output_layout_traversal_decls(Traversal, !DeclSet, !IO),
ProcLabel = make_proc_label_from_rtti(RttiProcLabel),
Kind = maybe_proc_layout_and_more_kind(MaybeRest, ProcLabel),
(
MaybeRest = no_proc_id_and_more,
output_proc_layout_data_defn_start(RttiProcLabel, Kind, Traversal,
!IO),
output_layout_no_proc_id_group(!IO),
output_proc_layout_data_defn_end(!IO)
;
MaybeRest = proc_id_and_more(MaybeProcStatic, MaybeExecTrace,
ProcBodyBytes, ModuleCommonLayout),
(
MaybeProcStatic = yes(ProcStatic),
output_proc_static_data_defn(RttiProcLabel, ProcStatic, !DeclSet,
!IO)
;
MaybeProcStatic = no
),
(
MaybeExecTrace = yes(ExecTrace),
HeadVarNums = ExecTrace ^ head_var_nums,
output_proc_layout_head_var_nums(RttiProcLabel, HeadVarNums,
!DeclSet, !IO),
VarNames = ExecTrace ^ var_names,
MaxVarNum = ExecTrace ^ max_var_num,
output_proc_layout_var_names(RttiProcLabel, VarNames, MaxVarNum,
!DeclSet, !IO),
output_layout_exec_trace_decls(RttiProcLabel, ExecTrace,
!DeclSet, !IO),
output_layout_exec_trace(RttiProcLabel, ExecTrace, !DeclSet, !IO)
;
MaybeExecTrace = no
),
(
ProcBodyBytes = []
;
ProcBodyBytes = [_ | _],
io.write_string("\n", !IO),
output_layout_name_storage_type_name(
proc_layout_body_bytecode(RttiProcLabel), yes, !IO),
io.write_string(" = {\n", !IO),
output_bytecodes_driver(ProcBodyBytes, !IO),
io.write_string("};\n\n", !IO)
),
output_layout_decl(ModuleCommonLayout, !DeclSet, !IO),
output_proc_layout_data_defn_start(RttiProcLabel, Kind, Traversal,
!IO),
Origin = RttiProcLabel ^ pred_info_origin,
output_layout_proc_id_group(ProcLabel, Origin, !IO),
(
MaybeExecTrace = no,
io.write_string("NULL,\n", !IO)
;
MaybeExecTrace = yes(_),
io.write_string("&", !IO),
output_layout_name(proc_layout_exec_trace(RttiProcLabel), !IO),
io.write_string(",\n", !IO)
),
(
MaybeProcStatic = no,
io.write_string("NULL,\n", !IO)
;
MaybeProcStatic = yes(_),
io.write_string("&", !IO),
output_layout_name(proc_static(RttiProcLabel), !IO),
io.write_string(",\n", !IO)
),
(
ProcBodyBytes = [],
io.write_string("NULL,\n", !IO)
;
ProcBodyBytes = [_ | _],
output_layout_name(proc_layout_body_bytecode(RttiProcLabel), !IO),
io.write_string(",\n", !IO)
),
io.write_string("&", !IO),
output_layout_name(ModuleCommonLayout, !IO),
output_proc_layout_data_defn_end(!IO)
),
DeclId = decl_data_addr(layout_addr(proc_layout(RttiProcLabel, Kind))),
decl_set_insert(DeclId, !DeclSet).
:- func maybe_proc_layout_and_more_kind(maybe_proc_id_and_more,
proc_label) = proc_layout_kind.
maybe_proc_layout_and_more_kind(MaybeRest, ProcLabel) = Kind :-
(
MaybeRest = no_proc_id_and_more,
Kind = proc_layout_traversal
;
MaybeRest = proc_id_and_more(_, _, _, _),
Kind = proc_layout_proc_id(proc_label_user_or_uci(ProcLabel))
).
proc_label_user_or_uci(ordinary_proc_label(_, _, _, _, _, _)) = user.
proc_label_user_or_uci(special_proc_label(_, _, _, _, _, _)) = uci.
:- pred output_proc_layout_data_defn_start(rtti_proc_label::in,
proc_layout_kind::in, proc_layout_stack_traversal::in,
io::di, io::uo) is det.
output_proc_layout_data_defn_start(RttiProcLabel, Kind, Traversal, !IO) :-
io.write_string("\n", !IO),
output_layout_name_storage_type_name(proc_layout(RttiProcLabel, Kind),
yes, !IO),
io.write_string(" = {\n", !IO),
output_layout_traversal_group(Traversal, !IO).
:- pred output_proc_layout_data_defn_end(io::di, io::uo) is det.
output_proc_layout_data_defn_end(!IO) :-
io.write_string("};\n", !IO).
:- pred output_layout_traversal_decls(proc_layout_stack_traversal::in,
decl_set::in, decl_set::out, io::di, io::uo) is det.
output_layout_traversal_decls(Traversal, !DeclSet, !IO) :-
Traversal = proc_layout_stack_traversal(MaybeEntryLabel, _MaybeSuccipSlot,
_StackSlotCount, _Detism),
(
MaybeEntryLabel = yes(EntryLabel),
output_code_addr_decls(code_label(EntryLabel), !DeclSet, !IO)
;
MaybeEntryLabel = no
).
:- pred output_layout_traversal_group(proc_layout_stack_traversal::in,
io::di, io::uo) is det.
output_layout_traversal_group(Traversal, !IO) :-
Traversal = proc_layout_stack_traversal(MaybeEntryLabel, MaybeSuccipSlot,
StackSlotCount, Detism),
io.write_string("{\n", !IO),
(
MaybeEntryLabel = yes(EntryLabel),
output_code_addr(code_label(EntryLabel), !IO)
;
MaybeEntryLabel = no,
% The actual code address will be put into the structure
% by module initialization code.
io.write_string("NULL", !IO)
),
io.write_string(",\n{ ", !IO),
(
MaybeSuccipSlot = yes(SuccipSlot),
io.write_int(SuccipSlot, !IO)
;
MaybeSuccipSlot = no,
io.write_int(-1, !IO)
),
io.write_string(" },\n", !IO),
io.write_int(StackSlotCount, !IO),
io.write_string(",\n", !IO),
io.write_string(detism_to_c_detism(Detism), !IO),
io.write_string("\n},\n", !IO).
:- 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".
:- pred output_layout_proc_id_group(proc_label::in, pred_origin::in,
io::di, io::uo) is det.
output_layout_proc_id_group(ProcLabel, Origin, !IO) :-
io.write_string("{\n", !IO),
output_proc_id(ProcLabel, Origin, !IO),
io.write_string("},\n", !IO).
:- pred output_layout_no_proc_id_group(io::di, io::uo) is det.
output_layout_no_proc_id_group(!IO) :-
io.write_string("-1\n", !IO).
:- pred output_layout_exec_trace_decls(rtti_proc_label::in,
proc_layout_exec_trace::in, decl_set::in, decl_set::out,
io::di, io::uo) is det.
output_layout_exec_trace_decls(RttiProcLabel, ExecTrace, !DeclSet, !IO) :-
ExecTrace = proc_layout_exec_trace(MaybeCallLabelLayout,
EventDataAddrs, MaybeTableInfo, _HeadVarNums, _VarNames, _MaxVarNum,
_MaxRegNum, _MaybeFromFullSlot, _MaybeIoSeqSlot,
_MaybeTrailSlot, _MaybeMaxfrSlot, _EvalMethod,
_MaybeCallTableSlot, _EffTraceLevel, _Flags),
ProcLabel = make_proc_label_from_rtti(RttiProcLabel),
ModuleName = get_defining_module_name(ProcLabel),
output_label_layout_addrs_in_vector(EventDataAddrs, "MR_DECL_LABEL_LAYOUT",
!IO),
EventDataDeclIds = list.map(wrap_decl_data_addr, EventDataAddrs),
list.foldl(decl_set_insert, EventDataDeclIds, !DeclSet),
(
MaybeCallLabelLayout = yes(CallLabelDetails),
CallLabelDetails = label_layout_details(CallProcLabel, LabelNum,
LabelVars),
CallLabelLayout = label_layout(CallProcLabel, LabelNum, LabelVars),
output_layout_decl(CallLabelLayout, !DeclSet, !IO)
;
MaybeCallLabelLayout = no
),
output_layout_decl(module_layout(ModuleName), !DeclSet, !IO),
(
MaybeTableInfo = yes(TableInfo),
output_data_addr_decls(TableInfo, !DeclSet, !IO)
;
MaybeTableInfo = no
).
:- func wrap_decl_data_addr(data_addr) = decl_id.
wrap_decl_data_addr(DataAddr) = decl_data_addr(DataAddr).
% 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(list(int)::in, io::di, io::uo) is det.
output_bytecodes_driver(Bytes, !IO) :-
(
Bytes = []
;
Bytes = [_ | _],
output_bytecodes(Bytes, BytesLeft, 0, 256, !IO),
output_bytecodes_driver(BytesLeft, !IO)
).
:- pred output_bytecodes(list(int)::in, list(int)::out, int::in, int::in,
io::di, io::uo) is det.
output_bytecodes(Bytes, BytesLeft, !.Seq, MaxSeq, !IO) :-
(
Bytes = [],
BytesLeft = []
;
Bytes = [Head | Tail],
( !.Seq < MaxSeq ->
io.write_int(Head, !IO),
io.write_char(',', !IO),
!:Seq = !.Seq + 1,
( unchecked_rem(!.Seq, 16) = 0 ->
io.write_char('\n', !IO)
;
true
),
output_bytecodes(Tail, BytesLeft, !.Seq, MaxSeq, !IO)
;
BytesLeft = Bytes
)
).
:- pred output_layout_exec_trace(rtti_proc_label::in,
proc_layout_exec_trace::in, decl_set::in, decl_set::out,
io::di, io::uo) is det.
output_layout_exec_trace(RttiProcLabel, ExecTrace, !DeclSet, !IO) :-
ExecTrace = proc_layout_exec_trace(MaybeCallLabelDetails,
EventDataAddrs, MaybeTableInfo, HeadVarNums, _VarNames, MaxVarNum,
MaxRegNum, MaybeFromFullSlot, MaybeIoSeqSlot, MaybeTrailSlot,
MaybeMaxfrSlot, EvalMethod, MaybeCallTableSlot, EffTraceLevel, Flags),
(
EventDataAddrs = []
;
EventDataAddrs = [_ | _],
io.write_string("\n", !IO),
output_layout_name_storage_type_name(
proc_layout_label_layouts(RttiProcLabel), yes, !IO),
io.write_string(" = {\n", !IO),
output_label_layout_addrs_in_vector(EventDataAddrs, "MR_LABEL_LAYOUT",
!IO),
io.write_string("};\n\n", !IO)
),
output_layout_name_storage_type_name(
proc_layout_exec_trace(RttiProcLabel), yes, !IO),
io.write_string(" = {\n", !IO),
(
MaybeCallLabelDetails = yes(CallLabelDetails),
io.write_string("MR_LABEL_LAYOUT_REF(", !IO),
CallLabelDetails = label_layout_details(CallProcLabel, CallLabelNum,
_),
output_label(internal_label(CallLabelNum, CallProcLabel), no, !IO),
io.write_string("),\n", !IO)
;
MaybeCallLabelDetails = no,
io.write_string("NULL,\n", !IO)
),
io.write_string("(const MR_ModuleLayout *) &", !IO),
ProcLabel = make_proc_label_from_rtti(RttiProcLabel),
ModuleName = get_defining_module_name(ProcLabel),
output_layout_name(module_layout(ModuleName), !IO),
io.write_string(",\n", !IO),
(
EventDataAddrs = [],
io.write_string("NULL,\n", !IO)
;
EventDataAddrs = [_ | _],
output_layout_name(proc_layout_label_layouts(RttiProcLabel), !IO),
io.write_string(",\n", !IO)
),
list.length(EventDataAddrs, NumEventDataAddrs),
io.write_int(NumEventDataAddrs, !IO),
io.write_string(",\n", !IO),
io.write_string("{ ", !IO),
(
MaybeTableInfo = yes(TableInfo),
io.write_string("(const void *) &", !IO),
output_data_addr(TableInfo, !IO)
;
MaybeTableInfo = no,
io.write_string("NULL", !IO)
),
io.write_string(" },\n", !IO),
output_layout_name(proc_layout_head_var_nums(RttiProcLabel), !IO),
io.write_string(",\n", !IO),
output_layout_name(proc_layout_var_names(RttiProcLabel), !IO),
io.write_string(",\n", !IO),
io.write_int(list.length(HeadVarNums), !IO),
io.write_string(",\n", !IO),
io.write_int(MaxVarNum, !IO),
io.write_string(",\n", !IO),
io.write_int(MaxRegNum, !IO),
io.write_string(",\n", !IO),
write_maybe_slot_num(MaybeFromFullSlot, !IO),
io.write_string(",\n", !IO),
write_maybe_slot_num(MaybeIoSeqSlot, !IO),
io.write_string(",\n", !IO),
write_maybe_slot_num(MaybeTrailSlot, !IO),
io.write_string(",\n", !IO),
write_maybe_slot_num(MaybeMaxfrSlot, !IO),
io.write_string(",\n", !IO),
io.write_string(eval_method_to_c_string(EvalMethod), !IO),
io.write_string(",\n", !IO),
write_maybe_slot_num(MaybeCallTableSlot, !IO),
io.write_string(",\n", !IO),
io.write_string(trace_level_rep(EffTraceLevel), !IO),
io.write_string(",\n", !IO),
io.write_int(Flags, !IO),
io.write_string("\n};\n", !IO).
:- pred write_maybe_slot_num(maybe(int)::in, io::di, io::uo) is det.
write_maybe_slot_num(yes(SlotNum), !IO) :-
io.write_int(SlotNum, !IO).
write_maybe_slot_num(no, !IO) :-
io.write_int(-1, !IO).
:- func eval_method_to_c_string(eval_method) = string.
eval_method_to_c_string(eval_normal) = "MR_EVAL_METHOD_NORMAL".
eval_method_to_c_string(eval_loop_check) = "MR_EVAL_METHOD_LOOP_CHECK".
eval_method_to_c_string(eval_memo) = "MR_EVAL_METHOD_MEMO".
eval_method_to_c_string(eval_minimal(MinimalMethod)) = Str :-
(
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"
).
eval_method_to_c_string(eval_table_io(Decl, Unitize)) = Str :-
(
Decl = table_io_proc,
Unitize = table_io_alone,
Str = "MR_EVAL_METHOD_TABLE_IO"
;
Decl = table_io_proc,
Unitize = table_io_unitize,
Str = "MR_EVAL_METHOD_TABLE_IO_UNITIZE"
;
Decl = table_io_decl,
Unitize = table_io_alone,
Str = "MR_EVAL_METHOD_TABLE_IO_DECL"
;
Decl = table_io_decl,
Unitize = table_io_unitize,
Str = "MR_EVAL_METHOD_TABLE_IO_UNITIZE_DECL"
).
:- pred output_proc_layout_head_var_nums(rtti_proc_label::in, list(int)::in,
decl_set::in, decl_set::out, io::di, io::uo) is det.
output_proc_layout_head_var_nums(ProcLabel, HeadVarNums, !DeclSet, !IO) :-
io.write_string("\n", !IO),
output_layout_name_storage_type_name(proc_layout_head_var_nums(ProcLabel),
yes, !IO),
io.write_string(" = {\n", !IO),
(
HeadVarNums = [],
% ANSI/ISO C doesn't allow empty arrays, so place a dummy value
% in the array.
io.write_string("0\n", !IO)
;
HeadVarNums = [_ | _],
list.foldl(output_number_in_vector, HeadVarNums, !IO)
),
io.write_string("};\n", !IO),
DeclId = decl_data_addr(layout_addr(proc_layout_head_var_nums(ProcLabel))),
decl_set_insert(DeclId, !DeclSet).
:- pred output_proc_layout_var_names(rtti_proc_label::in, list(int)::in,
int::in, decl_set::in, decl_set::out, io::di, io::uo) is det.
output_proc_layout_var_names(ProcLabel, VarNames, MaxVarNum, !DeclSet, !IO) :-
list.length(VarNames, VarNameCount),
expect(unify(VarNameCount, MaxVarNum), this_file,
"output_proc_layout_var_names: VarNameCount != MaxVarNum"),
io.write_string("\n", !IO),
output_layout_name_storage_type_name(proc_layout_var_names(ProcLabel), yes,
!IO),
io.write_string(" = {\n", !IO),
(
VarNames = [],
% ANSI/ISO C doesn't allow empty arrays, so place a dummy value
% in the array.
io.write_string("0\n", !IO)
;
VarNames = [_ | _],
list.foldl(output_number_in_vector, VarNames, !IO)
),
io.write_string("};\n", !IO),
DeclId = decl_data_addr(layout_addr(proc_layout_var_names(ProcLabel))),
decl_set_insert(DeclId, !DeclSet).
%-----------------------------------------------------------------------------%
:- pred output_closure_proc_id_data_defn(proc_label::in, int::in,
proc_label::in, module_name::in, string::in, int::in, pred_origin::in,
string::in, decl_set::in, decl_set::out, io::di, io::uo) is det.
output_closure_proc_id_data_defn(CallerProcLabel, SeqNo, ClosureProcLabel,
ModuleName, FileName, LineNumber, PredOrigin, GoalPath,
!DeclSet, !IO) :-
io.write_string("\n", !IO),
LayoutName = closure_proc_id(CallerProcLabel, SeqNo, ClosureProcLabel),
output_layout_name_storage_type_name(LayoutName, yes, !IO),
io.write_string(" = {\n{\n", !IO),
output_proc_id(ClosureProcLabel, PredOrigin, !IO),
io.write_string("},\n", !IO),
quote_and_write_string(sym_name_to_string(ModuleName), !IO),
io.write_string(",\n", !IO),
quote_and_write_string(FileName, !IO),
io.write_string(",\n", !IO),
io.write_int(LineNumber, !IO),
io.write_string(",\n", !IO),
quote_and_write_string(GoalPath, !IO),
io.write_string("\n};\n", !IO),
decl_set_insert(decl_data_addr(layout_addr(LayoutName)), !DeclSet).
:- pred output_proc_id(proc_label::in, pred_origin::in, io::di, io::uo) is det.
output_proc_id(ProcLabel, Origin, !IO) :-
(
ProcLabel = ordinary_proc_label(DefiningModule, PredOrFunc,
DeclaringModule, PredName0, Arity, Mode),
PredName = origin_name(Origin, PredName0),
output_pred_or_func(PredOrFunc, !IO),
io.write_string(",\n", !IO),
quote_and_write_string(sym_name_to_string(DeclaringModule), !IO),
io.write_string(",\n", !IO),
quote_and_write_string(sym_name_to_string(DefiningModule), !IO),
io.write_string(",\n", !IO),
quote_and_write_string(PredName, !IO),
io.write_string(",\n", !IO),
io.write_int(Arity, !IO),
io.write_string(",\n", !IO),
io.write_int(Mode, !IO),
io.write_string("\n", !IO)
;
ProcLabel = special_proc_label(DefiningModule, SpecialPredId,
TypeModule, TypeName, TypeArity, Mode),
TypeCtor = type_ctor(qualified(TypeModule, TypeName), TypeArity),
PredName0 = special_pred_name(SpecialPredId, TypeCtor),
PredName = origin_name(Origin, PredName0),
quote_and_write_string(TypeName, !IO),
io.write_string(",\n", !IO),
quote_and_write_string(sym_name_to_string(TypeModule), !IO),
io.write_string(",\n", !IO),
quote_and_write_string(sym_name_to_string(DefiningModule), !IO),
io.write_string(",\n", !IO),
quote_and_write_string(PredName, !IO),
io.write_string(",\n", !IO),
io.write_int(TypeArity, !IO),
io.write_string(",\n", !IO),
io.write_int(Mode, !IO),
io.write_string("\n", !IO)
).
:- func origin_name(pred_origin, string) = string.
origin_name(Origin, Name0) = Name :-
(
Origin = origin_lambda(FileName0, LineNum, SeqNo),
( string.append("IntroducedFrom", _, Name0) ->
string.replace_all(FileName0, ".", "_", FileName),
( SeqNo > 1 ->
string.format("lambda%d_%s_%d",
[i(SeqNo), s(FileName), i(LineNum)], Name)
;
string.format("lambda_%s_%d", [s(FileName), i(LineNum)], Name)
)
;
% If the lambda pred has a meaningful name, use it.
% This happens when the lambda is a partial application
% that happens to supply zero arguments.
Name = Name0
)
;
Origin = origin_special_pred(_SpecialPredId - _TypeCtor),
Name = Name0
% We can't use the following code until we have adapted the
% code in the runtime and trace directories to handle the names
% of special preds the same way as we do user-defined names.
% (
% SpecialPredId = unify,
% SpecialName = "unify"
% ;
% SpecialPredId = compare,
% SpecialName = "compare"
% ;
% SpecialPredId = index,
% SpecialName = "index"
% ;
% SpecialPredId = initialise,
% SpecialName = "init"
% ),
% TypeCtor = TypeSymName - TypeArity,
% TypeName = sym_name_to_string(TypeSymName),
% string.format("%s_for_%s_%d",
% [s(SpecialName), s(TypeName), i(TypeArity)], Name)
;
Origin = origin_transformed(Transform, OldOrigin, _),
OldName = origin_name(OldOrigin, ""),
( OldName = "" ->
Name = Name0
;
Name = OldName ++ "_" ++ pred_transform_name(Transform)
)
;
( Origin = origin_instance_method(_)
; Origin = origin_created(_)
; Origin = origin_assertion(_, _)
; Origin = origin_user(_)
),
Name = Name0
).
:- func pred_transform_name(pred_transformation) = string.
pred_transform_name(transform_higher_order_specialization(Seq)) =
"ho" ++ int_to_string(Seq).
pred_transform_name(transform_higher_order_type_specialization(Proc)) =
"hoproc" ++ int_to_string(Proc).
pred_transform_name(transform_type_specialization(Substs)) =
string.join_list("_", list.map(subst_to_name, Substs)).
pred_transform_name(transform_unused_argument_elimination(Posns)) =
"ua_" ++ string.join_list("_", list.map(int_to_string, Posns)).
pred_transform_name(transform_accumulator(Posns)) = "acc_" ++
string.join_list("_", list.map(int_to_string, Posns)).
pred_transform_name(transform_loop_invariant(Proc)) =
"inv_" ++ int_to_string(Proc).
pred_transform_name(transform_tuple(Proc)) = "tup_" ++ int_to_string(Proc).
pred_transform_name(transform_untuple(Proc)) = "untup_" ++ int_to_string(Proc).
pred_transform_name(transform_dependent_parallel_conjunction) =
"dep_par_conj_".
pred_transform_name(transform_return_via_ptr(ProcId, ArgPos)) =
"retptr_" ++ int_to_string(proc_id_to_int(ProcId)) ++ "_args"
++ ints_to_string(ArgPos).
pred_transform_name(transform_table_generator) = "table_gen".
pred_transform_name(transform_dnf(N)) = "dnf_" ++ int_to_string(N).
:- func ints_to_string(list(int)) = string.
ints_to_string([]) = "".
ints_to_string([N | Ns]) = "_" ++ int_to_string(N) ++ ints_to_string(Ns).
:- func subst_to_name(pair(int, mer_type)) = string.
subst_to_name(TVar - Type) =
string.format("%d/%s",
[i(TVar), s(mercury_type_to_string(varset.init, no, Type))]).
%-----------------------------------------------------------------------------%
% 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 = 4.
:- pred output_module_common_layout_data_defn(module_name::in, int::in,
string_with_0s::in, decl_set::in, decl_set::out, io::di, io::uo) is det.
output_module_common_layout_data_defn(ModuleName, StringTableSize, StringTable,
!DeclSet, !IO) :-
output_module_string_table(ModuleName, StringTableSize, StringTable,
!DeclSet, !IO),
ModuleCommonLayoutName = module_common_layout(ModuleName),
io.write_string("\n", !IO),
output_layout_name_storage_type_name(ModuleCommonLayoutName, yes, !IO),
io.write_string(" = {\n", !IO),
io.write_int(layout_version_number, !IO),
io.write_string(",\n", !IO),
quote_and_write_string(sym_name_to_string(ModuleName), !IO),
io.write_string(",\n", !IO),
io.write_int(StringTableSize, !IO),
io.write_string(",\n", !IO),
ModuleStringTableName = module_layout_string_table(ModuleName),
output_layout_name(ModuleStringTableName, !IO),
io.write_string("\n};\n", !IO),
decl_set_insert(decl_data_addr(layout_addr(ModuleCommonLayoutName)),
!DeclSet).
:- pred output_module_layout_data_defn(module_name::in, layout_name::in,
list(layout_name)::in, list(file_layout_data)::in,
trace_level::in, int::in, int::in, maybe(event_set_layout_data)::in,
decl_set::in, decl_set::out, io::di, io::uo) is det.
output_module_layout_data_defn(ModuleName, ModuleCommonLayoutName,
ProcLayoutNames, FileLayouts, TraceLevel, SuppressedEvents,
NumLabels, MaybeEventSetLayout, !DeclSet, !IO) :-
output_layout_decl(module_common_layout(ModuleName), !DeclSet, !IO),
output_module_layout_proc_vector_defn(ModuleName, ProcLayoutNames,
ProcVectorName, !DeclSet, !IO),
output_file_layout_data_defns(ModuleName, 0, FileLayouts,
FileLayoutNames, !DeclSet, !IO),
output_file_layout_vector_data_defn(ModuleName, FileLayoutNames,
FileVectorName, !DeclSet, !IO),
io.write_string("\n", !IO),
LabelExecCountName = module_layout_label_exec_count(ModuleName,
NumLabels),
output_layout_name_storage_type_name(LabelExecCountName, yes, !IO),
io.write_string(";\n", !IO),
decl_set_insert(decl_data_addr(layout_addr(LabelExecCountName)), !DeclSet),
(
MaybeEventSetLayout = no
;
MaybeEventSetLayout = yes(EventSetDataLayout),
EventSetDataLayout =
event_set_layout_data(EventSetDataA, TypesRvalMap),
EventSetDataA = event_set_data(_EventSetName, EventSetDesc,
EventSpecsA, _MaxNumAttr),
output_event_set_desc_defn(ModuleName, EventSetDesc, !DeclSet, !IO),
output_event_specs_and_components(EventSpecsA, ModuleName,
TypesRvalMap, !DeclSet, !IO)
),
ModuleLayoutName = module_layout(ModuleName),
io.write_string("\n", !IO),
output_layout_name_storage_type_name(ModuleLayoutName, yes, !IO),
io.write_string(" = {\n", !IO),
io.write_string("&", !IO),
output_layout_name(ModuleCommonLayoutName, !IO),
io.write_string(",\n", !IO),
list.length(ProcLayoutNames, ProcLayoutVectorLength),
io.write_int(ProcLayoutVectorLength, !IO),
io.write_string(",\n", !IO),
output_layout_name(ProcVectorName, !IO),
io.write_string(",\n", !IO),
list.length(FileLayouts, FileLayoutVectorLength),
io.write_int(FileLayoutVectorLength, !IO),
io.write_string(",\n", !IO),
output_layout_name(FileVectorName, !IO),
io.write_string(",\n", !IO),
io.write_string(trace_level_rep(TraceLevel), !IO),
io.write_string(",\n", !IO),
io.write_int(SuppressedEvents, !IO),
io.write_string(",\n", !IO),
io.write_int(NumLabels, !IO),
io.write_string(",\n", !IO),
output_layout_name(LabelExecCountName, !IO),
io.write_string(",\n", !IO),
(
MaybeEventSetLayout = no,
io.write_string("NULL,\n", !IO),
io.write_string("NULL,\n", !IO),
io.write_string("0,\n", !IO),
io.write_string("0,\n", !IO),
io.write_string("NULL", !IO)
;
MaybeEventSetLayout = yes(EventSetDataLayoutB),
EventSetDataLayoutB =
event_set_layout_data(EventSetDataB, _TypesRvalMap),
EventSetDataB = event_set_data(EventSetName, _EventSetDesc,
EventSpecsB, MaxNumAttr),
quote_and_write_string(EventSetName, !IO),
io.write_string(",\n", !IO),
EventSetDescLayoutName = module_layout_event_set_desc(ModuleName),
output_layout_name(EventSetDescLayoutName, !IO),
io.write_string(",\n", !IO),
io.write_int(MaxNumAttr, !IO),
io.write_string(",\n", !IO),
io.write_int(list.length(EventSpecsB), !IO),
io.write_string(",\n", !IO),
EventSpecLayoutName = module_layout_event_specs(ModuleName),
output_layout_name(EventSpecLayoutName, !IO)
),
io.write_string("\n};\n", !IO),
decl_set_insert(decl_data_addr(layout_addr(ModuleLayoutName)), !DeclSet).
:- pred output_event_specs_and_components(list(event_spec)::in,
module_name::in, map(int, rval)::in,
decl_set::in, decl_set::out, io::di, io::uo) is det.
output_event_specs_and_components(EventSpecs, ModuleName, TypesRvalMap,
!DeclSet, !IO) :-
list.foldl2(output_event_spec_components(ModuleName), EventSpecs,
!DeclSet, !IO),
LayoutName = module_layout_event_specs(ModuleName),
DataAddr = layout_addr(LayoutName),
decl_set_insert(decl_data_addr(DataAddr), !DeclSet),
output_layout_name_storage_type_name(LayoutName, yes, !IO),
io.write_string(" = {\n", !IO),
io.write_list(EventSpecs, ",\n",
output_event_spec(ModuleName, TypesRvalMap), !IO),
io.write_string("\n};\n\n", !IO).
:- pred output_event_spec_components(module_name::in, event_spec::in,
decl_set::in, decl_set::out, io::di, io::uo) is det.
output_event_spec_components(ModuleName, EventSpec, !DeclSet, !IO) :-
EventSpec = event_spec(EventNumber, _EventName, _EventLineNumber,
Attrs, SynthOrder),
AttrNamesLayoutName =
module_layout_event_arg_names(ModuleName, EventNumber),
AttrNamesDataAddr = layout_addr(AttrNamesLayoutName),
decl_set_insert(decl_data_addr(AttrNamesDataAddr), !DeclSet),
output_layout_name_storage_type_name(AttrNamesLayoutName, yes, !IO),
io.write_string(" = {\n", !IO),
io.write_list(Attrs, ", ", output_attr_name, !IO),
io.write_string("\n};\n\n", !IO),
(
SynthOrder = []
;
SynthOrder = [_ | _],
list.foldl2(output_synth_attr_args(ModuleName, EventNumber),
Attrs, !DeclSet, !IO),
SynthAttrsLayoutName =
module_layout_event_synth_attrs(ModuleName, EventNumber),
SynthAttrsDataAddr = layout_addr(SynthAttrsLayoutName),
decl_set_insert(decl_data_addr(SynthAttrsDataAddr), !DeclSet),
output_layout_name_storage_type_name(SynthAttrsLayoutName, yes, !IO),
io.write_string(" = {\n", !IO),
io.write_list(Attrs, ",\n",
output_synth_attr(ModuleName, EventNumber), !IO),
io.write_string("\n};\n\n", !IO),
SynthOrderLayoutName =
module_layout_event_synth_order(ModuleName, EventNumber),
SynthOrderDataAddr = layout_addr(SynthOrderLayoutName),
decl_set_insert(decl_data_addr(SynthOrderDataAddr), !DeclSet),
output_layout_name_storage_type_name(SynthOrderLayoutName, yes, !IO),
io.write_string(" = {\n", !IO),
% The -1 acts as sentinel.
io.write_list(SynthOrder ++ [-1], ", ", io.write_int, !IO),
io.write_string("\n};\n\n", !IO)
).
:- pred output_attr_name(event_attribute::in, io::di, io::uo) is det.
output_attr_name(Attr, !IO) :-
io.write_string("""", !IO),
io.write_string(Attr ^ attr_name, !IO),
io.write_string("""", !IO).
:- pred output_synth_attr_args(module_name::in, int::in, event_attribute::in,
decl_set::in, decl_set::out, io::di, io::uo) is det.
output_synth_attr_args(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),
ArgsDataAddr = layout_addr(ArgsLayoutName),
decl_set_insert(decl_data_addr(ArgsDataAddr), !DeclSet),
output_layout_name_storage_type_name(ArgsLayoutName, yes, !IO),
io.write_string(" =\n{ ", !IO),
io.write_list(ArgAttrNums, ", ", io.write_int, !IO),
io.write_string(" };\n\n", !IO),
OrderLayoutName = module_layout_event_synth_attr_order(ModuleName,
EventNumber, AttrNumber),
OrderDataAddr = layout_addr(OrderLayoutName),
decl_set_insert(decl_data_addr(OrderDataAddr), !DeclSet),
output_layout_name_storage_type_name(OrderLayoutName, yes, !IO),
io.write_string(" =\n{ ", !IO),
OrderSentinel = Order ++ [-1],
io.write_list(OrderSentinel, ", ", io.write_int, !IO),
io.write_string(" };\n\n", !IO)
;
MaybeSynthCall = no
).
:- pred output_synth_attr(module_name::in, int::in, event_attribute::in,
io::di, io::uo) is det.
output_synth_attr(ModuleName, EventNumber, Attr, !IO) :-
io.write_string("{ ", !IO),
MaybeSynthCall = Attr ^ attr_maybe_synth_call,
(
MaybeSynthCall = yes(SynthCall),
SynthCall = event_attr_synth_call(_FuncAttrName - FuncAttrNum,
ArgAttrNameNums, _EvalOrder),
io.write_int(FuncAttrNum, !IO),
io.write_string(", ", !IO),
io.write_int(list.length(ArgAttrNameNums), !IO),
io.write_string(",\n ", !IO),
AttrNumber = Attr ^ attr_num,
ArgsLayoutName = module_layout_event_synth_attr_args(ModuleName,
EventNumber, AttrNumber),
output_layout_name(ArgsLayoutName, !IO),
io.write_string(",\n ", !IO),
OrderLayoutName = module_layout_event_synth_attr_order(ModuleName,
EventNumber, AttrNumber),
output_layout_name(OrderLayoutName, !IO)
;
MaybeSynthCall = no,
io.write_string("-1, -1, NULL, NULL", !IO)
),
io.write_string(" }", !IO).
:- pred output_event_spec(module_name::in, map(int, rval)::in, event_spec::in,
io::di, io::uo) is det.
output_event_spec(ModuleName, TypesRvalMap, EventSpec, !IO) :-
EventSpec = event_spec(EventNumber, EventName, _EventLineNumber, Attrs,
SynthOrder),
map.lookup(TypesRvalMap, EventNumber, TypesRval),
io.write_string("{ """, !IO),
io.write_string(EventName, !IO),
io.write_string(""", ", !IO),
io.write_int(list.length(Attrs), !IO),
io.write_string(",\n\t", !IO),
AttrNamesLayoutName =
module_layout_event_arg_names(ModuleName, EventNumber),
output_layout_name(AttrNamesLayoutName, !IO),
io.write_string(",\n\t(MR_TypeInfo *) ", !IO),
output_rval_as_addr(TypesRval, !IO),
io.write_string(",\n\t", !IO),
(
SynthOrder = [],
io.write_string("NULL, NULL }", !IO)
;
SynthOrder = [_ | _],
SynthAttrsLayoutName =
module_layout_event_synth_attrs(ModuleName, EventNumber),
SynthOrderLayoutName =
module_layout_event_synth_order(ModuleName, EventNumber),
output_layout_name(SynthAttrsLayoutName, !IO),
io.write_string(",\n\t", !IO),
output_layout_name(SynthOrderLayoutName, !IO),
io.write_string(" }", !IO)
).
:- pred output_module_layout_proc_vector_defn(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(ModuleName, ProcLayoutNames,
VectorName, !DeclSet, !IO) :-
list.foldl2(output_layout_decl, ProcLayoutNames, !DeclSet, !IO),
VectorName = module_layout_proc_vector(ModuleName),
io.write_string("\n", !IO),
output_layout_name_storage_type_name(VectorName, yes, !IO),
io.write_string(" = {\n", !IO),
(
ProcLayoutNames = [],
% ANSI/ISO C doesn't allow empty arrays, so place a dummy value
% in the array.
io.write_string("NULL\n", !IO)
;
ProcLayoutNames = [_ | _],
list.foldl(output_proc_layout_name_in_vector, ProcLayoutNames, !IO)
),
io.write_string("};\n", !IO),
decl_set_insert(decl_data_addr(layout_addr(VectorName)), !DeclSet).
:- pred output_proc_layout_name_in_vector(layout_name::in, io::di, io::uo)
is det.
output_proc_layout_name_in_vector(LayoutName, !IO) :-
( LayoutName = proc_layout(RttiProcLabel, _) ->
ProcLabel = make_proc_label_from_rtti(RttiProcLabel),
io.write_string("MR_PROC_LAYOUT1(", !IO),
output_proc_label_no_prefix(ProcLabel, !IO),
io.write_string(")\n", !IO)
;
unexpected(this_file,
"output_proc_layout_name_in_vector: not proc layout")
).
%-----------------------------------------------------------------------------%
:- pred output_event_set_desc_defn(module_name::in, string::in,
decl_set::in, decl_set::out, io::di, io::uo) is det.
output_event_set_desc_defn(ModuleName, EventSetDesc, !DeclSet, !IO) :-
LayoutName = module_layout_event_set_desc(ModuleName),
io.write_string("\n", !IO),
output_layout_name_storage_type_name(LayoutName, yes, !IO),
io.write_string(" = {", !IO),
output_module_string_table_strings(EventSetDesc, [], !IO),
io.write_string("};\n", !IO),
decl_set_insert(decl_data_addr(layout_addr(LayoutName)), !DeclSet).
:- pred output_module_string_table(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(ModuleName, _StringTableSize,
string_with_0s(StringTable0), !DeclSet, !IO) :-
TableName = module_layout_string_table(ModuleName),
io.write_string("\n", !IO),
output_layout_name_storage_type_name(TableName, yes, !IO),
io.write_string(" = {", !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(FirstString, Rest, !IO),
io.write_string("};\n", !IO),
decl_set_insert(decl_data_addr(layout_addr(TableName)), !DeclSet).
:- pred output_module_string_table_strings(string::in, list(string)::in,
io::di, io::uo) is det.
output_module_string_table_strings(String, [], !IO) :-
output_module_string_table_chars(0, length(String) - 1, String, !IO).
output_module_string_table_strings(String, [Next | Rest], !IO) :-
output_module_string_table_chars(0, length(String) - 1, String, !IO),
io.write_string(",\n", !IO),
output_module_string_table_strings(Next, Rest, !IO).
:- pred output_module_string_table_chars(int::in, int::in, string::in,
io::di, io::uo) is det.
output_module_string_table_chars(CurIndex, MaxIndex, String, !IO) :-
( CurIndex =< MaxIndex ->
( CurIndex mod 10 = 0 ->
io.nl(!IO)
;
true
),
string.unsafe_index(String, CurIndex, Char),
io.write_char('''', !IO),
c_util.output_quoted_char(Char, !IO),
io.write_char('''', !IO),
io.write_string(", ", !IO),
output_module_string_table_chars(CurIndex + 1, MaxIndex, String, !IO)
;
io.write_char('''', !IO),
c_util.output_quoted_char(char.det_from_int(0), !IO),
io.write_char('''', !IO)
).
%-----------------------------------------------------------------------------%
:- pred output_file_layout_vector_data_defn(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(ModuleName, FileLayoutNames, VectorName,
!DeclSet, !IO) :-
list.foldl2(output_layout_decl, FileLayoutNames, !DeclSet, !IO),
VectorName = module_layout_file_vector(ModuleName),
io.write_string("\n", !IO),
output_layout_name_storage_type_name(VectorName, yes, !IO),
io.write_string(" = {\n", !IO),
(
FileLayoutNames = [],
% ANSI/ISO C doesn't allow empty arrays, so place a dummy value
% in the array.
io.write_string("NULL\n", !IO)
;
FileLayoutNames = [_ | _],
list.foldl(output_layout_name_in_vector("&"), FileLayoutNames, !IO)
),
io.write_string("};\n", !IO),
decl_set_insert(decl_data_addr(layout_addr(VectorName)), !DeclSet).
:- pred output_file_layout_data_defns(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(ModuleName, FileNum, [FileLayout | FileLayouts],
[FileLayoutName | FileLayoutNames], !DeclSet, !IO) :-
output_file_layout_data_defn(ModuleName, FileNum, FileLayout,
FileLayoutName, !DeclSet, !IO),
output_file_layout_data_defns(ModuleName, FileNum + 1, FileLayouts,
FileLayoutNames, !DeclSet, !IO).
:- pred output_file_layout_data_defn(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(ModuleName, FileNum, FileLayout, FileLayoutName,
!DeclSet, !IO) :-
FileLayout = file_layout_data(FileName, LineNoLabelList),
list.map2(line_no_label_to_label_layout_addr, LineNoLabelList,
LineNos, LabelLayoutAddrs),
list.foldl2(output_data_addr_decls, LabelLayoutAddrs, !DeclSet, !IO),
list.length(LineNoLabelList, VectorLengths),
output_file_layout_line_number_vector_defn(ModuleName, FileNum,
LineNos, LineNumberVectorName, !DeclSet, !IO),
output_file_layout_label_layout_vector_defn(ModuleName, FileNum,
LabelLayoutAddrs, LabelVectorName, !DeclSet, !IO),
FileLayoutName = file_layout(ModuleName, FileNum),
io.write_string("\n", !IO),
output_layout_name_storage_type_name(FileLayoutName, yes, !IO),
io.write_string(" = {\n", !IO),
quote_and_write_string(FileName, !IO),
io.write_string(",\n", !IO),
io.write_int(VectorLengths, !IO),
io.write_string(",\n", !IO),
output_layout_name(LineNumberVectorName, !IO),
io.write_string(",\n", !IO),
output_layout_name(LabelVectorName, !IO),
io.write_string("\n};\n", !IO),
decl_set_insert(decl_data_addr(layout_addr(FileLayoutName)), !DeclSet).
:- pred output_file_layout_line_number_vector_defn(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(ModuleName, FileNum, LineNumbers,
LayoutName, !DeclSet, !IO) :-
LayoutName = file_layout_line_number_vector(ModuleName, FileNum),
io.write_string("\n", !IO),
output_layout_name_storage_type_name(LayoutName, yes, !IO),
io.write_string(" = {\n", !IO),
(
LineNumbers = [],
% ANSI/ISO C doesn't allow empty arrays, so place a dummy value
% in the array.
io.write_string("0\n", !IO)
;
LineNumbers = [_ | _],
list.foldl(output_number_in_vector, LineNumbers, !IO)
),
io.write_string("};\n", !IO),
decl_set_insert(decl_data_addr(layout_addr(LayoutName)), !DeclSet).
:- pred output_file_layout_label_layout_vector_defn(module_name::in, int::in,
list(data_addr)::in, layout_name::out, decl_set::in, decl_set::out,
io::di, io::uo) is det.
output_file_layout_label_layout_vector_defn(ModuleName, FileNum, LabelAddrs,
LayoutName, !DeclSet, !IO) :-
LayoutName = file_layout_label_layout_vector(ModuleName, FileNum),
io.write_string("\n", !IO),
output_layout_name_storage_type_name(LayoutName, yes, !IO),
io.write_string(" = {\n", !IO),
(
LabelAddrs = [],
% ANSI/ISO C doesn't allow empty arrays, so place a dummy value
% in the array.
io.write_string("NULL\n", !IO)
;
LabelAddrs = [_ | _],
output_label_layout_addrs_in_vector(LabelAddrs, "MR_LABEL_LAYOUT", !IO)
),
io.write_string("};\n", !IO),
decl_set_insert(decl_data_addr(layout_addr(LayoutName)), !DeclSet).
%-----------------------------------------------------------------------------%
:- pred output_label_layout_addrs_in_vector(list(data_addr)::in, string::in,
io::di, io::uo) is det.
output_label_layout_addrs_in_vector([], _, !IO).
output_label_layout_addrs_in_vector([DataAddr | DataAddrs], Macro, !IO) :-
(
DataAddr = layout_addr(LayoutName),
LayoutName = label_layout(ProcLabel, LabelNum, label_has_var_info)
->
groupable_labels(ProcLabel, 1, _N, [LabelNum], RevLabelNums,
DataAddrs, RemainingDataAddrs),
list.reverse(RevLabelNums, LabelNums),
io.write_string(Macro, !IO),
io.write_int(list.length(LabelNums), !IO),
io.write_string("(", !IO),
output_proc_label_no_prefix(ProcLabel, !IO),
io.write_string(",", !IO),
io.write_list(LabelNums, ",", io.write_int, !IO),
io.write_string(")\n", !IO),
output_label_layout_addrs_in_vector(RemainingDataAddrs, Macro, !IO)
;
unexpected(this_file,
"output_label_layout_addrs_in_vector: not label layout")
).
:- pred groupable_labels(proc_label::in, int::in, int::out,
list(int)::in, list(int)::out, list(data_addr)::in, list(data_addr)::out)
is det.
groupable_labels(GroupProcLabel, !Count, !RevLabelsNums, !DataAddrs) :-
(
!.DataAddrs = []
;
!.DataAddrs = [DataAddr | DataAddrsTail],
(
DataAddr = layout_addr(LayoutName),
LayoutName = label_layout(ProcLabel, LabelNum, label_has_var_info)
->
% There must be a macro of the form MR_LABEL_LAYOUT<n> and
% MR_DECL_LABEL_LAYOUT<n> for every <n> up to MaxChunkSize.
MaxChunkSize = 9,
(
% We cannot group together labels from different procedures.
ProcLabel = GroupProcLabel,
% Leave room for the one we're adding.
!.Count < MaxChunkSize
->
!:DataAddrs = DataAddrsTail,
!:Count = !.Count + 1,
!:RevLabelsNums = [LabelNum | !.RevLabelsNums],
groupable_labels(GroupProcLabel, !Count, !RevLabelsNums,
!DataAddrs)
;
true
)
;
unexpected(this_file, "groupable_labels: not label layout")
)
).
%-----------------------------------------------------------------------------%
:- pred line_no_label_to_label_layout_addr(pair(int, layout_name)::in,
int::out, data_addr::out) is det.
line_no_label_to_label_layout_addr(LineNo - LabelLayout, LineNo, DataAddr) :-
DataAddr = layout_addr(LabelLayout).
:- pred quote_and_write_string(string::in, io::di, io::uo) is det.
quote_and_write_string(String, !IO) :-
io.write_string("""", !IO),
c_util.output_quoted_string(String, !IO),
io.write_string("""", !IO).
:- pred output_number_in_vector(int::in, io::di, io::uo) is det.
output_number_in_vector(Num, !IO) :-
io.write_int(Num, !IO),
io.write_string(",\n", !IO).
:- pred output_layout_name_in_vector(string::in, layout_name::in,
io::di, io::uo) is det.
output_layout_name_in_vector(Prefix, Name, !IO) :-
io.write_string(Prefix, !IO),
output_layout_name(Name, !IO),
io.write_string(",\n", !IO).
:- pred output_data_addr_in_vector(string::in, data_addr::in,
io::di, io::uo) is det.
output_data_addr_in_vector(Prefix, DataAddr, !IO) :-
io.write_string(Prefix, !IO),
output_data_addr(DataAddr, !IO),
io.write_string(",\n", !IO).
%-----------------------------------------------------------------------------%
:- pred output_proc_static_data_defn(rtti_proc_label::in,
proc_layout_proc_static::in, decl_set::in, decl_set::out,
io::di, io::uo) is det.
output_proc_static_data_defn(RttiProcLabel, ProcLayoutProcStatic,
!DeclSet, !IO) :-
ProcLayoutProcStatic = proc_layout_proc_static(HLDSProcStatic,
DeepExcpVars),
HLDSProcStatic = hlds_proc_static(FileName, LineNumber, IsInInterface,
CallSites),
list.foldl2(output_call_site_static_decl, CallSites, !DeclSet, !IO),
output_call_site_static_array(RttiProcLabel, CallSites, !DeclSet, !IO),
LayoutName = proc_static(RttiProcLabel),
io.write_string("\n", !IO),
output_layout_name_storage_type_name(LayoutName, yes, !IO),
io.write_string(" = {\n", !IO),
quote_and_write_string(FileName, !IO),
io.write_string(",\n", !IO),
io.write_int(LineNumber, !IO),
io.write_string(",\n", !IO),
(
IsInInterface = yes,
io.write_string("MR_TRUE", !IO)
;
IsInInterface = no,
io.write_string("MR_FALSE", !IO)
),
io.write_string(",\n", !IO),
io.write_int(list.length(CallSites), !IO),
io.write_string(",\n", !IO),
CallSitesLayoutName = proc_static_call_sites(RttiProcLabel),
output_layout_name(CallSitesLayoutName, !IO),
io.write_string(",\n#ifdef MR_USE_ACTIVATION_COUNTS\n", !IO),
io.write_string("0,\n", !IO),
io.write_string("#endif\n", !IO),
io.write_string("NULL,\n", !IO),
DeepExcpVars = deep_excp_slots(TopCSDSlot, MiddleCSDSlot,
OldOutermostSlot),
io.write_int(TopCSDSlot, !IO),
io.write_string(",\n\t", !IO),
io.write_int(MiddleCSDSlot, !IO),
io.write_string(",\n\t", !IO),
io.write_int(OldOutermostSlot, !IO),
io.write_string("\n};\n", !IO),
decl_set_insert(decl_data_addr(layout_addr(LayoutName)), !DeclSet).
:- pred output_call_site_static_array(rtti_proc_label::in,
list(call_site_static_data)::in, decl_set::in, decl_set::out,
io::di, io::uo) is det.
output_call_site_static_array(RttiProcLabel, CallSites, !DeclSet, !IO) :-
LayoutName = proc_static_call_sites(RttiProcLabel),
io.write_string("\n", !IO),
output_layout_name_storage_type_name(LayoutName, yes, !IO),
io.write_string(" = {\n", !IO),
list.foldl2(output_call_site_static, CallSites, 0, _, !IO),
io.write_string("};\n", !IO),
decl_set_insert(decl_data_addr(layout_addr(LayoutName)), !DeclSet).
:- pred output_call_site_static(call_site_static_data::in, int::in, int::out,
io::di, io::uo) is det.
output_call_site_static(CallSiteStatic, Index, Index + 1, !IO) :-
io.write_string("{ /* ", !IO),
io.write_int(Index, !IO),
io.write_string(" */ ", !IO),
(
CallSiteStatic = normal_call(Callee, TypeSubst, FileName, LineNumber,
GoalPath),
io.write_string("MR_callsite_normal_call, (MR_ProcLayout *)\n&", !IO),
CalleeProcLabel = make_proc_label_from_rtti(Callee),
CalleeUserOrUci = proc_label_user_or_uci(CalleeProcLabel),
output_layout_name(proc_layout(Callee,
proc_layout_proc_id(CalleeUserOrUci)), !IO),
( TypeSubst = "" ->
io.write_string(", NULL, ", !IO)
;
io.write_string(",\n""", !IO),
io.write_string(TypeSubst, !IO),
io.write_string(""", ", !IO)
)
;
CallSiteStatic = special_call(FileName, LineNumber, GoalPath),
io.write_string("MR_callsite_special_call, NULL, NULL, ", !IO)
;
CallSiteStatic = higher_order_call(FileName, LineNumber, GoalPath),
io.write_string("MR_callsite_higher_order_call, NULL, NULL, ", !IO)
;
CallSiteStatic = method_call(FileName, LineNumber, GoalPath),
io.write_string("MR_callsite_method_call, NULL, NULL, ", !IO)
;
CallSiteStatic = callback(FileName, LineNumber, GoalPath),
io.write_string("MR_callsite_callback, NULL, NULL, ", !IO)
),
io.write_string("""", !IO),
io.write_string(FileName, !IO),
io.write_string(""", ", !IO),
io.write_int(LineNumber, !IO),
io.write_string(", """, !IO),
io.write_string(goal_path_to_string(GoalPath), !IO),
io.write_string(""" },\n", !IO).
:- pred output_call_site_static_decl(call_site_static_data::in,
decl_set::in, decl_set::out, io::di, io::uo) is det.
output_call_site_static_decl(CallSiteStatic, !DeclSet, !IO) :-
(
CallSiteStatic = normal_call(Callee, _, _, _, _),
CalleeProcLabel = make_proc_label_from_rtti(Callee),
CalleeUserOrUci = proc_label_user_or_uci(CalleeProcLabel),
output_maybe_layout_name_decl(proc_layout(Callee,
proc_layout_proc_id(CalleeUserOrUci)), !DeclSet, !IO)
;
CallSiteStatic = special_call(_, _, _)
;
CallSiteStatic = higher_order_call(_, _, _)
;
CallSiteStatic = method_call(_, _, _)
;
CallSiteStatic = callback(_, _, _)
).
%-----------------------------------------------------------------------------%
:- pred output_table_io_decl(rtti_proc_label::in, proc_layout_kind::in,
int::in, rval::in, rval::in, decl_set::in, decl_set::out,
io::di, io::uo) is det.
output_table_io_decl(RttiProcLabel, ProcLayoutKind, NumPTIs,
PTIVectorRval, TypeParamsRval, !DeclSet, !IO) :-
output_rval_decls(PTIVectorRval, !DeclSet, !IO),
LayoutName = table_io_decl(RttiProcLabel),
ProcLayoutName = proc_layout(RttiProcLabel, ProcLayoutKind),
output_layout_decl(ProcLayoutName, !DeclSet, !IO),
io.write_string("\n", !IO),
output_layout_name_storage_type_name(LayoutName, yes, !IO),
io.write_string(" = {\n(const MR_ProcLayout *) &", !IO),
output_layout_name(ProcLayoutName, !IO),
io.write_string(",\n", !IO),
io.write_int(NumPTIs, !IO),
io.write_string(",\n(const MR_PseudoTypeInfo *) ", !IO),
output_rval(PTIVectorRval, !IO),
io.write_string(",\n(const MR_TypeParamLocns *) ", !IO),
output_rval(TypeParamsRval, !IO),
io.write_string("\n};\n", !IO),
decl_set_insert(decl_data_addr(layout_addr(LayoutName)), !DeclSet).
%-----------------------------------------------------------------------------%
output_pred_or_func(PredOrFunc, !IO) :-
(
PredOrFunc = pf_predicate,
io.write_string("MR_PREDICATE", !IO)
;
PredOrFunc = pf_function,
io.write_string("MR_FUNCTION", !IO)
).
%-----------------------------------------------------------------------------%
:- func this_file = string.
this_file = "layout_out.m".
%-----------------------------------------------------------------------------%