Commit graph

39 commits

Author SHA1 Message Date
Folkert
8698ea3c72 update mono tests 2022-01-23 15:46:53 +01:00
ayazhafiz
a5de224626 Specialize polymorphic non-function expressions
This commit fixes a long-standing bug wherein bindings to polymorphic,
non-function expressions would be lowered at binding site, rather than
being specialized at the call site.

Concretely, consider the program

```
main =
    n = 1

    idU8 : U8 -> U8
    idU8 = \m -> m

    idU8 n
```

Prior to this commit, we would lower `n = 1` as part of the IR, and the
`n` at the call site `idU8 n` would reference the lowered definition.
However, at the definition site, `1` has the polymorphic type `Num *` -
it is not until the the call site that we are able to refine the type
bound by `n`, but at that point it's too late. Since the default layout
for `Num *` is a signed 64-bit int, we would generate IR like

```
procedure main():
    let App.n : Builtin(Int(I64)) = 1i64;
    ...
    let App.5 : Builtin(Int(U8)) = CallByName Add.idU8 App.n;
    ret App.5;
```

But we know `idU8` expects a `u8`; giving it an `i64` is nonsense.
Indeed this would trigger LLVM miscompilations later on.

To remedy this, we now keep a sidecar table that maps symbols to the
polymorphic expression they reference, when they do so. We then
specialize references to symbols on the fly at usage sites, similar to
how we specialize function usages.

Looking at our example, the definition `n = 1` is now never lowered to
the IR directly. We only generate code for `1` at each place `n` is
referenced. As a larger example, you can imagine that

```
main =
    n = 1

    asU8 : U8 -> U8
    asU32 : U32 -> U8

    asU8 n + asU32 n
```

is lowered to the moral equivalent of

```
main =
    asU8 : U8 -> U8
    asU32 : U32 -> U8

    asU8 1 + asU32 1
```

Moreover, transient usages of polymorphic expressions are lowered
successfully with this approach. See for example the
`monomorphized_tag_with_polymorphic_arg_and_monomorphic_arg` test in
this commit, which checks that

```
main =
    mono : U8
    mono = 15
    poly = A
    wrap = Wrapped poly mono

    useWrap1 : [Wrapped [A] U8, Other] -> U8
    useWrap1 =
        \w -> when w is
            Wrapped A n -> n
            Other -> 0

    useWrap2 : [Wrapped [A, B] U8] -> U8
    useWrap2 =
        \w -> when w is
            Wrapped A n -> n
            Wrapped B _ -> 0

    useWrap1 wrap * useWrap2 wrap
```

has proper code generated for it, in the presence of the polymorphic
`wrap` which references the polymorphic `poly`.

https://github.com/rtfeldman/roc/pull/2347 had a different approach to
this - polymorphic expressions would be converted to (possibly capturing) thunks.
This has the benefit of reducing code size if there are many polymorphic
usages, but may make the generated code slower and makes integration
with the existing IR implementation harder. In practice I think the
average number of polymorphic usages of an expression will be very
small.

Closes https://github.com/rtfeldman/roc/issues/2336
Closes https://github.com/rtfeldman/roc/issues/2254
Closes https://github.com/rtfeldman/roc/issues/2344
2022-01-19 22:52:15 -05:00
Folkert
202a8438ce change UserApp -> Test in mono tests 2022-01-19 23:22:19 +01:00
Folkert
2adcbecf8a update mono tests 2022-01-19 21:01:18 +01:00
Jan Van Bruggen
1e9d2d1239 Remove accidental trailing spaces 2022-01-18 22:25:46 -07:00
Folkert de Vries
e1d990896a
Merge branch 'trunk' into mono-display 2022-01-14 13:55:52 +01:00
ayazhafiz
9f78eb2e01 Fix bug that caused extraneous assignment in IR generation
Previously we would expand optional record fields to assignments when
converting record patterns to "when" expressions. This resulted in
incorrect code being generated.
2022-01-13 18:34:25 -05:00
ayazhafiz
e655ab7d3b Module comments for reset-reuse
Figuring out what this module was doing, and why, took me a bit less
than half an hour. We should document what's happening for others in the
future so they don't need to follow up on Zulip necessarily.
2022-01-13 16:33:23 -05:00
Folkert
79d5c82dfb cleanup 2021-11-27 16:36:43 +01:00
Folkert
19de25426c update mono test 2021-11-19 19:01:03 +01:00
Folkert
b7f26baf95 add mono test 2021-09-24 15:44:09 +02:00
Brendan Hansknecht
0c6f8f308f Remove f16. It is not really supported by modern CPU hardware. 2021-09-21 16:51:47 -07:00
Folkert
77911cb68a store closure data for bool/byte again 2021-09-18 01:01:38 +02:00
Folkert
5b2661e394 update mono tests 2021-09-08 19:59:30 +02:00
Folkert
b97c2d5d84 store literals in lists directly 2021-09-05 21:23:08 +02:00
Folkert
de2f1c808b update mono tests 2021-08-16 21:03:58 +02:00
Folkert
8effd19ff9 stop emitting invoke again 2021-08-16 21:03:26 +02:00
Folkert
441eb02ca3 represent bool closure as unit 2021-08-14 15:54:05 +02:00
Folkert
9b8f8b3c16 AppliedTag don't unroll recursive layouts 2021-07-16 18:23:57 +02:00
Folkert
743e8bd86f stop defining the tag id when it is not used 2021-07-16 18:17:21 +02:00
Folkert
ed28b02b57 shift store_pattern over to decision_tree 2021-07-11 01:06:22 +02:00
Folkert
e7c88cac98 refactor guards 2021-07-04 21:17:57 +02:00
Folkert
16f6259f7f fix all the things 2021-06-27 14:39:28 +02:00
Folkert
98a9dc0945 remove tag id from data bytes for non-recursive tags 2021-06-26 17:01:23 +02:00
Folkert
84855dae5e rename in mono tests 2021-06-21 23:16:09 +02:00
Folkert
6744e009ac more single record cases 2021-06-21 22:56:44 +02:00
Folkert
7a36c25848 simpify pattern match on non-indexable values 2021-06-21 21:24:46 +02:00
Folkert
cc93da006d emit less MultiTagUnion 2021-06-21 20:56:03 +02:00
Folkert
3a6ef8a53d use in decision_tree 2021-06-20 23:53:57 +02:00
Folkert
e274976c6a make it work 2021-06-20 22:36:22 +02:00
Folkert
454241a04f use GetTagId in one more place 2021-06-20 21:05:02 +02:00
Folkert
aecb509909 update mono tests 2021-06-20 20:50:25 +02:00
Folkert
08cb889e6e use GetTagId in test 2021-06-20 17:04:58 +02:00
Folkert
1e7cb5da00 use GetTagId 2021-06-20 17:02:32 +02:00
Folkert
db05e55752 add tag union closure test 2021-06-20 17:00:24 +02:00
Folkert
3a97ccd8ac fix recursive layout issue 2021-06-02 14:37:02 +02:00
Folkert
fb6ba3de57 update mono tests 2021-06-01 21:45:51 +02:00
rvcas
6001312393 chore: add mono txt files to git 2021-06-01 15:40:12 -04:00
Folkert
54057c90b8 new mono testing mechanism 2021-05-30 18:09:41 +02:00