JIT compiler - showing generated machine code

When using LLVM as a JIT compiler, you can use module.dump() to show the generated intermediate code, which is good.

Is there similarly a programmatic way to show the generated x64 machine code in assembly format?

I'm not sure if there is a ready-made solution, but you can consider using the MC component of LLVM to easily write yourself a disassembler (easily == 100 to 200 LOC, if I recall correctly). For inspiration, take a look at how "llvm-mc --disassemble" works.

-- Sanjoy

If you want to do this solely for debugging, the easiest way is to print it out as hex bytes (“0xhhx”, byte) and then either pipe or redirect that output to llvm-mc.

David

From: llvm-dev [mailto:llvm-dev-bounces@lists.llvm.org]
> When using LLVM as a JIT compiler, you can use module.dump() to show the generated
> intermediate code, which is good.
>
> Is there similarly a programmatic way to show the generated x64 machine code in
> assembly format?

I'm not sure if there is a ready-made solution, but you can consider using the MC
component of LLVM to easily write yourself a disassembler (easily == 100 to 200 LOC,
if I recall correctly). For inspiration, take a look at how "llvm-mc --disassemble"
works.

After generating code for the module, we use something like this to run an additional pass to display the assembly in the log:

    legacy::PassManager* pMPasses = new legacy::PassManager();
    target_machine->Options.MCOptions.AsmVerbose = true;
    if (target_machine->addPassesToEmitFile(*pMPasses, *llvm_log,
                                            TargetMachine::CGFT_AssemblyFile)) {
        llvm_log->flush();
        delete pMPasses;
        sysLogger("** could not add emit file pass **");
    } else {
        pMPasses->run(*pMod);
        delete pMPasses;
    }

We found that setting AsmVerbose early would often display different x86 code than was actually in the final functions. There might well be better ways to do this these days.

- Chuck

Note: you have to clone “pMod” before generating the binary code, if you are reusing is this is not equivalent to the binary code generated. This is because the Target adds some “lowering” IR pass that will modify the IR during codegen.