diff --git a/tools/jello/jello.cpp b/tools/jello/jello.cpp index 3cf83bce8d7..1add86fa59d 100644 --- a/tools/jello/jello.cpp +++ b/tools/jello/jello.cpp @@ -9,10 +9,10 @@ //===----------------------------------------------------------------------===// #include "llvm/Module.h" +#include "llvm/PassManager.h" #include "llvm/Bytecode/Reader.h" -#include "llvm/CodeGen/MFunction.h" -#include "../lib/Target/X86/X86.h" // FIXME: become generic eventually -#include "../lib/Target/X86/X86InstructionInfo.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetMachineImpls.h" #include "Support/CommandLine.h" #include "Support/Statistic.h" @@ -25,52 +25,39 @@ namespace { cl::value_desc("function name")); } - -/// ExecuteFunction - Compile the specified function to machine code, and -/// execute it. -/// -static void ExecuteFunction(Function &F) { - X86InstructionInfo II; - - // Perform instruction selection to turn the function into an x86 SSA form - MFunction *MF = X86SimpleInstructionSelection(F); - - // TODO: optional optimizations go here - - // If -debug is specified, output selected code to stderr - /*DEBUG*/(MF->print(std::cerr, II)); - - // Perform register allocation to convert to a concrete x86 representation - X86SimpleRegisterAllocation(MF); - - // If -debug is specified, output compiled code to stderr - /*DEBUG*/(X86PrintCode(MF, std::cerr)); - - // Emit register allocated X86 code now... - void *PFun = X86EmitCodeToMemory(MF); - - // We don't need the machine specific representation for this function anymore - delete MF; -} - - //===----------------------------------------------------------------------===// // main Driver function // int main(int argc, char **argv) { cl::ParseCommandLineOptions(argc, argv, " llvm just in time compiler\n"); - std::string ErrorMsg; - if (Module *M = ParseBytecodeFile(InputFile, &ErrorMsg)) { - for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) - if (I->getName() == MainFunction) - ExecuteFunction(*I); + // Allocate a target... in the future this will be controllable on the + // command line. + std::auto_ptr target(allocateX86TargetMachine()); + assert(target.get() && "Could not allocate target machine!"); - delete M; - return 0; + TargetMachine &Target = *target.get(); + + // Parse the input bytecode file... + std::string ErrorMsg; + std::auto_ptr M(ParseBytecodeFile(InputFile, &ErrorMsg)); + if (M.get() == 0) { + std::cerr << argv[0] << ": bytecode '" << InputFile + << "' didn't read correctly: << " << ErrorMsg << "\n"; + return 1; } + + PassManager Passes; + if (Target.addPassesToJITCompile(Passes)) { + std::cerr << argv[0] << ": target '" << Target.TargetName + << "' doesn't support JIT compilation!\n"; + return 1; + } + + // JIT all of the methods in the module. Eventually this will JIT functions + // on demand. + Passes.run(*M.get()); - std::cerr << "Error parsing '" << InputFile << "': " << ErrorMsg << "\n"; return 1; }