[m-dev.] variable not found bug
Zoltan Somogyi
zs at cs.mu.oz.au
Mon Mar 17 12:28:34 AEDT 1997
> Anyone want to have a look at the following bug? Tom? Zoltan?
> The Mercury compiler dies with a "variable not found"
> error, apparently while computing liveness.
> (The program compiles fine with `--no-inlining').
I have isolated the problem. The root is this piece of code:
> :- func error(string) = _.
> error(S) = _ :-
> error(S).
Its real and inferred determinism is erroneous, but it is implicitly
declared as det.
The problem is that when error/2 is inlined, in first_denomination and
then in cc_tail, the inlining keeps the goal_info from the inlined call.
It thus believes that the goal representing the body of error/2 (which is
just the call to error/1 by the time we get to inlining) is det, that the
conjunction containing the call is also det, and that the conjunction
actually generates a binding for the return value. The relevant part
of the HLDS dump from after inlining is:
else
% nonlocals: V_12
bad -> % determinism: det
( % conjunction
% nonlocals: V_16
% determinism: det
V_16 = "wrong kind of coin"
% new insts: V_16 -> unique("wrong kind of coin")
,
% nonlocals: TypeInfo_5
% determinism: det
TypeInfo_5 = base_type_info("", "int", 0)
% new insts: TypeInfo_5 -> ground
,
% nonlocals: V_12, V_16, TypeInfo_5
bad -> % determinism: det
error(V_16)
% new insts: V_12 -> ground
% V_16 -> bound("wrong kind of coin")
)
bad -> % new insts: V_12 -> ground
)
% new insts: V_12 -> ground
)
% new insts: V_12 -> ground
)
% new insts: V_12 -> ground
)
% new insts: V_12 -> ground
)
% new insts: V_12 -> ground
,
% nonlocals: HeadVar__1, V_10, V_12
% determinism: det
int:'-'(HeadVar__1, V_12, V_10)
% new insts: V_10 -> unique
,
% nonlocals: V_14
% determinism: det
V_14 = 1
% new insts: V_14 -> unique(1)
,
% nonlocals: HeadVar__2, V_13, V_14
% determinism: det
int:'-'(HeadVar__2, V_14, V_13)
% new insts: V_13 -> unique
% V_14 -> bound(1)
The software error arises because follow_code propagates the two subtractions
and the assignment to V_14 into the previous nested if-then-elses, including
the one containing the call to error/1. Since that branch does not bind V_12,
the first subtraction has an input that is not bound; hence the error from
the code generator. (The error message talks about V_28 because follow_code
reruns quantification to rename variables apart.)
Follow_code is designed not to propagate anything into branches that can't
succeed, but in this case the determinism of the goal falsely says that it
*can* succeed, which implies that it *does* bind V_12, and that therefore
propagating the follow-code into the branch is both necessary and safe.
It seems to me that the proper solution is to make inlining merge the
the goal_info of the called goal with the goal_info of the body of the
inlined proc. The determinism should come from the inlined proc, and
so should the delta-instmap (suitably renamed). Possibly other fields
should also be taken from the inlined proc.
Zoltan.
More information about the developers
mailing list