Add a very simple Ion register allocator
Categories
(Core :: JavaScript Engine: JIT, task, P3)
Tracking
()
Tracking | Status | |
---|---|---|
firefox140 | --- | fixed |
People
(Reporter: jandem, Assigned: jandem)
References
(Blocks 2 open bugs)
Details
(Whiteboard: [js-perf-next] )
Attachments
(15 files)
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review | |
48 bytes,
text/x-phabricator-request
|
Details | Review |
Register allocation is usually the slowest part of the Ion compiler backend. To help us experiment with future Ion changes (multiple tiers, backend improvements etc) and to document the LIR => register allocator interface, I've written a second very simple register allocator this week.
We used to have the 'stupid allocator' for this, but we removed it in bug 1617593 because (IIRC) it didn't support Wasm stack results. This allocator also didn't attempt to generate good code: it pre-allocated a 16-byte stack slot for each virtual register and spilled temps or unused/short-lived outputs. It also didn't support safepoints (it didn't have enough information for this) so it relied on the register allocation verifier code to fill the safepoints.
The 'simple allocator' I've written is inspired by the stupid allocator, but it does two passes over the LIR:
- Scan the LIR instructions (last to first) to identify the last-use of each vreg and create a
liveIn
bit set for each basic block. This is a simplified version of the backtracking allocator'sbuildLivenessInfo
code. - Iterate over all LIR instructions (first to last) and allocate registers for each instruction's uses and defs. This also fills the safepoints and allocates/frees/reuses stack slots. Virtual registers that are used in other blocks are spilled but in a lot of cases we can carry live registers to successor blocks with a single predecessor.
With a few simple heuristics this results in pretty decent code within basic blocks. Because it allocates and frees stack slots using the StackSlotAllocator
class, it was also easy to support Wasm stack result areas in this allocator.
Updated•21 days ago
|
Assignee | ||
Comment 1•6 days ago
|
||
RegisterAllocator
is the base class for all register allocators. The backtracking
allocator needs this data but my simple allocator doesn't.
Updated•6 days ago
|
Assignee | ||
Comment 2•6 days ago
|
||
This is more efficient too because lowering records how many entries there are
so we can now pre-allocate these vectors without having to reallocate.
Minor fix: in findFirstNonCallSafepoint
the assertion was using getSafepoint
instead of getNonCallSafepoint
.
Assignee | ||
Comment 3•6 days ago
|
||
Assignee | ||
Comment 4•6 days ago
|
||
Also renames LInstruction::InputIterator
to LInstruction::InputIter
to be
less verbose.
Assignee | ||
Comment 5•6 days ago
|
||
The boilerplate for this (including skipping BogusTemp
definitions) is a bit tedious
so add an iterator for this.
The term 'definition' is used for both outputs and temps so use OutputIter
for outputs
to be more specific.
Assignee | ||
Comment 6•6 days ago
|
||
Assignee | ||
Comment 7•6 days ago
|
||
StackSlotAllocator
already has normalSlots
and doubleSlots
vectors so we just
need to add a quadSlots
vector and a freeSlot
method to support returning slots to
the slot allocator.
This is nice for the simple register allocator because it then doesn't need to track
available stack slots itself.
Assignee | ||
Comment 8•6 days ago
|
||
The backtracking allocator also adds registers for at-start uses to safepoints,
so change the verifier to check these uses too.
Also remove the early return for THIS_FRAME_ARGSLOT
allocations in checkSafepointAllocation
.
It's not clear why that's there so it's safer to check these allocations too.
Assignee | ||
Comment 9•6 days ago
|
||
This fixes a regression from bug 1938317 part 3 that I noticed while reading the code.
We'd incorrectly mark an instruction's output register as a live-register and
save/restore it while we didn't before that change.
We can't easily check for this in the regalloc verifier because the same register
could also be added to the safepoint's live-regs for a different vreg that was live
at the start of the instruction.
Assignee | ||
Comment 10•6 days ago
|
||
This is used to mark a subset of liveRegs
as 'clobbered' for some debug checks.
Calls always have an empty liveRegs
set, so check in the verifier that clobberedRegs
is empty for calls too.
Assignee | ||
Comment 11•6 days ago
|
||
The simple allocator wants to do the same thing.
Longer-term maybe this should be handled during lowering so that we don't need to
rewrite the LUse
here.
Assignee | ||
Comment 12•6 days ago
|
||
This lets us get the slot-and-width data out as uint32_t
and we can create a
SlotAndWidth
and LStackSlot
from that later.
The simple allocator will use that to represent stack slots so that it doesn't
need to compute the width from the type each time it works with stack slots.
Assignee | ||
Comment 13•6 days ago
|
||
Register allocation is usually the slowest part of the Ion compiler backend.
This patch adds the Simple Allocator, a register allocator that results in worse
JIT code but is a lot faster than Backtracking. It's often faster than codegen
and/or GVN.
This allocator lets us experiment with different compilation strategies in the future
and it provides a useful baseline for measuring and optimizing the performance of
the backtracking allocator. It also helps document our LIR => Register Allocator
interface.
Assignee | ||
Comment 14•6 days ago
|
||
This is just to have some smoke tests for now to help catch regressions.
Assignee | ||
Comment 15•6 days ago
|
||
This converts the JitOption
to a pref so that it can also be set from the browser.
Updated•6 days ago
|
Assignee | ||
Updated•5 days ago
|
Updated•1 day ago
|
Comment 16•9 hours ago
|
||
Comment 17•8 hours ago
|
||
Comment 18•7 minutes ago
|
||
bugherder |
https://hg.mozilla.org/mozilla-central/rev/16486f3c512a
https://hg.mozilla.org/mozilla-central/rev/f553fab31d68
https://hg.mozilla.org/mozilla-central/rev/e554e29defee
https://hg.mozilla.org/mozilla-central/rev/96be331c17cd
https://hg.mozilla.org/mozilla-central/rev/8d60ccbe17b3
https://hg.mozilla.org/mozilla-central/rev/e666541e11e5
https://hg.mozilla.org/mozilla-central/rev/142f85de20cf
https://hg.mozilla.org/mozilla-central/rev/9d66932d0f3f
https://hg.mozilla.org/mozilla-central/rev/621f05dd87a6
https://hg.mozilla.org/mozilla-central/rev/e907796231d8
https://hg.mozilla.org/mozilla-central/rev/dcd9496c1da4
https://hg.mozilla.org/mozilla-central/rev/4cdacf348de8
https://hg.mozilla.org/mozilla-central/rev/91c0929b0d84
https://hg.mozilla.org/mozilla-central/rev/2514b6dd41ae
https://hg.mozilla.org/mozilla-central/rev/16111ec3bf26
Description
•