[m-rev.] diff: decr_sp_and_return

Zoltan Somogyi zs at cs.mu.OZ.AU
Wed Sep 14 11:28:20 AEST 2005


When returning from det and semidet predicates, load the return address into a
local C variable instead of the succip abstract machine "register" before
popping the stack frame and returning. This gives the C compiler more freedom
to reorder instructions.

This diff gets a 1.4% speed increase on the compiler.

runtime/mercury_stacks.h:
	Provide a new macro, MR_decr_sp_and_return, to do the combined job that 
	its name describes.

compiler/llds.m:
	Add a new LLDS instruction that corresponds to the new macro.

compiler/llds_out.m:
	Output the new LLDS instruction.

compiler/peephole.m:
	Add a predicate that looks for and exploits opportunities for using
	the new instruction.

compiler/optimize.m:
	Invoke the new peephole predicate as the next-to-last optimization
	pass. (The last is wrapping up blocks created by --use-local-vars.)

compiler/*.m:
	Minor changes to handle the new instruction.

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/tests
cvs diff: Diffing browser
cvs diff: Diffing bytecode
cvs diff: Diffing compiler
Index: compiler/dupelim.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/dupelim.m,v
retrieving revision 1.68
diff -u -b -r1.68 dupelim.m
--- compiler/dupelim.m	13 Sep 2005 08:25:28 -0000	1.68
+++ compiler/dupelim.m	13 Sep 2005 08:32:36 -0000
@@ -404,6 +404,9 @@
         Instr1 = decr_sp(_),
         Instr = Instr1
     ;
+        Instr1 = decr_sp_and_return(_),
+        Instr = Instr1
+    ;
         Instr1 = fork(_, _, _),
         Instr = Instr1
     ;
@@ -822,6 +825,13 @@
         )
     ;
         Instr1 = decr_sp(_),
+        ( Instr1 = Instr2 ->
+            MaybeInstr = yes(Instr1)
+        ;
+            MaybeInstr = no
+        )
+    ;
+        Instr1 = decr_sp_and_return(_),
         ( Instr1 = Instr2 ->
             MaybeInstr = yes(Instr1)
         ;
Index: compiler/dupproc.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/dupproc.m,v
retrieving revision 1.3
diff -u -b -r1.3 dupproc.m
--- compiler/dupproc.m	13 Sep 2005 08:25:28 -0000	1.3
+++ compiler/dupproc.m	13 Sep 2005 08:29:21 -0000
@@ -264,6 +264,9 @@
 		Instr = decr_sp(_),
 		StdInstr = Instr
 	;
+		Instr = decr_sp_and_return(_),
+		StdInstr = Instr
+	;
 		Instr = fork(Child, Parent, NumSlots),
 		standardize_label(Child, StdChild, DupProcMap),
 		standardize_label(Parent, StdParent, DupProcMap),
Index: compiler/exprn_aux.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/exprn_aux.m,v
retrieving revision 1.60
diff -u -b -r1.60 exprn_aux.m
--- compiler/exprn_aux.m	13 Sep 2005 08:25:28 -0000	1.60
+++ compiler/exprn_aux.m	13 Sep 2005 08:29:21 -0000
@@ -458,6 +458,9 @@
 		Uinstr0 = decr_sp(_),
 		Uinstr = Uinstr0
 	;
+		Uinstr0 = decr_sp_and_return(_),
+		Uinstr = Uinstr0
+	;
 		Uinstr0 = pragma_c(Decls, Components0, MayCallMercury,
 			MaybeLabel1, MaybeLabel2, MaybeLabel3, MaybeLabel4,
 			ReferStackSlot, MayDupl),
Index: compiler/jumpopt.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/jumpopt.m,v
retrieving revision 1.79
diff -u -b -r1.79 jumpopt.m
--- compiler/jumpopt.m	13 Sep 2005 08:25:29 -0000	1.79
+++ compiler/jumpopt.m	13 Sep 2005 08:29:21 -0000
@@ -774,6 +774,10 @@
         NewInstrs = [Instr0],
         RemainInstrs = Instrs0
     ;
+        Uinstr0 = decr_sp_and_return(_),
+        NewInstrs = [Instr0],
+        RemainInstrs = Instrs0
+    ;
         Uinstr0 = store_ticket(_),
         NewInstrs = [Instr0],
         RemainInstrs = Instrs0
Index: compiler/livemap.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/livemap.m,v
retrieving revision 1.67
diff -u -b -r1.67 livemap.m
--- compiler/livemap.m	13 Sep 2005 08:25:29 -0000	1.67
+++ compiler/livemap.m	14 Sep 2005 01:21:20 -0000
@@ -274,6 +274,11 @@
     ;
         Uinstr0 = decr_sp(_)
     ;
+        Uinstr0 = decr_sp_and_return(_),
+        % These instructions should be generated only *after* any optimizations
+        % that need livemaps have been run for the last time.
+        unexpected(this_file, "build_livemap_instr: decr_sp_and_return")
+    ;
         Uinstr0 = init_sync_term(_, _)
     ;
         Uinstr0 = fork(_, _, _)
Index: compiler/llds.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/llds.m,v
retrieving revision 1.317
diff -u -b -r1.317 llds.m
--- compiler/llds.m	13 Sep 2005 08:25:29 -0000	1.317
+++ compiler/llds.m	13 Sep 2005 08:29:22 -0000
@@ -382,6 +382,10 @@
     ;       decr_sp(int)
             % Decrement the det stack pointer.
 
+    ;       decr_sp_and_return(int)
+            % Pick up the return address from its slot in the stack frame,
+            % decrement the det stack pointer, and jump to the return address.
+
     ;       pragma_c(
                 pragma_c_decls          :: list(pragma_c_decl),
                 pragma_c_components     :: list(pragma_c_component),
Index: compiler/llds_out.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/llds_out.m,v
retrieving revision 1.257
diff -u -b -r1.257 llds_out.m
--- compiler/llds_out.m	13 Sep 2005 08:25:30 -0000	1.257
+++ compiler/llds_out.m	13 Sep 2005 08:29:22 -0000
@@ -1847,6 +1847,7 @@
     output_rval_decls(Rval, !DeclSet, !IO).
 output_instr_decls(_, incr_sp(_, _), !DeclSet, !IO).
 output_instr_decls(_, decr_sp(_), !DeclSet, !IO).
+output_instr_decls(_, decr_sp_and_return(_), !DeclSet, !IO).
 output_instr_decls(StackLayoutLabels, pragma_c(_, Comps, _, _,
         MaybeLayoutLabel, MaybeOnlyLayoutLabel, _, _, _), !DeclSet, !IO) :-
     (
@@ -2289,6 +2290,11 @@
 
 output_instruction(decr_sp(N), _, !IO) :-
     io__write_string("\tMR_decr_sp(", !IO),
+    io__write_int(N, !IO),
+    io__write_string(");\n", !IO).
+
+output_instruction(decr_sp_and_return(N), _, !IO) :-
+    io__write_string("\tMR_decr_sp_and_return(", !IO),
     io__write_int(N, !IO),
     io__write_string(");\n", !IO).
 
Index: compiler/middle_rec.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/middle_rec.m,v
retrieving revision 1.106
diff -u -b -r1.106 middle_rec.m
--- compiler/middle_rec.m	13 Sep 2005 08:25:30 -0000	1.106
+++ compiler/middle_rec.m	13 Sep 2005 08:29:23 -0000
@@ -485,6 +485,7 @@
     middle_rec__find_used_registers_rval(Rval, !Used).
 middle_rec__find_used_registers_instr(incr_sp(_, _), !Used).
 middle_rec__find_used_registers_instr(decr_sp(_), !Used).
+middle_rec__find_used_registers_instr(decr_sp_and_return(_), !Used).
 middle_rec__find_used_registers_instr(pragma_c(_, Components,
         _, _, _, _, _, _, _), !Used) :-
     middle_rec__find_used_registers_components(Components, !Used).
Index: compiler/opt_debug.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/opt_debug.m,v
retrieving revision 1.156
diff -u -b -r1.156 opt_debug.m
--- compiler/opt_debug.m	13 Sep 2005 08:25:31 -0000	1.156
+++ compiler/opt_debug.m	13 Sep 2005 08:29:23 -0000
@@ -748,6 +748,9 @@
         Instr = decr_sp(Size),
         Str = "decr_sp(" ++ int_to_string(Size) ++ ")"
     ;
+        Instr = decr_sp_and_return(Size),
+        Str = "decr_sp_and_return(" ++ int_to_string(Size) ++ ")"
+    ;
         Instr = init_sync_term(Lval, N),
         Str = "init_sync_term(" ++ dump_lval(Lval) ++ ", "
             ++ int_to_string(N) ++")"
Index: compiler/opt_util.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/opt_util.m,v
retrieving revision 1.134
diff -u -b -r1.134 opt_util.m
--- compiler/opt_util.m	13 Sep 2005 08:25:31 -0000	1.134
+++ compiler/opt_util.m	13 Sep 2005 08:29:23 -0000
@@ -824,6 +824,10 @@
         Uinstr0 = decr_sp(_),
         Need = no
     ;
+        % handled specially
+        Uinstr0 = decr_sp_and_return(_),
+        Need = no
+    ;
         Uinstr0 = pragma_c(_, _, _, _, _, _, _, _, _),
         Need = no
     ;
@@ -943,6 +947,7 @@
 can_instr_branch_away(prune_tickets_to(_), no).
 can_instr_branch_away(incr_sp(_, _), no).
 can_instr_branch_away(decr_sp(_), no).
+can_instr_branch_away(decr_sp_and_return(_), yes).
 can_instr_branch_away(init_sync_term(_, _), no).
 can_instr_branch_away(fork(_, _, _), yes).
 can_instr_branch_away(join_and_terminate(_), no).
@@ -1019,6 +1024,7 @@
 can_instr_fall_through(prune_tickets_to(_), yes).
 can_instr_fall_through(incr_sp(_, _), yes).
 can_instr_fall_through(decr_sp(_), yes).
+can_instr_fall_through(decr_sp_and_return(_), no).
 can_instr_fall_through(init_sync_term(_, _), yes).
 can_instr_fall_through(fork(_, _, _), no).
 can_instr_fall_through(join_and_terminate(_), no).
@@ -1065,6 +1071,7 @@
 can_use_livevals(prune_tickets_to(_), no).
 can_use_livevals(incr_sp(_, _), no).
 can_use_livevals(decr_sp(_), no).
+can_use_livevals(decr_sp_and_return(_), yes).
 can_use_livevals(init_sync_term(_, _), no).
 can_use_livevals(fork(_, _, _), no).
 can_use_livevals(join_and_terminate(_), no).
@@ -1128,6 +1135,12 @@
 instr_labels_2(prune_tickets_to(_), [], []).
 instr_labels_2(incr_sp(_, _), [], []).
 instr_labels_2(decr_sp(_), [], []).
+instr_labels_2(decr_sp_and_return(_), [], []) :-
+    % XXX decr_sp_and_return does refer to a code addr, but the code addr it
+    % refers to is the original succip (now in a stack slot), which is not
+    % necessarily the current succip. However, we introduce decr_sp_and_return
+    % so late that this predicate should never be invoked on such instructions.
+    unexpected(this_file, "instr_labels_2: decr_sp_and_return").
 instr_labels_2(init_sync_term(_, _), [], []).
 instr_labels_2(fork(Child, Parent, _), [Child, Parent], []).
 instr_labels_2(join_and_terminate(_), [], []).
@@ -1184,6 +1197,9 @@
 possible_targets(prune_tickets_to(_), [], []).
 possible_targets(incr_sp(_, _), [], []).
 possible_targets(decr_sp(_), [], []).
+possible_targets(decr_sp_and_return(_), [], []) :-
+    % See the comment in instr_labels_2.
+    unexpected(this_file, "possible_targets: decr_sp_and_return").
 possible_targets(init_sync_term(_, _), [], []).
 possible_targets(fork(Child, Parent, _), [Child, Parent], []).
 possible_targets(join_and_terminate(_), [], []).
@@ -1255,6 +1271,7 @@
 instr_rvals_and_lvals(prune_tickets_to(Rval), [Rval], []).
 instr_rvals_and_lvals(incr_sp(_, _), [], []).
 instr_rvals_and_lvals(decr_sp(_), [], []).
+instr_rvals_and_lvals(decr_sp_and_return(_), [], []).
 instr_rvals_and_lvals(init_sync_term(Lval, _), [], [Lval]).
 instr_rvals_and_lvals(fork(_, _, _), [], []).
 instr_rvals_and_lvals(join_and_terminate(Lval), [], [Lval]).
@@ -1399,6 +1416,7 @@
     count_temps_rval(Rval, !R, !F).
 count_temps_instr(incr_sp(_, _), !R, !F).
 count_temps_instr(decr_sp(_), !R, !F).
+count_temps_instr(decr_sp_and_return(_), !R, !F).
 count_temps_instr(init_sync_term(Lval, _), !R, !F) :-
     count_temps_lval(Lval, !R, !F).
 count_temps_instr(fork(_, _, _), !R, !F).
@@ -1837,6 +1855,7 @@
     ).
 replace_labels_instr(incr_sp(Size, Msg), _, _, incr_sp(Size, Msg)).
 replace_labels_instr(decr_sp(Size), _, _, decr_sp(Size)).
+replace_labels_instr(decr_sp_and_return(Size), _, _, decr_sp_and_return(Size)).
 replace_labels_instr(init_sync_term(T, N), _, _,
         init_sync_term(T, N)).
 replace_labels_instr(fork(Child0, Parent0, SlotCount), Replmap, _,
Index: compiler/optimize.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/optimize.m,v
retrieving revision 1.48
diff -u -b -r1.48 optimize.m
--- compiler/optimize.m	7 Sep 2005 06:51:56 -0000	1.48
+++ compiler/optimize.m	14 Sep 2005 01:11:41 -0000
@@ -539,6 +539,17 @@
         DelaySlot = no
     ),
     (
+        VeryVerbose = yes,
+        io__write_string("% Optimizing returns for ", !IO),
+        io__write_string(LabelStr, !IO),
+        io__write_string("\n", !IO)
+    ;
+        VeryVerbose = no
+    ),
+    combine_decr_sp(!Instrs),
+    optimize__maybe_opt_debug(!.Instrs, C, "after combine decr_sp",
+        ProcLabel, !OptDebugInfo, !IO),
+    (
         UseLocalVars = yes,
         (
             VeryVerbose = yes,
Index: compiler/peephole.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/peephole.m,v
retrieving revision 1.84
diff -u -b -r1.84 peephole.m
--- compiler/peephole.m	7 Sep 2005 06:51:56 -0000	1.84
+++ compiler/peephole.m	13 Sep 2005 04:17:07 -0000
@@ -27,6 +27,8 @@
 :- 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.
+
 :- implementation.
 
 :- import_module backend_libs__builtin_ops.
@@ -79,10 +81,12 @@
         opt_util__skip_comments(Instrs0, Instrs1),
         peephole__match(Instr0, Comment0, InvalidPatterns, Instrs1, Instrs2)
     ->
-        ( Instrs2 = [Instr2 - Comment2 | Instrs3] ->
+        (
+            Instrs2 = [Instr2 - Comment2 | Instrs3],
             peephole__opt_instr(Instr2, Comment2, InvalidPatterns,
                 Instrs3, Instrs, _)
         ;
+            Instrs2 = [],
             Instrs = Instrs2
         ),
         Mod = yes
@@ -384,3 +388,21 @@
     ).
 
 %-----------------------------------------------------------------------------%
+
+combine_decr_sp([], []).
+combine_decr_sp([Instr0 | Instrs0], Instrs) :-
+    combine_decr_sp(Instrs0, Instrs1),
+    (
+        Instr0 = assign(succip, lval(stackvar(N))) - _,
+        opt_util__skip_comments_livevals(Instrs1, Instrs2),
+        Instrs2 = [Instr2 | Instrs3],
+        Instr2 = decr_sp(N) - _,
+        opt_util__skip_comments_livevals(Instrs3, Instrs4),
+        Instrs4 = [Instr4 | Instrs5],
+        Instr4 = goto(succip) - Comment
+    ->
+        NewInstr = decr_sp_and_return(N) - Comment,
+        Instrs = [NewInstr | Instrs5]
+    ;
+        Instrs = [Instr0 | Instrs1]
+    ).
Index: compiler/reassign.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/reassign.m,v
retrieving revision 1.11
diff -u -b -r1.11 reassign.m
--- compiler/reassign.m	13 Sep 2005 08:25:32 -0000	1.11
+++ compiler/reassign.m	13 Sep 2005 08:40:30 -0000
@@ -109,6 +109,7 @@
 :- implementation.
 
 :- import_module ll_backend__code_util.
+:- import_module parse_tree__error_util.
 
 :- import_module map.
 :- import_module require.
@@ -142,27 +143,24 @@
         !:RevInstrs = [Instr0 | !.RevInstrs]
     ;
         Uinstr0 = block(_, _, _),
-        error("remove_reassign_loop: block")
+        unexpected(this_file, "remove_reassign_loop: block")
     ;
         Uinstr0 = assign(Target, Source),
         (
             map__search(!.KnownContentsMap, Target, KnownContents),
             KnownContents = Source
         ->
-            % By not including Instr0 in !RevInstrs, we are deleting it.
+            % By not including Instr0 in !:RevInstrs, we are deleting Instr0.
             true
         ;
             !:RevInstrs = [Instr0 | !.RevInstrs],
             clobber_dependents(Target, !KnownContentsMap, !DepLvalMap),
             (
-                % For Targets of the following form, the code
-                % generator ensures that the storage location
-                % referred to by Target can only be updated
-                % through the Target lval, and not through
-                % some other lval, unless one uses mem_addr to
-                % explicitly create an alias and mem_ref to
-                % access the memory location via that alias.
-
+                % For Targets of the following form, the code generator ensures
+                % that the storage location referred to by Target can only be
+                % updated through the Target lval, and not through some other
+                % lval, unless one uses mem_addr to explicitly create an alias
+                % and mem_ref to access the memory location via that alias.
                 no_implicit_alias_target(Target)
             ->
                 record_known(Target, Source, !KnownContentsMap, !DepLvalMap)
@@ -184,24 +182,22 @@
     ;
         Uinstr0 = label(_),
         !:RevInstrs = [Instr0 | !.RevInstrs],
-            % We don't know what is stored where at the
-            % instructions that jump here.
+        % We don't know what is stored where at the instructions that
+        % jump here.
         !:KnownContentsMap = map__init,
         !:DepLvalMap = map__init
     ;
         Uinstr0 = goto(_),
         !:RevInstrs = [Instr0 | !.RevInstrs],
-            % The value of KnownContentsMap doesn't really matter
-            % since the next instruction (which must be a label)
-            % will reset it to empty anyway.
+        % The value of !:KnownContentsMap doesn't really matter since the next
+        % instruction (which must be a label) will reset it to empty anyway.
         !:KnownContentsMap = map__init,
         !:DepLvalMap = map__init
     ;
         Uinstr0 = computed_goto(_, _),
         !:RevInstrs = [Instr0 | !.RevInstrs],
-            % The value of KnownContentsMap doesn't really matter
-            % since the next instruction (which must be a label)
-            % will reset it to empty anyway.
+        % The value of !:KnownContentsMap doesn't really matter since the next
+        % instruction (which must be a label) will reset it to empty anyway.
         !:KnownContentsMap = map__init,
         !:DepLvalMap = map__init
     ;
@@ -237,8 +233,8 @@
     ;
         Uinstr0 = free_heap(_),
         !:RevInstrs = [Instr0 | !.RevInstrs]
-        % There is no need to update KnownContentsMap since
-        % later code should never refer to the freed cell.
+        % There is no need to update KnownContentsMap since later code
+        % should never refer to the freed cell.
     ;
         Uinstr0 = store_ticket(Target),
         !:RevInstrs = [Instr0 | !.RevInstrs],
@@ -264,23 +260,26 @@
         !:RevInstrs = [Instr0 | !.RevInstrs]
 %   ;
 %       Uinstr0 = discard_tickets_to(_),
-%       !:RevInstrs = [Instr0 | !.RevInstrs],
-%       !:KnownContentsMap = KnownContentsMap0,
-%       !:DepLvalMap = DepLvalMap0
+%       !:RevInstrs = [Instr0 | !.RevInstrs]
     ;
         Uinstr0 = incr_sp(_, _),
         !:RevInstrs = [Instr0 | !.RevInstrs],
-            % All stackvars now refer to new locations.
-            % Rather than delete only stackvars from
-            % KnownContentsMap0, we delete everything.
+        % All stackvars now refer to new locations. Rather than delete
+        % only stackvars from KnownContentsMap, we delete everything.
         !:KnownContentsMap = map__init,
         !:DepLvalMap = map__init
     ;
         Uinstr0 = decr_sp(_),
         !:RevInstrs = [Instr0 | !.RevInstrs],
-            % All stackvars now refer to new locations.
-            % Rather than delete only stackvars from
-            % KnownContentsMap0, we delete everything.
+        % All stackvars now refer to new locations. Rather than delete
+        % only stackvars from KnownContentsMap, we delete everything.
+        !:KnownContentsMap = map__init,
+        !:DepLvalMap = map__init
+    ;
+        Uinstr0 = decr_sp_and_return(_),
+        !:RevInstrs = [Instr0 | !.RevInstrs],
+        % All stackvars now refer to new locations. Rather than delete
+        % only stackvars from KnownContentsMap, we delete everything.
         !:KnownContentsMap = map__init,
         !:DepLvalMap = map__init
     ;
@@ -296,19 +295,17 @@
     ;
         Uinstr0 = fork(_, _, _),
         !:RevInstrs = [Instr0 | !.RevInstrs],
-            % Both the parent and the child thread jump to labels
-            % specified by the fork instruction, so the value of
-            % KnownContentsMap doesn't really matter since the
-            % next instruction (which must be a label) will
-            % reset it to empty anyway.
+        % Both the parent and the child thread jump to labels specified
+        % by the fork instruction, so the value of !:KnownContentsMap doesn't
+        % really matter since the next instruction (which must be a label)
+        % will reset it to empty anyway.
         !:KnownContentsMap = map__init,
         !:DepLvalMap = map__init
     ;
         Uinstr0 = join_and_terminate(_),
         !:RevInstrs = [Instr0 | !.RevInstrs],
-            % The value of KnownContentsMap doesn't really matter
-            % since this instruction terminates the execution of
-            % this thread.
+        % The value of KnownContentsMap doesn't really matter since this
+        % instruction terminates the execution of this thread.
         !:KnownContentsMap = map__init,
         !:DepLvalMap = map__init
     ;
@@ -321,9 +318,9 @@
     remove_reassign_loop(Instrs0, !.KnownContentsMap, !.DepLvalMap,
         !RevInstrs).
 
-    % Succeed iff the lval cannot have an alias created for it without
-    % the use of a mem_ref lval or an instruction with embedded C code,
-    % both of which cause us to clobber the known contents map.
+    % Succeed iff the lval cannot have an alias created for it without the
+    % use of a mem_ref lval or an instruction with embedded C code, both of
+    % which cause us to clobber the known contents map.
     %
 :- pred no_implicit_alias_target(lval::in) is semidet.
 
@@ -342,13 +339,12 @@
     ;
         true
     ),
-        % LLDS code can refer to arbitrary locations on the stack
-        % or in the heap with mem_ref lvals. Since we don't keep track
-        % of which locations have their addresses taken, on any
-        % assignment through a mem_ref lval we throw way the known
-        % contents map. This is a conservative approximation of the
-        % desired behaviour, which would invalidate only the entries
-        % of lvals that may be referred to via this mem_ref.
+    % LLDS code can refer to arbitrary locations on the stack or in the heap
+    % with mem_ref lvals. Since we don't keep track of which locations have
+    % their addresses taken, on any assignment through a mem_ref lval we throw
+    % way the known contents map. This is a conservative approximation of the
+    % desired behaviour, which would invalidate only the entries of lvals
+    % that may be referred to via this mem_ref.
     code_util__lvals_in_rval(lval(Target), SubLvals),
     (
         list__member(SubLval, SubLvals),
@@ -378,8 +374,8 @@
         % or its converse.
         true
     ;
-        record_known_lval_rval(TargetLval, SourceRval, !KnownContentsMap,
-            !DepLvalMap),
+        record_known_lval_rval(TargetLval, SourceRval,
+            !KnownContentsMap, !DepLvalMap),
         ( SourceRval = lval(SourceLval) ->
             record_known_lval_rval(SourceLval, lval(TargetLval),
                 !KnownContentsMap, !DepLvalMap)
@@ -434,3 +430,11 @@
         DepLvals = set__make_singleton_set(Target),
         svmap__det_insert(SubLval, DepLvals, !DepLvalMap)
     ).
+
+%-----------------------------------------------------------------------------%
+
+:- func this_file = string.
+
+this_file = "reassign.m".
+
+%-----------------------------------------------------------------------------%
Index: compiler/use_local_vars.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/compiler/use_local_vars.m,v
retrieving revision 1.16
diff -u -b -r1.16 use_local_vars.m
--- compiler/use_local_vars.m	13 Sep 2005 08:25:32 -0000	1.16
+++ compiler/use_local_vars.m	13 Sep 2005 08:29:24 -0000
@@ -436,8 +436,7 @@
 
 :- pred substitute_lval_in_instr_until_defn_2(lval::in, lval::in,
     instruction::in, instruction::out,
-    list(instruction)::in, list(instruction)::out,
-    int::in, int::out) is det.
+    list(instruction)::in, list(instruction)::out, int::in, int::out) is det.
 
 substitute_lval_in_instr_until_defn_2(OldLval, NewLval, !Instr, !Instrs, !N) :-
     !.Instr = Uinstr0 - _,
@@ -512,6 +511,8 @@
     ;
         Uinstr0 = decr_sp(_)
     ;
+        Uinstr0 = decr_sp_and_return(_)
+    ;
         Uinstr0 = init_sync_term(_, _)
     ;
         Uinstr0 = fork(_, _, _)
@@ -530,3 +531,5 @@
 :- func this_file = string.
 
 this_file = "use_local_vars.m".
+
+%-----------------------------------------------------------------------------%
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/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/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/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/logged_output
cvs diff: Diffing extras/moose
cvs diff: Diffing extras/moose/samples
cvs diff: Diffing extras/moose/tests
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/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/trailed_update
cvs diff: Diffing extras/trailed_update/samples
cvs diff: Diffing extras/trailed_update/tests
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
Index: runtime/mercury_stacks.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_stacks.h,v
retrieving revision 1.51
diff -u -b -r1.51 mercury_stacks.h
--- runtime/mercury_stacks.h	13 Sep 2005 08:25:39 -0000	1.51
+++ runtime/mercury_stacks.h	13 Sep 2005 12:34:19 -0000
@@ -112,21 +112,33 @@
 #define MR_stackvar(n)                  MR_based_stackvar(MR_sp, (n))
 #define MR_sv(n)                        MR_stackvar(n)
 
-#define MR_incr_sp(n)   (                                                     \
-                MR_debugincrsp(n, MR_sp),                                     \
-                MR_sp_word = (MR_Word) (MR_sp + (n)),                         \
-                MR_detstack_extend_check(),                                   \
-                MR_detstack_overflow_check(),                                 \
-                MR_collect_det_frame_stats(n),                                \
-                (void) 0                                                      \
-            )
+#define MR_incr_sp(n)                                                         \
+    do {                                                                      \
+        MR_debugincrsp(n, MR_sp);                                             \
+        MR_sp_word = (MR_Word) (MR_sp + (n));                                 \
+        MR_detstack_extend_check();                                           \
+        MR_detstack_overflow_check();                                         \
+        MR_collect_det_frame_stats(n);                                        \
+    } while (0)
 
-#define MR_decr_sp(n)   (                                                     \
-                MR_debugdecrsp(n, MR_sp),                                     \
-                MR_sp_word = (MR_Word) (MR_sp - (n)),                         \
-                MR_detstack_underflow_check(),                                \
-                (void) 0                                                      \
-            )
+#define MR_decr_sp(n)                                                         \
+    do {                                                                      \
+        MR_debugdecrsp(n, MR_sp);                                             \
+        MR_sp_word = (MR_Word) (MR_sp - (n));                                 \
+        MR_detstack_underflow_check();                                        \
+    } while (0)
+
+#define MR_decr_sp_and_return(n)                                              \
+    do {                                                                      \
+        MR_Code *return_addr;                                                 \
+                                                                              \
+        return_addr = (MR_Word *) MR_stackvar(n);                             \
+        MR_debugdecrsp(n, MR_sp);                                             \
+        MR_sp_word = (MR_Word) (MR_sp - (n));                                 \
+        MR_detstack_underflow_check();                                        \
+        MR_debugproceed();                                                    \
+        MR_GOTO(return_addr);                                                 \
+    } while (0)
 
 /*
 ** The msg argument of MR_incr_sp_push_msg is not used at runtime. It is
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/recompilation
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 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:  mercury-reviews at cs.mu.oz.au
administrative address: owner-mercury-reviews at cs.mu.oz.au
unsubscribe: Address: mercury-reviews-request at cs.mu.oz.au Message: unsubscribe
subscribe:   Address: mercury-reviews-request at cs.mu.oz.au Message: subscribe
--------------------------------------------------------------------------



More information about the reviews mailing list