[m-dev.] for review: fix bug in unique mode checking
Fergus Henderson
fjh at cs.mu.OZ.AU
Fri Apr 9 05:50:33 AEST 1999
On 09-Apr-1999, Fergus Henderson <fjh at cs.mu.OZ.AU> wrote:
> tests/hard_coded/Mmakefile:
> Disable the test case bidirectional.m, since the compiler now
> rejects it, due to the above change to unique_modes.m.
> The compiler is again being overly conservative in its analysis.
> The problem is similar to that in the two test cases above,
> unfortunately there is no easy work-around in this case.
> The compiler really ought to support this style of bidirectional
> code using unique modes, so I do consider this to be a significant
> problem, but the fix is a fair bit of work, so I will deal with
> that as a separate change.
Actually it turned out to be not so difficult after all.
I think I will still commit it as a separate change, though.
Could someone please review this one too?
--------------------
Estimated hours taken: 1
Perform some minor simplifications in mode analysis,
so as to provide more information to unique mode analysis.
Previously unique_modes.m was reporting spurious errors
for tests/hard_coded/bidirectional.m, because modes.m
produced output containing a subgoal of the form
`disj([Goal, conj([disj([])]])' instead of just `Goal',
and the presence of a disjunction then caused unique mode
analysis to make overly conservative assumptions.
compiler/modes.m:
Ensure that we do not produce singleton conjunctions or disjunctions.
Also, if the result of mode checking a disjunct is a (nested)
disjunction, then merge it with the containing disjunction.
If the nested disjunction is the empty disjunction (fail),
then this means it will be deleted.
tests/hard_coded/Mmakefile:
Re-enable the test case bidirectional.m, since the compiler now
accepts it, due to the above change.
Index: compiler/modes.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/modes.m,v
retrieving revision 1.228
diff -u -r1.228 modes.m
--- modes.m 1998/11/20 04:08:33 1.228
+++ modes.m 1999/04/08 19:39:54
@@ -925,12 +925,13 @@
compute_instmap_delta(InstMap0, InstMap, NonLocals, DeltaInstMap),
goal_info_set_instmap_delta(GoalInfo0, DeltaInstMap, GoalInfo).
-modecheck_goal_expr(conj(List0), _GoalInfo0, conj(List)) -->
+modecheck_goal_expr(conj(List0), GoalInfo0, Goal) -->
mode_checkpoint(enter, "conj"),
( { List0 = [] } -> % for efficiency, optimize common case
- { List = [] }
+ { Goal = conj([]) }
;
- modecheck_conj_list(List0, List)
+ modecheck_conj_list(List0, List),
+ { conj_list_to_goal(List, GoalInfo0, Goal - _GoalInfo) }
),
mode_checkpoint(exit, "conj").
@@ -961,16 +962,17 @@
instmap__unify(NonLocals, InstMapNonlocalList),
mode_checkpoint(exit, "par_conj").
-modecheck_goal_expr(disj(List0, SM), GoalInfo0, disj(List, SM)) -->
+modecheck_goal_expr(disj(List0, SM), GoalInfo0, Goal) -->
mode_checkpoint(enter, "disj"),
( { List0 = [] } -> % for efficiency, optimize common case
- { List = [] },
+ { Goal = disj(List0, SM) },
{ instmap__init_unreachable(InstMap) },
mode_info_set_instmap(InstMap)
;
{ goal_info_get_nonlocals(GoalInfo0, NonLocals) },
modecheck_disj_list(List0, List, InstMapList),
- instmap__merge(NonLocals, InstMapList, disj)
+ instmap__merge(NonLocals, InstMapList, disj),
+ { disj_list_to_goal(List, GoalInfo0, Goal - _GoalInfo) }
),
mode_checkpoint(exit, "disj").
@@ -1450,12 +1452,19 @@
:- mode modecheck_disj_list(in, out, out, mode_info_di, mode_info_uo) is det.
modecheck_disj_list([], [], []) --> [].
-modecheck_disj_list([Goal0 | Goals0], [Goal | Goals], [InstMap | InstMaps]) -->
+modecheck_disj_list([Goal0 | Goals0], Goals, [InstMap | InstMaps]) -->
mode_info_dcg_get_instmap(InstMap0),
modecheck_goal(Goal0, Goal),
mode_info_dcg_get_instmap(InstMap),
mode_info_set_instmap(InstMap0),
- modecheck_disj_list(Goals0, Goals, InstMaps).
+ modecheck_disj_list(Goals0, Goals1, InstMaps),
+ %
+ % If Goal is a nested disjunction,
+ % then merge it with the outer disjunction.
+ % If Goal is `fail', this will delete it.
+ %
+ { goal_to_disj_list(Goal, DisjList) },
+ { list__append(DisjList, Goals1, Goals) }.
:- pred modecheck_case_list(list(case), prog_var, list(case), list(instmap),
mode_info, mode_info).
Index: tests/hard_coded/Mmakefile
===================================================================
RCS file: /home/mercury1/repository/tests/hard_coded/Mmakefile,v
retrieving revision 1.55
diff -u -r1.55 Mmakefile
--- Mmakefile 1999/03/26 04:34:14 1.55
+++ Mmakefile 1999/04/08 17:18:29
@@ -9,7 +9,6 @@
PROGS= \
address_of_builtins \
agg \
+ bidirectional \
bigtest \
boyer \
c_write_string \
@@ -94,6 +93,8 @@
# we do no pass the following tests
# var_not_found -- "sorry, not implemented" in polymorphism.m.
-# bidirectional -- unique mode analysis is overly conservative
-# and thus rejects this test case.
#-----------------------------------------------------------------------------#
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3 | -- the last words of T. S. Garp.
More information about the developers
mailing list