llc.cpp revision af632c91a0090d8448dd10e48d8ce53f31be0a21
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
168b477ed579794ba6d76915d56b3f448a7dd20120Owen Anderson#include "llvm/LLVMContext.h"
1746ac43c1bbdf010507f61750368297889ac1b6c6Chris Lattner#include "llvm/Module.h"
18cd50d3fafabec10c09f3ed0466924a951943d6d0Chris Lattner#include "llvm/PassManager.h"
197d0ba026401321be1645b4142abeb85e943d0577Vikram S. Adve#include "llvm/Pass.h"
203c2d4bf97fa96fe171883cd80e4ea93fc43563e6Daniel Dunbar#include "llvm/ADT/Triple.h"
213c2d4bf97fa96fe171883cd80e4ea93fc43563e6Daniel Dunbar#include "llvm/Analysis/Verifier.h"
22778b06bbcecbe52125dddcb06e898806b1e2b3c7Dan Gohman#include "llvm/Support/IRReader.h"
233c2d4bf97fa96fe171883cd80e4ea93fc43563e6Daniel Dunbar#include "llvm/CodeGen/LinkAllAsmWriterComponents.h"
243c2d4bf97fa96fe171883cd80e4ea93fc43563e6Daniel Dunbar#include "llvm/CodeGen/LinkAllCodegenComponents.h"
253c2d4bf97fa96fe171883cd80e4ea93fc43563e6Daniel Dunbar#include "llvm/Config/config.h"
26551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/CommandLine.h"
27c58d01b235fb6aba9edb49f6dbe08edaa756a873David Greene#include "llvm/Support/Debug.h"
2871847813bc419f7a0667468136a07429c6d9f164David Greene#include "llvm/Support/FormattedStream.h"
29c30598bc3ad792eb8cc75b188eb872a28c62ab71Chris Lattner#include "llvm/Support/ManagedStatic.h"
30551ccae044b0ff658fe629dd67edd5ffe75d10e8Reid Spencer#include "llvm/Support/PluginLoader.h"
31cc14d25dd99e891c586bd56aa41796abbe4ac3d8Chris Lattner#include "llvm/Support/PrettyStackTrace.h"
323c2d4bf97fa96fe171883cd80e4ea93fc43563e6Daniel Dunbar#include "llvm/System/Host.h"
33bed85ff010b95923646ed4e187a5d432cedf67daChris Lattner#include "llvm/System/Signals.h"
343c2d4bf97fa96fe171883cd80e4ea93fc43563e6Daniel Dunbar#include "llvm/Target/SubtargetFeature.h"
353c2d4bf97fa96fe171883cd80e4ea93fc43563e6Daniel Dunbar#include "llvm/Target/TargetData.h"
363c2d4bf97fa96fe171883cd80e4ea93fc43563e6Daniel Dunbar#include "llvm/Target/TargetMachine.h"
373c2d4bf97fa96fe171883cd80e4ea93fc43563e6Daniel Dunbar#include "llvm/Target/TargetRegistry.h"
382deb58f72ec6547a2f760fc48f86b4d95d0a4a02Chris Lattner#include "llvm/Target/TargetSelect.h"
3986f42bdad93677fa0ca33b27afb0f493028376cbReid Spencer#include <memory>
40d0fde30ce850b78371fd1386338350591f9ff494Brian Gaekeusing namespace llvm;
41d0fde30ce850b78371fd1386338350591f9ff494Brian Gaeke
427d0ba026401321be1645b4142abeb85e943d0577Vikram S. Adve// General options for llc.  Other pass-specific options are specified
437d0ba026401321be1645b4142abeb85e943d0577Vikram S. Adve// within the corresponding llc passes, and target-specific options
447d0ba026401321be1645b4142abeb85e943d0577Vikram S. Adve// and back-end code generation options are specified with the target machine.
453da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman//
46b5881f126d4baab41dc7efb2824a53601ef167b0Chris Lattnerstatic cl::opt<std::string>
47a99be51bf5cdac1438069d4b01766c47704961c8Gabor GreifInputFilename(cl::Positional, cl::desc("<input bitcode>"), cl::init("-"));
485ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner
49b5881f126d4baab41dc7efb2824a53601ef167b0Chris Lattnerstatic cl::opt<std::string>
505ff62e90d0bc321206023897edc1e2691cb0fbb6Chris LattnerOutputFilename("o", cl::desc("Output filename"), cl::value_desc("filename"));
515ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner
52baa26395ccf17fc988bb9cf62d6659ca8415ece9Dan Gohmanstatic cl::opt<bool>
53baa26395ccf17fc988bb9cf62d6659ca8415ece9Dan GohmanForce("f", cl::desc("Enable binary output on terminals"));
545ff62e90d0bc321206023897edc1e2691cb0fbb6Chris Lattner
55712e80e188c306125e32e46e9ed5db9dfc2f7cc9Evan Cheng// Determine optimization level.
5698a366d547772010e94609e4584489b3e5ce0043Bill Wendlingstatic cl::opt<char>
57be8cc2a3dedeb7685f07e68cdc4b9502eb97eb2bBill WendlingOptLevel("O",
58712e80e188c306125e32e46e9ed5db9dfc2f7cc9Evan Cheng         cl::desc("Optimization level. [-O0, -O1, -O2, or -O3] "
59712e80e188c306125e32e46e9ed5db9dfc2f7cc9Evan Cheng                  "(default = '-O2')"),
60be8cc2a3dedeb7685f07e68cdc4b9502eb97eb2bBill Wendling         cl::Prefix,
61be8cc2a3dedeb7685f07e68cdc4b9502eb97eb2bBill Wendling         cl::ZeroOrMore,
6298a366d547772010e94609e4584489b3e5ce0043Bill Wendling         cl::init(' '));
63178e0c41ce22160e6a1005420a52c29162dd87d3Chris Lattner
64f33b8663bdd9056660c9e520f20d9a562cbcff0bChris Lattnerstatic cl::opt<std::string>
65be193839fa8650bc4f2974a82327543054202190Chris LattnerTargetTriple("mtriple", cl::desc("Override target triple for module"));
66178e0c41ce22160e6a1005420a52c29162dd87d3Chris Lattner
671d929216916dc992f8643dda971aac58d47c7765Daniel Dunbarstatic cl::opt<std::string>
681d929216916dc992f8643dda971aac58d47c7765Daniel DunbarMArch("march", cl::desc("Architecture to generate code for (see --version)"));
693da94aec4d429b2ba0f65fa040c33650cade196bMisha Brukman
70b1e1180ca0b32f37aa74d7ad703eeaf91e66c8faJim Laskeystatic cl::opt<std::string>
715c1799b29375fcd899f67a31fb4dda4ef3e2127fMikhail GlushenkovMCPU("mcpu",
727b7593c4815d95f53148d41b171580e8c88741b6Chris Lattner  cl::desc("Target a specific cpu type (-mcpu=help for details)"),
73b1e1180ca0b32f37aa74d7ad703eeaf91e66c8faJim Laskey  cl::value_desc("cpu-name"),
74b1e1180ca0b32f37aa74d7ad703eeaf91e66c8faJim Laskey  cl::init(""));
75b1e1180ca0b32f37aa74d7ad703eeaf91e66c8faJim Laskey
76b1e1180ca0b32f37aa74d7ad703eeaf91e66c8faJim Laskeystatic cl::list<std::string>
775c1799b29375fcd899f67a31fb4dda4ef3e2127fMikhail GlushenkovMAttrs("mattr",
78b1e1180ca0b32f37aa74d7ad703eeaf91e66c8faJim Laskey  cl::CommaSeparated,
797b7593c4815d95f53148d41b171580e8c88741b6Chris Lattner  cl::desc("Target specific attributes (-mattr=help for details)"),
802094725532836da20db56412ad7f88bc8eb6e586Chris Lattner  cl::value_desc("a1,+a2,-a3,..."));
81b1e1180ca0b32f37aa74d7ad703eeaf91e66c8faJim Laskey
82812125aea956d0c22d92b456dbc5030a1d2780efChris Lattnercl::opt<TargetMachine::CodeGenFileType>
83211edae4843f5c2ee9c376e88e4cf0ecc8745f03Chris LattnerFileType("filetype", cl::init(TargetMachine::CGFT_AssemblyFile),
84812125aea956d0c22d92b456dbc5030a1d2780efChris Lattner  cl::desc("Choose a file type (not all types are supported by all targets):"),
85812125aea956d0c22d92b456dbc5030a1d2780efChris Lattner  cl::values(
86211edae4843f5c2ee9c376e88e4cf0ecc8745f03Chris Lattner       clEnumValN(TargetMachine::CGFT_AssemblyFile, "asm",
87b8cab9227a0f6ffbdaae33e3c64268e265008a6aDan Gohman                  "Emit an assembly ('.s') file"),
88211edae4843f5c2ee9c376e88e4cf0ecc8745f03Chris Lattner       clEnumValN(TargetMachine::CGFT_ObjectFile, "obj",
89b8cab9227a0f6ffbdaae33e3c64268e265008a6aDan Gohman                  "Emit a native object ('.o') file [experimental]"),
905669e3009761dff20b67e18a382c334041887928Chris Lattner       clEnumValN(TargetMachine::CGFT_Null, "null",
915669e3009761dff20b67e18a382c334041887928Chris Lattner                  "Emit nothing, for performance testing"),
92812125aea956d0c22d92b456dbc5030a1d2780efChris Lattner       clEnumValEnd));
93812125aea956d0c22d92b456dbc5030a1d2780efChris Lattner
944418c2b3acfcb6cdb05f133aef8eef74ed0d0566Reid Spencercl::opt<bool> NoVerify("disable-verify", cl::Hidden,
95d29b6aa608d69f19b57ebd2ae630b040b1c4951dJeff Cohen                       cl::desc("Do not verify input module"));
964418c2b3acfcb6cdb05f133aef8eef74ed0d0566Reid Spencer
97812125aea956d0c22d92b456dbc5030a1d2780efChris Lattner
98d18e31ae17390d9c6f6cf93d18badf962452031dDevang Patelstatic cl::opt<bool>
99d18e31ae17390d9c6f6cf93d18badf962452031dDevang PatelDisableRedZone("disable-red-zone",
100d18e31ae17390d9c6f6cf93d18badf962452031dDevang Patel  cl::desc("Do not emit code that uses the red zone."),
101d18e31ae17390d9c6f6cf93d18badf962452031dDevang Patel  cl::init(false));
102d18e31ae17390d9c6f6cf93d18badf962452031dDevang Patel
103578efa920abd218ba75a0fb3c9b8398f4c0a774bDevang Patelstatic cl::opt<bool>
104578efa920abd218ba75a0fb3c9b8398f4c0a774bDevang PatelNoImplicitFloats("no-implicit-float",
105578efa920abd218ba75a0fb3c9b8398f4c0a774bDevang Patel  cl::desc("Don't generate implicit floating point instructions (x86-only)"),
106578efa920abd218ba75a0fb3c9b8398f4c0a774bDevang Patel  cl::init(false));
107578efa920abd218ba75a0fb3c9b8398f4c0a774bDevang Patel
108812125aea956d0c22d92b456dbc5030a1d2780efChris Lattner// GetFileNameRoot - Helper function to get the basename of a filename.
109b5881f126d4baab41dc7efb2824a53601ef167b0Chris Lattnerstatic inline std::string
110e45110e01282862e95c3d28c489dedd9a08ffa31Chris LattnerGetFileNameRoot(const std::string &InputFilename) {
111b5881f126d4baab41dc7efb2824a53601ef167b0Chris Lattner  std::string IFN = InputFilename;
112b5881f126d4baab41dc7efb2824a53601ef167b0Chris Lattner  std::string outputFilename;
1132f64f9f264d30dd0ac4880eb16ba9eeac538e94cVikram S. Adve  int Len = IFN.length();
114b5d09bf4cc7769ccbd86a96fb8ea92e3c6e3bbc7John Criswell  if ((Len > 2) &&
115d81c450afcc0258586d677813c388b0c8f289887Dan Gohman      IFN[Len-3] == '.' &&
116d81c450afcc0258586d677813c388b0c8f289887Dan Gohman      ((IFN[Len-2] == 'b' && IFN[Len-1] == 'c') ||
117d81c450afcc0258586d677813c388b0c8f289887Dan Gohman       (IFN[Len-2] == 'l' && IFN[Len-1] == 'l'))) {
118b5881f126d4baab41dc7efb2824a53601ef167b0Chris Lattner    outputFilename = std::string(IFN.begin(), IFN.end()-3); // s/.bc/.s/
1192f64f9f264d30dd0ac4880eb16ba9eeac538e94cVikram S. Adve  } else {
1203524fc2197c17edcea786a9bb0e00246438dba90Chris Lattner    outputFilename = IFN;
1212f64f9f264d30dd0ac4880eb16ba9eeac538e94cVikram S. Adve  }
1222f64f9f264d30dd0ac4880eb16ba9eeac538e94cVikram S. Adve  return outputFilename;
1232f64f9f264d30dd0ac4880eb16ba9eeac538e94cVikram S. Adve}
1242f64f9f264d30dd0ac4880eb16ba9eeac538e94cVikram S. Adve
12551b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbarstatic formatted_raw_ostream *GetOutputStream(const char *TargetName,
12651b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar                                              const char *ProgName) {
1271911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner  if (OutputFilename != "") {
1281911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner    if (OutputFilename == "-")
12971847813bc419f7a0667468136a07429c6d9f164David Greene      return &fouts();
1301911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner
1311911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner    // Make sure that the Out file gets unlinked from the disk if we get a
1321911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner    // SIGINT
1331911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner    sys::RemoveFileOnSignal(sys::Path(OutputFilename));
1341911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner
135cb3718832375a581c5ea23f15918f3ea447a446cOwen Anderson    std::string error;
13617e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner    raw_fd_ostream *FDOut =
13717e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner      new raw_fd_ostream(OutputFilename.c_str(), error,
13817e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner                         raw_fd_ostream::F_Binary);
139ed3e8b4ed2a3ab44d316e16a54d963f8927c6783Dan Gohman    if (!error.empty()) {
14065f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman      errs() << error << '\n';
141a1bdcedc3879510a874d24c450e07feb170d9cd6Dan Gohman      delete FDOut;
142ed3e8b4ed2a3ab44d316e16a54d963f8927c6783Dan Gohman      return 0;
143ed3e8b4ed2a3ab44d316e16a54d963f8927c6783Dan Gohman    }
144a1bdcedc3879510a874d24c450e07feb170d9cd6Dan Gohman    formatted_raw_ostream *Out =
145a1bdcedc3879510a874d24c450e07feb170d9cd6Dan Gohman      new formatted_raw_ostream(*FDOut, formatted_raw_ostream::DELETE_STREAM);
146ed3e8b4ed2a3ab44d316e16a54d963f8927c6783Dan Gohman
147ed3e8b4ed2a3ab44d316e16a54d963f8927c6783Dan Gohman    return Out;
1481911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner  }
1495c1799b29375fcd899f67a31fb4dda4ef3e2127fMikhail Glushenkov
1501911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner  if (InputFilename == "-") {
1511911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner    OutputFilename = "-";
15271847813bc419f7a0667468136a07429c6d9f164David Greene    return &fouts();
1531911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner  }
1541911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner
1551911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner  OutputFilename = GetFileNameRoot(InputFilename);
1565c1799b29375fcd899f67a31fb4dda4ef3e2127fMikhail Glushenkov
1570d9eb9b4917340acbfc831890655b8e9724959f6Daniel Dunbar  bool Binary = false;
1581911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner  switch (FileType) {
159211edae4843f5c2ee9c376e88e4cf0ecc8745f03Chris Lattner  default: assert(0 && "Unknown file type");
160211edae4843f5c2ee9c376e88e4cf0ecc8745f03Chris Lattner  case TargetMachine::CGFT_AssemblyFile:
16151b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar    if (TargetName[0] == 'c') {
16251b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar      if (TargetName[1] == 0)
1635027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        OutputFilename += ".cbe.c";
16451b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar      else if (TargetName[1] == 'p' && TargetName[2] == 'p')
1655027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        OutputFilename += ".cpp";
1665027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov      else
1675027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov        OutputFilename += ".s";
1685027652b8ae5414d634288d456364ef2534cb406Anton Korobeynikov    } else
1691911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner      OutputFilename += ".s";
1701911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner    break;
171211edae4843f5c2ee9c376e88e4cf0ecc8745f03Chris Lattner  case TargetMachine::CGFT_ObjectFile:
1721911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner    OutputFilename += ".o";
1730d9eb9b4917340acbfc831890655b8e9724959f6Daniel Dunbar    Binary = true;
1741911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner    break;
1755669e3009761dff20b67e18a382c334041887928Chris Lattner  case TargetMachine::CGFT_Null:
1765669e3009761dff20b67e18a382c334041887928Chris Lattner    OutputFilename += ".null";
1770d9eb9b4917340acbfc831890655b8e9724959f6Daniel Dunbar    Binary = true;
1781911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner    break;
1791911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner  }
1805c1799b29375fcd899f67a31fb4dda4ef3e2127fMikhail Glushenkov
1811911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner  // Make sure that the Out file gets unlinked from the disk if we get a
1821911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner  // SIGINT
1831911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner  sys::RemoveFileOnSignal(sys::Path(OutputFilename));
1845c1799b29375fcd899f67a31fb4dda4ef3e2127fMikhail Glushenkov
185cb3718832375a581c5ea23f15918f3ea447a446cOwen Anderson  std::string error;
18617e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner  unsigned OpenFlags = 0;
18717e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner  if (Binary) OpenFlags |= raw_fd_ostream::F_Binary;
18817e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner  raw_fd_ostream *FDOut = new raw_fd_ostream(OutputFilename.c_str(), error,
18917e9edc4a7bbeadf756494cf39fcacc9eff72202Chris Lattner                                             OpenFlags);
190cb3718832375a581c5ea23f15918f3ea447a446cOwen Anderson  if (!error.empty()) {
19165f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman    errs() << error << '\n';
192a1bdcedc3879510a874d24c450e07feb170d9cd6Dan Gohman    delete FDOut;
1931911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner    return 0;
1941911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner  }
1955c1799b29375fcd899f67a31fb4dda4ef3e2127fMikhail Glushenkov
196a1bdcedc3879510a874d24c450e07feb170d9cd6Dan Gohman  formatted_raw_ostream *Out =
197a1bdcedc3879510a874d24c450e07feb170d9cd6Dan Gohman    new formatted_raw_ostream(*FDOut, formatted_raw_ostream::DELETE_STREAM);
198a1bdcedc3879510a874d24c450e07feb170d9cd6Dan Gohman
1991911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner  return Out;
2001911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner}
201da784ee81f082781fb61258546fec7c82ba6a8f0Chris Lattner
2025b836c4a06c584544647d5b013b193510ac5ced5Chris Lattner// main - Entry point for the llc compiler.
2035b836c4a06c584544647d5b013b193510ac5ced5Chris Lattner//
2045b836c4a06c584544647d5b013b193510ac5ced5Chris Lattnerint main(int argc, char **argv) {
2051a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  sys::PrintStackTraceOnErrorSignal();
206cc14d25dd99e891c586bd56aa41796abbe4ac3d8Chris Lattner  PrettyStackTraceProgram X(argc, argv);
207c58d01b235fb6aba9edb49f6dbe08edaa756a873David Greene
208c58d01b235fb6aba9edb49f6dbe08edaa756a873David Greene  // Enable debug stream buffering.
209c58d01b235fb6aba9edb49f6dbe08edaa756a873David Greene  EnableDebugBuffering = true;
210c58d01b235fb6aba9edb49f6dbe08edaa756a873David Greene
2110d7c695c74ae6d5f68cc07378c17491915e607d3Owen Anderson  LLVMContext &Context = getGlobalContext();
212cc14d25dd99e891c586bd56aa41796abbe4ac3d8Chris Lattner  llvm_shutdown_obj Y;  // Call llvm_shutdown() on exit.
213e45110e01282862e95c3d28c489dedd9a08ffa31Chris Lattner
2142b991bbd9918d7ae67d3f6d9ae69cf15d929698bDaniel Dunbar  // Initialize targets first, so that --version shows registered targets.
2152deb58f72ec6547a2f760fc48f86b4d95d0a4a02Chris Lattner  InitializeAllTargets();
2162deb58f72ec6547a2f760fc48f86b4d95d0a4a02Chris Lattner  InitializeAllAsmPrinters();
217af632c91a0090d8448dd10e48d8ce53f31be0a21Chris Lattner  InitializeAllAsmParsers();
218494d663175bbaa7db4743105d1efdf78be9cdb03Daniel Dunbar
219494d663175bbaa7db4743105d1efdf78be9cdb03Daniel Dunbar  cl::ParseCommandLineOptions(argc, argv, "llvm system compiler\n");
2202deb58f72ec6547a2f760fc48f86b4d95d0a4a02Chris Lattner
2211a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  // Load the module to be compiled...
222778b06bbcecbe52125dddcb06e898806b1e2b3c7Dan Gohman  SMDiagnostic Err;
2231a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  std::auto_ptr<Module> M;
2245c1799b29375fcd899f67a31fb4dda4ef3e2127fMikhail Glushenkov
225778b06bbcecbe52125dddcb06e898806b1e2b3c7Dan Gohman  M.reset(ParseIRFile(InputFilename, Err, Context));
2261a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  if (M.get() == 0) {
227778b06bbcecbe52125dddcb06e898806b1e2b3c7Dan Gohman    Err.Print(argv[0], errs());
2281a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    return 1;
2291a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  }
2301a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  Module &mod = *M.get();
2315c1799b29375fcd899f67a31fb4dda4ef3e2127fMikhail Glushenkov
2321a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  // If we are supposed to override the target triple, do so now.
2331a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  if (!TargetTriple.empty())
2341a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    mod.setTargetTriple(TargetTriple);
2355c1799b29375fcd899f67a31fb4dda4ef3e2127fMikhail Glushenkov
2363c2d4bf97fa96fe171883cd80e4ea93fc43563e6Daniel Dunbar  Triple TheTriple(mod.getTargetTriple());
2373c2d4bf97fa96fe171883cd80e4ea93fc43563e6Daniel Dunbar  if (TheTriple.getTriple().empty())
2383c2d4bf97fa96fe171883cd80e4ea93fc43563e6Daniel Dunbar    TheTriple.setTriple(sys::getHostTriple());
2393c2d4bf97fa96fe171883cd80e4ea93fc43563e6Daniel Dunbar
2403c2d4bf97fa96fe171883cd80e4ea93fc43563e6Daniel Dunbar  // Allocate target machine.  First, check whether the user has explicitly
2413c2d4bf97fa96fe171883cd80e4ea93fc43563e6Daniel Dunbar  // specified an architecture to compile for. If so we have to look it up by
2423c2d4bf97fa96fe171883cd80e4ea93fc43563e6Daniel Dunbar  // name, because it might be a backend that has no mapping to a target triple.
2431d929216916dc992f8643dda971aac58d47c7765Daniel Dunbar  const Target *TheTarget = 0;
2441d929216916dc992f8643dda971aac58d47c7765Daniel Dunbar  if (!MArch.empty()) {
2451d929216916dc992f8643dda971aac58d47c7765Daniel Dunbar    for (TargetRegistry::iterator it = TargetRegistry::begin(),
2461d929216916dc992f8643dda971aac58d47c7765Daniel Dunbar           ie = TargetRegistry::end(); it != ie; ++it) {
2471d929216916dc992f8643dda971aac58d47c7765Daniel Dunbar      if (MArch == it->getName()) {
2481d929216916dc992f8643dda971aac58d47c7765Daniel Dunbar        TheTarget = &*it;
2491d929216916dc992f8643dda971aac58d47c7765Daniel Dunbar        break;
2501d929216916dc992f8643dda971aac58d47c7765Daniel Dunbar      }
2511d929216916dc992f8643dda971aac58d47c7765Daniel Dunbar    }
2521d929216916dc992f8643dda971aac58d47c7765Daniel Dunbar
2531d929216916dc992f8643dda971aac58d47c7765Daniel Dunbar    if (!TheTarget) {
2541d929216916dc992f8643dda971aac58d47c7765Daniel Dunbar      errs() << argv[0] << ": error: invalid target '" << MArch << "'.\n";
2551d929216916dc992f8643dda971aac58d47c7765Daniel Dunbar      return 1;
2563c2d4bf97fa96fe171883cd80e4ea93fc43563e6Daniel Dunbar    }
2573c2d4bf97fa96fe171883cd80e4ea93fc43563e6Daniel Dunbar
2583c2d4bf97fa96fe171883cd80e4ea93fc43563e6Daniel Dunbar    // Adjust the triple to match (if known), otherwise stick with the
2593c2d4bf97fa96fe171883cd80e4ea93fc43563e6Daniel Dunbar    // module/host triple.
2603c2d4bf97fa96fe171883cd80e4ea93fc43563e6Daniel Dunbar    Triple::ArchType Type = Triple::getArchTypeForLLVMName(MArch);
2613c2d4bf97fa96fe171883cd80e4ea93fc43563e6Daniel Dunbar    if (Type != Triple::UnknownArch)
2623c2d4bf97fa96fe171883cd80e4ea93fc43563e6Daniel Dunbar      TheTriple.setArch(Type);
26351b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar  } else {
2641a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    std::string Err;
2654bd03abe593222b26e84066223feb321bf738625Daniel Dunbar    TheTarget = TargetRegistry::lookupTarget(TheTriple.getTriple(), Err);
26651b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar    if (TheTarget == 0) {
26765f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman      errs() << argv[0] << ": error auto-selecting target for module '"
26865f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman             << Err << "'.  Please use the -march option to explicitly "
26965f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman             << "pick a target.\n";
2701a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner      return 1;
271b1e1180ca0b32f37aa74d7ad703eeaf91e66c8faJim Laskey    }
2721a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  }
273b1e1180ca0b32f37aa74d7ad703eeaf91e66c8faJim Laskey
2741a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  // Package up features to be passed to target/subtarget
2751a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  std::string FeaturesStr;
2761a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  if (MCPU.size() || MAttrs.size()) {
2771a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    SubtargetFeatures Features;
2781a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    Features.setCPU(MCPU);
2791a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    for (unsigned i = 0; i != MAttrs.size(); ++i)
2801a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner      Features.AddFeature(MAttrs[i]);
2811a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    FeaturesStr = Features.getString();
2821a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  }
2835c1799b29375fcd899f67a31fb4dda4ef3e2127fMikhail Glushenkov
28451b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar  std::auto_ptr<TargetMachine>
2854b3d57228cae1cba0897b80a73fddd4b8a61894aDaniel Dunbar    target(TheTarget->createTargetMachine(TheTriple.getTriple(), FeaturesStr));
2861a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  assert(target.get() && "Could not allocate target machine!");
2871a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  TargetMachine &Target = *target.get();
2881ef8bdaedbd98bee35a573b8bc87149f2182cb5eReid Spencer
2891a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  // Figure out where we are going to send the output...
29051b198af83cb0080c2709b04c129a3d774c07765Daniel Dunbar  formatted_raw_ostream *Out = GetOutputStream(TheTarget->getName(), argv[0]);
2911a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  if (Out == 0) return 1;
2925c1799b29375fcd899f67a31fb4dda4ef3e2127fMikhail Glushenkov
293712e80e188c306125e32e46e9ed5db9dfc2f7cc9Evan Cheng  CodeGenOpt::Level OLvl = CodeGenOpt::Default;
29498a366d547772010e94609e4584489b3e5ce0043Bill Wendling  switch (OptLevel) {
29598a366d547772010e94609e4584489b3e5ce0043Bill Wendling  default:
29665f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman    errs() << argv[0] << ": invalid optimization level.\n";
2978dc85ddf809b9b987b92da27c0ff7875d6e1f72dBill Wendling    return 1;
29898a366d547772010e94609e4584489b3e5ce0043Bill Wendling  case ' ': break;
29998a366d547772010e94609e4584489b3e5ce0043Bill Wendling  case '0': OLvl = CodeGenOpt::None; break;
300bf57b52ba424bbaaa6e2d25dd4df731deb59f959Evan Cheng  case '1': OLvl = CodeGenOpt::Less; break;
301581b93415ef207a2103913e24874889426b1063eBill Wendling  case '2': OLvl = CodeGenOpt::Default; break;
30298a366d547772010e94609e4584489b3e5ce0043Bill Wendling  case '3': OLvl = CodeGenOpt::Aggressive; break;
30398a366d547772010e94609e4584489b3e5ce0043Bill Wendling  }
30498a366d547772010e94609e4584489b3e5ce0043Bill Wendling
305d44f16fce7b23d61e0b10cfdca3d10869b0236aeDan Gohman  // Request that addPassesToEmitFile run the Verifier after running
306d44f16fce7b23d61e0b10cfdca3d10869b0236aeDan Gohman  // passes which modify the IR.
307d44f16fce7b23d61e0b10cfdca3d10869b0236aeDan Gohman#ifndef NDEBUG
308d44f16fce7b23d61e0b10cfdca3d10869b0236aeDan Gohman  bool DisableVerify = false;
309d44f16fce7b23d61e0b10cfdca3d10869b0236aeDan Gohman#else
310d44f16fce7b23d61e0b10cfdca3d10869b0236aeDan Gohman  bool DisableVerify = true;
311d44f16fce7b23d61e0b10cfdca3d10869b0236aeDan Gohman#endif
312d44f16fce7b23d61e0b10cfdca3d10869b0236aeDan Gohman
3131a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  // If this target requires addPassesToEmitWholeFile, do it now.  This is
3141a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  // used by strange things like the C backend.
3151a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  if (Target.WantsWholeFile()) {
3161a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    PassManager PM;
3174e02eb0f67356762eeb12a75f8d4d6f47de955a4Daniel Dunbar
3184e02eb0f67356762eeb12a75f8d4d6f47de955a4Daniel Dunbar    // Add the target data from the target machine, if it exists, or the module.
3194e02eb0f67356762eeb12a75f8d4d6f47de955a4Daniel Dunbar    if (const TargetData *TD = Target.getTargetData())
3204e02eb0f67356762eeb12a75f8d4d6f47de955a4Daniel Dunbar      PM.add(new TargetData(*TD));
3214e02eb0f67356762eeb12a75f8d4d6f47de955a4Daniel Dunbar    else
3224e02eb0f67356762eeb12a75f8d4d6f47de955a4Daniel Dunbar      PM.add(new TargetData(&mod));
3234e02eb0f67356762eeb12a75f8d4d6f47de955a4Daniel Dunbar
3241a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    if (!NoVerify)
3251a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner      PM.add(createVerifierPass());
3265c1799b29375fcd899f67a31fb4dda4ef3e2127fMikhail Glushenkov
3271a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    // Ask the target to add backend passes as necessary.
328d44f16fce7b23d61e0b10cfdca3d10869b0236aeDan Gohman    if (Target.addPassesToEmitWholeFile(PM, *Out, FileType, OLvl,
329d44f16fce7b23d61e0b10cfdca3d10869b0236aeDan Gohman                                        DisableVerify)) {
33065f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman      errs() << argv[0] << ": target does not support generation of this"
33165f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman             << " file type!\n";
33271847813bc419f7a0667468136a07429c6d9f164David Greene      if (Out != &fouts()) delete Out;
3331a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner      // And the Out file is empty and useless, so remove it now.
3341a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner      sys::Path(OutputFilename).eraseFromDisk();
3351a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner      return 1;
3361a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    }
3371a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    PM.run(mod);
3381a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  } else {
3391a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    // Build up all of the passes that we want to do to the module.
340f0356fe140af1a30587b9a86bcfb1b2c51b8ce20Jeffrey Yasskin    FunctionPassManager Passes(M.get());
3414e02eb0f67356762eeb12a75f8d4d6f47de955a4Daniel Dunbar
3424e02eb0f67356762eeb12a75f8d4d6f47de955a4Daniel Dunbar    // Add the target data from the target machine, if it exists, or the module.
3434e02eb0f67356762eeb12a75f8d4d6f47de955a4Daniel Dunbar    if (const TargetData *TD = Target.getTargetData())
3444e02eb0f67356762eeb12a75f8d4d6f47de955a4Daniel Dunbar      Passes.add(new TargetData(*TD));
3454e02eb0f67356762eeb12a75f8d4d6f47de955a4Daniel Dunbar    else
3464e02eb0f67356762eeb12a75f8d4d6f47de955a4Daniel Dunbar      Passes.add(new TargetData(&mod));
3475c1799b29375fcd899f67a31fb4dda4ef3e2127fMikhail Glushenkov
3481911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner#ifndef NDEBUG
3491a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    if (!NoVerify)
3501a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner      Passes.add(createVerifierPass());
3511911fd4f85aebcd4d7b8f27313c5a363eebf49cbChris Lattner#endif
3525c1799b29375fcd899f67a31fb4dda4ef3e2127fMikhail Glushenkov
35323120babfaa23e1ecfe374866f498855dbe5fe27Evan Cheng    // Override default to generate verbose assembly.
35423120babfaa23e1ecfe374866f498855dbe5fe27Evan Cheng    Target.setAsmVerbosityDefault(true);
35523120babfaa23e1ecfe374866f498855dbe5fe27Evan Cheng
356d44f16fce7b23d61e0b10cfdca3d10869b0236aeDan Gohman    if (Target.addPassesToEmitFile(Passes, *Out, FileType, OLvl,
357d44f16fce7b23d61e0b10cfdca3d10869b0236aeDan Gohman                                   DisableVerify)) {
35865f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman      errs() << argv[0] << ": target does not support generation of this"
35965f57c233cd4499e2e8b52a503201e64edfd6a9eDan Gohman             << " file type!\n";
36071847813bc419f7a0667468136a07429c6d9f164David Greene      if (Out != &fouts()) delete Out;
3611a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner      // And the Out file is empty and useless, so remove it now.
3621a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner      sys::Path(OutputFilename).eraseFromDisk();
3631a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner      return 1;
3641a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    }
365546d0fbd9718ea5ad422faaeffea939fe7312408Bill Wendling
3661a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    Passes.doInitialization();
3675c1799b29375fcd899f67a31fb4dda4ef3e2127fMikhail Glushenkov
3681a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    // Run our queue of passes all at once now, efficiently.
3691a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    // TODO: this could lazily stream functions out of the module.
3701a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    for (Module::iterator I = mod.begin(), E = mod.end(); I != E; ++I)
371d18e31ae17390d9c6f6cf93d18badf962452031dDevang Patel      if (!I->isDeclaration()) {
372d18e31ae17390d9c6f6cf93d18badf962452031dDevang Patel        if (DisableRedZone)
373d18e31ae17390d9c6f6cf93d18badf962452031dDevang Patel          I->addFnAttr(Attribute::NoRedZone);
374578efa920abd218ba75a0fb3c9b8398f4c0a774bDevang Patel        if (NoImplicitFloats)
375578efa920abd218ba75a0fb3c9b8398f4c0a774bDevang Patel          I->addFnAttr(Attribute::NoImplicitFloat);
3761a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner        Passes.run(*I);
377d18e31ae17390d9c6f6cf93d18badf962452031dDevang Patel      }
3785c1799b29375fcd899f67a31fb4dda4ef3e2127fMikhail Glushenkov
3791a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner    Passes.doFinalization();
3801a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  }
3815c1799b29375fcd899f67a31fb4dda4ef3e2127fMikhail Glushenkov
3821a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  // Delete the ostream if it's not a stdout stream
38371847813bc419f7a0667468136a07429c6d9f164David Greene  if (Out != &fouts()) delete Out;
38405e5e070ee73309025e11bea0c15d7fc9c25fea6Chris Lattner
3851a7354082ad62d9e31faf3d6ad15c39debc94fd6Chris Lattner  return 0;
3862f64f9f264d30dd0ac4880eb16ba9eeac538e94cVikram S. Adve}
387