mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-18 19:03:45 +00:00
Estimated hours taken: 90
This change makes the tracer a lot more useful. The major points are:
- you can now print the values of live variables at all trace ports,
not just at entry and exit ports;
- you can now print the values of polymorphic variables;
- you can now set spy points;
- you can now say "give me back control when execution starts going
forward again";
- the implementation no longer saves and restores a thousand pseudo-registers
unnecessarily;
- the implementation no longer insists that stack layouts must be present
either for all labels or for none;
- you can now execute programs compiled with tracing without user intervention
if that is what you want.
The last change makes bootstrapping with --generate-trace possible in theory,
although this has not yet been done successfully.
The three major things remaining to be done to make the tracer an adequate
replacement for Prolog debugging are
- a real term browser;
- a redo capability
- being able to trace different modules at different levels
(full/interface/none).
Two less important things to do are making the representation of typeinfos
themselves type correct :-( and not including partially clobbered variables
in trace events (we already filter out fully clobbered variables, which are
the vast majority of all at-least-partially clobbered variables).
compiler/trace.m:
We now record information about what (non-fully-clobbered) variables
are live where in a label that we associate with each event,
a label we allocate for this purpose. Since the stack layouts can
only describe registers and stack slots, generating a trace event
may now require materializing some variables and moving some others
from fields to registers or stack slots.
We now recognize three kinds of events: external, normal internal
and nondet pragma C code internal. We have different predicates
for generating each kind of event, since the three kinds of callers
are different and have different information available.
compiler/arg_info.m:
compiler/code_info.m:
Move some code that always belonged in arg_info.m to arg_info.m
from code_info.m.
compiler/code_exprn.m:
Add a predicate to find out which registers are in use, so the tracer
can avoid saving and restoring registers that are not use.
compiler/code_gen.m:
Reorganize the handling of epilogs. Whereas epilogs used to generate
the failure handling code, this is now done in generate_category_code,
because failure handling is now complicated by having to save the
input args for the fail event, and the setup for this naturally
belongs in generate_category_code.
Rename generate_{prolog,epilog} as generate_{entry,exit}, since
this makes clear that the latter now only handles success
continuations, not failure continuations.
Spell prologue and epilogue correctly elsewhere.
Also move the responsibility for the call event to
generate_category_code.
Move Tyson's recent additions for tracing to trace.m in a generalized
form, since they are now needed for all events, not just call and exit.
Remove obsolete code for eager code generation.
compiler/code_info.m:
Add a predicate to call the new predicate in code_exprn.
Export a predicate for trace.m.
Considerably simplify the treatment of continuation_infos,
with code_info structures now storing only the stuff that can change
during code generation (due to trace events).
compiler/code_util.m:
compiler/opt_util.m:
compiler/vn_filter.m:
compiler/trace.m:
Move some code to code_util.m from opt_util.m and generalize it a bit,
since the new predicate in code_exprn.m now needs the functionality.
Make trace.m and vn_filter.m refer to the moved predicates by their
new name.
compiler/continuation_info.m:
Major reorganization and simplification of the data structures.
The data that changes during code generation is now stored in the
code generator state; data that is only available after code generation
is combined with the info from the code generator state and put into
the HLDS; data that is available only after optimization is put
directly into the HLDS.
Do not add continuation_info records for labels that are not used
either by tracing or by agc. For labels that are used by either,
always include stack layout information if any variables are live.
(The removal of an unnecessary layer of maybe's wasn't ready
for this time around; Tom will remove this layer soon.)
compiler/continuation_info.m:
compiler/stack_layout.m:
Do not associate the stack layout information at procedure entry and
exit with the per-procedure data structure. Since we now associate this
info with the labels of those events instead, they do not need special
handling. However, do include a pointer to the layout structure of
the label associated with the call event in the per-procedure data,
so that we can later implement redo in the debugger.
compiler/stack_layout.m:
Handle the possibility that the set of type variables that are needed
at a point is not numbered 1-N without any missing type var numbers.
This can happen if all variables whose types include a low-numbered
type variable die before some of those whose types include a higher-
numbered type variable.
compiler/*_switch*.m:
compiler/ite_gen.m:
compiler/disj_gen.m:
When creating trace events, associate not just a goal path but
also a pre-death set with events that represent entry to a computation
branch. Trace.m now needs the pre-death set so that it can avoid
trying to flush variables that are not supposed to be live in the
computation branch being traced.
Since putting variable values in positions that can be described
by stack layouts (which includes only registers and stack slots,
not fields etc) may require generating code, make sure that this
code is generated when code_info has the appropriate contents
(i.e. just before the generating the code the entrance to which
the event refers to).
compiler/pragma_c_gen.m:
Add two new event types to signify entry to the C code fragments
executed on first call and on later reentries.
compiler/handle_options.m:
Handle some more implications of tracing, and document them better.
One of these changes (follow_vars) ought to allow munta to pass
the debugger test cases.
compiler/llds_out.m:
When generating init_{entry,label,local} operations, append a suffix
_sl to the macro name if the label whose info is being registered
has a stack layout record. This will cause the stack layout to be
registered also. For other labels, the macro without the _sl will
register NULL instead.
compiler/live_vars.m:
compiler/liveness.m:
compiler/store_alloc.m:
If tracing is on, try to preserve the input arguments throughout
the execution of the procedure. This is not possible if any part
of an input argument is clobbered, but in the absence of a utility
predicate that can test for this, we ignore the issue for now.
compiler/mercury_compile.m:
Do not invoke continuation_info__process_instructions to add
stack layout information about call return sites unless we are doing
agc. (Tracing does not require this info, and it is big.)
Pass info on which labels have stack layout records to llds_out.m.
Fix some misleading progress messages.
compiler/{lambda,polymorphism,goal_util}.m:
Enforce the invariant that if the signature of a procedure created
for a lambda goal includes a type variable, it also includes the
typeinfo for that type variable.
(This change is from Simon.)
library/{benchmarking,std_util}.m:
Add the _sl suffix to init_* macros in hand-written code where
necessary.
library/require.m:
When error is called from a program that does tracing, make it
print the number of the last event.
runtime/mercury_{conf_param.h,trace.c}:
util/mkinit.c:
Rename MR_USE_DEBUGGER as MR_USE_EXTERNAL_DEBUGGER, since we
have an internal one as well.
runtime/mercury_goto.h:
For each of the init_{entry,label,local} macros, and the macros
they invoke, add a new variant (denoted by a _sl suffix on the
macro name) that will cause the stack layout record associated
with the label to be registered also. For labels initialized
with the variants without the _sl, initialization will register
NULL instead.
runtime/mercury_{memory,misc}.c:
In several locations, just before exiting with a fatal error in
a program that does tracing, print the number of the last event.
runtime/mercury_regorder.h:
Add two new macros, MR_NUM_SPECIAL_REG and MR_MAX_SPECIAL_REG_MR
that mercury_trace.c uses to decide how much fake_reg to save and
restore.
runtime/mercury_stack_layout.h:
Change the definition of MR_Var_Shape_Info to reflect the real type
of one of its fields more closely.
Make the type names conform to the Mercury style guide
With_Studly_Cap_Names.
Fix the name and the definition of MR_DETISM_DET_CODE_MODEL.
runtime/mercury_stack_layout.c:
Use the new forms of the type names.
runtime/mercury_trace.[ch]:
runtime/mercury_wrapper.c:
Add support for turning tracing on and off and for choosing the
external or internal debugger.
Modify the prototype of MR_trace() to reflect the new arg giving
the number of the highest numbered rN register in use at the call.
Support the new trace ports for nondet pragma C code.
runtime/mercury_trace.c:
Implement a new command set more in line with what we intend to
grow towards in the future:
[N] s/S/CR to skip N events
f/F to finish the execution of the current call
c/C to continue to the end
The upper case versions print events as they go, the lower case
ones don't.
Add several new commands:
N g/G to go to event #N
r to skip all following exit and fail ports until we come to
another port type
b module pred
to add a breakpoint (which actually functions like a spy point)
? to list all breakpoints
+ to enable a numbered breakpoint
- to disable a numbered breakpoint
Save/restore only the necessary registers, not all of them.
Do not indent trace events by the depth, since the depth can get
very large (4800 in one case I looked at).
Provide functions for other parts of the runtime and the library
to call to print the number of the last trace event.
There is a reference here back to the library, but this will
go away when the tabling change is committed.
runtime/mercury_trace.[ch]:
Add a new function, MR_trace_report. This function, which is for
invocation in the event of a fatal error, reports what the number
of the last event was (if tracing is enabled). This should allow
the programmer to go more directly to the source of the problem.
runtime/mercury_wrapper.[ch]:
Remove the long obsolete code for initializing r[123] with integers.
scripts/mdb:
A new script for turning on the tracing code in an executable.
scripts/Mmakefile:
bindist/Mmakefile:
bindist/bindist.Makefile.in:
Include mdb in the list of scripts to be installed.
doc/Mmakefile:
Include mdb in the list of scripts with autogenerated man pages.
tests/misc_tests/Mmakefile:
tests/misc_tests/debugger_regs.*:
tests/misc_tests/debugger_test.*:
Move the tests of the debugger to the new tests/debugger directory.
In the process, give debugger_test back its original name,
"interpreter", and give it an input script that tests the new
debugger commands while avoiding the printing of excessively large
terms (although they still overflow 80 columns).
tests/debugger/Mmakefile:
tests/debugger/runtests:
tests/debugger/debugger_regs.*:
tests/debugger/interpreter.*:
The moved test cases and copied Mmakefile/runtests.
tests/debugger/queens.*:
A new test case to test the printing of variables in polymorphic
procedures.
This directory contains files used to create a binary distribution of Mercury. Files that will be incorporated in the binary distribution start with `bindist.'. The other files (this README, and the Mmake file) are only used to build the distribution. To build a binary distribution, first build and install the compiler from the source distribution (see the instructions in ../INSTALL). Then just do an `mmake bindist'.