[m-rev.] diff: avoid quadratic behavior when optimizating basic blocks
Zoltan Somogyi
zs at csse.unimelb.edu.au
Wed May 25 18:03:16 AEST 2011
compiler/basic_block.m:
Record the number of instructions in each basic block.
compiler/use_local_vars.m:
Do not perform this quadratic optimization on basic blocks
on which it would take too long.
compiler/dupelim.m:
Don't try to detect duplicates in big blocks; the attempt is expensive,
and also very likely to fail. (Big blocks are unlikely to duplicated;
the optimization was meant for redundant copies of the procedure
epilogue.)
compiler/livemap.m:
Put a limit on the number of iterations done by the fixpoint algorithm.
Zoltan.
cvs diff: Diffing compiler
Index: compiler/basic_block.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/basic_block.m,v
retrieving revision 1.39
diff -u -b -r1.39 basic_block.m
--- compiler/basic_block.m 23 May 2011 05:08:00 -0000 1.39
+++ compiler/basic_block.m 25 May 2011 06:33:52 -0000
@@ -35,22 +35,25 @@
:- type block_info
---> block_info(
% The label starting the block.
- starting_label :: label,
+ bi_starting_label :: label,
% The instruction containing the label.
- label_instr :: instruction,
+ bi_label_instr :: instruction,
% The code of the block without the initial label.
- later_instrs :: list(instruction),
+ bi_later_instrs :: list(instruction),
+
+ % The number of instructions in bi_later_instrs.
+ bi_num_later_instrs :: int,
% Does the previous block (if any) fall through to this block?
- fallen_into :: bool,
+ bi_fallen_into :: bool,
% The labels we can jump to (not falling through).
- jump_dests :: list(label),
+ bi_jump_dests :: list(label),
% The label we fall through to (if there is one).
- fall_dest :: maybe(label)
+ bi_fall_dest :: maybe(label)
).
% create_basic_blocks(ProcInstrs, Comments, ProcLabel, !C, NewLabels,
@@ -81,14 +84,14 @@
:- pred extend_basic_blocks(list(label)::in, list(label)::out,
block_map::in, block_map::out, set(label)::in) is det.
- % flatten_basic_blocks(LabelSeq, BlockMap, Instrs):
+ % flatten_basic_blocks(LabelSeq, BlockMap, Instrs, NumInstrs):
%
% Given LabelSeq, a sequence of labels each referring to a block in
% BlockMap, return the concatenation of the basic blocks referred to by
% the labels in LabelSeq.
%
:- pred flatten_basic_blocks(list(label)::in, block_map::in,
- list(instruction)::out) is det.
+ list(instruction)::out, int::out) is det.
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
@@ -97,6 +100,7 @@
:- import_module ll_backend.opt_util.
+:- import_module int.
:- import_module require.
%-----------------------------------------------------------------------------%
@@ -132,14 +136,20 @@
RestInstrs = [OrigInstr0 | OrigInstrs0]
),
(
- take_until_end_of_block(RestInstrs, BlockInstrs, Instrs1),
+ take_until_end_of_block(RestInstrs, [], RevBlockInstrs, Instrs1),
build_block_map(Instrs1, LabelSeq1, ProcLabel, NextFallInto, !BlockMap,
!NewLabels, !C),
- ( list.last(BlockInstrs, LastInstr) ->
+ (
+ RevBlockInstrs = [LastInstr | _],
+ reverse_and_count_list(RevBlockInstrs, [], BlockInstrs,
+ 0, NumBlockInstrs),
LastInstr = llds_instr(LastUinstr, _),
opt_util.possible_targets(LastUinstr, SideLabels, _SideCodeAddrs),
opt_util.can_instr_fall_through(LastUinstr) = NextFallInto
;
+ RevBlockInstrs = [],
+ BlockInstrs = [],
+ NumBlockInstrs = 0,
SideLabels = [],
NextFallInto = yes
),
@@ -150,32 +160,37 @@
NextFallInto = no,
MaybeFallThrough = no
),
- BlockInfo = block_info(Label, LabelInstr, BlockInstrs, FallInto,
- SideLabels, MaybeFallThrough),
+ BlockInfo = block_info(Label, LabelInstr, BlockInstrs, NumBlockInstrs,
+ FallInto, SideLabels, MaybeFallThrough),
map.det_insert(Label, BlockInfo, !BlockMap),
LabelSeq = [Label | LabelSeq1]
).
-%-----------------------------------------------------------------------------%
-
:- pred take_until_end_of_block(list(instruction)::in,
- list(instruction)::out, list(instruction)::out) is det.
+ list(instruction)::in, list(instruction)::out,
+ list(instruction)::out) is det.
-take_until_end_of_block([], [], []).
-take_until_end_of_block([Instr0 | Instrs0], BlockInstrs, Rest) :-
+take_until_end_of_block([], !RevBlockInstrs, []).
+take_until_end_of_block([Instr0 | Instrs0], !RevBlockInstrs, Rest) :-
Instr0 = llds_instr(Uinstr0, _Comment),
( Uinstr0 = label(_) ->
- BlockInstrs = [],
Rest = [Instr0 | Instrs0]
; opt_util.can_instr_branch_away(Uinstr0) = yes ->
- BlockInstrs = [Instr0],
+ !:RevBlockInstrs = [Instr0 | !.RevBlockInstrs],
Rest = Instrs0
;
- take_until_end_of_block(Instrs0, BlockInstrs1, Rest),
- BlockInstrs = [Instr0 | BlockInstrs1]
+ !:RevBlockInstrs = [Instr0 | !.RevBlockInstrs],
+ take_until_end_of_block(Instrs0, !RevBlockInstrs, Rest)
).
-%-----------------------------------------------------------------------------%
+:- pred reverse_and_count_list(list(T)::in, list(T)::in, list(T)::out,
+ int::in, int::out) is det.
+
+reverse_and_count_list([], !List, !N).
+reverse_and_count_list([X | Xs], !List, !N) :-
+ !:List = [X | !.List],
+ !:N = !.N + 1,
+ reverse_and_count_list(Xs, !List, !N).
:- pred get_fallthrough_from_seq(list(label)::in, maybe(label)::out) is det.
@@ -199,9 +214,11 @@
map.lookup(!.BlockMap, Label, BlockInfo),
map.lookup(!.BlockMap, NextLabel, NextBlockInfo),
BlockInfo = block_info(BlockLabel, BlockLabelInstr, BlockInstrs,
- BlockFallInto, BlockSideLabels, BlockMaybeFallThrough),
+ NumBlockInstrs, BlockFallInto, BlockSideLabels,
+ BlockMaybeFallThrough),
NextBlockInfo = block_info(NextBlockLabel, _, NextBlockInstrs,
- NextBlockFallInto, NextBlockSideLabels, NextBlockMaybeFallThrough),
+ NumNextBlockInstrs, NextBlockFallInto, NextBlockSideLabels,
+ NextBlockMaybeFallThrough),
expect(unify(BlockLabel, Label), $module, $pred,
"block label mismatch"),
expect(unify(NextBlockLabel, NextLabel), $module, $pred,
@@ -211,7 +228,8 @@
expect(unify(NextBlockFallInto, yes), $module, $pred,
"fall into mismatch"),
NewBlockInfo = block_info(BlockLabel, BlockLabelInstr,
- BlockInstrs ++ NextBlockInstrs, BlockFallInto,
+ BlockInstrs ++ NextBlockInstrs,
+ NumBlockInstrs + NumNextBlockInstrs, BlockFallInto,
BlockSideLabels ++ NextBlockSideLabels, NextBlockMaybeFallThrough),
map.det_update(Label, NewBlockInfo, !BlockMap),
map.delete(NextLabel, !BlockMap),
@@ -224,12 +242,14 @@
%-----------------------------------------------------------------------------%
-flatten_basic_blocks([], _, []).
-flatten_basic_blocks([Label | Labels], BlockMap, Instrs) :-
- flatten_basic_blocks(Labels, BlockMap, RestInstrs),
+flatten_basic_blocks([], _, [], 0).
+flatten_basic_blocks([Label | Labels], BlockMap, Instrs, NumInstrs) :-
+ flatten_basic_blocks(Labels, BlockMap, RestInstrs, RestNumInstrs),
map.lookup(BlockMap, Label, BlockInfo),
- BlockInfo = block_info(_, BlockLabelInstr, BlockInstrs, _, _, _),
- list.append([BlockLabelInstr | BlockInstrs], RestInstrs, Instrs).
+ BlockInfo = block_info(_, BlockLabelInstr, BlockInstrs, NumBlockInstrs,
+ _, _, _),
+ Instrs = [BlockLabelInstr | BlockInstrs] ++ RestInstrs,
+ NumInstrs = NumBlockInstrs + RestNumInstrs.
%-----------------------------------------------------------------------------%
:- end_module ll_backend.basic_block.
Index: compiler/dupelim.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/dupelim.m,v
retrieving revision 1.101
diff -u -b -r1.101 dupelim.m
--- compiler/dupelim.m 23 May 2011 05:08:01 -0000 1.101
+++ compiler/dupelim.m 25 May 2011 06:40:11 -0000
@@ -65,6 +65,7 @@
:- import_module ll_backend.opt_util.
:- import_module bool.
+:- import_module int.
:- import_module map.
:- import_module maybe.
:- import_module require.
@@ -104,7 +105,7 @@
map.init(ReplMap0),
process_clusters(Clusters, LabelSeq0, LabelSeq, BlockMap0, BlockMap,
ReplMap0, ReplMap),
- flatten_basic_blocks(LabelSeq, BlockMap, Instrs1),
+ flatten_basic_blocks(LabelSeq, BlockMap, Instrs1, _),
opt_util.replace_labels_instruction_list(Instrs1, Instrs2,
ReplMap, yes, no),
Instrs = Comments ++ Instrs2
@@ -122,12 +123,16 @@
dupelim_build_maps([], _, !StdMap, !Fixed).
dupelim_build_maps([Label | Labels], BlockMap, !StdMap, !Fixed) :-
map.lookup(BlockMap, Label, BlockInfo),
- BlockInfo = block_info(_, _, Instrs, _, _, MaybeFallThrough),
+ BlockInfo = block_info(_, _, Instrs, NumInstrs, _, _, MaybeFallThrough),
+ ( NumInstrs < std_block_size_limit ->
standardize_instr_block(Instrs, MaybeFallThrough, StdInstrs),
( map.search(!.StdMap, StdInstrs, Cluster) ->
map.det_update(StdInstrs, [Label | Cluster], !StdMap)
;
map.det_insert(StdInstrs, [Label], !StdMap)
+ )
+ ;
+ true
),
(
MaybeFallThrough = yes(FallIntoLabel),
@@ -138,6 +143,14 @@
list.foldl(add_pragma_pref_labels, Instrs, !Fixed),
dupelim_build_maps(Labels, BlockMap, !StdMap, !Fixed).
+ % Don't try to standardize blocks that have more instructions than this.
+ % They are extremely unlikely to be duplicate blocks, so the work would
+ % be almost certainly wasted.
+ %
+:- func std_block_size_limit = int.
+
+std_block_size_limit = 10.
+
:- pred add_pragma_pref_labels(instruction::in,
set(label)::in, set(label)::out) is det.
@@ -234,14 +247,14 @@
Cluster = cluster(Exemplar, ElimLabels),
map.lookup(!.BlockMap, Exemplar, ExemplarInfo0),
ExemplarInfo0 = block_info(ExLabel, ExLabelInstr, ExInstrs0,
- ExFallInto, ExSideLabels, ExMaybeFallThrough),
+ ExNumInstrs, ExFallInto, ExSideLabels, ExMaybeFallThrough),
expect(unify(Exemplar, ExLabel), $module, $pred,
"exemplar label mismatch"),
process_elim_labels(ElimLabels, ExInstrs0, !LabelSeq, !.BlockMap,
Exemplar, !ReplMap, UnifiedInstrs,
ExMaybeFallThrough, UnifiedMaybeFallThrough),
ExemplarInfo = block_info(ExLabel, ExLabelInstr, UnifiedInstrs,
- ExFallInto, ExSideLabels, UnifiedMaybeFallThrough),
+ ExNumInstrs, ExFallInto, ExSideLabels, UnifiedMaybeFallThrough),
map.det_update(Exemplar, ExemplarInfo, !BlockMap),
process_clusters(Clusters, !LabelSeq, !BlockMap, !ReplMap).
@@ -265,7 +278,7 @@
process_elim_labels([ElimLabel | ElimLabels], Instrs0, !LabelSeq, BlockMap,
Exemplar, !ReplMap, Instrs, !MaybeFallThrough) :-
map.lookup(BlockMap, ElimLabel, ElimLabelInfo),
- ElimLabelInfo = block_info(ElimLabel2, _, ElimInstrs,
+ ElimLabelInfo = block_info(ElimLabel2, _, ElimInstrs, _NumElimInstrs,
_, _, ElimMaybeFallThrough),
expect(unify(ElimLabel, ElimLabel2), $module, $pred,
"elim label mismatch"),
Index: compiler/livemap.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/livemap.m,v
retrieving revision 1.100
diff -u -b -r1.100 livemap.m
--- compiler/livemap.m 23 May 2011 05:08:04 -0000 1.100
+++ compiler/livemap.m 25 May 2011 06:40:48 -0000
@@ -44,6 +44,7 @@
:- import_module parse_tree.prog_data.
:- import_module bool.
+:- import_module int.
:- import_module require.
:- import_module string.
@@ -65,12 +66,12 @@
build_livemap(Instrs, MaybeLivemap) :-
map.init(Livemap0),
list.reverse(Instrs, BackInstrs),
- build_livemap_fixpoint(BackInstrs, Livemap0, MaybeLivemap).
+ build_livemap_fixpoint(BackInstrs, Livemap0, 0, MaybeLivemap).
-:- pred build_livemap_fixpoint(list(instruction)::in, livemap::in,
+:- pred build_livemap_fixpoint(list(instruction)::in, livemap::in, int::in,
maybe(livemap)::out) is det.
-build_livemap_fixpoint(Backinstrs, Livemap0, MaybeLivemap) :-
+build_livemap_fixpoint(Backinstrs, Livemap0, CurIteration, MaybeLivemap) :-
set.init(Livevals0),
livemap_do_build(Backinstrs, Livevals0, no, ContainsBadUserCode,
Livemap0, Livemap1),
@@ -82,7 +83,12 @@
( livemap.equal_livemaps(Livemap0, Livemap1) ->
MaybeLivemap = yes(Livemap1)
;
- build_livemap_fixpoint(Backinstrs, Livemap1, MaybeLivemap)
+ ( CurIteration < livemap_iteration_limit ->
+ build_livemap_fixpoint(Backinstrs, Livemap1, CurIteration + 1,
+ MaybeLivemap)
+ ;
+ MaybeLivemap = no
+ )
)
).
@@ -110,6 +116,12 @@
set.equal(Liveset1, Liveset2),
equal_livemaps_keys(Labels, Livemap1, Livemap2).
+ % Don't iterate the map building process more than this many times.
+ %
+:- func livemap_iteration_limit = int.
+
+livemap_iteration_limit = 5.
+
%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
Index: compiler/use_local_vars.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/use_local_vars.m,v
retrieving revision 1.47
diff -u -b -r1.47 use_local_vars.m
--- compiler/use_local_vars.m 23 May 2011 05:08:15 -0000 1.47
+++ compiler/use_local_vars.m 25 May 2011 06:39:44 -0000
@@ -104,13 +104,17 @@
AutoComments, ProcLabel, !C) :-
create_basic_blocks(Instrs0, Comments0, ProcLabel, !C, NewLabels,
LabelSeq, BlockMap0),
- flatten_basic_blocks(LabelSeq, BlockMap0, TentativeInstrs),
+ flatten_basic_blocks(LabelSeq, BlockMap0, TentativeInstrs,
+ NumTentativeInstrs),
+ % If the number of instructions in the procedure is too big,
+ % then building MaybeLiveMap will probably take too long.
+ ( NumTentativeInstrs < local_vars_proc_size_limit ->
build_livemap(TentativeInstrs, MaybeLiveMap),
extend_basic_blocks(LabelSeq, EBBLabelSeq, BlockMap0, EBBBlockMap0,
NewLabels),
list.foldl(use_local_vars_block(MaybeLiveMap, NumRealRRegs,
AccessThreshold), EBBLabelSeq, EBBBlockMap0, EBBBlockMap),
- flatten_basic_blocks(EBBLabelSeq, EBBBlockMap, Instrs1),
+ flatten_basic_blocks(EBBLabelSeq, EBBBlockMap, Instrs1, _),
(
MaybeLiveMap = yes(LiveMap),
@@ -122,7 +126,10 @@
;
Comments = Comments0
),
- Instrs = Comments ++ Instrs1.
+ Instrs = Comments ++ Instrs1
+ ;
+ Instrs = Instrs0
+ ).
:- pred use_local_vars_block(maybe(livemap)::in, int::in, int::in, label::in,
block_map::in, block_map::out) is det.
@@ -130,17 +137,25 @@
use_local_vars_block(MaybeLiveMap, NumRealRRegs, AccessThreshold, Label,
!BlockMap) :-
map.lookup(!.BlockMap, Label, BlockInfo0),
- BlockInfo0 = block_info(BlockLabel, LabelInstr, RestInstrs0,
+ BlockInfo0 = block_info(BlockLabel, LabelInstr, RestInstrs0, BlockSize,
FallInto, JumpLabels, MaybeFallThrough),
+ % The algorithm we use is half-quadratic, so using it on long instruction
+ % lists is not a good idea. The correct fix of course would be to reduce
+ % the complexity of the algorithm, but that is not trivial to do.
+ ( BlockSize < local_vars_block_size_limit ->
counter.init(1, TempCounter0),
- use_local_vars_instrs(RestInstrs0, RestInstrs, TempCounter0, TempCounter,
- NumRealRRegs, AccessThreshold, MaybeLiveMap, MaybeFallThrough),
+ use_local_vars_instrs(RestInstrs0, RestInstrs,
+ TempCounter0, TempCounter, NumRealRRegs,
+ AccessThreshold, MaybeLiveMap, MaybeFallThrough),
( TempCounter = TempCounter0 ->
true
;
- BlockInfo = block_info(BlockLabel, LabelInstr, RestInstrs, FallInto,
- JumpLabels, MaybeFallThrough),
+ BlockInfo = block_info(BlockLabel, LabelInstr, RestInstrs,
+ BlockSize, FallInto, JumpLabels, MaybeFallThrough),
map.det_update(Label, BlockInfo, !BlockMap)
+ )
+ ;
+ true
).
%-----------------------------------------------------------------------------%
@@ -782,5 +797,15 @@
).
%-----------------------------------------------------------------------------%
+
+:- func local_vars_proc_size_limit = int.
+
+local_vars_proc_size_limit = 10000.
+
+:- func local_vars_block_size_limit = int.
+
+local_vars_block_size_limit = 200.
+
+%-----------------------------------------------------------------------------%
:- end_module ll_backend.use_local_vars.
%-----------------------------------------------------------------------------%
cvs diff: Diffing compiler/notes
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/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_allegro
cvs diff: Diffing extras/graphics/mercury_allegro/examples
cvs diff: Diffing extras/graphics/mercury_allegro/samples
cvs diff: Diffing extras/graphics/mercury_allegro/samples/demo
cvs diff: Diffing extras/graphics/mercury_allegro/samples/mandel
cvs diff: Diffing extras/graphics/mercury_allegro/samples/pendulum2
cvs diff: Diffing extras/graphics/mercury_allegro/samples/speed
cvs diff: Diffing extras/graphics/mercury_cairo
cvs diff: Diffing extras/graphics/mercury_cairo/samples
cvs diff: Diffing extras/graphics/mercury_cairo/samples/data
cvs diff: Diffing extras/graphics/mercury_cairo/tutorial
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/monte
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/posix/samples
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/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/c_interface/standalone_c
cvs diff: Diffing samples/concurrency
cvs diff: Diffing samples/concurrency/dining_philosophers
cvs diff: Diffing samples/concurrency/midimon
cvs diff: Diffing samples/diff
cvs diff: Diffing samples/java_interface
cvs diff: Diffing samples/java_interface/java_calls_mercury
cvs diff: Diffing samples/java_interface/mercury_calls_java
cvs diff: Diffing samples/muz
cvs diff: Diffing samples/rot13
cvs diff: Diffing samples/solutions
cvs diff: Diffing samples/solver_types
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 ssdb
cvs diff: Diffing tests
cvs diff: Diffing tests/analysis
cvs diff: Diffing tests/analysis/ctgc
cvs diff: Diffing tests/analysis/excp
cvs diff: Diffing tests/analysis/ext
cvs diff: Diffing tests/analysis/sharing
cvs diff: Diffing tests/analysis/table
cvs diff: Diffing tests/analysis/trail
cvs diff: Diffing tests/analysis/unused_args
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
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/stm
cvs diff: Diffing tests/stm/orig
cvs diff: Diffing tests/stm/orig/stm-compiler
cvs diff: Diffing tests/stm/orig/stm-compiler/test1
cvs diff: Diffing tests/stm/orig/stm-compiler/test10
cvs diff: Diffing tests/stm/orig/stm-compiler/test2
cvs diff: Diffing tests/stm/orig/stm-compiler/test3
cvs diff: Diffing tests/stm/orig/stm-compiler/test4
cvs diff: Diffing tests/stm/orig/stm-compiler/test5
cvs diff: Diffing tests/stm/orig/stm-compiler/test6
cvs diff: Diffing tests/stm/orig/stm-compiler/test7
cvs diff: Diffing tests/stm/orig/stm-compiler/test8
cvs diff: Diffing tests/stm/orig/stm-compiler/test9
cvs diff: Diffing tests/stm/orig/stm-compiler-par
cvs diff: Diffing tests/stm/orig/stm-compiler-par/bm1
cvs diff: Diffing tests/stm/orig/stm-compiler-par/bm2
cvs diff: Diffing tests/stm/orig/stm-compiler-par/stmqueue
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test1
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test10
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test11
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test2
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test3
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test4
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test5
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test6
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test7
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test8
cvs diff: Diffing tests/stm/orig/stm-compiler-par/test9
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test1
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test2
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test3
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test4
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test5
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test6
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test7
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test8
cvs diff: Diffing tests/stm/orig/stm-compiler-par-asm_fast/test9
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