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