Fix big bug introduced with symbol table changes
[oota-llvm.git] / tools / jello / jello.cpp
1 //===-- jello.cpp - LLVM Just in Time Compiler ----------------------------===//
2 //
3 // This tool implements a just-in-time compiler for LLVM, allowing direct
4 // execution of LLVM bytecode in an efficient manner.
5 //
6 // FIXME: This code will get more object oriented as we get the call back
7 // intercept stuff implemented.
8 //
9 //===----------------------------------------------------------------------===//
10
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"
18
19
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";
26   }
27   void finishFunction(MachineFunction &F) {
28     std::cout << "\n";
29   }
30   void startBasicBlock(MachineBasicBlock &BB) {
31     std::cout << "\n--- Basic Block: " << BB.getBasicBlock()->getName() << "\n";
32   }
33
34   void emitByte(unsigned char B) {
35     std::cout << "0x" << std::hex << (unsigned int)B << std::dec << " ";
36   }
37   void emitPCRelativeDisp(Value *V) {
38     std::cout << "<" << V->getName() << ": 0x00 0x00 0x00 0x00> ";
39   }
40 };
41
42
43 namespace {
44   cl::opt<std::string>
45   InputFile(cl::desc("<input bytecode>"), cl::Positional, cl::init("-"));
46
47   cl::opt<std::string>
48   MainFunction("f", cl::desc("Function to execute"), cl::init("main"),
49                cl::value_desc("function name"));
50 }
51
52 //===----------------------------------------------------------------------===//
53 // main Driver function
54 //
55 int main(int argc, char **argv) {
56   cl::ParseCommandLineOptions(argc, argv, " llvm just in time compiler\n");
57
58   // Allocate a target... in the future this will be controllable on the
59   // command line.
60   std::auto_ptr<TargetMachine> target(allocateX86TargetMachine());
61   assert(target.get() && "Could not allocate target machine!");
62
63   TargetMachine &Target = *target.get();
64
65   // Parse the input bytecode file...
66   std::string ErrorMsg;
67   std::auto_ptr<Module> M(ParseBytecodeFile(InputFile, &ErrorMsg));
68   if (M.get() == 0) {
69     std::cerr << argv[0] << ": bytecode '" << InputFile
70               << "' didn't read correctly: << " << ErrorMsg << "\n";
71     return 1;
72   }
73
74   PassManager Passes;
75
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";
80     return 1;
81   }
82
83   // Turn the machine code intermediate representation into bytes in memory that
84   // may be executed.
85   //
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";
90     return 1;
91   }
92
93   // JIT all of the methods in the module.  Eventually this will JIT functions
94   // on demand.
95   Passes.run(*M.get());
96   
97   return 0;
98 }
99