lto.cpp revision 59c8d8ae892f8c9e7ab4054d6be3efd0b66a7e4f
130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng//===-lto.cpp - LLVM Link Time Optimizer ----------------------------------===//
230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng//
330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng//                     The LLVM Compiler Infrastructure
430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng//
530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng// This file is distributed under the University of Illinois Open Source
630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng// License. See LICENSE.TXT for details.
730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng//
830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng//===----------------------------------------------------------------------===//
930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng//
1030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng// This file implements the Link Time Optimization library. This library is
1130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng// intended to be used by linker to optimize code at link time.
1230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng//
1330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng//===----------------------------------------------------------------------===//
1430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
1530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include "llvm/Module.h"
1630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include "llvm/PassManager.h"
1730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include "llvm/Linker.h"
1830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include "llvm/Constants.h"
1930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include "llvm/DerivedTypes.h"
2030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include "llvm/ModuleProvider.h"
2130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include "llvm/Bitcode/ReaderWriter.h"
2230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include "llvm/Support/CommandLine.h"
2330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include "llvm/Support/FileUtilities.h"
2430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include "llvm/Support/SystemUtils.h"
2530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include "llvm/Support/Mangler.h"
2630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include "llvm/Support/MemoryBuffer.h"
2730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include "llvm/System/Program.h"
2830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include "llvm/System/Signals.h"
2930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include "llvm/Analysis/Passes.h"
3030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include "llvm/Analysis/LoopPass.h"
3130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include "llvm/Analysis/Verifier.h"
3230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include "llvm/CodeGen/FileWriters.h"
3330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include "llvm/Target/SubtargetFeature.h"
3430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include "llvm/Target/TargetOptions.h"
3530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include "llvm/Target/TargetData.h"
3630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include "llvm/Target/TargetMachine.h"
3730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include "llvm/Target/TargetMachineRegistry.h"
3830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include "llvm/Target/TargetAsmInfo.h"
3930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include "llvm/Transforms/IPO.h"
4030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include "llvm/Transforms/Scalar.h"
4130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include "llvm/Analysis/LoadValueNumbering.h"
4230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include "llvm/Support/MathExtras.h"
4330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include "llvm/LinkTimeOptimizer.h"
4430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include <fstream>
4530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng#include <ostream>
4630692c65c4174412c90e79489e98ab85c1a7412fBen Chengusing namespace llvm;
4730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
4830692c65c4174412c90e79489e98ab85c1a7412fBen Chengextern "C"
4930692c65c4174412c90e79489e98ab85c1a7412fBen Chengllvm::LinkTimeOptimizer *createLLVMOptimizer(unsigned VERSION)
5030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng{
5130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  // Linker records LLVM_LTO_VERSION based on llvm optimizer available
5230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  // during linker build. Match linker's recorded LTO VERSION number
5330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  // with installed llvm optimizer version. If these numbers do not match
5430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  // then linker may not be able to use llvm optimizer dynamically.
5530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  if (VERSION != LLVM_LTO_VERSION)
5630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    return NULL;
5730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
5830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  llvm::LTO *l = new llvm::LTO();
5930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  return l;
6030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng}
6130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
6230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng/// If symbol is not used then make it internal and let optimizer takes
6330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng/// care of it.
6430692c65c4174412c90e79489e98ab85c1a7412fBen Chengvoid LLVMSymbol::mayBeNotUsed() {
6530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  gv->setLinkage(GlobalValue::InternalLinkage);
6630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng}
6730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
6830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng// Map LLVM LinkageType to LTO LinakgeType
6930692c65c4174412c90e79489e98ab85c1a7412fBen Chengstatic LTOLinkageTypes
7030692c65c4174412c90e79489e98ab85c1a7412fBen ChenggetLTOLinkageType(GlobalValue *v)
7130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng{
7230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  LTOLinkageTypes lt;
7330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  if (v->hasExternalLinkage())
7430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    lt = LTOExternalLinkage;
7530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  else if (v->hasLinkOnceLinkage())
7630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    lt = LTOLinkOnceLinkage;
7730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  else if (v->hasWeakLinkage())
7830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    lt = LTOWeakLinkage;
7930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  else
8030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    // Otherwise it is internal linkage for link time optimizer
8130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    lt = LTOInternalLinkage;
8230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  return lt;
8330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng}
8430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
8530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng// MAP LLVM VisibilityType to LTO VisibilityType
8630692c65c4174412c90e79489e98ab85c1a7412fBen Chengstatic LTOVisibilityTypes
8730692c65c4174412c90e79489e98ab85c1a7412fBen ChenggetLTOVisibilityType(GlobalValue *v)
8830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng{
8930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  LTOVisibilityTypes vis;
9030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  if (v->hasHiddenVisibility())
9130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    vis = LTOHiddenVisibility;
9230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  else if (v->hasProtectedVisibility())
9330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    vis = LTOProtectedVisibility;
9430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  else
9530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    vis = LTODefaultVisibility;
9630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  return vis;
9730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng}
9830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
9930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng// Find exeternal symbols referenced by VALUE. This is a recursive function.
10030692c65c4174412c90e79489e98ab85c1a7412fBen Chengstatic void
10130692c65c4174412c90e79489e98ab85c1a7412fBen ChengfindExternalRefs(Value *value, std::set<std::string> &references,
10230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng                 Mangler &mangler) {
10330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
10430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  if (GlobalValue *gv = dyn_cast<GlobalValue>(value)) {
10530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    LTOLinkageTypes lt = getLTOLinkageType(gv);
10630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    if (lt != LTOInternalLinkage && strncmp (gv->getName().c_str(), "llvm.", 5))
10730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng      references.insert(mangler.getValueName(gv));
10830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  }
10930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
11030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  // GlobalValue, even with InternalLinkage type, may have operands with
11130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  // ExternalLinkage type. Do not ignore these operands.
11230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  if (Constant *c = dyn_cast<Constant>(value))
11330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    // Handle ConstantExpr, ConstantStruct, ConstantArry etc..
11430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    for (unsigned i = 0, e = c->getNumOperands(); i != e; ++i)
11530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng      findExternalRefs(c->getOperand(i), references, mangler);
11630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng}
11730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
11830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng/// If Module with InputFilename is available then remove it from allModules
11930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng/// and call delete on it.
12030692c65c4174412c90e79489e98ab85c1a7412fBen Chengvoid
12130692c65c4174412c90e79489e98ab85c1a7412fBen ChengLTO::removeModule (const std::string &InputFilename)
12230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng{
12330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  NameToModuleMap::iterator pos = allModules.find(InputFilename.c_str());
12430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  if (pos == allModules.end())
12530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    return;
12630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
12730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  Module *m = pos->second;
12830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  allModules.erase(pos);
12930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  delete m;
13030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng}
13130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
13230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng/// InputFilename is a LLVM bitcode file. If Module with InputFilename is
13330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng/// available then return it. Otherwise parseInputFilename.
13430692c65c4174412c90e79489e98ab85c1a7412fBen ChengModule *
13530692c65c4174412c90e79489e98ab85c1a7412fBen ChengLTO::getModule(const std::string &InputFilename)
13630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng{
13730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  Module *m = NULL;
13830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
13930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  NameToModuleMap::iterator pos = allModules.find(InputFilename.c_str());
14030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  if (pos != allModules.end())
14130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    m = allModules[InputFilename.c_str()];
14230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  else {
14330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    if (MemoryBuffer *Buffer
14430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng        = MemoryBuffer::getFile(&InputFilename[0], InputFilename.size())) {
14530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng      m = ParseBitcodeFile(Buffer);
14630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng      delete Buffer;
14730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    }
14830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    allModules[InputFilename.c_str()] = m;
14930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  }
15030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  return m;
15130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng}
15230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
15330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng/// InputFilename is a LLVM bitcode file. Reade this bitcode file and
15430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng/// set corresponding target triplet string.
15530692c65c4174412c90e79489e98ab85c1a7412fBen Chengvoid
15630692c65c4174412c90e79489e98ab85c1a7412fBen ChengLTO::getTargetTriple(const std::string &InputFilename,
15730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng                     std::string &targetTriple)
15830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng{
15930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  Module *m = getModule(InputFilename);
16030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  if (m)
16130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    targetTriple = m->getTargetTriple();
16230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng}
16330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
16430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng/// InputFilename is a LLVM bitcode file. Read it using bitcode reader.
16530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng/// Collect global functions and symbol names in symbols vector.
16630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng/// Collect external references in references vector.
16730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng/// Return LTO_READ_SUCCESS if there is no error.
16830692c65c4174412c90e79489e98ab85c1a7412fBen Chengenum LTOStatus
16930692c65c4174412c90e79489e98ab85c1a7412fBen ChengLTO::readLLVMObjectFile(const std::string &InputFilename,
17030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng                        NameToSymbolMap &symbols,
17130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng                        std::set<std::string> &references)
17230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng{
17330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  Module *m = getModule(InputFilename);
17430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  if (!m)
17530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    return LTO_READ_FAILURE;
17630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
17730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  // Collect Target info
17830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  getTarget(m);
17930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
18030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  if (!Target)
18130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    return LTO_READ_FAILURE;
18230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
18330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  // Use mangler to add GlobalPrefix to names to match linker names.
18430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  // FIXME : Instead of hard coding "-" use GlobalPrefix.
18530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  Mangler mangler(*m, Target->getTargetAsmInfo()->getGlobalPrefix());
18630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  modules.push_back(m);
18730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
18830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  for (Module::iterator f = m->begin(), e = m->end(); f != e; ++f) {
18930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    LTOLinkageTypes lt = getLTOLinkageType(f);
19030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    LTOVisibilityTypes vis = getLTOVisibilityType(f);
19130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    if (!f->isDeclaration() && lt != LTOInternalLinkage
19230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng        && strncmp (f->getName().c_str(), "llvm.", 5)) {
19330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng      int alignment = ( 16 > f->getAlignment() ? 16 : f->getAlignment());
19430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng      LLVMSymbol *newSymbol = new LLVMSymbol(lt, vis, f, f->getName(),
19530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng                                             mangler.getValueName(f),
19630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng                                             Log2_32(alignment));
19730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng      symbols[newSymbol->getMangledName()] = newSymbol;
19830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng      allSymbols[newSymbol->getMangledName()] = newSymbol;
19930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    }
20030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
20130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    // Collect external symbols referenced by this function.
20230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    for (Function::iterator b = f->begin(), fe = f->end(); b != fe; ++b)
20330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng      for (BasicBlock::iterator i = b->begin(), be = b->end();
20430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng           i != be; ++i) {
20530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng        for (unsigned count = 0, total = i->getNumOperands();
20630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng             count != total; ++count)
20730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng          findExternalRefs(i->getOperand(count), references, mangler);
20830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng      }
20930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  }
21030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
21130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  for (Module::global_iterator v = m->global_begin(), e = m->global_end();
21230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng       v !=  e; ++v) {
21330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    LTOLinkageTypes lt = getLTOLinkageType(v);
21430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    LTOVisibilityTypes vis = getLTOVisibilityType(v);
21530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    if (!v->isDeclaration() && lt != LTOInternalLinkage
21630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng        && strncmp (v->getName().c_str(), "llvm.", 5)) {
21730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng      const TargetData *TD = Target->getTargetData();
21830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng      LLVMSymbol *newSymbol = new LLVMSymbol(lt, vis, v, v->getName(),
21930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng                                             mangler.getValueName(v),
22030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng                                             TD->getPreferredAlignmentLog(v));
22130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng      symbols[newSymbol->getMangledName()] = newSymbol;
22230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng      allSymbols[newSymbol->getMangledName()] = newSymbol;
22330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
22430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng      for (unsigned count = 0, total = v->getNumOperands();
22530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng           count != total; ++count)
22630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng        findExternalRefs(v->getOperand(count), references, mangler);
22730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
22830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    }
22930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  }
23030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
23130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  return LTO_READ_SUCCESS;
23230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng}
23330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
23430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng/// Get TargetMachine.
23530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng/// Use module M to find appropriate Target.
23630692c65c4174412c90e79489e98ab85c1a7412fBen Chengvoid
23730692c65c4174412c90e79489e98ab85c1a7412fBen ChengLTO::getTarget (Module *M) {
23830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
23930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  if (Target)
24030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    return;
24130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
24230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  std::string Err;
24330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  const TargetMachineRegistry::entry* March =
24430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    TargetMachineRegistry::getClosestStaticTargetForModule(*M, Err);
24530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
24630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  if (March == 0)
24730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    return;
24830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
24930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  // Create target
25030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  std::string Features;
25130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  Target = March->CtorFn(*M, Features);
25230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng}
25330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
25430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng/// Optimize module M using various IPO passes. Use exportList to
25530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng/// internalize selected symbols. Target platform is selected
25630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng/// based on information available to module M. No new target
25730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng/// features are selected.
25830692c65c4174412c90e79489e98ab85c1a7412fBen Chengenum LTOStatus
25930692c65c4174412c90e79489e98ab85c1a7412fBen ChengLTO::optimize(Module *M, std::ostream &Out,
26030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng              std::vector<const char *> &exportList)
26130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng{
26230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  // Instantiate the pass manager to organize the passes.
26330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  PassManager Passes;
26430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
26530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  // Collect Target info
26630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  getTarget(M);
26730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
26830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  if (!Target)
26930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    return LTO_NO_TARGET;
27030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
27130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  // If target supports exception handling then enable it now.
27230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  if (Target->getTargetAsmInfo()->doesSupportExceptionHandling())
27330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    ExceptionHandling = true;
27430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
27530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  // Start off with a verification pass.
27630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  Passes.add(createVerifierPass());
27730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
27830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  // Add an appropriate TargetData instance for this module...
27930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  Passes.add(new TargetData(*Target->getTargetData()));
28030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
28130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  // Internalize symbols if export list is nonemty
28230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  if (!exportList.empty())
28330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    Passes.add(createInternalizePass(exportList));
28430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
28530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  // Now that we internalized some globals, see if we can hack on them!
28630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  Passes.add(createGlobalOptimizerPass());
28730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
28830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  // Linking modules together can lead to duplicated global constants, only
28930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  // keep one copy of each constant...
29030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  Passes.add(createConstantMergePass());
29130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
29230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  // If the -s command line option was specified, strip the symbols out of the
29330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  // resulting program to make it smaller.  -s is a GLD option that we are
29430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  // supporting.
29530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  Passes.add(createStripSymbolsPass());
29630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
29730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  // Propagate constants at call sites into the functions they call.
29830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  Passes.add(createIPConstantPropagationPass());
29930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
30030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  // Remove unused arguments from functions...
30130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  Passes.add(createDeadArgEliminationPass());
30230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
30330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  Passes.add(createFunctionInliningPass()); // Inline small functions
30430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
30530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  Passes.add(createPruneEHPass());            // Remove dead EH info
30630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
30730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  Passes.add(createGlobalDCEPass());          // Remove dead functions
30830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
30930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  // If we didn't decide to inline a function, check to see if we can
31030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  // transform it to pass arguments by value instead of by reference.
31130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  Passes.add(createArgumentPromotionPass());
31230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
31330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  // The IPO passes may leave cruft around.  Clean up after them.
31430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  Passes.add(createInstructionCombiningPass());
31530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
31630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  Passes.add(createScalarReplAggregatesPass()); // Break up allocas
31730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
31830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  // Run a few AA driven optimizations here and now, to cleanup the code.
31930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  Passes.add(createGlobalsModRefPass());      // IP alias analysis
32030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
32130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  Passes.add(createLICMPass());               // Hoist loop invariants
32230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  Passes.add(createLoadValueNumberingPass()); // GVN for load instrs
32330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  Passes.add(createGCSEPass());               // Remove common subexprs
32430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  Passes.add(createDeadStoreEliminationPass()); // Nuke dead stores
32530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
32630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  // Cleanup and simplify the code after the scalar optimizations.
32730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  Passes.add(createInstructionCombiningPass());
32830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
32930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  // Delete basic blocks, which optimization passes may have killed...
33030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  Passes.add(createCFGSimplificationPass());
33130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
33230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  // Now that we have optimized the program, discard unreachable functions...
33330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  Passes.add(createGlobalDCEPass());
33430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
33530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  // Make sure everything is still good.
33630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  Passes.add(createVerifierPass());
33730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
33830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  FunctionPassManager *CodeGenPasses =
33930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    new FunctionPassManager(new ExistingModuleProvider(M));
34030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
34130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  CodeGenPasses->add(new TargetData(*Target->getTargetData()));
34230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
34330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  MachineCodeEmitter *MCE = 0;
34430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
34530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  switch (Target->addPassesToEmitFile(*CodeGenPasses, Out,
34630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng                                      TargetMachine::AssemblyFile, true)) {
34730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  default:
34830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  case FileModel::Error:
34930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    return LTO_WRITE_FAILURE;
35030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  case FileModel::AsmFile:
35130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    break;
35230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  case FileModel::MachOFile:
35330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    MCE = AddMachOWriter(*CodeGenPasses, Out, *Target);
35430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    break;
35530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  case FileModel::ElfFile:
35630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    MCE = AddELFWriter(*CodeGenPasses, Out, *Target);
35730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    break;
35830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  }
35930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
36030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  if (Target->addPassesToEmitFileFinish(*CodeGenPasses, MCE, true))
36130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    return LTO_WRITE_FAILURE;
36230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
36330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  // Run our queue of passes all at once now, efficiently.
36430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  Passes.run(*M);
36530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
36630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  // Run the code generator, if present.
36730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  CodeGenPasses->doInitialization();
36830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) {
36930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    if (!I->isDeclaration())
37030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng      CodeGenPasses->run(*I);
37130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  }
37230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  CodeGenPasses->doFinalization();
37330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
37430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  return LTO_OPT_SUCCESS;
37530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng}
37630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
37730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng///Link all modules together and optimize them using IPO. Generate
37830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng/// native object file using OutputFilename
37930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng/// Return appropriate LTOStatus.
38030692c65c4174412c90e79489e98ab85c1a7412fBen Chengenum LTOStatus
38130692c65c4174412c90e79489e98ab85c1a7412fBen ChengLTO::optimizeModules(const std::string &OutputFilename,
38230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng                     std::vector<const char *> &exportList,
38330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng                     std::string &targetTriple,
38430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng                     bool saveTemps, const char *FinalOutputFilename)
38530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng{
38630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  if (modules.empty())
38730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    return LTO_NO_WORK;
38830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
38930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  std::ios::openmode io_mode =
39030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    std::ios::out | std::ios::trunc | std::ios::binary;
39130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  std::string *errMsg = NULL;
39230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  Module *bigOne = modules[0];
39330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  Linker theLinker("LinkTimeOptimizer", bigOne, false);
39430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  for (unsigned i = 1, e = modules.size(); i != e; ++i)
39530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    if (theLinker.LinkModules(bigOne, modules[i], errMsg))
39630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng      return LTO_MODULE_MERGE_FAILURE;
39730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  //  all modules have been handed off to the linker.
39830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  modules.clear();
39930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
40030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  sys::Path FinalOutputPath(FinalOutputFilename);
40130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  FinalOutputPath.eraseSuffix();
40230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
40330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  switch(CGModel) {
40430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  case LTO_CGM_Dynamic:
40530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    Target->setRelocationModel(Reloc::PIC_);
40630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    break;
40730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  case LTO_CGM_DynamicNoPIC:
40830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    Target->setRelocationModel(Reloc::DynamicNoPIC);
40930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    break;
41030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  case LTO_CGM_Static:
41130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    Target->setRelocationModel(Reloc::Static);
41230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    break;
41330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  }
41430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
41530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  if (saveTemps) {
41630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    std::string tempFileName(FinalOutputPath.c_str());
41730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    tempFileName += "0.bc";
41830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    std::ofstream Out(tempFileName.c_str(), io_mode);
41930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    WriteBitcodeToFile(bigOne, Out);
42030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  }
42130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
42230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  // Strip leading underscore because it was added to match names
42330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  // seen by linker.
42430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  for (unsigned i = 0, e = exportList.size(); i != e; ++i) {
42530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    const char *name = exportList[i];
42630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    NameToSymbolMap::iterator itr = allSymbols.find(name);
42730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    if (itr != allSymbols.end())
42830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng      exportList[i] = allSymbols[name]->getName();
42930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  }
43030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
43130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
43230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  std::string ErrMsg;
43330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  sys::Path TempDir = sys::Path::GetTemporaryDirectory(&ErrMsg);
43430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  if (TempDir.isEmpty()) {
43530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    cerr << "lto: " << ErrMsg << "\n";
43630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    return LTO_WRITE_FAILURE;
43730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  }
43830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  sys::Path tmpAsmFilePath(TempDir);
43930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  if (!tmpAsmFilePath.appendComponent("lto")) {
44030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    cerr << "lto: " << ErrMsg << "\n";
44130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    TempDir.eraseFromDisk(true);
44230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    return LTO_WRITE_FAILURE;
44330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  }
44430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  if (tmpAsmFilePath.createTemporaryFileOnDisk(true, &ErrMsg)) {
44530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    cerr << "lto: " << ErrMsg << "\n";
44630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    TempDir.eraseFromDisk(true);
44730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    return LTO_WRITE_FAILURE;
44830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  }
44930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  sys::RemoveFileOnSignal(tmpAsmFilePath);
45030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
45130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  std::ofstream asmFile(tmpAsmFilePath.c_str(), io_mode);
45230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  if (!asmFile.is_open() || asmFile.bad()) {
45330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    if (tmpAsmFilePath.exists()) {
45430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng      tmpAsmFilePath.eraseFromDisk();
45530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng      TempDir.eraseFromDisk(true);
45630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    }
45730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    return LTO_WRITE_FAILURE;
45830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  }
45930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
46030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  enum LTOStatus status = optimize(bigOne, asmFile, exportList);
46130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  asmFile.close();
46230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  if (status != LTO_OPT_SUCCESS) {
46330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    tmpAsmFilePath.eraseFromDisk();
46430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    TempDir.eraseFromDisk(true);
46530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    return status;
46630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  }
46730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
46830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  if (saveTemps) {
46930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    std::string tempFileName(FinalOutputPath.c_str());
47030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    tempFileName += "1.bc";
47130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    std::ofstream Out(tempFileName.c_str(), io_mode);
47230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    WriteBitcodeToFile(bigOne, Out);
47330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  }
47430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
47530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  targetTriple = bigOne->getTargetTriple();
47630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
47730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  // Run GCC to assemble and link the program into native code.
47830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  //
47930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  // Note:
48030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  //  We can't just assemble and link the file with the system assembler
48130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  //  and linker because we don't know where to put the _start symbol.
48230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  //  GCC mysteriously knows how to do it.
48330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  const sys::Path gcc = sys::Program::FindProgramByName("gcc");
48430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  if (gcc.isEmpty()) {
48530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    tmpAsmFilePath.eraseFromDisk();
48630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    TempDir.eraseFromDisk(true);
48730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    return LTO_ASM_FAILURE;
48830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  }
48930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng
49030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  std::vector<const char*> args;
49130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  args.push_back(gcc.c_str());
49230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  if (strncmp(targetTriple.c_str(), "i686-apple-", 11) == 0) {
49330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    args.push_back("-arch");
49430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    args.push_back("i386");
49530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  }
49630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  if (strncmp(targetTriple.c_str(), "x86_64-apple-", 13) == 0) {
49730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    args.push_back("-arch");
49830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    args.push_back("x86_64");
49930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  }
50030692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  if (strncmp(targetTriple.c_str(), "powerpc-apple-", 14) == 0) {
50130692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    args.push_back("-arch");
50230692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    args.push_back("ppc");
50330692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  }
50430692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  if (strncmp(targetTriple.c_str(), "powerpc64-apple-", 16) == 0) {
50530692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    args.push_back("-arch");
50630692c65c4174412c90e79489e98ab85c1a7412fBen Cheng    args.push_back("ppc64");
50730692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  }
50830692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  args.push_back("-c");
50930692c65c4174412c90e79489e98ab85c1a7412fBen Cheng  args.push_back("-x");
510  args.push_back("assembler");
511  args.push_back("-o");
512  args.push_back(OutputFilename.c_str());
513  args.push_back(tmpAsmFilePath.c_str());
514  args.push_back(0);
515
516  if (sys::Program::ExecuteAndWait(gcc, &args[0], 0, 0, 1, 0, &ErrMsg)) {
517    cerr << "lto: " << ErrMsg << "\n";
518    return LTO_ASM_FAILURE;
519  }
520
521  tmpAsmFilePath.eraseFromDisk();
522  TempDir.eraseFromDisk(true);
523
524  return LTO_OPT_SUCCESS;
525}
526
527void LTO::printVersion() {
528    cl::PrintVersionMessage();
529}
530
531/// Unused pure-virtual destructor. Must remain empty.
532LinkTimeOptimizer::~LinkTimeOptimizer() {}
533
534/// Destruct LTO. Delete all modules, symbols and target.
535LTO::~LTO() {
536
537  for (std::vector<Module *>::iterator itr = modules.begin(), e = modules.end();
538       itr != e; ++itr)
539    delete *itr;
540
541  modules.clear();
542
543  for (NameToSymbolMap::iterator itr = allSymbols.begin(), e = allSymbols.end();
544       itr != e; ++itr)
545    delete itr->second;
546
547  allSymbols.clear();
548
549  delete Target;
550}
551