5 ms·
Fusing that would be very difficult, since it's hard to write that many registers with a single op, and I don't think they recommend it. This does mean signed o
by Veedrac 6y ago
Fusing that would be very difficult, since it's hard to write that many registers with a single op, and I don't think they recommend it. This does mean signed overflow checking will be comparatively expensive. But thanks for the reference, I agree this is a weak point :).
- ithkuil 6y agoYou don't have to use real registers in a single op. Fusing means interpreting a pattern in the input stream and issuing a different instruction from a richer microarchitectural instruction set
- jcranmer 6y agoYou have to preserve the architectural registers at the end of the sequence. So if there are 5 registers, you either have to have a 5-register microinstruction, or issue multiple 3-register microinstructions instead.
- ithkuil 6y agoYou have to preserve architectural registers only when some other instruction actually depends on them. When you detect a dependency you lazily compute their content (causing a stall)
- brucehoult 6y agoThe dependency could be arbitrarily many millions of instructions away. The only way to know there isn't a dependency is if that register gets clobbered by something else very soon afterwards. But this whole topic of "checking for signed overflow is expensive" is overblown. It's simply not that important an operation, especially in the context of those languages that do it a lot also doing a lot of memory references, which are far more expensive. Adding arbitrary completely unknown integers is pretty rare. If you know both numbers are greater than zero then a single compare-and-branch is all you need. If one of the numbers is a constant then a single compare-and-branch is all you need.
- jcranmer 6y agoThat sounds like an amazingly bad idea, because you would instead have to retain the two source registers until you can prove that you don't need the two output registers anymore, which can be arbitrarily far in the future.
- brandmeyer 6y agoAt least in their papers and mailing list discussion, the limit for simple fusion is not on the number of source operands, but on the number of destination operands. A classic example is a PC-relative long jump: auipc lr, zero, .LONG_TARGET20 jalr lr, lr, .LONG_TARGET12 Only one register (the link register) is clobbered, so the pair can be fused into a single wide jump-and-link. So in parent's example, sov might fuse with the following bnez, but it likely wouldn't fuse with the preceding addition.
- Veedrac 6y agoYes, I missed the edit, I was only commenting on the first part. Quite a few things determine whether a fusion is doable or not. In addition to the number of destination registers, you do, to a more relaxed extent, care about source operands, but also things like ‘does this fit nicely in a single pass through the pipeline?’ and even just ‘is this materially beneficial?’ Lots of cores (but not all) can write two registers from a fused instruction, given the right conditions, and sov does rerun the addition, so add-sov fusion sounds very doable to me.