Skip to content

Commit ab66ca6

Browse files
committed
Search float stack dimensions for self-recursive word effects
The self-recursive fixpoint search only tried data stack dimensions. Words like trace-ray that take float inputs ({1, 0, 6, 3}) were rejected. Now the search also covers FIn and FOut up to the float depth at the first RECURSE call.
1 parent 1568437 commit ab66ca6

1 file changed

Lines changed: 23 additions & 16 deletions

File tree

pkg/compiler/stackeffect.go

Lines changed: 23 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -314,7 +314,7 @@ func analyzeWithSelfRef(
314314
ds := depthState{depth: 0, minDepth: 0}
315315
pendingMerges := map[int]depthState{}
316316
dead := false
317-
maxIn := 0
317+
maxIn, maxFIn := 0, 0
318318
for i := 0; i < len(entry.Body); i++ {
319319
if saved, ok := pendingMerges[i]; ok {
320320
delete(pendingMerges, i)
@@ -328,34 +328,41 @@ func analyzeWithSelfRef(
328328
}
329329
item := entry.Body[i]
330330
if item.Word != nil && item.Word == entry {
331-
// depth at RECURSE + items consumed below entry = max possible In
332331
in := 0
333332
if ds.minDepth < 0 {
334333
in = -ds.minDepth
335334
}
336335
maxIn = ds.depth + in
336+
fin := 0
337+
if ds.fminDepth < 0 {
338+
fin = -ds.fminDepth
339+
}
340+
maxFIn = ds.fdepth + fin
337341
break
338342
}
339343
_ = a.processItem(item, i, &ds, pendingMerges, &dead)
340344
}
341-
if maxIn == 0 {
342-
maxIn = 4 // fallback
345+
if maxIn == 0 && maxFIn == 0 {
346+
maxIn = 4
343347
}
344348

345-
// Try all combinations {in, out} up to maxIn.
346-
// Most recursive words have In == Out or Out < In.
349+
// Try all combinations up to the bounds found at the RECURSE call.
347350
for in := 0; in <= maxIn; in++ {
348351
for out := 0; out <= maxIn; out++ {
349-
candidate := StackEffect{in, out, 0, 0}
350-
tempKnown[entry.Xt] = candidate
351-
av := &effectAnalyzer{
352-
body: entry.Body,
353-
knownEffects: tempKnown,
354-
wordName: entry.Name,
355-
}
356-
result, err := av.analyze()
357-
if err == nil && result == candidate {
358-
return result, nil
352+
for fin := 0; fin <= maxFIn; fin++ {
353+
for fout := 0; fout <= maxFIn; fout++ {
354+
candidate := StackEffect{in, out, fin, fout}
355+
tempKnown[entry.Xt] = candidate
356+
av := &effectAnalyzer{
357+
body: entry.Body,
358+
knownEffects: tempKnown,
359+
wordName: entry.Name,
360+
}
361+
result, err := av.analyze()
362+
if err == nil && result == candidate {
363+
return result, nil
364+
}
365+
}
359366
}
360367
}
361368
}

0 commit comments

Comments
 (0)