regalloc: simplifies regInUseSet (#2227)
This makes the compilation slightly faster and simplifies the codebase.
```
goos: darwin
goarch: arm64
pkg: github.com/tetratelabs/wazero
│ old.txt │ new.txt │
│ sec/op │ sec/op vs base │
Compilation-10 2.499 ± 0% 2.478 ± 2% -0.84% (p=0.026 n=7)
│ old.txt │ new.txt │
│ B/op │ B/op vs base │
Compilation-10 341.0Mi ± 0% 341.1Mi ± 0% ~ (p=0.128 n=7)
│ old.txt │ new.txt │
│ allocs/op │ allocs/op vs base │
Compilation-10 606.9k ± 0% 606.9k ± 0% ~ (p=0.383 n=7)
```
Signed-off-by: Takeshi Yoneda <t.y.mathetake@gmail.com>
This commit is contained in:
@@ -972,6 +972,12 @@ func (a *Allocator) fixMergeState(f Function, blk Block) {
|
||||
bID := blk.ID()
|
||||
blkSt := a.getOrAllocateBlockState(bID)
|
||||
desiredOccupants := &blkSt.startRegs
|
||||
var desiredOccupantsSet RegSet
|
||||
for i, v := range desiredOccupants {
|
||||
if v != VRegInvalid {
|
||||
desiredOccupantsSet = desiredOccupantsSet.add(RealReg(i))
|
||||
}
|
||||
}
|
||||
|
||||
if wazevoapi.RegAllocLoggingEnabled {
|
||||
fmt.Println("fixMergeState", blk.ID(), ":", desiredOccupants.format(a.regInfo))
|
||||
@@ -993,12 +999,12 @@ func (a *Allocator) fixMergeState(f Function, blk Block) {
|
||||
// Finds the free registers if any.
|
||||
intTmp, floatTmp := VRegInvalid, VRegInvalid
|
||||
if intFree := s.findAllocatable(
|
||||
a.regInfo.AllocatableRegisters[RegTypeInt], desiredOccupants.set,
|
||||
a.regInfo.AllocatableRegisters[RegTypeInt], desiredOccupantsSet,
|
||||
); intFree != RealRegInvalid {
|
||||
intTmp = FromRealReg(intFree, RegTypeInt)
|
||||
}
|
||||
if floatFree := s.findAllocatable(
|
||||
a.regInfo.AllocatableRegisters[RegTypeFloat], desiredOccupants.set,
|
||||
a.regInfo.AllocatableRegisters[RegTypeFloat], desiredOccupantsSet,
|
||||
); floatFree != RealRegInvalid {
|
||||
floatTmp = FromRealReg(floatFree, RegTypeFloat)
|
||||
}
|
||||
|
||||
@@ -366,7 +366,7 @@ func TestAllocator_livenessAnalysis_copy(t *testing.T) {
|
||||
|
||||
func Test_findOrSpillAllocatable_prefersSpill(t *testing.T) {
|
||||
t.Run("ok", func(t *testing.T) {
|
||||
s := &state{}
|
||||
s := &state{regsInUse: newRegInUseSet()}
|
||||
s.regsInUse.add(RealReg(1), VReg(2222222))
|
||||
got := s.findOrSpillAllocatable(&Allocator{}, []RealReg{3}, 0, 3)
|
||||
require.Equal(t, RealReg(3), got)
|
||||
|
||||
@@ -46,23 +46,24 @@ func (rs RegSet) Range(f func(allocatedRealReg RealReg)) {
|
||||
}
|
||||
}
|
||||
|
||||
type regInUseSet struct {
|
||||
set RegSet
|
||||
vrs [64]VReg
|
||||
type regInUseSet [64]VReg
|
||||
|
||||
func newRegInUseSet() regInUseSet {
|
||||
var ret regInUseSet
|
||||
ret.reset()
|
||||
return ret
|
||||
}
|
||||
|
||||
func (rs *regInUseSet) reset() {
|
||||
rs.set = 0
|
||||
for i := range rs.vrs {
|
||||
rs.vrs[i] = VRegInvalid
|
||||
for i := range rs {
|
||||
rs[i] = VRegInvalid
|
||||
}
|
||||
}
|
||||
|
||||
func (rs *regInUseSet) format(info *RegisterInfo) string { //nolint:unused
|
||||
var ret []string
|
||||
for i := 0; i < 64; i++ {
|
||||
if rs.set&(1<<uint(i)) != 0 {
|
||||
vr := rs.vrs[i]
|
||||
for i, vr := range rs {
|
||||
if vr != VRegInvalid {
|
||||
ret = append(ret, fmt.Sprintf("(%s->v%d)", info.RealRegName(RealReg(i)), vr.ID()))
|
||||
}
|
||||
}
|
||||
@@ -70,39 +71,28 @@ func (rs *regInUseSet) format(info *RegisterInfo) string { //nolint:unused
|
||||
}
|
||||
|
||||
func (rs *regInUseSet) has(r RealReg) bool {
|
||||
if r >= 64 {
|
||||
return false
|
||||
}
|
||||
return rs.set&(1<<uint(r)) != 0
|
||||
return r < 64 && rs[r] != VRegInvalid
|
||||
}
|
||||
|
||||
func (rs *regInUseSet) get(r RealReg) VReg {
|
||||
if r >= 64 {
|
||||
return VRegInvalid
|
||||
}
|
||||
return rs.vrs[r]
|
||||
return rs[r]
|
||||
}
|
||||
|
||||
func (rs *regInUseSet) remove(r RealReg) {
|
||||
if r >= 64 {
|
||||
return
|
||||
}
|
||||
rs.set &= ^(1 << uint(r))
|
||||
rs.vrs[r] = VRegInvalid
|
||||
rs[r] = VRegInvalid
|
||||
}
|
||||
|
||||
func (rs *regInUseSet) add(r RealReg, vr VReg) {
|
||||
if r >= 64 {
|
||||
return
|
||||
}
|
||||
rs.set |= 1 << uint(r)
|
||||
rs.vrs[r] = vr
|
||||
rs[r] = vr
|
||||
}
|
||||
|
||||
func (rs *regInUseSet) range_(f func(allocatedRealReg RealReg, vr VReg)) {
|
||||
for i := 0; i < 64; i++ {
|
||||
if rs.set&(1<<uint(i)) != 0 {
|
||||
f(RealReg(i), rs.vrs[i])
|
||||
for i, vr := range rs {
|
||||
if vr != VRegInvalid {
|
||||
f(RealReg(i), vr)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user