<div dir="ltr">Fixing <a href="mailto:llvm-dev@llvm.org">llvm-dev@llvm.org</a> to <a href="mailto:llvm-dev@lists.llvm.org">llvm-dev@lists.llvm.org</a></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Nov 17, 2020 at 11:27 AM Thomas Lively <<a href="mailto:tlively@google.com">tlively@google.com</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div dir="ltr">Thanks for your work on this, Paulo!<br><br>Here's some more detail about how function pointers work today in the<br>WebAssembly backend and how they differ from the `funcref` Paulo is working on.<br><br>Today in the WebAssembly backend, both function and data pointers are emitted as<br>WebAssembly `i32` values. Data pointers are indices into the WebAssembly linear<br>memory and function pointers are indices into a separate function table. The<br>linker is responsible for laying out function references in the table and<br>resolving function pointer relocations to the correct table indices.<br><br>WebAssembly `funcref` values are an alternative mechanism for referencing<br>functions that our LLVM backend does not yet support. Unlike the `i32` table<br>indices used to implement normal function pointers, `funcref` values are opaque<br>and non-integral. `funcref`s cannot be stored into memory and cannot be<br>inspected, but they can be called.<br><br>We would like to model both table indices and `funcref`s as function pointers in<br>LLVM IR since they are both callable in WebAssembly. Since table indices are<br>numbers that can be inspected, manipulated, and stored into memory, it makes<br>sense to model them as LLVM IR function pointers into a "normal" address space<br>like address space 0. `funcref` values should instead be modeled as LLVM IR<br>function pointers into a non-integral address space. Since we want to be able to<br>use both in a single program, we need the ability to call function pointers of<br>different address spaces in the same LLVM IR module. That means having multiple<br>program address spaces, as described in this RFC and Paulo's corresponding<br>patch.<br></div><br><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Tue, Nov 17, 2020 at 9:11 AM Paulo Matos <pmatos@linki.tools> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex">Hello all,<br>
<br>
TL;DR; The current design for the implementation of reference types in<br>
the WebAssembly backend requires the use of multiple program address<br>
spaces. We propose an implementation of multiple address spaces in<br>
D91428 [1] - this is a backwards compatible change.<br>
<br>
# Problem<br>
<br>
Currently the default program address and the default data address space<br>
is the same, namely AS0. We can at the moment, change the program<br>
address space with P<n> in the data layout string. This allows harvard<br>
architectures to separate code and data into different address spaces.<br>
However, only one program address space is allowed.<br>
<br>
At Igalia [2], we are interested in implementing support for reference<br>
types [3] on the WebAssembly backend. After discussions with Thomas<br>
Lively and Andy Wingo, the design we have for reference types involves<br>
having funcrefs and externrefs living in a different address spaces<br>
(non-integral) from normal code/data. Since funcrefs are callable, we<br>
also need to be able to call them. However, as things stand if we use<br>
`P1` in the data layout, normal function calls will cease to work.<br>
<br>
# Design Summary<br>
<br>
The reference types implementation introduces two (reference) types:<br>
funcrefs and externrefs.<br>
Funcrefs are references to functions that can be called, while<br>
externrefs are opaque. Because of the way they interact with memory they<br>
need to live in a separate address space. However, to call funcrefs<br>
which live in a separate address space, this address space needs to be<br>
marked as a program address space. Since we wish that normal function<br>
calls keep working as well, we need AS0 to be a program address space<br>
too. This is what the solution to this RFC addresses. The Data Layout<br>
string for WebAssembly would therefore contain ni:1-P0-P1.<br>
<br>
# Solution<br>
<br>
As mentioned in the TL;DR; the proposed implementation is live in D91428<br>
[1]. The patch is small and backwards compatible, and there should be no<br>
visible changes, unless you use multiple program address spaces.<br>
<br>
With the patch, you should be able to use multiple Px-Py-... to mark<br>
your address spaces as code address spaces. The first one will be<br>
considered the default program address space. So, the order in which the<br>
Ps show up in the data layout string _matters_.<br>
<br>
The program address spaces are kept in a small vector without<br>
duplicates. Therefore P0-P1-P0 is the same as P0-P1, and P0 is the<br>
default address space.<br>
<br>
<br>
# Refs<br>
<br>
[1] <a href="https://reviews.llvm.org/D91428" rel="noreferrer" target="_blank">https://reviews.llvm.org/D91428</a><br>
[2] <a href="https://www.igalia.com" rel="noreferrer" target="_blank">https://www.igalia.com</a><br>
[3] <a href="https://webassembly.github.io/reference-types/core/" rel="noreferrer" target="_blank">https://webassembly.github.io/reference-types/core/</a><br>
<br>
Regards,<br>
-- <br>
Paulo Matos<br>
</blockquote></div>
</blockquote></div>