7 ms·
> This is part of the inspiration for LLVM, or Low Level Virtual Machine, which is a kind of "abstract assembly" that looks vaguely like machine code but is pla
by azakai 10y ago
> This is part of the inspiration for LLVM, or Low Level Virtual Machine, which is a kind of "abstract assembly" that looks vaguely like machine code but is platform-independent.
LLVM is not platform-independent.
LLVM IR has baked-in constants, ABI details, and other platform-specific things. The "LLVM IR is a compiler IR" post has a good summary,
http://comments.gmane.org/gmane.comp.compilers.llvm.devel/43769 http://comments.gmane.org/gmane.comp.compilers.llvm.devel/43...
One result of that is that the following quote is not true:
> a compiler writer can target LLVM and then have his language work across platforms (e.g. on Linux, Mac, and Windows machines)
Actually a compiler must generate different LLVM IR for each platform.
It is true that LLVM does abstract some or even most things away - CPU architecture is (mostly) handled for you, for example, which is what the author mentions - but many important things aren't.
> as well as with other languages that use LLVM
You'll still need to make sure to use the right ABIs for those languages.
In fact, LLVM has somewhat poor abstraction for the C ABI, in that it exists in clang and not in LLVM, as a result, Rust has had to duplicate a bunch of that code. This point actually supports the author's position - targeting Rust would actually be a more portable target than LLVM!
Overall, it might make sense to compile to Rust. But probably to Rust MIR, the IR they are developing. MIR needs to mature and stabilize, but there are already signs of an ecosystem starting to form around it. It's interesting speculation, but it would be exciting to see Rust MIR be "the new LLVM."
- ZenoArrow 10y agoReading the article, I get the impression that the VM part of the LLVM name is causing some confusion. For all those reading this that may have thought LLVM acts like a low-level version of something like the JVM (as the name suggests, I got caught out with this before too), it's not the case. LLVM is a compiler framework, the main output of which isn't bytecode for a VM but is rather machine code for the platform you're running on. There is no performance overhead from running LLVM-generated code because LLVM is not part of the final runtime.
- ternaryoperator 10y agoThat's very helpful. Having only read about LLVM without actually using it, your note clarified confusion I had about it.
- ZenoArrow 10y agoYou're welcome ternaryoperator.
- groovy2shoes 10y agoLLVM is a virtual machine, though, even in the sense that the Java VM or the Lua VM are virtual machines! Virtual machines (a.k.a. abstract machines, though technically virtual machines are a subset of the abstract machines) are simply computers that are implemented in software. When you target the LLVM, you do generate bitcode in much the same way you'd generate bitcode for the JVM (though the bitcode itself is very different). What makes the LLVM low-level, compared to the JVM or the LVM for example, is that it doesn't offer the same level of abstraction that they do. For example, the JVM abstracts not only the machine, but also the operating system, the program linker/loader, and even some devices, etc. On the other hand, the LLVM essentially abstracts the CPU's instruction set, and that's about it. This is why even when generating LLVM bitcode rather than native code, you still need to worry about things like ABI, naming conventions, system calls, etc. -- because those things are separate from the physical machine's ISA. However, just like with physical machines, I'd wager that it'd be possible to implement those abstractions on top of the LLVM, though it's likely easier and more efficient to just have a retargetable code generator. Note that the LLVM can also operate as a JIT VM much like Java's HotSpot VM or LuaJIT's VM, and in such a mode the differences are less obvious from the outside. Similarly, both Java and Lua can be compiled to native code (in fact, in order for JIT to work, this must be the case), but going a step further, they can be compiled AOT. In a sort of "middle-ground", they can be compiled to their respective bitcode, and then further compiled into native code -- precisely the way the LLVM tends to operate. The idea goes way back. There are plenty of examples throughout history of compilers targeting virtual (abstract) machines, and it offers several advantages. Portability is the one everyone talks about, but there can also be advantages for code density and compiler complexity, among others. For example, the ANSI/ISO/IEC standard for the C programming language defines the semantics of C in terms of the operation of an abstract machine. A handy way to specify the operational semantics of a language! [EDIT: In fact, the original purpose of abstract machines was for this kind of formal specification of semantics; it was nearly a decade before people realized the other advantages of AMs when used as an abstraction in programs themselves.] See also: Landin's SECD machine, BCPL (O-code), UCSD Pascal (P-code), (O)Caml (CAM - categorical abstract machine), the G-machine, and many more.
- kibwen 10y agoI think this is a bit too keen to hew to the textbook definition of "virtual machine". In modern industry practice a "virtual machine" tends to imply "we wrote an interpreter, and to run your program you execute this interpreter and feed it your program". In the interest of being precise, I'd rather call LLVM an "abstract" machine, in the same vein as the C abstract machine defined by the C language specification (https://blogs.msdn.microsoft.com/larryosterman/2007/05/16/the-c-abstract-machine/ https://blogs.msdn.microsoft.com/larryosterman/2007/05/16/th...).
- wcrichton 10y agoTotally fair points, it's an overgeneralization to say that LLVM gives you platform-independence for free (look at Rust's battle for Windows for some perspective!). Perhaps you could consider that another +1 for Rust is that it manages those platform differences well. As for compiling to MIR, that's a solid point--I think the only reason you would compile to Rust instead of MIR is that it's easier as the compiler writer. As mentioned in the post, you can write code generators quickly just using quasiquotations.
- steveklabnik 10y ago> (look at Rust's battle for Windows for some perspective!) Or in other directions, there's some instances where Windows support is _better_ than other platforms, like stack probes.
- kibwen 10y agoMIR will likely never be "stabilized" in the sense of providing a reliable and unchanging public interface. AFAIK, this is what HIR is for (the IR that's one step above MIR), which is how syntax extensions are intended to be stabilized.