[m-dev.] for review: --optimize-mostly-det-tailcalls
Zoltan Somogyi
zs at cs.mu.OZ.AU
Sun Jun 6 13:14:41 AEST 1999
This is for review by Tom. I would also like to ask Warwick to check
what speedup (if any) the new option provides for hanoidiff_ite in HAL,
which is what it was designed for. (You should resolve the conflict in
code_info.m between this change and the patch I gave you earlier by setting
both bools to "no" if ResumeKnown is resume_is_known(wont_be_set),
and treating resume_is_known(has_been_set) is resume_known is treated here.)
Estimated hours taken: 3
Add a new option, --optimize-mostly-det-tailcalls, that enables the use of
Prolog style nondet tail calls (which check whether the current frame is
on top of the nondet stack and only do a tail call if it is).
This option is not likely to help Mercury code, since most of the time
the test will fail, which means we incurred its cost and did not gain
the benefit of the tailcall. However, HAL often has predicates that are
declared nondet but are det or semidet most of the time, and these can
benefit.
compiler/options.m:
doc/user_guide.texi:
Add the new option, which is not on by default and is not turned on
at any optimization level; you have to give it explicitly.
compiler/llds.m:
Modify the call_model type to distinguish the new style nondet tail
call from the old (which does not do a runtime test).
compiler/code_info.m:
Check the fail state whether it is suitable for new style nondet
tail calls.
compiler/call_gen.m:
Put the result from code_info.m into the generated LLDS.
compiler/jumpopt.m:
Use the new flag in the LLDS to perform the optimization, if the
option is given.
Document the main predicate and its new argument.
compiler/optimize.m:
Pass the value of the new option to jumpopt.
Zoltan.
cvs diff: Diffing .
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/include
cvs diff: Diffing boehm_gc/include/private
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
Index: compiler/call_gen.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/call_gen.m,v
retrieving revision 1.131
diff -u -b -r1.131 call_gen.m
--- call_gen.m 1999/06/01 09:43:35 1.131
+++ call_gen.m 1999/06/06 02:46:29
@@ -377,8 +377,9 @@
{ FlushCode = empty }
;
{ CodeModel = model_non },
- code_info__may_use_nondet_tailcall(TailCall),
- { CallModel = nondet(TailCall) },
+ code_info__may_use_nondet_tailcall(NoCheckTailCall,
+ CheckTailCall),
+ { CallModel = nondet(NoCheckTailCall, CheckTailCall) },
code_info__flush_resume_vars_to_stack(FlushCode),
code_info__set_resume_point_and_frame_to_unknown
).
Index: compiler/code_info.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/code_info.m,v
retrieving revision 1.239
diff -u -b -r1.239 code_info.m
--- code_info.m 1999/04/30 08:23:44 1.239
+++ code_info.m 1999/06/06 02:53:08
@@ -1191,9 +1191,11 @@
% Checks whether the current failure environment would allow
% a model_non call at this point to be turned into a tail call,
% provided of course that the return from the call is followed
- % immediately by succeed().
+ % immediately by succeed(). The two bools are designed to be
+ % plugged into the args of a nondet call_model; for their meaning,
+ % see the documentation of call_model in llds.m.
-:- pred code_info__may_use_nondet_tailcall(bool::out,
+:- pred code_info__may_use_nondet_tailcall(bool::out, bool::out,
code_info::in, code_info::out) is det.
% Materialize the given variables into registers or stack slots.
@@ -2102,18 +2104,27 @@
{ stack__top(ResumePoints, TopResumePoint) },
code_info__pick_matching_resume_addr(TopResumePoint, CodeAddr).
-code_info__may_use_nondet_tailcall(MayTailCall) -->
+code_info__may_use_nondet_tailcall(NoCheckTailCall, CheckTailCall) -->
code_info__get_fail_info(FailInfo),
- { FailInfo = fail_info(ResumePoints, ResumeKnown, _, _, _) },
- (
- { ResumeKnown = resume_point_known },
- { stack__top_det(ResumePoints, TopResumePoint) },
- { TopResumePoint = stack_only(_, do_fail) }
+ { FailInfo = fail_info(ResumePoints0, ResumeKnown, _, _, _) },
+ {
+ stack__pop(ResumePoints0, ResumePoint1, ResumePoints1),
+ stack__is_empty(ResumePoints1),
+ ResumePoint1 = stack_only(_, do_fail)
->
- { MayTailCall = yes }
+ (
+ ResumeKnown = resume_point_known,
+ NoCheckTailCall = yes,
+ CheckTailCall = no
+ ;
+ ResumeKnown = resume_point_unknown,
+ NoCheckTailCall = no,
+ CheckTailCall = yes
+ )
;
- { MayTailCall = no }
- ).
+ NoCheckTailCall = no,
+ CheckTailCall = no
+ }.
%---------------------------------------------------------------------------%
Index: compiler/jumpopt.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/jumpopt.m,v
retrieving revision 1.46
diff -u -b -r1.46 jumpopt.m
--- jumpopt.m 1999/05/28 05:26:18 1.46
+++ jumpopt.m 1999/06/06 04:00:01
@@ -17,15 +17,32 @@
:- import_module llds.
:- import_module list, bool.
-:- pred jumpopt_main(list(instruction), bool, bool, list(instruction), bool).
-:- mode jumpopt_main(in, in, in, out, out) is det.
+ % Take an instruction list and optimize jumps. This includes jumps
+ % implicit in procedure returns.
+ %
+ % The three bool inputs should be
+ %
+ % - the value of the --optimize-fulljumps option,
+ %
+ % - an indication of whether this is the final application of this
+ % optimization, and
+ %
+ % - the value of the --optimize-mostly-det-tailcalls option
+ % respectively.
+ %
+ % The bool output says whether the instruction sequence was modified
+ % by the optimization.
+
+:- pred jumpopt_main(list(instruction), bool, bool, bool,
+ list(instruction), bool).
+:- mode jumpopt_main(in, in, in, in, out, out) is det.
%-----------------------------------------------------------------------------%
:- implementation.
:- import_module code_util, opt_util.
-:- import_module std_util, map, string, require.
+:- import_module int, std_util, map, string, require.
% We first build up a bunch of tables giving information about labels.
% We then traverse the instruction list, using the information in the
@@ -53,7 +70,7 @@
% numbering, which can do a better job of optimizing this block, have
% been applied.
-jumpopt_main(Instrs0, Blockopt, Recjump, Instrs, Mod) :-
+jumpopt_main(Instrs0, Blockopt, Recjump, MostlyDetTailCall, Instrs, Mod) :-
map__init(Instrmap0),
map__init(Lvalmap0),
map__init(Procmap0),
@@ -65,8 +82,16 @@
Procmap0, Procmap, Sdprocmap0, Sdprocmap, Succmap0, Succmap),
map__init(Forkmap0),
jumpopt__build_forkmap(Instrs0, Sdprocmap, Forkmap0, Forkmap),
+ ( MostlyDetTailCall = yes ->
+ opt_util__get_prologue(Instrs0, ProcLabel, _, _, _),
+ opt_util__new_label_no(Instrs0, 500, LabelNum),
+ MostlyDetTailCallInfo = yes(ProcLabel - LabelNum)
+ ;
+ MostlyDetTailCallInfo = no
+ ),
jumpopt__instr_list(Instrs0, comment(""), Instrmap, Blockmap, Lvalmap,
- Procmap, Sdprocmap, Forkmap, Succmap, Instrs1),
+ Procmap, Sdprocmap, Forkmap, Succmap, MostlyDetTailCallInfo,
+ _, Instrs1),
opt_util__filter_out_bad_livevals(Instrs1, Instrs),
( Instrs = Instrs0 ->
Mod = no
@@ -184,14 +209,18 @@
% between the if-val and the goto.
:- pred jumpopt__instr_list(list(instruction), instr, instrmap, tailmap,
- lvalmap, tailmap, tailmap, tailmap, tailmap, list(instruction)).
-:- mode jumpopt__instr_list(in, in, in, in, in, in, in, in, in, out)
+ lvalmap, tailmap, tailmap, tailmap, tailmap,
+ maybe(pair(proc_label, int)), maybe(pair(proc_label, int)),
+ list(instruction)).
+:- mode jumpopt__instr_list(in, in, in, in, in, in, in, in, in, in, out, out)
is det.
jumpopt__instr_list([], _PrevInstr, _Instrmap, _Blockmap,
- _Lvalmap, _Procmap, _Sdprocmap, _Forkmap, _Succmap, []).
+ _Lvalmap, _Procmap, _Sdprocmap, _Forkmap, _Succmap,
+ MostlyDetTailCallInfo, MostlyDetTailCallInfo, []).
jumpopt__instr_list([Instr0 | Instrs0], PrevInstr, Instrmap, Blockmap,
- Lvalmap, Procmap, Sdprocmap, Forkmap, Succmap, Instrs) :-
+ Lvalmap, Procmap, Sdprocmap, Forkmap, Succmap,
+ MostlyDetTailCallInfo0, MostlyDetTailCallInfo, Instrs) :-
Instr0 = Uinstr0 - Comment0,
string__append(Comment0, " (redirected return)", Redirect),
(
@@ -209,7 +238,8 @@
opt_util__filter_out_livevals(Between0, Between1),
list__append(Between1, [livevals(Livevals) - "",
goto(Proc) - Redirect], NewInstrs),
- RemainInstrs = Instrs0
+ RemainInstrs = Instrs0,
+ MostlyDetTailCallInfo1 = MostlyDetTailCallInfo0
;
% Look for semidet style tailcalls.
CallModel = semidet,
@@ -218,10 +248,12 @@
->
list__append(Between, [livevals(Livevals) - "",
goto(Proc) - Redirect], NewInstrs),
- RemainInstrs = Instrs0
+ RemainInstrs = Instrs0,
+ MostlyDetTailCallInfo1 = MostlyDetTailCallInfo0
;
- % Look for nondet style tailcalls.
- CallModel = nondet(yes),
+ % Look for nondet style tailcalls which do not need
+ % a runtime check.
+ CallModel = nondet(yes, _),
map__search(Succmap, RetLabel, BetweenIncl),
BetweenIncl = [livevals(_) - _, goto(_) - _],
PrevInstr = livevals(Livevals)
@@ -236,8 +268,37 @@
livevals(Livevals) - "",
goto(Proc) - Redirect
],
- RemainInstrs = Instrs0
+ RemainInstrs = Instrs0,
+ MostlyDetTailCallInfo1 = MostlyDetTailCallInfo0
;
+ % Look for nondet style tailcalls which do need
+ % a runtime check.
+ CallModel = nondet(_, yes),
+ MostlyDetTailCallInfo0 = yes(ProcLabel - LabelNum0),
+ map__search(Succmap, RetLabel, BetweenIncl),
+ BetweenIncl = [livevals(_) - _, goto(_) - _],
+ PrevInstr = livevals(Livevals)
+ ->
+ NewLabel = local(ProcLabel, LabelNum0),
+ NewInstrs = [
+ if_val(binop(ne, lval(curfr), lval(maxfr)),
+ label(NewLabel))
+ - "branch around if cannot tail call",
+ assign(maxfr, lval(prevfr(lval(curfr))))
+ - "discard this frame",
+ assign(succip, lval(succip(lval(curfr))))
+ - "setup PC on return from tailcall",
+ assign(curfr, lval(succfr(lval(curfr))))
+ - "setup curfr on return from tailcall",
+ livevals(Livevals) - "",
+ goto(Proc) - Redirect,
+ label(NewLabel) - "non tail call",
+ Instr0
+ ],
+ RemainInstrs = Instrs0,
+ LabelNum1 is LabelNum0 + 1,
+ MostlyDetTailCallInfo1 = yes(ProcLabel - LabelNum1)
+ ;
% Short circuit the return label if possible.
map__search(Instrmap, RetLabel, RetInstr)
->
@@ -250,10 +311,12 @@
NewInstrs = [call(Proc, label(DestLabel),
GC, CallModel) - Redirect],
RemainInstrs = Instrs0
- )
+ ),
+ MostlyDetTailCallInfo1 = MostlyDetTailCallInfo0
;
NewInstrs = [Instr0],
- RemainInstrs = Instrs0
+ RemainInstrs = Instrs0,
+ MostlyDetTailCallInfo1 = MostlyDetTailCallInfo0
)
;
Uinstr0 = goto(label(TargetLabel))
@@ -263,7 +326,8 @@
opt_util__is_this_label_next(TargetLabel, Instrs0, _)
->
NewInstrs = [],
- RemainInstrs = Instrs0
+ RemainInstrs = Instrs0,
+ MostlyDetTailCallInfo1 = MostlyDetTailCallInfo0
;
PrevInstr = if_val(_, label(IfTargetLabel)),
opt_util__is_this_label_next(IfTargetLabel, Instrs0, _)
@@ -275,7 +339,8 @@
% We cannot eliminate the instruction here because
% that would require altering the if_val instruction.
NewInstrs = [Instr0],
- RemainInstrs = Instrs0
+ RemainInstrs = Instrs0,
+ MostlyDetTailCallInfo1 = MostlyDetTailCallInfo0
;
% Replace a jump to a det epilog with the epilog.
map__search(Procmap, TargetLabel, Between0)
@@ -283,7 +348,8 @@
jumpopt__adjust_livevals(PrevInstr, Between0, Between),
list__append(Between, [goto(succip) - "shortcircuit"],
NewInstrs),
- RemainInstrs = Instrs0
+ RemainInstrs = Instrs0,
+ MostlyDetTailCallInfo1 = MostlyDetTailCallInfo0
;
% Replace a jump to a semidet epilog with the epilog.
map__search(Sdprocmap, TargetLabel, Between0)
@@ -291,14 +357,16 @@
jumpopt__adjust_livevals(PrevInstr, Between0, Between),
list__append(Between, [goto(succip) - "shortcircuit"],
NewInstrs),
- RemainInstrs = Instrs0
+ RemainInstrs = Instrs0,
+ MostlyDetTailCallInfo1 = MostlyDetTailCallInfo0
;
% Replace a jump to a nondet epilog with the epilog.
map__search(Succmap, TargetLabel, BetweenIncl0)
->
jumpopt__adjust_livevals(PrevInstr, BetweenIncl0,
NewInstrs),
- RemainInstrs = Instrs0
+ RemainInstrs = Instrs0,
+ MostlyDetTailCallInfo1 = MostlyDetTailCallInfo0
;
% Replace a jump to a non-epilog block with the
% block itself. These jumps are treated separately
@@ -330,7 +398,9 @@
map__delete(Blockmap, DestLabel, CrippledBlockmap),
jumpopt__instr_list(AdjustedBlock, comment(""),
Instrmap, CrippledBlockmap, Lvalmap, Procmap,
- Sdprocmap, Forkmap, Succmap, NewInstrs),
+ Sdprocmap, Forkmap, Succmap,
+ MostlyDetTailCallInfo0,
+ MostlyDetTailCallInfo1, NewInstrs),
RemainInstrs = Instrs0
;
% Short-circuit the goto.
@@ -361,15 +431,18 @@
[Lvalinstr | NewInstrs0], NewInstrs)
;
NewInstrs = NewInstrs0
- )
+ ),
+ MostlyDetTailCallInfo1 = MostlyDetTailCallInfo0
;
NewInstrs = [Instr0],
- RemainInstrs = Instrs0
+ RemainInstrs = Instrs0,
+ MostlyDetTailCallInfo1 = MostlyDetTailCallInfo0
)
; Uinstr0 = computed_goto(Index, LabelList0) ->
% Short-circuit all the destination labels.
jumpopt__short_labels(LabelList0, Instrmap, LabelList),
RemainInstrs = Instrs0,
+ MostlyDetTailCallInfo1 = MostlyDetTailCallInfo0,
( LabelList = LabelList0 ->
NewInstrs = [Instr0]
;
@@ -424,7 +497,8 @@
% the recursive call. We can't go into an infinite
% loop because each application of the transformation
% strictly reduces the size of the code.
- RemainInstrs = [NewInstr | AfterGoto]
+ RemainInstrs = [NewInstr | AfterGoto],
+ MostlyDetTailCallInfo1 = MostlyDetTailCallInfo0
;
map__search(Instrmap, TargetLabel, TargetInstr)
->
@@ -488,15 +562,18 @@
;
NewInstrs = [Instr0],
RemainInstrs = Instrs0
- )
+ ),
+ MostlyDetTailCallInfo1 = MostlyDetTailCallInfo0
;
NewInstrs = [Instr0],
- RemainInstrs = Instrs0
+ RemainInstrs = Instrs0,
+ MostlyDetTailCallInfo1 = MostlyDetTailCallInfo0
)
; Uinstr0 = assign(Lval, Rval0) ->
% Any labels mentioned in Rval0 should be short-circuited.
jumpopt__short_labels_rval(Rval0, Instrmap, Rval),
RemainInstrs = Instrs0,
+ MostlyDetTailCallInfo1 = MostlyDetTailCallInfo0,
( Rval = Rval0 ->
NewInstrs = [Instr0]
;
@@ -506,7 +583,8 @@
)
;
NewInstrs = [Instr0],
- RemainInstrs = Instrs0
+ RemainInstrs = Instrs0,
+ MostlyDetTailCallInfo1 = MostlyDetTailCallInfo0
),
( ( Uinstr0 = comment(_) ; NewInstrs = [] ) ->
NewPrevInstr = PrevInstr
@@ -514,7 +592,8 @@
NewPrevInstr = Uinstr0
),
jumpopt__instr_list(RemainInstrs, NewPrevInstr, Instrmap, Blockmap,
- Lvalmap, Procmap, Sdprocmap, Forkmap, Succmap, Instrs9),
+ Lvalmap, Procmap, Sdprocmap, Forkmap, Succmap,
+ MostlyDetTailCallInfo1, MostlyDetTailCallInfo, Instrs9),
list__append(NewInstrs, Instrs9, Instrs).
% We avoid generating statements that redefine the value of a location
Index: compiler/llds.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/llds.m,v
retrieving revision 1.241
diff -u -b -r1.241 llds.m
--- llds.m 1999/05/28 05:26:19 1.241
+++ llds.m 1999/06/06 02:41:16
@@ -157,7 +157,28 @@
:- type call_model
---> det
; semidet
- ; nondet(bool).
+ ; nondet(
+ bool, % True iff at the point of the call (a)
+ % the procedure has no more alternatives, and
+ % (b) curfr and maxfr are guaranteed to be
+ % identical.
+ %
+ % Under these conditions, the call can be
+ % transformed into a tail call whenever its
+ % return address leads to the procedure
+ % epilogue.
+
+ bool % True iff at the point of the call (a)
+ % the procedure has no more alternatives, and
+ % (b) curfr and maxfr not are guaranteed to be
+ % identical.
+ %
+ % Under these conditions, the call can be
+ % transformed into a tail call whenever its
+ % return address leads to the procedure
+ % epilogue AND curfr and maxfr are found
+ % to be identical at runtime.
+ ).
% `instr' defines the various LLDS virtual machine instructions.
% Each instruction gets compiled to a simple piece of C code
Index: compiler/optimize.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/optimize.m,v
retrieving revision 1.16
diff -u -b -r1.16 optimize.m
--- optimize.m 1999/03/12 05:53:28 1.16
+++ optimize.m 1999/06/06 04:02:24
@@ -134,6 +134,8 @@
),
globals__io_lookup_bool_option(optimize_jumps, Jumpopt),
globals__io_lookup_bool_option(optimize_fulljumps, FullJumpopt),
+ globals__io_lookup_bool_option(optimize_mostly_det_tailcalls,
+ MostlyDetTailCalls),
( { Jumpopt = yes } ->
( { VeryVerbose = yes } ->
io__write_string("% Optimizing jumps for "),
@@ -142,7 +144,8 @@
;
[]
),
- { jumpopt_main(Instrs1, FullJumpopt, Final, Instrs2, Mod1) },
+ { jumpopt_main(Instrs1, FullJumpopt, Final, MostlyDetTailCalls,
+ Instrs2, Mod1) },
( { Mod1 = yes } ->
opt_debug__msg(DebugOpt, "after jump optimization"),
opt_debug__dump_instrs(DebugOpt, Instrs2)
@@ -248,6 +251,8 @@
[]
),
globals__io_lookup_bool_option(optimize_fulljumps, FullJumpopt),
+ globals__io_lookup_bool_option(optimize_mostly_det_tailcalls,
+ MostlyDetTailCalls),
( { Jumps = yes, FullJumpopt = yes } ->
( { VeryVerbose = yes } ->
io__write_string("% Optimizing jumps for "),
@@ -257,7 +262,7 @@
[]
),
{ jumpopt_main(Instrs1, FullJumpopt, Final,
- Instrs2, Mod2) },
+ MostlyDetTailCalls, Instrs2, Mod2) },
( { Mod2 = yes } ->
opt_debug__msg(DebugOpt, "after jump optimization"),
opt_debug__dump_instrs(DebugOpt, Instrs2)
Index: compiler/options.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/options.m,v
retrieving revision 1.265
diff -u -b -r1.265 options.m
--- options.m 1999/06/01 09:44:08 1.265
+++ options.m 1999/06/06 02:26:21
@@ -295,6 +295,7 @@
; optimize_peep
; optimize_jumps
; optimize_fulljumps
+ ; optimize_mostly_det_tailcalls
; optimize_labels
; optimize_dups
%%% unused: ; optimize_copyprop
@@ -633,6 +634,7 @@
optimize_peep - bool(no),
optimize_jumps - bool(no),
optimize_fulljumps - bool(no),
+ optimize_mostly_det_tailcalls - bool(no),
optimize_labels - bool(no),
optimize_dups - bool(no),
%%% optimize_copyprop - bool(no),
@@ -990,6 +992,8 @@
long_option("optimise-jumps", optimize_jumps).
long_option("optimize-fulljumps", optimize_fulljumps).
long_option("optimise-fulljumps", optimize_fulljumps).
+long_option("optimize-mostly-det-tailcalls", optimize_mostly_det_tailcalls).
+long_option("optimise-mostly-det-tailcalls", optimize_mostly_det_tailcalls).
long_option("optimize-labels", optimize_labels).
long_option("optimise-labels", optimize_labels).
long_option("optimize-dups", optimize_dups).
@@ -2077,6 +2081,12 @@
"\tDisable elimination of jumps to jumps.",
"--no-optimize-fulljumps",
"\tDisable elimination of jumps to ordinary code.",
+ "--optimize-mostly-det-tailcalls",
+ "\tConvert nondet calls into tail calls whenever possible,",
+ "\teven if the code before the call is not guaranteed to be det.",
+ "\tThis increases speed only if the code before the call turns",
+ "\tout to be det most of the time, but can reduce speed if this",
+ "\tis not the case.",
"--no-optimize-labels",
"\tDisable elimination of dead labels and code.",
"--optimize-dups",
cvs diff: Diffing compiler/notes
cvs diff: Diffing debian
cvs diff: Diffing doc
Index: doc/user_guide.texi
===================================================================
RCS file: /home/mercury1/repository/mercury/doc/user_guide.texi,v
retrieving revision 1.176
diff -u -b -r1.176 user_guide.texi
--- user_guide.texi 1999/06/01 09:44:47 1.176
+++ user_guide.texi 1999/06/06 04:38:39
@@ -3483,6 +3483,14 @@
Disable elimination of jumps to ordinary code.
@sp 1
+ at item --optimize-mostly-det-tailcalls
+Convert nondet calls into tail calls whenever possible,
+even if the code before the call is not guaranteed to be det.
+This increases speed only if the code before the call turns
+out to be det most of the time, but can reduce speed if this
+is not the case.
+
+ at sp 1
@item --no-optimize-labels
Disable elimination of dead labels and code.
cvs diff: Diffing extras
cvs diff: Diffing extras/aditi
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/dynamic_linking
cvs diff: Diffing extras/exceptions
cvs diff: Diffing extras/graphics
cvs diff: Diffing extras/graphics/mercury_opengl
cvs diff: Diffing extras/graphics/mercury_tcltk
cvs diff: Diffing extras/graphics/samples
cvs diff: Diffing extras/graphics/samples/calc
cvs diff: Diffing extras/graphics/samples/maze
cvs diff: Diffing extras/graphics/samples/pent
cvs diff: Diffing extras/lazy_evaluation
cvs diff: Diffing extras/odbc
cvs diff: Diffing extras/references
cvs diff: Diffing extras/references/samples
cvs diff: Diffing extras/references/tests
cvs diff: Diffing extras/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
cvs diff: Diffing library
cvs diff: Diffing profiler
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 scripts
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/hard_coded
cvs diff: Diffing tests/hard_coded/sub-modules
cvs diff: Diffing tests/hard_coded/typeclasses
cvs diff: Diffing tests/invalid
cvs diff: Diffing tests/misc_tests
cvs diff: Diffing tests/tabling
cvs diff: Diffing tests/term
cvs diff: Diffing tests/valid
cvs diff: Diffing tests/warnings
cvs diff: Diffing tools
cvs diff: Diffing trace
cvs diff: Diffing trial
cvs diff: Diffing util
--------------------------------------------------------------------------
mercury-developers mailing list
Post messages to: mercury-developers at cs.mu.oz.au
Administrative Queries: owner-mercury-developers at cs.mu.oz.au
Subscriptions: mercury-developers-request at cs.mu.oz.au
--------------------------------------------------------------------------
More information about the developers
mailing list