[m-rev.] diff/for review: lookup disjunctions
Zoltan Somogyi
zs at csse.unimelb.edu.au
Mon Dec 11 14:13:59 AEDT 2006
Does anyone want to review this?
Julien: when this diff has been in place for a while without problems,
we can stop supporting fact tables.
Zoltan.
For disjunctions in which all disjuncts are just facts, generate code
that does table lookup.
compiler/disj_gen.m:
Implement lookup disjunctions. The new code based on the code in
lookup_switch.m for generating switches in which some some switch arms
are disjunctions. The code we generate is a specialized version
we would generate for such switch arms.
compiler/lookup_switch.m:
compiler/lookup_util.m:
Move some predicates from lookup_switch.m to lookup_util.m, to allow
disj_gen.m to call them also.
Reorder some argument lists to group related arguments together.
Give some predicates more descriptive names.
In lookup_switch.m, improve some comments. In lookup_util.m, avoid
computing ExprnOpts many times.
compiler/switch_gen.m:
Fix some obsolete some comments.
compiler/continuation_info.m:
Provide for a description of the stack slot used by the new code in
disj_gen.m.
compiler/opt_debug.m:
Pass a maybe(proc_label) argument to the predicates that dump rvals
and things that may contain rvals, so that rvals that are code
constants may be printed in the short, user-friendly format
(e.g. local_1, instead of the full, usually very long label name).
This was helpful in debugging the change to disj_gen.m.
Remove the old predicates whose sole purpose was to supply a
proc_label for this purpose (e.g. dump_label_for_proc), since now
even the predicates they are based on (e.g. dump_label) can now
be given a proc_label.
compiler/frameopt.m:
compiler/use_local_vars.m:
compiler/switch_gen.m:
Conform to the change to opt_debug.m.
tests/hard_coded/lookup_disj.{m,exp}:
New test case to test the handling of the lookup tables.
Existing test cases, specifically do_while, nasty_nondet, and
nondet_ite* in general, and pretty_printing in hard_coded,
are already tough tests of the handling of the code generator's
internal data structures (such as the failure stack and the set of
reserved stack slots).
tests/hard_coded/Mmakefile:
Enable the new test case.
cvs diff: Diffing .
cvs diff: Diffing analysis
cvs diff: Diffing bindist
cvs diff: Diffing boehm_gc
cvs diff: Diffing boehm_gc/Mac_files
cvs diff: Diffing boehm_gc/cord
cvs diff: Diffing boehm_gc/cord/private
cvs diff: Diffing boehm_gc/doc
cvs diff: Diffing boehm_gc/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing boehm_gc/libatomic_ops-1.2
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/doc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/gcc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/hpc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/ibmc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/icc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/msftc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/src/atomic_ops/sysdeps/sunc
cvs diff: Diffing boehm_gc/libatomic_ops-1.2/tests
cvs diff: Diffing boehm_gc/tests
cvs diff: Diffing boehm_gc/windows-untested
cvs diff: Diffing boehm_gc/windows-untested/vc60
cvs diff: Diffing boehm_gc/windows-untested/vc70
cvs diff: Diffing boehm_gc/windows-untested/vc71
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
Index: compiler/continuation_info.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/continuation_info.m,v
retrieving revision 1.84
diff -u -b -r1.84 continuation_info.m
--- compiler/continuation_info.m 5 Dec 2006 03:50:49 -0000 1.84
+++ compiler/continuation_info.m 10 Dec 2006 04:16:46 -0000
@@ -317,6 +317,7 @@
---> ticket % A ticket (trail pointer).
; ticket_counter % A copy of the ticket counter.
; trace_data
+ ; lookup_disj_cur
; lookup_switch_cur
; lookup_switch_max
; sync_term % A syncronization term used
@@ -908,6 +909,7 @@
% XXX we may need to modify this, if the GC is going to garbage-collect
% the trail.
live_value_type(ticket_counter, live_value_unwanted).
+live_value_type(lookup_disj_cur, live_value_unwanted).
live_value_type(lookup_switch_cur, live_value_unwanted).
live_value_type(lookup_switch_max, live_value_unwanted).
live_value_type(sync_term, live_value_unwanted).
Index: compiler/disj_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/disj_gen.m,v
retrieving revision 1.99
diff -u -b -r1.99 disj_gen.m
--- compiler/disj_gen.m 1 Dec 2006 15:03:54 -0000 1.99
+++ compiler/disj_gen.m 10 Dec 2006 09:42:29 -0000
@@ -33,6 +33,7 @@
:- implementation.
+:- import_module backend_libs.builtin_ops.
:- import_module hlds.goal_form.
:- import_module hlds.hlds_llds.
:- import_module libs.compiler_util.
@@ -41,10 +42,15 @@
:- import_module libs.tree.
:- import_module libs.tree.
:- import_module ll_backend.code_gen.
+:- import_module ll_backend.continuation_info.
+:- import_module ll_backend.global_data.
+:- import_module ll_backend.lookup_util.
:- import_module ll_backend.trace_gen.
:- import_module parse_tree.prog_data.
:- import_module bool.
+:- import_module int.
+:- import_module map.
:- import_module maybe.
:- import_module pair.
:- import_module set.
@@ -69,16 +75,239 @@
;
set.init(ResumeVars)
),
+ (
+ CodeModel = model_non,
+ is_lookup_disj(AddTrailOps, ResumeVars, Goals, DisjGoalInfo,
+ LookupDisjInfo, !CI)
+ ->
+ generate_lookup_disj(ResumeVars, LookupDisjInfo, Code, !CI)
+ ;
generate_real_disj(AddTrailOps, CodeModel, ResumeVars, Goals,
DisjGoalInfo, Code, !CI)
+ )
).
-%---------------------------------------------------------------------------%
+:- type lookup_disj_info
+ ---> lookup_disj_info(
+ ldi_variables :: list(prog_var),
+ % The output variables.
+
+ ldi_store_map :: abs_store_map,
+ ldi_branch_end :: branch_end,
+ ldi_liveness :: set(prog_var),
+
+ lds_cur_slot :: lval,
+
+ lds_resume_map :: resume_map,
+ lds_flush_code :: code_tree,
+
+ lds_save_ticket_code :: code_tree,
+ lds_maybe_ticket_slot :: maybe(lval),
+
+ lds_save_hp_code :: code_tree,
+ lds_maybe_hp_slot :: maybe(lval),
+
+ lds_hijack_info :: disj_hijack_info,
+ lds_prepare_hijack_code :: code_tree,
+
+ ldi_solns :: list(list(rval)),
+ ldi_field_types :: list(llds_type)
+ ).
+
+:- pred is_lookup_disj(bool::in, set(prog_var)::in, list(hlds_goal)::in,
+ hlds_goal_info::in, lookup_disj_info::out, code_info::in, code_info::out)
+ is semidet.
+
+is_lookup_disj(AddTrailOps, ResumeVars, Goals, DisjGoalInfo, LookupDisjInfo,
+ !CI) :-
+ code_info.get_maybe_trace_info(!.CI, MaybeTraceInfo),
+ MaybeTraceInfo = no,
+
+ % Lookup disjunctions rely on static ground terms to work.
+ code_info.get_globals(!.CI, Globals),
+ globals.lookup_bool_option(Globals, static_ground_terms, yes),
+
+ % Since we generate two code sequences, one for the first solution and one
+ % for all the later solutions, we don't get any benefit over the code
+ % sequence generated by generate_real_disj unless there are at least three
+ % solutions.
+ Goals = [_, _, _ | _],
+ all_disjuncts_are_conj_of_unify(Goals),
+
+ figure_out_output_vars(!.CI, DisjGoalInfo, OutVars),
+ VarTypes = get_var_types(!.CI),
+ list.map(map.lookup(VarTypes), OutVars, OutTypes),
+
+ code_info.produce_vars(ResumeVars, ResumeMap, FlushCode, !CI),
-:- pred disj_gen.generate_real_disj(bool::in, code_model::in,
- set(prog_var)::in, list(hlds_goal)::in, hlds_goal_info::in,
+ % We cannot release this stack slot anywhere, since it will be needed
+ % after backtracking.
+ code_info.acquire_temp_slot(lookup_disj_cur, CurSlot, !CI),
+ code_info.maybe_save_ticket(AddTrailOps, SaveTicketCode, MaybeTicketSlot,
+ !CI),
+ code_info.get_globals(!.CI, Globals),
+ globals.lookup_bool_option(Globals, reclaim_heap_on_nondet_failure,
+ ReclaimHeap),
+ code_info.maybe_save_hp(ReclaimHeap, SaveHpCode, MaybeHpSlot, !CI),
+ code_info.prepare_for_disj_hijack(model_non, HijackInfo, PrepareHijackCode,
+ !CI),
+
+ % Every update to the code_info that needs to persist beyond the
+ % disjunction as a whole (e.g. the reservations of the stack slots required
+ % to implement the hijack) must be done before we remember this position.
+ code_info.remember_position(!.CI, CurPos),
+
+ goal_info_get_store_map(DisjGoalInfo, StoreMap),
+ generate_constants_for_disjuncts(Goals, OutVars, StoreMap, Solns,
+ no, MaybeEnd, MaybeLiveness, !CI),
+ (
+ MaybeLiveness = yes(Liveness)
+ ;
+ MaybeLiveness = no,
+ unexpected(this_file, "is_lookup_disj: no liveness")
+ ),
+ code_info.reset_to_position(CurPos, !CI),
+
+ code_info.get_globals(!.CI, Globals),
+ globals.lookup_bool_option(Globals, unboxed_float, UnboxFloat),
+ find_general_llds_types(UnboxFloat, OutTypes, Solns, LLDSTypes),
+ LookupDisjInfo = lookup_disj_info(OutVars, StoreMap, MaybeEnd, Liveness,
+ CurSlot, ResumeMap, FlushCode, SaveTicketCode, MaybeTicketSlot,
+ SaveHpCode, MaybeHpSlot, HijackInfo, PrepareHijackCode,
+ Solns, LLDSTypes).
+
+:- pred generate_lookup_disj(set(prog_var)::in, lookup_disj_info::in,
code_tree::out, code_info::in, code_info::out) is det.
+generate_lookup_disj(ResumeVars, LookupDisjInfo, Code, !CI) :-
+ LookupDisjInfo = lookup_disj_info(OutVars, StoreMap, MaybeEnd, Liveness,
+ CurSlot, ResumeMap, FlushCode, SaveTicketCode, MaybeTicketSlot,
+ SaveHpCode, MaybeHpSlot, HijackInfo, PrepareHijackCode,
+ Solns, LLDSTypes),
+
+ list.length(Solns, NumSolns),
+ list.length(OutVars, NumOutVars),
+
+ code_info.add_vector_static_cell(LLDSTypes, Solns, SolnVectorAddr, !CI),
+ SolnVectorAddrRval = const(llconst_data_addr(SolnVectorAddr, no)),
+
+ code_info.get_next_label(EndLabel, !CI),
+
+ % Since we release BaseReg only after the calls to generate_branch_end
+ % (invoked through set_liveness_and_end_branch) we must ensure that
+ % generate_branch_end won't want to overwrite BaseReg.
+ code_info.acquire_reg_not_in_storemap(StoreMap, BaseReg, !CI),
+
+ BaseRegInitCode = node([
+ assign(BaseReg,
+ mem_addr(heap_ref(SolnVectorAddrRval, 0, const(llconst_int(0)))))
+ - "Compute base address for this case"
+ ]),
+ SaveSlotCode = node([
+ assign(CurSlot, const(llconst_int(NumOutVars)))
+ - "Setup current slot in the solution array"
+ ]),
+
+ code_info.remember_position(!.CI, DisjEntry),
+
+ code_info.make_resume_point(ResumeVars, resume_locs_stack_only,
+ ResumeMap, ResumePoint, !CI),
+ code_info.effect_resume_point(ResumePoint, model_non, UpdateRedoipCode,
+ !CI),
+ generate_offset_assigns(OutVars, 0, BaseReg, !CI),
+ code_info.flush_resume_vars_to_stack(FirstFlushResumeVarsCode, !CI),
+
+ % Forget the variables that are needed only at the resumption point at
+ % the start of the next disjunct, so that we don't generate exceptions
+ % when their storage is clobbered by the movement of the live variables
+ % to the places indicated in the store map.
+ code_info.pop_resume_point(!CI),
+ code_info.pickup_zombies(FirstZombies, !CI),
+ code_info.make_vars_forward_dead(FirstZombies, !CI),
+
+ set_liveness_and_end_branch(StoreMap, MaybeEnd, Liveness,
+ FirstBranchEndCode, !CI),
+ code_info.release_reg(BaseReg, !CI),
+
+ GotoEndCode = node([
+ goto(code_label(EndLabel)) - "goto end of lookup disj"
+ ]),
+
+ code_info.reset_to_position(DisjEntry, !CI),
+ code_info.generate_resume_point(ResumePoint, ResumePointCode, !CI),
+
+ code_info.maybe_reset_ticket(MaybeTicketSlot, reset_reason_undo,
+ RestoreTicketCode),
+ code_info.maybe_restore_hp(MaybeHpSlot, RestoreHpCode),
+
+ code_info.acquire_reg_not_in_storemap(StoreMap, LaterBaseReg, !CI),
+ code_info.get_next_label(UndoLabel, !CI),
+ code_info.get_next_label(AfterUndoLabel, !CI),
+ MaxSlot = (NumSolns - 1) * NumOutVars,
+ TestMoreSolnsCode = node([
+ assign(LaterBaseReg, lval(CurSlot))
+ - "Init later base register",
+ if_val(binop(int_ge, lval(LaterBaseReg), const(llconst_int(MaxSlot))),
+ code_label(UndoLabel))
+ - "Jump to undo hijack code if there are no more solutions",
+ assign(CurSlot,
+ binop(int_add, lval(CurSlot), const(llconst_int(NumOutVars))))
+ - "Update current slot",
+ goto(code_label(AfterUndoLabel))
+ - "Jump around undo hijack code",
+ label(UndoLabel)
+ - "Undo hijack code"
+ ]),
+ code_info.undo_disj_hijack(HijackInfo, UndoHijackCode, !CI),
+ AfterUndoLabelCode = node([
+ label(AfterUndoLabel)
+ - "Return later answer code",
+ assign(LaterBaseReg,
+ mem_addr(heap_ref(SolnVectorAddrRval, 0, lval(LaterBaseReg))))
+ - "Compute base address in later array for this solution"
+ ]),
+
+ % We need to call effect_resume_point in order to push ResumePoint
+ % onto the failure continuation stack, so pop_resume_point can pop
+ % it off. However, since the redoip already points there, we don't need
+ % to execute _LaterUpdateRedoipCode.
+ code_info.effect_resume_point(ResumePoint, model_non,
+ _LaterUpdateRedoipCode, !CI),
+
+ generate_offset_assigns(OutVars, 0, LaterBaseReg, !CI),
+ code_info.flush_resume_vars_to_stack(LaterFlushResumeVarsCode, !CI),
+
+ % Forget the variables that are needed only at the resumption point at
+ % the start of the next disjunct, so that we don't generate exceptions
+ % when their storage is clobbered by the movement of the live variables
+ % to the places indicated in the store map.
+ code_info.pop_resume_point(!CI),
+ code_info.pickup_zombies(LaterZombies, !CI),
+ code_info.make_vars_forward_dead(LaterZombies, !CI),
+
+ set_liveness_and_end_branch(StoreMap, MaybeEnd, Liveness,
+ LaterBranchEndCode, !CI),
+
+ code_info.after_all_branches(StoreMap, MaybeEnd, !CI),
+
+ EndLabelCode = node([
+ label(EndLabel) - "end of lookup disj"
+ ]),
+
+ Comment = node([comment("lookup disj") - ""]),
+ Code = tree_list([Comment, FlushCode, BaseRegInitCode,
+ SaveSlotCode, SaveTicketCode, SaveHpCode, PrepareHijackCode,
+ UpdateRedoipCode, FirstFlushResumeVarsCode, FirstBranchEndCode,
+ GotoEndCode, ResumePointCode, RestoreTicketCode, RestoreHpCode,
+ TestMoreSolnsCode, UndoHijackCode, AfterUndoLabelCode,
+ LaterFlushResumeVarsCode, LaterBranchEndCode, EndLabelCode]).
+
+%---------------------------------------------------------------------------%
+
+:- pred generate_real_disj(bool::in, code_model::in, set(prog_var)::in,
+ list(hlds_goal)::in, hlds_goal_info::in, code_tree::out,
+ code_info::in, code_info::out) is det.
+
generate_real_disj(AddTrailOps, CodeModel, ResumeVars, Goals, DisjGoalInfo,
Code, !CI) :-
% Make sure that the variables whose values will be needed on backtracking
@@ -119,8 +348,8 @@
% Save the values of any stack slots we may hijack, and if necessary,
% set the redofr slot of the top frame to point to this frame.
- code_info.prepare_for_disj_hijack(CodeModel, HijackInfo,
- PrepareHijackCode, !CI),
+ code_info.prepare_for_disj_hijack(CodeModel, HijackInfo, PrepareHijackCode,
+ !CI),
code_info.get_next_label(EndLabel, !CI),
@@ -161,8 +390,8 @@
% we arrive at this disjunct.
(
MaybeEntryResumePoint = yes(EntryResumePoint),
- code_info.generate_resume_point(EntryResumePoint,
- EntryResumePointCode, !CI)
+ code_info.generate_resume_point(EntryResumePoint, EntryResumePointCode,
+ !CI)
;
MaybeEntryResumePoint = no,
EntryResumePointCode = empty
@@ -181,8 +410,8 @@
code_info.maybe_restore_hp(MaybeHpSlot0, RestoreHpCode),
% Reset the solver state if necessary.
- code_info.maybe_reset_ticket(MaybeTicketSlot,
- reset_reason_undo, RestoreTicketCode)
+ code_info.maybe_reset_ticket(MaybeTicketSlot, reset_reason_undo,
+ RestoreTicketCode)
;
MaybeEntryResumePoint = no,
RestoreHpCode = empty,
@@ -265,14 +494,14 @@
% the place indicated by StoreMap, and accumulate information about
% the code_info state at the ends of the branches so far.
goal_info_get_store_map(DisjGoalInfo, StoreMap),
- code_info.generate_branch_end(StoreMap, MaybeEnd0, MaybeEnd1,
- SaveCode, !CI),
+ code_info.generate_branch_end(StoreMap, MaybeEnd0, MaybeEnd1, SaveCode,
+ !CI),
BranchCode = node([
goto(code_label(EndLabel)) - "skip to end of nondet disj"
]),
- disj_gen.generate_disjuncts(Goals, CodeModel, FullResumeMap,
+ generate_disjuncts(Goals, CodeModel, FullResumeMap,
yes(NextResumePoint), HijackInfo, DisjGoalInfo,
EndLabel, ReclaimHeap, MaybeHpSlot, MaybeTicketSlot, BranchStart,
MaybeEnd1, MaybeEnd, RestCode, !CI),
Index: compiler/frameopt.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/frameopt.m,v
retrieving revision 1.108
diff -u -b -r1.108 frameopt.m
--- compiler/frameopt.m 1 Dec 2006 15:03:56 -0000 1.108
+++ compiler/frameopt.m 10 Dec 2006 08:26:23 -0000
@@ -2051,7 +2051,7 @@
% This can happen if fulljump optimization has redirected the
% return.
Comments = [comment("exit side labels "
- ++ dump_labels_for_proc(ProcLabel, SideLabels)) - ""]
+ ++ dump_labels(yes(ProcLabel), SideLabels)) - ""]
),
PrevNeedsFrame = prev_block_needs_frame(OrdNeedsFrame, BlockInfo0),
( Type = exit_block(ExitInfo) ->
@@ -2221,19 +2221,19 @@
SideLabels, MaybeFallThrough, Type),
expect(unify(Label, BlockLabel), this_file,
"describe_block: label mismatch"),
- LabelStr = dump_label_for_proc(ProcLabel, Label),
+ LabelStr = dump_label(yes(ProcLabel), Label),
BlockInstrsStr = dump_fullinstrs(ProcLabel, yes, BlockInstrs),
Heading = "\nBLOCK " ++ LabelStr ++ "\n\n",
( map.search(PredMap, Label, PredLabel) ->
PredStr = "previous label " ++
- dump_label_for_proc(ProcLabel, PredLabel) ++ "\n"
+ dump_label(yes(ProcLabel), PredLabel) ++ "\n"
;
PredStr = "no previous label\n"
),
(
FallInto = yes(FallIntoFromLabel),
FallIntoStr = "fallen into from " ++
- dump_label_for_proc(ProcLabel, FallIntoFromLabel) ++ "\n"
+ dump_label(yes(ProcLabel), FallIntoFromLabel) ++ "\n"
;
FallInto = no,
FallIntoStr = "not fallen into\n"
@@ -2244,12 +2244,12 @@
;
SideLabels = [_ | _],
SideStr = "side labels " ++
- dump_labels_for_proc(ProcLabel, SideLabels) ++ "\n"
+ dump_labels(yes(ProcLabel), SideLabels) ++ "\n"
),
(
MaybeFallThrough = yes(FallThroughLabel),
FallThroughStr = "falls through to " ++
- dump_label_for_proc(ProcLabel, FallThroughLabel) ++ "\n"
+ dump_label(yes(ProcLabel), FallThroughLabel) ++ "\n"
;
MaybeFallThrough = no,
FallThroughStr = "does not fall through\n"
@@ -2336,7 +2336,7 @@
++ ", size: "
++ int_to_string(Size)
++ ", redoip: "
- ++ dump_code_addr(Redoip)
+ ++ dump_code_addr(no, Redoip)
++ "\n".
:- func describe_nondet_exit(proc_label, nondet_exit_info) = string.
@@ -2369,20 +2369,20 @@
:- func describe_reason(proc_label, needs_frame_reason) = string.
describe_reason(ProcLabel, code_needs_frame(Label)) =
- "code " ++ dump_label_for_proc(ProcLabel, Label).
+ "code " ++ dump_label(yes(ProcLabel), Label).
describe_reason(_ProcLabel, keep_frame) = "keep_frame".
describe_reason(_ProcLabel, redoip_label) = "redoip_label".
describe_reason(ProcLabel, frontier(Label, Reasons)) =
- "frontier(" ++ dump_label_for_proc(ProcLabel, Label) ++ ", {"
+ "frontier(" ++ dump_label(yes(ProcLabel), Label) ++ ", {"
++ describe_reasons(ProcLabel, to_sorted_list(Reasons)) ++ "})".
describe_reason(ProcLabel, jump_around(Label, Reasons)) =
- "jump_around(" ++ dump_label_for_proc(ProcLabel, Label) ++ ", {"
+ "jump_around(" ++ dump_label(yes(ProcLabel), Label) ++ ", {"
++ describe_reasons(ProcLabel, to_sorted_list(Reasons)) ++ "})".
describe_reason(ProcLabel, succ_propagated(Label, Reason)) =
- "successor(" ++ dump_label_for_proc(ProcLabel, Label) ++ ", "
+ "successor(" ++ dump_label(yes(ProcLabel), Label) ++ ", "
++ describe_reason(ProcLabel, Reason) ++ ")".
describe_reason(ProcLabel, pred_propagated(Label, Reason)) =
- "predecessor(" ++ dump_label_for_proc(ProcLabel, Label) ++ ", "
+ "predecessor(" ++ dump_label(yes(ProcLabel), Label) ++ ", "
++ describe_reason(ProcLabel, Reason) ++ ")".
:- func describe_reasons(proc_label, list(needs_frame_reason)) = string.
Index: compiler/lookup_switch.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/lookup_switch.m,v
retrieving revision 1.72
diff -u -b -r1.72 lookup_switch.m
--- compiler/lookup_switch.m 1 Dec 2006 15:04:04 -0000 1.72
+++ compiler/lookup_switch.m 10 Dec 2006 04:38:13 -0000
@@ -11,8 +11,8 @@
%
% For switches on atomic types in which the cases contain only the
% construction of constants, generate code which just assigns the values of
-% the output variables by indexing into an array of values for each output
-% variable.
+% the output variables by indexing into an array of values for the output
+% variables.
%
% For switches that can fail, the generated code does a range check on the
% index, and then does a lookup in a bit-vector to see if there is a value for
@@ -156,10 +156,10 @@
StoreMap, !MaybeEnd, CodeModel, LookupSwitchInfo, !CI) :-
% We need the code_info structure to generate code for the cases to
% get the constants (if they exist). We can't throw it away at the
- % end because we may have allocated some new static ground term labels.
+ % end because we may have allocated some new static ground terms.
% Since lookup switches rely on static ground terms to work efficiently,
- % there is no point in using a lookup switch if static-ground-terms are
+ % there is no point in using a lookup switch if static ground terms are
% not enabled. Well, actually, it is possible that they might be a win in
% some circumstances, but it would take a pretty complex heuristic to get
% it right, so, lets just use a simple one - no static ground terms,
@@ -240,8 +240,9 @@
),
figure_out_output_vars(!.CI, GoalInfo, OutVars),
code_info.remember_position(!.CI, CurPos),
- generate_constants(TaggedCases, OutVars, StoreMap, !MaybeEnd,
- CaseSolns, MaybeLiveness, set.init, ResumeVars, no, GoalTrailOps, !CI),
+ generate_constants_for_lookup_switch(TaggedCases, OutVars, StoreMap,
+ CaseSolns, !MaybeEnd, MaybeLiveness, set.init, ResumeVars,
+ no, GoalTrailOps, !CI),
code_info.reset_to_position(CurPos, !CI),
(
MaybeLiveness = yes(Liveness)
@@ -310,16 +311,17 @@
%---------------------------------------------------------------------------%
-:- pred generate_constants(cases_list::in, list(prog_var)::in,
- abs_store_map::in, branch_end::in, branch_end::out,
- assoc_list(int, soln_consts)::out, maybe(set(prog_var))::out,
+:- pred generate_constants_for_lookup_switch(cases_list::in,
+ list(prog_var)::in, abs_store_map::in, assoc_list(int, soln_consts)::out,
+ branch_end::in, branch_end::out, maybe(set(prog_var))::out,
set(prog_var)::in, set(prog_var)::out, bool::in, bool::out,
code_info::in, code_info::out) is semidet.
-generate_constants([], _Vars, _StoreMap, !MaybeEnd, [], no, !ResumeVars,
- !GoalTrailOps, !CI).
-generate_constants([Case | Cases], Vars, StoreMap, !MaybeEnd, [CaseVal | Rest],
- MaybeLiveness, !ResumeVars, !GoalTrailOps, !CI) :-
+generate_constants_for_lookup_switch([], _Vars, _StoreMap, [], !MaybeEnd, no,
+ !ResumeVars, !GoalTrailOps, !CI).
+generate_constants_for_lookup_switch([Case | Cases], Vars, StoreMap,
+ [CaseVal | Rest], !MaybeEnd, MaybeLiveness, !ResumeVars,
+ !GoalTrailOps, !CI) :-
Case = extended_case(_, int_tag(CaseTag), _, Goal),
Goal = GoalExpr - GoalInfo,
@@ -354,23 +356,23 @@
% generate_constants_for_disjuncts in lookup_util.m.
code_info.pre_goal_update(GoalInfo, no, !CI),
code_info.get_instmap(!.CI, InstMap),
- generate_constants_for_disjuncts(Disjuncts, Vars, StoreMap, !MaybeEnd,
- Solns, MaybeLiveness, !CI),
+ generate_constants_for_disjuncts(Disjuncts, Vars, StoreMap, Solns,
+ !MaybeEnd, MaybeLiveness, !CI),
code_info.set_instmap(InstMap, !CI),
code_info.post_goal_update(GoalInfo, !CI),
CaseVal = CaseTag - several_solns(Solns)
;
goal_is_conj_of_unify(Goal),
- % The pre- and post-goal updates for the goals themselves are
- % done as part of the call to generate_goal in
+ % The pre- and post-goal updates for the goals themselves
+ % are done as part of the call to generate_goal in
% generate_constants_for_disjuncts in lookup_util.m.
- generate_constants_for_arm(Goal, Vars, StoreMap, !MaybeEnd, Soln,
- Liveness, !CI),
+ generate_constants_for_arm(Goal, Vars, StoreMap, Soln,
+ !MaybeEnd, Liveness, !CI),
MaybeLiveness = yes(Liveness),
CaseVal = CaseTag - one_soln(Soln)
),
- generate_constants(Cases, Vars, StoreMap, !MaybeEnd, Rest, _, !ResumeVars,
- !GoalTrailOps, !CI).
+ generate_constants_for_lookup_switch(Cases, Vars, StoreMap, Rest,
+ !MaybeEnd, _, !ResumeVars, !GoalTrailOps, !CI).
%---------------------------------------------------------------------------%
@@ -540,7 +542,7 @@
% Now generate the static cells into which we do the lookups of the values
% of the output variables, if there are any.
%
- % We put a dummy row at the start
+ % We put a dummy row at the start.
list.length(LLDSTypes, NumLLDSTypes),
InitRowNumber = 1,
DummyLaterSolnRow = list.map(default_value_for_type, LLDSTypes),
@@ -689,8 +691,8 @@
% Forget the variables that are needed only at the resumption point at
% the start of the next disjunct, so that we don't generate exceptions
- % when their storage is clobbered by the movement of the live
- % variables to the places indicated in the store map.
+ % when their storage is clobbered by the movement of the live variables
+ % to the places indicated in the store map.
code_info.pop_resume_point(!CI),
code_info.pickup_zombies(FirstZombies, !CI),
code_info.make_vars_forward_dead(FirstZombies, !CI),
@@ -749,8 +751,8 @@
% Forget the variables that are needed only at the resumption point at
% the start of the next disjunct, so that we don't generate exceptions
- % when their storage is clobbered by the movement of the live
- % variables to the places indicated in the store map.
+ % when their storage is clobbered by the movement of the live variables
+ % to the places indicated in the store map.
code_info.pop_resume_point(!CI),
code_info.pickup_zombies(LaterZombies, !CI),
code_info.make_vars_forward_dead(LaterZombies, !CI),
@@ -794,18 +796,6 @@
LaterKindsCode])
).
-:- pred set_liveness_and_end_branch(abs_store_map::in, branch_end::in,
- set(prog_var)::in, code_tree::out, code_info::in, code_info::out) is det.
-
-set_liveness_and_end_branch(StoreMap, MaybeEnd0, Liveness, BranchEndCode,
- !CI) :-
- % We keep track of what variables are supposed to be live at the end
- % of cases. We have to do this explicitly because generating a `fail' slot
- % last would yield the wrong liveness.
- code_info.set_forward_live_vars(Liveness, !CI),
- code_info.generate_branch_end(StoreMap, MaybeEnd0, _MaybeEnd,
- BranchEndCode, !CI).
-
% Note that we specify --optimise-constructor-last-call for this module
% in order to make this predicate tail recursive.
%
@@ -992,19 +982,6 @@
%-----------------------------------------------------------------------------%
-:- pred generate_offset_assigns(list(prog_var)::in, int::in, lval::in,
- code_info::in, code_info::out) is det.
-
-generate_offset_assigns([], _, _, !CI).
-generate_offset_assigns([Var | Vars], Offset, BaseReg, !CI) :-
- LookupLval = field(yes(0), lval(BaseReg), const(llconst_int(Offset))),
- code_info.assign_lval_to_var(Var, LookupLval, Code, !CI),
- expect(tree.is_empty(Code), this_file,
- "generate_offset_assigns: nonempty code"),
- generate_offset_assigns(Vars, Offset + 1, BaseReg, !CI).
-
-%-----------------------------------------------------------------------------%
-
:- func default_value_for_type(llds_type) = rval.
default_value_for_type(bool) = const(llconst_int(0)).
Index: compiler/lookup_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/lookup_util.m,v
retrieving revision 1.2
diff -u -b -r1.2 lookup_util.m
--- compiler/lookup_util.m 3 May 2006 06:46:15 -0000 1.2
+++ compiler/lookup_util.m 10 Dec 2006 04:39:42 -0000
@@ -58,14 +58,20 @@
% does steps 2, 3 and 4).
%
:- pred generate_constants_for_arm(hlds_goal::in, list(prog_var)::in,
- abs_store_map::in, branch_end::in, branch_end::out, list(rval)::out,
+ abs_store_map::in, list(rval)::out, branch_end::in, branch_end::out,
set(prog_var)::out, code_info::in, code_info::out) is semidet.
:- pred generate_constants_for_disjuncts(list(hlds_goal)::in,
- list(prog_var)::in, abs_store_map::in, branch_end::in, branch_end::out,
- list(list(rval))::out, maybe(set(prog_var))::out,
+ list(prog_var)::in, abs_store_map::in, list(list(rval))::out,
+ branch_end::in, branch_end::out, maybe(set(prog_var))::out,
code_info::in, code_info::out) is semidet.
+:- pred set_liveness_and_end_branch(abs_store_map::in, branch_end::in,
+ set(prog_var)::in, code_tree::out, code_info::in, code_info::out) is det.
+
+:- pred generate_offset_assigns(list(prog_var)::in, int::in, lval::in,
+ code_info::in, code_info::out) is det.
+
%-----------------------------------------------------------------------------%
:- implementation.
@@ -73,12 +79,14 @@
:- import_module check_hlds.mode_util.
:- import_module hlds.code_model.
:- import_module hlds.instmap.
+:- import_module libs.compiler_util.
:- import_module libs.globals.
:- import_module libs.tree.
:- import_module ll_backend.code_gen.
:- import_module ll_backend.exprn_aux.
:- import_module bool.
+:- import_module int.
:- import_module pair.
:- import_module solutions.
@@ -132,19 +140,23 @@
CaseRvals, Liveness, !CI).
:- pred do_generate_constants_for_arm(hlds_goal::in, list(prog_var)::in,
- abs_store_map::in, bool::in, branch_end::in, branch_end::out,
- list(rval)::out, set(prog_var)::out, code_info::in, code_info::out)
- is semidet.
+ abs_store_map::in, bool::in, list(rval)::out,
+ branch_end::in, branch_end::out, set(prog_var)::out,
+ code_info::in, code_info::out) is semidet.
-do_generate_constants_for_arm(Goal, Vars, StoreMap, SetToUnknown, !MaybeEnd,
- CaseRvals, Liveness, !CI) :-
+do_generate_constants_for_arm(Goal, Vars, StoreMap, SetToUnknown, CaseRvals,
+ !MaybeEnd, Liveness, !CI) :-
code_info.remember_position(!.CI, BranchStart),
Goal = _GoalExpr - GoalInfo,
goal_info_get_code_model(GoalInfo, CodeModel),
code_gen.generate_goal(CodeModel, Goal, Code, !CI),
tree.tree_of_lists_is_empty(Code),
code_info.get_forward_live_vars(!.CI, Liveness),
- get_arm_rvals(Vars, CaseRvals, !CI),
+
+ code_info.get_globals(!.CI, Globals),
+ globals.get_options(Globals, Options),
+ exprn_aux.init_exprn_opts(Options, ExprnOpts),
+ get_arm_rvals(Vars, CaseRvals, !CI, ExprnOpts),
(
SetToUnknown = no
;
@@ -157,35 +169,32 @@
code_info.generate_branch_end(StoreMap, !MaybeEnd, _EndCode, !CI),
code_info.reset_to_position(BranchStart, !CI).
-generate_constants_for_disjuncts([], _Vars, _StoreMap, !MaybeEnd, [],
+generate_constants_for_disjuncts([], _Vars, _StoreMap, [], !MaybeEnd,
no, !CI).
generate_constants_for_disjuncts([Disjunct0 | Disjuncts], Vars, StoreMap,
- !MaybeEnd, [Soln | Solns], yes(Liveness), !CI) :-
- % The pre_goal_update sanity check insists on no_resume_point, to make
- % sure that all resume points have been handled by surrounding code.
+ [Soln | Solns], !MaybeEnd, yes(Liveness), !CI) :-
+ % The pre_goal_update sanity check insists on no_resume_point, to ensure
+ % that all resume points have been handled by surrounding code.
Disjunct0 = DisjunctGoalExpr - DisjunctGoalInfo0,
goal_info_set_resume_point(no_resume_point,
DisjunctGoalInfo0, DisjunctGoalInfo),
Disjunct = DisjunctGoalExpr - DisjunctGoalInfo,
- do_generate_constants_for_arm(Disjunct, Vars, StoreMap, yes, !MaybeEnd,
- Soln, Liveness, !CI),
- generate_constants_for_disjuncts(Disjuncts, Vars, StoreMap, !MaybeEnd,
- Solns, _, !CI).
+ do_generate_constants_for_arm(Disjunct, Vars, StoreMap, yes, Soln,
+ !MaybeEnd, Liveness, !CI),
+ generate_constants_for_disjuncts(Disjuncts, Vars, StoreMap, Solns,
+ !MaybeEnd, _, !CI).
%---------------------------------------------------------------------------%
:- pred get_arm_rvals(list(prog_var)::in, list(rval)::out,
- code_info::in, code_info::out) is semidet.
+ code_info::in, code_info::out, exprn_opts::in) is semidet.
-get_arm_rvals([], [], !CI).
-get_arm_rvals([Var | Vars], [Rval | Rvals], !CI) :-
+get_arm_rvals([], [], !CI, _ExprnOpts).
+get_arm_rvals([Var | Vars], [Rval | Rvals], !CI, ExprnOpts) :-
code_info.produce_variable(Var, Code, Rval, !CI),
tree.tree_of_lists_is_empty(Code),
- code_info.get_globals(!.CI, Globals),
- globals.get_options(Globals, Options),
- exprn_aux.init_exprn_opts(Options, ExprnOpts),
rval_is_constant(Rval, ExprnOpts),
- get_arm_rvals(Vars, Rvals, !CI).
+ get_arm_rvals(Vars, Rvals, !CI, ExprnOpts).
% rval_is_constant(Rval, ExprnOpts) is true iff Rval is a constant.
% This depends on the options governing nonlocal gotos, asm labels enabled
@@ -204,3 +213,28 @@
rval_is_constant(Exprn0, ExprnOpts).
%---------------------------------------------------------------------------%
+
+set_liveness_and_end_branch(StoreMap, MaybeEnd0, Liveness, BranchEndCode,
+ !CI) :-
+ % We keep track of what variables are supposed to be live at the end
+ % of cases. We have to do this explicitly because generating a `fail' slot
+ % last would yield the wrong liveness.
+ code_info.set_forward_live_vars(Liveness, !CI),
+ code_info.generate_branch_end(StoreMap, MaybeEnd0, _MaybeEnd,
+ BranchEndCode, !CI).
+
+generate_offset_assigns([], _, _, !CI).
+generate_offset_assigns([Var | Vars], Offset, BaseReg, !CI) :-
+ LookupLval = field(yes(0), lval(BaseReg), const(llconst_int(Offset))),
+ code_info.assign_lval_to_var(Var, LookupLval, Code, !CI),
+ expect(tree.is_empty(Code), this_file,
+ "generate_offset_assigns: nonempty code"),
+ generate_offset_assigns(Vars, Offset + 1, BaseReg, !CI).
+
+%---------------------------------------------------------------------------%
+
+:- func this_file = string.
+
+this_file = "lookup_util.m".
+
+%---------------------------------------------------------------------------%
Index: compiler/opt_debug.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/opt_debug.m,v
retrieving revision 1.183
diff -u -b -r1.183 opt_debug.m
--- compiler/opt_debug.m 5 Dec 2006 03:50:56 -0000 1.183
+++ compiler/opt_debug.m 10 Dec 2006 08:26:23 -0000
@@ -40,30 +40,26 @@
:- func dump_intlist(list(int)) = string.
-:- func dump_livemap(livemap) = string.
+:- func dump_livemap(maybe(proc_label), livemap) = string.
-:- func dump_livemap_for_proc(proc_label, livemap) = string.
-
-:- func dump_livemaplist(assoc_list(label, lvalset)) = string.
-
-:- func dump_livemaplist_for_proc(proc_label, assoc_list(label, lvalset))
+:- func dump_livemaplist(maybe(proc_label), assoc_list(label, lvalset))
= string.
-:- func dump_livevals(lvalset) = string.
+:- func dump_livevals(maybe(proc_label), lvalset) = string.
-:- func dump_livelist(list(lval)) = string.
+:- func dump_livelist(maybe(proc_label), list(lval)) = string.
:- func dump_reg(reg_type, int) = string.
-:- func dump_lval(lval) = string.
+:- func dump_lval(maybe(proc_label), lval) = string.
-:- func dump_rval(rval) = string.
+:- func dump_rval(maybe(proc_label), rval) = string.
-:- func dump_rvals(list(rval)) = string.
+:- func dump_rvals(maybe(proc_label), list(rval)) = string.
-:- func dump_mem_ref(mem_ref) = string.
+:- func dump_mem_ref(maybe(proc_label), mem_ref) = string.
-:- func dump_const(rval_const) = string.
+:- func dump_const(maybe(proc_label), rval_const) = string.
:- func dump_data_addr(data_addr) = string.
@@ -85,27 +81,19 @@
:- func dump_binop(binary_op) = string.
-:- func dump_label(label) = string.
-
-:- func dump_label_for_proc(proc_label, label) = string.
+:- func dump_label(maybe(proc_label), label) = string.
-:- func dump_labels(list(label)) = string.
+:- func dump_labels(maybe(proc_label), list(label)) = string.
-:- func dump_labels_for_proc(proc_label, list(label)) = string.
-
-:- func dump_label_pairs(list(pair(label))) = string.
+:- func dump_label_pairs(maybe(proc_label), list(pair(label))) = string.
:- func dump_proclabel(proc_label) = string.
-:- func dump_maybe_rvals(list(maybe(rval)), int) = string.
-
-:- func dump_code_addr(code_addr) = string.
+:- func dump_maybe_rvals(maybe(proc_label), list(maybe(rval)), int) = string.
-:- func dump_code_addr_for_proc(proc_label, code_addr) = string.
+:- func dump_code_addr(maybe(proc_label), code_addr) = string.
-:- func dump_code_addrs(list(code_addr)) = string.
-
-:- func dump_code_addrs_for_proc(proc_label, list(code_addr)) = string.
+:- func dump_code_addrs(maybe(proc_label), list(code_addr)) = string.
:- func dump_bool(bool) = string.
@@ -205,65 +193,58 @@
dump_intlist([H | T]) =
" " ++ int_to_string(H) ++ dump_intlist(T).
-dump_livemap(Livemap) =
- dump_livemaplist(map.to_assoc_list(Livemap)).
-
-dump_livemap_for_proc(ProcLabel, Livemap) =
- dump_livemaplist_for_proc(ProcLabel, map.to_assoc_list(Livemap)).
+dump_livemap(MaybeProcLabel, Livemap) =
+ dump_livemaplist(MaybeProcLabel, map.to_assoc_list(Livemap)).
-dump_livemaplist([]) = "".
-dump_livemaplist([Label - Lvalset | Livemaplist]) =
- dump_label(Label) ++ " ->" ++ dump_livevals(Lvalset) ++ "\n"
- ++ dump_livemaplist(Livemaplist).
-
-dump_livemaplist_for_proc(_ProcLabel, []) = "".
-dump_livemaplist_for_proc(ProcLabel, [Label - Lvalset | Livemaplist]) =
- dump_label_for_proc(ProcLabel, Label) ++ " ->" ++
- dump_livevals(Lvalset) ++ "\n" ++
- dump_livemaplist_for_proc(ProcLabel, Livemaplist).
-
-dump_livevals(Lvalset) =
- dump_livelist(set.to_sorted_list(Lvalset)).
-
-dump_livelist(Lvals) =
- dump_livelist_2(Lvals, "").
-
-:- func dump_livelist_2(list(lval), string) = string.
-
-dump_livelist_2([], _) = "".
-dump_livelist_2([Lval | Lvallist], Prefix) =
- Prefix ++ dump_lval(Lval) ++ dump_livelist_2(Lvallist, " ").
+dump_livemaplist(_, []) = "".
+dump_livemaplist(MaybeProcLabel, [Label - Lvalset | Livemaplist]) =
+ dump_label(MaybeProcLabel, Label) ++ " ->" ++
+ dump_livevals(MaybeProcLabel, Lvalset) ++ "\n" ++
+ dump_livemaplist(MaybeProcLabel, Livemaplist).
+
+dump_livevals(MaybeProcLabel, Lvalset) =
+ dump_livelist(MaybeProcLabel, set.to_sorted_list(Lvalset)).
+
+dump_livelist(MaybeProcLabel, Lvals) =
+ dump_livelist_2(MaybeProcLabel, Lvals, "").
+
+:- func dump_livelist_2(maybe(proc_label), list(lval), string) = string.
+
+dump_livelist_2(_, [], _) = "".
+dump_livelist_2(MaybeProcLabel, [Lval | Lvallist], Prefix) =
+ Prefix ++ dump_lval(MaybeProcLabel, Lval) ++
+ dump_livelist_2(MaybeProcLabel, Lvallist, " ").
dump_reg(reg_r, N) =
"r" ++ int_to_string(N).
dump_reg(reg_f, N) =
"f" ++ int_to_string(N).
-dump_lval(reg(Type, Num)) =
+dump_lval(_, reg(Type, Num)) =
dump_reg(Type, Num).
-dump_lval(stackvar(N)) =
+dump_lval(_, stackvar(N)) =
"sv" ++ int_to_string(N).
-dump_lval(parent_stackvar(N)) =
+dump_lval(_, parent_stackvar(N)) =
"parent_sv" ++ int_to_string(N).
-dump_lval(framevar(N)) =
+dump_lval(_, framevar(N)) =
"fv" ++ int_to_string(N).
-dump_lval(succip) = "succip".
-dump_lval(maxfr) = "maxfr".
-dump_lval(curfr) = "curfr".
-dump_lval(succfr_slot(R)) =
- "succfr_slot(" ++ dump_rval(R) ++ ")".
-dump_lval(prevfr_slot(R)) =
- "prevfr_slot(" ++ dump_rval(R) ++ ")".
-dump_lval(redofr_slot(R)) =
- "redofr_slot(" ++ dump_rval(R) ++ ")".
-dump_lval(redoip_slot(R)) =
- "redoip_slot(" ++ dump_rval(R) ++ ")".
-dump_lval(succip_slot(R)) =
- "succip_slot(" ++ dump_rval(R) ++ ")".
-dump_lval(hp) = "hp".
-dump_lval(sp) = "sp".
-dump_lval(parent_sp) = "parent_sp".
-dump_lval(field(MT, N, F)) = Str :-
+dump_lval(_, succip) = "succip".
+dump_lval(_, maxfr) = "maxfr".
+dump_lval(_, curfr) = "curfr".
+dump_lval(MaybeProcLabel, succfr_slot(R)) =
+ "succfr_slot(" ++ dump_rval(MaybeProcLabel, R) ++ ")".
+dump_lval(MaybeProcLabel, prevfr_slot(R)) =
+ "prevfr_slot(" ++ dump_rval(MaybeProcLabel, R) ++ ")".
+dump_lval(MaybeProcLabel, redofr_slot(R)) =
+ "redofr_slot(" ++ dump_rval(MaybeProcLabel, R) ++ ")".
+dump_lval(MaybeProcLabel, redoip_slot(R)) =
+ "redoip_slot(" ++ dump_rval(MaybeProcLabel, R) ++ ")".
+dump_lval(MaybeProcLabel, succip_slot(R)) =
+ "succip_slot(" ++ dump_rval(MaybeProcLabel, R) ++ ")".
+dump_lval(_, hp) = "hp".
+dump_lval(_, sp) = "sp".
+dump_lval(_, parent_sp) = "parent_sp".
+dump_lval(MaybeProcLabel, field(MT, N, F)) = Str :-
(
MT = yes(T),
string.int_to_string(T, T_str)
@@ -271,72 +252,76 @@
MT = no,
T_str = "no"
),
- Str = "field(" ++ T_str ++ ", " ++ dump_rval(N) ++ ", "
- ++ dump_rval(F) ++ ")".
-dump_lval(lvar(_)) = "lvar(_)".
-dump_lval(temp(Type, Num)) =
+ Str = "field(" ++ T_str ++ ", " ++ dump_rval(MaybeProcLabel, N) ++ ", "
+ ++ dump_rval(MaybeProcLabel, F) ++ ")".
+dump_lval(_, lvar(_)) = "lvar(_)".
+dump_lval(_, temp(Type, Num)) =
"temp_" ++ dump_reg(Type, Num).
-dump_lval(mem_ref(R)) =
- "mem_ref(" ++ dump_rval(R) ++ ")".
-dump_lval(global_var_ref(env_var_ref(VarName))) =
+dump_lval(MaybeProcLabel, mem_ref(R)) =
+ "mem_ref(" ++ dump_rval(MaybeProcLabel, R) ++ ")".
+dump_lval(_, global_var_ref(env_var_ref(VarName))) =
"global_var_ref(env_var_ref(" ++ VarName ++ "))".
-dump_rval(lval(Lval)) =
- dump_lval(Lval).
-dump_rval(var(Var)) =
+dump_rval(MaybeProcLabel, lval(Lval)) =
+ dump_lval(MaybeProcLabel, Lval).
+dump_rval(_, var(Var)) =
"var(" ++ int_to_string(term.var_to_int(Var)) ++ ")".
-dump_rval(mkword(T, N)) =
- "mkword(" ++ int_to_string(T) ++ ", " ++ dump_rval(N) ++ ")".
-dump_rval(const(C)) =
- dump_const(C).
-dump_rval(unop(O, N)) =
- dump_unop(O) ++ "(" ++ dump_rval(N) ++ ")".
-dump_rval(binop(O, N1, N2)) =
+dump_rval(MaybeProcLabel, mkword(T, N)) =
+ "mkword(" ++ int_to_string(T) ++ ", " ++
+ dump_rval(MaybeProcLabel, N) ++ ")".
+dump_rval(MaybeProcLabel, const(C)) =
+ dump_const(MaybeProcLabel, C).
+dump_rval(MaybeProcLabel, unop(O, N)) =
+ dump_unop(O) ++ "(" ++ dump_rval(MaybeProcLabel, N) ++ ")".
+dump_rval(MaybeProcLabel, binop(O, N1, N2)) =
(
( N1 = binop(_, _, _)
; N2 = binop(_, _, _)
)
->
"binop(" ++ dump_binop(O) ++ ", "
- ++ dump_rval(N1) ++ ", " ++ dump_rval(N2) ++ ")"
+ ++ dump_rval(MaybeProcLabel, N1) ++ ", " ++
+ dump_rval(MaybeProcLabel, N2) ++ ")"
;
- dump_rval(N1) ++ " " ++ dump_binop(O) ++ " " ++ dump_rval(N2)
+ dump_rval(MaybeProcLabel, N1) ++ " " ++ dump_binop(O) ++ " " ++
+ dump_rval(MaybeProcLabel, N2)
).
-dump_rval(mem_addr(M)) =
- "mem_addr(" ++ dump_mem_ref(M) ++ ")".
+dump_rval(MaybeProcLabel, mem_addr(M)) =
+ "mem_addr(" ++ dump_mem_ref(MaybeProcLabel, M) ++ ")".
-dump_rvals([]) = "".
-dump_rvals([Rval | Rvals]) =
- dump_rval(Rval) ++ ", " ++ dump_rvals(Rvals).
-
-dump_mem_ref(stackvar_ref(N)) =
- "stackvar_ref(" ++ dump_rval(N) ++ ")".
-dump_mem_ref(framevar_ref(N)) =
- "framevar_ref(" ++ dump_rval(N) ++ ")".
-dump_mem_ref(heap_ref(R, T, N)) =
- "heap_ref(" ++ dump_rval(R) ++ ", " ++ int_to_string(T) ++ ", "
- ++ dump_rval(N) ++ ")".
-
-dump_const(llconst_true) = "true".
-dump_const(llconst_false) = "false".
-dump_const(llconst_int(I)) =
+dump_rvals(_, []) = "".
+dump_rvals(MaybeProcLabel, [Rval | Rvals]) =
+ dump_rval(MaybeProcLabel, Rval) ++ ", " ++
+ dump_rvals(MaybeProcLabel, Rvals).
+
+dump_mem_ref(MaybeProcLabel, stackvar_ref(N)) =
+ "stackvar_ref(" ++ dump_rval(MaybeProcLabel, N) ++ ")".
+dump_mem_ref(MaybeProcLabel, framevar_ref(N)) =
+ "framevar_ref(" ++ dump_rval(MaybeProcLabel, N) ++ ")".
+dump_mem_ref(MaybeProcLabel, heap_ref(R, T, N)) =
+ "heap_ref(" ++ dump_rval(MaybeProcLabel, R) ++ ", " ++ int_to_string(T) ++ ", "
+ ++ dump_rval(MaybeProcLabel, N) ++ ")".
+
+dump_const(_, llconst_true) = "true".
+dump_const(_, llconst_false) = "false".
+dump_const(_, llconst_int(I)) =
int_to_string(I).
-dump_const(llconst_float(F)) =
+dump_const(_, llconst_float(F)) =
float_to_string(F).
-dump_const(llconst_string(S)) =
+dump_const(_, llconst_string(S)) =
"""" ++ S ++ """".
-dump_const(llconst_multi_string(L, _S)) =
+dump_const(_, llconst_multi_string(L, _S)) =
"multi_string(" ++ int_to_string(L) ++ ")".
-dump_const(llconst_code_addr(CodeAddr)) =
- "code_addr_const(" ++ dump_code_addr(CodeAddr) ++ ")".
-dump_const(llconst_data_addr(DataAddr, MaybeOffset)) = Str :-
- DataAddr_str = dump_data_addr(DataAddr),
+dump_const(MaybeProcLabel, llconst_code_addr(CodeAddr)) =
+ "code_addr_const(" ++ dump_code_addr(MaybeProcLabel, CodeAddr) ++ ")".
+dump_const(_, llconst_data_addr(DataAddr, MaybeOffset)) = Str :-
+ DataAddrStr = dump_data_addr(DataAddr),
(
MaybeOffset = no,
- Str = "data_addr_const(" ++ DataAddr_str ++ ")"
+ Str = "data_addr_const(" ++ DataAddrStr ++ ")"
;
MaybeOffset = yes(Offset),
- Str = "data_addr_const(" ++ DataAddr_str ++ ", "
+ Str = "data_addr_const(" ++ DataAddrStr ++ ", "
++ int_to_string(Offset) ++ ")"
).
@@ -447,7 +432,7 @@
Str = "tc_instance(" ++ TypesStr ++ ")".
dump_layout_name(label_layout(ProcLabel, LabelNum, LabelVars)) = Str :-
- LabelStr = dump_label(internal_label(LabelNum, ProcLabel)),
+ LabelStr = dump_label(no, internal_label(LabelNum, ProcLabel)),
(
LabelVars = label_has_var_info,
LabelVarsStr = "label_has_var_info"
@@ -457,13 +442,13 @@
),
Str = "label_layout(" ++ LabelStr ++ ", " ++ LabelVarsStr ++ ")".
dump_layout_name(user_event_layout(ProcLabel, LabelNum)) = Str :-
- LabelStr = dump_label(internal_label(LabelNum, ProcLabel)),
+ LabelStr = dump_label(no, internal_label(LabelNum, ProcLabel)),
Str = "user_event_layout(" ++ LabelStr ++ ")".
dump_layout_name(user_event_attr_names(ProcLabel, LabelNum)) = Str :-
- LabelStr = dump_label(internal_label(LabelNum, ProcLabel)),
+ LabelStr = dump_label(no, internal_label(LabelNum, ProcLabel)),
Str = "user_event_attr_names(" ++ LabelStr ++ ")".
dump_layout_name(user_event_attr_var_nums(ProcLabel, LabelNum)) = Str :-
- LabelStr = dump_label(internal_label(LabelNum, ProcLabel)),
+ LabelStr = dump_label(no, internal_label(LabelNum, ProcLabel)),
Str = "user_event_attr_var_nums(" ++ LabelStr ++ ")".
dump_layout_name(proc_layout(RttiProcLabel, _)) =
"proc_layout(" ++ dump_rttiproclabel(RttiProcLabel) ++ ")".
@@ -520,90 +505,70 @@
dump_binop(Op) =
llds_out.binary_op_to_string(Op).
-dump_maybe_rvals([], _) = "".
-dump_maybe_rvals([MR | MRs], N) = Str :-
+dump_maybe_rvals(_, [], _) = "".
+dump_maybe_rvals(MaybeProcLabel, [MR | MRs], N) = Str :-
( N > 0 ->
(
MR = yes(R),
- MR_str = dump_rval(R)
+ MR_str = dump_rval(MaybeProcLabel, R)
;
MR = no,
MR_str = "no"
),
- Str = MR_str ++ ", " ++ dump_maybe_rvals(MRs, N - 1)
+ Str = MR_str ++ ", " ++ dump_maybe_rvals(MaybeProcLabel, MRs, N - 1)
;
Str = "truncated"
).
-dump_code_addr(code_label(Label)) = dump_label(Label).
-dump_code_addr(code_imported_proc(ProcLabel)) = dump_proclabel(ProcLabel).
-dump_code_addr(code_succip) = "succip".
-dump_code_addr(do_succeed(Last)) = Str :-
- (
- Last = no,
- Str = "do_succeed"
- ;
- Last = yes,
- Str = "do_last_succeed"
- ).
-dump_code_addr(do_redo) = "do_redo".
-dump_code_addr(do_fail) = "do_fail".
-dump_code_addr(do_trace_redo_fail_shallow) =
- "do_trace_redo_fail_shallow".
-dump_code_addr(do_trace_redo_fail_deep) = "do_trace_redo_fail_deep".
-dump_code_addr(do_call_closure(Variant)) =
+dump_code_addr(MaybeProcLabel, code_label(Label)) =
+ dump_label(MaybeProcLabel, Label).
+dump_code_addr(_, code_imported_proc(ProcLabel)) = dump_proclabel(ProcLabel).
+dump_code_addr(_, code_succip) = "succip".
+dump_code_addr(_, do_succeed(no)) = "do_succeed".
+dump_code_addr(_, do_succeed(yes)) = "do_last_succeed".
+dump_code_addr(_, do_redo) = "do_redo".
+dump_code_addr(_, do_fail) = "do_fail".
+dump_code_addr(_, do_trace_redo_fail_shallow) = "do_trace_redo_fail_shallow".
+dump_code_addr(_, do_trace_redo_fail_deep) = "do_trace_redo_fail_deep".
+dump_code_addr(_, do_call_closure(Variant)) =
"do_call_closure_" ++ ho_call_variant_to_string(Variant).
-dump_code_addr(do_call_class_method(Variant)) =
+dump_code_addr(_, do_call_class_method(Variant)) =
"do_call_class_method_" ++ ho_call_variant_to_string(Variant).
-dump_code_addr(do_not_reached) = "do_not_reached".
-
-dump_code_addr_for_proc(ProcLabel, CodeAddr) =
- ( CodeAddr = code_label(Label) ->
- dump_label_for_proc(ProcLabel, Label)
- ;
- dump_code_addr(CodeAddr)
- ).
+dump_code_addr(_, do_not_reached) = "do_not_reached".
-dump_code_addrs([]) = "".
-dump_code_addrs([Addr | Addrs]) =
- " " ++ dump_code_addr(Addr) ++ dump_code_addrs(Addrs).
+dump_code_addrs(_, []) = "".
+dump_code_addrs(MaybeProcLabel, [Addr | Addrs]) =
+ " " ++ dump_code_addr(MaybeProcLabel, Addr) ++
+ dump_code_addrs(MaybeProcLabel, Addrs).
-dump_code_addrs_for_proc(_, []) = "".
-dump_code_addrs_for_proc(ProcLabel, [Addr | Addrs]) =
- " " ++ dump_code_addr_for_proc(ProcLabel, Addr) ++
- dump_code_addrs_for_proc(ProcLabel, Addrs).
-
-dump_label(internal_label(N, ProcLabel)) =
+dump_label(no, internal_label(N, ProcLabel)) =
dump_proclabel(ProcLabel) ++ "_i" ++ int_to_string(N).
-dump_label(entry_label(_, ProcLabel)) =
+dump_label(no, entry_label(_, ProcLabel)) =
dump_proclabel(ProcLabel).
-
-dump_label_for_proc(CurProcLabel, internal_label(N, ProcLabel)) = Str :-
+dump_label(yes(CurProcLabel), internal_label(N, ProcLabel)) = Str :-
string.int_to_string(N, N_str),
( CurProcLabel = ProcLabel ->
Str = "local_" ++ N_str
;
Str = dump_proclabel(ProcLabel) ++ "_" ++ N_str
).
-dump_label_for_proc(CurProcLabel, entry_label(_, ProcLabel)) = Str :-
+dump_label(yes(CurProcLabel), entry_label(_, ProcLabel)) = Str :-
( CurProcLabel = ProcLabel ->
Str = "CUR_PROC_ENTRY"
;
Str = dump_proclabel(ProcLabel)
).
-dump_labels([]) = "".
-dump_labels([Label | Labels]) =
- " " ++ dump_label(Label) ++ dump_labels(Labels).
-
-dump_labels_for_proc(_, []) = "".
-dump_labels_for_proc(ProcLabel, [Label | Labels]) =
- " " ++ dump_label_for_proc(ProcLabel, Label) ++
- dump_labels_for_proc(ProcLabel, Labels).
-
-dump_label_pairs([]) = "".
-dump_label_pairs([L1 - L2 | Labels]) =
- " " ++ dump_label(L1) ++ "-" ++ dump_label(L2) ++ dump_label_pairs(Labels).
+dump_labels(_, []) = "".
+dump_labels(MaybeProcLabel, [Label | Labels]) =
+ " " ++ dump_label(MaybeProcLabel, Label) ++
+ dump_labels(MaybeProcLabel, Labels).
+
+dump_label_pairs(_, []) = "".
+dump_label_pairs(MaybeProcLabel, [L1 - L2 | Labels]) =
+ " " ++ dump_label(MaybeProcLabel, L1) ++ "-" ++
+ dump_label(MaybeProcLabel, L2) ++
+ dump_label_pairs(MaybeProcLabel, Labels).
:- func dump_rttiproclabel(rtti_proc_label) = string.
@@ -649,7 +614,7 @@
Str = "comment(" ++ Comment ++ ")"
;
Instr = livevals(Livevals),
- Str = "livevals(" ++ dump_livevals(Livevals) ++ ")"
+ Str = "livevals(" ++ dump_livevals(yes(ProcLabel), Livevals) ++ ")"
;
Instr = block(RTemps, FTemps, Instrs),
Str = "block(" ++ int_to_string(RTemps) ++ ", "
@@ -658,7 +623,8 @@
++ ")"
;
Instr = assign(Lval, Rval),
- Str = dump_lval(Lval) ++ " := " ++ dump_rval(Rval)
+ Str = dump_lval(yes(ProcLabel), Lval) ++ " := " ++
+ dump_rval(yes(ProcLabel), Rval)
;
Instr = llcall(Callee, ReturnLabel, _LiveInfo, _Context, _GoalPath,
CallModel),
@@ -678,14 +644,14 @@
CallModel = call_model_nondet(unchecked_tail_call),
CallModelStr = "nondet unchecked_tail_call"
),
- Str = "call(" ++ dump_code_addr_for_proc(ProcLabel, Callee) ++ ", "
- ++ dump_code_addr_for_proc(ProcLabel, ReturnLabel) ++ ", ..., "
+ Str = "call(" ++ dump_code_addr(yes(ProcLabel), Callee) ++ ", "
+ ++ dump_code_addr(yes(ProcLabel), ReturnLabel) ++ ", ..., "
++ CallModelStr ++ ")"
;
Instr = mkframe(FrameInfo, MaybeRedoip),
(
MaybeRedoip = yes(Redoip),
- R_str = dump_code_addr_for_proc(ProcLabel, Redoip)
+ R_str = dump_code_addr(yes(ProcLabel), Redoip)
;
MaybeRedoip = no,
R_str = "no_redoip"
@@ -713,27 +679,27 @@
)
;
Instr = label(Label),
- Str = dump_label_for_proc(ProcLabel, Label) ++ ":"
+ Str = dump_label(yes(ProcLabel), Label) ++ ":"
;
Instr = goto(CodeAddr),
- Str = "goto " ++ dump_code_addr_for_proc(ProcLabel, CodeAddr)
+ Str = "goto " ++ dump_code_addr(yes(ProcLabel), CodeAddr)
;
Instr = computed_goto(Rval, Labels),
- Str = "computed_goto " ++ dump_rval(Rval) ++ ":"
- ++ dump_labels_for_proc(ProcLabel, Labels)
+ Str = "computed_goto " ++ dump_rval(yes(ProcLabel), Rval) ++ ":"
+ ++ dump_labels(yes(ProcLabel), Labels)
;
Instr = arbitrary_c_code(Code, _),
Str = "arbitrary_c_code(" ++ Code ++ ")"
;
Instr = if_val(Rval, CodeAddr),
- Str = "if (" ++ dump_rval(Rval) ++ ") goto "
- ++ dump_code_addr_for_proc(ProcLabel, CodeAddr)
+ Str = "if (" ++ dump_rval(yes(ProcLabel), Rval) ++ ") goto "
+ ++ dump_code_addr(yes(ProcLabel), CodeAddr)
;
Instr = save_maxfr(Lval),
- Str = "save_maxfr(" ++ dump_lval(Lval) ++ ")"
+ Str = "save_maxfr(" ++ dump_lval(yes(ProcLabel), Lval) ++ ")"
;
Instr = restore_maxfr(Lval),
- Str = "restore_maxfr(" ++ dump_lval(Lval) ++ ")"
+ Str = "restore_maxfr(" ++ dump_lval(yes(ProcLabel), Lval) ++ ")"
;
Instr = incr_hp(Lval, MaybeTag, MaybeOffset, Size, _, MayUseAtomic),
(
@@ -750,24 +716,25 @@
MaybeOffset = yes(Offset),
string.int_to_string(Offset, O_str)
),
- Str = "incr_hp(" ++ dump_lval(Lval) ++ ", " ++ T_str ++ ", " ++ O_str
- ++ ", " ++ dump_rval(Size) ++
- ", " ++ dump_may_use_atomic(MayUseAtomic) ++ ")"
+ Str = "incr_hp(" ++ dump_lval(yes(ProcLabel), Lval) ++ ", " ++
+ T_str ++ ", " ++ O_str ++ ", " ++
+ dump_rval(yes(ProcLabel), Size) ++ ", " ++
+ dump_may_use_atomic(MayUseAtomic) ++ ")"
;
Instr = mark_hp(Lval),
- Str = "mark_hp(" ++ dump_lval(Lval) ++ ")"
+ Str = "mark_hp(" ++ dump_lval(yes(ProcLabel), Lval) ++ ")"
;
Instr = restore_hp(Rval),
- Str = "restore_hp(" ++ dump_rval(Rval) ++ ")"
+ Str = "restore_hp(" ++ dump_rval(yes(ProcLabel), Rval) ++ ")"
;
Instr = free_heap(Rval),
- Str = "free_heap(" ++ dump_rval(Rval) ++ ")"
+ Str = "free_heap(" ++ dump_rval(yes(ProcLabel), Rval) ++ ")"
;
Instr = store_ticket(Lval),
- Str = "store_ticket(" ++ dump_lval(Lval) ++ ")"
+ Str = "store_ticket(" ++ dump_lval(yes(ProcLabel), Lval) ++ ")"
;
Instr = reset_ticket(Rval, _Reason),
- Str = "reset_ticket(" ++ dump_rval(Rval) ++ ", _)"
+ Str = "reset_ticket(" ++ dump_rval(yes(ProcLabel), Rval) ++ ", _)"
;
Instr = discard_ticket,
Str = "discard_ticket"
@@ -776,10 +743,10 @@
Str = "prune_ticket"
;
Instr = mark_ticket_stack(Lval),
- Str = "mark_ticket_stack(" ++ dump_lval(Lval) ++ ")"
+ Str = "mark_ticket_stack(" ++ dump_lval(yes(ProcLabel), Lval) ++ ")"
;
Instr = prune_tickets_to(Rval),
- Str = "prune_tickets_to(" ++ dump_rval(Rval) ++ ")"
+ Str = "prune_tickets_to(" ++ dump_rval(yes(ProcLabel), Rval) ++ ")"
;
Instr = incr_sp(Size, _, Kind),
Str = "incr_sp(" ++ int_to_string(Size) ++ ", " ++
@@ -792,25 +759,26 @@
Str = "decr_sp_and_return(" ++ int_to_string(Size) ++ ")"
;
Instr = init_sync_term(Lval, N),
- Str = "init_sync_term(" ++ dump_lval(Lval) ++ ", "
+ Str = "init_sync_term(" ++ dump_lval(yes(ProcLabel), Lval) ++ ", "
++ int_to_string(N) ++ ")"
;
Instr = fork(Child),
- Str = "fork(" ++ dump_label_for_proc(ProcLabel, Child) ++ ")"
+ Str = "fork(" ++ dump_label(yes(ProcLabel), Child) ++ ")"
;
Instr = join_and_continue(Lval, Label),
- Str = "join(" ++ dump_lval(Lval) ++ ", "
- ++ dump_label_for_proc(ProcLabel, Label) ++ ")"
+ Str = "join(" ++ dump_lval(yes(ProcLabel), Lval) ++ ", "
+ ++ dump_label(yes(ProcLabel), Label) ++ ")"
;
Instr = pragma_c(Decls, Comps, MCM, MFNL, MFL, MFOL, MNF, SSR, MD),
+ MaybeProcLabel = yes(ProcLabel),
Str = "pragma_c(\n"
++ "declarations:\n" ++ dump_decls(Decls)
- ++ "components:\n" ++ dump_components(ProcLabel, Comps)
+ ++ "components:\n" ++ dump_components(MaybeProcLabel, Comps)
++ dump_may_call_mercury(MCM) ++ "\n"
- ++ dump_maybe_label_for_proc("fix nolayout:", ProcLabel, MFNL)
- ++ dump_maybe_label_for_proc("fix layout:", ProcLabel, MFL)
- ++ dump_maybe_label_for_proc("fix onlylayout:", ProcLabel, MFOL)
- ++ dump_maybe_label_for_proc("nofix:", ProcLabel, MNF)
+ ++ dump_maybe_label("fix nolayout:", MaybeProcLabel, MFNL)
+ ++ dump_maybe_label("fix layout:", MaybeProcLabel, MFL)
+ ++ dump_maybe_label("fix onlylayout:", MaybeProcLabel, MFOL)
+ ++ dump_maybe_label("nofix:", MaybeProcLabel, MNF)
++ dump_bool_msg("stack slot ref:", SSR)
++ dump_bool_msg("may duplicate:", MD)
++ ")"
@@ -821,11 +789,11 @@
dump_may_call_mercury(proc_may_call_mercury) = "may_call_mercury".
dump_may_call_mercury(proc_will_not_call_mercury) = "will_not_call_mercury".
-:- func dump_maybe_label_for_proc(string, proc_label, maybe(label)) = string.
+:- func dump_maybe_label(string, maybe(proc_label), maybe(label)) = string.
-dump_maybe_label_for_proc(_Msg, _ProcLabel, no) = "".
-dump_maybe_label_for_proc(Msg, ProcLabel, yes(Label)) =
- Msg ++ " " ++ dump_label_for_proc(ProcLabel, Label) ++ "\n".
+dump_maybe_label(_Msg, _MaybeProcLabel, no) = "".
+dump_maybe_label(Msg, MaybeProcLabel, yes(Label)) =
+ Msg ++ " " ++ dump_label(MaybeProcLabel, Label) ++ "\n".
:- func dump_bool_msg(string, bool) = string.
@@ -850,45 +818,54 @@
dump_decl(pragma_c_struct_ptr_decl(StructTag, VarName)) =
"decl struct" ++ StructTag ++ " " ++ VarName ++ "\n".
-:- func dump_components(proc_label, list(pragma_c_component)) = string.
+:- func dump_components(maybe(proc_label), list(pragma_c_component)) = string.
dump_components(_, []) = "".
-dump_components(ProcLabel, [Comp | Comps]) =
- dump_component(ProcLabel, Comp) ++ dump_components(ProcLabel, Comps).
-
-:- func dump_component(proc_label, pragma_c_component) = string.
-
-dump_component(_, pragma_c_inputs(Inputs)) = dump_input_components(Inputs).
-dump_component(_, pragma_c_outputs(Outputs)) = dump_output_components(Outputs).
+dump_components(MaybeProcLabel, [Comp | Comps]) =
+ dump_component(MaybeProcLabel, Comp) ++
+ dump_components(MaybeProcLabel, Comps).
+
+:- func dump_component(maybe(proc_label), pragma_c_component) = string.
+
+dump_component(MaybeProcLabel, pragma_c_inputs(Inputs)) =
+ dump_input_components(MaybeProcLabel, Inputs).
+dump_component(MaybeProcLabel, pragma_c_outputs(Outputs)) =
+ dump_output_components(MaybeProcLabel, Outputs).
dump_component(_, pragma_c_user_code(_, Code)) = Code ++ "\n".
dump_component(_, pragma_c_raw_code(Code, _, _)) = Code ++ "\n".
-dump_component(ProcLabel, pragma_c_fail_to(Label)) =
- "fail to " ++ dump_label_for_proc(ProcLabel, Label) ++ "\n".
+dump_component(MaybeProcLabel, pragma_c_fail_to(Label)) =
+ "fail to " ++ dump_label(MaybeProcLabel, Label) ++ "\n".
dump_component(_, pragma_c_noop) = "".
-:- func dump_input_components(list(pragma_c_input)) = string.
-
-dump_input_components([]) = "".
-dump_input_components([Input | Inputs]) =
- dump_input_component(Input) ++ "\n" ++
- dump_input_components(Inputs).
-
-:- func dump_output_components(list(pragma_c_output)) = string.
-
-dump_output_components([]) = "".
-dump_output_components([Input | Inputs]) =
- dump_output_component(Input) ++ "\n" ++
- dump_output_components(Inputs).
-
-:- func dump_input_component(pragma_c_input) = string.
+:- func dump_input_components(maybe(proc_label), list(pragma_c_input))
+ = string.
-dump_input_component(pragma_c_input(Var, _, Dummy, _, Rval, _, _)) =
- Var ++ dump_maybe_dummy(Dummy) ++ " := " ++ dump_rval(Rval).
+dump_input_components(_, []) = "".
+dump_input_components(MaybeProcLabel, [Input | Inputs]) =
+ dump_input_component(MaybeProcLabel, Input) ++ "\n" ++
+ dump_input_components(MaybeProcLabel, Inputs).
-:- func dump_output_component(pragma_c_output) = string.
+:- func dump_output_components(maybe(proc_label), list(pragma_c_output))
+ = string.
-dump_output_component(pragma_c_output(Lval, _, Dummy, _, Var, _, _)) =
- dump_lval(Lval) ++ " := " ++ Var ++ dump_maybe_dummy(Dummy).
+dump_output_components(_, []) = "".
+dump_output_components(MaybeProcLabel, [Input | Inputs]) =
+ dump_output_component(MaybeProcLabel, Input) ++ "\n" ++
+ dump_output_components(MaybeProcLabel, Inputs).
+
+:- func dump_input_component(maybe(proc_label), pragma_c_input) = string.
+
+dump_input_component(MaybeProcLabel,
+ pragma_c_input(Var, _, Dummy, _, Rval, _, _)) =
+ Var ++ dump_maybe_dummy(Dummy) ++ " := " ++
+ dump_rval(MaybeProcLabel, Rval).
+
+:- func dump_output_component(maybe(proc_label), pragma_c_output) = string.
+
+dump_output_component(MaybeProcLabel,
+ pragma_c_output(Lval, _, Dummy, _, Var, _, _)) =
+ dump_lval(MaybeProcLabel, Lval) ++ " := " ++ Var ++
+ dump_maybe_dummy(Dummy).
:- func dump_maybe_dummy(bool) = string.
Index: compiler/switch_gen.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/switch_gen.m,v
retrieving revision 1.101
diff -u -b -r1.101 switch_gen.m
--- compiler/switch_gen.m 1 Dec 2006 15:04:22 -0000 1.101
+++ compiler/switch_gen.m 10 Dec 2006 02:50:41 -0000
@@ -17,13 +17,12 @@
%
% Currently the following forms of indexing are used:
%
-% For switches on atomic data types (int, char, enums),
-% if the cases are not sparse, we use the value of the switch variable
-% to index into a jump table.
+% For switches on atomic data types (int, char, enums), if the cases are not
+% sparse, we use the value of the switch variable to index into a jump table.
%
% If all the alternative goals for a switch on an atomic data type
% contain only construction unifications of constants, then we generate
-% a dense lookup table (an array) for each output variable of the switch,
+% a dense lookup table (an array) for the output variables of the switch,
% rather than a dense jump table, so that executing the switch becomes
% a matter of doing an array index for each output variable - avoiding
% the branch overhead of the jump-table.
@@ -35,7 +34,7 @@
% in the form of a try-me-else chain, a try chain, a dense jump table
% or a binary search.
%
-% For switches on strings, we lookup the address to jump to in a hash table,
+% For switches on strings, we look up the address to jump to in a hash table,
% using open addressing to resolve hash collisions.
%
% For all other cases (or if the --smart-indexing option was disabled),
Index: compiler/use_local_vars.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/use_local_vars.m,v
retrieving revision 1.28
diff -u -b -r1.28 use_local_vars.m
--- compiler/use_local_vars.m 1 Nov 2006 02:31:10 -0000 1.28
+++ compiler/use_local_vars.m 10 Dec 2006 08:26:23 -0000
@@ -116,7 +116,8 @@
flatten_basic_blocks(EBBLabelSeq, EBBBlockMap, Instrs1),
(
AutoComments = yes,
- NewComment = comment("\n" ++ dump_livemap(LiveMap)) - "",
+ NewComment = comment("\n" ++
+ dump_livemap(yes(ProcLabel), LiveMap)) - "",
Comments = Comments0 ++ [NewComment]
;
AutoComments = no,
cvs diff: Diffing compiler/notes
cvs diff: Diffing debian
cvs diff: Diffing debian/patches
cvs diff: Diffing deep_profiler
cvs diff: Diffing deep_profiler/notes
cvs diff: Diffing doc
cvs diff: Diffing extras
cvs diff: Diffing extras/base64
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/concurrency
cvs diff: Diffing extras/curs
cvs diff: Diffing extras/curs/samples
cvs diff: Diffing extras/curses
cvs diff: Diffing extras/curses/sample
cvs diff: Diffing extras/dynamic_linking
cvs diff: Diffing extras/error
cvs diff: Diffing extras/fixed
cvs diff: Diffing extras/gator
cvs diff: Diffing extras/gator/generations
cvs diff: Diffing extras/gator/generations/1
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/easyx
cvs diff: Diffing extras/graphics/easyx/samples
cvs diff: Diffing extras/graphics/mercury_glut
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/gears
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/lex
cvs diff: Diffing extras/lex/samples
cvs diff: Diffing extras/lex/tests
cvs diff: Diffing extras/log4m
cvs diff: Diffing extras/logged_output
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/moose/tests
cvs diff: Diffing extras/mopenssl
cvs diff: Diffing extras/morphine
cvs diff: Diffing extras/morphine/non-regression-tests
cvs diff: Diffing extras/morphine/scripts
cvs diff: Diffing extras/morphine/source
cvs diff: Diffing extras/net
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/posix
cvs diff: Diffing extras/quickcheck
cvs diff: Diffing extras/quickcheck/tutes
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/solver_types
cvs diff: Diffing extras/solver_types/library
cvs diff: Diffing extras/stream
cvs diff: Diffing extras/stream/tests
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing extras/windows_installer_generator
cvs diff: Diffing extras/windows_installer_generator/sample
cvs diff: Diffing extras/windows_installer_generator/sample/images
cvs diff: Diffing extras/xml
cvs diff: Diffing extras/xml/samples
cvs diff: Diffing extras/xml_stylesheets
cvs diff: Diffing java
cvs diff: Diffing java/runtime
cvs diff: Diffing library
cvs diff: Diffing mdbcomp
cvs diff: Diffing profiler
cvs diff: Diffing robdd
cvs diff: Diffing runtime
cvs diff: Diffing runtime/GETOPT
cvs diff: Diffing runtime/machdeps
cvs diff: Diffing samples
cvs diff: Diffing samples/c_interface
cvs diff: Diffing samples/c_interface/c_calls_mercury
cvs diff: Diffing samples/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/c_interface/mercury_calls_c
cvs diff: Diffing samples/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing samples/tests
cvs diff: Diffing samples/tests/c_interface
cvs diff: Diffing samples/tests/c_interface/c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/cplusplus_calls_mercury
cvs diff: Diffing samples/tests/c_interface/mercury_calls_c
cvs diff: Diffing samples/tests/c_interface/mercury_calls_cplusplus
cvs diff: Diffing samples/tests/c_interface/mercury_calls_fortran
cvs diff: Diffing samples/tests/c_interface/simpler_c_calls_mercury
cvs diff: Diffing samples/tests/c_interface/simpler_cplusplus_calls_mercury
cvs diff: Diffing samples/tests/diff
cvs diff: Diffing samples/tests/muz
cvs diff: Diffing samples/tests/rot13
cvs diff: Diffing samples/tests/solutions
cvs diff: Diffing samples/tests/toplevel
cvs diff: Diffing scripts
cvs diff: Diffing slice
cvs diff: Diffing tests
cvs diff: Diffing tests/benchmarks
cvs diff: Diffing tests/debugger
cvs diff: Diffing tests/debugger/declarative
cvs diff: Diffing tests/dppd
cvs diff: Diffing tests/general
cvs diff: Diffing tests/general/accumulator
cvs diff: Diffing tests/general/string_format
cvs diff: Diffing tests/general/structure_reuse
cvs diff: Diffing tests/grade_subdirs
cvs diff: Diffing tests/hard_coded
Index: tests/hard_coded/Mmakefile
===================================================================
RCS file: /home/mercury/mercury1/repository/tests/hard_coded/Mmakefile,v
retrieving revision 1.303
diff -u -b -r1.303 Mmakefile
--- tests/hard_coded/Mmakefile 17 Nov 2006 05:57:08 -0000 1.303
+++ tests/hard_coded/Mmakefile 10 Dec 2006 09:55:38 -0000
@@ -316,12 +316,14 @@
# The foreign_type_assertion test is currently meaningful only in C grades.
# Mutables work properly only in C grades.
# Trace goal with runtime conditions work properly only in C grades.
+# The lookup_disj test case uses C foreign_proc code to print progress reports.
ifeq "$(filter il% java%,$(GRADE))" ""
C_ONLY_PROGS= \
factt \
factt_sort_test \
float_gv \
foreign_type_assertion \
+ lookup_disj \
trace_goal_env_1 \
trace_goal_env_2
else
Index: tests/hard_coded/lookup_disj.exp
===================================================================
RCS file: tests/hard_coded/lookup_disj.exp
diff -N tests/hard_coded/lookup_disj.exp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/hard_coded/lookup_disj.exp 10 Dec 2006 11:22:42 -0000
@@ -0,0 +1,10 @@
+peek 1
+peek 2
+peek 3
+peek 4
+peek 5
+solution 1.10 - one, 11, a
+solution 2.20 - two, 12, b
+solution 3.30 - three, 13, c
+solution 4.40 - four, 14, f(a)
+solution 5.50 - five, 15, g(a)
Index: tests/hard_coded/lookup_disj.m
===================================================================
RCS file: tests/hard_coded/lookup_disj.m
diff -N tests/hard_coded/lookup_disj.m
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/hard_coded/lookup_disj.m 10 Dec 2006 05:30:57 -0000
@@ -0,0 +1,67 @@
+% vim: ts=4 sw=4 et ft=mercury
+
+:- module lookup_disj.
+
+:- interface.
+
+:- import_module io.
+
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+
+:- import_module list.
+:- import_module solutions.
+:- import_module pair.
+:- import_module string.
+
+main(!IO) :-
+ solutions(p, Solns),
+ list.foldl(write_solution, Solns, !IO).
+
+:- type t
+ ---> a
+ ; b
+ ; c
+ ; f(t)
+ ; g(t).
+
+:- type soln
+ ---> soln(
+ pair(float, string),
+ int,
+ t
+ ).
+
+:- pred p(soln::out) is multi.
+
+p(Soln) :-
+ q(Pair, Int0, T),
+ peek_at_solution(Int0, Int),
+ Soln = soln(Pair, Int, T).
+
+:- pred q(pair(float, string)::out, int::out, t::out) is multi.
+
+q(1.1 - "one", 1, a).
+q(2.2 - "two", 2, b).
+q(3.3 - "three", 3, c).
+q(4.4 - "four", 4, f(a)).
+q(5.5 - "five", 5, g(a)).
+
+:- pred peek_at_solution(int::in, int::out) is det.
+
+:- pragma foreign_proc("C",
+ peek_at_solution(Int0::in, Int::out),
+ [will_not_call_mercury, promise_pure, thread_safe],
+"
+ printf(""peek %ld\\n"", (long) Int0);
+ Int = Int0 + 10;
+").
+
+:- pred write_solution(soln::in, io::di, io::uo) is det.
+
+write_solution(Soln, !IO) :-
+ Soln = soln(Float - Str, Int, T),
+ io.format("solution %.2f - %5s, %d, ", [f(Float), s(Str), i(Int)], !IO),
+ io.write(T, !IO),
+ io.nl(!IO).
cvs diff: Diffing tests/hard_coded/exceptions
cvs diff: Diffing tests/hard_coded/purity
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/invalid/purity
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/mmc_make
cvs diff: Diffing tests/mmc_make/lib
cvs diff: Diffing tests/par_conj
cvs diff: Diffing tests/recompilation
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/trailing
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
cvs diff: Diffing util
cvs diff: Diffing vim
cvs diff: Diffing vim/after
cvs diff: Diffing vim/ftplugin
cvs diff: Diffing vim/syntax
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to: mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions: mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------
More information about the reviews
mailing list