[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