llc.cpp revision 98a366d547772010e94609e4584489b3e5ce0043
15b836c4a06c584544647d5b013b193510ac5ced5Chris Lattner//===-- llc.cpp - Implement the LLVM Native Code Generator ----------------===//
23da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman//
37c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell//                     The LLVM Compiler Infrastructure
47c0e022c5c4be4b11e199a53f73bbdd84e34aa80John Criswell//
521c62da287237d39d0d95004881ea4baae3be6daChris Lattner// This file is distributed under the University of Illinois Open Source
621c62da287237d39d0d95004881ea4baae3be6daChris Lattner// 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
12a99be51bf5cdac1438069d4b01766c47704961c8Gabor Greif// or C code, given LLVM bitcode.
13e737c7ac63f1e4359c508601d5be60f7551b076dChris Lattner//
14b79757c621c83dc3f410aacdc6db7639f9e47c6eChris Lattner//===----------------------------------------------------------------------===//
15cb465fc71ecb64d3d168a0cf754fa442abb0f6f9Vikram S. Adve
161a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner#include "llvm/Bitcode/ReaderWriter.h"
17546d0fbd9718ea5ad422faaeffea939fe7312408Bill Wendling#include "llvm/CodeGen/FileWriters.h"
18d3a680ae2cb1ca2d96d1272754af4702862dcb30Chris Lattner#include "llvm/CodeGen/LinkAllCodegenComponents.h"
192b11004d569ee3dd7bd5d184c44fecd5d4bbfce7Anton Korobeynikov#include "llvm/CodeGen/LinkAllAsmWriterComponents.h"
20b1e1180ca0b32f37aa74d7ad703eeaf91e66c8faJim Laskey#include "llvm/Target/SubtargetFeature.h"
2107000c6f01d8f57170f2d4c77a86d934bdc5c696Owen Anderson#include "llvm/Target/TargetData.h"
22805eb96727fc07c4b599528f91370841d722bffaVikram S. Adve#include "llvm/Target/TargetMachine.h"
23e45110e01282862e95c3d28c489dedd9a08ffa31Chris Lattner#include "llvm/Target/TargetMachineRegistry.h"
2465f1b895bb1c196409747c60373b2fbfbf5fe6b4Chris Lattner#include "llvm/Transforms/Scalar.h"
2546ac43c1bbdf010507f61750368297889ac1b6c6Chris Lattner#include "llvm/Module.h"
26744879ea01779a48f898a801c847677b0bfa824aChris Lattner#include "llvm/ModuleProvider.h"
27cd50d3fafabec10c09f3ed0466924a951943d6d0Chris Lattner#include "llvm/PassManager.h"
287d0ba026401321be1645b4142abeb85e943d0577Vikram S. Adve#include "llvm/Pass.h"
29551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/CommandLine.h"
302388a588bdf32610e18a66c0c6ef248087fd1cdcMikhail Glushenkov#include "llvm/Support/FileUtilities.h"
31c30598bc3ad792eb8cc75b188eb872a28c62ab71Chris Lattner#include "llvm/Support/ManagedStatic.h"
321a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner#include "llvm/Support/MemoryBuffer.h"
33551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/PluginLoader.h"
34cc14d25dd99e891c586bd56aa41796abbe4ac3d8Chris Lattner#include "llvm/Support/PrettyStackTrace.h"
352388a588bdf32610e18a66c0c6ef248087fd1cdcMikhail Glushenkov#include "llvm/Support/RegistryParser.h"
36cb3718832375a581c5ea23f15918f3ea447a446cOwen Anderson#include "llvm/Support/raw_ostream.h"
374418c2b3acfcb6cdb05f133aef8eef74ed0d0566Reid Spencer#include "llvm/Analysis/Verifier.h"
38bed85ff010b95923646ed4e187a5d432cedf67daChris Lattner#include "llvm/System/Signals.h"
39812125aea956d0c22d92b456dbc5030a1d2780efChris Lattner#include "llvm/Config/config.h"
40af303d53e6013417d189621c75179df6c7cbdcdeReid Spencer#include "llvm/LinkAllVMCore.h"
4178f7e1a9cdc9a373c9a18598cd5e47ac5476bfe6Chris Lattner#include <fstream>
4286f42bdad93677fa0ca33b27afb0f493028376cbReid Spencer#include <iostream>
4386f42bdad93677fa0ca33b27afb0f493028376cbReid Spencer#include <memory>
44d0fde30ce850b78371fd1386338350591f9ff494Brian Gaekeusing namespace llvm;
45d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
467d0ba026401321be1645b4142abeb85e943d0577Vikram S. Adve// General options for llc.  Other pass-specific options are specified
477d0ba026401321be1645b4142abeb85e943d0577Vikram S. Adve// within the corresponding llc passes, and target-specific options
487d0ba026401321be1645b4142abeb85e943d0577Vikram S. Adve// and back-end code generation options are specified with the target machine.
493da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman//
50b5881f126d4baab41dc7efb2824a53601ef167b0Chris Lattnerstatic cl::opt<std::string>
51a99be51bf5cdac1438069d4b01766c47704961c8Gabor GreifInputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-"));
525ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner
53b5881f126d4baab41dc7efb2824a53601ef167b0Chris Lattnerstatic cl::opt<std::string>
545ff62e90d0bc321206023897edc1e2691cb0fbb6Chris LattnerOutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"));
555ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner
565ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattnerstatic cl::opt<bool> Force("f", cl::desc("Overwrite output files"));
575ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner
58be8cc2a3dedeb7685f07e68cdc4b9502eb97eb2bBill Wendling// Determine optimization level. Level -O0 is equivalent to "fast" code gen.
5998a366d547772010e94609e4584489b3e5ce0043Bill Wendlingstatic cl::opt<char>
60be8cc2a3dedeb7685f07e68cdc4b9502eb97eb2bBill WendlingOptLevel("O",
6198a366d547772010e94609e4584489b3e5ce0043Bill Wendling         cl::desc("Optimization level. Similar to llvm-gcc -O."),
62be8cc2a3dedeb7685f07e68cdc4b9502eb97eb2bBill Wendling         cl::Prefix,
63be8cc2a3dedeb7685f07e68cdc4b9502eb97eb2bBill Wendling         cl::ZeroOrMore,
6498a366d547772010e94609e4584489b3e5ce0043Bill Wendling         cl::init(' '));
65178e0c41ce22160e6a1005420a52c29162dd87d3Chris Lattner
66f33b8663bdd9056660c9e520f20d9a562cbcff0bChris Lattnerstatic cl::opt<std::string>
67be193839fa8650bc4f2974a82327543054202190Chris LattnerTargetTriple("mtriple", cl::desc("Override target triple for module"));
68178e0c41ce22160e6a1005420a52c29162dd87d3Chris Lattner
694b2b9402c5c369b94b35837470a170f1d0e47e1fGordon Henriksenstatic cl::opt<const TargetMachineRegistry::entry*, false,
702388a588bdf32610e18a66c0c6ef248087fd1cdcMikhail Glushenkov               RegistryParser<TargetMachine> >
71cbb34a76a9d893901fbad3267c833426e4a2dde4Chris LattnerMArch("march", cl::desc("Architecture to generate code for:"));
723da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman
73b1e1180ca0b32f37aa74d7ad703eeaf91e66c8faJim Laskeystatic cl::opt<std::string>
745c1799b29375fcd899f67a31fb4dda4ef3e2127fMikhail GlushenkovMCPU("mcpu",
757b7593c4815d95f53148d41b171580e8c88741b6Chris Lattner  cl::desc("Target a specific cpu type (-mcpu=help for details)"),
76b1e1180ca0b32f37aa74d7ad703eeaf91e66c8faJim Laskey  cl::value_desc("cpu-name"),
77b1e1180ca0b32f37aa74d7ad703eeaf91e66c8faJim Laskey  cl::init(""));
78b1e1180ca0b32f37aa74d7ad703eeaf91e66c8faJim Laskey
79b1e1180ca0b32f37aa74d7ad703eeaf91e66c8faJim Laskeystatic cl::list<std::string>
805c1799b29375fcd899f67a31fb4dda4ef3e2127fMikhail GlushenkovMAttrs("mattr",
81b1e1180ca0b32f37aa74d7ad703eeaf91e66c8faJim Laskey  cl::CommaSeparated,
827b7593c4815d95f53148d41b171580e8c88741b6Chris Lattner  cl::desc("Target specific attributes (-mattr=help for details)"),
832094725532836da20db56412ad7f88bc8eb6e586Chris Lattner  cl::value_desc("a1,+a2,-a3,..."));
84b1e1180ca0b32f37aa74d7ad703eeaf91e66c8faJim Laskey
85812125aea956d0c22d92b456dbc5030a1d2780efChris Lattnercl::opt<TargetMachine::CodeGenFileType>
86812125aea956d0c22d92b456dbc5030a1d2780efChris LattnerFileType("filetype", cl::init(TargetMachine::AssemblyFile),
87812125aea956d0c22d92b456dbc5030a1d2780efChris Lattner  cl::desc("Choose a file type (not all types are supported by all targets):"),
88812125aea956d0c22d92b456dbc5030a1d2780efChris Lattner  cl::values(
89262b05f637238be741376620526a940efb553ab2Misha Brukman       clEnumValN(TargetMachine::AssemblyFile, "asm",
90b8cab9227a0f6ffbdaae33e3c64268e265008a6aDan Gohman                  "Emit an assembly ('.s') file"),
91262b05f637238be741376620526a940efb553ab2Misha Brukman       clEnumValN(TargetMachine::ObjectFile, "obj",
92b8cab9227a0f6ffbdaae33e3c64268e265008a6aDan Gohman                  "Emit a native object ('.o') file [experimental]"),
93812125aea956d0c22d92b456dbc5030a1d2780efChris Lattner       clEnumValN(TargetMachine::DynamicLibrary, "dynlib",
94b8cab9227a0f6ffbdaae33e3c64268e265008a6aDan Gohman                  "Emit a native dynamic library ('.so') file"
95712b835de015d72815788f46b16bc947db28d909Nate Begeman                  " [experimental]"),
96812125aea956d0c22d92b456dbc5030a1d2780efChris Lattner       clEnumValEnd));
97812125aea956d0c22d92b456dbc5030a1d2780efChris Lattner
984418c2b3acfcb6cdb05f133aef8eef74ed0d0566Reid Spencercl::opt<bool> NoVerify("disable-verify", cl::Hidden,
99d29b6aa608d69f19b57ebd2ae630b040b1c4951dJeff Cohen                       cl::desc("Do not verify input module"));
1004418c2b3acfcb6cdb05f133aef8eef74ed0d0566Reid Spencer
101812125aea956d0c22d92b456dbc5030a1d2780efChris Lattner
102812125aea956d0c22d92b456dbc5030a1d2780efChris Lattner// GetFileNameRoot - Helper function to get the basename of a filename.
103b5881f126d4baab41dc7efb2824a53601ef167b0Chris Lattnerstatic inline std::string
104e45110e01282862e95c3d28c489dedd9a08ffa31Chris LattnerGetFileNameRoot(const std::string &InputFilename) {
105b5881f126d4baab41dc7efb2824a53601ef167b0Chris Lattner  std::string IFN = InputFilename;
106b5881f126d4baab41dc7efb2824a53601ef167b0Chris Lattner  std::string outputFilename;
1072f64f9f264d30dd0ac4880eb16ba9eeac538e94cVikram S. Adve  int Len = IFN.length();
108b5d09bf4cc7769ccbd86a96fb8ea92e3c6e3bbc7John Criswell  if ((Len > 2) &&
109b5d09bf4cc7769ccbd86a96fb8ea92e3c6e3bbc7John Criswell      IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') {
110b5881f126d4baab41dc7efb2824a53601ef167b0Chris Lattner    outputFilename = std::string(IFN.begin(), IFN.end()-3); // s/.bc/.s/
1112f64f9f264d30dd0ac4880eb16ba9eeac538e94cVikram S. Adve  } else {
1123524fc2197c17edcea786a9bb0e00246438dba90Chris Lattner    outputFilename = IFN;
1132f64f9f264d30dd0ac4880eb16ba9eeac538e94cVikram S. Adve  }
1142f64f9f264d30dd0ac4880eb16ba9eeac538e94cVikram S. Adve  return outputFilename;
1152f64f9f264d30dd0ac4880eb16ba9eeac538e94cVikram S. Adve}
1162f64f9f264d30dd0ac4880eb16ba9eeac538e94cVikram S. Adve
117cb3718832375a581c5ea23f15918f3ea447a446cOwen Andersonstatic raw_ostream *GetOutputStream(const char *ProgName) {
1181911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner  if (OutputFilename != "") {
1191911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner    if (OutputFilename == "-")
120cb3718832375a581c5ea23f15918f3ea447a446cOwen Anderson      return &outs();
1211911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner
1221911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner    // Specified an output filename?
1231911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner    if (!Force && std::ifstream(OutputFilename.c_str())) {
1241911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner      // If force is not specified, make sure not to overwrite a file!
1251911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner      std::cerr << ProgName << ": error opening '" << OutputFilename
1261911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner                << "': file exists!\n"
1271911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner                << "Use -f command line argument to force output\n";
1281911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner      return 0;
1291911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner    }
1301911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner    // Make sure that the Out file gets unlinked from the disk if we get a
1311911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner    // SIGINT
1321911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner    sys::RemoveFileOnSignal(sys::Path(OutputFilename));
1331911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner
134cb3718832375a581c5ea23f15918f3ea447a446cOwen Anderson    std::string error;
1350d9eb9b4917340acbfc831890655b8e9724959f6Daniel Dunbar    raw_ostream *Out = new raw_fd_ostream(OutputFilename.c_str(), true, error);
136ed3e8b4ed2a3ab44d316e16a54d963f8927c6783Dan Gohman    if (!error.empty()) {
137ed3e8b4ed2a3ab44d316e16a54d963f8927c6783Dan Gohman      std::cerr << error << '\n';
138ed3e8b4ed2a3ab44d316e16a54d963f8927c6783Dan Gohman      delete Out;
139ed3e8b4ed2a3ab44d316e16a54d963f8927c6783Dan Gohman      return 0;
140ed3e8b4ed2a3ab44d316e16a54d963f8927c6783Dan Gohman    }
141ed3e8b4ed2a3ab44d316e16a54d963f8927c6783Dan Gohman
142ed3e8b4ed2a3ab44d316e16a54d963f8927c6783Dan Gohman    return Out;
1431911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner  }
1445c1799b29375fcd899f67a31fb4dda4ef3e2127fMikhail Glushenkov
1451911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner  if (InputFilename == "-") {
1461911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner    OutputFilename = "-";
147cb3718832375a581c5ea23f15918f3ea447a446cOwen Anderson    return &outs();
1481911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner  }
1491911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner
1501911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner  OutputFilename = GetFileNameRoot(InputFilename);
1515c1799b29375fcd899f67a31fb4dda4ef3e2127fMikhail Glushenkov
1520d9eb9b4917340acbfc831890655b8e9724959f6Daniel Dunbar  bool Binary = false;
1531911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner  switch (FileType) {
1541911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner  case TargetMachine::AssemblyFile:
1555027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    if (MArch->Name[0] == 'c') {
1565027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      if (MArch->Name[1] == 0)
1575027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        OutputFilename += ".cbe.c";
1585027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      else if (MArch->Name[1] == 'p' && MArch->Name[2] == 'p')
1595027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        OutputFilename += ".cpp";
1605027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      else
1615027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        OutputFilename += ".s";
1625027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    } else
1631911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner      OutputFilename += ".s";
1641911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner    break;
1651911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner  case TargetMachine::ObjectFile:
1661911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner    OutputFilename += ".o";
1670d9eb9b4917340acbfc831890655b8e9724959f6Daniel Dunbar    Binary = true;
1681911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner    break;
1691911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner  case TargetMachine::DynamicLibrary:
1701911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner    OutputFilename += LTDL_SHLIB_EXT;
1710d9eb9b4917340acbfc831890655b8e9724959f6Daniel Dunbar    Binary = true;
1721911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner    break;
1731911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner  }
1745c1799b29375fcd899f67a31fb4dda4ef3e2127fMikhail Glushenkov
1751911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner  if (!Force && std::ifstream(OutputFilename.c_str())) {
1761911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner    // If force is not specified, make sure not to overwrite a file!
1771911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner    std::cerr << ProgName << ": error opening '" << OutputFilename
1781911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner                          << "': file exists!\n"
1791911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner                          << "Use -f command line argument to force output\n";
1801911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner    return 0;
1811911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner  }
1825c1799b29375fcd899f67a31fb4dda4ef3e2127fMikhail Glushenkov
1831911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner  // Make sure that the Out file gets unlinked from the disk if we get a
1841911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner  // SIGINT
1851911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner  sys::RemoveFileOnSignal(sys::Path(OutputFilename));
1865c1799b29375fcd899f67a31fb4dda4ef3e2127fMikhail Glushenkov
187cb3718832375a581c5ea23f15918f3ea447a446cOwen Anderson  std::string error;
1880d9eb9b4917340acbfc831890655b8e9724959f6Daniel Dunbar  raw_ostream *Out = new raw_fd_ostream(OutputFilename.c_str(), Binary, error);
189cb3718832375a581c5ea23f15918f3ea447a446cOwen Anderson  if (!error.empty()) {
190ed3e8b4ed2a3ab44d316e16a54d963f8927c6783Dan Gohman    std::cerr << error << '\n';
1911911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner    delete Out;
1921911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner    return 0;
1931911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner  }
1945c1799b29375fcd899f67a31fb4dda4ef3e2127fMikhail Glushenkov
1951911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner  return Out;
1961911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner}
197da784ee81f082781fb61258546fec7c82ba6a8f0Chris Lattner
1985b836c4a06c584544647d5b013b193510ac5ced5Chris Lattner// main - Entry point for the llc compiler.
1995b836c4a06c584544647d5b013b193510ac5ced5Chris Lattner//
2005b836c4a06c584544647d5b013b193510ac5ced5Chris Lattnerint main(int argc, char **argv) {
2011a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  sys::PrintStackTraceOnErrorSignal();
202cc14d25dd99e891c586bd56aa41796abbe4ac3d8Chris Lattner  PrettyStackTraceProgram X(argc, argv);
203cc14d25dd99e891c586bd56aa41796abbe4ac3d8Chris Lattner  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
204cc14d25dd99e891c586bd56aa41796abbe4ac3d8Chris Lattner  cl::ParseCommandLineOptions(argc, argv, "llvm system compiler\n");
205e45110e01282862e95c3d28c489dedd9a08ffa31Chris Lattner
2061a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  // Load the module to be compiled...
2071a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  std::string ErrorMessage;
2081a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  std::auto_ptr<Module> M;
2095c1799b29375fcd899f67a31fb4dda4ef3e2127fMikhail Glushenkov
210744879ea01779a48f898a801c847677b0bfa824aChris Lattner  std::auto_ptr<MemoryBuffer> Buffer(
211065344dfd5a7b3502098810b981eb0077e5d81f3Chris Lattner                   MemoryBuffer::getFileOrSTDIN(InputFilename, &ErrorMessage));
212744879ea01779a48f898a801c847677b0bfa824aChris Lattner  if (Buffer.get())
213744879ea01779a48f898a801c847677b0bfa824aChris Lattner    M.reset(ParseBitcodeFile(Buffer.get(), &ErrorMessage));
2141a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  if (M.get() == 0) {
215a99be51bf5cdac1438069d4b01766c47704961c8Gabor Greif    std::cerr << argv[0] << ": bitcode didn't read correctly.\n";
2161a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    std::cerr << "Reason: " << ErrorMessage << "\n";
2171a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    return 1;
2181a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  }
2191a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  Module &mod = *M.get();
2205c1799b29375fcd899f67a31fb4dda4ef3e2127fMikhail Glushenkov
2211a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  // If we are supposed to override the target triple, do so now.
2221a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  if (!TargetTriple.empty())
2231a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    mod.setTargetTriple(TargetTriple);
2245c1799b29375fcd899f67a31fb4dda4ef3e2127fMikhail Glushenkov
2251a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  // Allocate target machine.  First, check whether the user has
2261a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  // explicitly specified an architecture to compile for.
2271a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  if (MArch == 0) {
2281a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    std::string Err;
2291a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    MArch = TargetMachineRegistry::getClosestStaticTargetForModule(mod, Err);
2301ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer    if (MArch == 0) {
2311a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner      std::cerr << argv[0] << ": error auto-selecting target for module '"
2321a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner                << Err << "'.  Please use the -march option to explicitly "
2331a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner                << "pick a target.\n";
2341a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner      return 1;
235b1e1180ca0b32f37aa74d7ad703eeaf91e66c8faJim Laskey    }
2361a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  }
237b1e1180ca0b32f37aa74d7ad703eeaf91e66c8faJim Laskey
2381a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  // Package up features to be passed to target/subtarget
2391a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  std::string FeaturesStr;
2401a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  if (MCPU.size() || MAttrs.size()) {
2411a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    SubtargetFeatures Features;
2421a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    Features.setCPU(MCPU);
2431a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    for (unsigned i = 0; i != MAttrs.size(); ++i)
2441a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner      Features.AddFeature(MAttrs[i]);
2451a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    FeaturesStr = Features.getString();
2461a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  }
2475c1799b29375fcd899f67a31fb4dda4ef3e2127fMikhail Glushenkov
2481a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  std::auto_ptr<TargetMachine> target(MArch->CtorFn(mod, FeaturesStr));
2491a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  assert(target.get() && "Could not allocate target machine!");
2501a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  TargetMachine &Target = *target.get();
2511ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer
2521a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  // Figure out where we are going to send the output...
253cb3718832375a581c5ea23f15918f3ea447a446cOwen Anderson  raw_ostream *Out = GetOutputStream(argv[0]);
2541a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  if (Out == 0) return 1;
2555c1799b29375fcd899f67a31fb4dda4ef3e2127fMikhail Glushenkov
25698a366d547772010e94609e4584489b3e5ce0043Bill Wendling  CodeGenOpt::Level OLvl = CodeGenOpt::Aggressive;
25798a366d547772010e94609e4584489b3e5ce0043Bill Wendling
25898a366d547772010e94609e4584489b3e5ce0043Bill Wendling  switch (OptLevel) {
25998a366d547772010e94609e4584489b3e5ce0043Bill Wendling  default:
26098a366d547772010e94609e4584489b3e5ce0043Bill Wendling  case ' ': break;
26198a366d547772010e94609e4584489b3e5ce0043Bill Wendling  case '0': OLvl = CodeGenOpt::None; break;
26298a366d547772010e94609e4584489b3e5ce0043Bill Wendling  case '1': OLvl = CodeGenOpt::One; break;
26398a366d547772010e94609e4584489b3e5ce0043Bill Wendling  case '2': OLvl = CodeGenOpt::Two; break;
26498a366d547772010e94609e4584489b3e5ce0043Bill Wendling  case 's': OLvl = CodeGenOpt::Size; break;
26598a366d547772010e94609e4584489b3e5ce0043Bill Wendling  case '3': OLvl = CodeGenOpt::Aggressive; break;
26698a366d547772010e94609e4584489b3e5ce0043Bill Wendling  case '4': OLvl = CodeGenOpt::LTO; break;
26798a366d547772010e94609e4584489b3e5ce0043Bill Wendling  }
26898a366d547772010e94609e4584489b3e5ce0043Bill Wendling
2691a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  // If this target requires addPassesToEmitWholeFile, do it now.  This is
2701a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  // used by strange things like the C backend.
2711a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  if (Target.WantsWholeFile()) {
2721a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    PassManager PM;
2731a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    PM.add(new TargetData(*Target.getTargetData()));
2741a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    if (!NoVerify)
2751a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner      PM.add(createVerifierPass());
2765c1799b29375fcd899f67a31fb4dda4ef3e2127fMikhail Glushenkov
2771a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    // Ask the target to add backend passes as necessary.
27898a366d547772010e94609e4584489b3e5ce0043Bill Wendling    if (Target.addPassesToEmitWholeFile(PM, *Out, FileType, OLvl)) {
2791a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner      std::cerr << argv[0] << ": target does not support generation of this"
2801a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner                << " file type!\n";
281cb3718832375a581c5ea23f15918f3ea447a446cOwen Anderson      if (Out != &outs()) delete Out;
2821a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner      // And the Out file is empty and useless, so remove it now.
2831a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner      sys::Path(OutputFilename).eraseFromDisk();
2841a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner      return 1;
2851a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    }
2861a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    PM.run(mod);
2871a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  } else {
2881a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    // Build up all of the passes that we want to do to the module.
28933ef2bb2680de321cd6d2056a1ecce635e6d1c75Dan Gohman    ExistingModuleProvider Provider(M.release());
29033ef2bb2680de321cd6d2056a1ecce635e6d1c75Dan Gohman    FunctionPassManager Passes(&Provider);
2911a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    Passes.add(new TargetData(*Target.getTargetData()));
2925c1799b29375fcd899f67a31fb4dda4ef3e2127fMikhail Glushenkov
2931911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner#ifndef NDEBUG
2941a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    if (!NoVerify)
2951a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner      Passes.add(createVerifierPass());
2961911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner#endif
2975c1799b29375fcd899f67a31fb4dda4ef3e2127fMikhail Glushenkov
2981a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    // Ask the target to add backend passes as necessary.
2991a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    MachineCodeEmitter *MCE = 0;
300546d0fbd9718ea5ad422faaeffea939fe7312408Bill Wendling
30123120babfaa23e1ecfe374866f498855dbe5fe27Evan Cheng    // Override default to generate verbose assembly.
30223120babfaa23e1ecfe374866f498855dbe5fe27Evan Cheng    Target.setAsmVerbosityDefault(true);
30323120babfaa23e1ecfe374866f498855dbe5fe27Evan Cheng
30498a366d547772010e94609e4584489b3e5ce0043Bill Wendling    switch (Target.addPassesToEmitFile(Passes, *Out, FileType, OLvl)) {
3051a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    default:
3061a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner      assert(0 && "Invalid file model!");
3071a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner      return 1;
3081a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    case FileModel::Error:
3091a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner      std::cerr << argv[0] << ": target does not support generation of this"
3101a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner                << " file type!\n";
311cb3718832375a581c5ea23f15918f3ea447a446cOwen Anderson      if (Out != &outs()) delete Out;
3121a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner      // And the Out file is empty and useless, so remove it now.
3131a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner      sys::Path(OutputFilename).eraseFromDisk();
3141a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner      return 1;
3151a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    case FileModel::AsmFile:
3161a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner      break;
3171a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    case FileModel::MachOFile:
3181a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner      MCE = AddMachOWriter(Passes, *Out, Target);
3191a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner      break;
3201a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    case FileModel::ElfFile:
3211a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner      MCE = AddELFWriter(Passes, *Out, Target);
3221a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner      break;
3231a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    }
324546d0fbd9718ea5ad422faaeffea939fe7312408Bill Wendling
32598a366d547772010e94609e4584489b3e5ce0043Bill Wendling    if (Target.addPassesToEmitFileFinish(Passes, MCE, OLvl)) {
3261a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner      std::cerr << argv[0] << ": target does not support generation of this"
3271a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner                << " file type!\n";
328cb3718832375a581c5ea23f15918f3ea447a446cOwen Anderson      if (Out != &outs()) delete Out;
3291a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner      // And the Out file is empty and useless, so remove it now.
3301a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner      sys::Path(OutputFilename).eraseFromDisk();
3311a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner      return 1;
3321a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    }
3335c1799b29375fcd899f67a31fb4dda4ef3e2127fMikhail Glushenkov
3341a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    Passes.doInitialization();
3355c1799b29375fcd899f67a31fb4dda4ef3e2127fMikhail Glushenkov
3361a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    // Run our queue of passes all at once now, efficiently.
3371a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    // TODO: this could lazily stream functions out of the module.
3381a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    for (Module::iterator I = mod.begin(), E = mod.end(); I != E; ++I)
3391a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner      if (!I->isDeclaration())
3401a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner        Passes.run(*I);
3415c1799b29375fcd899f67a31fb4dda4ef3e2127fMikhail Glushenkov
3421a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    Passes.doFinalization();
3431a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  }
3445c1799b29375fcd899f67a31fb4dda4ef3e2127fMikhail Glushenkov
3451a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  // Delete the ostream if it's not a stdout stream
346cb3718832375a581c5ea23f15918f3ea447a446cOwen Anderson  if (Out != &outs()) delete Out;
34705e5e070ee73309025e11bea0c15d7fc9c25fea6Chris Lattner
3481a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  return 0;
3492f64f9f264d30dd0ac4880eb16ba9eeac538e94cVikram S. Adve}
350