<pre>On Tue, Apr 1, 2008 at 9:49 AM, Vania Joloboff <<a href="mailto:vania@liama.ia.ac.cn">vania@liama.ia.ac.cn</a>> wrote:<br></pre><div class="gmail_quote"><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;">




<div bgcolor="#ffffff" text="#000000">
Hello,<br>
<br>
We are a research project in joint french-chinese laboratory. We are
considering using<br>
 LLVM in our project but we'd like to have some additional info before
we dive in. <br>
Since we are new kids on the block, please bear with us...<br>
<br>
We are interested in using LLVM for emulation of real hardware. What we
have as<br>
 input is the binary code of the program to run. Today we emulate each
instruction <br>
behavior sequentially, which has pros and cons. We want to build a
faster simulator,<br>
and an idea is to decompile the binary code into an LLVM
representation, then compile<br>
it to the simulation host and run it. Hopefully it would be faster
because perhaps we<br>
may use one LLVM instruction for several machine instructions, and we
can benefit <br>
from the real host stack and the real registers instead of a simulated
stack<br>
and simulated registers.<br>
<br>
So we have several questions:<br>
<br>
1. Do you have an opinion on the feasibility of the project ? <br>
           Do you know if it has been done before.</div></blockquote><div>Using LLVM for dynamic binary translation is definitely feasible, last year I was working on llvm-qemu during Google Summer of Code 2007 which in fact does binary translation with LLVM. It is a modified version of qemu which uses the LLVM JIT for optimization and code generation. Currently it translates from ARM machine code to LLVM IR (at basic block level) and via the LLVM JIT to x86 machine code. All source architectures supported by qemu (x86, x86-64, ARM, SPARC, PowerPC, MIPS, m68k) can be translated to LLVM IR this way (adding support for one of these architectures only requires minor changes to llvm-qemu).<br>
 <br>The end result was that llvm-qemu was running about half the speed of regular qemu on the synthetic benchmark nbench (using a hotspot-like approach: interpretation of blocks with few executions and JITing of blocks with high execution counts). However, there is still potential for improvement, one being an efficient implementation of direct block chaining (in certain cases a block can directly jump to its successor instead of falling back to the dispatcher, this is currently implemented with calls instead of jmps, which should be possible to implement with jmps now, after the recent work on tail call optimizations).  Direct block chaining is a very useful optimization, on the nbench test case enabling direct block chaining for regular qemu leads to a 100% speed increase. Another promising improvement would be the capability to build "super"-blocks from a set of connected basic blocks, resembling a "hot path". This work is partially finished and, once complete, should yield a significant performance improvement since a "super"-block offers a lot more optimization potential compared to a single basic block. Nevertheless, it is unlikely that llvm-qemu will ever be much faster than regular qemu (by replacing its code generator completely, which it currently does), which is due to the fact that regular qemu has a very lightweight code generator (it basically only copies blocks of memory and performs some patching to them and only does static register allocation) which generates reasonably good code, with a very low overhead for compilation time. In contrast the LLVM JIT generates really high quality code (in fact the JIT and the static compiler share the same code generator), but at a higher price in terms of compilation time. Ideally the current code generator of qemu would coexist with the LLVM JIT in llvm-qemu, allowing for different levels of code quality/compilation time depending on the execution frequency of a particular block.<br>
<br>I guess in your situation, the chances are much higher that you will see a significant performance increase since you apparently don't do any dynamic binary translation yet, especially if you decide to use your existing interpreter in combination with the LLVM JIT in a hotspot-like manner.<br>
<br>An important question is how you perform the translation from your source architecture to LLVM IR, for llvm-qemu I could benefit from the fact that qemu translates from source machine code to an intermediate representation which has its instructions implemented in C, thus I could use llvm-gcc to compile the instructions to equivalent LLVM IR and did not have to worry about the actual translation from machine code to qemu IR. Going directly from machine code to LLVM IR certainly requires more effort.<br>
<br>Which architectures are you interested in particularly?<br><br><br></div><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><div bgcolor="#ffffff" text="#000000">
<br>
3 We want to generate directly the in-memory IR and dynamicall call the
LLVM code<br>
    generator on a chunk of code that has been decompiled, not a
complete program.<br>
<i>         </i>Is this possible ? Is it worthwile in terms of
performance ?<br>
</div></blockquote><div>Yes, that's perfectly possible and that's what llvm-qemu does too (translation is performed at basic block level).  As Patrick already pointed out, static recompilation is not really feasible in most cases.<br>
<br>If you're interested, you can find llvm-qemu at <a href="http://code.google.com/p/llvm-qemu/">http://code.google.com/p/llvm-qemu/</a>, the Wiki contains a page which lists the progress of the project (including some numbers regarding performance).<br>
<br>Greetings,<br><br>Tilmann Scheller<br></div></div><br>