lto.cpp revision f2ca21f88f4e38996b6804dfa25fe7a72814736d
1a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel//===-lto.cpp - LLVM Link Time Optimizer ----------------------------------===//
2a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel//
3a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel//                     The LLVM Compiler Infrastructure
4a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel//
5a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel// This file was developed by Devang Patel and is distributed under
6a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel// the University of Illinois Open Source License. See LICENSE.TXT for details.
7a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel//
8a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel//===----------------------------------------------------------------------===//
9a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel//
10a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel// This file implementes link time optimization library. This library is
11a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel// intended to be used by linker to optimize code at link time.
12a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel//
13a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel//===----------------------------------------------------------------------===//
14a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
15a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel#include "llvm/Module.h"
16a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel#include "llvm/PassManager.h"
17a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel#include "llvm/Linker.h"
18a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel#include "llvm/Constants.h"
19a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel#include "llvm/DerivedTypes.h"
20a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel#include "llvm/SymbolTable.h"
21a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel#include "llvm/Bytecode/Reader.h"
22a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel#include "llvm/Bytecode/Writer.h"
23a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel#include "llvm/Support/CommandLine.h"
24a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel#include "llvm/Support/FileUtilities.h"
25a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel#include "llvm/Support/SystemUtils.h"
2630235dad4b77ed83ca985030aff4fb4767551e5dDevang Patel#include "llvm/Support/Mangler.h"
27a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel#include "llvm/System/Program.h"
28a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel#include "llvm/System/Signals.h"
29a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel#include "llvm/Analysis/Passes.h"
30a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel#include "llvm/Analysis/Verifier.h"
31a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel#include "llvm/Target/SubtargetFeature.h"
32a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel#include "llvm/Target/TargetData.h"
33a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel#include "llvm/Target/TargetMachine.h"
34a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel#include "llvm/Target/TargetMachineRegistry.h"
35a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel#include "llvm/Transforms/IPO.h"
36a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel#include "llvm/Transforms/Scalar.h"
37a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel#include "llvm/Analysis/LoadValueNumbering.h"
38a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel#include "llvm/LinkTimeOptimizer.h"
39a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel#include <fstream>
40a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel#include <iostream>
41a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
42a89d47f54d1f83d328f6169151653bfc742607bfDevang Patelusing namespace llvm;
43a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
44a89d47f54d1f83d328f6169151653bfc742607bfDevang Patelextern "C"
45a89d47f54d1f83d328f6169151653bfc742607bfDevang Patelllvm::LinkTimeOptimizer *createLLVMOptimizer()
46a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel{
47c7cfbc58ad88f127df6949791401969a09da560fDevang Patel  llvm::LTO *l = new llvm::LTO();
48a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  return l;
49a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel}
50a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
51a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
52a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
53a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel/// If symbol is not used then make it internal and let optimizer takes
54a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel/// care of it.
55a89d47f54d1f83d328f6169151653bfc742607bfDevang Patelvoid LLVMSymbol::mayBeNotUsed() {
56a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  gv->setLinkage(GlobalValue::InternalLinkage);
57a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel}
58a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
59a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel// Helper routine
60a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel// FIXME : Take advantage of GlobalPrefix from AsmPrinter
61a89d47f54d1f83d328f6169151653bfc742607bfDevang Patelstatic const char *addUnderscore(const char *name) {
62a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  size_t namelen = strlen(name);
63a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  char *symName = (char*)malloc(namelen+2);
64a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  symName[0] = '_';
65a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  strcpy(&symName[1], name);
66a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  return symName;
67a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel}
68a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
69a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel// Map LLVM LinkageType to LTO LinakgeType
70a89d47f54d1f83d328f6169151653bfc742607bfDevang Patelstatic LTOLinkageTypes
71a89d47f54d1f83d328f6169151653bfc742607bfDevang PatelgetLTOLinkageType(GlobalValue *v)
72a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel{
73a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  LTOLinkageTypes lt;
74a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  if (v->hasExternalLinkage())
75a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel    lt = LTOExternalLinkage;
76a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  else if (v->hasLinkOnceLinkage())
77a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel    lt = LTOLinkOnceLinkage;
78a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  else if (v->hasWeakLinkage())
79a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel    lt = LTOWeakLinkage;
80a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  else
81a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel    // Otherwise it is internal linkage for link time optimizer
82a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel    lt = LTOInternalLinkage;
83a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  return lt;
84a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel}
85a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
86a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel// Find exeternal symbols referenced by VALUE. This is a recursive function.
87a89d47f54d1f83d328f6169151653bfc742607bfDevang Patelstatic void
8830235dad4b77ed83ca985030aff4fb4767551e5dDevang PatelfindExternalRefs(Value *value, std::set<std::string> &references,
892198f9cec47b4683377d4f4080acb14dd94fad65Devang Patel                 Mangler &mangler) {
90304d5f2edc954a3ef9904ea6d8f9421f40c9abe4Devang Patel
91304d5f2edc954a3ef9904ea6d8f9421f40c9abe4Devang Patel  if (GlobalValue *gv = dyn_cast<GlobalValue>(value)) {
92a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel    LTOLinkageTypes lt = getLTOLinkageType(gv);
93a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel    if (lt != LTOInternalLinkage && strncmp (gv->getName().c_str(), "llvm.", 5))
9430235dad4b77ed83ca985030aff4fb4767551e5dDevang Patel      references.insert(mangler.getValueName(gv));
95a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  }
96544ea34a9f7aeef5fa3cbfdaae5933f93f4f68ecDevang Patel
97544ea34a9f7aeef5fa3cbfdaae5933f93f4f68ecDevang Patel  // GlobalValue, even with InternalLinkage type, may have operands with
98544ea34a9f7aeef5fa3cbfdaae5933f93f4f68ecDevang Patel  // ExternalLinkage type. Do not ignore these operands.
9997d92d50aa52fd7f891ddeaf9e3886305a5a77d9Devang Patel  if (Constant *c = dyn_cast<Constant>(value))
100304d5f2edc954a3ef9904ea6d8f9421f40c9abe4Devang Patel    // Handle ConstantExpr, ConstantStruct, ConstantArry etc..
101304d5f2edc954a3ef9904ea6d8f9421f40c9abe4Devang Patel    for (unsigned i = 0, e = c->getNumOperands(); i != e; ++i)
10230235dad4b77ed83ca985030aff4fb4767551e5dDevang Patel      findExternalRefs(c->getOperand(i), references, mangler);
103a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel}
104a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
105f2ca21f88f4e38996b6804dfa25fe7a72814736dDevang Patel/// If Moduel with InputFilename is available then remove it.
106f2ca21f88f4e38996b6804dfa25fe7a72814736dDevang Patelvoid
107f2ca21f88f4e38996b6804dfa25fe7a72814736dDevang PatelLTO::removeModule (const std::string &InputFilename)
108f2ca21f88f4e38996b6804dfa25fe7a72814736dDevang Patel{
109f2ca21f88f4e38996b6804dfa25fe7a72814736dDevang Patel  NameToModuleMap::iterator pos = allModules.find(InputFilename.c_str());
110f2ca21f88f4e38996b6804dfa25fe7a72814736dDevang Patel  if (pos != allModules.end()) {
111f2ca21f88f4e38996b6804dfa25fe7a72814736dDevang Patel    Module *m = allModules[InputFilename.c_str()];
112f2ca21f88f4e38996b6804dfa25fe7a72814736dDevang Patel    allModules.erase(pos);
113f2ca21f88f4e38996b6804dfa25fe7a72814736dDevang Patel    delete m;
114f2ca21f88f4e38996b6804dfa25fe7a72814736dDevang Patel  }
115f2ca21f88f4e38996b6804dfa25fe7a72814736dDevang Patel}
116f2ca21f88f4e38996b6804dfa25fe7a72814736dDevang Patel
1170701a2f70df66134ead84d4fe86b20b8f28c4fc3Devang Patel/// InputFilename is a LLVM bytecode file. If Module with InputFilename is
1180701a2f70df66134ead84d4fe86b20b8f28c4fc3Devang Patel/// available then return it. Otherwise parseInputFilename.
1190701a2f70df66134ead84d4fe86b20b8f28c4fc3Devang PatelModule *
120c7cfbc58ad88f127df6949791401969a09da560fDevang PatelLTO::getModule(const std::string &InputFilename)
1210701a2f70df66134ead84d4fe86b20b8f28c4fc3Devang Patel{
1220701a2f70df66134ead84d4fe86b20b8f28c4fc3Devang Patel  Module *m = NULL;
1230701a2f70df66134ead84d4fe86b20b8f28c4fc3Devang Patel
1240701a2f70df66134ead84d4fe86b20b8f28c4fc3Devang Patel  NameToModuleMap::iterator pos = allModules.find(InputFilename.c_str());
1250701a2f70df66134ead84d4fe86b20b8f28c4fc3Devang Patel  if (pos != allModules.end())
1260701a2f70df66134ead84d4fe86b20b8f28c4fc3Devang Patel    m = allModules[InputFilename.c_str()];
1270701a2f70df66134ead84d4fe86b20b8f28c4fc3Devang Patel  else {
1280701a2f70df66134ead84d4fe86b20b8f28c4fc3Devang Patel    m = ParseBytecodeFile(InputFilename);
1290701a2f70df66134ead84d4fe86b20b8f28c4fc3Devang Patel    allModules[InputFilename.c_str()] = m;
1300701a2f70df66134ead84d4fe86b20b8f28c4fc3Devang Patel  }
1310701a2f70df66134ead84d4fe86b20b8f28c4fc3Devang Patel  return m;
1320701a2f70df66134ead84d4fe86b20b8f28c4fc3Devang Patel}
1330701a2f70df66134ead84d4fe86b20b8f28c4fc3Devang Patel
134a291a68161bd37448404dc10c4815d4420cb2d30Devang Patel/// InputFilename is a LLVM bytecode file. Reade this bytecode file and
135a291a68161bd37448404dc10c4815d4420cb2d30Devang Patel/// set corresponding target triplet string.
136a291a68161bd37448404dc10c4815d4420cb2d30Devang Patelvoid
137c7cfbc58ad88f127df6949791401969a09da560fDevang PatelLTO::getTargetTriple(const std::string &InputFilename,
138a291a68161bd37448404dc10c4815d4420cb2d30Devang Patel				   std::string &targetTriple)
139a291a68161bd37448404dc10c4815d4420cb2d30Devang Patel{
140a291a68161bd37448404dc10c4815d4420cb2d30Devang Patel  Module *m = getModule(InputFilename);
141a291a68161bd37448404dc10c4815d4420cb2d30Devang Patel  if (m)
142a291a68161bd37448404dc10c4815d4420cb2d30Devang Patel    targetTriple = m->getTargetTriple();
143a291a68161bd37448404dc10c4815d4420cb2d30Devang Patel}
144a291a68161bd37448404dc10c4815d4420cb2d30Devang Patel
145a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel/// InputFilename is a LLVM bytecode file. Read it using bytecode reader.
146a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel/// Collect global functions and symbol names in symbols vector.
147a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel/// Collect external references in references vector.
148a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel/// Return LTO_READ_SUCCESS if there is no error.
149a89d47f54d1f83d328f6169151653bfc742607bfDevang Patelenum LTOStatus
150c7cfbc58ad88f127df6949791401969a09da560fDevang PatelLTO::readLLVMObjectFile(const std::string &InputFilename,
1512198f9cec47b4683377d4f4080acb14dd94fad65Devang Patel                                      NameToSymbolMap &symbols,
1522198f9cec47b4683377d4f4080acb14dd94fad65Devang Patel                                      std::set<std::string> &references)
153a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel{
1540701a2f70df66134ead84d4fe86b20b8f28c4fc3Devang Patel  Module *m = getModule(InputFilename);
155a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  if (!m)
156a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel    return LTO_READ_FAILURE;
15730235dad4b77ed83ca985030aff4fb4767551e5dDevang Patel
15830235dad4b77ed83ca985030aff4fb4767551e5dDevang Patel  // Use mangler to add GlobalPrefix to names to match linker names.
15930235dad4b77ed83ca985030aff4fb4767551e5dDevang Patel  // FIXME : Instead of hard coding "-" use GlobalPrefix.
16030235dad4b77ed83ca985030aff4fb4767551e5dDevang Patel  Mangler mangler(*m, "_");
161a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
162a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  modules.push_back(m);
163a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
164a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  for (Module::iterator f = m->begin(), e = m->end(); f != e; ++f) {
165a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
166a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel    LTOLinkageTypes lt = getLTOLinkageType(f);
167a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
168a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel    if (!f->isExternal() && lt != LTOInternalLinkage
1692198f9cec47b4683377d4f4080acb14dd94fad65Devang Patel        && strncmp (f->getName().c_str(), "llvm.", 5)) {
17030235dad4b77ed83ca985030aff4fb4767551e5dDevang Patel      LLVMSymbol *newSymbol = new LLVMSymbol(lt, f, f->getName(),
1712198f9cec47b4683377d4f4080acb14dd94fad65Devang Patel                                             mangler.getValueName(f));
17230235dad4b77ed83ca985030aff4fb4767551e5dDevang Patel      symbols[newSymbol->getMangledName()] = newSymbol;
17330235dad4b77ed83ca985030aff4fb4767551e5dDevang Patel      allSymbols[newSymbol->getMangledName()] = newSymbol;
174a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel    }
17530235dad4b77ed83ca985030aff4fb4767551e5dDevang Patel
176a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel    // Collect external symbols referenced by this function.
177a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel    for (Function::iterator b = f->begin(), fe = f->end(); b != fe; ++b)
178a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel      for (BasicBlock::iterator i = b->begin(), be = b->end();
1792198f9cec47b4683377d4f4080acb14dd94fad65Devang Patel           i != be; ++i)
1802198f9cec47b4683377d4f4080acb14dd94fad65Devang Patel        for (unsigned count = 0, total = i->getNumOperands();
1812198f9cec47b4683377d4f4080acb14dd94fad65Devang Patel             count != total; ++count)
1822198f9cec47b4683377d4f4080acb14dd94fad65Devang Patel          findExternalRefs(i->getOperand(count), references, mangler);
183a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  }
184a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
185a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  for (Module::global_iterator v = m->global_begin(), e = m->global_end();
186a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel       v !=  e; ++v) {
187a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel    LTOLinkageTypes lt = getLTOLinkageType(v);
188a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel    if (!v->isExternal() && lt != LTOInternalLinkage
1892198f9cec47b4683377d4f4080acb14dd94fad65Devang Patel        && strncmp (v->getName().c_str(), "llvm.", 5)) {
19030235dad4b77ed83ca985030aff4fb4767551e5dDevang Patel      LLVMSymbol *newSymbol = new LLVMSymbol(lt, v, v->getName(),
1912198f9cec47b4683377d4f4080acb14dd94fad65Devang Patel                                             mangler.getValueName(v));
19230235dad4b77ed83ca985030aff4fb4767551e5dDevang Patel      symbols[newSymbol->getMangledName()] = newSymbol;
193ed872865d0316ec754d93f703dd39f21745e45caDevang Patel      allSymbols[newSymbol->getMangledName()] = newSymbol;
194304d5f2edc954a3ef9904ea6d8f9421f40c9abe4Devang Patel
195304d5f2edc954a3ef9904ea6d8f9421f40c9abe4Devang Patel      for (unsigned count = 0, total = v->getNumOperands();
1962198f9cec47b4683377d4f4080acb14dd94fad65Devang Patel           count != total; ++count)
1972198f9cec47b4683377d4f4080acb14dd94fad65Devang Patel        findExternalRefs(v->getOperand(count), references, mangler);
198304d5f2edc954a3ef9904ea6d8f9421f40c9abe4Devang Patel
199a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel    }
200a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  }
201a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
202a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  return LTO_READ_SUCCESS;
203a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel}
204a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
205a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel/// Optimize module M using various IPO passes. Use exportList to
206a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel/// internalize selected symbols. Target platform is selected
207a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel/// based on information available to module M. No new target
208a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel/// features are selected.
209a89d47f54d1f83d328f6169151653bfc742607bfDevang Patelstatic enum LTOStatus lto_optimize(Module *M, std::ostream &Out,
2102198f9cec47b4683377d4f4080acb14dd94fad65Devang Patel                                   std::vector<const char *> &exportList)
211a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel{
212a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  // Instantiate the pass manager to organize the passes.
213a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  PassManager Passes;
214a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
215a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  // Collect Target info
216a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  std::string Err;
217a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  const TargetMachineRegistry::Entry* March =
218a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel    TargetMachineRegistry::getClosestStaticTargetForModule(*M, Err);
219a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
220a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  if (March == 0)
221a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel    return LTO_NO_TARGET;
222a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
223a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  // Create target
224a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  std::string Features;
225a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  std::auto_ptr<TargetMachine> target(March->CtorFn(*M, Features));
226a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  if (!target.get())
227a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel    return LTO_NO_TARGET;
228a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
229a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  TargetMachine &Target = *target.get();
230a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
231a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  // Start off with a verification pass.
232a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  Passes.add(createVerifierPass());
233a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
234a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  // Add an appropriate TargetData instance for this module...
235a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  Passes.add(new TargetData(*Target.getTargetData()));
236a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
237a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  // Often if the programmer does not specify proper prototypes for the
238a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  // functions they are calling, they end up calling a vararg version of the
239a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  // function that does not get a body filled in (the real function has typed
240a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  // arguments).  This pass merges the two functions.
241a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  Passes.add(createFunctionResolvingPass());
242a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
243a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  // Internalize symbols if export list is nonemty
244a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  if (!exportList.empty())
245a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel    Passes.add(createInternalizePass(exportList));
246a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
247a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  // Now that we internalized some globals, see if we can hack on them!
248a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  Passes.add(createGlobalOptimizerPass());
249a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
250a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  // Linking modules together can lead to duplicated global constants, only
251a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  // keep one copy of each constant...
252a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  Passes.add(createConstantMergePass());
253a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
254a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  // If the -s command line option was specified, strip the symbols out of the
255a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  // resulting program to make it smaller.  -s is a GLD option that we are
256a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  // supporting.
257a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  Passes.add(createStripSymbolsPass());
258a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
259a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  // Propagate constants at call sites into the functions they call.
260a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  Passes.add(createIPConstantPropagationPass());
261a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
262a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  // Remove unused arguments from functions...
263a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  Passes.add(createDeadArgEliminationPass());
264a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
265a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  Passes.add(createFunctionInliningPass()); // Inline small functions
266a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
267a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  Passes.add(createPruneEHPass());            // Remove dead EH info
268a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
269a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  Passes.add(createGlobalDCEPass());          // Remove dead functions
270a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
271a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  // If we didn't decide to inline a function, check to see if we can
272a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  // transform it to pass arguments by value instead of by reference.
273a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  Passes.add(createArgumentPromotionPass());
274a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
275a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  // The IPO passes may leave cruft around.  Clean up after them.
276a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  Passes.add(createInstructionCombiningPass());
277a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
278a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  Passes.add(createScalarReplAggregatesPass()); // Break up allocas
279a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
280a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  // Run a few AA driven optimizations here and now, to cleanup the code.
281a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  Passes.add(createGlobalsModRefPass());      // IP alias analysis
282a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
283a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  Passes.add(createLICMPass());               // Hoist loop invariants
284a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  Passes.add(createLoadValueNumberingPass()); // GVN for load instrs
285a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  Passes.add(createGCSEPass());               // Remove common subexprs
286a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  Passes.add(createDeadStoreEliminationPass()); // Nuke dead stores
287a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
288a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  // Cleanup and simplify the code after the scalar optimizations.
289a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  Passes.add(createInstructionCombiningPass());
290a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
291a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  // Delete basic blocks, which optimization passes may have killed...
292a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  Passes.add(createCFGSimplificationPass());
293a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
294a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  // Now that we have optimized the program, discard unreachable functions...
295a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  Passes.add(createGlobalDCEPass());
296a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
297a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  // Make sure everything is still good.
298a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  Passes.add(createVerifierPass());
299a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
300998051a2211a5f86b38941de0aca241b34895e1eDevang Patel  FunctionPassManager *CodeGenPasses =
301998051a2211a5f86b38941de0aca241b34895e1eDevang Patel    new FunctionPassManager(new ExistingModuleProvider(M));
302998051a2211a5f86b38941de0aca241b34895e1eDevang Patel
303998051a2211a5f86b38941de0aca241b34895e1eDevang Patel  CodeGenPasses->add(new TargetData(*Target.getTargetData()));
304998051a2211a5f86b38941de0aca241b34895e1eDevang Patel  Target.addPassesToEmitFile(*CodeGenPasses, Out, TargetMachine::AssemblyFile,
305998051a2211a5f86b38941de0aca241b34895e1eDevang Patel			     true);
306a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
307a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  // Run our queue of passes all at once now, efficiently.
308a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  Passes.run(*M);
309a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
310998051a2211a5f86b38941de0aca241b34895e1eDevang Patel  // Run the code generator, if present.
311998051a2211a5f86b38941de0aca241b34895e1eDevang Patel  CodeGenPasses->doInitialization();
312998051a2211a5f86b38941de0aca241b34895e1eDevang Patel  for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) {
313998051a2211a5f86b38941de0aca241b34895e1eDevang Patel    if (!I->isExternal())
314998051a2211a5f86b38941de0aca241b34895e1eDevang Patel      CodeGenPasses->run(*I);
315998051a2211a5f86b38941de0aca241b34895e1eDevang Patel  }
316998051a2211a5f86b38941de0aca241b34895e1eDevang Patel  CodeGenPasses->doFinalization();
317998051a2211a5f86b38941de0aca241b34895e1eDevang Patel
318a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  return LTO_OPT_SUCCESS;
319a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel}
320a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
321a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel///Link all modules together and optimize them using IPO. Generate
322a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel/// native object file using OutputFilename
323a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel/// Return appropriate LTOStatus.
324a89d47f54d1f83d328f6169151653bfc742607bfDevang Patelenum LTOStatus
325c7cfbc58ad88f127df6949791401969a09da560fDevang PatelLTO::optimizeModules(const std::string &OutputFilename,
3262681023488d70303ec788bc8a0a3f5336257830aDevang Patel                                   std::vector<const char *> &exportList,
3272681023488d70303ec788bc8a0a3f5336257830aDevang Patel                                   std::string &targetTriple)
328a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel{
329a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  if (modules.empty())
330a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel    return LTO_NO_WORK;
331a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
332a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  std::ios::openmode io_mode =
333a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel    std::ios::out | std::ios::trunc | std::ios::binary;
334a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  std::string *errMsg = NULL;
335a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  Module *bigOne = modules[0];
336a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  Linker theLinker("LinkTimeOptimizer", bigOne, false);
337a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  for (unsigned i = 1, e = modules.size(); i != e; ++i)
338a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel    if (theLinker.LinkModules(bigOne, modules[i], errMsg))
339a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel      return LTO_MODULE_MERGE_FAILURE;
340a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
341a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel#if 0
342a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  // Enable this when -save-temps is used
343a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  std::ofstream Out("big.bc", io_mode);
344a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  WriteBytecodeToFile(bigOne, Out, true);
345a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel#endif
346a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
347a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  // Strip leading underscore because it was added to match names
34894a0ac9bea7411bf98512b44b7e9bba42ee9a07fDevang Patel  // seen by linker.
349a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  for (unsigned i = 0, e = exportList.size(); i != e; ++i) {
350a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel    const char *name = exportList[i];
351ed872865d0316ec754d93f703dd39f21745e45caDevang Patel    NameToSymbolMap::iterator itr = allSymbols.find(name);
352ed872865d0316ec754d93f703dd39f21745e45caDevang Patel    if (itr != allSymbols.end())
353ed872865d0316ec754d93f703dd39f21745e45caDevang Patel      exportList[i] = allSymbols[name]->getName();
354a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  }
355a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
3563f0e5e205772af1529d980cb1fb2c910ef38417cDevang Patel
357e5c9cb5eb6bce502faaedea04014dab46f6540f4Reid Spencer  std::string ErrMsg;
3583f0e5e205772af1529d980cb1fb2c910ef38417cDevang Patel  sys::Path TempDir = sys::Path::GetTemporaryDirectory(&ErrMsg);
3599f5d48bcb1c6e72363567089242960bfde5171bbDevang Patel  if (TempDir.isEmpty()) {
3609f5d48bcb1c6e72363567089242960bfde5171bbDevang Patel    std::cerr << "lto: " << ErrMsg << "\n";
3619f5d48bcb1c6e72363567089242960bfde5171bbDevang Patel    return LTO_WRITE_FAILURE;
3629f5d48bcb1c6e72363567089242960bfde5171bbDevang Patel  }
3633f0e5e205772af1529d980cb1fb2c910ef38417cDevang Patel  sys::Path tmpAsmFilePath(TempDir);
3643f0e5e205772af1529d980cb1fb2c910ef38417cDevang Patel  if (!tmpAsmFilePath.appendComponent("lto")) {
3653f0e5e205772af1529d980cb1fb2c910ef38417cDevang Patel    std::cerr << "lto: " << ErrMsg << "\n";
3663f0e5e205772af1529d980cb1fb2c910ef38417cDevang Patel    TempDir.eraseFromDisk(true);
3673f0e5e205772af1529d980cb1fb2c910ef38417cDevang Patel    return LTO_WRITE_FAILURE;
3683f0e5e205772af1529d980cb1fb2c910ef38417cDevang Patel  }
369e5c9cb5eb6bce502faaedea04014dab46f6540f4Reid Spencer  if (tmpAsmFilePath.createTemporaryFileOnDisk(&ErrMsg)) {
370e5c9cb5eb6bce502faaedea04014dab46f6540f4Reid Spencer    std::cerr << "lto: " << ErrMsg << "\n";
3713f0e5e205772af1529d980cb1fb2c910ef38417cDevang Patel    TempDir.eraseFromDisk(true);
372ca64012ac6b21d868ccf2fcc26febd991ef2cc9cDevang Patel    return LTO_WRITE_FAILURE;
373e5c9cb5eb6bce502faaedea04014dab46f6540f4Reid Spencer  }
374a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  sys::RemoveFileOnSignal(tmpAsmFilePath);
375a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
376a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  std::ofstream asmFile(tmpAsmFilePath.c_str(), io_mode);
377a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  if (!asmFile.is_open() || asmFile.bad()) {
3783f0e5e205772af1529d980cb1fb2c910ef38417cDevang Patel    if (tmpAsmFilePath.exists()) {
379a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel      tmpAsmFilePath.eraseFromDisk();
3803f0e5e205772af1529d980cb1fb2c910ef38417cDevang Patel      TempDir.eraseFromDisk(true);
3813f0e5e205772af1529d980cb1fb2c910ef38417cDevang Patel    }
382a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel    return LTO_WRITE_FAILURE;
383a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  }
384a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
385a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  enum LTOStatus status = lto_optimize(bigOne, asmFile, exportList);
386a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  asmFile.close();
387a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  if (status != LTO_OPT_SUCCESS) {
388a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel    tmpAsmFilePath.eraseFromDisk();
3893f0e5e205772af1529d980cb1fb2c910ef38417cDevang Patel    TempDir.eraseFromDisk(true);
390a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel    return status;
391a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  }
392a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
3932681023488d70303ec788bc8a0a3f5336257830aDevang Patel  targetTriple = bigOne->getTargetTriple();
3942681023488d70303ec788bc8a0a3f5336257830aDevang Patel
395a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  // Run GCC to assemble and link the program into native code.
396a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  //
397a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  // Note:
398a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  //  We can't just assemble and link the file with the system assembler
399a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  //  and linker because we don't know where to put the _start symbol.
400a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  //  GCC mysteriously knows how to do it.
401dc4c38279f6bf3b001515e6723e7b6d79ed378b0Devang Patel  const sys::Path gcc = sys::Program::FindProgramByName("gcc");
402a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  if (gcc.isEmpty()) {
403a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel    tmpAsmFilePath.eraseFromDisk();
4043f0e5e205772af1529d980cb1fb2c910ef38417cDevang Patel    TempDir.eraseFromDisk(true);
405a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel    return LTO_ASM_FAILURE;
406a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  }
407a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
408a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  std::vector<const char*> args;
409a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  args.push_back(gcc.c_str());
410a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  args.push_back("-c");
411a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  args.push_back("-x");
412a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  args.push_back("assembler");
413a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  args.push_back("-o");
414a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  args.push_back(OutputFilename.c_str());
415a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  args.push_back(tmpAsmFilePath.c_str());
416a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  args.push_back(0);
417a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
4189f5d48bcb1c6e72363567089242960bfde5171bbDevang Patel  if (sys::Program::ExecuteAndWait(gcc, &args[0], 0, 0, 1, &ErrMsg)) {
4199f5d48bcb1c6e72363567089242960bfde5171bbDevang Patel    std::cerr << "lto: " << ErrMsg << "\n";
4209f5d48bcb1c6e72363567089242960bfde5171bbDevang Patel    return LTO_ASM_FAILURE;
4219f5d48bcb1c6e72363567089242960bfde5171bbDevang Patel  }
422a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
423a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  tmpAsmFilePath.eraseFromDisk();
4243f0e5e205772af1529d980cb1fb2c910ef38417cDevang Patel  TempDir.eraseFromDisk(true);
425a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel
426a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel  return LTO_OPT_SUCCESS;
427a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel}
428