for review: big step towards a usable debugger, round 3 (part 2 of 3)
Zoltan Somogyi
zs at cs.mu.OZ.AU
Wed Apr 8 18:49:22 AEST 1998
ws4 has the code from the previous proposal,
es2 has the code from the current proposal.
--- ws4/compiler/code_gen.m Tue Apr 7 16:37:37 1998
+++ ws2/compiler/code_gen.m Wed Apr 8 11:28:16 1998
@@ -256,48 +256,47 @@
%---------------------------------------------------------------------------%
% Generate_category_code generates code for an entire procedure.
- % Its algorithm has three main stages:
+ % Its algorithm has three or four main stages:
%
% - generate code for the body goal
- % - generate code for the prologue
- % - generate code for the epilogue
+ % - generate code for the procedure entry
+ % - generate code for the procedure exit
+ % - generate code for the procedure fail (if needed)
+ %
+ % The first three tasks are forwarded to other procedures.
+ % The fourth task, if needed, is done by generate_category_code.
%
% The only caller of generate_category_code, generate_proc_code,
% has set up the code generator state to reflect what the machine
% state will be on entry to the procedure. Ensuring that the
- % machine state at exit/fail will conform to the expectation
- % of the caller is the job of the epilogue.
+ % machine state at exit will conform to the expectation
+ % of the caller is the job of code_gen__generate_exit.
%
- % The reason why we generate the prologue after the body is that
+ % The reason why we generate the entry code after the body is that
% information such as the total number of stack slots needed,
- % which is needed when creating the prologue, cannot be conveniently
- % obtained before generating the body, since the code generator
- % may allocate temporary variables to hold values such as saved
- % heap and trail pointers.
+ % which is needed in the procedure entry prologue, cannot be
+ % conveniently obtained before generating the body, since the
+ % code generator may allocate temporary variables to hold values
+ % such as saved heap and trail pointers.
%
- % Code_gen__generate_prologue cannot depend on the code generator
+ % Code_gen__generate_entry cannot depend on the code generator
% state, since when it is invoked this state is not appropriate
- % for the prologue. Nor can it change the code generator state,
- % since that would confuse code_gen__generate_epilogue.
+ % for the procedure entry. Nor can it change the code generator state,
+ % since that would confuse code_gen__generate_exit.
%
% Generating CALL trace events is done by generate_category_code,
% since only on entry to generate_category_code is the code generator
% state set up right. Generating EXIT trace events is done by
- % code_gen__generate_exit, since the epilogue takes care of the
- % successes of all procedures of all three code models.
- % Generating FAIL trace events is done by generate_category_code,
- % since this requires modifying how we generate code for the body
- % of the procedure (failures must now branch to a different place).
- % Since FAIL trace events are part of the failure continuation,
- % generate_category_code takes care of the failure continuation
- % as well. (Det procedures of course have no failure continuation.
- % Nondet procedures have a failure continuation, but in the absence
- % of tracing this continuation needs no code. Only semidet procedures
- % need code for the failure continuation at all times.)
- % code_gen__generate_epilogue.
- %
- % Procedures defined by nondet pragma C codes are a special case.
- % Pragma_c_gen__generate_pragma_c_code handles XXX
+ % code_gen__generate_exit. Generating FAIL trace events is done
+ % by generate_category_code, since this requires modifying how
+ % we generate code for the body of the procedure (failures must
+ % now branch to a different place). Since FAIL trace events are
+ % part of the failure continuation, generate_category_code takes
+ % care of the failure continuation as well. (Model_det procedures
+ % of course have no failure continuation. Model_non procedures have
+ % a failure continuation, but in the absence of tracing this
+ % continuation needs no code. Only model_semi procedures need code
+ % for the failure continuation at all times.)
:- pred generate_category_code(code_model, hlds_goal, proc_info, code_tree,
maybe(label), frame_info, code_info, code_info).
@@ -322,11 +321,12 @@
code_info__get_maybe_trace_info(MaybeTraceInfo),
( { MaybeTraceInfo = yes(TraceInfo) } ->
- { trace__fail_vars(ProcInfo, ResumeVars) },
+ code_info__get_module_info(ModuleInfo),
+ { trace__fail_vars(ModuleInfo, ProcInfo, ResumeVars) },
% Protect these vars from being forgotten,
% so they will be around for the exit trace.
code_info__push_resume_point_vars(ResumeVars),
- trace__generate_event_code(call, TraceInfo,
+ trace__generate_external_event_code(call, TraceInfo,
TraceCallLabel, _TypeInfos, TraceCallCode),
{ MaybeTraceCallLabel = yes(TraceCallLabel) }
;
@@ -357,11 +357,12 @@
goto(succip) - "Return from procedure call"
]) },
( { MaybeTraceInfo = yes(TraceInfo) } ->
- { trace__fail_vars(ProcInfo, ResumeVars) },
+ code_info__get_module_info(ModuleInfo),
+ { trace__fail_vars(ModuleInfo, ProcInfo, ResumeVars) },
code_info__make_known_failure_cont(ResumeVars, orig_and_stack,
no, SetupCode),
code_info__push_resume_point_vars(ResumeVars),
- trace__generate_event_code(call, TraceInfo,
+ trace__generate_external_event_code(call, TraceInfo,
TraceCallLabel, _TypeInfos, TraceCallCode),
{ MaybeTraceCallLabel = yes(TraceCallLabel) },
code_gen__generate_goal(model_semi, Goal, BodyCode),
@@ -372,7 +373,8 @@
code_info__pop_resume_point_vars,
code_info__restore_failure_cont(ResumeCode),
code_info__set_forward_live_vars(ResumeVars),
- trace__generate_event_code(fail, TraceInfo, TraceFailCode),
+ trace__generate_external_event_code(fail, TraceInfo, _, _,
+ TraceFailCode),
{ Code =
tree(EntryCode,
tree(SetupCode,
@@ -409,11 +411,12 @@
% we must arrange the tracing of failure out of this proc
code_info__get_maybe_trace_info(MaybeTraceInfo),
( { MaybeTraceInfo = yes(TraceInfo) } ->
- { trace__fail_vars(ProcInfo, ResumeVars) },
+ code_info__get_module_info(ModuleInfo),
+ { trace__fail_vars(ModuleInfo, ProcInfo, ResumeVars) },
code_info__make_known_failure_cont(ResumeVars, orig_and_stack,
yes, SetupCode),
code_info__push_resume_point_vars(ResumeVars),
- trace__generate_event_code(call, TraceInfo,
+ trace__generate_external_event_code(call, TraceInfo,
TraceCallLabel, _TypeInfos, TraceCallCode),
{ MaybeTraceCallLabel = yes(TraceCallLabel) },
code_gen__generate_goal(model_non, Goal, BodyCode),
@@ -424,7 +427,8 @@
code_info__pop_resume_point_vars,
code_info__restore_failure_cont(RestoreCode),
code_info__set_forward_live_vars(ResumeVars),
- trace__generate_event_code(fail, TraceInfo, TraceFailCode),
+ trace__generate_external_event_code(fail, TraceInfo, _, _,
+ TraceFailCode),
code_info__generate_failure(FailCode),
{ Code =
tree(PrologCode,
@@ -462,7 +466,8 @@
% code to fill in some special slots in the stack frame
% a comment to mark prologue end
%
- % At the moment the only special slot is the succip slot.
+ % At the moment the only special slots are the succip slot, and
+ % the slots holding the call number and call depth for tracing.
%
% Not all frames will have all these components. For example, the code
% to allocate a stack frame will be missing if the procedure doesn't
@@ -583,7 +588,7 @@
% Generate the success epilogue for a procedure.
%
- % The epilogue will contain
+ % The success epilogue will contain
%
% a comment to mark epilogue start
% code to place the output arguments where their caller expects
@@ -593,13 +598,9 @@
% a jump back to the caller, including livevals information
% a comment to mark epilogue end
%
- % The failure continuation will contain
- %
- % code that sets up the failure resumption point
- % code to restore registers from some special slots
- % code to deallocate the stack frame
- % code to set r1 to FALSE
- % a jump back to the caller, including livevals information
+ % The parts of this that restore registers and deallocate the stack
+ % frame are also part of the failure epilog, which is handled by
+ % our caller; this is why return RestoreDeallocCode.
%
% At the moment the only special slots are the succip slot, and
% the slots holding the call number and call depth for tracing.
@@ -608,7 +609,7 @@
% nondet procedures we don't deallocate the stack frame before
% success.
%
- % Epilogs for procedures defined by nondet pragma C codes do not
+ % Epilogues for procedures defined by nondet pragma C codes do not
% follow the rules above. For such procedures, the normal functions
% of the epilogue are handled when traversing the pragma C code goal;
% we need only #undef a macro defined by the procedure prologue.
@@ -634,7 +635,7 @@
will_not_call_mercury, no)
- ""
]) },
- { RestoreDeallocCode = empty }, % XXX
+ { RestoreDeallocCode = empty }, % always empty for nondet code
{ EpilogCode =
tree(StartComment,
tree(UndefCode,
@@ -676,7 +677,7 @@
code_info__get_maybe_trace_info(MaybeTraceInfo),
( { MaybeTraceInfo = yes(TraceInfo) } ->
- trace__generate_event_code(exit, TraceInfo,
+ trace__generate_external_event_code(exit, TraceInfo,
_, TypeInfoDatas, TraceExitCode),
{ assoc_list__values(TypeInfoDatas, TypeInfoLvals) }
;
@@ -1201,8 +1202,8 @@
(
Instrn0 = livevals(LiveVals0),
Instrns0 \= [goto(succip) - _ | _]
- % XXX we should also test for tailcalls
- % once we start generating them directly
+ % XXX We should also test for tailcalls
+ % if we ever start generating them directly.
->
set__insert(LiveVals0, stackvar(StackLoc), LiveVals1),
Instrn = livevals(LiveVals1)
--- ws4/compiler/continuation_info.m Tue Apr 7 16:37:38 1998
+++ ws2/compiler/continuation_info.m Wed Apr 1 14:12:12 1998
@@ -26,15 +26,16 @@
%
% - After we finish generating code for a procedure, we record
% all the static information about the procedure (some of which
-% is available only after code generation), and the info about
-% internal labels accumulated in the code generator state,
+% is available only after code generation), together with the
+% info about internal labels accumulated in the code generator state,
% in the continuation_info structure (which is part of HLDS).
%
% - If agc_stack_layouts is set, we make a pass over the
% optimized code recorded in the final LLDS instructions.
% In this pass, we collect information from call instructions
% about the internal labels to which calls can return.
-% This info will also go straight into the HLDS.
+% This info will also go straight into the continuation_info
+% in the HLDS.
%
% stack_layout.m converts the information collected in this module into
% stack_layout tables.
@@ -63,10 +64,14 @@
:- type proc_layout_info
---> proc_layout_info(
proc_label, % the proc label
- determinism, % which stack is used
+ determinism, % determines which stack is used
int, % number of stack slots
maybe(int), % location of succip on stack
- maybe(label), % name of the label of the call event
+ maybe(label), % if generate_trace is set,
+ % this contains the label associated
+ % with the call event, whose stack
+ % layout says which variables were
+ % live and where on entry
proc_label_layout_info
% info for each internal label,
% needed for basic_stack_layouts
@@ -212,21 +220,7 @@
% Process the continuation label info.
list__foldl(continuation_info__process_continuation, Calls,
- Internals0, Internals1),
-
- % Add empty entries for the labels that do not have real info,
- % since if continuation_info__process_instructions is invoked
- % then MR_USE_STACK_LAYOUTS will be defined, and this demands
- % a stack layout data structure for every label, even if it
- % is not used. When this aspect of the runtime is fixed,
- % we will be able to remove this step.
- GetAllInternalLabels = lambda([Instr::in, Label::out] is semidet, (
- Instr = label(Label) - _Comment,
- Label = local(_, _)
- )),
- list__filter_map(GetAllInternalLabels, Instructions, Labels),
- list__foldl(continuation_info__ensure_label_is_present, Labels,
- Internals1, Internals),
+ Internals0, Internals),
ProcLayoutInfo = proc_layout_info(A, B, C, D, E, Internals),
map__det_update(ContInfo0, PredProcId, ProcLayoutInfo, ContInfo).
diff -u ws4/compiler/dense_switch.m ws2/compiler/dense_switch.m
--- ws4/compiler/dense_switch.m Tue Apr 7 16:37:39 1998
+++ ws2/compiler/dense_switch.m Sat Mar 28 15:03:46 1998
@@ -236,18 +236,9 @@
->
{ Comment = "case of dense switch" },
% We need to save the expression cache, etc.,
- % and restore them when we've finished
+ % and restore them when we've finished.
code_info__grab_code_info(CodeInfoAtStart),
- 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) },
- trace__generate_event_code(switch(Path, PreDeaths),
- 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),
{ Code =
diff -u ws4/compiler/disj_gen.m ws2/compiler/disj_gen.m
--- ws4/compiler/disj_gen.m Tue Apr 7 16:37:39 1998
+++ ws2/compiler/disj_gen.m Sat Mar 28 15:02:25 1998
@@ -75,7 +75,7 @@
% disjunct that might allocate some heap space.
{ MaybeHpSlot = no },
- % Generate all the disjuncts
+ % Generate all the disjuncts.
code_info__get_next_label(EndLabel),
disj_gen__generate_pruned_disjuncts(Goals, StoreMap, EndLabel,
ReclaimHeap, MaybeHpSlot, MaybeTicketSlot, no, GoalsCode),
@@ -125,7 +125,7 @@
code_info__make_known_failure_cont(ResumeVars, ResumeLocs, no,
ModContCode),
% The next line is to enable Goal to pass the
- % pre_goal_update sanity check
+ % pre_goal_update sanity check.
{ goal_info_set_resume_point(GoalInfo0, no_resume_point,
GoalInfo) },
{ Goal = GoalExpr0 - GoalInfo },
@@ -133,11 +133,11 @@
( { First = no } ->
% Reset the heap pointer to recover memory
% allocated by the previous disjunct(s),
- % if necessary
+ % if necessary.
code_info__maybe_restore_hp(MaybeHpSlot0,
RestoreHPCode),
- % Reset the solver state if necessary
+ % Reset the solver state if necessary.
code_info__maybe_reset_ticket(MaybeTicketSlot, undo,
RestoreTicketCode)
;
@@ -146,7 +146,7 @@
),
% Save hp if it needs to be saved and hasn't been
- % saved previously
+ % saved previously.
(
{ ReclaimHeap = yes },
{ code_util__goal_may_allocate_heap(Goal) },
@@ -161,21 +161,13 @@
code_info__grab_code_info(CodeInfo),
- % generate the disjunct as a semi-deterministic goal
+ % Generate the disjunct as a semi-deterministic goal.
{ CodeModel = model_semi ->
true
;
error("pruned disj non-last goal is not semidet")
},
- code_info__get_maybe_trace_info(MaybeTraceInfo),
- ( { MaybeTraceInfo = yes(TraceInfo) } ->
- { goal_info_get_goal_path(GoalInfo, Path) },
- { goal_info_get_pre_deaths(GoalInfo, PreDeaths) },
- trace__generate_event_code(disj(Path, PreDeaths),
- 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),
@@ -204,26 +196,18 @@
RestCode)))))))))
}
;
- % Emit code for the last disjunct
+ % Emit code for the last disjunct.
- % Restore the heap pointer if necessary
+ % Restore the heap pointer if necessary.
code_info__maybe_restore_and_discard_hp(MaybeHpSlot0,
RestoreHPCode),
- % Restore the solver state if necessary
+ % Restore the solver state if necessary.
code_info__maybe_reset_and_discard_ticket(MaybeTicketSlot,
undo, RestorePopTicketCode),
- % Generate the goal
- code_info__get_maybe_trace_info(MaybeTraceInfo),
- ( { MaybeTraceInfo = yes(TraceInfo) } ->
- { goal_info_get_goal_path(GoalInfo0, Path0) },
- { goal_info_get_pre_deaths(GoalInfo0, PreDeaths0) },
- trace__generate_event_code(disj(Path0, PreDeaths0),
- TraceInfo, TraceCode)
- ;
- { TraceCode = empty }
- ),
+ % Generate the goal.
+ trace__maybe_generate_internal_event_code(Goal0, TraceCode),
code_gen__generate_goal(CodeModel, Goal0, GoalCode),
code_info__generate_branch_end(CodeModel, StoreMap, SaveCode),
@@ -309,7 +293,7 @@
code_info__make_known_failure_cont(ResumeVars, ResumeLocs, yes,
ModContCode),
% The next line is to enable Goal to pass the
- % pre_goal_update sanity check
+ % pre_goal_update sanity check.
{ goal_info_set_resume_point(GoalInfo0, no_resume_point,
GoalInfo) },
{ Goal = GoalExpr0 - GoalInfo },
@@ -317,11 +301,11 @@
( { First = no } ->
% Reset the heap pointer to recover memory
% allocated by the previous disjunct(s),
- % if necessary
+ % if necessary.
code_info__maybe_restore_hp(MaybeHpSlot,
RestoreHPCode),
- % Reset the solver state if necessary
+ % Reset the solver state if necessary.
code_info__maybe_reset_ticket(MaybeTicketSlot, undo,
RestoreTicketCode)
;
@@ -331,21 +315,12 @@
code_info__grab_code_info(CodeInfo),
- code_info__get_maybe_trace_info(MaybeTraceInfo),
- ( { MaybeTraceInfo = yes(TraceInfo) } ->
- { goal_info_get_goal_path(GoalInfo, Path) },
- { goal_info_get_pre_deaths(GoalInfo, PreDeaths) },
- trace__generate_event_code(disj(Path, PreDeaths),
- TraceInfo, TraceCode)
- ;
- { TraceCode = empty }
- ),
-
+ trace__maybe_generate_internal_event_code(Goal, TraceCode),
code_gen__generate_goal(model_non, Goal, GoalCode),
code_info__generate_branch_end(model_non, StoreMap, SaveCode),
- % make sure every variable in the resume set is in its
- % stack slot
+ % Make sure every variable in the resume set is in its
+ % stack slot.
code_info__flush_resume_vars_to_stack(FlushResumeVarsCode),
{ BranchCode = node([
@@ -356,9 +331,9 @@
code_info__slap_code_info(CodeInfo),
code_info__pop_resume_point_vars,
- % make sure that the redoip of the top nondet frame
+ % Make sure that the redoip of the top nondet frame
% points to the right label, and set up the start of
- % the next disjunct
+ % the next disjunct.
code_info__restore_failure_cont(RestoreContCode),
disj_gen__generate_non_disjuncts(Goals, StoreMap, EndLabel,
@@ -376,7 +351,7 @@
RestCode)))))))))
}
;
- % Emit code for the last disjunct
+ % Emit code for the last disjunct.
{ Goals = [] ->
true
@@ -384,24 +359,15 @@
error("disj_gen__generate_non_disjuncts: last disjunct followed by others")
},
- % Restore the heap pointer if necessary
+ % Restore the heap pointer if necessary.
code_info__maybe_restore_and_discard_hp(MaybeHpSlot,
RestoreHPCode),
- % Restore the solver state if necessary
+ % Restore the solver state if necessary.
code_info__maybe_reset_and_discard_ticket(MaybeTicketSlot,
undo, RestorePopTicketCode),
- code_info__get_maybe_trace_info(MaybeTraceInfo),
- ( { MaybeTraceInfo = yes(TraceInfo) } ->
- { goal_info_get_goal_path(GoalInfo0, Path0) },
- { goal_info_get_pre_deaths(GoalInfo0, PreDeaths0) },
- trace__generate_event_code(disj(Path0, PreDeaths0),
- TraceInfo, TraceCode)
- ;
- { TraceCode = empty }
- ),
-
+ trace__maybe_generate_internal_event_code(Goal0, TraceCode),
code_gen__generate_goal(model_non, Goal0, GoalCode),
code_info__generate_branch_end(model_non, StoreMap, SaveCode),
diff -u ws4/compiler/handle_options.m ws2/compiler/handle_options.m
--- ws4/compiler/handle_options.m Tue Apr 7 16:37:39 1998
+++ ws2/compiler/handle_options.m Tue Mar 31 16:50:37 1998
@@ -262,8 +262,8 @@
% --generate-trace requires
% - disabling optimizations that would change
% the trace being generated
- % - enabling excess_assign to exclude junk vars from the trace
- % (and to ensure consistent paths across optimization levels)
+ % - enabling some low level optimizations to ensure consistent
+ % paths across optimization levels)
% - enabling stack layouts
% - enabling typeinfo liveness
globals__io_lookup_bool_option(generate_trace, Trace),
@@ -286,13 +286,20 @@
% removes a source of variability in the goal paths
% reported by tracing.
globals__io_set_option(excess_assign, bool(yes)),
+ % The explicit setting of the following option
+ % removes a source of variability in the goal paths
+ % reported by tracing.
+ globals__io_set_option(follow_code, bool(yes)),
% The following option selects a special-case
% code generator that cannot (yet) implement tracing.
globals__io_set_option(middle_rec, bool(no)),
% Tracing inserts C code into the generated LLDS.
% Value numbering cannot optimize such LLDS code.
- % We turn value numbering off now so that we don't
- % have to discover this fact anew for each procedure.
+ % (If it tried, it would get it wrong due to the
+ % absence of liveness annotations on the introduced
+ % labels.) We turn value numbering off now so that
+ % we don't have to discover this fact anew
+ % for each procedure.
globals__io_set_option(optimize_value_number, bool(no)),
% The following options cause the info required
% by tracing to be generated.
--- ws4/compiler/live_vars.m Tue Apr 7 16:37:50 1998
+++ ws2/compiler/live_vars.m Tue Mar 31 20:06:05 1998
@@ -51,7 +51,7 @@
module_info_globals(ModuleInfo, Globals),
globals__lookup_bool_option(Globals, generate_trace, Trace),
( Trace = yes ->
- trace__fail_vars(ProcInfo0, ResumeVars0),
+ trace__fail_vars(ModuleInfo, ProcInfo0, ResumeVars0),
set__insert(LiveSets0, ResumeVars0, LiveSets1)
;
set__init(ResumeVars0),
--- ws4/compiler/liveness.m Tue Apr 7 16:37:51 1998
+++ ws2/compiler/liveness.m Tue Mar 31 20:06:13 1998
@@ -167,7 +167,7 @@
module_info_globals(ModuleInfo, Globals),
globals__lookup_bool_option(Globals, generate_trace, Trace),
( Trace = yes ->
- trace__fail_vars(ProcInfo0, ResumeVars0)
+ trace__fail_vars(ModuleInfo, ProcInfo0, ResumeVars0)
;
set__init(ResumeVars0)
),
diff -u ws4/compiler/llds_out.m ws2/compiler/llds_out.m
--- ws4/compiler/llds_out.m Sat Mar 28 16:00:50 1998
+++ ws2/compiler/llds_out.m Tue Mar 31 11:33:58 1998
@@ -18,13 +18,13 @@
:- interface.
:- import_module llds, prog_data, hlds_data.
-:- import_module bool, io.
+:- import_module set_bbbtree, bool, io.
% Given a 'c_file' structure, open the appropriate .c file
% and output the code into that file.
-:- pred output_c_file(c_file, io__state, io__state).
-:- mode output_c_file(in, di, uo) is det.
+:- pred output_c_file(c_file, set_bbbtree(label), io__state, io__state).
+:- mode output_c_file(in, in, di, uo) is det.
% Convert an lval to a string description of that lval.
@@ -135,16 +135,17 @@
; data_addr(data_addr)
; pragma_c_struct(string).
-output_c_file(C_File) -->
+output_c_file(C_File, StackLayoutLabels) -->
globals__io_lookup_bool_option(split_c_files, SplitFiles),
( { SplitFiles = yes } ->
{ C_File = c_file(ModuleName, C_HeaderInfo, C_Modules) },
module_name_to_file_name(ModuleName, ".dir", yes, ObjDirName),
make_directory(ObjDirName),
output_c_file_init(ModuleName, C_Modules),
- output_c_file_list(C_Modules, 1, ModuleName, C_HeaderInfo)
+ output_c_file_list(C_Modules, 1, ModuleName, C_HeaderInfo,
+ StackLayoutLabels)
;
- output_single_c_file(C_File, no)
+ output_single_c_file(C_File, no, StackLayoutLabels)
).
:- pred make_directory(string, io__state, io__state).
@@ -156,15 +157,17 @@
io__call_system(Command, _Result).
:- pred output_c_file_list(list(c_module), int, module_name,
- list(c_header_code), io__state, io__state).
-:- mode output_c_file_list(in, in, in, in, di, uo) is det.
+ list(c_header_code), set_bbbtree(label), io__state, io__state).
+:- mode output_c_file_list(in, in, in, in, in, di, uo) is det.
-output_c_file_list([], _, _, _) --> [].
-output_c_file_list([Module|Modules], Num, ModuleName, C_HeaderLines) -->
+output_c_file_list([], _, _, _, _) --> [].
+output_c_file_list([Module|Modules], Num, ModuleName, C_HeaderLines,
+ StackLayoutLabels) -->
output_single_c_file(c_file(ModuleName, C_HeaderLines, [Module]),
- yes(Num)),
+ yes(Num), StackLayoutLabels),
{ Num1 is Num + 1 },
- output_c_file_list(Modules, Num1, ModuleName, C_HeaderLines).
+ output_c_file_list(Modules, Num1, ModuleName, C_HeaderLines,
+ StackLayoutLabels).
:- pred output_c_file_init(module_name, list(c_module), io__state, io__state).
:- mode output_c_file_init(in, in, di, uo) is det.
@@ -205,11 +208,12 @@
io__set_exit_status(1)
).
-:- pred output_single_c_file(c_file, maybe(int), io__state, io__state).
-:- mode output_single_c_file(in, in, di, uo) is det.
+:- pred output_single_c_file(c_file, maybe(int), set_bbbtree(label),
+ io__state, io__state).
+:- mode output_single_c_file(in, in, in, di, uo) is det.
-output_single_c_file(c_file(ModuleName, C_HeaderLines, Modules), SplitFiles)
- -->
+output_single_c_file(c_file(ModuleName, C_HeaderLines, Modules), SplitFiles,
+ StackLayoutLabels) -->
( { SplitFiles = yes(Num) } ->
module_name_to_split_c_file_name(ModuleName, Num, ".c",
FileName)
@@ -245,7 +249,7 @@
{ gather_c_file_labels(Modules, Labels) },
{ set__init(DeclSet0) },
output_c_label_decl_list(Labels, DeclSet0, DeclSet),
- output_c_module_list(Modules, DeclSet),
+ output_c_module_list(Modules, StackLayoutLabels, DeclSet),
( { SplitFiles = yes(_) } ->
[]
;
@@ -424,18 +428,21 @@
io__write_string("_bunch_"),
io__write_int(Number).
-:- pred output_c_module_list(list(c_module), decl_set, io__state, io__state).
-:- mode output_c_module_list(in, in, di, uo) is det.
+:- pred output_c_module_list(list(c_module), set_bbbtree(label), decl_set,
+ io__state, io__state).
+:- mode output_c_module_list(in, in, in, di, uo) is det.
-output_c_module_list([], _) --> [].
-output_c_module_list([M | Ms], DeclSet0) -->
- output_c_module(M, DeclSet0, DeclSet),
- output_c_module_list(Ms, DeclSet).
+output_c_module_list([], _, _) --> [].
+output_c_module_list([M | Ms], StackLayoutLabels, DeclSet0) -->
+ output_c_module(M, StackLayoutLabels, DeclSet0, DeclSet),
+ output_c_module_list(Ms, StackLayoutLabels, DeclSet).
-:- pred output_c_module(c_module, decl_set, decl_set, io__state, io__state).
-:- mode output_c_module(in, in, out, di, uo) is det.
+:- pred output_c_module(c_module, set_bbbtree(label), decl_set, decl_set,
+ io__state, io__state).
+:- mode output_c_module(in, in, in, out, di, uo) is det.
-output_c_module(c_module(ModuleName, Procedures), DeclSet0, DeclSet) -->
+output_c_module(c_module(ModuleName, Procedures), StackLayoutLabels,
+ DeclSet0, DeclSet) -->
io__write_string("\n"),
output_c_procedure_list_decls(Procedures, DeclSet0, DeclSet),
io__write_string("\n"),
@@ -443,7 +450,7 @@
io__write_string(ModuleName),
io__write_string(")\n"),
{ gather_c_module_labels(Procedures, Labels) },
- output_c_label_init_list(Labels),
+ output_c_label_init_list(Labels, StackLayoutLabels),
io__write_string("BEGIN_CODE\n"),
io__write_string("\n"),
globals__io_lookup_bool_option(auto_comments, PrintComments),
@@ -452,7 +459,7 @@
io__write_string("END_MODULE\n").
output_c_module(c_data(ModuleName, VarName, ExportedFromModule, ArgVals,
- _Refs), DeclSet0, DeclSet) -->
+ _Refs), _, DeclSet0, DeclSet) -->
io__write_string("\n"),
{ DataAddr = data_addr(data_addr(ModuleName, VarName)) },
output_cons_arg_decls(ArgVals, "", "", 0, _, DeclSet0, DeclSet1),
@@ -471,7 +478,7 @@
0, _),
{ set__insert(DeclSet1, DataAddr, DeclSet) }.
-output_c_module(c_code(C_Code, Context), DeclSet, DeclSet) -->
+output_c_module(c_code(C_Code, Context), _, DeclSet, DeclSet) -->
globals__io_lookup_bool_option(auto_comments, PrintComments),
( { PrintComments = yes } ->
io__write_string("/* "),
@@ -485,7 +492,7 @@
io__write_string("\n"),
output_reset_line_num.
-output_c_module(c_export(PragmaExports), DeclSet, DeclSet) -->
+output_c_module(c_export(PragmaExports), _, DeclSet, DeclSet) -->
output_exported_c_functions(PragmaExports).
% output_c_header_include_lines reverses the list of c header lines
@@ -522,6 +529,7 @@
:- pred output_exported_c_functions(list(string), io__state, io__state).
:- mode output_exported_c_functions(in, di, uo) is det.
+
output_exported_c_functions([]) --> [].
output_exported_c_functions([F | Fs]) -->
io__write_string(F),
@@ -568,36 +576,53 @@
output_label(Label),
io__write_string(");\n").
-:- pred output_c_label_init_list(list(label), io__state, io__state).
-:- mode output_c_label_init_list(in, di, uo) is det.
+:- pred output_c_label_init_list(list(label), set_bbbtree(label),
+ io__state, io__state).
+:- mode output_c_label_init_list(in, in, di, uo) is det.
-output_c_label_init_list([]) --> [].
-output_c_label_init_list([Label | Labels]) -->
- output_c_label_init(Label),
- output_c_label_init_list(Labels).
+output_c_label_init_list([], _) --> [].
+output_c_label_init_list([Label | Labels], StackLayoutLabels) -->
+ output_c_label_init(Label, StackLayoutLabels),
+ output_c_label_init_list(Labels, StackLayoutLabels).
-:- pred output_c_label_init(label, io__state, io__state).
-:- mode output_c_label_init(in, di, uo) is det.
+:- pred output_c_label_init(label, set_bbbtree(label), io__state, io__state).
+:- mode output_c_label_init(in, in, di, uo) is det.
-output_c_label_init(Label) -->
+output_c_label_init(Label, StackLayoutLabels) -->
(
{ Label = exported(_) },
- io__write_string("\tinit_entry("),
+ ( { set_bbbtree__member(Label, StackLayoutLabels) } ->
+ io__write_string("\tinit_entry_sl(")
+ ;
+ io__write_string("\tinit_entry(")
+ ),
output_label(Label),
io__write_string(");\n")
;
{ Label = local(_) },
- io__write_string("\tinit_entry("),
+ ( { set_bbbtree__member(Label, StackLayoutLabels) } ->
+ io__write_string("\tinit_entry_sl(")
+ ;
+ io__write_string("\tinit_entry(")
+ ),
output_label(Label),
io__write_string(");\n")
;
{ Label = c_local(_) },
- io__write_string("\tinit_local("),
+ ( { set_bbbtree__member(Label, StackLayoutLabels) } ->
+ io__write_string("\tinit_local_sl(")
+ ;
+ io__write_string("\tinit_local(")
+ ),
output_label(Label),
io__write_string(");\n")
;
{ Label = local(_, _) },
- io__write_string("\tinit_label("),
+ ( { set_bbbtree__member(Label, StackLayoutLabels) } ->
+ io__write_string("\tinit_label_sl(")
+ ;
+ io__write_string("\tinit_label(")
+ ),
output_label(Label),
io__write_string(");\n")
).
diff -u ws4/compiler/mercury_compile.m ws2/compiler/mercury_compile.m
--- ws4/compiler/mercury_compile.m Tue Apr 7 16:37:51 1998
+++ ws2/compiler/mercury_compile.m Thu Apr 2 13:09:45 1998
@@ -26,7 +26,7 @@
% library modules
:- import_module int, list, map, set, std_util, dir, require, string, bool.
-:- import_module library, getopt, term, varset.
+:- import_module library, getopt, term, set_bbbtree, varset.
% the main compiler passes (in order of execution)
:- import_module handle_options, prog_io, prog_out, modules, module_qual.
@@ -1664,10 +1664,12 @@
{ base_type_info__generate_llds(HLDS0, BaseTypeInfos) },
{ base_type_layout__generate_llds(HLDS0, HLDS1, BaseTypeLayouts) },
{ BasicStackLayout = yes ->
- stack_layout__generate_llds(HLDS1, HLDS, StackLayouts),
+ stack_layout__generate_llds(HLDS1, HLDS,
+ StackLayouts, StackLayoutLabelMap),
list__append(StackLayouts, BaseTypeLayouts, StaticData0)
;
HLDS = HLDS1,
+ set_bbbtree__init(StackLayoutLabelMap),
StaticData0 = BaseTypeLayouts
},
@@ -1677,7 +1679,8 @@
{ list__append(BaseTypeInfos, StaticData, AllData) },
mercury_compile__chunk_llds(HLDS, LLDS1, AllData, CommonData,
LLDS2, NumChunks),
- mercury_compile__output_llds(ModuleName, LLDS2, Verbose, Stats),
+ mercury_compile__output_llds(ModuleName, LLDS2, StackLayoutLabelMap,
+ Verbose, Stats),
export__produce_header_file(HLDS, ModuleName),
@@ -1791,18 +1794,19 @@
Num1 is Num + 1,
mercury_compile__combine_chunks_2(Chunks, ModName, Num1, Modules).
-:- pred mercury_compile__output_llds(module_name, c_file, bool, bool,
- io__state, io__state).
-:- mode mercury_compile__output_llds(in, in, in, in, di, uo) is det.
+:- pred mercury_compile__output_llds(module_name, c_file, set_bbbtree(label),
+ bool, bool, io__state, io__state).
+:- mode mercury_compile__output_llds(in, in, in, in, in, di, uo) is det.
-mercury_compile__output_llds(ModuleName, LLDS, Verbose, Stats) -->
+mercury_compile__output_llds(ModuleName, LLDS, StackLayoutLabels,
+ Verbose, Stats) -->
maybe_write_string(Verbose,
"% Writing output to `"),
module_name_to_file_name(ModuleName, ".c", yes, FileName),
maybe_write_string(Verbose, FileName),
maybe_write_string(Verbose, "'..."),
maybe_flush_output(Verbose),
- output_c_file(LLDS),
+ output_c_file(LLDS, StackLayoutLabels),
maybe_write_string(Verbose, " done.\n"),
maybe_flush_output(Verbose),
maybe_report_stats(Stats).
diff -u ws4/compiler/pragma_c_gen.m ws2/compiler/pragma_c_gen.m
--- ws4/compiler/pragma_c_gen.m Tue Apr 7 16:38:01 1998
+++ ws2/compiler/pragma_c_gen.m Sat Mar 28 15:23:48 1998
@@ -532,17 +532,10 @@
code_info__maybe_save_ticket(UseTrail, SaveTicketCode, MaybeTicketSlot),
code_info__maybe_reset_ticket(MaybeTicketSlot, undo, RestoreTicketCode),
- code_info__get_maybe_trace_info(MaybeTraceInfo),
- ( { MaybeTraceInfo = yes(TraceInfo) } ->
- { set__init(Empty) },
- trace__generate_event_code(disj([disj(1)], Empty), TraceInfo,
- FirstTraceCode),
- trace__generate_event_code(disj([disj(2)], Empty), TraceInfo,
- LaterTraceCode)
- ;
- { FirstTraceCode = empty },
- { LaterTraceCode = empty }
- ),
+ trace__maybe_generate_pragma_event_code(nondet_pragma_first,
+ FirstTraceCode),
+ trace__maybe_generate_pragma_event_code(nondet_pragma_later,
+ LaterTraceCode),
{ FirstDisjunctCode =
tree(SaveHeapCode,
diff -u ws4/compiler/stack_layout.m ws2/compiler/stack_layout.m
--- ws4/compiler/stack_layout.m Tue Apr 7 16:38:01 1998
+++ ws2/compiler/stack_layout.m Wed Apr 1 13:53:06 1998
@@ -87,20 +87,27 @@
% live data names (Word *) - pointer to vector of String
% type parameters (Word *) - pointer to vector of MR_Live_Lval
%
+% 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 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 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 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,
-% in some cases, XXX
+% 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
@@ -133,17 +140,17 @@
:- interface.
:- import_module hlds_module, llds.
-:- import_module list.
+:- 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 term, set.
+:- import_module assoc_list, bool, string, int, require.
+:- import_module map, std_util, term, set.
:- type stack_layout_info --->
stack_layout_info(
@@ -152,7 +159,9 @@
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
).
%---------------------------------------------------------------------------%
@@ -160,7 +169,8 @@
% Process all the continuation information stored in the HLDS,
% converting it into LLDS data structures.
-stack_layout__generate_llds(ModuleInfo0, ModuleInfo, CModules) :-
+stack_layout__generate_llds(ModuleInfo0, ModuleInfo, CModules,
+ StackLayoutLabels) :-
module_info_get_continuation_info(ModuleInfo0, ContinuationInfo),
continuation_info__get_all_proc_layouts(ContinuationInfo,
ProcLayoutList),
@@ -172,13 +182,15 @@
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).
@@ -216,9 +228,31 @@
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) ->
@@ -264,7 +298,7 @@
{ CModule = c_data(ModuleName, stack_layout(Label), yes,
MaybeRvals, []) },
- stack_layout__add_cmodule(CModule).
+ stack_layout__add_cmodule(CModule, Label).
%---------------------------------------------------------------------------%
@@ -331,7 +365,7 @@
{ 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 accurate GC or for tracing.
@@ -620,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__add_cmodule(c_module::in,
+:- pred stack_layout__get_cmodules(list(c_module)::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_cmodules(CModules, LayoutInfo, LayoutInfo) :-
+ LayoutInfo = stack_layout_info(_, _, _, _, _, CModules, _).
+
+:- pred stack_layout__get_label_set(set_bbbtree(label)::out,
+ stack_layout_info::in, stack_layout_info::out) is det.
+
+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).
diff -u ws4/compiler/string_switch.m ws2/compiler/string_switch.m
--- ws4/compiler/string_switch.m Tue Apr 7 16:38:02 1998
+++ ws2/compiler/string_switch.m Sat Mar 28 15:05:48 1998
@@ -303,28 +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) },
- { goal_info_get_pre_deaths(GoalInfo, PreDeaths) },
- trace__generate_event_code(switch(Path, PreDeaths),
- 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([
diff -u ws4/compiler/switch_gen.m ws2/compiler/switch_gen.m
--- ws4/compiler/switch_gen.m Tue Apr 7 16:38:02 1998
+++ ws2/compiler/switch_gen.m Sat Mar 28 15:41:34 1998
@@ -307,22 +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) },
- { goal_info_get_pre_deaths(GoalInfo, PreDeaths) },
- trace__generate_event_code(switch(Path, PreDeaths), 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([
@@ -341,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 =
diff -u ws4/compiler/tag_switch.m ws2/compiler/tag_switch.m
--- ws4/compiler/tag_switch.m Tue Apr 7 16:38:28 1998
+++ ws2/compiler/tag_switch.m Sat Mar 28 15:11:24 1998
@@ -659,18 +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) },
- { goal_info_get_pre_deaths(GoalInfo,
- PreDeaths) },
- trace__generate_event_code(
- switch(Path, PreDeaths),
- 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),
@@ -806,16 +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) },
- { goal_info_get_pre_deaths(GoalInfo, PreDeaths) },
- trace__generate_event_code(switch(Path, PreDeaths),
- TraceInfo, TraceCode)
- ;
- { TraceCode = empty }
- ),
( { Cases0 = [_|_] ; CanFail = can_fail } ->
code_info__grab_code_info(CodeInfo),
code_info__get_next_label(ElseLabel),
@@ -825,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([
@@ -854,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([
@@ -884,16 +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) },
- { goal_info_get_pre_deaths(GoalInfo, PreDeaths) },
- trace__generate_event_code(switch(Path, PreDeaths),
- TraceInfo, TraceCode)
- ;
- { TraceCode = empty }
- ),
( { Cases0 = [_|_] ; CanFail = can_fail } ->
code_info__grab_code_info(CodeInfo),
code_info__get_next_label(ThisStagLabel),
@@ -907,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([
@@ -936,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([
@@ -981,29 +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) },
- { goal_info_get_pre_deaths(GoalInfo,
- PreDeaths) },
- trace__generate_event_code(
- switch(Path, PreDeaths),
- 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([
@@ -1067,18 +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) },
- { goal_info_get_pre_deaths(GoalInfo,
- PreDeaths) },
- trace__generate_event_code(
- switch(Path, PreDeaths),
- 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),
More information about the developers
mailing list