/// create - Create an return a new JIT compiler if there is one available /// for the current target. Otherwise, return null. /// ExecutionEngine *JIT::create(ModuleProvider *MP, IntrinsicLowering *IL) { if (MArch == 0) { std::string Error; MArch = TargetMachineRegistry::getClosestTargetForJIT(Error); if (MArch == 0) return 0; } else if (MArch->JITMatchQualityFn() == 0) { std::cerr << "WARNING: This target JIT is not designed for the host you are" << " running. If bad things happen, please choose a different " << "-march switch.\n"; } // Allocate a target... TargetMachine *Target = MArch->CtorFn(*MP->getModule(), IL); assert(Target && "Could not allocate target machine!"); // If the target supports JIT code generation, return a new JIT now. if (TargetJITInfo *TJ = Target->getJITInfo()) return new JIT(MP, *Target, *TJ); return 0; }
// main - Entry point for the llc compiler. // int main(int argc, char **argv) { cl::ParseCommandLineOptions(argc, argv, " llvm system compiler\n"); PrintStackTraceOnErrorSignal(); // Load the module to be compiled... std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename)); if (M.get() == 0) { std::cerr << argv[0] << ": bytecode didn't read correctly.\n"; return 1; } Module &mod = *M.get(); // Allocate target machine. First, check whether the user has // explicitly specified an architecture to compile for. TargetMachine* (*TargetMachineAllocator)(const Module&, IntrinsicLowering *) = 0; if (MArch == 0) { std::string Err; MArch = TargetMachineRegistry::getClosestStaticTargetForModule(mod, Err); if (MArch == 0) { std::cerr << argv[0] << ": error auto-selecting target for module '" << Err << "'. Please use the -march option to explicitly " << "pick a target.\n"; return 1; } } std::auto_ptr<TargetMachine> target(MArch->CtorFn(mod, 0)); assert(target.get() && "Could not allocate target machine!"); TargetMachine &Target = *target.get(); const TargetData &TD = Target.getTargetData(); // Build up all of the passes that we want to do to the module... PassManager Passes; Passes.add(new TargetData("llc", TD.isLittleEndian(), TD.getPointerSize(), TD.getPointerAlignment(), TD.getDoubleAlignment())); // Figure out where we are going to send the output... std::ostream *Out = 0; if (OutputFilename != "") { if (OutputFilename != "-") { // Specified an output filename? if (!Force && std::ifstream(OutputFilename.c_str())) { // If force is not specified, make sure not to overwrite a file! std::cerr << argv[0] << ": error opening '" << OutputFilename << "': file exists!\n" << "Use -f command line argument to force output\n"; return 1; } Out = new std::ofstream(OutputFilename.c_str()); // Make sure that the Out file gets unlinked from the disk if we get a // SIGINT RemoveFileOnSignal(OutputFilename); } else { Out = &std::cout; } } else { if (InputFilename == "-") { OutputFilename = "-"; Out = &std::cout; } else { OutputFilename = GetFileNameRoot(InputFilename); if (MArch->Name[0] != 'c' || MArch->Name[1] != 0) // not CBE OutputFilename += ".s"; else OutputFilename += ".cbe.c"; if (!Force && std::ifstream(OutputFilename.c_str())) { // If force is not specified, make sure not to overwrite a file! std::cerr << argv[0] << ": error opening '" << OutputFilename << "': file exists!\n" << "Use -f command line argument to force output\n"; return 1; } Out = new std::ofstream(OutputFilename.c_str()); if (!Out->good()) { std::cerr << argv[0] << ": error opening " << OutputFilename << "!\n"; delete Out; return 1; } // Make sure that the Out file gets unlinked from the disk if we get a // SIGINT RemoveFileOnSignal(OutputFilename); } } // Ask the target to add backend passes as necessary if (Target.addPassesToEmitAssembly(Passes, *Out)) { std::cerr << argv[0] << ": target '" << Target.getName() << "' does not support static compilation!\n"; if (Out != &std::cout) delete Out; // And the Out file is empty and useless, so remove it now. std::remove(OutputFilename.c_str()); return 1; } else { // Run our queue of passes all at once now, efficiently. Passes.run(*M.get()); } // Delete the ostream if it's not a stdout stream if (Out != &std::cout) delete Out; return 0; }
// main - Entry point for the llc compiler. // int main(int argc, char **argv) { llvm_shutdown_obj X; // Call llvm_shutdown() on exit. cl::ParseCommandLineOptions(argc, argv, "llvm system compiler\n"); sys::PrintStackTraceOnErrorSignal(); // Load the module to be compiled... std::string ErrorMessage; std::auto_ptr<Module> M; std::auto_ptr<MemoryBuffer> Buffer( MemoryBuffer::getFileOrSTDIN(InputFilename, &ErrorMessage)); if (Buffer.get()) M.reset(ParseBitcodeFile(Buffer.get(), &ErrorMessage)); if (M.get() == 0) { std::cerr << argv[0] << ": bitcode didn't read correctly.\n"; std::cerr << "Reason: " << ErrorMessage << "\n"; return 1; } Module &mod = *M.get(); // If we are supposed to override the target triple, do so now. if (!TargetTriple.empty()) mod.setTargetTriple(TargetTriple); // Allocate target machine. First, check whether the user has // explicitly specified an architecture to compile for. if (MArch == 0) { std::string Err; MArch = TargetMachineRegistry::getClosestStaticTargetForModule(mod, Err); if (MArch == 0) { std::cerr << argv[0] << ": error auto-selecting target for module '" << Err << "'. Please use the -march option to explicitly " << "pick a target.\n"; return 1; } } // Package up features to be passed to target/subtarget std::string FeaturesStr; if (MCPU.size() || MAttrs.size()) { SubtargetFeatures Features; Features.setCPU(MCPU); for (unsigned i = 0; i != MAttrs.size(); ++i) Features.AddFeature(MAttrs[i]); FeaturesStr = Features.getString(); } std::auto_ptr<TargetMachine> target(MArch->CtorFn(mod, FeaturesStr)); assert(target.get() && "Could not allocate target machine!"); TargetMachine &Target = *target.get(); // Figure out where we are going to send the output... std::ostream *Out = GetOutputStream(argv[0]); if (Out == 0) return 1; // If this target requires addPassesToEmitWholeFile, do it now. This is // used by strange things like the C backend. if (Target.WantsWholeFile()) { PassManager PM; PM.add(new TargetData(*Target.getTargetData())); if (!NoVerify) PM.add(createVerifierPass()); // Ask the target to add backend passes as necessary. if (Target.addPassesToEmitWholeFile(PM, *Out, FileType, Fast)) { std::cerr << argv[0] << ": target does not support generation of this" << " file type!\n"; if (Out != &std::cout) delete Out; // And the Out file is empty and useless, so remove it now. sys::Path(OutputFilename).eraseFromDisk(); return 1; } PM.run(mod); } else { // Build up all of the passes that we want to do to the module. ExistingModuleProvider Provider(M.release()); FunctionPassManager Passes(&Provider); Passes.add(new TargetData(*Target.getTargetData())); #ifndef NDEBUG if (!NoVerify) Passes.add(createVerifierPass()); #endif // Ask the target to add backend passes as necessary. MachineCodeEmitter *MCE = 0; switch (Target.addPassesToEmitFile(Passes, *Out, FileType, Fast)) { default: assert(0 && "Invalid file model!"); return 1; case FileModel::Error: std::cerr << argv[0] << ": target does not support generation of this" << " file type!\n"; if (Out != &std::cout) delete Out; // And the Out file is empty and useless, so remove it now. sys::Path(OutputFilename).eraseFromDisk(); return 1; case FileModel::AsmFile: break; case FileModel::MachOFile: MCE = AddMachOWriter(Passes, *Out, Target); break; case FileModel::ElfFile: MCE = AddELFWriter(Passes, *Out, Target); break; } if (Target.addPassesToEmitFileFinish(Passes, MCE, Fast)) { std::cerr << argv[0] << ": target does not support generation of this" << " file type!\n"; if (Out != &std::cout) delete Out; // And the Out file is empty and useless, so remove it now. sys::Path(OutputFilename).eraseFromDisk(); return 1; } Passes.doInitialization(); // Run our queue of passes all at once now, efficiently. // TODO: this could lazily stream functions out of the module. for (Module::iterator I = mod.begin(), E = mod.end(); I != E; ++I) if (!I->isDeclaration()) Passes.run(*I); Passes.doFinalization(); } // Delete the ostream if it's not a stdout stream if (Out != &std::cout) delete Out; return 0; }