llc.cpp revision e45110e01282862e95c3d28c489dedd9a08ffa31
15b836c4a06c584544647d5b013b193510ac5ced5Chris Lattner//===-- llc.cpp - Implement the LLVM Native Code Generator ----------------===// 27c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell// 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. 77c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell// 87c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell//===----------------------------------------------------------------------===// 9e737c7ac63f1e4359c508601d5be60f7551b076dChris Lattner// 10e40eae73705d2ea55dc50d664d1be3ea04c545c8Brian Gaeke// This is the llc code generator driver. It provides a convenient 11e40eae73705d2ea55dc50d664d1be3ea04c545c8Brian Gaeke// 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" 23cee8f9ae67104576b2028125b56e9ba4856a1d66Chris Lattner#include "Support/CommandLine.h" 24e45110e01282862e95c3d28c489dedd9a08ffa31Chris Lattner#include "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. 357d0ba026401321be1645b4142abeb85e943d0577Vikram S. Adve// 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 445ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner 45e45110e01282862e95c3d28c489dedd9a08ffa31Chris Lattnerstatic cl::opt<const TargetMachineRegistry::Entry*, false, TargetNameParser> 46e45110e01282862e95c3d28c489dedd9a08ffa31Chris LattnerMArch("march", cl::desc("Architecture to generate assembly for:")); 47e45110e01282862e95c3d28c489dedd9a08ffa31Chris Lattner 483524fc2197c17edcea786a9bb0e00246438dba90Chris Lattner// GetFileNameRoot - Helper function to get the basename of a filename... 49b5881f126d4baab41dc7efb2824a53601ef167b0Chris Lattnerstatic inline std::string 50e45110e01282862e95c3d28c489dedd9a08ffa31Chris LattnerGetFileNameRoot(const std::string &InputFilename) { 51b5881f126d4baab41dc7efb2824a53601ef167b0Chris Lattner std::string IFN = InputFilename; 52b5881f126d4baab41dc7efb2824a53601ef167b0Chris Lattner std::string outputFilename; 532f64f9f264d30dd0ac4880eb16ba9eeac538e94cVikram S. Adve int Len = IFN.length(); 54b5d09bf4cc7769ccbd86a96fb8ea92e3c6e3bbc7John Criswell if ((Len > 2) && 55b5d09bf4cc7769ccbd86a96fb8ea92e3c6e3bbc7John Criswell IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') { 56b5881f126d4baab41dc7efb2824a53601ef167b0Chris Lattner outputFilename = std::string(IFN.begin(), IFN.end()-3); // s/.bc/.s/ 572f64f9f264d30dd0ac4880eb16ba9eeac538e94cVikram S. Adve } else { 583524fc2197c17edcea786a9bb0e00246438dba90Chris Lattner outputFilename = IFN; 592f64f9f264d30dd0ac4880eb16ba9eeac538e94cVikram S. Adve } 602f64f9f264d30dd0ac4880eb16ba9eeac538e94cVikram S. Adve return outputFilename; 612f64f9f264d30dd0ac4880eb16ba9eeac538e94cVikram S. Adve} 622f64f9f264d30dd0ac4880eb16ba9eeac538e94cVikram S. Adve 63da784ee81f082781fb61258546fec7c82ba6a8f0Chris Lattner 645b836c4a06c584544647d5b013b193510ac5ced5Chris Lattner// main - Entry point for the llc compiler. 655b836c4a06c584544647d5b013b193510ac5ced5Chris Lattner// 665b836c4a06c584544647d5b013b193510ac5ced5Chris Lattnerint main(int argc, char **argv) { 672f64f9f264d30dd0ac4880eb16ba9eeac538e94cVikram S. Adve cl::ParseCommandLineOptions(argc, argv, " llvm system compiler\n"); 68364d1203e7adaededf3c01f58bd968ee61f4a316Chris Lattner PrintStackTraceOnErrorSignal(); 69364d1203e7adaededf3c01f58bd968ee61f4a316Chris Lattner 702f64f9f264d30dd0ac4880eb16ba9eeac538e94cVikram S. Adve // Load the module to be compiled... 71697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner std::auto_ptr<Module> M(ParseBytecodeFile(InputFilename)); 725b836c4a06c584544647d5b013b193510ac5ced5Chris Lattner if (M.get() == 0) { 735b836c4a06c584544647d5b013b193510ac5ced5Chris Lattner std::cerr << argv[0] << ": bytecode didn't read correctly.\n"; 745b836c4a06c584544647d5b013b193510ac5ced5Chris Lattner return 1; 755b836c4a06c584544647d5b013b193510ac5ced5Chris Lattner } 762e2f2dcd6af454a26838457dbfd61ceca7cef41bBrian Gaeke Module &mod = *M.get(); 772e2f2dcd6af454a26838457dbfd61ceca7cef41bBrian Gaeke 782e2f2dcd6af454a26838457dbfd61ceca7cef41bBrian Gaeke // Allocate target machine. First, check whether the user has 792e2f2dcd6af454a26838457dbfd61ceca7cef41bBrian Gaeke // explicitly specified an architecture to compile for. 806fb6ce3148ec4a9aaab47800da2365d7f60a6f5bChris Lattner TargetMachine* (*TargetMachineAllocator)(const Module&, 816fb6ce3148ec4a9aaab47800da2365d7f60a6f5bChris Lattner IntrinsicLowering *) = 0; 82e45110e01282862e95c3d28c489dedd9a08ffa31Chris Lattner if (MArch == 0) { 83e45110e01282862e95c3d28c489dedd9a08ffa31Chris Lattner std::string Err; 84e45110e01282862e95c3d28c489dedd9a08ffa31Chris Lattner MArch = TargetMachineRegistry::getClosestStaticTargetForModule(mod, Err); 85e45110e01282862e95c3d28c489dedd9a08ffa31Chris Lattner if (MArch == 0) { 86e45110e01282862e95c3d28c489dedd9a08ffa31Chris Lattner std::cerr << argv[0] << ": error auto-selecting target for module '" 87e45110e01282862e95c3d28c489dedd9a08ffa31Chris Lattner << Err << "'. Please use the -march option to explicitly " 88e45110e01282862e95c3d28c489dedd9a08ffa31Chris Lattner << "pick a target.\n"; 89bb43350e32c949ff9465eb898a2ed5ad9d1f3f9fChris Lattner return 1; 90e45110e01282862e95c3d28c489dedd9a08ffa31Chris Lattner } 912e2f2dcd6af454a26838457dbfd61ceca7cef41bBrian Gaeke } 92e45110e01282862e95c3d28c489dedd9a08ffa31Chris Lattner 93e45110e01282862e95c3d28c489dedd9a08ffa31Chris Lattner std::auto_ptr<TargetMachine> target(MArch->CtorFn(mod, 0)); 942e2f2dcd6af454a26838457dbfd61ceca7cef41bBrian Gaeke assert(target.get() && "Could not allocate target machine!"); 952e2f2dcd6af454a26838457dbfd61ceca7cef41bBrian Gaeke TargetMachine &Target = *target.get(); 962e2f2dcd6af454a26838457dbfd61ceca7cef41bBrian Gaeke const TargetData &TD = Target.getTargetData(); 9739fd659d683592df13ccfa39f1825b1173a9ff04Chris Lattner 983524fc2197c17edcea786a9bb0e00246438dba90Chris Lattner // Build up all of the passes that we want to do to the module... 99f4de63f65fa995e68e3cd268117ab065068be413Chris Lattner PassManager Passes; 1003524fc2197c17edcea786a9bb0e00246438dba90Chris Lattner 10110daaa141661d96843f3d8ece0e5a4c2da4b6e87Chris Lattner Passes.add(new TargetData("llc", TD.isLittleEndian(), TD.getPointerSize(), 102bc19466912f4074bc0dc20d389fb1775a674dfd6Chris Lattner TD.getPointerAlignment(), TD.getDoubleAlignment())); 1032b5f2c1a648895d4075f0f35c8a37bd485b9eab0Chris Lattner 104e41576d14136e57e07fbc512a0092323a11c8d43Chris Lattner // Figure out where we are going to send the output... 105e41576d14136e57e07fbc512a0092323a11c8d43Chris Lattner std::ostream *Out = 0; 106cccc28c6744c67be33833edd41caa0dbfda521bcChris Lattner if (OutputFilename != "") { 1075ce1a585df6749b168be4bc9b719b1abdfc98207Brian Gaeke if (OutputFilename != "-") { 1085ce1a585df6749b168be4bc9b719b1abdfc98207Brian Gaeke // Specified an output filename? 1095ce1a585df6749b168be4bc9b719b1abdfc98207Brian Gaeke if (!Force && std::ifstream(OutputFilename.c_str())) { 1105ce1a585df6749b168be4bc9b719b1abdfc98207Brian Gaeke // If force is not specified, make sure not to overwrite a file! 1115ce1a585df6749b168be4bc9b719b1abdfc98207Brian Gaeke std::cerr << argv[0] << ": error opening '" << OutputFilename 1125ce1a585df6749b168be4bc9b719b1abdfc98207Brian Gaeke << "': file exists!\n" 1135ce1a585df6749b168be4bc9b719b1abdfc98207Brian Gaeke << "Use -f command line argument to force output\n"; 1145ce1a585df6749b168be4bc9b719b1abdfc98207Brian Gaeke return 1; 1155ce1a585df6749b168be4bc9b719b1abdfc98207Brian Gaeke } 1165ce1a585df6749b168be4bc9b719b1abdfc98207Brian Gaeke Out = new std::ofstream(OutputFilename.c_str()); 1175ce1a585df6749b168be4bc9b719b1abdfc98207Brian Gaeke 118452fea997232437902385e88366482b01957eeefMisha Brukman // Make sure that the Out file gets unlinked from the disk if we get a 1195ce1a585df6749b168be4bc9b719b1abdfc98207Brian Gaeke // SIGINT 1205ce1a585df6749b168be4bc9b719b1abdfc98207Brian Gaeke RemoveFileOnSignal(OutputFilename); 1215ce1a585df6749b168be4bc9b719b1abdfc98207Brian Gaeke } else { 1225ce1a585df6749b168be4bc9b719b1abdfc98207Brian Gaeke Out = &std::cout; 123cccc28c6744c67be33833edd41caa0dbfda521bcChris Lattner } 124cccc28c6744c67be33833edd41caa0dbfda521bcChris Lattner } else { 125cccc28c6744c67be33833edd41caa0dbfda521bcChris Lattner if (InputFilename == "-") { 126cccc28c6744c67be33833edd41caa0dbfda521bcChris Lattner OutputFilename = "-"; 127cccc28c6744c67be33833edd41caa0dbfda521bcChris Lattner Out = &std::cout; 128cccc28c6744c67be33833edd41caa0dbfda521bcChris Lattner } else { 1292e2f2dcd6af454a26838457dbfd61ceca7cef41bBrian Gaeke OutputFilename = GetFileNameRoot(InputFilename); 13074661c838c66f8e30226da8a1f3b77548a584203Chris Lattner 131e45110e01282862e95c3d28c489dedd9a08ffa31Chris Lattner if (MArch->Name[0] != 'c' || MArch->Name[1] != 0) // not CBE 13274661c838c66f8e30226da8a1f3b77548a584203Chris Lattner OutputFilename += ".s"; 13374661c838c66f8e30226da8a1f3b77548a584203Chris Lattner else 13474661c838c66f8e30226da8a1f3b77548a584203Chris Lattner OutputFilename += ".cbe.c"; 135cccc28c6744c67be33833edd41caa0dbfda521bcChris Lattner 136888912dbe01c715aa5a0ddec19da6ef12f382ebfChris Lattner if (!Force && std::ifstream(OutputFilename.c_str())) { 137697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner // If force is not specified, make sure not to overwrite a file! 138b5881f126d4baab41dc7efb2824a53601ef167b0Chris Lattner std::cerr << argv[0] << ": error opening '" << OutputFilename 139b5881f126d4baab41dc7efb2824a53601ef167b0Chris Lattner << "': file exists!\n" 140b5881f126d4baab41dc7efb2824a53601ef167b0Chris Lattner << "Use -f command line argument to force output\n"; 141697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner return 1; 142697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner } 143cccc28c6744c67be33833edd41caa0dbfda521bcChris Lattner 144697954c15da58bd8b186dbafdedd8b06db770201Chris Lattner Out = new std::ofstream(OutputFilename.c_str()); 145cccc28c6744c67be33833edd41caa0dbfda521bcChris Lattner if (!Out->good()) { 146cccc28c6744c67be33833edd41caa0dbfda521bcChris Lattner std::cerr << argv[0] << ": error opening " << OutputFilename << "!\n"; 147cccc28c6744c67be33833edd41caa0dbfda521bcChris Lattner delete Out; 148cccc28c6744c67be33833edd41caa0dbfda521bcChris Lattner return 1; 149cccc28c6744c67be33833edd41caa0dbfda521bcChris Lattner } 150cccc28c6744c67be33833edd41caa0dbfda521bcChris Lattner 151452fea997232437902385e88366482b01957eeefMisha Brukman // Make sure that the Out file gets unlinked from the disk if we get a 1520f82df410caf8242406fa7e8bbd555e4854ffe48Chris Lattner // SIGINT 15376d12299b5333d71bfc079614031f97c97aa5148Chris Lattner RemoveFileOnSignal(OutputFilename); 1543524fc2197c17edcea786a9bb0e00246438dba90Chris Lattner } 155cccc28c6744c67be33833edd41caa0dbfda521bcChris Lattner } 1567d0ba026401321be1645b4142abeb85e943d0577Vikram S. Adve 1572e2f2dcd6af454a26838457dbfd61ceca7cef41bBrian Gaeke // Ask the target to add backend passes as necessary 1586334205cb5c626d2b35e42dd4c710b857bf0a126Chris Lattner if (Target.addPassesToEmitAssembly(Passes, *Out)) { 159b5881f126d4baab41dc7efb2824a53601ef167b0Chris Lattner std::cerr << argv[0] << ": target '" << Target.getName() 1602e2f2dcd6af454a26838457dbfd61ceca7cef41bBrian Gaeke << "' does not support static compilation!\n"; 1612e2f2dcd6af454a26838457dbfd61ceca7cef41bBrian Gaeke if (Out != &std::cout) delete Out; 1622e2f2dcd6af454a26838457dbfd61ceca7cef41bBrian Gaeke // And the Out file is empty and useless, so remove it now. 1632e2f2dcd6af454a26838457dbfd61ceca7cef41bBrian Gaeke std::remove(OutputFilename.c_str()); 1642e2f2dcd6af454a26838457dbfd61ceca7cef41bBrian Gaeke return 1; 1656334205cb5c626d2b35e42dd4c710b857bf0a126Chris Lattner } else { 1666334205cb5c626d2b35e42dd4c710b857bf0a126Chris Lattner // Run our queue of passes all at once now, efficiently. 1676334205cb5c626d2b35e42dd4c710b857bf0a126Chris Lattner Passes.run(*M.get()); 1686334205cb5c626d2b35e42dd4c710b857bf0a126Chris Lattner } 16905e5e070ee73309025e11bea0c15d7fc9c25fea6Chris Lattner 1700f82df410caf8242406fa7e8bbd555e4854ffe48Chris Lattner // Delete the ostream if it's not a stdout stream 171e41576d14136e57e07fbc512a0092323a11c8d43Chris Lattner if (Out != &std::cout) delete Out; 172e41576d14136e57e07fbc512a0092323a11c8d43Chris Lattner 173d7477ee9d97f80fd5dac252dad4f1c1f83660115Chris Lattner return 0; 1742f64f9f264d30dd0ac4880eb16ba9eeac538e94cVikram S. Adve} 175