[m-rev.] diff: optimize succeed into succeed_discard

Zoltan Somogyi zs at csse.unimelb.edu.au
Tue Jan 23 15:49:55 AEDT 2007


Optimize code sequences such as

	mkframe(framesize, do_fail)
	...
	if (...) goto ...
	...
	succeed()

in which the ...s do not contains labels or update any of the control slots
of the frame. The optimization is replacing the succeed with a succeed_discard,
avoiding a future backtrack that cannot succeed.

compiler/peephole.m:
	Look for the pattern and act on it.

	Rejig the arguments of peephole's main predicate to avoid the need to
	rebuild the original instruction on the heap by passing it whole,
	instead of in pieces.

	Rename predicates to avoid the need for module qualification.

compiler/opt_util.m:
	Add a utility predicate needed by peephole.

compiler/optimize.m:
	Conform to the predicate renames in peephole.

Zoltan.

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/opt_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/opt_util.m,v
retrieving revision 1.161
diff -u -b -r1.161 opt_util.m
--- compiler/opt_util.m	15 Jan 2007 02:23:48 -0000	1.161
+++ compiler/opt_util.m	22 Jan 2007 07:15:36 -0000
@@ -150,6 +150,16 @@
 :- pred no_stack_straight_line(list(instruction)::in,
     list(instruction)::out, list(instruction)::out) is det.
 
+    % Check whether the given instruction sequence consist of an initial
+    % sequence of instructions that do not refer to stackvars and do not
+    % contain any entry points or unconditional branches away, until a
+    % goto(do_succeed(yes)) instruction. If yes, return that initial sequence,
+    % the comment on the goto(do_succeed(yes)) instruction, and the
+    % instructions after it.
+    %
+:- pred may_replace_succeed_with_succeed_discard(list(instruction)::in,
+    list(instruction)::out, string::out, list(instruction)::out) is semidet.
+
     % Remove the labels from a block of code for jumpopt.
     %
 :- pred filter_out_labels(list(instruction)::in, list(instruction)::out)
@@ -646,6 +656,54 @@
         Instrs = [Instr0 | Instrs0]
     ).
 
+may_replace_succeed_with_succeed_discard(Instrs0, UntilSucceed, SucceedComment,
+        Remain) :-
+    may_replace_succeed_with_succeed_discard_2(Instrs0, [], RevUntilSucceed,
+        SucceedComment, Remain),
+    list.reverse(RevUntilSucceed, UntilSucceed).
+
+:- pred may_replace_succeed_with_succeed_discard_2(list(instruction)::in,
+    list(instruction)::in, list(instruction)::out, string::out,
+    list(instruction)::out) is semidet.
+
+may_replace_succeed_with_succeed_discard_2([Instr0 | Instrs0],
+        !RevUntilSucceed, SucceedComment, Remain) :-
+    Instr0 = llds_instr(Uinstr, Comment),
+    (
+        Uinstr = goto(do_succeed(yes))
+    ->
+        SucceedComment = Comment,
+        Remain = Instrs0
+    ;
+        (
+            Uinstr = assign(Lval, Rval),
+            lval_refers_stackvars(Lval) = no,
+            rval_refers_stackvars(Rval) = no
+        ;
+            ( Uinstr = comment(_)
+            ; Uinstr = livevals(_)
+            ; Uinstr = if_val(_, _)
+            ; Uinstr = incr_hp(_, _, _, _, _, _)
+            ; Uinstr = mark_hp(_)
+            ; Uinstr = restore_hp(_)
+            ; Uinstr = free_heap(_)
+            ; Uinstr = store_ticket(_)
+            ; Uinstr = store_ticket(_)
+            ; Uinstr = reset_ticket(_, _)
+            ; Uinstr = prune_ticket
+            ; Uinstr = discard_ticket
+            ; Uinstr = mark_ticket_stack(_)
+            ; Uinstr = prune_tickets_to(_)
+            )
+        )
+    ->
+        !:RevUntilSucceed = [Instr0 | !.RevUntilSucceed],
+        may_replace_succeed_with_succeed_discard_2(Instrs0, !RevUntilSucceed,
+            SucceedComment, Remain)
+    ;
+        fail
+    ).
+
 lval_refers_stackvars(reg(_, _)) = no.
 lval_refers_stackvars(stackvar(_)) = yes.
 lval_refers_stackvars(parent_stackvar(_)) = yes.
Index: compiler/optimize.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/optimize.m,v
retrieving revision 1.61
diff -u -b -r1.61 optimize.m
--- compiler/optimize.m	19 Jan 2007 07:04:24 -0000	1.61
+++ compiler/optimize.m	22 Jan 2007 07:28:45 -0000
@@ -380,7 +380,7 @@
             VeryVerbose = no
         ),
         globals.io_get_gc_method(GC_Method, !IO),
-        peephole.optimize(GC_Method, !Instrs, Mod2),
+        peephole_optimize(GC_Method, !Instrs, Mod2),
         maybe_opt_debug(!.Instrs, !.C, "peep", "after peephole",
             ProcLabel, !OptDebugInfo, !IO)
     ;
@@ -516,7 +516,7 @@
                 VeryVerbose = no
             ),
             globals.io_get_gc_method(GC_Method, !IO),
-            peephole.optimize(GC_Method, !Instrs, _Mod),
+            peephole_optimize(GC_Method, !Instrs, _Mod),
             maybe_opt_debug(!.Instrs, !.C, "peep", "after peephole",
                 ProcLabel, !OptDebugInfo, !IO)
         ;
Index: compiler/peephole.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/peephole.m,v
retrieving revision 1.98
diff -u -b -r1.98 peephole.m
--- compiler/peephole.m	6 Jan 2007 09:23:47 -0000	1.98
+++ compiler/peephole.m	23 Jan 2007 04:40:44 -0000
@@ -24,7 +24,7 @@
 
     % Peephole optimize a list of instructions.
     %
-:- pred peephole.optimize(gc_method::in, list(instruction)::in,
+:- pred peephole_optimize(gc_method::in, list(instruction)::in,
     list(instruction)::out, bool::out) is det.
 
 :- pred combine_decr_sp(list(instruction)::in, list(instruction)::out) is det.
@@ -47,7 +47,8 @@
 
     % Patterns that can be switched off.
     %
-:- type pattern --->        incr_sp.
+:- type pattern
+    --->    incr_sp.
 
     % We zip down to the end of the instruction list, and start attempting
     % to optimize instruction sequences. As long as we can continue
@@ -55,17 +56,17 @@
     % when we find a sequence we can't optimize, we back up and try
     % to optimize the sequence starting with the previous instruction.
     %
-peephole.optimize(GC_Method, Instrs0, Instrs, Mod) :-
-    peephole.invalid_opts(GC_Method, InvalidPatterns),
-    peephole.optimize_2(InvalidPatterns, Instrs0, Instrs, Mod).
+peephole_optimize(GC_Method, Instrs0, Instrs, Mod) :-
+    invalid_peephole_opts(GC_Method, InvalidPatterns),
+    peephole_optimize_2(InvalidPatterns, Instrs0, Instrs, Mod).
 
-:- pred peephole.optimize_2(list(pattern)::in, list(instruction)::in,
+:- pred peephole_optimize_2(list(pattern)::in, list(instruction)::in,
     list(instruction)::out, bool::out) is det.
 
-peephole.optimize_2(_, [], [], no).
-peephole.optimize_2(InvalidPatterns, [Instr0 | Instrs0], Instrs, Mod) :-
-    peephole.optimize_2(InvalidPatterns, Instrs0, Instrs1, Mod0),
-    peephole.opt_instr(Instr0, InvalidPatterns, Instrs1, Instrs, Mod1),
+peephole_optimize_2(_, [], [], no).
+peephole_optimize_2(InvalidPatterns, [Instr0 | Instrs0], Instrs, Mod) :-
+    peephole_optimize_2(InvalidPatterns, Instrs0, Instrs1, Mod0),
+    peephole_opt_instr(Instr0, Instrs1, InvalidPatterns, Instrs, Mod1),
     ( Mod0 = no, Mod1 = no ->
         Mod = no
     ;
@@ -75,19 +76,17 @@
     % Try to optimize the beginning of the given instruction sequence.
     % If successful, try it again.
     %
-:- pred peephole.opt_instr(instruction::in, list(pattern)::in,
-    list(instruction)::in, list(instruction)::out, bool::out) is det.
+:- pred peephole_opt_instr(instruction::in, list(instruction)::in,
+    list(pattern)::in, list(instruction)::out, bool::out) is det.
 
-peephole.opt_instr(Instr0, InvalidPatterns, Instrs0, Instrs, Mod) :-
-    Instr0 = llds_instr(Uinstr0, Comment0),
+peephole_opt_instr(Instr0, Instrs0, InvalidPatterns, Instrs, Mod) :-
     (
         opt_util.skip_comments(Instrs0, Instrs1),
-        peephole.match(Uinstr0, Comment0, InvalidPatterns, Instrs1, Instrs2)
+        peephole_match(Instr0, Instrs1, InvalidPatterns, Instrs2)
     ->
         (
-            Instrs2 = [llds_instr(Uinstr2, Comment2) | Instrs3],
-            peephole.opt_instr(llds_instr(Uinstr2, Comment2), InvalidPatterns,
-                Instrs3, Instrs, _)
+            Instrs2 = [Instr2 | Instrs3],
+            peephole_opt_instr(Instr2, Instrs3, InvalidPatterns, Instrs, _)
         ;
             Instrs2 = [],
             Instrs = Instrs2
@@ -103,26 +102,26 @@
     % Build a map that associates each label in a computed goto with the
     % values of the switch rval that cause a jump to it.
     %
-:- pred peephole.build_jump_label_map(list(label)::in, int::in,
+:- pred build_peephole_jump_label_map(list(label)::in, int::in,
     map(label, list(int))::in, map(label, list(int))::out) is det.
 
-peephole.build_jump_label_map([], _, !LabelMap).
-peephole.build_jump_label_map([Label | Labels], Val, !LabelMap) :-
+build_peephole_jump_label_map([], _, !LabelMap).
+build_peephole_jump_label_map([Label | Labels], Val, !LabelMap) :-
     ( map.search(!.LabelMap, Label, Vals0) ->
         map.det_update(!.LabelMap, Label, [Val | Vals0], !:LabelMap)
     ;
         map.det_insert(!.LabelMap, Label, [Val], !:LabelMap)
     ),
-    peephole.build_jump_label_map(Labels, Val + 1, !LabelMap).
+    build_peephole_jump_label_map(Labels, Val + 1, !LabelMap).
 
     % If one of the two labels has only one associated value, return it and
     % the associated value as the first two output arguments, and the
     % remaining label as the last output argument.
     %
-:- pred peephole.pick_one_val_label(pair(label, list(int))::in,
+:- pred peephole_pick_one_val_label(pair(label, list(int))::in,
     pair(label, list(int))::in, label::out, int::out, label::out) is semidet.
 
-peephole.pick_one_val_label(LabelVals1, LabelVals2, OneValLabel, Val,
+peephole_pick_one_val_label(LabelVals1, LabelVals2, OneValLabel, Val,
         OtherLabel) :-
     LabelVals1 = Label1 - Vals1,
     LabelVals2 = Label2 - Vals2,
@@ -140,8 +139,8 @@
 
     % Look for code patterns that can be optimized, and optimize them.
     %
-:- pred peephole.match(instr::in, string::in, list(pattern)::in,
-    list(instruction)::in, list(instruction)::out) is semidet.
+:- pred peephole_match(instruction::in, list(instruction)::in,
+    list(pattern)::in, list(instruction)::out) is semidet.
 
     % A `computed_goto' with all branches pointing to the same label
     % can be replaced with an unconditional goto.
@@ -150,25 +149,26 @@
     % can be replaced with a conditional branch followed by an unconditional
     % goto.
     %
-peephole.match(computed_goto(SelectorRval, Labels), Comment, _,
-        Instrs0, Instrs) :-
-    peephole.build_jump_label_map(Labels, 0, map.init, LabelMap),
+peephole_match(Instr0, Instrs0, _, Instrs) :-
+    Instr0 = llds_instr(Uinstr0, Comment0),
+    Uinstr0 = computed_goto(SelectorRval, Labels),
+    build_peephole_jump_label_map(Labels, 0, map.init, LabelMap),
     map.to_assoc_list(LabelMap, LabelValsList),
     (
         LabelValsList = [Label - _]
     ->
-        GotoInstr = llds_instr(goto(code_label(Label)), Comment),
+        GotoInstr = llds_instr(goto(code_label(Label)), Comment0),
         Instrs = [GotoInstr | Instrs0]
     ;
         LabelValsList = [LabelVals1, LabelVals2],
-        peephole.pick_one_val_label(LabelVals1, LabelVals2, OneValLabel,
+        peephole_pick_one_val_label(LabelVals1, LabelVals2, OneValLabel,
             Val, OtherLabel)
     ->
         CondRval = binop(eq, SelectorRval, const(llconst_int(Val))),
-        CommentInstr = llds_instr(comment(Comment), ""),
+        CommentInstr = llds_instr(comment(Comment0), ""),
         BranchInstr = llds_instr(if_val(CondRval, code_label(OneValLabel)),
             ""),
-        GotoInstr = llds_instr(goto(code_label(OtherLabel)), Comment),
+        GotoInstr = llds_instr(goto(code_label(OtherLabel)), Comment0),
         Instrs = [CommentInstr, BranchInstr, GotoInstr | Instrs0]
     ;
         fail
@@ -183,13 +183,15 @@
     % A conditional branch to a label followed by that label
     % can be eliminated.
     %
-peephole.match(if_val(Rval, CodeAddr), Comment, _, Instrs0, Instrs) :-
+peephole_match(Instr0, Instrs0, _, Instrs) :-
+    Instr0 = llds_instr(Uinstr0, Comment0),
+    Uinstr0 = if_val(Rval, CodeAddr),
     (
         opt_util.is_const_condition(Rval, Taken)
     ->
         (
             Taken = yes,
-            Instrs = [llds_instr(goto(CodeAddr), Comment) | Instrs0]
+            Instrs = [llds_instr(goto(CodeAddr), Comment0) | Instrs0]
         ;
             Taken = no,
             Instrs = Instrs0
@@ -244,15 +246,27 @@
     % These three classes of patterns are mutually exclusive because if_val
     % and goto are not straight-line code.
     %
-    % We also look for the following pattern, which can happen when predicates
-    % that are actually semidet are declared to be nondet:
+    % The fourth pattern we look for can happen when predicates that are
+    % actually semidet are declared to be nondet:
     %
     %   mkframe(NFI, dofail)
     %   <straight,nostack instrs>   =>  <straight,nostack instrs>
     %   succeed                         proceed
     %
-peephole.match(mkframe(NondetFrameInfo, yes(Redoip1)), Comment, _,
-        Instrs0, Instrs) :-
+    % The fifth pattern can happen e.g. for lookup switches:
+    %
+    %   mkframe(NFI, dofail)            mkframe(NFI, dofail)
+    %   <nostack instrs, no labels> =>  <nostack instrs, no labels>
+    %   succeed                         succeed_discard
+    %
+    % The fifth pattern may apply even if the fourth doesn't, since it permits
+    % branches away between the mkframe and the succeed. However, if there are
+    % none, and both patterns apply, we prefer to apply the fourth pattern's
+    % transformation.
+    %
+peephole_match(Instr0, Instrs0, _, Instrs) :-
+    Instr0 = llds_instr(Uinstr0, Comment0),
+    Uinstr0 = mkframe(NondetFrameInfo, yes(Redoip0)),
     (
         % A mkframe sets curfr to point to the new frame
         % only for ordinary frames, not temp frames.
@@ -261,44 +275,44 @@
         ;
             AllowedBases = [maxfr]
         ),
-        opt_util.next_assign_to_redoip(Instrs0, AllowedBases, [], Redoip2,
+        opt_util.next_assign_to_redoip(Instrs0, AllowedBases, [], Redoip1,
             Skipped, Rest),
         opt_util.touches_nondet_ctrl(Skipped) = no
     ->
         Instrs1 = Skipped ++ Rest,
-        NewInstr = llds_instr(mkframe(NondetFrameInfo, yes(Redoip2)), Comment),
+        NewInstr = llds_instr(mkframe(NondetFrameInfo, yes(Redoip1)),
+            Comment0),
         Instrs = [NewInstr | Instrs1]
     ;
         opt_util.skip_comments_livevals(Instrs0, Instrs1),
         Instrs1 = [Instr1 | Instrs2],
-        Instr1 = llds_instr(if_val(Test, Target), Comment2),
+        Instr1 = llds_instr(if_val(Test, Target), Comment1),
         (
-            Redoip1 = do_fail,
+            Redoip0 = do_fail,
             ( Target = do_redo ; Target = do_fail)
         ->
             InstrsPrime = [
-                llds_instr(if_val(Test, do_redo), Comment2),
-                llds_instr(mkframe(NondetFrameInfo, yes(do_fail)), Comment)
+                llds_instr(if_val(Test, do_redo), Comment1),
+                llds_instr(mkframe(NondetFrameInfo, yes(do_fail)), Comment0)
                 | Instrs2
             ]
         ;
-            Redoip1 = code_label(_)
+            Redoip0 = code_label(_)
         ->
             (
                 Target = do_fail
             ->
                 InstrsPrime = [
-                    llds_instr(if_val(Test, do_redo), Comment2),
-                    llds_instr(mkframe(NondetFrameInfo, yes(Redoip1)), Comment)
+                    llds_instr(if_val(Test, do_redo), Comment1),
+                    Instr0
                     | Instrs2
                 ]
             ;
                 Target = do_redo
             ->
                 InstrsPrime = [
-                    llds_instr(mkframe(NondetFrameInfo, yes(Redoip1)),
-                        Comment),
-                    llds_instr(if_val(Test, Redoip1), Comment2)
+                    Instr0,
+                    llds_instr(if_val(Test, Redoip0), Comment1)
                     | Instrs2
                 ]
             ;
@@ -316,7 +330,7 @@
     ->
         Instrs = [llds_instr(goto(do_redo), Comment2) | Instrs2]
     ;
-        Redoip1 = do_fail,
+        Redoip0 = do_fail,
         no_stack_straight_line(Instrs0, Straight, Instrs1),
         Instrs1 = [Instr1 | Instrs2],
         Instr1 = llds_instr(goto(do_succeed(_)), _)
@@ -325,6 +339,15 @@
             "return from optimized away mkframe"),
         Instrs = Straight ++ [GotoSuccip | Instrs2]
     ;
+        Redoip0 = do_fail,
+        may_replace_succeed_with_succeed_discard(Instrs0, UntilSucceed,
+            SucceedComment, Instrs2)
+    ->
+        DiscardUinstr = goto(do_succeed(no)),
+        DiscardComment = SucceedComment ++ " (added discard)",
+        DiscardInstr = llds_instr(DiscardUinstr, DiscardComment),
+        Instrs = [Instr0 | UntilSucceed] ++ [DiscardInstr | Instrs2]
+    ;
         fail
     ).
 
@@ -334,11 +357,14 @@
     %   store_ticket(Lval)          =>  store_ticket(Lval)
     %   reset_ticket(Lval, _R)
     %
-peephole.match(store_ticket(Lval), Comment, _, Instrs0, Instrs) :-
+peephole_match(Instr0, Instrs0, _, Instrs) :-
+    Instr0 = llds_instr(Uinstr0, Comment0),
+    Uinstr0 = store_ticket(Lval),
+
     opt_util.skip_comments(Instrs0, Instrs1),
     Instrs1 = [Instr1 | Instrs2],
-    Instr1 = llds_instr(reset_ticket(lval(Lval), _Reason), _Comment2),
-    NewInstr2 = llds_instr(store_ticket(Lval), Comment),
+    Instr1 = llds_instr(reset_ticket(lval(Lval), _Reason), _Comment1),
+    NewInstr2 = llds_instr(store_ticket(Lval), Comment0),
     Instrs = [NewInstr2 | Instrs2].
 
     % If an assignment to a redoip slot is followed by another, with
@@ -356,23 +382,24 @@
     % straight-line instructions, then we can discard the nondet stack
     % frame early.
     %
-peephole.match(assign(redoip_slot(lval(Base)), Redoip), Comment, _,
-        Instrs0, Instrs) :-
+peephole_match(Instr0, Instrs0, _, Instrs) :-
+    Instr0 = llds_instr(Uinstr0, Comment0),
+    Uinstr0 = assign(redoip_slot(lval(Base)), Redoip0),
     (
-        opt_util.next_assign_to_redoip(Instrs0, [Base], [], Redoip2,
+        opt_util.next_assign_to_redoip(Instrs0, [Base], [], Redoip1,
             Skipped, Rest),
         opt_util.touches_nondet_ctrl(Skipped) = no
     ->
         Instrs1 = Skipped ++ Rest,
         RedoipInstr = llds_instr(assign(redoip_slot(lval(Base)),
-            const(llconst_code_addr(Redoip2))), Comment),
+            const(llconst_code_addr(Redoip1))), Comment0),
         Instrs = [RedoipInstr | Instrs1]
     ;
         Base = curfr,
-        Redoip = const(llconst_code_addr(do_fail)),
+        Redoip0 = const(llconst_code_addr(do_fail)),
         opt_util.straight_alternative(Instrs0, Between, After),
         opt_util.touches_nondet_ctrl(Between) = no,
-        string.sub_string_search(Comment, "curfr==maxfr", _)
+        string.sub_string_search(Comment0, "curfr==maxfr", _)
     ->
         SucceedInstr = llds_instr(goto(do_succeed(yes)), "early discard"),
         Instrs = Between ++ [SucceedInstr] ++ After
@@ -394,7 +421,9 @@
     %   succip = detstackvar(N)
     %   decr_sp N
     %
-peephole.match(incr_sp(N, _, _), _, InvalidPatterns, Instrs0, Instrs) :-
+peephole_match(Instr0, Instrs0, InvalidPatterns, Instrs) :-
+    Instr0 = llds_instr(Uinstr0, _Comment0),
+    Uinstr0 = incr_sp(N, _, _),
     \+ list.member(incr_sp, InvalidPatterns),
     ( opt_util.no_stackvars_til_decr_sp(Instrs0, N, Between, Remain) ->
         Instrs = Between ++ Remain
@@ -406,9 +435,9 @@
 
     % Given a GC method, return the list of invalid peephole optimizations.
     %
-:- pred peephole.invalid_opts(gc_method::in, list(pattern)::out) is det.
+:- pred invalid_peephole_opts(gc_method::in, list(pattern)::out) is det.
 
-peephole.invalid_opts(GC_Method, InvalidPatterns) :-
+invalid_peephole_opts(GC_Method, InvalidPatterns) :-
     ( GC_Method = gc_accurate ->
         InvalidPatterns = [incr_sp]
     ;
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
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