Skip to content

Instantly share code, notes, and snippets.

@jaredramirez
Last active October 11, 2020 16:49
Show Gist options
  • Save jaredramirez/99cb8d68c8b39c7d8804cfb013d68bf4 to your computer and use it in GitHub Desktop.
Save jaredramirez/99cb8d68c8b39c7d8804cfb013d68bf4 to your computer and use it in GitHub Desktop.

Builtin Bitcode Generations

Currently, Roc generates builtin functions for things thare are not provided as an LLVM intrensic. The way this is done is by writing the functions in Rust, the compiling with rustc and emiting LLVM bitcode. Then, the compiler uses that file as a base and adds to it as part of the code gen process. So far this is working great, but there seems to be a limitation to this approach. To compile Rust to LLVM bitcode, you can't use external crates. This effects the builtins we write in two major ways:

  1. You can't use any code from crates.io
  2. Relatedly, you can only use rust primitives (no core or std)

When adding the Num.atan function, which doesn't have an LLVM intrensic, we tried to use the libm crate. After running into the problem mentioned above, we ended up copying just the atan function from the crate into the Roc module. While this works in a one-off case, it's not an ideal solution long term. This came up again shortly after, when trying to implement the countGraphemes method from the unicode-segmentation crate. After trying to figure out ways to use more external crates in the bitcode generation, I think there are a couple possible solutions:

  1. Clone all external crates into a vendor folder, then compile each one to bitcode, the link them all into 1 big bitcode file.

I have solution patrially working. We can compile each library into it's own bitcode file and join them using llvm-link. The cons for this approach are that we need to clone any external library, including core and compile them separately. This isnt' too bad, especially since we can do some optimization with LLVM to drop any dead code, etc, etc to remove any parts of the external crates that we don't use.

  1. Clone each function we need from external crates into the builints/bitcode crate directly.

This makes the compliation eaiser, but

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment