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:
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
BIN
internal/integration_test/fuzzcases/testdata/2082.wasm
vendored
Normal file
BIN
internal/integration_test/fuzzcases/testdata/2082.wasm
vendored
Normal file
Binary file not shown.
30
internal/integration_test/fuzzcases/testdata/2082.wat
vendored
Normal file
30
internal/integration_test/fuzzcases/testdata/2082.wat
vendored
Normal 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))
|
||||
)
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user