Skip to content

Commit d3f20d7

Browse files
authored
Merge pull request #5745 from unisonweb/topic/affine-improvements
Relax a criterion for recognizing affine handlers
2 parents 3766e89 + 479abb6 commit d3f20d7

File tree

3 files changed

+67
-7
lines changed

3 files changed

+67
-7
lines changed

unison-runtime/src/Unison/Runtime/ANF.hs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2504,7 +2504,7 @@ prettyRefs [] = showString "{}"
25042504
prettyRefs (r : rs) =
25052505
showString "{"
25062506
. showsShort r
2507-
. foldr (\t r -> shows t . showString "," . r) id rs
2507+
. foldr (\t r -> showString "," . showsShort t . r) id rs
25082508
. showString "}"
25092509

25102510
prettyFunc :: (Var v) => Func v -> ShowS

unison-runtime/src/Unison/Runtime/ANF/Optimize.hs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -572,8 +572,8 @@ augmentHandler ::
572572
augmentHandler opts _self group
573573
| Rec [(mv0, matcher)] entry <- group,
574574
Lambda ccs (ABTN.TAbss args body) <- entry,
575-
thunk : vs <- shiftArgs args,
576-
Just body <- augmentHandlerEntry vs thunk mv0 ah body,
575+
thunk : _ <- shiftArgs args,
576+
Just body <- augmentHandlerEntry thunk mv0 ah body,
577577
Just amatcher <- translateHandlerMatch opts mv0 ah matcher =
578578
Just
579579
. Rec [(mv0, matcher), (ah, amatcher)]
@@ -609,14 +609,13 @@ translateHandlerMatch opts self ah (Lambda ccs (ABTN.TAbss args body))
609609
-- one, then the result is a modified version with an affine handler
610610
-- filled in.
611611
augmentHandlerEntry ::
612-
(Var v) => [v] -> v -> v -> v -> ANormal v -> Maybe (ANormal v)
613-
augmentHandlerEntry vs thunk0 mv0 ah body
612+
(Var v) => v -> v -> v -> ANormal v -> Maybe (ANormal v)
613+
augmentHandlerEntry thunk0 mv0 ah body
614614
| TName hv (Right mv1) us body <- body,
615615
THnd rs nh Nothing (TFrc thunk1) <- body,
616616
mv0 == mv1,
617617
nh == hv,
618-
thunk0 == thunk1,
619-
Prelude.and (zipWith (==) us vs) =
618+
thunk0 == thunk1 =
620619
Just
621620
. TName hv (Right mv1) us
622621
. TName ahp (Right ah) us

unison-src/transcripts/idempotent/affine-handlers.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -231,3 +231,64 @@ scratch/main> io.test fail'count'test
231231
232232
Tip: Use view 1 to view the source of a test.
233233
```
234+
235+
This tests a case where affine handlers were not being optimized due
236+
to overly restrictive criteria for recognizing them. In this case,
237+
because n \< o, parts of the handler will end up with the n and o
238+
variables in different orders. I.E. an 'entry point' will end up with
239+
`o n -> ...` because the `o` gets prepended, but the matching cases
240+
will end up with `n o -> ...` because its argument list is generated
241+
based completely on the order in which free variables are sorted by
242+
name.
243+
244+
This has nothing to do with the handler being affine, and was just an
245+
overly restrictive assumption about the exact form that handlers end
246+
up in in the intermediate code. It shouldn't even matter if some
247+
variables in the entry are unused in the matcher, although I'm
248+
uncertain if that can happen. So, checking the relationship between
249+
the argument list of the matcher and the entry point has just been
250+
removed.
251+
252+
``` unison
253+
local'counter : Nat -> '{Count} r -> r
254+
local'counter o th =
255+
h n = cases
256+
{ tick -> k } ->
257+
handle k (n + o) with h (n+1)
258+
{ r } -> r
259+
handle !th with h 0
260+
261+
local'count'test = do
262+
[ testPerf do local'counter 5 do count'wrap 1000 100 ]
263+
```
264+
265+
``` ucm :added-by-ucm
266+
Loading changes detected in scratch.u.
267+
268+
I found and typechecked these definitions in scratch.u. If you
269+
do an `update`, here's how your codebase would change:
270+
271+
⍟ These new definitions are ok to `update`:
272+
273+
local'count'test : '{IO, Exception} [Result]
274+
local'counter : Nat -> '{Count} r -> r
275+
```
276+
277+
``` ucm
278+
scratch/main> add
279+
280+
Okay, I'm searching the branch for code that needs to be
281+
updated...
282+
283+
Done.
284+
285+
scratch/main> io.test local'count'test
286+
287+
New test results:
288+
289+
1. local'count'test ◉ performance improved
290+
291+
✅ 1 test(s) passing
292+
293+
Tip: Use view 1 to view the source of a test.
294+
```

0 commit comments

Comments
 (0)