[m-rev.] for review: fix half of Mantis bug #548
Peter Wang
novalazy at gmail.com
Thu Feb 10 16:13:56 AEDT 2022
On Thu, 10 Feb 2022 10:22:32 +1100 "Zoltan Somogyi" <zoltan.somogyi at runbox.com> wrote:
> For review by anyone.
>
> I can see four ways to fix the second problem in Mantis 548.
> Here they are, but this discussion makes sense only if you have read
> the comments in the new test case descrbing that problem.
>
> 1. Change how we represent HLDS vars in the MLDS. At the moment,
> that representation, lvn_prog_var, consists of the HLDS variable's name
> and its number. This means that if we generate code twice for the same
> HLDS code, we will get the same MLDS name for every HLDS variable
> in that HLDS code. We could fix this by including in lvn_prog_var
> a unique integer, allocated from a counter when the MLDS variable
> is constructed, either in addition to, or in place of, the HLDS variable number.
> This should be simple to implement, but would make HLDS dumps
> harder to read, either by adding clutter (if we keep the HLDS variable number)
> or by removing a link to the HLDS (if we replace the HLDS variable number).
>
> 2. We could keep locals vars as they are, but add the unique integer
> to the field name that we turn MLDS variables into. This would involve
> adding an integer, again allocated from a counter, to fvn_env_field_from_local_var.
> This may be somewhat harder to implement, because it breaks the current
> direct correspondence between the local var and field name versions
> of a HLDS variable.
>
> 3. The name collision for field vars occurs because two different switch arms,
> which are independent pieces of code, use the same environment structure.
> We could change things so that independent pieces of code get separate
> environment structures. This change would be so complex that I definitely
> won't be doing it :-(
>
> 4. As a compromise, when we construct the environment structure,
> we could replace whatever code appends the lists of local vars from
> different places to construct the list of fields to put into the environment
> structure with code that unions sets of local vars instead, so that
> even if two independent pieces of code specify the same local variable
> (as in the case of the code that tickled this bug), we won't get duplicate
> field names. This approach would probably not be too hard to implement,
> but I definitely wouldn't be able to write a convincing correctness
> argument in its favor :-(
>
> Opinions?
1. Seems overkill to me.
2. Sounds okay to me (barring difficulty of implementation).
4. It sounds like a variation of (2) which avoids adding distinguishing
suffixes unless a name collision would arise, which would be a slightly
better result than (2), but may not be worth the extra complexity.
But you seem to suggest that (4) would be easier than (2).
> diff --git a/tests/hard_coded/Mercury.options b/tests/hard_coded/Mercury.options
> index de994ee36..5f39fdf27 100644
> --- a/tests/hard_coded/Mercury.options
> +++ b/tests/hard_coded/Mercury.options
> @@ -15,6 +15,7 @@ MCFLAGS-bug300 = --no-const-struct --optimize-constructor-last-call
> MCFLAGS-bug314 = --trace deep
> MCFLAGS-bug392 = -O0 --deforestation
> MCFLAGS-bug455_mod_a = --intermodule-optimization
> +MCFLAGS-bug458 = --inlining
The module name is wrong. Perhaps --inlining is not necessary given the
pragma inline?
> +test_pred(T, List, A, N) :-
> + (
> + ( T = f1(_, _)
> + ; T = f2(_, _)
> + ; T = f3(_, _)
> + ; T = f4(_, _)
> + ; T = f5(_, _)
> + ; T = f6(_, _)
> + ; T = f7(_, _)
> + ; T = f8(_, _)
> + ),
> + N = 11
> + ;
> + ( T = f0(_, _)
> + ; T = f9(_, _)
> + ),
> + % The two bug we are testing for occurred when ml_tag_switch.m
two bugs
> + % duplicated the code of this switch arm for two different
> + % primary tag values, one unshared (as is f0) and one shared
> + % (as is f9).
> + %
> + % One bug was that auxiliary MLDS functions inside divisible_by_some
> + % were generated once and then used twice, resulting in duplicate
> + % function definition.
definitions
> + %
> + % The other bug involved the fact that the local variables of this arm
> + % are put into an environment structure by the implementation of the
> + % commit implicit in the "some [I]" quantification inlined here.
> + % When this arm is duplicated, we get duplicate field names in this
> + % environment structure *even if we do not duplicate the MLDS code
> + % of this case, but generate it fresh for each ptag*, because
> + %
> + % - the name of each MLDS variable representing a HLDS variable
> + % is constructed solely from the HLDS name and number of the HLDS
> + % variable, and
> + %
> + % - the name of each field in the environment structure that represents
> + % an MLDS variable is constructed solely from the name of that MLDS
> + % variable.
> + %
> + % At neither stage did we add any kind of suffix to ensure the
> + % uniqueness of the name. (For the problem with duplicate aux function
> + % definitions, generating the code of this arm fresh for each ptag
> + % does fix the problem, because for aux MLDS functions, we *do*
> + % add a unique numerical suffix to their name.)
> + ( if divisible_by_some(List, A) then
> + N = A
> + else
> + N = 42
> + )
> + ).
The rest looks fine.
Peter
More information about the reviews
mailing list