1 //===-- jello.cpp - LLVM Just in Time Compiler ----------------------------===//
3 // This tool implements a just-in-time compiler for LLVM, allowing direct
4 // execution of LLVM bytecode in an efficient manner.
6 // FIXME: This code will get more object oriented as we get the call back
7 // intercept stuff implemented.
9 //===----------------------------------------------------------------------===//
11 #include "llvm/Module.h"
12 #include "llvm/PassManager.h"
13 #include "llvm/Bytecode/Reader.h"
14 #include "llvm/Target/TargetMachine.h"
15 #include "llvm/Target/TargetMachineImpls.h"
16 #include "Support/CommandLine.h"
17 #include "Support/Statistic.h"
20 #include "llvm/CodeGen/MachineCodeEmitter.h"
21 #include "llvm/CodeGen/MachineFunction.h"
22 struct JelloMachineCodeEmitter : public MachineCodeEmitter {
23 void startFunction(MachineFunction &F) {
24 std::cout << "\n**** Writing machine code for function: "
25 << F.getFunction()->getName() << "\n";
27 void finishFunction(MachineFunction &F) {
30 void startBasicBlock(MachineBasicBlock &BB) {
31 std::cout << "\n--- Basic Block: " << BB.getBasicBlock()->getName() << "\n";
34 void emitByte(unsigned char B) {
35 std::cout << "0x" << std::hex << (unsigned int)B << std::dec << " ";
37 void emitPCRelativeDisp(Value *V) {
38 std::cout << "<" << V->getName() << ": 0x00 0x00 0x00 0x00> ";
45 InputFile(cl::desc("<input bytecode>"), cl::Positional, cl::init("-"));
48 MainFunction("f", cl::desc("Function to execute"), cl::init("main"),
49 cl::value_desc("function name"));
52 //===----------------------------------------------------------------------===//
53 // main Driver function
55 int main(int argc, char **argv) {
56 cl::ParseCommandLineOptions(argc, argv, " llvm just in time compiler\n");
58 // Allocate a target... in the future this will be controllable on the
60 std::auto_ptr<TargetMachine> target(allocateX86TargetMachine());
61 assert(target.get() && "Could not allocate target machine!");
63 TargetMachine &Target = *target.get();
65 // Parse the input bytecode file...
67 std::auto_ptr<Module> M(ParseBytecodeFile(InputFile, &ErrorMsg));
69 std::cerr << argv[0] << ": bytecode '" << InputFile
70 << "' didn't read correctly: << " << ErrorMsg << "\n";
76 // Compile LLVM Code down to machine code in the intermediate representation
77 if (Target.addPassesToJITCompile(Passes)) {
78 std::cerr << argv[0] << ": target '" << Target.getName()
79 << "' doesn't support JIT compilation!\n";
83 // Turn the machine code intermediate representation into bytes in memory that
86 JelloMachineCodeEmitter MCE;
87 if (Target.addPassesToEmitMachineCode(Passes, MCE)) {
88 std::cerr << argv[0] << ": target '" << Target.getName()
89 << "' doesn't support machine code emission!\n";
93 // JIT all of the methods in the module. Eventually this will JIT functions