mirror of
https://github.com/Mercury-Language/mercury.git
synced 2025-12-20 08:19:28 +00:00
Estimated hours taken: 40
Support line numbers in the debugger. You now get contexts (filename:lineno
pairs) printed in several circumstances, and you can put breakpoints on
contexts, when they correspond to trace events or to calls. The latter are
implemented as breakpoints on the label layouts of the return sites.
This required extending the debugging RTTI, so that associated with each
module there is now a new data structure listing the source file names that
contribute labels with layout structures to the code of the module. For each
such source file, this table gives a list of all such labels arising from
that file. The table entry for a label gives the line number within the file,
and the pointer to the label layout structure.
compiler/llds.m:
Add a context field to the call instruction.
compiler/continuation_info.m:
Instead of the old division of continuation info about labels into
trace ports and everything else, divide them into trace ports, resume
points and return sites. Record contexts with trace ports, and record
contexts and called procedure information with return sites.
compiler/code_info.m:
Conform to the changes in continuation_info.m.
compiler/options.m:
Add a new option that allows us to disable the generation of line
number information for size benchmarking (it has no other use).
compiler/stack_layout.m:
Generate the new components of the RTTI, unless the option says not to.
compiler/code_gen.m:
compiler/pragma_c_gen.m:
compiler/trace.m:
Include contexts in the information we gather for the layouts
associated with the events we generate.
compiler/call_gen.m:
Include contexts in the call LLDS instructions, for association
with the return site's label layout structure (which is done after
code generation is finished).
compiler/handle_options.m:
Delete the code that tests or sets the deleted options.
compiler/mercury_compile.m:
Delete the code that tests the deleted options.
compiler/basic_block.m:
compiler/dupelim.m:
compiler/frameopt.m:
compiler/livemap.m:
compiler/llds_common.m:
compiler/llds_out.m:
compiler/middle_rec.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/value_number.m:
compiler/vn_*.m:
Trivial changes to conform to the changes to llds.m.
compiler/jumpopt.m:
Do not optimize away jumps to labels with layout structures.
The jumps we are particularly concerned about now are the jumps
that return from procedure calls. Previously, it was okay to redirect
returns from several calls so that all go to the same label, since
the live variable information associated with the labels could be
merged. However, we now also associate line numbers with calls, and
these cannot be usefully merged.
compiler/optimize.m:
Pass the information required by jumpopt to it.
doc/user_guide.texi:
Document that you can now break at line numbers.
Document the new "context" command, and the -d or --detailed option
of the stack command and the commands that set ancestor levels.
runtime/mercury_stack_layout.h:
Extend the module layout structure definition with the new tables.
Remove the conditional facility for including label numbers in label
layout structures. It hasn't been used in a long time, and neither
Tyson or me expect to use it to debug either gc or the debugger itself,
so it has no uses left; the line numbers have superseded it.
runtime/mercury_stack_trace.[ch]:
Extend the code to print stack traces to also optionally print
contexts.
Add some utility predicates currently used by the debugger that could
also be use for debugging gc or for more detailed stack traces.
trace/mercury_trace_internal.c:
Implement the "break <context>" command, the "context" command, and
the -d or --detailed option of the stack command and the commands
that set ancestor levels.
Conditionally define a conditionally used variable.
trace/mercury_trace_external.c:
Minor changes to keep up with the changes to stack traces.
Delete an unused variable.
trace/mercury_trace_spy.[ch]:
Check for breakpoints on contexts.
trace/mercury_trace_tables.[ch]:
Add functions to search the RTTI data structures for labels
corresponding to a given context.
trace/mercury_trace_vars.[ch]:
Remember the context of the current environment.
tests/debugger/queen.{inp,exp}:
Test the new capabilities of the debugger.
tests/debugger/*.{inp,exp}:
Update the expected output of the debugger to account for contexts.
In some cases, modify the input script to put contexts where they don't
overflow lines.
211 lines
6.7 KiB
Mathematica
211 lines
6.7 KiB
Mathematica
%-----------------------------------------------------------------------------%
|
|
% Copyright (C) 1995-1999 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.
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
% vn_type.m - types for value numbering.
|
|
|
|
% Author: zs.
|
|
|
|
%-----------------------------------------------------------------------------%
|
|
|
|
:- module vn_type.
|
|
|
|
:- interface.
|
|
:- import_module llds, builtin_ops, livemap, options.
|
|
:- import_module getopt, map, set, list, std_util.
|
|
|
|
:- type vn == int.
|
|
|
|
:- type vnlval ---> vn_reg(reg_type, int)
|
|
; vn_temp(reg_type, int)
|
|
; vn_stackvar(int)
|
|
; vn_framevar(int)
|
|
; vn_succip
|
|
; vn_maxfr
|
|
; vn_curfr
|
|
; vn_succfr(vn)
|
|
; vn_prevfr(vn)
|
|
; vn_redofr(vn)
|
|
; vn_redoip(vn)
|
|
; vn_succip(vn)
|
|
; vn_hp
|
|
; vn_sp
|
|
; vn_field(maybe(tag), vn, vn)
|
|
; vn_mem_ref(vn).
|
|
|
|
% these lvals do not have vnlval parallels
|
|
% lvar(var)
|
|
|
|
:- type vnrval ---> vn_origlval(vnlval)
|
|
; vn_mkword(tag, vn)
|
|
; vn_const(rval_const)
|
|
; vn_create(tag, list(maybe(rval)),
|
|
create_arg_types, static_or_dynamic,
|
|
int, string)
|
|
; vn_unop(unary_op, vn)
|
|
; vn_binop(binary_op, vn, vn)
|
|
; vn_stackvar_addr(int)
|
|
; vn_framevar_addr(int)
|
|
; vn_heap_addr(vn, int, int).
|
|
|
|
% these rvals do not have vnrval parallels
|
|
% var(var)
|
|
|
|
% given a vnlval, figure out its type
|
|
:- pred vn_type__vnlval_type(vnlval::in, llds_type::out) is det.
|
|
|
|
% given a vnrval, figure out its type
|
|
:- pred vn_type__vnrval_type(vnrval::in, llds_type::out) is det.
|
|
|
|
:- type vn_src ---> src_ctrl(int)
|
|
; src_liveval(vnlval)
|
|
; src_access(vnlval)
|
|
; src_vn(int).
|
|
|
|
:- type vn_node ---> node_shared(vn)
|
|
; node_lval(vnlval)
|
|
; node_origlval(vnlval)
|
|
; node_ctrl(int).
|
|
|
|
:- type vn_instr ---> vn_livevals(lvalset)
|
|
; vn_call(code_addr, code_addr, list(liveinfo),
|
|
term__context, call_model)
|
|
; vn_mkframe(nondet_frame_info, code_addr)
|
|
; vn_label(label)
|
|
; vn_goto(code_addr)
|
|
; vn_computed_goto(vn, list(label))
|
|
; vn_if_val(vn, code_addr)
|
|
; vn_mark_hp(vnlval)
|
|
; vn_restore_hp(vn)
|
|
; vn_store_ticket(vnlval)
|
|
; vn_reset_ticket(vn, reset_trail_reason)
|
|
; vn_discard_ticket
|
|
; vn_mark_ticket_stack(vnlval)
|
|
; vn_discard_tickets_to(vn)
|
|
; vn_incr_sp(int, string)
|
|
; vn_decr_sp(int).
|
|
|
|
:- type parentry == pair(lval, list(rval)).
|
|
:- type parallel ---> parallel(label, label, list(parentry)).
|
|
|
|
:- type vnlvalset == set(vnlval).
|
|
|
|
:- type ctrlmap == map(int, vn_instr).
|
|
:- type flushmap == map(int, flushmapentry).
|
|
:- type flushmapentry == map(vnlval, vn).
|
|
:- type parmap == map(int, list(parallel)).
|
|
|
|
:- type vn_ctrl_tuple ---> tuple(int, ctrlmap, flushmap, int, parmap).
|
|
|
|
:- type vn_params.
|
|
|
|
:- pred vn_type__init_params(option_table(option), vn_params).
|
|
:- mode vn_type__init_params(in, out) is det.
|
|
|
|
:- pred vn_type__bytes_per_word(vn_params, int).
|
|
:- mode vn_type__bytes_per_word(in, out) is det.
|
|
|
|
:- pred vn_type__real_r_regs(vn_params, int).
|
|
:- mode vn_type__real_r_regs(in, out) is det.
|
|
|
|
:- pred vn_type__real_f_regs(vn_params, int).
|
|
:- mode vn_type__real_f_regs(in, out) is det.
|
|
|
|
:- pred vn_type__real_r_temps(vn_params, int).
|
|
:- mode vn_type__real_r_temps(in, out) is det.
|
|
|
|
:- pred vn_type__real_f_temps(vn_params, int).
|
|
:- mode vn_type__real_f_temps(in, out) is det.
|
|
|
|
:- pred vn_type__costof_assign(vn_params, int).
|
|
:- mode vn_type__costof_assign(in, out) is det.
|
|
|
|
:- pred vn_type__costof_intops(vn_params, int).
|
|
:- mode vn_type__costof_intops(in, out) is det.
|
|
|
|
:- pred vn_type__costof_stackref(vn_params, int).
|
|
:- mode vn_type__costof_stackref(in, out) is det.
|
|
|
|
:- pred vn_type__costof_heapref(vn_params, int).
|
|
:- mode vn_type__costof_heapref(in, out) is det.
|
|
|
|
:- implementation.
|
|
|
|
:- import_module int.
|
|
|
|
:- type vn_params ---> vn_params(
|
|
int, % word size in bytes
|
|
% needed for incr_hp; incr_hp
|
|
int, % number of real r regs
|
|
int, % number of real f regs
|
|
int, % number of real r temps
|
|
int, % number of real f temps
|
|
int, % cost of assign
|
|
int, % cost of int operation
|
|
int, % cost of stack reference
|
|
int % cost of heap reference
|
|
).
|
|
|
|
vn_type__init_params(OptionTable, VnParams) :-
|
|
getopt__lookup_int_option(OptionTable, num_real_r_regs, RealRRegs),
|
|
getopt__lookup_int_option(OptionTable, num_real_f_regs, RealFRegs),
|
|
getopt__lookup_int_option(OptionTable, num_real_r_temps, RealRTemps),
|
|
getopt__lookup_int_option(OptionTable, num_real_f_temps, RealFTemps),
|
|
getopt__lookup_int_option(OptionTable, bytes_per_word, WordBytes),
|
|
VnParams = vn_params(WordBytes, RealRRegs, RealFRegs,
|
|
RealRTemps, RealFTemps, 1, 1, 2, 2).
|
|
|
|
vn_type__bytes_per_word(vn_params(BytesPerWord, _, _, _, _, _, _, _, _),
|
|
BytesPerWord).
|
|
vn_type__real_r_regs(vn_params(_, RealRRegs, _, _, _, _, _, _, _),
|
|
RealRRegs).
|
|
vn_type__real_f_regs(vn_params(_, _, RealFRegs, _, _, _, _, _, _),
|
|
RealFRegs).
|
|
vn_type__real_r_temps(vn_params(_, _, _, RealRTemps, _, _, _, _, _),
|
|
RealRTemps).
|
|
vn_type__real_f_temps(vn_params(_, _, _, _, RealFTemps, _, _, _, _),
|
|
RealFTemps).
|
|
vn_type__costof_assign(vn_params(_, _, _, _, _, AssignCost, _, _, _),
|
|
AssignCost).
|
|
vn_type__costof_intops(vn_params(_, _, _, _, _, _, IntOpCost, _, _),
|
|
IntOpCost).
|
|
vn_type__costof_stackref(vn_params(_, _, _, _, _, _, _, StackCost, _),
|
|
StackCost).
|
|
vn_type__costof_heapref(vn_params(_, _, _, _, _, _, _, _, HeapCost),
|
|
HeapCost).
|
|
|
|
vn_type__vnrval_type(vn_origlval(Lval), Type) :-
|
|
vn_type__vnlval_type(Lval, Type).
|
|
vn_type__vnrval_type(vn_create(_, _, _, _, _, _), data_ptr).
|
|
vn_type__vnrval_type(vn_mkword(_, _), data_ptr). % see comment in llds.m
|
|
vn_type__vnrval_type(vn_const(Const), Type) :-
|
|
llds__const_type(Const, Type).
|
|
vn_type__vnrval_type(vn_unop(UnOp, _), Type) :-
|
|
llds__unop_return_type(UnOp, Type).
|
|
vn_type__vnrval_type(vn_binop(BinOp, _, _), Type) :-
|
|
llds__binop_return_type(BinOp, Type).
|
|
vn_type__vnrval_type(vn_stackvar_addr(_), data_ptr).
|
|
vn_type__vnrval_type(vn_framevar_addr(_), data_ptr).
|
|
vn_type__vnrval_type(vn_heap_addr(_, _, _), data_ptr).
|
|
|
|
vn_type__vnlval_type(vn_reg(RegType, _), Type) :-
|
|
llds__register_type(RegType, Type).
|
|
vn_type__vnlval_type(vn_succip, code_ptr).
|
|
vn_type__vnlval_type(vn_maxfr, data_ptr).
|
|
vn_type__vnlval_type(vn_curfr, data_ptr).
|
|
vn_type__vnlval_type(vn_hp, data_ptr).
|
|
vn_type__vnlval_type(vn_sp, data_ptr).
|
|
vn_type__vnlval_type(vn_temp(RegType, _), Type) :-
|
|
llds__register_type(RegType, Type).
|
|
vn_type__vnlval_type(vn_stackvar(_), word).
|
|
vn_type__vnlval_type(vn_framevar(_), word).
|
|
vn_type__vnlval_type(vn_succip(_), code_ptr).
|
|
vn_type__vnlval_type(vn_redoip(_), code_ptr).
|
|
vn_type__vnlval_type(vn_redofr(_), data_ptr).
|
|
vn_type__vnlval_type(vn_succfr(_), data_ptr).
|
|
vn_type__vnlval_type(vn_prevfr(_), data_ptr).
|
|
vn_type__vnlval_type(vn_field(_, _, _), word).
|
|
vn_type__vnlval_type(vn_mem_ref(_), word).
|