11 comments

[ 3.0 ms ] story [ 41.8 ms ] thread
While this is quite nifty, I don't see why people other than LLVM developers would be interested in the LLVM IR output. Isn't the final CPU real assembly more informative?
In a literal sense, the LLVM IR is more informative because it literally has more information attached to the instructions. This information gets lost when the machine code is produced.

This information will be very useful to any compiler that uses LLVM as a back end, not just LLVM itself. Of course it may not be particularly useful to anyone else unless they're particularly interested in trying to diagnose why their code is being optimized in a certain way.

I also imagine the compiler developers population has a high overlap with the "neck beard" type c developer, unix person that would prefer not to use a web app as part of their development workflow.

It turns out that there's already a really easy way of executing compiler output on your CPU without the use of JavaScript...

I'm a hobbyist compiler developer who does dev on Atom, debug in repl.it and prototype in Coffescript to generate LLVM IR. The world is big!
>https://github.com/kripken/llvm.js

It seems to be big

I suppose nowadays you can just use something like that to achieve similar thing?

>llc -mtriple=wasm32-unknown-unknown -O3 -filetype=obj main.ll -o main.o

>wasm-ld main.o -o main.wasm --no-entry -allow-undefined

Yes, although part of the fun the demo is that the LLVM tools are themselves running in the browser. Note that the demo is from 2015, so it predates WebAssembly.
Does anyone know what the differences between llvm and wasm are?

Can wasm be optimized as much as llvm? Just wondering if we could have just put llvm in the browser.

One of the precursors of WebAssembly was Portable Native Client (PNaCl)[1], which did use a frozen subset of LLVM IR as its program representation. But LLVM IR was designed to be a compiler IR, not a program binary format. WebAssembly was specifically designed for the Web use case, and unlike LLVM IR it supports streaming compilation and requires structured control flow, which makes it easier and less risky to implement in JS engines.

Other commenters are correct that LLVM IR has more information in it than WebAssembly, but that is working as intended. The idea is that toolchains will do the heavy optimization work so that WebAssembly engines can be simpler and just do the final code generation.

[1] https://developer.chrome.com/native-client/nacl-and-pnacl

WASM is specifically designed to be cpu-independent, so you can run a single .wasm file on any machine.

In contrast, LLVM IR is designed to be cpu- and OS-specific. Take a look at the very first line in the example: ‘target triple = "i386-pc-linux-gnu"’. Decidedly not web-friendly, though perhaps you could try to make a web triple?

The "IR" stands for intermediate representation, it is expressly not CPU/OS specific.

The target triple isn't actually relevant in this demo, try setting it to "42" and it will still compile and run. For documentation so you know I'm not just bullshitting http://llvm.org/docs/LangRef.html#target-triple note that it's optional and can be overriden at compile time (which is what is happening here).

In a true browser implementation the target triple would be set to whatever platform the browser is running on, that way the browser compiled the web distributed IR straight to native code.

Google's PNACL, a precursor to WASM which shipped in Chrome, did exactly the above using LLVM IR. A web target triple was not needed as the LLVM IR was the web representation and the platform the browser was running on was the target triple. No need for a new web intermediary.

WASM works the same way, you distribute the representation and the browser converts it into a native target via compilation. WASM was designed to be less foreign to browser data structures/types and easier to implement in existing browser JS engines though. It's also easier to implement tiered compilation on. There are other reasons WASM was made instead of continuing to use LLVM IR but it's not because IR was CPU/OS specific.

LLVM does have web target triples though nowadays, wasm32 and wasm64. Previously it also had an asmjs target (which worked with standard JS engines at slower speeds without modification).