[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