for review: an even bigger step towards the debugger (part 3 of 4)
Zoltan Somogyi
zs at cs.mu.OZ.AU
Wed Apr 1 17:11:29 AEST 1998
Index: compiler/stack_layout.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/stack_layout.m,v
retrieving revision 1.9
diff -u -u -r1.9 stack_layout.m
--- stack_layout.m 1998/03/11 05:10:05 1.9
+++ stack_layout.m 1998/04/01 03:53:06
@@ -34,7 +34,7 @@
% (the location will be set to -1
% if there is no succip available).
%
-% if the option procid_stack_layout is set, i.e. if we are doing stack
+% If the option procid_stack_layout is set, i.e. if we are doing stack
% tracing, execution tracing or profiling, the table will also include
% information on the identity of the procedure. This information will take
% one of two forms. Almost all procedures use the first form:
@@ -63,36 +63,18 @@
% The meanings of the fields in both forms are the same as in procedure labels.
%
% If the option trace_stack_layout is set, i.e. if we are doing execution
-% tracing, the table will also include information on the variables that are
-% live at entry to and exit from the procedure:
+% tracing, the table will also include one extra field:
%
-% # of live vars at entry (Integer)
-% live data pairs (Word *) - pointer to vector of pairs
-% containing MR_Live_Lval and MR_Live_Type
-% live data names (Word *) - pointer to vector of String
-% type parameters (Word *) - pointer to vector of MR_Live_Lval
+% call trace info (Word *) - pointer to label stack layout
%
-% # of live vars at exit (Integer)
-% live data pairs (Word *) - pointer to vector of pairs
-% containing MR_Live_Lval and MR_Live_Type
-% live data names (Word *) - pointer to vector of String
-% type parameters (Word *) - pointer to vector of MR_Live_Lval
-%
-% The live data pair vector will have an entry for each live variable.
-% The entry will give the location of the variable and its type (it also
-% has room for its instantiation state, but this is not filled in yet).
-%
-% The live data name vector pointer may be NULL. If it is not, the vector
-% will have an entry for each live variable, with each entry being either
-% NULL or giving the name of the variable.
-%
-% The number of type parameters is never stored as it is not needed --
-% the type parameter vector will simply be indexed by the type parameter
-% number stored within pseudo-typeinfos inside the elements of the live
-% data pairs vectors.
+% This will point to the per-label layout info for the label associated
+% with the call event at the entry to the procedure. The purpose of this
+% information is to allow the runtime debugger to find out which variables
+% are where on entry, so it can reexecute the procedure if asked to do so
+% and if the values of the required variables are still available.
%
% If the option basic_stack_layout is set, we generate stack layout tables
-% for all labels internal to the procedure. This table will be stored in the
+% for some labels internal to the procedure. This table will be stored in the
% global variable whose name is
% mercury_data__stack_layout__mercury__<proc_label>_i<label_number>.
% This table has the following format:
@@ -103,29 +85,49 @@
% live data pairs (Word *) - pointer to vector of pairs
% containing MR_Live_Lval and MR_Live_Type
% live data names (Word *) - pointer to vector of String
-% live data names (Word *) - pointer to vector of String
% type parameters (Word *) - pointer to vector of MR_Live_Lval
%
-% We need detailed information about the variables that are live at an internal
-% label in two kinds of circumstances:
+% The internal label number field is just for the convenience of those
+% implementors who are debugging stack layout dependent code. It holds
+% either the label number, or -1 indicating the entry label.
+%
+% The live data pair vector will have an entry for each live variable.
+% The entry will give the location of the variable and its type. (It also
+% has room for its instantiation state, but this is not filled in yet.)
+%
+% The live data name vector pointer will be NULL. If it is not, the vector
+% will have an entry for each live variable, with each entry giving the name
+% of the variable (it is either a pointer to a string, or a NULL pointer,
+% which means that the variable has no name).
%
-% - the option trace_stack_layout is set, and the label represents
-% a traced event (with the current set of events, this means the
-% the entrance to one branch of a branched control structure)
+% The number of type parameters is never stored as it is not needed --
+% the type parameter vector will simply be indexed by the type variable's
+% variable number stored within pseudo-typeinfos inside the elements
+% of the live data pairs vectors. Since we allocate type variable numbers
+% sequentially, the type parameter vector will usually be dense. However,
+% after all variables whose types include e.g. type variable 2 have gone
+% out of scope, variables whose types include type variable 3 may still
+% be around.
+%
+% We need detailed information about the variables that are live at an
+% internal label in two kinds of circumstances. Stack layout information
+% will be present only for labels that fall into one or both of these
+% circumstances.
+%
+% - The option trace_stack_layout is set, and the label represents
+% a traced event at which variable info is needed (call, exit,
+% or entrance to one branch of a branched control structure;
+% fail events have no variable information).
%
-% - the option agc_stack_layout is set, and the label represents
+% - The option agc_stack_layout is set, and the label represents
% a point where execution can resume after a procedure call or
% after backtracking.
%
-% If either of these conditions holds for a given label at which there are some
-% live variables, all the fields above will be present in the stack layout
-% table for that label. However, the pointer to the live data names vector
-% will be NULL unless the first condition holds for the label (i.e. the label
-% is used in execution tracing).
-%
-% If neither condition holds for a given label, or if the number of live
-% variables at that label is zero, then the "# of live vars" field will be zero
-% and the last four fields will not be present.
+% If there are no number of live variables at a label, the "# of live vars"
+% field will be zero and the last four fields will not be present.
+% Even if there are some live variables at a label, however, the pointer
+% to the live data names vector will be NULL unless the first condition
+% holds for the label (i.e. the label is used in execution tracing).
%
% XXX: Presently, type parameter vectors are not created, and
% inst information is ignored. We also do not yet enable procid stack
@@ -137,17 +139,18 @@
:- interface.
-:- import_module hlds_module, list, llds.
+:- import_module hlds_module, llds.
+:- import_module list, set_bbbtree.
-:- pred stack_layout__generate_llds(module_info, module_info, list(c_module)).
-:- mode stack_layout__generate_llds(in, out, out) is det.
+:- pred stack_layout__generate_llds(module_info::in, module_info::out,
+ list(c_module)::out, set_bbbtree(label)::out) is det.
:- implementation.
:- import_module globals, options, continuation_info, llds_out.
:- import_module hlds_data, hlds_pred, base_type_layout, prog_data, prog_out.
-:- import_module assoc_list, bool, string, int, map, std_util, require.
-:- import_module set.
+:- import_module assoc_list, bool, string, int, require.
+:- import_module map, std_util, term, set.
:- type stack_layout_info --->
stack_layout_info(
@@ -156,16 +159,21 @@
bool, % generate agc layout info?
bool, % generate tracing layout info?
bool, % generate procedure id layout info?
- list(c_module) % generated data
+ list(c_module), % generated data
+ set_bbbtree(label)
+ % the set of labels with stack layouts
).
%---------------------------------------------------------------------------%
- % Initialize the StackLayoutInfo, and begin processing.
-stack_layout__generate_llds(ModuleInfo0, ModuleInfo, CModules) :-
+ % Process all the continuation information stored in the HLDS,
+ % converting it into LLDS data structures.
+
+stack_layout__generate_llds(ModuleInfo0, ModuleInfo, CModules,
+ StackLayoutLabels) :-
module_info_get_continuation_info(ModuleInfo0, ContinuationInfo),
- continuation_info__get_all_proc_layouts(ProcLayoutList,
- ContinuationInfo, _),
+ continuation_info__get_all_proc_layouts(ContinuationInfo,
+ ProcLayoutList),
module_info_name(ModuleInfo0, ModuleName),
module_info_get_cell_count(ModuleInfo0, CellCount),
@@ -174,61 +182,77 @@
globals__lookup_bool_option(Globals, trace_stack_layout, TraceLayout),
globals__lookup_bool_option(Globals, procid_stack_layout,
ProcInfoLayout),
+ set_bbbtree__init(StackLayoutLabels0),
LayoutInfo0 = stack_layout_info(ModuleName, CellCount, AgcLayout,
- TraceLayout, ProcInfoLayout, []),
+ TraceLayout, ProcInfoLayout, [], StackLayoutLabels0),
list__foldl(stack_layout__construct_layouts, ProcLayoutList,
LayoutInfo0, LayoutInfo),
stack_layout__get_cmodules(CModules, LayoutInfo, _),
+ stack_layout__get_label_set(StackLayoutLabels, LayoutInfo, _),
stack_layout__get_cell_number(FinalCellCount, LayoutInfo, _),
module_info_set_cell_count(ModuleInfo0, FinalCellCount, ModuleInfo).
%---------------------------------------------------------------------------%
- % Construct the layouts for a single procedure.
+ % Construct the layouts that concern a single procedure:
+ % the procedure-specific layout and the layouts of the labels
+ % inside that procedure.
:- pred stack_layout__construct_layouts(proc_layout_info::in,
- stack_layout_info::in, stack_layout_info::out) is det.
+ stack_layout_info::in, stack_layout_info::out) is det.
stack_layout__construct_layouts(ProcLayoutInfo) -->
-
- { ProcLayoutInfo = proc_layout_info(MaybeGeneralInfo, InternalMap,
- EntryInfo, ExitInfo) },
-
- ( { MaybeGeneralInfo = yes(GeneralInfo) } ->
- stack_layout__construct_proc_layout(GeneralInfo, EntryInfo,
- ExitInfo),
- { GeneralInfo = proc_layout_general_info(ProcLabel, _, _, _) },
- { map__to_assoc_list(InternalMap, Internals) },
- list__foldl(stack_layout__construct_internal_layout(ProcLabel),
- Internals)
- ;
- { error("stack_layout__construct_layouts: uninitialized proc layout") }
- ).
+ { ProcLayoutInfo = proc_layout_info(ProcLabel, Detism,
+ StackSlots, SuccipLoc, CallLabel, InternalMap) },
+ stack_layout__construct_proc_layout(ProcLabel, Detism,
+ StackSlots, SuccipLoc, CallLabel),
+ { map__to_assoc_list(InternalMap, Internals) },
+ list__foldl(stack_layout__construct_internal_layout(ProcLabel),
+ Internals).
%---------------------------------------------------------------------------%
- % Construct the layout describing a single procedure.
+ % Construct a procedure-specific layout.
+
+:- pred stack_layout__construct_proc_layout(proc_label::in,
+ determinism::in, int::in, maybe(int)::in, maybe(label)::in,
+ stack_layout_info::in, stack_layout_info::out) is det.
-:- pred stack_layout__construct_proc_layout(proc_layout_general_info::in,
- maybe(continuation_label_info)::in,
- maybe(continuation_label_info)::in,
- stack_layout_info::in, stack_layout_info::out) is det.
-
-stack_layout__construct_proc_layout(GeneralInfo, MaybeEntryInfo,
- MaybeExitInfo) -->
- { GeneralInfo = proc_layout_general_info(ProcLabel, Detism,
- StackSlots, SuccipLoc) },
+stack_layout__construct_proc_layout(ProcLabel, Detism, StackSlots,
+ MaybeSuccipLoc, MaybeCallLabel) -->
{
- SuccipLoc = yes(Location0)
+ MaybeSuccipLoc = yes(Location0)
->
Location = Location0
;
% Use a dummy location of -1 if there is
- % no succip on the stack. The runtime system
- % might be able to work around this, depending
- % upon what it is using the stack layouts for.
+ % no succip on the stack.
+ %
+ % This case can arise in two circumstances.
+ % First, procedures that use the nondet stack
+ % have a special slot for the succip, so the
+ % succip is not stored in a general purpose
+ % slot. Second, procedures that use the det stack
+ % but which do not call other procedures
+ % do not save the succip on the stack.
+ %
+ % The tracing system does not care about the
+ % location of the saved succip. The accurate
+ % garbage collector does. It should know from
+ % the determinism that the procedure uses the
+ % nondet stack, which takes care of the first
+ % possibility above. Procedures that do not call
+ % other procedures do not establish resumption
+ % points and thus agc is not interested in them.
+ % As far as stack dumps go, calling error counts
+ % as a call, so any procedure that may call error
+ % (directly or indirectly) will have its saved succip
+ % location recorded, so the stack dump will work.
+ %
+ % Future uses of stack layouts will have to have
+ % similar constraints.
Location = -1
},
{ determinism_components(Detism, _, at_most_many) ->
@@ -244,32 +268,37 @@
{ stack_layout__represent_determinism(Detism, DetismRval) },
{ MaybeRvals0 = [yes(CodeAddrRval), yes(DetismRval),
yes(StackSlotsRval), yes(SuccipRval)] },
- stack_layout__get_module_name(ModuleName),
stack_layout__get_procid_stack_layout(ProcIdLayout),
(
{ ProcIdLayout = yes }
->
{ stack_layout__construct_procid_rvals(ProcLabel, IdRvals) },
- { list__append(MaybeRvals0, IdRvals, MaybeRvals1) },
+ { list__append(MaybeRvals0, IdRvals, MaybeRvals1) }
+ ;
+ { MaybeRvals1 = MaybeRvals0 }
+ ),
- stack_layout__get_trace_stack_layout(TraceLayout),
- (
- { TraceLayout = yes }
- ->
- stack_layout__construct_trace_rvals(MaybeEntryInfo,
- MaybeExitInfo, TraceRvals),
- { list__append(MaybeRvals1, TraceRvals, MaybeRvals) }
+ stack_layout__get_module_name(ModuleName),
+ stack_layout__get_trace_stack_layout(TraceLayout),
+ (
+ { TraceLayout = yes }
+ ->
+ ( { MaybeCallLabel = yes(CallLabel) } ->
+ { CallRval = yes(const(data_addr_const(
+ data_addr(ModuleName,
+ stack_layout(CallLabel))))) },
+ { list__append(MaybeRvals1, [CallRval], MaybeRvals) }
;
- { MaybeRvals = MaybeRvals1 }
+ { error("stack_layout__construct_proc_layout: call label not present") }
)
;
- { MaybeRvals = MaybeRvals0 }
+ { MaybeRvals = MaybeRvals1 }
),
{ CModule = c_data(ModuleName, stack_layout(Label), yes,
MaybeRvals, []) },
- stack_layout__add_cmodule(CModule).
+ stack_layout__add_cmodule(CModule, Label).
%---------------------------------------------------------------------------%
@@ -315,7 +344,7 @@
%---------------------------------------------------------------------------%
- % Construct the layout describing a single continuation label.
+ % Construct the layout describing a single internal label.
:- pred stack_layout__construct_internal_layout(proc_label::in,
pair(label, internal_layout_info)::in,
@@ -326,74 +355,40 @@
stack_layout__get_module_name(ModuleName),
{ EntryAddrRval = const(data_addr_const(data_addr(ModuleName,
stack_layout(local(ProcLabel))))) },
-
- stack_layout__construct_agc_rvals(Internal, AgcRvals),
-
- { LayoutRvals = [yes(EntryAddrRval) | AgcRvals] },
-
+ { Label = local(_, LabelNum0) ->
+ LabelNum = LabelNum0
+ ;
+ LabelNum = -1
+ },
+ { LabelNumRval = const(int_const(LabelNum)) },
+ stack_layout__construct_internal_rvals(Internal, AgcRvals),
+ { LayoutRvals = [yes(EntryAddrRval), yes(LabelNumRval) | AgcRvals] },
{ CModule = c_data(ModuleName, stack_layout(Label), yes,
LayoutRvals, []) },
- stack_layout__add_cmodule(CModule).
+ stack_layout__add_cmodule(CModule, Label).
- % Construct the rvals required for tracing.
-
-:- pred stack_layout__construct_trace_rvals(maybe(continuation_label_info)::in,
- maybe(continuation_label_info)::in, list(maybe(rval))::out,
- stack_layout_info::in, stack_layout_info::out) is det.
+ % Construct the rvals required for accurate GC or for tracing.
-stack_layout__construct_trace_rvals(MaybeEntryInfo, MaybeExitInfo,
- RvalList) -->
- (
- { MaybeEntryInfo = yes(EntryInfo) },
- { MaybeExitInfo = yes(ExitInfo) }
- ->
- { EntryInfo = continuation_label_info(EntryLvals, EntryTVars) },
- { ExitInfo = continuation_label_info(ExitLvals, ExitTVars) },
- stack_layout__construct_livelval_rvals(EntryLvals, EntryTVars,
- EntryRvals),
- stack_layout__construct_livelval_rvals(ExitLvals, ExitTVars,
- ExitRvals),
- { list__append(EntryRvals, ExitRvals, RvalList) }
- ;
- { error("stack_layout__construct_trace_rvals: entry or exit information not available.") }
- ).
-
- % Construct the rvals required for accurate GC.
-
-:- pred stack_layout__construct_agc_rvals(internal_layout_info::in,
+:- pred stack_layout__construct_internal_rvals(internal_layout_info::in,
list(maybe(rval))::out,
stack_layout_info::in, stack_layout_info::out) is det.
-stack_layout__construct_agc_rvals(Internal, RvalList) -->
- stack_layout__get_agc_stack_layout(AgcStackLayout),
+stack_layout__construct_internal_rvals(Internal, RvalList) -->
(
- { AgcStackLayout = yes }
+ { Internal = yes(layout_label_info(LiveLvalSet, TVars)) }
->
- { Internal = internal_layout_info(ContinuationLabelInfo) },
- {
- ContinuationLabelInfo = yes(continuation_label_info(
- LiveLvalSet0, TVars0))
- ->
- LiveLvalSet = LiveLvalSet0,
- TVars = TVars0
- ;
- % This label is not being used as a continuation,
- % or we are not doing accurate GC, so we record
- % no live values here.
- % This might not be a true reflection of the
- % liveness at this point, so the values cannot
- % be relied upon by the runtime system unless
- % you know you are at a continuation (and doing
- % accurate GC).
-
- set__init(LiveLvalSet),
- set__init(TVars)
- },
stack_layout__construct_livelval_rvals(LiveLvalSet, TVars,
RvalList)
;
- { RvalList = [yes(const(int_const(0))),
- yes(const(int_const(0)))] }
+ % This label is not being used as a continuation,
+ % or we are not doing accurate GC, so we record
+ % no live values here.
+ % This might not be a true reflection of the
+ % liveness at this point, so the values cannot
+ % be relied upon by the runtime system unless
+ % you know you are at a continuation (and doing
+ % accurate GC).
+ { RvalList = [yes(const(int_const(0)))] }
).
%---------------------------------------------------------------------------%
@@ -403,34 +398,60 @@
stack_layout_info, stack_layout_info).
:- mode stack_layout__construct_livelval_rvals(in, in, out, in, out) is det.
-stack_layout__construct_livelval_rvals(LiveLvalSet, TVarSet, RvalList) -->
+stack_layout__construct_livelval_rvals(LiveLvalSet, TVarLocnSet, RvalList) -->
{ set__to_sorted_list(LiveLvalSet, LiveLvals) },
{ list__length(LiveLvals, Length) },
- { LengthRval = const(int_const(Length)) },
- stack_layout__construct_liveval_pairs(LiveLvals, LiveValRval,
- NamesRval),
-
- { set__to_sorted_list(TVarSet, TVars) },
- { assoc_list__values(TVars, TypeParamLvals) },
- stack_layout__construct_type_parameter_locn_vector(TypeParamLvals,
- TypeParamRval),
-
- { RvalList = [yes(LengthRval), yes(LiveValRval),
- yes(NamesRval), yes(TypeParamRval)] }.
+ { VarLengthRval = const(int_const(Length)) },
+ ( { Length > 0 } ->
+ stack_layout__construct_liveval_pairs(LiveLvals, LiveValRval,
+ NamesRval),
+
+ { set__to_sorted_list(TVarLocnSet, TVarLocns) },
+ stack_layout__construct_type_param_locn_vector(TVarLocns, 1,
+ TypeParamLocs),
+ stack_layout__get_next_cell_number(CNum1),
+ { TypeParamRval = create(0, TypeParamLocs, no, CNum1,
+ "stack_layout_type_param_locn_vector") },
+ { list__length(TypeParamLocs, TypeParamsLength) },
+ { TypeParamLengthRval = const(int_const(TypeParamsLength)) },
+
+ { RvalList = [yes(VarLengthRval), yes(LiveValRval),
+ yes(NamesRval), yes(TypeParamLengthRval),
+ yes(TypeParamRval)] }
+ ;
+ { RvalList = [yes(VarLengthRval)] }
+ ).
%---------------------------------------------------------------------------%
-:- pred stack_layout__construct_type_parameter_locn_vector(list(lval)::in,
- rval::out, stack_layout_info::in, stack_layout_info::out) is det.
+ % Given a association list of type variables and their locations
+ % sorted on the type variables, represent them in an array of
+ % location descriptions indexed by the type variable. The next
+ % slot to fill is given by the second argument.
+
+:- pred stack_layout__construct_type_param_locn_vector(
+ assoc_list(tvar, lval)::in, int::in, list(maybe(rval))::out,
+ stack_layout_info::in, stack_layout_info::out) is det.
+
+stack_layout__construct_type_param_locn_vector([], _, []) --> [].
+stack_layout__construct_type_param_locn_vector([TVar - Locn | TVarLocns],
+ CurSlot, Vector) -->
+ { term__var_to_int(TVar, TVarNum) },
+ { NextSlot is CurSlot + 1 },
+ ( { TVarNum = CurSlot } ->
+ { stack_layout__represent_lval(Locn, Rval) },
+ stack_layout__construct_type_param_locn_vector(TVarLocns,
+ NextSlot, VectorTail),
+ { Vector = [yes(Rval) | VectorTail] }
+ ; { TVarNum > CurSlot } ->
+ stack_layout__construct_type_param_locn_vector(TVarLocns,
+ NextSlot, VectorTail),
+ % This slot will never be referred to.
+ { Vector = [yes(const(int_const(0))) | VectorTail] }
+ ;
-stack_layout__construct_type_parameter_locn_vector(TypeParamLvals,
- TypeParamVector) -->
- { MakeLval = lambda([Lval::in, yes(Rval)::out] is det, (
- stack_layout__represent_lval(Lval, Rval))) },
- { list__map(MakeLval, TypeParamLvals, TypeParamLocs) },
- stack_layout__get_next_cell_number(CNum1),
- { TypeParamVector = create(0, TypeParamLocs, no, CNum1,
- "stack_layout_type_parameter_locn_vector") }.
+ { error("unsorted tvars in construct_type_param_locn_vector") }
+ ).
% Construct a vector of (lval, live_value_type) pairs,
% and a corresponding vector of variable names.
@@ -488,7 +509,7 @@
%
% Low integers for special values, a pointer for other values.
% (Remember to keep the low integers below the max varint value in
- % runtime/type_info.h).
+ % runtime/mercury_type_info.h).
:- pred stack_layout__represent_live_value_type(live_value_type, rval,
stack_layout_info, stack_layout_info).
@@ -509,8 +530,8 @@
stack_layout__represent_live_value_type(var(Type, _Inst), Rval) -->
stack_layout__get_cell_number(CNum0),
{ base_type_layout__construct_pseudo_type_info(Type, Rval0,
- CNum0, CNum) },
- stack_layout__set_cell_number(CNum),
+ CNum0, CNum1) },
+ stack_layout__set_cell_number(CNum1),
% XXX hack - don't yet write out insts
{ Rval1 = const(int_const(-1)) },
stack_layout__get_next_cell_number(CNum2),
@@ -633,60 +654,68 @@
stack_layout_info::in, stack_layout_info::out) is det.
stack_layout__get_module_name(ModuleName, LayoutInfo, LayoutInfo) :-
- LayoutInfo = stack_layout_info(ModuleName, _, _, _, _, _).
+ LayoutInfo = stack_layout_info(ModuleName, _, _, _, _, _, _).
:- pred stack_layout__get_next_cell_number(int::out,
stack_layout_info::in, stack_layout_info::out) is det.
stack_layout__get_next_cell_number(CNum0, LayoutInfo0, LayoutInfo) :-
- LayoutInfo0 = stack_layout_info(A, CNum0, C, D, E, F),
+ LayoutInfo0 = stack_layout_info(A, CNum0, C, D, E, F, G),
CNum is CNum0 + 1,
- LayoutInfo = stack_layout_info(A, CNum, C, D, E, F).
+ LayoutInfo = stack_layout_info(A, CNum, C, D, E, F, G).
:- pred stack_layout__get_cell_number(int::out,
stack_layout_info::in, stack_layout_info::out) is det.
stack_layout__get_cell_number(CNum, LayoutInfo, LayoutInfo) :-
- LayoutInfo = stack_layout_info(_, CNum, _, _, _, _).
-
-:- pred stack_layout__get_cmodules(list(c_module)::out,
- stack_layout_info::in, stack_layout_info::out) is det.
-
-stack_layout__get_cmodules(CModules, LayoutInfo, LayoutInfo) :-
- LayoutInfo = stack_layout_info(_, _, _, _, _, CModules).
+ LayoutInfo = stack_layout_info(_, CNum, _, _, _, _, _).
:- pred stack_layout__get_agc_stack_layout(bool::out,
stack_layout_info::in, stack_layout_info::out) is det.
stack_layout__get_agc_stack_layout(AgcStackLayout, LayoutInfo, LayoutInfo) :-
- LayoutInfo = stack_layout_info(_, _, AgcStackLayout, _, _, _).
+ LayoutInfo = stack_layout_info(_, _, AgcStackLayout, _, _, _, _).
:- pred stack_layout__get_trace_stack_layout(bool::out,
stack_layout_info::in, stack_layout_info::out) is det.
stack_layout__get_trace_stack_layout(TraceStackLayout, LayoutInfo,
LayoutInfo) :-
- LayoutInfo = stack_layout_info(_, _, _, TraceStackLayout, _, _).
+ LayoutInfo = stack_layout_info(_, _, _, TraceStackLayout, _, _, _).
:- pred stack_layout__get_procid_stack_layout(bool::out,
stack_layout_info::in, stack_layout_info::out) is det.
stack_layout__get_procid_stack_layout(ProcIdStackLayout, LayoutInfo,
LayoutInfo) :-
- LayoutInfo = stack_layout_info(_, _, _, _, ProcIdStackLayout, _).
+ LayoutInfo = stack_layout_info(_, _, _, _, ProcIdStackLayout, _, _).
+
+:- pred stack_layout__get_cmodules(list(c_module)::out,
+ stack_layout_info::in, stack_layout_info::out) is det.
+
+stack_layout__get_cmodules(CModules, LayoutInfo, LayoutInfo) :-
+ LayoutInfo = stack_layout_info(_, _, _, _, _, CModules, _).
-:- pred stack_layout__add_cmodule(c_module::in,
+:- pred stack_layout__get_label_set(set_bbbtree(label)::out,
stack_layout_info::in, stack_layout_info::out) is det.
-stack_layout__add_cmodule(CModule, LayoutInfo0, LayoutInfo) :-
- LayoutInfo0 = stack_layout_info(A, B, C, D, E, CModules0),
+stack_layout__get_label_set(StackLayoutLabels, LayoutInfo, LayoutInfo) :-
+ LayoutInfo = stack_layout_info(_, _, _, _, _, _, StackLayoutLabels).
+
+:- pred stack_layout__add_cmodule(c_module::in, label::in,
+ stack_layout_info::in, stack_layout_info::out) is det.
+
+stack_layout__add_cmodule(CModule, Label, LayoutInfo0, LayoutInfo) :-
+ LayoutInfo0 = stack_layout_info(A, B, C, D, E, CModules0,
+ StackLayoutLabels0),
CModules = [CModule | CModules0],
- LayoutInfo = stack_layout_info(A, B, C, D, E, CModules).
+ set_bbbtree__insert(StackLayoutLabels0, Label, StackLayoutLabels),
+ LayoutInfo = stack_layout_info(A, B, C, D, E, CModules,
+ StackLayoutLabels).
:- pred stack_layout__set_cell_number(int::in,
stack_layout_info::in, stack_layout_info::out) is det.
stack_layout__set_cell_number(CNum, LayoutInfo0, LayoutInfo) :-
- LayoutInfo0 = stack_layout_info(A, _, C, D, E, F),
- LayoutInfo = stack_layout_info(A, CNum, C, D, E, F).
-
+ LayoutInfo0 = stack_layout_info(A, _, C, D, E, F, G),
+ LayoutInfo = stack_layout_info(A, CNum, C, D, E, F, G).
Index: compiler/store_alloc.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/store_alloc.m,v
retrieving revision 1.60
diff -u -u -r1.60 store_alloc.m
--- store_alloc.m 1998/03/24 00:06:59 1.60
+++ store_alloc.m 1998/03/31 10:04:23
@@ -37,7 +37,7 @@
:- implementation.
:- import_module follow_vars, liveness, hlds_goal, llds.
-:- import_module options, globals, goal_util, mode_util, instmap.
+:- import_module options, globals, goal_util, mode_util, instmap, trace.
:- import_module list, map, set, std_util, assoc_list.
:- import_module bool, int, require, term.
@@ -60,7 +60,12 @@
proc_info_goal(ProcInfo0, Goal2)
),
initial_liveness(ProcInfo0, ModuleInfo, Liveness0),
- set__init(ResumeVars0),
+ globals__lookup_bool_option(Globals, generate_trace, Trace),
+ ( Trace = yes ->
+ trace__fail_vars(ModuleInfo, ProcInfo0, ResumeVars0)
+ ;
+ set__init(ResumeVars0)
+ ),
store_alloc_in_goal(Goal2, Liveness0, ResumeVars0, ModuleInfo, Goal, _),
proc_info_set_goal(ProcInfo0, Goal, ProcInfo).
Index: compiler/string_switch.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/string_switch.m,v
retrieving revision 1.28
diff -u -u -r1.28 string_switch.m
--- string_switch.m 1998/03/03 17:36:05 1.28
+++ string_switch.m 1998/03/28 04:05:48
@@ -303,27 +303,16 @@
{ LabelCode = node([
label(Label) - Comment
]) },
- code_info__get_maybe_trace_info(MaybeTraceInfo),
- ( { MaybeTraceInfo = yes(TraceInfo) } ->
- { Goal = _ - GoalInfo },
- { goal_info_get_goal_path(GoalInfo, Path) },
- trace__generate_event_code(switch(Path), TraceInfo,
- TraceCode)
- ;
- { TraceCode = empty }
- ),
+ code_info__grab_code_info(CodeInfo),
+ trace__maybe_generate_internal_event_code(Goal, TraceCode),
+ code_gen__generate_goal(CodeModel, Goal, GoalCode),
+ code_info__generate_branch_end(CodeModel, StoreMap, SaveCode),
(
{ string_switch__this_is_last_case(Slot, TblSize,
HashSlotMap) }
->
- code_gen__generate_goal(CodeModel, Goal, GoalCode),
- code_info__generate_branch_end(CodeModel, StoreMap,
- SaveCode)
+ []
;
- code_info__grab_code_info(CodeInfo),
- code_gen__generate_goal(CodeModel, Goal, GoalCode),
- code_info__generate_branch_end(CodeModel, StoreMap,
- SaveCode),
code_info__slap_code_info(CodeInfo)
),
{ FinishCode = node([
Index: compiler/switch_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/switch_gen.m,v
retrieving revision 1.64
diff -u -u -r1.64 switch_gen.m
--- switch_gen.m 1998/03/03 17:36:06 1.64
+++ switch_gen.m 1998/03/28 04:41:34
@@ -307,21 +307,13 @@
switch_gen__generate_cases([case(_, _, Cons, Goal) | Cases], Var, CodeModel,
CanFail, StoreMap, EndLabel, CasesCode) -->
- code_info__get_maybe_trace_info(MaybeTraceInfo),
- ( { MaybeTraceInfo = yes(TraceInfo) } ->
- { Goal = _ - GoalInfo },
- { goal_info_get_goal_path(GoalInfo, Path) },
- trace__generate_event_code(switch(Path), TraceInfo,
- TraceCode)
- ;
- { TraceCode = empty }
- ),
code_info__grab_code_info(CodeInfo0),
(
{ Cases = [_|_] ; CanFail = can_fail }
->
unify_gen__generate_tag_test(Var, Cons, branch_on_failure,
NextLabel, TestCode),
+ trace__maybe_generate_internal_event_code(Goal, TraceCode),
code_gen__generate_goal(CodeModel, Goal, GoalCode),
code_info__generate_branch_end(CodeModel, StoreMap, SaveCode),
{ ElseCode = node([
@@ -340,6 +332,7 @@
code_info__grab_code_info(CodeInfo1),
code_info__slap_code_info(CodeInfo0)
;
+ trace__maybe_generate_internal_event_code(Goal, TraceCode),
code_gen__generate_goal(CodeModel, Goal, GoalCode),
code_info__generate_branch_end(CodeModel, StoreMap, SaveCode),
{ ThisCaseCode =
Index: compiler/tag_switch.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/tag_switch.m,v
retrieving revision 1.43
diff -u -u -r1.43 tag_switch.m
--- tag_switch.m 1998/03/03 17:36:08 1.43
+++ tag_switch.m 1998/03/28 04:11:24
@@ -659,15 +659,8 @@
->
% There is no secondary tag, so there is no switch on it
( { GoalList = [-1 - Goal] } ->
- code_info__get_maybe_trace_info(MaybeTraceInfo),
- ( { MaybeTraceInfo = yes(TraceInfo) } ->
- { Goal = _ - GoalInfo },
- { goal_info_get_goal_path(GoalInfo, Path) },
- trace__generate_event_code(switch(Path),
- TraceInfo, TraceCode)
- ;
- { TraceCode = empty }
- ),
+ trace__maybe_generate_internal_event_code(Goal,
+ TraceCode),
code_gen__generate_goal(CodeModel, Goal, GoalCode),
code_info__generate_branch_end(CodeModel, StoreMap,
SaveCode),
@@ -803,15 +796,6 @@
tag_switch__generate_secondary_try_me_else_chain([Case0 | Cases0], StagRval,
CodeModel, CanFail, StoreMap, EndLabel, FailLabel, Code) -->
{ Case0 = Secondary - Goal },
- code_info__get_maybe_trace_info(MaybeTraceInfo),
- ( { MaybeTraceInfo = yes(TraceInfo) } ->
- { Goal = _ - GoalInfo },
- { goal_info_get_goal_path(GoalInfo, Path) },
- trace__generate_event_code(switch(Path), TraceInfo,
- TraceCode)
- ;
- { TraceCode = empty }
- ),
( { Cases0 = [_|_] ; CanFail = can_fail } ->
code_info__grab_code_info(CodeInfo),
code_info__get_next_label(ElseLabel),
@@ -821,6 +805,7 @@
label(ElseLabel))
- "test remote sec tag only"
]) },
+ trace__maybe_generate_internal_event_code(Goal, TraceCode),
code_gen__generate_goal(CodeModel, Goal, GoalCode),
code_info__generate_branch_end(CodeModel, StoreMap, SaveCode),
{ GotoLabelCode = node([
@@ -850,6 +835,7 @@
{ Code = tree(ThisCode, FailCode) }
)
;
+ trace__maybe_generate_internal_event_code(Goal, TraceCode),
code_gen__generate_goal(CodeModel, Goal, GoalCode),
code_info__generate_branch_end(CodeModel, StoreMap, SaveCode),
{ GotoCode = node([
@@ -880,15 +866,6 @@
CodeModel, CanFail, StoreMap, EndLabel, FailLabel,
PrevTests0, PrevCases0, Code) -->
{ Case0 = Secondary - Goal },
- code_info__get_maybe_trace_info(MaybeTraceInfo),
- ( { MaybeTraceInfo = yes(TraceInfo) } ->
- { Goal = _ - GoalInfo },
- { goal_info_get_goal_path(GoalInfo, Path) },
- trace__generate_event_code(switch(Path), TraceInfo,
- TraceCode)
- ;
- { TraceCode = empty }
- ),
( { Cases0 = [_|_] ; CanFail = can_fail } ->
code_info__grab_code_info(CodeInfo),
code_info__get_next_label(ThisStagLabel),
@@ -902,6 +879,7 @@
label(ThisStagLabel) -
"handle next secondary tag"
]) },
+ trace__maybe_generate_internal_event_code(Goal, TraceCode),
code_gen__generate_goal(CodeModel, Goal, GoalCode),
code_info__generate_branch_end(CodeModel, StoreMap, SaveCode),
{ GotoCode = node([
@@ -931,6 +909,7 @@
{ Code = tree(PrevTests, tree(FailCode, PrevCases)) }
)
;
+ trace__maybe_generate_internal_event_code(Goal, TraceCode),
code_gen__generate_goal(CodeModel, Goal, GoalCode),
code_info__generate_branch_end(CodeModel, StoreMap, SaveCode),
{ GotoCode = node([
@@ -976,26 +955,15 @@
label(NewLabel) -
"start of case in secondary tag switch"
]) },
- code_info__get_maybe_trace_info(MaybeTraceInfo),
- ( { MaybeTraceInfo = yes(TraceInfo) } ->
- { Goal = _ - GoalInfo },
- { goal_info_get_goal_path(GoalInfo, Path) },
- trace__generate_event_code(switch(Path),
- TraceInfo, TraceCode)
- ;
- { TraceCode = empty }
- ),
+ code_info__grab_code_info(CodeInfo),
+ trace__maybe_generate_internal_event_code(Goal,
+ TraceCode),
+ code_gen__generate_goal(CodeModel, Goal, GoalCode),
+ code_info__generate_branch_end(CodeModel, StoreMap,
+ SaveCode),
( { CaseList1 = [] } ->
- code_gen__generate_goal(CodeModel, Goal,
- GoalCode),
- code_info__generate_branch_end(CodeModel,
- StoreMap, SaveCode)
+ []
;
- code_info__grab_code_info(CodeInfo),
- code_gen__generate_goal(CodeModel, Goal,
- GoalCode),
- code_info__generate_branch_end(CodeModel,
- StoreMap, SaveCode),
code_info__slap_code_info(CodeInfo)
),
{ GotoCode = node([
@@ -1059,15 +1027,8 @@
),
{ MaybeFinalCodeInfo = MaybeFinalCodeInfo0 }
; { StagGoals = [CurSec - Goal] } ->
- code_info__get_maybe_trace_info(MaybeTraceInfo),
- ( { MaybeTraceInfo = yes(TraceInfo) } ->
- { Goal = _ - GoalInfo },
- { goal_info_get_goal_path(GoalInfo, Path) },
- trace__generate_event_code(switch(Path),
- TraceInfo, TraceCode)
- ;
- { TraceCode = empty }
- ),
+ trace__maybe_generate_internal_event_code(Goal,
+ TraceCode),
code_gen__generate_goal(CodeModel, Goal, GoalCode),
code_info__generate_branch_end(CodeModel, StoreMap,
SaveCode),
Index: compiler/trace.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/trace.m,v
retrieving revision 1.7
diff -u -u -r1.7 trace.m
--- trace.m 1998/02/03 08:18:35 1.7
+++ trace.m 1998/03/31 10:50:00
@@ -3,7 +3,9 @@
% This file may only be copied under the terms of the GNU General
% Public License - see the file COPYING in the Mercury distribution.
%-----------------------------------------------------------------------------%
-
+%
+% Author: zs.
+%
% This module handles the generation of traces for the trace analysis system.
%
% For the general basis of trace analysis systems, see the paper
@@ -11,13 +13,31 @@
% available from http://www.irisa.fr/lande/ducasse.
%
% We reserve two slots in the stack frame of the traced procedure.
-% One contains the call sequence number, which is set in the procedure prolog
+% One contains the call sequence number, which is set in the procedure prologue
% by incrementing a global counter. The other contains the call depth, which
% is also set by incrementing a global variable containing the depth of the
% caller. The caller sets this global variable from its own saved depth
% just before the call.
-
-% Author: zs.
+%
+% Each event has a label associated with it. The stack layout for that label
+% records what variables are live and where they are at the time of the event.
+% These labels are generated by the same predicate that generates the code
+% for the event, and are initially not used for anything else.
+% However, some of these labels may be fallen into from other places,
+% and thus optimization may redirect references from labels to one of these
+% labels. This cannot happen in the opposite direction, due to the reference
+% to each event's label from the event's pragma C code instruction.
+% (This prevents labelopt from removing the label.)
+%
+% We classify events into three kinds: external events (call, exit, fail),
+% internal events (switch, disj, ite_then, ite_else), and nondet pragma C
+% events (first, later). Code_gen.m, which calls this module to generate
+% all external events, checks whether tracing is required before calling us;
+% the predicates handing internal and nondet pragma C events must check this
+% themselves. The predicates generating internal events need the goal
+% following the event as a parameter. For the first and later arms of
+% nondet pragma C code, there is no such hlds_goal, which is why these events
+% need a bit of special treatment.
%-----------------------------------------------------------------------------%
@@ -25,42 +45,112 @@
:- interface.
-:- import_module hlds_goal, llds, code_info.
-
-:- type trace_port ---> call
- ; exit
- ; fail
- ; ite_then(goal_path)
- ; ite_else(goal_path)
- ; switch(goal_path)
- ; disj(goal_path).
+:- import_module hlds_goal, hlds_pred, hlds_module.
+:- import_module prog_data, llds, code_info.
+:- import_module assoc_list, set, term.
+
+:- type external_trace_port
+ ---> call
+ ; exit
+ ; fail.
+
+:- type nondet_pragma_trace_port
+ ---> nondet_pragma_first
+ ; nondet_pragma_later.
:- type trace_info.
+ % Return the set of input variables whose values should be preserved
+ % until the exit and fail ports. This will be all the input variables,
+ % except those that can be totally clobbered during the evaluation
+ % of the procedure (those partially clobbered may still be of interest,
+ % although to handle them properly we need to record insts in stack
+ % layouts).
+:- pred trace__fail_vars(module_info::in, proc_info::in, set(var)::out) is det.
+
+ % Set up the code generator state for tracing, by reserving
+ % slots for the call number and call depth.
:- pred trace__setup(code_info::in, code_info::out) is det.
+ % Generate code to fill in the slots for the call number and depth.
:- pred trace__generate_slot_fill_code(trace_info::in, code_tree::out) is det.
+ % Generate code to reset the call depth before a call.
:- pred trace__generate_depth_reset_code(trace_info::in, code_tree::out) is det.
-:- pred trace__generate_event_code(trace_port::in, trace_info::in,
+ % If generate_trace is set, generate code for an internal trace event.
+ % This predicate must be called just before generating code for the
+ % given goal.
+:- pred trace__maybe_generate_internal_event_code(hlds_goal::in,
+ code_tree::out, code_info::in, code_info::out) is det.
+
+ % If generate_trace is set, generate code for a nondet pragma C code
+ % trace event.
+:- pred trace__maybe_generate_pragma_event_code(nondet_pragma_trace_port::in,
code_tree::out, code_info::in, code_info::out) is det.
+ % Generate code for an external trace event.
+ % Besides the trace code, we return the label on which we have hung
+ % the trace liveness information and data on the type variables in the
+ % liveness information, since some of our callers also need this
+ % information.
+:- pred trace__generate_external_event_code(external_trace_port::in,
+ trace_info::in, label::out, assoc_list(tvar, lval)::out, code_tree::out,
+ code_info::in, code_info::out) is det.
+
:- pred trace__path_to_string(goal_path::in, string::out) is det.
%-----------------------------------------------------------------------------%
:- implementation.
-:- import_module hlds_module, hlds_pred, llds_out, code_util, tree.
-:- import_module bool, int, list, std_util, string, require.
+:- import_module continuation_info, type_util, llds_out, tree.
+:- import_module (inst), instmap, inst_match, mode_util.
+:- import_module list, bool, int, string, map, std_util, varset, require.
+
+:- type trace_port
+ ---> call
+ ; exit
+ ; fail
+ ; ite_then
+ ; ite_else
+ ; switch
+ ; disj
+ ; nondet_pragma_first
+ ; nondet_pragma_later.
+
+ % Information specific to a trace port.
+:- type trace_port_info
+ ---> external
+ ; internal(
+ goal_path, % The path of the goal whose start
+ % this port represents.
+ set(var) % The pre-death set of this goal.
+ )
+ ; nondet_pragma.
+ % Information for tracing that is valid throughout the execution
+ % of a procedure.
:- type trace_info
---> trace_info(
lval, % stack slot of call sequence number
lval % stack slot of call depth
).
+trace__fail_vars(ModuleInfo, ProcInfo, FailVars) :-
+ proc_info_headvars(ProcInfo, HeadVars),
+ proc_info_argmodes(ProcInfo, Modes),
+ proc_info_arg_info(ProcInfo, ArgInfos),
+ mode_list_get_final_insts(Modes, ModuleInfo, Insts),
+ (
+ trace__build_fail_vars(HeadVars, Insts, ArgInfos,
+ ModuleInfo, FailVarsList)
+ ->
+ set__list_to_set(FailVarsList, FailVars)
+ ;
+ error("length mismatch in trace__fail_vars")
+ ).
+
trace__setup -->
code_info__get_trace_slot(CallNumSlot),
code_info__get_trace_slot(CallDepthSlot),
@@ -89,53 +179,222 @@
c_code(Stmt) - ""
]).
-trace__generate_event_code(Port, TraceInfo, TraceCode) -->
- code_info__get_pred_id(PredId),
- code_info__get_proc_id(ProcId),
- code_info__get_module_info(ModuleInfo),
+trace__maybe_generate_internal_event_code(Goal, Code) -->
+ code_info__get_maybe_trace_info(MaybeTraceInfo),
+ ( { MaybeTraceInfo = yes(TraceInfo) } ->
+ { Goal = _ - GoalInfo },
+ { goal_info_get_goal_path(GoalInfo, Path) },
+ { goal_info_get_pre_deaths(GoalInfo, PreDeaths) },
+ {
+ Path = [LastStep | _],
+ (
+ LastStep = switch(_),
+ PortPrime = switch
+ ;
+ LastStep = disj(_),
+ PortPrime = disj
+ ;
+ LastStep = ite_then,
+ PortPrime = ite_then
+ ;
+ LastStep = ite_else,
+ PortPrime = ite_else
+ )
+ ->
+ Port = PortPrime
+ ;
+ error("trace__generate_internal_event_code: bad path")
+ },
+ trace__generate_event_code(Port, internal(Path, PreDeaths),
+ TraceInfo, _, _, Code)
+ ;
+ { Code = empty }
+ ).
+
+trace__maybe_generate_pragma_event_code(PragmaPort, Code) -->
+ code_info__get_maybe_trace_info(MaybeTraceInfo),
+ ( { MaybeTraceInfo = yes(TraceInfo) } ->
+ { trace__convert_nondet_pragma_port_type(PragmaPort, Port) },
+ trace__generate_event_code(Port, nondet_pragma, TraceInfo,
+ _, _, Code)
+ ;
+ { Code = empty }
+ ).
+
+trace__generate_external_event_code(ExternalPort, TraceInfo,
+ Label, TvarDataList, Code) -->
+ { trace__convert_external_port_type(ExternalPort, Port) },
+ trace__generate_event_code(Port, external, TraceInfo,
+ Label, TvarDataList, Code).
+
+:- pred trace__generate_event_code(trace_port::in, trace_port_info::in,
+ trace_info::in, label::out, assoc_list(tvar, lval)::out,
+ code_tree::out, code_info::in, code_info::out) is det.
+
+trace__generate_event_code(Port, PortInfo, TraceInfo, Label, TvarDataList,
+ Code) -->
+ code_info__get_next_label(Label),
+ code_info__get_known_variables(LiveVars0),
{
- code_util__make_proc_label(ModuleInfo, PredId, ProcId, ProcLabel),
- llds_out__get_label(local(ProcLabel), yes, LabelStr),
+ PortInfo = external,
+ LiveVars = LiveVars0,
+ PathStr = ""
+ ;
+ PortInfo = internal(Path, PreDeaths),
+ set__to_sorted_list(PreDeaths, PreDeathList),
+ list__delete_elems(LiveVars0, PreDeathList, LiveVars),
+ trace__path_to_string(Path, PathStr)
+ ;
+ PortInfo = nondet_pragma,
+ LiveVars = [],
+ PathStr = ""
+ },
+ code_info__get_varset(VarSet),
+ code_info__get_instmap(InstMap),
+ { set__init(TvarSet0) },
+ trace__produce_vars(LiveVars, VarSet, InstMap, TvarSet0, TvarSet,
+ VarInfoList, ProduceCode),
+ { set__to_sorted_list(TvarSet, TvarList) },
+ code_info__variable_locations(VarLocs),
+ code_info__get_proc_info(ProcInfo),
+ { proc_info_typeinfo_varmap(ProcInfo, TypeInfoMap) },
+ { trace__find_typeinfos_for_tvars(TvarList, VarLocs, TypeInfoMap,
+ TvarDataList) },
+ code_info__max_reg_in_use(MaxReg),
+ {
+ set__list_to_set(VarInfoList, VarInfoSet),
+ set__list_to_set(TvarDataList, TvarDataSet),
+ LayoutLabelInfo = layout_label_info(VarInfoSet, TvarDataSet),
+ llds_out__get_label(Label, yes, LabelStr),
TraceInfo = trace_info(CallNumLval, CallDepthLval),
trace__stackref_to_string(CallNumLval, CallNumStr),
trace__stackref_to_string(CallDepthLval, CallDepthStr),
Quote = """",
Comma = ", ",
trace__port_to_string(Port, PortStr),
- ( trace__port_path(Port, Path) ->
- trace__path_to_string(Path, PathStr)
- ;
- PathStr = ""
- ),
+ IfStmt = "\tif (MR_trace_enabled) {\n",
+ EndStmt = "\t}",
+ SaveStmt = "\t\tsave_transient_registers();\n",
+ RestoreStmt = "\t\trestore_transient_registers();\n",
+ string__int_to_string(MaxReg, MaxRegStr),
string__append_list([
- "MR_trace(",
- "(const Word *) &mercury_data__stack_layout__", LabelStr, Comma,
- PortStr, Comma,
+ "\t\tMR_trace((const MR_Stack_Layout_Label *)\n",
+ "\t\t\t&mercury_data__stack_layout__", LabelStr, Comma, "\n",
+ "\t\t\t", PortStr, Comma,
CallNumStr, Comma,
- CallDepthStr, Comma,
- Quote, PathStr, Quote, ");\n"],
+ CallDepthStr, Comma, "\n",
+ "\t\t\t", Quote, PathStr, Quote, Comma,
+ MaxRegStr, ");\n"],
+ CallStmt),
+ string__append_list([IfStmt, SaveStmt, CallStmt, RestoreStmt, EndStmt],
TraceStmt),
- TraceCode = node([c_code(TraceStmt) - ""])
- }.
+ TraceCode =
+ node([
+ label(Label)
+ - "A label to hang trace liveness on",
+ % Referring to the label from the pragma_c
+ % prevents the label from being renamed
+ % or optimized away.
+ % The label is before the trace code
+ % because sometimes this pair is preceded
+ % by another label, and this way we can
+ % eliminate this other label.
+ pragma_c([], [pragma_c_raw_code(TraceStmt)],
+ may_call_mercury, yes(Label))
+ - ""
+ ]),
+ Code = tree(ProduceCode, TraceCode)
+ },
+ code_info__add_layout_for_label(Label, yes(LayoutLabelInfo)).
+
+:- pred trace__produce_vars(list(var)::in, varset::in, instmap::in,
+ set(tvar)::in, set(tvar)::out, list(var_info)::out, code_tree::out,
+ code_info::in, code_info::out) is det.
+
+trace__produce_vars([], _, _, Tvars, Tvars, [], empty) --> [].
+trace__produce_vars([Var | Vars], VarSet, InstMap, Tvars0, Tvars,
+ [VarInfo | VarInfos], tree(VarCode, VarsCode)) -->
+ code_info__produce_variable_in_reg_or_stack(Var, VarCode, Rval),
+ code_info__variable_type(Var, Type),
+ {
+ ( Rval = lval(LvalPrime) ->
+ Lval = LvalPrime
+ ;
+ error("var not an lval in trace__produce_vars")
+ % If the value of the variable is known,
+ % we record it as living in a nonexistent location, r0.
+ % The code that interprets layout information must know this.
+ % Lval = reg(r, 0)
+ ),
+ varset__lookup_name(VarSet, Var, "V_", Name),
+ instmap__lookup_var(InstMap, Var, Inst),
+ LiveType = var(Type, Inst),
+ VarInfo = var_info(Lval, LiveType, Name),
+ type_util__vars(Type, TypeVars),
+ set__insert_list(Tvars0, TypeVars, Tvars1)
+ },
+ trace__produce_vars(Vars, VarSet, InstMap, Tvars1, Tvars,
+ VarInfos, VarsCode).
+
+ % For each type variable in the given list, find out where the
+ % typeinfo var for that type variable is.
+
+:- pred trace__find_typeinfos_for_tvars(list(tvar)::in,
+ map(var, set(rval))::in, map(tvar, type_info_locn)::in,
+ assoc_list(tvar, lval)::out) is det.
+
+trace__find_typeinfos_for_tvars(TypeVars, VarLocs, TypeInfoMap, TypeInfoDatas)
+ :-
+ map__apply_to_list(TypeVars, TypeInfoMap, TypeInfoLocns),
+ list__map(type_info_locn_var, TypeInfoLocns, TypeInfoVars),
+
+ map__apply_to_list(TypeInfoVars, VarLocs, TypeInfoLvalSets),
+ FindSingleLval = lambda([Set::in, Lval::out] is det, (
+ (
+ set__remove_least(Set, Value, _),
+ Value = lval(Lval0)
+ ->
+ Lval = Lval0
+ ;
+ error("trace__find_typeinfos_for_tvars: typeinfo var not available")
+ ))
+ ),
+ list__map(FindSingleLval, TypeInfoLvalSets, TypeInfoLvals),
+ assoc_list__from_corresponding_lists(TypeVars, TypeInfoLvals,
+ TypeInfoDatas).
%-----------------------------------------------------------------------------%
-:- pred trace__port_path(trace_port::in, goal_path::out) is semidet.
+:- pred trace__build_fail_vars(list(var)::in, list(inst)::in,
+ list(arg_info)::in, module_info::in, list(var)::out) is semidet.
-trace__port_path(ite_then(Path), Path).
-trace__port_path(ite_else(Path), Path).
-trace__port_path(switch(Path), Path).
-trace__port_path(disj(Path), Path).
+trace__build_fail_vars([], [], [], _, []).
+trace__build_fail_vars([Var | Vars], [Inst | Insts], [Info | Infos],
+ ModuleInfo, FailVars) :-
+ trace__build_fail_vars(Vars, Insts, Infos, ModuleInfo, FailVars0),
+ Info = arg_info(_Loc, ArgMode),
+ (
+ ArgMode = top_in,
+ \+ inst_is_clobbered(ModuleInfo, Inst)
+ ->
+ FailVars = [Var | FailVars0]
+ ;
+ FailVars = FailVars0
+ ).
+
+%-----------------------------------------------------------------------------%
:- pred trace__port_to_string(trace_port::in, string::out) is det.
trace__port_to_string(call, "MR_PORT_CALL").
trace__port_to_string(exit, "MR_PORT_EXIT").
trace__port_to_string(fail, "MR_PORT_FAIL").
-trace__port_to_string(ite_then(_), "MR_PORT_THEN").
-trace__port_to_string(ite_else(_), "MR_PORT_ELSE").
-trace__port_to_string(switch(_), "MR_PORT_SWITCH").
-trace__port_to_string(disj(_), "MR_PORT_DISJ").
+trace__port_to_string(ite_then, "MR_PORT_THEN").
+trace__port_to_string(ite_else, "MR_PORT_ELSE").
+trace__port_to_string(switch, "MR_PORT_SWITCH").
+trace__port_to_string(disj, "MR_PORT_DISJ").
+trace__port_to_string(nondet_pragma_first, "MR_PORT_PRAGMA_FIRST").
+trace__port_to_string(nondet_pragma_later, "MR_PORT_PRAGMA_LATER").
:- pred trace__code_model_to_string(code_model::in, string::out) is det.
@@ -186,3 +445,18 @@
trace__path_step_to_string(ite_else, "e;").
trace__path_step_to_string(neg, "~;").
trace__path_step_to_string(exist, "q;").
+
+:- pred trace__convert_external_port_type(external_trace_port::in,
+ trace_port::out) is det.
+
+trace__convert_external_port_type(call, call).
+trace__convert_external_port_type(exit, exit).
+trace__convert_external_port_type(fail, fail).
+
+:- pred trace__convert_nondet_pragma_port_type(nondet_pragma_trace_port::in,
+ trace_port::out) is det.
+
+trace__convert_nondet_pragma_port_type(nondet_pragma_first,
+ nondet_pragma_first).
+trace__convert_nondet_pragma_port_type(nondet_pragma_later,
+ nondet_pragma_later).
Index: compiler/vn_filter.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/vn_filter.m,v
retrieving revision 1.15
diff -u -u -r1.15 vn_filter.m
--- vn_filter.m 1998/01/13 10:14:09 1.15
+++ vn_filter.m 1998/03/16 04:30:41
@@ -25,7 +25,7 @@
:- implementation.
-:- import_module opt_util.
+:- import_module code_util, opt_util.
:- import_module require, std_util.
% Look for assignments to temp variables. If possible and profitable,
@@ -38,7 +38,7 @@
Instr0 = Uinstr0 - _,
Uinstr0 = assign(Temp, Defn),
Temp = temp(_, _),
- opt_util__lvals_in_rval(Defn, Deps),
+ code_util__lvals_in_rval(Defn, Deps),
vn_filter__can_substitute(Instrs0, Temp, Defn, Deps,
Instrs1)
->
@@ -73,7 +73,7 @@
Instr0 = Uinstr0 - Comment,
(
vn_filter__user_instr(Uinstr0, yes(Rval)),
- opt_util__lvals_in_rval(Rval, Lvals),
+ code_util__lvals_in_rval(Rval, Lvals),
list__delete_first(Lvals, Temp, OtherLvals)
->
% We don't want to perform the subsitution
@@ -81,7 +81,7 @@
\+ list__member(Temp, OtherLvals),
\+ (
vn_filter__defining_instr(Uinstr0, yes(Lval)),
- opt_util__lvals_in_lval(Lval, AccessLvals),
+ code_util__lvals_in_lval(Lval, AccessLvals),
list__member(Temp, AccessLvals)
),
vn_filter__replace_in_user_instr(Uinstr0, Temp, Defn, Uinstr1),
@@ -99,7 +99,7 @@
->
fail
;
- opt_util__lvals_in_lval(Lval, AccessLvals),
+ code_util__lvals_in_lval(Lval, AccessLvals),
list__delete_first(AccessLvals, Temp, OtherAccessLvals)
->
\+ list__member(Temp, OtherAccessLvals),
cvs diff: Diffing compiler/notes
cvs diff: Diffing doc
Index: doc/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/Mmakefile,v
retrieving revision 1.7
diff -u -u -r1.7 Mmakefile
--- Mmakefile 1998/03/11 22:07:20 1.7
+++ Mmakefile 1998/04/01 06:19:44
@@ -75,7 +75,8 @@
library_1.html faq_1.html transition_guide_1.html
.PHONY: manpages
-manpages: c2init.1 mmc.1 mgnuc.1 ml.1 mmake.1 msc.1 mprof.1 mprof_merge_runs.1
+manpages: c2init.1 mmc.1 mgnuc.1 ml.1 mmake.1 mmd.1 msc.1 mprof.1 \
+ mprof_merge_runs.1
#-----------------------------------------------------------------------------#
cvs diff: Diffing extras
cvs diff: Diffing extras/cgi
cvs diff: Diffing extras/complex_numbers
cvs diff: Diffing extras/complex_numbers/samples
cvs diff: Diffing extras/complex_numbers/tests
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/Togl-1.2
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/references
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing library
Index: library/array.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/array.m,v
retrieving revision 1.44
diff -u -u -r1.44 array.m
--- array.m 1998/03/31 23:16:23 1.44
+++ array.m 1998/04/01 04:43:02
@@ -288,9 +288,9 @@
Declare_entry(mercury__array__array_compare_3_0);
BEGIN_MODULE(array_module_builtins)
- init_entry(mercury____Unify___array__array_1_0);
- init_entry(mercury____Index___array__array_1_0);
- init_entry(mercury____Compare___array__array_1_0);
+ init_entry_sl(mercury____Unify___array__array_1_0);
+ init_entry_sl(mercury____Index___array__array_1_0);
+ init_entry_sl(mercury____Compare___array__array_1_0);
BEGIN_CODE
Define_entry(mercury____Unify___array__array_1_0);
Index: library/benchmarking.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/benchmarking.m,v
retrieving revision 1.12
diff -u -u -r1.12 benchmarking.m
--- benchmarking.m 1998/02/02 02:49:57 1.12
+++ benchmarking.m 1998/03/30 10:10:46
@@ -558,9 +558,9 @@
Declare_entry(do_call_det_closure);
BEGIN_MODULE(benchmark_nondet_module)
- init_entry(mercury__benchmarking__benchmark_nondet_5_0);
- init_label(mercury__benchmarking__benchmark_nondet_5_0_i1);
- init_label(mercury__benchmarking__benchmark_nondet_5_0_i2);
+ init_entry_sl(mercury__benchmarking__benchmark_nondet_5_0);
+ init_label_sl(mercury__benchmarking__benchmark_nondet_5_0_i1);
+ init_label_sl(mercury__benchmarking__benchmark_nondet_5_0_i2);
BEGIN_CODE
Define_entry(mercury__benchmarking__benchmark_nondet_5_0);
@@ -648,8 +648,8 @@
MR_MAKE_STACK_LAYOUT_INTERNAL(mercury__benchmarking__benchmark_det_5_0, 1);
BEGIN_MODULE(benchmark_det_module)
- init_entry(mercury__benchmarking__benchmark_det_5_0);
- init_label(mercury__benchmarking__benchmark_det_5_0_i1);
+ init_entry_sl(mercury__benchmarking__benchmark_det_5_0);
+ init_label_sl(mercury__benchmarking__benchmark_det_5_0_i1);
BEGIN_CODE
Define_entry(mercury__benchmarking__benchmark_det_5_0);
Index: library/require.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/require.m,v
retrieving revision 1.18
diff -u -u -r1.18 require.m
--- require.m 1998/03/11 05:57:41 1.18
+++ require.m 1998/03/26 08:12:05
@@ -58,6 +58,7 @@
:- pragma c_code(error(Message::in), "
fflush(stdout);
fprintf(stderr, ""Software error: %s\\n"", Message);
+ MR_trace_report(stderr);
MR_dump_stack(MR_succip, MR_sp);
exit(1);
#ifndef USE_GCC_NONLOCAL_GOTOS
Index: library/std_util.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/std_util.m,v
retrieving revision 1.115
diff -u -u -r1.115 std_util.m
--- std_util.m 1998/01/30 02:15:04 1.115
+++ std_util.m 1998/03/30 10:11:31
@@ -494,15 +494,15 @@
MR_MAKE_STACK_LAYOUT_INTERNAL(mercury__std_util__builtin_aggregate_4_0, 3);
BEGIN_MODULE(builtin_aggregate_module)
- init_entry(mercury__std_util__builtin_aggregate_4_0);
- init_entry(mercury__std_util__builtin_aggregate_4_1);
- init_entry(mercury__std_util__builtin_aggregate_4_2);
- init_entry(mercury__std_util__builtin_aggregate_4_3);
- init_entry(mercury__std_util__builtin_aggregate_4_4);
- init_entry(mercury__std_util__builtin_aggregate_4_5);
- init_label(mercury__std_util__builtin_aggregate_4_0_i1);
- init_label(mercury__std_util__builtin_aggregate_4_0_i2);
- init_label(mercury__std_util__builtin_aggregate_4_0_i3);
+ init_entry_sl(mercury__std_util__builtin_aggregate_4_0);
+ init_entry_sl(mercury__std_util__builtin_aggregate_4_1);
+ init_entry_sl(mercury__std_util__builtin_aggregate_4_2);
+ init_entry_sl(mercury__std_util__builtin_aggregate_4_3);
+ init_entry_sl(mercury__std_util__builtin_aggregate_4_4);
+ init_entry_sl(mercury__std_util__builtin_aggregate_4_5);
+ init_label_sl(mercury__std_util__builtin_aggregate_4_0_i1);
+ init_label_sl(mercury__std_util__builtin_aggregate_4_0_i2);
+ init_label_sl(mercury__std_util__builtin_aggregate_4_0_i3);
BEGIN_CODE
/*
@@ -1192,14 +1192,14 @@
MR_MAKE_STACK_LAYOUT_ENTRY(mercury____Compare___std_util__type_info_0_0);
BEGIN_MODULE(unify_univ_module)
- init_entry(mercury____Unify___std_util__univ_0_0);
- init_entry(mercury____Index___std_util__univ_0_0);
- init_entry(mercury____Compare___std_util__univ_0_0);
- init_label(mercury____Compare___std_util__univ_0_0_i1);
-
- init_entry(mercury____Unify___std_util__type_info_0_0);
- init_entry(mercury____Index___std_util__type_info_0_0);
- init_entry(mercury____Compare___std_util__type_info_0_0);
+ init_entry_sl(mercury____Unify___std_util__univ_0_0);
+ init_entry_sl(mercury____Index___std_util__univ_0_0);
+ init_entry_sl(mercury____Compare___std_util__univ_0_0);
+ init_label_sl(mercury____Compare___std_util__univ_0_0_i1);
+
+ init_entry_sl(mercury____Unify___std_util__type_info_0_0);
+ init_entry_sl(mercury____Index___std_util__type_info_0_0);
+ init_entry_sl(mercury____Compare___std_util__type_info_0_0);
BEGIN_CODE
Define_entry(mercury____Unify___std_util__univ_0_0);
{
cvs diff: Diffing lp_solve
cvs diff: Diffing lp_solve/lp_examples
cvs diff: Diffing profiler
cvs diff: Diffing runtime
Index: runtime/mercury_conf_param.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_conf_param.h,v
retrieving revision 1.1
diff -u -u -r1.1 mercury_conf_param.h
--- mercury_conf_param.h 1998/03/16 12:23:24 1.1
+++ mercury_conf_param.h 1998/03/31 10:17:55
@@ -90,7 +90,7 @@
/*
** Debugging options:
**
-** MR_USE_DEBUGGER:
+** MR_USE_EXTERNAL_DEBUGGER:
** Make MR_trace() use an external process debugger
** (with communication done via a socket interface)
** rather than using the debugger that is part of
Index: runtime/mercury_goto.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_goto.h,v
retrieving revision 1.7
diff -u -u -r1.7 mercury_goto.h
--- mercury_goto.h 1998/03/16 12:23:28 1.7
+++ mercury_goto.h 1998/03/30 08:56:14
@@ -35,22 +35,28 @@
*/
#if defined(MR_INSERT_LABELS)
- #define make_label(n, a, l) make_entry(n, a, l)
+ #define make_label(n, a, l) make_entry(n, a, l)
+ #define make_label_sl(n, a, l) make_entry_sl(n, a, l)
#else
- #define make_label(n, a, l) /* nothing */
+ #define make_label(n, a, l) /* nothing */
+ #define make_label_sl(n, a, l) /* nothing */
#endif
#if defined(MR_INSERT_LABELS) || defined(PROFILE_CALLS)
- #define make_local(n, a, l) make_entry(n, a, l)
+ #define make_local(n, a, l) make_entry(n, a, l)
+ #define make_local_sl(n, a, l) make_entry_sl(n, a, l)
#else
- #define make_local(n, a, l) /* nothing */
+ #define make_local(n, a, l) /* nothing */
+ #define make_local_sl(n, a, l) /* nothing */
#endif
#if defined(MR_INSERT_LABELS) || defined(PROFILE_CALLS) \
|| defined(MR_CHOOSE_ENTRY_POINT)
- #define make_entry(n, a, l) insert_entry(n, a, MR_STACK_LAYOUT(l))
+ #define make_entry(n, a, l) insert_entry(n, a, NULL)
+ #define make_entry_sl(n, a, l) insert_entry(n, a, MR_STACK_LAYOUT(l))
#else
- #define make_entry(n, a, l) /* nothing */
+ #define make_entry(n, a, l) /* nothing */
+ #define make_entry_sl(n, a, l) /* nothing */
#endif
@@ -471,6 +477,9 @@
#define init_entry(label) \
PRETEND_ADDRESS_IS_USED(&&label); \
make_entry(stringify(label), label, label)
+ #define init_entry_sl(label) \
+ PRETEND_ADDRESS_IS_USED(&&label); \
+ make_entry_sl(stringify(label), label, label)
#define ENTRY(label) (&label)
#define STATIC(label) (&label)
@@ -498,6 +507,9 @@
#define init_entry(label) \
make_entry(stringify(label), &&label, label); \
entry(label) = &&label
+ #define init_entry_sl(label) \
+ make_entry_sl(stringify(label), &&label, label); \
+ entry(label) = &&label
#define ENTRY(label) (entry(label))
#define STATIC(label) (entry(label))
@@ -514,13 +526,17 @@
label: \
{
#define init_local(label) make_local(stringify(label), &&label, label)
+ #define init_local_sl(label) make_local_sl(stringify(label), &&label, label)
#define Define_label(label) Define_local(label)
#define Declare_label(label) /* no declaration required */
#ifdef MR_INSERT_LABELS
#define init_label(label) \
make_label(stringify(label), &&entry(label), label)
+ #define init_label_sl(label) \
+ make_label_sl(stringify(label), &&entry(label), label)
#else
#define init_label(label) make_label(stringify(label), &&label, label)
+ #define init_label_sl(label) make_label_sl(stringify(label), &&label, label)
#endif
#define LOCAL(label) (&&entry(label))
@@ -560,6 +576,7 @@
} \
static Code* label(void) {
#define init_entry(label) make_entry(stringify(label), label, label)
+ #define init_entry_sl(label) make_entry_sl(stringify(label), label, label)
#define Declare_local(label) static Code *label(void)
#define Define_local(label) \
@@ -567,6 +584,7 @@
} \
static Code* label(void) {
#define init_local(label) make_local(stringify(label), label, label)
+ #define init_local_sl(label) make_local_sl(stringify(label), label, label)
#define Declare_label(label) static Code *label(void)
#define Define_label(label) \
@@ -574,6 +592,7 @@
} \
static Code* label(void) {
#define init_label(label) make_label(stringify(label), label, label)
+ #define init_label_sl(label) make_label_sl(stringify(label), label, label)
#define ENTRY(label) (label)
#define STATIC(label) (label)
Index: runtime/mercury_memory.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_memory.c,v
retrieving revision 1.5
diff -u -u -r1.5 mercury_memory.c
--- mercury_memory.c 1998/03/30 03:08:36 1.5
+++ mercury_memory.c 1998/03/31 10:12:05
@@ -80,6 +80,7 @@
#endif
#include "mercury_imp.h"
+#include "mercury_trace.h"
/*---------------------------------------------------------------------------*/
@@ -701,6 +702,7 @@
context_msg = explain_context(context);
write(STDERR, main_msg, strlen(main_msg));
write(STDERR, context_msg, strlen(context_msg));
+ MR_trace_report_raw(STDERR);
if (dump) {
print_dump_stack();
@@ -900,6 +902,7 @@
#endif
fprintf(stderr, "address involved: %p\n", address);
+ MR_trace_report(stderr);
print_dump_stack();
dump_prev_locations();
fprintf(stderr, "exiting from signal handler\n");
@@ -990,6 +993,7 @@
(void *) info->si_addr);
} /* end if */
+ MR_trace_report(stderr);
print_dump_stack();
dump_prev_locations();
fprintf(stderr, "exiting from signal handler\n");
@@ -1063,6 +1067,7 @@
explain_segv(info, context);
}
+ MR_trace_report(stderr);
print_dump_stack();
dump_prev_locations();
fprintf(stderr, "exiting from signal handler\n");
Index: runtime/mercury_misc.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_misc.c,v
retrieving revision 1.5
diff -u -u -r1.5 mercury_misc.c
--- mercury_misc.c 1998/03/30 03:08:38 1.5
+++ mercury_misc.c 1998/03/30 10:28:12
@@ -7,6 +7,7 @@
#include "mercury_imp.h"
#include "mercury_dlist.h"
#include "mercury_regs.h"
+#include "mercury_trace.h"
#include "mercury_misc.h"
#include <stdio.h>
@@ -468,6 +469,7 @@
void
fatal_error(const char *message) {
fprintf(stderr, "Mercury runtime: %s\n", message);
+ MR_trace_report(stderr);
exit(1);
}
Index: runtime/mercury_regorder.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_regorder.h,v
retrieving revision 1.2
diff -u -u -r1.2 mercury_regorder.h
--- mercury_regorder.h 1997/11/23 07:21:32 1.2
+++ mercury_regorder.h 1998/03/16 05:06:30
@@ -55,6 +55,11 @@
#define r31 count_usage(R_RN(31), mr35)
#define r32 count_usage(R_RN(32), mr36)
+/*
+** If you modify the following block, make sure that you update
+** the definitions of MR_NUM_SPECIAL_REG and MR_MAX_SPECIAL_REG_MR.
+*/
+
#define MR_succip LVALUE_CAST(Code *, count_usage(MR_SI_RN, mr1))
#define succip MR_succip
#define MR_hp LVALUE_CAST(Word *, count_usage(MR_HP_RN, mr5))
@@ -73,6 +78,12 @@
#define MR_trail_ptr count_usage(MR_TRAIL_PTR_RN, MR_trail_ptr_var)
#define MR_ticket_counter \
count_usage(MR_TICKET_COUNTER_RN, MR_ticket_counter_var)
+
+/* the number of special, non rN registers */
+#define MR_NUM_SPECIAL_REG 10
+
+/* the maximum mrN number of special, non rN registers */
+#define MR_MAX_SPECIAL_REG_MR 39
#define VIRTUAL_REG_MAP_BODY { \
2, \
Index: runtime/mercury_stack_layout.h
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_stack_layout.h,v
retrieving revision 1.2
diff -u -u -r1.2 mercury_stack_layout.h
--- mercury_stack_layout.h 1998/03/11 22:07:30 1.2
+++ mercury_stack_layout.h 1998/03/31 10:17:18
@@ -10,6 +10,10 @@
/*
** mercury_stack_layout.h -
** Definitions for the stack layout data structures.
+**
+** NOTE: The constants and data-structures used here need to be kept in
+** sync with the ones generated in the compiler. If you change anything here,
+** you may need to change compiler/stack_layout.m as well.
*/
/*
@@ -49,7 +53,8 @@
#define MR_DETISM_FIRST_SOLN(d) (((d) & 8) != 0)
-#define MR_DETISM_DET_CODE_MODEL(d) (((d) & 1) == 0)
+#define MR_DETISM_DET_STACK(d) (!MR_DETISM_AT_MOST_MANY(d) \
+ || MR_DETISM_FIRST_SOLN(d))
/*
** Definitions for "MR_Live_Lval"
@@ -112,7 +117,7 @@
** The data is encoded such that low values (less than
** TYPELAYOUT_MAX_VARINT) represent succip, hp, etc. Higher values
** represent data variables, and are pointers to a 2 word cell,
-** containing a type_info and an instantiation represention.
+** containing a pseudo type_info and an instantiation represention.
**
** This data is generated in compiler/stack_layout.m, which must be kept
** in sync with the constants defined here.
@@ -130,7 +135,7 @@
} MR_Lval_NonVar;
typedef struct {
- Word type; /* contains a type_info */
+ Word *pseudo_type_info;
Word inst; /* not yet used; currently always -1 */
} MR_Var_Shape_Info;
@@ -140,10 +145,10 @@
((MR_Lval_NonVar) T)
#define MR_LIVE_TYPE_GET_VAR_TYPE(T) \
- ((Word) ((MR_Var_Shape_Info *) T)->type)
+ (((MR_Var_Shape_Info *) T)->pseudo_type_info)
#define MR_LIVE_TYPE_GET_VAR_INST(T) \
- ((Word) ((MR_Var_Shape_Info *) T)->inst)
+ (((MR_Var_Shape_Info *) T)->inst)
/*
** Macros to support hand-written C code.
@@ -151,9 +156,10 @@
/*
** Define a stack layout for a label that you know very little about.
-** It's just a generic entry label, no useful information, except
+** It is just a generic entry label, no useful information, except
** the code address for the label.
*/
+
#ifdef MR_USE_STACK_LAYOUTS
#define MR_MAKE_STACK_LAYOUT_ENTRY(l) \
const struct mercury_data__stack_layout__##l##_struct { \
@@ -178,6 +184,7 @@
** The only useful information in this structure is the code address
** and the reference to the entry for this label.
*/
+
#ifdef MR_USE_STACK_LAYOUTS
#define MR_MAKE_STACK_LAYOUT_INTERNAL_WITH_ENTRY(l, e) \
const struct mercury_data__stack_layout__##l##_struct { \
@@ -208,6 +215,7 @@
** The only useful information in this structure is the code address
** and the reference to the entry for this label.
*/
+
#ifdef MR_USE_STACK_LAYOUTS
#define MR_MAKE_STACK_LAYOUT_INTERNAL(e, x) \
const struct mercury_data__stack_layout__##e##_i##x##_struct { \
@@ -227,18 +235,25 @@
** Structs and macros to support stack layouts.
*/
-typedef struct MR_stack_layout_var_struct {
+typedef struct MR_Stack_Layout_Var_Struct {
MR_Live_Lval MR_slv_locn;
MR_Live_Type MR_slv_live_type;
-} MR_stack_layout_var;
+} MR_Stack_Layout_Var;
-typedef struct MR_stack_layout_vars_struct {
- MR_stack_layout_var *MR_slvs_pairs;
+typedef struct MR_Stack_Layout_Vars_Struct {
+ MR_Stack_Layout_Var *MR_slvs_pairs;
String *MR_slvs_names;
- Word *MR_slvs_tvars;
-} MR_stack_layout_vars;
+ Integer MR_slvs_tvar_count;
+ MR_Live_Lval *MR_slvs_tvars;
+} MR_Stack_Layout_Vars;
+
+#define MR_name_if_present(vars, i) \
+ ((vars->MR_slvs_names != NULL \
+ && vars->MR_slvs_names[(i)] != NULL) \
+ ? vars->MR_slvs_names[(i)] \
+ : "")
-typedef struct MR_stack_layout_entry_struct {
+typedef struct MR_Stack_Layout_Entry_Struct {
Code *MR_sle_code_addr;
MR_Determinism MR_sle_detism;
Integer MR_sle_stack_slots;
@@ -251,20 +266,19 @@
Integer MR_sle_arity;
Integer MR_sle_mode;
/* the fields from here onwards are present only with trace layouts */
- Integer MR_sle_in_arg_count;
- MR_stack_layout_vars MR_sle_in_arg_info;
- Integer MR_sle_out_arg_count;
- MR_stack_layout_vars MR_sle_out_arg_info;
-} MR_stack_layout_entry;
-
-typedef struct MR_stack_layout_label_struct {
- MR_stack_layout_entry *MR_sll_entry;
+ struct MR_Stack_Layout_Label_Struct
+ *MR_sle_call_label;
+} MR_Stack_Layout_Entry;
+
+typedef struct MR_Stack_Layout_Label_Struct {
+ MR_Stack_Layout_Entry *MR_sll_entry;
+ Integer MR_sll_label_num;
Integer MR_sll_var_count;
/* the last field is present only if MR_sll_var_count > 0 */
- MR_stack_layout_vars MR_sll_var_info;
-} MR_stack_layout_label;
+ MR_Stack_Layout_Vars MR_sll_var_info;
+} MR_Stack_Layout_Label;
-/* The following macros support obsolete code. */
+/* The following macros support obsolete code (and probably don't work). */
#define MR_ENTRY_STACK_LAYOUT_GET_LABEL_ADDRESS(s) \
((Code *) field(0, (s), 0))
@@ -282,4 +296,3 @@
/*---------------------------------------------------------------------------*/
#endif /* not MERCURY_STACK_LAYOUT_H */
-
Index: runtime/mercury_stack_trace.c
===================================================================
RCS file: /home/mercury1/repository/mercury/runtime/mercury_stack_trace.c,v
retrieving revision 1.2
diff -u -u -r1.2 mercury_stack_trace.c
--- mercury_stack_trace.c 1998/03/16 12:23:37 1.2
+++ mercury_stack_trace.c 1998/03/20 08:11:17
@@ -17,13 +17,12 @@
void
MR_dump_stack(Code *success_pointer, Word *det_stack_pointer)
{
- Label *label;
- MR_Live_Lval location;
- MR_stack_layout_label *layout;
- MR_stack_layout_entry *entry_layout;
- MR_Lval_Type type;
- int number, determinism;
-
+ Label *label;
+ MR_Live_Lval location;
+ MR_Stack_Layout_Label *layout;
+ MR_Stack_Layout_Entry *entry_layout;
+ MR_Lval_Type type;
+ int number, determinism;
#ifndef MR_STACK_TRACE
fprintf(stderr, "Stack dump not available in this grade.\n");
@@ -36,7 +35,7 @@
fatal_error("internal label not found");
}
- layout = (MR_stack_layout_label *) label->e_layout;
+ layout = (MR_Stack_Layout_Label *) label->e_layout;
entry_layout = layout->MR_sll_entry;
label = lookup_label_addr(
@@ -65,4 +64,3 @@
} while (MR_DETISM_DET_CODE_MODEL(determinism));
#endif /* MR_STACK_TRACE */
}
More information about the developers
mailing list