[m-rev.] fix det unification regression
Fergus Henderson
fjh at cs.mu.OZ.AU
Thu Feb 12 15:05:00 AEDT 2004
Estimated hours taken: 3
Branches: main
Fix a recently introduced bug which caused the compiler to sometimes report
determinism errors in automatically-generated unification procedures.
compiler/unify_proc.m:
Disable the optimization to the way that we generate clauses for
unification procedures which Zoltan added recently, because it
breaks determinism analysis.
tests/general/Mmakefile.
tests/general/det_complicated_unify2.m:
tests/general/det_complicated_unify2.exp:
Add a new test case showing the problem. This is a variant of
det_complicated_unify.m in which the type involved is a d.u. type
rather than an enumeration. Mercury 0.11 passes this test case,
Zoltan's change broke it, and the patch to unify_proc.m above
ensures that we pass it again.
Workspace: /home/ceres/fjh/mercury
Index: compiler/unify_proc.m
===================================================================
RCS file: /home/mercury1/repository/mercury/compiler/unify_proc.m,v
retrieving revision 1.131
diff -u -d -r1.131 unify_proc.m
--- compiler/unify_proc.m 15 Jan 2004 07:36:18 -0000 1.131
+++ compiler/unify_proc.m 12 Feb 2004 03:55:41 -0000
@@ -1171,10 +1171,23 @@
% __Unify__(X, Y) :-
% (
% X = a1,
+% #if 0
% Y = X
+% % Actually, to avoid infinite recursion,
+% % the above unification is done as type int:
+% % CastX = unsafe_cast(X) `with_type` int,
+% % CastY = unsafe_cast(Y) `with_type` int,
+% % CastX = CastY
+% #else
+% Y = a1
+% #endif
% ;
% X = a2,
-% Y = X
+% #if 0
+% Y = X % Likewise, done as type int
+% #else
+% Y = a2
+% #endif
% ;
% X = b(X1),
% Y = b(Y2),
@@ -1191,12 +1204,21 @@
% X3 = Y3
% ).
%
-% Note that in the disjuncts handling constants, we want to unify Y with X,
-% not with the constant. This allows dupelim to take the code fragments
-% implementing the switch arms for constants and eliminate all but one of them.
+% Note that in the disjuncts handling constants, we want to unify Y with X
+% (as shown in the "#if 0 ... #else" parts), not with the constant
+% (as shown in the "#else" ... "#endif" parts).
+% Doing this allows dupelim to take the code fragments implementing
+% the switch arms for constants and eliminate all but one of them.
% This can be a significant code size saving for types with lots of constants,
% such as the one representing Aditi bytecodes, which can lead to significant
% reductions in C compilation time.
+% XXX But the optimization doesn't work, because it breaks determinism
+% analysis. In particular, if X and Y both have insts `bound(a2)', then
+% determinism analysis will infer that the unification can't fail and thus
+% that the procedure is det, but casting to int loses the binding information,
+% and so mode and determinism analysis can't tell that CastX = CastY is det.
+% (See e.g. tests/general/det_complicated_unify2.m.)
+% Hence this optimization is currently disabled.
:- pred unify_proc__generate_du_unify_clauses(list(constructor), prog_var,
prog_var, prog_context, list(clause),
@@ -1211,6 +1233,8 @@
list__length(ArgTypes, FunctorArity),
FunctorConsId = cons(FunctorName, FunctorArity),
(
+ % XXX This optimization disabled, see XXX comment above.
+ semidet_fail,
ArgTypes = [],
can_compare_constants_as_ints(!.Info) = yes
->
Index: tests/general/det_complicated_unify2.exp
===================================================================
RCS file: tests/general/det_complicated_unify2.exp
diff -N tests/general/det_complicated_unify2.exp
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/general/det_complicated_unify2.exp 12 Feb 2004 04:02:08 -0000
@@ -0,0 +1 @@
+worked
Index: tests/general/det_complicated_unify2.m
===================================================================
RCS file: tests/general/det_complicated_unify2.m
diff -N tests/general/det_complicated_unify2.m
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ tests/general/det_complicated_unify2.m 12 Feb 2004 03:45:16 -0000
@@ -0,0 +1,30 @@
+% This tests that the compiler handles deterministic complicated
+% unifications on enums and compound types correctly.
+% (Version 0.4 of the compiler failed this test.)
+
+:- module det_complicated_unify2.
+:- interface.
+:- import_module io.
+
+:- pred main(io__state::di, io__state::uo) is det.
+
+:- implementation.
+
+:- type foo ---> foo(bar).
+:- type foo2 ---> foo2(bar) ; yyy(int).
+:- type bar ---> bar ; zzz(int).
+
+main -->
+ { p(foo(bar),foo(bar)), p2(foo2(bar),foo2(bar)), q(bar, bar) },
+ io__write_string("worked\n").
+
+:- pred p(foo::in(bound(foo(bound(bar)))), foo::in(bound(foo(bound(bar)))))
+ is det.
+p(X, X).
+
+:- pred p2(foo2::in(bound(foo2(bound(bar)))),
+ foo2::in(bound(foo2(bound(bar))))) is det.
+p2(X, X).
+
+:- pred q(bar::in(bound(bar)), bar::in(bound(bar))) is det.
+q(X, X).
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
The University of Melbourne | of excellence is a lethal habit"
WWW: <http://www.cs.mu.oz.au/~fjh> | -- the last words of T. S. Garp.
--------------------------------------------------------------------------
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