[m-rev.] for review: fix delay death and parallel conjunctions

Peter Wang wangp at students.cs.mu.OZ.AU
Fri Jun 30 21:56:15 AEST 2006


Estimated hours taken: 6
Branches: main

compiler/liveness.m:
	Fix the deadness pass's handling of parallel conjunctions.
	This was causing problems with later passes (delay death and resume
	point detection) because variables were appearing in the pre-death
	and post-death sets that they shouldn't have.

	Also make detect_deadness_in_par_conj look more similar to
	detect_deadness_in_disj and detect_deadness_in_cases.

	Revert the previous change to delay_death_par_conj which was
	unnecessary and caused problems with nested parallel conjunctions and
	--delay-death.

tests/par_conj/Mercury.options:
tests/par_conj/Mmakefile:
tests/par_conj/par_ddeath.exp:
tests/par_conj/par_ddeath.m:
tests/par_conj/par_ddeath_2.exp:
tests/par_conj/par_ddeath_2.m:
	Add test cases.


Index: compiler/liveness.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/liveness.m,v
retrieving revision 1.146
diff -u -r1.146 liveness.m
--- compiler/liveness.m	28 Jun 2006 04:46:14 -0000	1.146
+++ compiler/liveness.m	30 Jun 2006 08:46:33 -0000
@@ -544,8 +544,9 @@
             _, CompletedNonLocals),
         set.init(Union0),
         detect_deadness_in_par_conj(Goals0, Goals, !.Deadness, Liveness0,
-            CompletedNonLocals, LiveInfo, Union0, Union),
-        set.union(Union, !Deadness)
+            CompletedNonLocals, LiveInfo, Union0, Union,
+            _CompletedNonLocalUnion),
+        !:Deadness = Union
     ).
 
 detect_deadness_in_goal_2(disj(Goals0), disj(Goals), GoalInfo, !Deadness,
@@ -732,20 +733,30 @@
 
 :- pred detect_deadness_in_par_conj(list(hlds_goal)::in, list(hlds_goal)::out,
     set(prog_var)::in, set(prog_var)::in, set(prog_var)::in, live_info::in,
-    set(prog_var)::in, set(prog_var)::out) is det.
+    set(prog_var)::in, set(prog_var)::out, set(prog_var)::out) is det.
 
-detect_deadness_in_par_conj([], [], _Deadness0, _Liveness0, _NonLocals,
-        _LiveInfo, !Union).
+detect_deadness_in_par_conj([], [], _Deadness0, _Liveness0, CompletedNonLocals,
+        _LiveInfo, !Union, CompletedNonLocalUnion) :-
+    set.intersect(!.Union, CompletedNonLocals, CompletedNonLocalUnion).
 detect_deadness_in_par_conj([Goal0 | Goals0], [Goal | Goals], Deadness0,
-        Liveness0, NonLocals, LiveInfo, !Union) :-
-    detect_deadness_in_goal(Goal0, Goal1, Deadness0, Deadness1,
+        Liveness0, CompletedNonLocals, LiveInfo, !Union,
+        CompletedNonLocalUnion) :-
+    detect_deadness_in_goal(Goal0, Goal1, Deadness0, DeadnessGoal,
         Liveness0, LiveInfo),
-    set.union(Deadness1, !Union),
+    set.union(DeadnessGoal, !Union),
     detect_deadness_in_par_conj(Goals0, Goals, Deadness0,
-        Liveness0, NonLocals, LiveInfo, !Union),
-    set.intersect(!.Union, NonLocals, NonLocalUnion),
-    set.difference(NonLocalUnion, Deadness1, Residue),
-    add_deadness_before_goal(Residue, Goal1, Goal).
+        Liveness0, CompletedNonLocals, LiveInfo, !Union,
+        CompletedNonLocalUnion),
+    Goal1 = _ - GoalInfo1,
+    goal_info_get_instmap_delta(GoalInfo1, InstmapDelta1),
+    ( instmap_delta_is_reachable(InstmapDelta1) ->
+        InstmapReachable = yes
+    ;
+        unexpected(this_file,
+            "detect_deadness_in_par_conj: unreachable instmap")
+    ),
+    add_branch_pre_deaths(DeadnessGoal, Deadness0, CompletedNonLocalUnion,
+        InstmapReachable, Goal1, Goal).
 
 %-----------------------------------------------------------------------------%
 
@@ -995,7 +1006,14 @@
         !.GoalExpr = foreign_proc(_, _, _, _, _, _)
     ;
         !.GoalExpr = conj(ConjType, Goals0),
-        delay_death_conj(Goals0, Goals, !BornVars, !DelayedDead, VarSet),
+        (
+            ConjType = plain_conj,
+            delay_death_conj(Goals0, Goals, !BornVars, !DelayedDead, VarSet)
+        ;
+            ConjType = parallel_conj,
+            delay_death_par_conj(Goals0, Goals, !BornVars, !DelayedDead,
+                VarSet)
+        ),
         !:GoalExpr = conj(ConjType, Goals)
     ;
         !.GoalExpr = disj(Goals0),
@@ -1066,6 +1084,20 @@
     delay_death_goal(Goal0, Goal, !BornVars, !DelayedDead, VarSet),
     delay_death_conj(Goals0, Goals, !BornVars, !DelayedDead, VarSet).
 
+:- pred delay_death_par_conj(list(hlds_goal)::in, list(hlds_goal)::out,
+    set(prog_var)::in, set(prog_var)::out,
+    set(prog_var)::in, set(prog_var)::out, prog_varset::in) is det.
+
+delay_death_par_conj([], [], !BornVars, !DelayedDead, _).
+delay_death_par_conj([Goal0 | Goals0], [Goal | Goals],
+        BornVars0, BornVars, DelayedDead0, DelayedDead, VarSet) :-
+    delay_death_goal(Goal0, Goal, BornVars0, BornVarsGoal,
+        DelayedDead0, DelayedDeadGoal, VarSet),
+    delay_death_par_conj(Goals0, Goals, BornVars0, BornVarsGoals,
+        DelayedDead0, DelayedDeadGoals, VarSet),
+    set.union(BornVarsGoal, BornVarsGoals, BornVars),
+    set.union(DelayedDeadGoal, DelayedDeadGoals, DelayedDead).
+
 :- pred delay_death_disj(list(hlds_goal)::in,
     assoc_list(hlds_goal, set(prog_var))::out,
     set(prog_var)::in, set(prog_var)::in, prog_varset::in,
Index: tests/par_conj/Mercury.options
===================================================================
RCS file: /home/mercury1/repository/tests/par_conj/Mercury.options,v
retrieving revision 1.1
diff -u -r1.1 Mercury.options
--- tests/par_conj/Mercury.options	28 Jun 2006 06:13:12 -0000	1.1
+++ tests/par_conj/Mercury.options	30 Jun 2006 04:38:04 -0000
@@ -0,0 +1,2 @@
+MCFLAGS-par_ddeath = --trace deep
+MCFLAGS-par_ddeath_2 = --trace deep
Index: tests/par_conj/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/par_conj/Mmakefile,v
retrieving revision 1.2
diff -u -r1.2 Mmakefile
--- tests/par_conj/Mmakefile	29 Jun 2006 03:53:34 -0000	1.2
+++ tests/par_conj/Mmakefile	30 Jun 2006 08:37:05 -0000
@@ -36,11 +36,13 @@
 	dep_par_20 \
 	dep_par_21 \
 	dep_par_22 \
-	dep_par_23
+	dep_par_23 \
+	par_ddeath
 
 INDEP_PAR_CONJ_PROGS = \
 	indep_par_append \
 	indep_par_nested \
+	par_ddeath \
 	threads_hang
 
 ifneq "$(findstring decldebug,$(GRADE))" ""
Index: tests/par_conj/par_ddeath.exp
===================================================================
RCS file: tests/par_conj/par_ddeath.exp
diff -N tests/par_conj/par_ddeath.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/par_ddeath.exp	30 Jun 2006 04:25:18 -0000
@@ -0,0 +1 @@
+100
Index: tests/par_conj/par_ddeath.m
===================================================================
RCS file: tests/par_conj/par_ddeath.m
diff -N tests/par_conj/par_ddeath.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/par_ddeath.m	30 Jun 2006 11:42:42 -0000
@@ -0,0 +1,30 @@
+% There was a problem with this file when --trace deep was used,
+% due to a bug in the --delay-death pass.
+% 
+% Uncaught Mercury exception:
+% Software Error: map.lookup: key not found
+%         Key Type: term.var(parse_tree.prog_data.prog_var_type)
+%         Key Value: var(6)
+%         Value Type: ll_backend.var_locn.var_state
+
+:- module par_ddeath.
+:- interface.
+:- import_module io.
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+:- import_module int.
+
+main(IO0, IO) :-
+    (
+        A = 100,
+        (
+            C = A
+        &
+	    true
+        )
+    &
+        true
+    ),
+    io.write_int(C, IO0, IO1),
+    io.nl(IO1, IO).
Index: tests/par_conj/par_ddeath_2.exp
===================================================================
RCS file: tests/par_conj/par_ddeath_2.exp
diff -N tests/par_conj/par_ddeath_2.exp
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/par_ddeath_2.exp	30 Jun 2006 08:39:05 -0000
@@ -0,0 +1 @@
+[0, 1, 2, 3, 4, 5]
Index: tests/par_conj/par_ddeath_2.m
===================================================================
RCS file: tests/par_conj/par_ddeath_2.m
diff -N tests/par_conj/par_ddeath_2.m
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ tests/par_conj/par_ddeath_2.m	30 Jun 2006 07:13:14 -0000
@@ -0,0 +1,29 @@
+% With --trace deep --parallel
+%
+% Uncaught Mercury exception:
+% Software Error: liveness.m: Unexpected: branches of if-then-else disagree on liveness
+% First: Low High Result
+% Rest:  Low High
+
+:- module par_ddeath_2.
+:- interface.
+:- import_module io.
+:- pred main(io::di, io::uo) is det.
+
+:- implementation.
+:- import_module int, list.
+
+main(!IO) :-
+    integers(0, 5, R),
+    io.print(R, !IO),
+    io.nl(!IO).
+
+:- pred integers(int::in, int::in, list(int)::out) is det.
+
+integers(Low, High, Result) :- 
+    ( Low =< High ->
+	integers(Low+1, High, Rest) &
+	Result = [Low | Rest]
+    ;
+	Result = []
+    ).
--------------------------------------------------------------------------
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