mirror of
https://github.com/Mercury-Language/mercury.git
synced 2026-04-19 03:13:40 +00:00
Common subexpression elimination (cse) declines to do its job of transforming
(
X = f(A1, ..., An),
goal A
;
X = f(B1, ..., Bn),
goal B
)
into
X = f(X1, ..., Xn),
(
A1 = X1, ..., An = Xn,
goal A
;
B1 = X1, ..., Bn = Xn,
goal B
)
when the insts of some of X's arguments are at least partially unique,
because mode analysis cannot track uniqueness through the extra unifications
that this transformation introduces. When this happens, and the procedure
this code is in does not match its declared determinism, generate a message
that gives this fact as a possible reason for that determinism mismatch.
This fixes Mantis bug #496 to the extent that we *can* fix it
without rewriting the whole of mode analysis.
compiler/hlds_pred.m:
Provide a slot in the proc_info for recording whether cse has declined
to pull a common unification out of a branched control structure because
of this concern, and if so, at what locations in the source code.
An unrelated change: move a slot used only by constraint-based mode
analysis, which is never enabled, from the proc_info to the proc_sub_info.
This should improve both speed and memory consumption, though very
slightly.
compiler/cse_detection.m:
Record each such location in this slot.
Doing this requires a change in approach. Previously, we did not try
to pull a unification out of any branch of a branched control structure
if it involved (partially or wholly) unique arguments. However, doing
this in just one branch cannot possibly affect the output of cse detection,
since it pulls a unification out of a branch only if can pull the same
unification out of all the other branches as well.
Our new approach is to transform branched control structures regardless
of uniqueness, and then *undo* the transformation (simply by discarding
its result) if it involves unique arguments. It is such undoing that we
record in the proc_info.
compiler/switch_detection.m:
Conform to the new approach.
compiler/hlds_out_pred.m:
Print the contents of the new slot in HLDS dumps.
compiler/det_report.m:
If the actual determinism of a procedure, as computed by determinism
analysis, does not match its declared determinism, *and* if the proc_info's
new slot says that cse declined to pull some common unifications
out of a branched control structure, then mention that fact, and
the usual fix, as a possible explanation of the determinism problem.
tests/invalid/bug496.{m,err_exp}:
The Mantis test case.
tests/invalid/Mmakefile:
Enable the new test case.
25 lines
1.6 KiB
Plaintext
25 lines
1.6 KiB
Plaintext
bug496.m:022: In `options_to_action'(in, in, out):
|
|
bug496.m:022: error: determinism declaration not satisfied.
|
|
bug496.m:022: Declared `det', inferred `nondet'.
|
|
bug496.m:050: Inside the case [|]/2 of the switch on AllActions:
|
|
bug496.m:050: disjunction has multiple clauses with solutions.
|
|
bug496.m:050: In argument 2 of functor `[|]/2':
|
|
bug496.m:050: unification with `list.[]' can fail.
|
|
bug496.m:053: In argument 2 of functor `[|]/2':
|
|
bug496.m:053: unification with `list.[V_11 | V_12]' can fail.
|
|
bug496.m:050: It is possible that the cause of the declared determinism not
|
|
bug496.m:050: being satisfied is the inability of determinism analysis to
|
|
bug496.m:050: recognize that a disjunction (usually created by the compiler
|
|
bug496.m:050: for a switch arm) is a switch on a *subterm* of a variable when
|
|
bug496.m:050: the instantiation state of that variable is at least partially
|
|
bug496.m:050: unique. This is because converting such a disjunction to a
|
|
bug496.m:050: switch requires replacing several unifications, one in each arm
|
|
bug496.m:050: of the disjunction, that each unify the variable representing
|
|
bug496.m:050: the subterm (e.g. the tail of a list) with the same function
|
|
bug496.m:050: symbol, with just one unification before the disjunction, but
|
|
bug496.m:050: due to limitations of the current modechecker, this
|
|
bug496.m:050: transformation could destroy the uniqueness.
|
|
bug496.m:050: In cases where this uniqueness is not needed, the programmer
|
|
bug496.m:050: can fix the determinism error by performing this transformation
|
|
bug496.m:050: manually.
|