Summary
=======
Replace the `PNode`-based fixup for call arguments in `ccgcalls` with a
MIR pass. This removes a dependency on `PNode`-based analysis from
`cgen`, and also makes it possible to, in the future, enable the fixup
when the JS or VM backends are used (both are also affected by the
issue).
While the used analysis stays mostly the same, an observable evaluation-
order violation is fixed. Injecting (shallow) copies for values passed
to both immutable and mutable parameters now considers *all* parameters,
instead of only parameters to the right of immutable ones. For example,
given:
```nim
f(a, a) # proc f(x: var T, y: T)
```
this fixes mutations through `x` inside `f` being visible on `y`.
Details
=======
The analysis used by the MIR pass works mostly the same as the one
previously used in `ccgcalls`: for each argument value that is not
explicitly passed by-reference, it is analyzed whether:
- the value is potentially mutated *after* it is bound to the parameter
but *before* the procedure is called
- the value is potentially also passed to a `var` parameter
If either is the case, the argument is shallow-copied to a temporary
that is then passed to the parameter instead.
The differences compared to the previous analysis are that:
- checking whether the argument value (or something that potentially
overlaps with it in memory) is also passed to a mutable parameter
now also considers preceding parameters. Previously, only the
following parameters were checked
- testing for overlapping values considers the whole path now, instead
of only the root. In effect, this means that for `f(a.x, a.y)`, where
the second parameter is mutable, no temporary is (unnecessarily)
injected for the first parameter
For overlap testing, the `maybeSameMutableLocation` procedure is
introduced, which mirrors the behaviour of `dfa.aliases` (the routine
used by the previous `PNode`-based analysis). Since dereferences of
pointer-like values are treated like a normal field access, calls like
`f(a[].x, b[].y)`, where one of the parameters is mutable and `a` and
`b` point to the same location, still cause observable evaluation-order
violations.
Finally, the analysis and temporary injection in `ccgcalls` is removed,
and a test is added for the fixed issue.