summaryrefslogtreecommitdiff
path: root/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/regalloc.go
diff options
context:
space:
mode:
authorLibravatar kim <89579420+NyaaaWhatsUpDoc@users.noreply.github.com>2024-05-27 15:46:15 +0000
committerLibravatar GitHub <noreply@github.com>2024-05-27 17:46:15 +0200
commit1e7b32490dfdccddd04f46d4b0416b48d749d51b (patch)
tree62a11365933a5a11e0800af64cbdf9172e5e6e7a /vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/regalloc.go
parent[chore] Small styling + link issues (#2933) (diff)
downloadgotosocial-1e7b32490dfdccddd04f46d4b0416b48d749d51b.tar.xz
[experiment] add alternative wasm sqlite3 implementation available via build-tag (#2863)
This allows for building GoToSocial with [SQLite transpiled to WASM](https://github.com/ncruces/go-sqlite3) and accessed through [Wazero](https://wazero.io/).
Diffstat (limited to 'vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/regalloc.go')
-rw-r--r--vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/regalloc.go319
1 files changed, 319 insertions, 0 deletions
diff --git a/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/regalloc.go b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/regalloc.go
new file mode 100644
index 000000000..3f36c84e5
--- /dev/null
+++ b/vendor/github.com/tetratelabs/wazero/internal/engine/wazevo/backend/regalloc.go
@@ -0,0 +1,319 @@
+package backend
+
+import (
+ "github.com/tetratelabs/wazero/internal/engine/wazevo/backend/regalloc"
+ "github.com/tetratelabs/wazero/internal/engine/wazevo/ssa"
+)
+
+// RegAllocFunctionMachine is the interface for the machine specific logic that will be used in RegAllocFunction.
+type RegAllocFunctionMachine[I regalloc.InstrConstraint] interface {
+ // InsertMoveBefore inserts the move instruction from src to dst before the given instruction.
+ InsertMoveBefore(dst, src regalloc.VReg, instr I)
+ // InsertStoreRegisterAt inserts the instruction(s) to store the given virtual register at the given instruction.
+ // If after is true, the instruction(s) will be inserted after the given instruction, otherwise before.
+ InsertStoreRegisterAt(v regalloc.VReg, instr I, after bool) I
+ // InsertReloadRegisterAt inserts the instruction(s) to reload the given virtual register at the given instruction.
+ // If after is true, the instruction(s) will be inserted after the given instruction, otherwise before.
+ InsertReloadRegisterAt(v regalloc.VReg, instr I, after bool) I
+ // ClobberedRegisters is called when the register allocation is done and the clobbered registers are known.
+ ClobberedRegisters(regs []regalloc.VReg)
+ // Swap swaps the two virtual registers after the given instruction.
+ Swap(cur I, x1, x2, tmp regalloc.VReg)
+ // LastInstrForInsertion implements LastInstrForInsertion of regalloc.Function. See its comment for details.
+ LastInstrForInsertion(begin, end I) I
+ // SSABlockLabel returns the label of the given ssa.BasicBlockID.
+ SSABlockLabel(id ssa.BasicBlockID) Label
+}
+
+type (
+ // RegAllocFunction implements regalloc.Function.
+ RegAllocFunction[I regalloc.InstrConstraint, m RegAllocFunctionMachine[I]] struct {
+ m m
+ ssb ssa.Builder
+ c Compiler
+ // iter is the iterator for reversePostOrderBlocks
+ iter int
+ reversePostOrderBlocks []RegAllocBlock[I, m]
+ // labelToRegAllocBlockIndex maps label to the index of reversePostOrderBlocks.
+ labelToRegAllocBlockIndex map[Label]int
+ loopNestingForestRoots []ssa.BasicBlock
+ }
+
+ // RegAllocBlock implements regalloc.Block.
+ RegAllocBlock[I regalloc.InstrConstraint, m RegAllocFunctionMachine[I]] struct {
+ // f is the function this instruction belongs to. Used to reuse the regAllocFunctionImpl.predsSlice slice for Defs() and Uses().
+ f *RegAllocFunction[I, m]
+ sb ssa.BasicBlock
+ l Label
+ begin, end I
+ loopNestingForestChildren []ssa.BasicBlock
+ cur I
+ id int
+ cachedLastInstrForInsertion I
+ }
+)
+
+// NewRegAllocFunction returns a new RegAllocFunction.
+func NewRegAllocFunction[I regalloc.InstrConstraint, M RegAllocFunctionMachine[I]](m M, ssb ssa.Builder, c Compiler) *RegAllocFunction[I, M] {
+ return &RegAllocFunction[I, M]{
+ m: m,
+ ssb: ssb,
+ c: c,
+ labelToRegAllocBlockIndex: make(map[Label]int),
+ }
+}
+
+// AddBlock adds a new block to the function.
+func (f *RegAllocFunction[I, M]) AddBlock(sb ssa.BasicBlock, l Label, begin, end I) {
+ i := len(f.reversePostOrderBlocks)
+ f.reversePostOrderBlocks = append(f.reversePostOrderBlocks, RegAllocBlock[I, M]{
+ f: f,
+ sb: sb,
+ l: l,
+ begin: begin,
+ end: end,
+ id: int(sb.ID()),
+ })
+ f.labelToRegAllocBlockIndex[l] = i
+}
+
+// Reset resets the function for the next compilation.
+func (f *RegAllocFunction[I, M]) Reset() {
+ f.reversePostOrderBlocks = f.reversePostOrderBlocks[:0]
+ f.iter = 0
+}
+
+// StoreRegisterAfter implements regalloc.Function StoreRegisterAfter.
+func (f *RegAllocFunction[I, M]) StoreRegisterAfter(v regalloc.VReg, instr regalloc.Instr) {
+ m := f.m
+ m.InsertStoreRegisterAt(v, instr.(I), true)
+}
+
+// ReloadRegisterBefore implements regalloc.Function ReloadRegisterBefore.
+func (f *RegAllocFunction[I, M]) ReloadRegisterBefore(v regalloc.VReg, instr regalloc.Instr) {
+ m := f.m
+ m.InsertReloadRegisterAt(v, instr.(I), false)
+}
+
+// ReloadRegisterAfter implements regalloc.Function ReloadRegisterAfter.
+func (f *RegAllocFunction[I, M]) ReloadRegisterAfter(v regalloc.VReg, instr regalloc.Instr) {
+ m := f.m
+ m.InsertReloadRegisterAt(v, instr.(I), true)
+}
+
+// StoreRegisterBefore implements regalloc.Function StoreRegisterBefore.
+func (f *RegAllocFunction[I, M]) StoreRegisterBefore(v regalloc.VReg, instr regalloc.Instr) {
+ m := f.m
+ m.InsertStoreRegisterAt(v, instr.(I), false)
+}
+
+// ClobberedRegisters implements regalloc.Function ClobberedRegisters.
+func (f *RegAllocFunction[I, M]) ClobberedRegisters(regs []regalloc.VReg) {
+ f.m.ClobberedRegisters(regs)
+}
+
+// SwapBefore implements regalloc.Function SwapBefore.
+func (f *RegAllocFunction[I, M]) SwapBefore(x1, x2, tmp regalloc.VReg, instr regalloc.Instr) {
+ f.m.Swap(instr.Prev().(I), x1, x2, tmp)
+}
+
+// PostOrderBlockIteratorBegin implements regalloc.Function PostOrderBlockIteratorBegin.
+func (f *RegAllocFunction[I, M]) PostOrderBlockIteratorBegin() regalloc.Block {
+ f.iter = len(f.reversePostOrderBlocks) - 1
+ return f.PostOrderBlockIteratorNext()
+}
+
+// PostOrderBlockIteratorNext implements regalloc.Function PostOrderBlockIteratorNext.
+func (f *RegAllocFunction[I, M]) PostOrderBlockIteratorNext() regalloc.Block {
+ if f.iter < 0 {
+ return nil
+ }
+ b := &f.reversePostOrderBlocks[f.iter]
+ f.iter--
+ return b
+}
+
+// ReversePostOrderBlockIteratorBegin implements regalloc.Function ReversePostOrderBlockIteratorBegin.
+func (f *RegAllocFunction[I, M]) ReversePostOrderBlockIteratorBegin() regalloc.Block {
+ f.iter = 0
+ return f.ReversePostOrderBlockIteratorNext()
+}
+
+// ReversePostOrderBlockIteratorNext implements regalloc.Function ReversePostOrderBlockIteratorNext.
+func (f *RegAllocFunction[I, M]) ReversePostOrderBlockIteratorNext() regalloc.Block {
+ if f.iter >= len(f.reversePostOrderBlocks) {
+ return nil
+ }
+ b := &f.reversePostOrderBlocks[f.iter]
+ f.iter++
+ return b
+}
+
+// LoopNestingForestRoots implements regalloc.Function LoopNestingForestRoots.
+func (f *RegAllocFunction[I, M]) LoopNestingForestRoots() int {
+ f.loopNestingForestRoots = f.ssb.LoopNestingForestRoots()
+ return len(f.loopNestingForestRoots)
+}
+
+// LoopNestingForestRoot implements regalloc.Function LoopNestingForestRoot.
+func (f *RegAllocFunction[I, M]) LoopNestingForestRoot(i int) regalloc.Block {
+ blk := f.loopNestingForestRoots[i]
+ l := f.m.SSABlockLabel(blk.ID())
+ index := f.labelToRegAllocBlockIndex[l]
+ return &f.reversePostOrderBlocks[index]
+}
+
+// InsertMoveBefore implements regalloc.Function InsertMoveBefore.
+func (f *RegAllocFunction[I, M]) InsertMoveBefore(dst, src regalloc.VReg, instr regalloc.Instr) {
+ f.m.InsertMoveBefore(dst, src, instr.(I))
+}
+
+// LowestCommonAncestor implements regalloc.Function LowestCommonAncestor.
+func (f *RegAllocFunction[I, M]) LowestCommonAncestor(blk1, blk2 regalloc.Block) regalloc.Block {
+ ret := f.ssb.LowestCommonAncestor(blk1.(*RegAllocBlock[I, M]).sb, blk2.(*RegAllocBlock[I, M]).sb)
+ l := f.m.SSABlockLabel(ret.ID())
+ index := f.labelToRegAllocBlockIndex[l]
+ return &f.reversePostOrderBlocks[index]
+}
+
+// Idom implements regalloc.Function Idom.
+func (f *RegAllocFunction[I, M]) Idom(blk regalloc.Block) regalloc.Block {
+ builder := f.ssb
+ idom := builder.Idom(blk.(*RegAllocBlock[I, M]).sb)
+ if idom == nil {
+ panic("BUG: idom must not be nil")
+ }
+ l := f.m.SSABlockLabel(idom.ID())
+ index := f.labelToRegAllocBlockIndex[l]
+ return &f.reversePostOrderBlocks[index]
+}
+
+// ID implements regalloc.Block.
+func (r *RegAllocBlock[I, m]) ID() int32 { return int32(r.id) }
+
+// BlockParams implements regalloc.Block.
+func (r *RegAllocBlock[I, m]) BlockParams(regs *[]regalloc.VReg) []regalloc.VReg {
+ c := r.f.c
+ *regs = (*regs)[:0]
+ for i := 0; i < r.sb.Params(); i++ {
+ v := c.VRegOf(r.sb.Param(i))
+ *regs = append(*regs, v)
+ }
+ return *regs
+}
+
+// InstrIteratorBegin implements regalloc.Block.
+func (r *RegAllocBlock[I, m]) InstrIteratorBegin() regalloc.Instr {
+ r.cur = r.begin
+ return r.cur
+}
+
+// InstrIteratorNext implements regalloc.Block.
+func (r *RegAllocBlock[I, m]) InstrIteratorNext() regalloc.Instr {
+ for {
+ if r.cur == r.end {
+ return nil
+ }
+ instr := r.cur.Next()
+ r.cur = instr.(I)
+ if instr == nil {
+ return nil
+ } else if instr.AddedBeforeRegAlloc() {
+ // Only concerned about the instruction added before regalloc.
+ return instr
+ }
+ }
+}
+
+// InstrRevIteratorBegin implements regalloc.Block.
+func (r *RegAllocBlock[I, m]) InstrRevIteratorBegin() regalloc.Instr {
+ r.cur = r.end
+ return r.cur
+}
+
+// InstrRevIteratorNext implements regalloc.Block.
+func (r *RegAllocBlock[I, m]) InstrRevIteratorNext() regalloc.Instr {
+ for {
+ if r.cur == r.begin {
+ return nil
+ }
+ instr := r.cur.Prev()
+ r.cur = instr.(I)
+ if instr == nil {
+ return nil
+ } else if instr.AddedBeforeRegAlloc() {
+ // Only concerned about the instruction added before regalloc.
+ return instr
+ }
+ }
+}
+
+// FirstInstr implements regalloc.Block.
+func (r *RegAllocBlock[I, m]) FirstInstr() regalloc.Instr {
+ return r.begin
+}
+
+// EndInstr implements regalloc.Block.
+func (r *RegAllocBlock[I, m]) EndInstr() regalloc.Instr {
+ return r.end
+}
+
+// LastInstrForInsertion implements regalloc.Block.
+func (r *RegAllocBlock[I, m]) LastInstrForInsertion() regalloc.Instr {
+ var nil I
+ if r.cachedLastInstrForInsertion == nil {
+ r.cachedLastInstrForInsertion = r.f.m.LastInstrForInsertion(r.begin, r.end)
+ }
+ return r.cachedLastInstrForInsertion
+}
+
+// Preds implements regalloc.Block.
+func (r *RegAllocBlock[I, m]) Preds() int { return r.sb.Preds() }
+
+// Pred implements regalloc.Block.
+func (r *RegAllocBlock[I, m]) Pred(i int) regalloc.Block {
+ sb := r.sb
+ pred := sb.Pred(i)
+ l := r.f.m.SSABlockLabel(pred.ID())
+ index := r.f.labelToRegAllocBlockIndex[l]
+ return &r.f.reversePostOrderBlocks[index]
+}
+
+// Entry implements regalloc.Block.
+func (r *RegAllocBlock[I, m]) Entry() bool { return r.sb.EntryBlock() }
+
+// Succs implements regalloc.Block.
+func (r *RegAllocBlock[I, m]) Succs() int {
+ return r.sb.Succs()
+}
+
+// Succ implements regalloc.Block.
+func (r *RegAllocBlock[I, m]) Succ(i int) regalloc.Block {
+ sb := r.sb
+ succ := sb.Succ(i)
+ if succ.ReturnBlock() {
+ return nil
+ }
+ l := r.f.m.SSABlockLabel(succ.ID())
+ index := r.f.labelToRegAllocBlockIndex[l]
+ return &r.f.reversePostOrderBlocks[index]
+}
+
+// LoopHeader implements regalloc.Block.
+func (r *RegAllocBlock[I, m]) LoopHeader() bool {
+ return r.sb.LoopHeader()
+}
+
+// LoopNestingForestChildren implements regalloc.Block.
+func (r *RegAllocBlock[I, m]) LoopNestingForestChildren() int {
+ r.loopNestingForestChildren = r.sb.LoopNestingForestChildren()
+ return len(r.loopNestingForestChildren)
+}
+
+// LoopNestingForestChild implements regalloc.Block.
+func (r *RegAllocBlock[I, m]) LoopNestingForestChild(i int) regalloc.Block {
+ blk := r.loopNestingForestChildren[i]
+ l := r.f.m.SSABlockLabel(blk.ID())
+ index := r.f.labelToRegAllocBlockIndex[l]
+ return &r.f.reversePostOrderBlocks[index]
+}