Fix rematerialization possibly increasing register pressure in vasm-graph-color
commitf9fd3a2964cc3888693367d48ffd2ddd3c969317
authorRick Lavoie <rlavoie@fb.com>
Thu, 27 Aug 2020 05:32:22 +0000 (26 22:32 -0700)
committerFacebook GitHub Bot <facebook-github-bot@users.noreply.github.com>
Thu, 27 Aug 2020 05:34:10 +0000 (26 22:34 -0700)
tree87ecdc81f0a0c1f90c087546692c5c54a9d6dc8f
parent2f3fb890790177e03ec38ae494aa172a3bde7595
Fix rematerialization possibly increasing register pressure in vasm-graph-color

Summary:
Whenever we spill a register, we first attempt to rematerialize the
value the register contains. If successful, this shortens the lifetime
of the register being spilled. However, it is important that this
rematerialization does not increase register pressure. It cannot since
we're already at max register pressure (since we're spilling), and if
we increase register pressure, the colorer will later fail.

Suppose we have the follow vasm snippet:

```
ssaalias %r1 => %r2
spill %r1 => %r1
phijmp {%r2}
```

(This is a common pattern if we have a phi input which isn't spilled,
but the phi def in the target block is spilled).

If we cannot rematerialize %r1, this becomes:

```
spill %r1 => %r3
phijmp {%r1}
```

and all is well. Register pressure is not increased.

However, suppose that %r1 is rematerializable in a way that cannot be
rematerialized directly into the spill slot (an 8-byte immediate is a
common example). Instead of the spill, we have:

```
ssaalias %r1 => %r2
ldimmq 0xffffffffffffffff => %r1
spill %r1 => %r1
phijmp {%r2}
```

This eventually becomes:

```
ldimmq 0xffffffffffffffff => %r3
spill %r3 => %r4
phijmp {%r1}
```

Here's a problem. We've introduced a new register (%r3), which has
increased register pressure across this block. If we're already at max
register pressure (which we probably are because we're spilling), the
program is no longer colorable and we've broken a spiller invariant.

The underlying problem is that the use of ssaalias has kept %r1 alive
across the block, until its used by the phijmp. Therefore, if the
rematerializer attempts to use %r1 has the rematerialization
destination (before spilling it), the SSA rewriter is going to create
a new temp, increasing register pressure.

To fix this, we have to enforce that we cannot do arbitrary
rematerializations if the dst of the spill is used by a ssaalias
instruction. If it is, we are limited only to rematerializations which
can write to the spill slot directly. This is fairly straight-forward
since we only introduce ssaalias instructions in very limited
circumstances.

Differential Revision: D23353347

fbshipit-source-id: 03628805b8aee9291a1f12aecc464c143a004bac
hphp/runtime/vm/jit/vasm-graph-color.cpp