4 ms·
LLVM 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 te
by groovy2shoes 10y ago
LLVM 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...).
- groovy2shoes 10y ago> I think this is a bit too keen to hew to the textbook definition of "virtual machine". That's interesting to me because I haven't ever read any textbook on virtual machines. If you could recommend one, I'd be very interested (especially if it covers designing an ISA that's a good fit for your language, which seems like a dark art to me; I've seen plenty of examples but no design docs or notes whatsoever). > 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". My experience has been exactly the opposite: people have a preference for the word interpreter. When they've written an interpreter, they call it an interpreter. When they've written a virtual machine, it's still often called an interpreter. For example, you rarely hear talk of the Python VM, Lua VM, Scheme VM, Lisp VM, etc. the way you hear talk about the JVM. I normally hear "the Python interpreter" or "the Lua interpreter", etc. I sometimes even hear these sorts of VMs referred to as bitcode or bytecode interpreters. > 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 I'd normally be with you on that one, but I referred to it as a virtual machine here for two reasons: 1) I most often hear the terms "virtual machine" and "abstract machine" used interchangeably, and 2) the LLVM -- Low-Level Virtual Machine -- is called a virtual machine by its creators. All in all, the distinction between the two isn't a large one, and only rarely an important one, so I thought it best in this case to avoid causing any more confusion than I already felt I might :) (As an aside, I think a big problem with the computation science field -- both in academia and in industry, though perhaps more pronounced in industry -- is the sheer lack of (and sometimes even disdain for!) precision in our jargon. Abstract vs. virtual machines is, of course, a topical example, but many others come to mind: parser, DSL, interface, object, message, native, relational, lightweight, functional, and many more. Of particular annoyance to me is the cloud of meanings surrounding the word "type" and its variations, along with a great deal of modifiers typically used alongside it ("strong", "weak", etc.). It's enough to drive the more formal/rigorous/pedantic of us batshit, myself included.)