diff options
author | Kaz Kylheku <kaz@kylheku.com> | 2023-05-04 18:49:15 -0700 |
---|---|---|
committer | Kaz Kylheku <kaz@kylheku.com> | 2023-05-04 18:49:15 -0700 |
commit | c7069b91d6b2889d0a87735f2a9501c85cb3e7ff (patch) | |
tree | 6b08ba2a4e1b2d6e31baa9f1927465a4d29aa4e3 /stdlib/struct.tl | |
parent | 4ff8ba49ba64ed8bc23634698790cc7020a0b62c (diff) | |
download | txr-c7069b91d6b2889d0a87735f2a9501c85cb3e7ff.tar.gz txr-c7069b91d6b2889d0a87735f2a9501c85cb3e7ff.tar.bz2 txr-c7069b91d6b2889d0a87735f2a9501c85cb3e7ff.zip |
compiler: liveness bug involving closures.
2022-09-13 commit 6e354e1c2d5d64d18f527d52db75e344a9223d95,
subject "compiler: bugfixes in dead code elimination",
introduced a problem. By allowing the closure body blocks to
be included in the links of the previous basic block that ends
in the close instruction, it caused liveness info to flow out
out of close blocks into the close instruction, which is
wrong. Thus registers used inside a closure, which are
entirely private, wrongly appear live outside of the closure,
interfering with optimizations like eliminating dead
registers.
We can't simply roll back the commit because the bug it
fixes will reappear. The fix is to pair the next field
with a prev field, and maintain them; don't rely on
the rlinks to point to the previous block.
* stdlib/optimize.tl (basic-block): New slot, prev.
(back-block join-block): As we delete the next block,
we must update that block's next block's prev link.
(basic-blocks link-graph): Build the prev links.
Fix the bug in handling the close instruction:
do not list the close body code among the links,
only the branch target of the close.
(basic-blocks do-peephole-block): In a few cases in
which we set the bl.next to nil, we also set the
bl.next.prev to nil, if bl.next exists.
(basic-blocks elim-dead-clode): Reset the bl.prev
of every block also.
(basic-block check-bypass-empty): Here, we no longer
depend on rlinks containing the previous block;
the prev gives it to us. So we move that fixup out
of the link, and also fix up the next blocks prev
pointer.
Diffstat (limited to 'stdlib/struct.tl')
0 files changed, 0 insertions, 0 deletions