wazevo(regalloc): spill the unused values with high priority (#2082)

Signed-off-by: Takeshi Yoneda <t.y.mathetake@gmail.com>
This commit is contained in:
Takeshi Yoneda
2024-02-20 16:22:09 +09:00
committed by GitHub
parent 8caae04aea
commit 08998eda2d
5 changed files with 42 additions and 3 deletions

View File

@@ -246,7 +246,8 @@ func (s *state) findOrSpillAllocatable(a *Allocator, allocatable []RealReg, forb
continue
}
if last := s.getVRegState(using.ID()).lastUse; r == RealRegInvalid || last > lastUseAt {
// last == -1 means the value won't be used anymore.
if last := s.getVRegState(using.ID()).lastUse; r == RealRegInvalid || last == -1 || (lastUseAt != -1 && last > lastUseAt) {
lastUseAt = last
r = candidateReal
spillVReg = using
@@ -258,7 +259,7 @@ func (s *state) findOrSpillAllocatable(a *Allocator, allocatable []RealReg, forb
}
if wazevoapi.RegAllocLoggingEnabled {
fmt.Printf("\tspilling v%d when: %s\n", spillVReg.ID(), forbiddenMask.format(a.regInfo))
fmt.Printf("\tspilling v%d when lastUseAt=%d and regsInUse=%s\n", spillVReg.ID(), lastUseAt, s.regsInUse.format(a.regInfo))
}
s.releaseRealReg(r)
return r

View File

@@ -1011,3 +1011,10 @@ func Test2078(t *testing.T) {
}
nodiff.RequireNoDiffT(t, getWasmBinary(t, "2078"), true, true)
}
func Test2082(t *testing.T) {
if !platform.CompilerSupported() {
return
}
nodiff.RequireNoDiffT(t, getWasmBinary(t, "2082"), true, true)
}

Binary file not shown.

View File

@@ -0,0 +1,30 @@
(module
(type (;0;) (func (param i32 i32 i32 i32 i32 i32 i32 i32)))
(func (;0;) (type 0) (param i32 i32 i32 i32 i32 i32 i32 i32)
call 1
i64.const -1
f64.convert_i64_u
i32.trunc_f64_s
unreachable
)
(func (result i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32 i32)
i32.const 0
i32.const 0
i32.const 0
i32.const 0
i32.const 0
i32.const 0
i32.const 0
i32.const 0
i32.const 0
i32.const 0
i32.const 0
i32.const 0
i32.const 0
i32.const 0
i32.const 0
i32.const 0
i32.const 0
)
(export "" (func 0))
)

View File

@@ -303,7 +303,8 @@ outer:
intRes, intErr := intF.Call(interpreterCtx, params...)
errorDuringInvocation = errorDuringInvocation || cmpErr != nil || intErr != nil
if errMismatch := ensureInvocationError(cmpErr, intErr); errMismatch != nil {
panic(fmt.Sprintf("error mismatch on invoking %s: %v", name, errMismatch))
err = errors.Join(err, fmt.Errorf("error mismatch on invoking %s: %v", name, errMismatch))
continue
}
matched := true