llc.cpp revision 3da94aec4d429b2ba0f65fa040c33650cade196b
15b836c4a06c584544647d5b013b193510ac5ced5Chris Lattner//===-- llc.cpp - Implement the LLVM Native Code Generator ----------------===// 23da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman// 37c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell// The LLVM Compiler Infrastructure 47c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell// 57c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell// This file was developed by the LLVM research group and is distributed under 67c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell// the University of Illinois Open Source License. See LICENSE.TXT for details. 73da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman// 87c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell//===----------------------------------------------------------------------===// 9e737c7ac63f1e4359c508601d5be60f7551b076dChris Lattner// 10e40eae73705d2ea55dc50d664d1be3ea04c545c8Brian Gaeke// This is the llc code generator driver. It provides a convenient 113da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman// command-line interface for generating native assembly-language code 12e40eae73705d2ea55dc50d664d1be3ea04c545c8Brian Gaeke// or C code, given LLVM bytecode. 13e737c7ac63f1e4359c508601d5be60f7551b076dChris Lattner// 14b79757c621c83dc3f410aacdc6db7639f9e47c6eChris Lattner//===----------------------------------------------------------------------===// 15cb465fc71ecb64d3d168a0cf754fa442abb0f6f9Vikram S. Adve 16cb465fc71ecb64d3d168a0cf754fa442abb0f6f9Vikram S. Adve#include "llvm/Bytecode/Reader.h" 17805eb96727fc07c4b599528f91370841d722bffaVikram S. Adve#include "llvm/Target/TargetMachine.h" 18e45110e01282862e95c3d28c489dedd9a08ffa31Chris Lattner#include "llvm/Target/TargetMachineRegistry.h" 1965f1b895bb1c196409747c60373b2fbfbf5fe6b4Chris Lattner#include "llvm/Transforms/Scalar.h" 2046ac43c1bbdf010507f61750368297889ac1b6c6Chris Lattner#include "llvm/Module.h" 21cd50d3fafabec10c09f3ed0466924a951943d6d0Chris Lattner#include "llvm/PassManager.h" 227d0ba026401321be1645b4142abeb85e943d0577Vikram S. Adve#include "llvm/Pass.h" 23551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/CommandLine.h" 24551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/PluginLoader.h" 25bed85ff010b95923646ed4e187a5d432cedf67daChris Lattner#include "llvm/System/Signals.h" 2678f7e1a9cdc9a373c9a18598cd5e47ac5476bfe6Chris Lattner#include <fstream> 2786f42bdad93677fa0ca33b27afb0f493028376cbReid Spencer#include <iostream> 2886f42bdad93677fa0ca33b27afb0f493028376cbReid Spencer#include <memory> 297d0ba026401321be1645b4142abeb85e943d0577Vikram S. Adve 30d0fde30ce850b78371fd1386338350591f9ff494Brian Gaekeusing namespace llvm; 31d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke 327d0ba026401321be1645b4142abeb85e943d0577Vikram S. Adve// General options for llc. Other pass-specific options are specified 337d0ba026401321be1645b4142abeb85e943d0577Vikram S. Adve// within the corresponding llc passes, and target-specific options 347d0ba026401321be1645b4142abeb85e943d0577Vikram S. Adve// and back-end code generation options are specified with the target machine. 353da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman// 36b5881f126d4baab41dc7efb2824a53601ef167b0Chris Lattnerstatic cl::opt<std::string> 375ff62e90d0bc321206023897edc1e2691cb0fbb6Chris LattnerInputFilename(cl::Positional, cl::desc("<input bytecode>"), cl::init("-")); 385ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner 39b5881f126d4baab41dc7efb2824a53601ef167b0Chris Lattnerstatic cl::opt<std::string> 405ff62e90d0bc321206023897edc1e2691cb0fbb6Chris LattnerOutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename")); 415ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner 425ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattnerstatic cl::opt<bool> Force("f", cl::desc("Overwrite output files")); 435ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner 44e45110e01282862e95c3d28c489dedd9a08ffa31Chris Lattnerstatic cl::opt<const TargetMachineRegistry::Entry*, false, TargetNameParser> 45e45110e01282862e95c3d28c489dedd9a08ffa31Chris LattnerMArch("march", cl::desc("Architecture to generate assembly for:")); 463da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 473524fc2197c17edcea786a9bb0e00246438dba90Chris Lattner// GetFileNameRoot - Helper function to get the basename of a filename... 48b5881f126d4baab41dc7efb2824a53601ef167b0Chris Lattnerstatic inline std::string 49e45110e01282862e95c3d28c489dedd9a08ffa31Chris LattnerGetFileNameRoot(const std::string &InputFilename) { 50b5881f126d4baab41dc7efb2824a53601ef167b0Chris Lattner std::string IFN = InputFilename; 51b5881f126d4baab41dc7efb2824a53601ef167b0Chris Lattner std::string outputFilename; 522f64f9f264d30dd0ac4880eb16ba9eeac538e94cVikram S. Adve int Len = IFN.length(); 53b5d09bf4cc7769ccbd86a96fb8ea92e3c6e3bbc7John Criswell if ((Len > 2) && 54b5d09bf4cc7769ccbd86a96fb8ea92e3c6e3bbc7John Criswell IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') { 55b5881f126d4baab41dc7efb2824a53601ef167b0Chris Lattner outputFilename = std::string(IFN.begin(), IFN.end()-3); // s/.bc/.s/ 562f64f9f264d30dd0ac4880eb16ba9eeac538e94cVikram S. Adve } else { 573524fc2197c17edcea786a9bb0e00246438dba90Chris Lattner outputFilename = IFN; 582f64f9f264d30dd0ac4880eb16ba9eeac538e94cVikram S. Adve } 592f64f9f264d30dd0ac4880eb16ba9eeac538e94cVikram S. Adve return outputFilename; 602f64f9f264d30dd0ac4880eb16ba9eeac538e94cVikram S. Adve} 612f64f9f264d30dd0ac4880eb16ba9eeac538e94cVikram S. Adve 62da784ee81f082781fb61258546fec7c82ba6a8f0Chris Lattner 635b836c4a06c584544647d5b013b193510ac5ced5Chris Lattner// main - Entry point for the llc compiler. 645b836c4a06c584544647d5b013b193510ac5ced5Chris Lattner// 655b836c4a06c584544647d5b013b193510ac5ced5Chris Lattnerint main(int argc, char **argv) { 661ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer try { 671ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer cl::ParseCommandLineOptions(argc, argv, " llvm system compiler\n"); 681ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer sys::PrintStackTraceOnErrorSignal(); 691ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer 701ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer // Load the module to be compiled... 711ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename)); 721ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer if (M.get() == 0) { 731ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer std::cerr << argv[0] << ": bytecode didn't read correctly.\n"; 74bb43350e32c949ff9465eb898a2ed5ad9d1f3f9fChris Lattner return 1; 75e45110e01282862e95c3d28c489dedd9a08ffa31Chris Lattner } 761ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer Module &mod = *M.get(); 77e45110e01282862e95c3d28c489dedd9a08ffa31Chris Lattner 781ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer // Allocate target machine. First, check whether the user has 791ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer // explicitly specified an architecture to compile for. 801ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer TargetMachine* (*TargetMachineAllocator)(const Module&, 811ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer IntrinsicLowering *) = 0; 821ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer if (MArch == 0) { 831ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer std::string Err; 841ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer MArch = TargetMachineRegistry::getClosestStaticTargetForModule(mod, Err); 851ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer if (MArch == 0) { 861ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer std::cerr << argv[0] << ": error auto-selecting target for module '" 871ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer << Err << "'. Please use the -march option to explicitly " 881ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer << "pick a target.\n"; 89878ba7cc5d87deb24aa8a21d7bd9b2ea7215976fMisha Brukman return 1; 905ce1a585df6749b168be4bc9b719b1abdfc98207Brian Gaeke } 911ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer } 925ce1a585df6749b168be4bc9b719b1abdfc98207Brian Gaeke 931ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer std::auto_ptr<TargetMachine> target(MArch->CtorFn(mod, 0)); 941ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer assert(target.get() && "Could not allocate target machine!"); 951ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer TargetMachine &Target = *target.get(); 961ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer const TargetData &TD = Target.getTargetData(); 971ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer 981ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer // Build up all of the passes that we want to do to the module... 991ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer PassManager Passes; 1001ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer Passes.add(new TargetData("llc", TD.isLittleEndian(), TD.getPointerSize(), 1011ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer TD.getPointerAlignment(), TD.getDoubleAlignment())); 1021ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer 1031ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer // Figure out where we are going to send the output... 1041ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer std::ostream *Out = 0; 1051ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer if (OutputFilename != "") { 1061ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer if (OutputFilename != "-") { 1071ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer // Specified an output filename? 1081ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer if (!Force && std::ifstream(OutputFilename.c_str())) { 1091ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer // If force is not specified, make sure not to overwrite a file! 1101ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer std::cerr << argv[0] << ": error opening '" << OutputFilename 1111ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer << "': file exists!\n" 1121ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer << "Use -f command line argument to force output\n"; 1131ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer return 1; 1141ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer } 1151ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer Out = new std::ofstream(OutputFilename.c_str()); 1161ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer 1171ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer // Make sure that the Out file gets unlinked from the disk if we get a 1181ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer // SIGINT 1191ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer sys::RemoveFileOnSignal(sys::Path(OutputFilename)); 1201ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer } else { 1211ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer Out = &std::cout; 1221ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer } 1235ce1a585df6749b168be4bc9b719b1abdfc98207Brian Gaeke } else { 1241ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer if (InputFilename == "-") { 1251ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer OutputFilename = "-"; 1261ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer Out = &std::cout; 1271ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer } else { 1283da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman OutputFilename = GetFileNameRoot(InputFilename); 1291ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer 1301ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer if (MArch->Name[0] != 'c' || MArch->Name[1] != 0) // not CBE 1311ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer OutputFilename += ".s"; 1321ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer else 1331ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer OutputFilename += ".cbe.c"; 1343da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 1351ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer if (!Force && std::ifstream(OutputFilename.c_str())) { 1361ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer // If force is not specified, make sure not to overwrite a file! 1371ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer std::cerr << argv[0] << ": error opening '" << OutputFilename 1381ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer << "': file exists!\n" 1391ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer << "Use -f command line argument to force output\n"; 1401ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer return 1; 1411ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer } 1423da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 1431ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer Out = new std::ofstream(OutputFilename.c_str()); 1441ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer if (!Out->good()) { 1451ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer std::cerr << argv[0] << ": error opening " << OutputFilename << "!\n"; 1461ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer delete Out; 1471ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer return 1; 1481ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer } 1493da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman 1501ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer // Make sure that the Out file gets unlinked from the disk if we get a 1511ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer // SIGINT 1521ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer sys::RemoveFileOnSignal(sys::Path(OutputFilename)); 1531ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer } 154cccc28c6744c67be33833edd41caa0dbfda521bcChris Lattner } 1551ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer 1561ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer // Ask the target to add backend passes as necessary 1571ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer if (Target.addPassesToEmitAssembly(Passes, *Out)) { 1581ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer std::cerr << argv[0] << ": target '" << Target.getName() 1591ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer << "' does not support static compilation!\n"; 1601ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer if (Out != &std::cout) delete Out; 1611ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer // And the Out file is empty and useless, so remove it now. 1621ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer std::remove(OutputFilename.c_str()); 1631ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer return 1; 164cccc28c6744c67be33833edd41caa0dbfda521bcChris Lattner } else { 1651ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer // Run our queue of passes all at once now, efficiently. 1661ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer Passes.run(*M.get()); 1673524fc2197c17edcea786a9bb0e00246438dba90Chris Lattner } 1687d0ba026401321be1645b4142abeb85e943d0577Vikram S. Adve 1691ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer // Delete the ostream if it's not a stdout stream 1702e2f2dcd6af454a26838457dbfd61ceca7cef41bBrian Gaeke if (Out != &std::cout) delete Out; 17105e5e070ee73309025e11bea0c15d7fc9c25fea6Chris Lattner 1721ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer return 0; 1731ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer } catch (const std::string& msg) { 1741ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer std::cerr << argv[0] << ": " << msg << "\n"; 1751ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer } catch (...) { 1761ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer std::cerr << argv[0] << ": Unexpected unknown exception occurred.\n"; 1771ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer } 1781ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer return 1; 1792f64f9f264d30dd0ac4880eb16ba9eeac538e94cVikram S. Adve} 180