Commit graph

1741 commits

Author SHA1 Message Date
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
72ee2d6327 Mark pretty_print_ir_symbols public 2022-01-13 16:35:09 -05:00
ayazhafiz
c38ca2dfa4 Anything for you mr paperclippy 2022-01-13 16:33:26 -05:00
ayazhafiz
8d372edda1 Add config variables for printing IR during mono stages 2022-01-13 16:33:26 -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
Richard Feldman
f83f50a9a7
Merge pull request #2337 from rtfeldman/i/2331
Use unsigned LLVM intrinsic arithmetic for unsigned integers
2022-01-12 08:29:30 -05:00
ayazhafiz
2c41c43aea Implement saturated add/subtract 2022-01-10 22:37:08 -05:00
ayazhafiz
103e85f339 Pretty-print laayouts when PRETTY_PRINT_IR_SYMBOLS is true 2022-01-10 19:21:18 -05:00
Brian Carroll
5560ecb63e Implement tail recursion for union refcounting procs 2022-01-06 22:43:02 +00:00
Brian Carroll
040b8ce430 Reduce code size for Union refcount procedures 2022-01-06 10:49:34 +00:00
Brian Carroll
d9cc3c5692 Modify refcount of contents *before* structure to prevent use-after-free 2022-01-06 10:49:34 +00:00
Brian Carroll
456bda0895 Prevent confusion between separate instances of RecursivePointer 2022-01-06 10:49:34 +00:00
Brian Carroll
ad95ea4a3b Remove a debug assert 2022-01-06 10:49:34 +00:00
Brian Carroll
5e642c880c Mask out union tag ID from pointer when calculating refcount address 2022-01-06 10:49:34 +00:00
Brian Carroll
5d7b4018b7 Generate refcounting helper procedures for tag unions 2022-01-05 12:24:04 +00:00
Folkert
fc4cea9f75 don't throw away a jump 2022-01-03 16:50:43 +01:00
Folkert
7044e95df8 fix imported function thunk 2022-01-03 16:18:53 +01:00
Brian Carroll
1de26c084d Make Struct DecRef a no-op 2022-01-01 21:57:28 +00:00
Brian Carroll
98ab97083a For DecRef, remove assumption that the refcounted symbol is ARG_1 2022-01-01 21:57:28 +00:00
Brian Carroll
176bb6f6aa Use joinpoints for DecRef 2022-01-01 21:57:28 +00:00
Brian Carroll
e55806fe27 Update is_rc_implemented_yet 2022-01-01 12:33:36 +00:00
Brian Carroll
8078afc74f Delete a stray println from debug 2022-01-01 11:39:55 +00:00
Brian Carroll
953d82b341 Merge branch 'trunk' of github.com:rtfeldman/roc into wasm-refcount-struct 2022-01-01 11:33:27 +00:00
Brian Carroll
310de090a3 Wasm: Refcounting for struct fields 2022-01-01 11:32:53 +00:00
Brian Carroll
12a330dd76 Refactor to move all refcount IR gen to the same file 2021-12-31 23:09:11 +00:00
Folkert
ee9f0b2f04 force imported thunks when assigned to a variable 2021-12-31 21:44:07 +01:00
Brian Carroll
f767014f30
Merge pull request #2301 from rtfeldman/wasm-refcount-list
Wasm refcounting for lists
2021-12-31 13:25:38 +00:00
Brian Carroll
c5663e3538 Generate IR helper proc for list refcounting 2021-12-30 17:15:31 +00:00
Brian Carroll
59472d3310 Slightly improve pretty printing of inc statement 2021-12-30 09:01:22 +00:00
ayazhafiz
d966d8921f Support nullable wrapped tag union layouts in REPL 2021-12-29 17:55:21 -06:00
Brian Carroll
37de499248 Reorganise code gen helper in roc_mono 2021-12-28 11:03:33 +00:00
Folkert de Vries
249878cbd9
Merge pull request #2281 from rtfeldman/i/2149
(llvm) Generate code for tag unions less than 64 bits in size correctly
2021-12-27 22:38:08 +01:00
Brian Carroll
c67b9e7a6f clippy 2021-12-27 18:11:48 +00:00
Brian Carroll
0285cd88c5 Don't emit tail recursion loop for non-recursive unions 2021-12-27 18:08:43 +00:00
Brian Carroll
0d8a2c8a49 Use tail call elimination where possible in == for tag unions 2021-12-27 18:08:43 +00:00
Brian Carroll
65a9464d98 Replace RecursivePointer todo with unreachable 2021-12-27 18:08:43 +00:00
ayazhafiz
a03f7fa46c Update layout tests 2021-12-26 14:44:43 -06:00
ayazhafiz
c8ba554d8c Clippy warning 2021-12-26 11:58:50 -06:00
ayazhafiz
5e5eb6dca8 (llvm) Generate code for tag unions less than 64 bits in size correctly
Previously, we assumed that a union layout always lived on >= 1 64-bit
boundary when generating an LLVM type for it. For small tags unions,
like `[ Ok i8, Err ]` this need not be the case; indeed, a tag union
like that is actually only 2 bits - 1 bit for the "i8" data, and one bit
of the tag kind.

This led to a discrepancy between what the layout IR and generated LLVM
code would assume about the size of tag unions. In the case above, the
layout IR would assume the tag data is 2 bits wide, and the tag id is 1
bit into the data. But the LLVM code would generate a type that was 65
bits wide, the first 64 bits being for the "i8" data and the last 1 bit
being for the tag kind.

Usually, just running the LLVM-emitted code would not present a problem.
But it does present a problem when we use the layout IR to inspect the
result of LLVM-run code, in particular when we try to look up the tag
ID, as the repl does. This patch fixes that issue.

Note that this bug did not present itself in `test_gen` previously
because the data that most tests check against is stored in the front of
the representation.

Closes #2149
2021-12-26 11:45:02 -06:00
Brian Carroll
e54ce0c975 Ensure procs are in the same order as the Symbols 2021-12-26 10:45:23 +00:00
Brian Carroll
9fb7048de0 Rename rec_ptr_layout -> recursive_union
I kept thinking it was of type Layout but it's not
2021-12-26 10:45:23 +00:00
Brian Carroll
ab7867d233 Separate specializations from procs
This was causing issues with recursive procs.
We need to be able to look up the proc's symbol
before we have finished generating it.
2021-12-26 10:45:23 +00:00
Brian Carroll
d08b79295c Fix unique names 2021-12-26 10:40:45 +00:00
Brian Carroll
da4cf721cc Fix equality on empty structures 2021-12-26 10:40:45 +00:00
Brian Carroll
a0afb64cb0 Fix bug storing linker data for generated procs 2021-12-26 10:40:45 +00:00
Brian Carroll
0fbe49dce9 Shorten some variable names 2021-12-26 10:40:45 +00:00
Brian Carroll
ca501fdcf1 Restructure CodeGenHelp to generate IR immediately, in depth-first traversal 2021-12-26 10:40:45 +00:00
ayazhafiz
1f81a598f7 Presence constraint flag -> Enum 2021-12-23 19:40:18 -06:00
ayazhafiz
b97ff380e3 Presence constraints for tag union types
This work is related to restricting tag union sizes in input positions.
As an example, for something like

```
\x -> when x is
    A M -> X
    A N -> X
    A _ -> X
```

we'd like to infer `[A [M, N]* ]` rather than the `[A, [M, N]* ]*` we
infer today. Notice the difference is that the former type tells us we
only accepts `A`s, but the argument of the `A` can be `M`, `N` or
anything else (hence the `_`).

So what's the idea? It's an encoding of the "must have"/"might have"
design discussed in https://github.com/rtfeldman/roc/issues/1758. Let's
take our example above and walk through unification of each branch.

Suppose `x` starts off as a flex var `t`.

```
\x -> when x is
    A M -> X
```

Now we introduce a new kind of constraint called a "presence"
constraint. It says "t has at least [A [M]]". I'll notate this as `t +=
[A [M]]`. When `t` is free as it is here, this is equivalent to `t ~
[A [M]]`.

```
\x -> when x is
    ...
    A N -> X
```

At this branch we introduce the presence constraint `[A [M]] += [A [N]]`.
Notice that there's two tag unions we care about resolving here - one is
the toplevel one that says "I have an `A ...` inside of me", and the
other one is the tag union that's the tyarg to `A`. They are distinct
and at different depths.

For the toplevel one, we first figure out if the number of tags in the
union needs to expand. It does not - we're hoping to resolve the type
`[A [M, N]]`, which only has `A` in the toplevel union. So, we don't
need to do anything extra there, other than the merge the nested tag
unions.

We recurse on the shared tags, and now we have the presence constraint
`[M] += [N]`. At this point it's important to remember that the left and
right hand types are backed by type variables, so this is really
something like `t11 [M] += t12 [N]`, where `[M]` and `[N]` are just what
we know the variables `t11` and `t12` to be at this moment. So how do we
solve for `t11 [M, N]` from here? Well, we can encode this constraint as
a type variable definition and a unification constraint we already know
how to solve:

```
New definition: t11 [M]a    (a fresh)
New constraint: a ~ t12 [N]
```

That's it; upon unification, `t11 [M, N]` falls out.

Okay, last step.

```
\x -> when x is
    ...
    A _ -> X
```

We now have `[A [M, N]] += [A a]`, where `a` is a fresh unbound
variable. Again nothing has to happen on the toplevel. We walk down and
find `t11 [M, N] += t21 a`. This is actually called an "open constraint"; we
differentiate it at the time we generate constraints because it follows
syntactically from the presence of an `_`, but it's semantically
equivalent to the presence constraint `t11 [M, N] += t21 a`. It's just
called opening because literally the only way `t11 [M, N] += t21 a` can
be true is if we set `t11 a`. Well, actually, we assume `a` is a tag
union, so we just make `t11` the open tag union `[M, N]a`. Since `a` is
unbound, this eventually becomes a wildcard and hence falls out `[M, N]*`.
Also, once we open a tag union with an open constraint, we never close
it again.

That's it. The rest falls out recursively. This gives us a really easy
way to encode these ordering constraints in the unification-based system
we have today with minimal additional intervention. We do have to patch
variables in-place sometimes, and the additive nature of these
constraints feels about out-of-place relative to unification, but it
seems to work well.

Resolves #1758
2021-12-23 19:40:18 -06:00