lto.cpp revision 94a0ac9bea7411bf98512b44b7e9bba42ee9a07f
11176bdada62cabc6ec4b0308a930e83b679d5d36John Reck//===-lto.cpp - LLVM Link Time Optimizer ----------------------------------===//
21176bdada62cabc6ec4b0308a930e83b679d5d36John Reck//
31176bdada62cabc6ec4b0308a930e83b679d5d36John Reck//                     The LLVM Compiler Infrastructure
41176bdada62cabc6ec4b0308a930e83b679d5d36John Reck//
51176bdada62cabc6ec4b0308a930e83b679d5d36John Reck// This file was developed by Devang Patel and is distributed under
61176bdada62cabc6ec4b0308a930e83b679d5d36John Reck// the University of Illinois Open Source License. See LICENSE.TXT for details.
71176bdada62cabc6ec4b0308a930e83b679d5d36John Reck//
81176bdada62cabc6ec4b0308a930e83b679d5d36John Reck//===----------------------------------------------------------------------===//
91176bdada62cabc6ec4b0308a930e83b679d5d36John Reck//
101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck// This file implementes link time optimization library. This library is
111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck// intended to be used by linker to optimize code at link time.
121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck//
131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck//===----------------------------------------------------------------------===//
141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include "llvm/Module.h"
161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include "llvm/PassManager.h"
171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include "llvm/Linker.h"
181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include "llvm/Constants.h"
191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include "llvm/DerivedTypes.h"
201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include "llvm/SymbolTable.h"
211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include "llvm/Bytecode/Reader.h"
221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include "llvm/Bytecode/Writer.h"
231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include "llvm/Support/CommandLine.h"
241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include "llvm/Support/FileUtilities.h"
251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include "llvm/Support/SystemUtils.h"
261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include "llvm/System/Program.h"
271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include "llvm/System/Signals.h"
281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include "llvm/Analysis/Passes.h"
291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include "llvm/Analysis/Verifier.h"
301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include "llvm/Target/SubtargetFeature.h"
311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include "llvm/Target/TargetData.h"
321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include "llvm/Target/TargetMachine.h"
331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include "llvm/Target/TargetMachineRegistry.h"
341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include "llvm/Transforms/IPO.h"
351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include "llvm/Transforms/Scalar.h"
361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include "llvm/Analysis/LoadValueNumbering.h"
371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include "llvm/LinkTimeOptimizer.h"
381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include <fstream>
391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#include <iostream>
401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
411176bdada62cabc6ec4b0308a930e83b679d5d36John Reckusing namespace llvm;
421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
431176bdada62cabc6ec4b0308a930e83b679d5d36John Reckextern "C"
441176bdada62cabc6ec4b0308a930e83b679d5d36John Reckllvm::LinkTimeOptimizer *createLLVMOptimizer()
451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  llvm::LinkTimeOptimizer *l = new llvm::LinkTimeOptimizer();
471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  return l;
481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck/// If symbol is not used then make it internal and let optimizer takes
531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck/// care of it.
541176bdada62cabc6ec4b0308a930e83b679d5d36John Reckvoid LLVMSymbol::mayBeNotUsed() {
551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  gv->setLinkage(GlobalValue::InternalLinkage);
561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck// Helper routine
591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck// FIXME : Take advantage of GlobalPrefix from AsmPrinter
601176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic const char *addUnderscore(const char *name) {
611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  size_t namelen = strlen(name);
621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  char *symName = (char*)malloc(namelen+2);
631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  symName[0] = '_';
641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  strcpy(&symName[1], name);
651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  return symName;
661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck// Map LLVM LinkageType to LTO LinakgeType
691176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic LTOLinkageTypes
701176bdada62cabc6ec4b0308a930e83b679d5d36John ReckgetLTOLinkageType(GlobalValue *v)
711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  LTOLinkageTypes lt;
731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  if (v->hasExternalLinkage())
741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    lt = LTOExternalLinkage;
751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  else if (v->hasLinkOnceLinkage())
761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    lt = LTOLinkOnceLinkage;
771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  else if (v->hasWeakLinkage())
781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    lt = LTOWeakLinkage;
791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  else
801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    // Otherwise it is internal linkage for link time optimizer
811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    lt = LTOInternalLinkage;
821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  return lt;
831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck// Find exeternal symbols referenced by VALUE. This is a recursive function.
861176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic void
871176bdada62cabc6ec4b0308a930e83b679d5d36John ReckfindExternalRefs(Value *value, std::set<const char *> &references) {
881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  if (ConstantExpr *ce = dyn_cast<ConstantExpr>(value))
901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    for (unsigned i = 0, e = ce->getNumOperands(); i != e; ++i)
911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck      findExternalRefs(ce->getOperand(i), references);
921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  else if (GlobalValue *gv = dyn_cast<GlobalValue>(value)) {
931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    LTOLinkageTypes lt = getLTOLinkageType(gv);
941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (lt != LTOInternalLinkage && strncmp (gv->getName().c_str(), "llvm.", 5))
951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck      references.insert(addUnderscore(gv->getName().c_str()));
961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  }
971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck/// InputFilename is a LLVM bytecode file. Read it using bytecode reader.
1001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck/// Collect global functions and symbol names in symbols vector.
1011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck/// Collect external references in references vector.
1021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck/// Return LTO_READ_SUCCESS if there is no error.
1031176bdada62cabc6ec4b0308a930e83b679d5d36John Reckenum LTOStatus
1041176bdada62cabc6ec4b0308a930e83b679d5d36John ReckLinkTimeOptimizer::readLLVMObjectFile(const std::string &InputFilename,
1051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				      NameToSymbolMap &symbols,
1061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				      std::set<const char *> &references)
1071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
1081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  Module *m = ParseBytecodeFile(InputFilename);
1091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  if (!m)
1101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return LTO_READ_FAILURE;
1111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  modules.push_back(m);
1131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  for (Module::iterator f = m->begin(), e = m->end(); f != e; ++f) {
1151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    LTOLinkageTypes lt = getLTOLinkageType(f);
1171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (!f->isExternal() && lt != LTOInternalLinkage
1191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	&& strncmp (f->getName().c_str(), "llvm.", 5)) {
1201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck      const char *name = addUnderscore(f->getName().c_str());
1211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck      LLVMSymbol *newSymbol = new LLVMSymbol(lt, f);
1221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck      symbols[name] = newSymbol;
1231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck      allSymbols[name] = newSymbol;
1241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
1251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    // Collect external symbols referenced by this function.
1271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    for (Function::iterator b = f->begin(), fe = f->end(); b != fe; ++b)
1281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck      for (BasicBlock::iterator i = b->begin(), be = b->end();
1291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	   i != be; ++i)
1301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	for (unsigned count = 0, total = i->getNumOperands();
1311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	     count != total; ++count)
1321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	  findExternalRefs(i->getOperand(count), references);
1331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  }
1341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  for (Module::global_iterator v = m->global_begin(), e = m->global_end();
1361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck       v !=  e; ++v) {
1371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    LTOLinkageTypes lt = getLTOLinkageType(v);
1381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (!v->isExternal() && lt != LTOInternalLinkage
1391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck	&& strncmp (v->getName().c_str(), "llvm.", 5)) {
1401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck      const char *name = addUnderscore(v->getName().c_str());
1411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck      LLVMSymbol *newSymbol = new LLVMSymbol(lt,v);
1421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck      symbols[name] = newSymbol;
1431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    }
1441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  }
1451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  return LTO_READ_SUCCESS;
1471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
1481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck/// Optimize module M using various IPO passes. Use exportList to
1501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck/// internalize selected symbols. Target platform is selected
1511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck/// based on information available to module M. No new target
1521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck/// features are selected.
1531176bdada62cabc6ec4b0308a930e83b679d5d36John Reckstatic enum LTOStatus lto_optimize(Module *M, std::ostream &Out,
1541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				   std::vector<const char *> &exportList)
1551176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
1561176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  // Instantiate the pass manager to organize the passes.
1571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  PassManager Passes;
1581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  // Collect Target info
1601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  std::string Err;
1611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  const TargetMachineRegistry::Entry* March =
1621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    TargetMachineRegistry::getClosestStaticTargetForModule(*M, Err);
1631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  if (March == 0)
1651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return LTO_NO_TARGET;
1661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  // Create target
1681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  std::string Features;
1691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  std::auto_ptr<TargetMachine> target(March->CtorFn(*M, Features));
1701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  if (!target.get())
1711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return LTO_NO_TARGET;
1721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  TargetMachine &Target = *target.get();
1741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  // Start off with a verification pass.
1761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  Passes.add(createVerifierPass());
1771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  // Add an appropriate TargetData instance for this module...
1791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  Passes.add(new TargetData(*Target.getTargetData()));
1801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  // Often if the programmer does not specify proper prototypes for the
1821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  // functions they are calling, they end up calling a vararg version of the
1831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  // function that does not get a body filled in (the real function has typed
1841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  // arguments).  This pass merges the two functions.
1851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  Passes.add(createFunctionResolvingPass());
1861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  // Internalize symbols if export list is nonemty
1881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  if (!exportList.empty())
1891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    Passes.add(createInternalizePass(exportList));
1901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  // Now that we internalized some globals, see if we can hack on them!
1921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  Passes.add(createGlobalOptimizerPass());
1931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  // Linking modules together can lead to duplicated global constants, only
1951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  // keep one copy of each constant...
1961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  Passes.add(createConstantMergePass());
1971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
1981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  // If the -s command line option was specified, strip the symbols out of the
1991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  // resulting program to make it smaller.  -s is a GLD option that we are
2001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  // supporting.
2011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  Passes.add(createStripSymbolsPass());
2021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  // Propagate constants at call sites into the functions they call.
2041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  Passes.add(createIPConstantPropagationPass());
2051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  // Remove unused arguments from functions...
2071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  Passes.add(createDeadArgEliminationPass());
2081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  Passes.add(createFunctionInliningPass()); // Inline small functions
2101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  Passes.add(createPruneEHPass());            // Remove dead EH info
2121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  Passes.add(createGlobalDCEPass());          // Remove dead functions
2141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  // If we didn't decide to inline a function, check to see if we can
2161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  // transform it to pass arguments by value instead of by reference.
2171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  Passes.add(createArgumentPromotionPass());
2181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  // The IPO passes may leave cruft around.  Clean up after them.
2201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  Passes.add(createInstructionCombiningPass());
2211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  Passes.add(createScalarReplAggregatesPass()); // Break up allocas
2231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  // Run a few AA driven optimizations here and now, to cleanup the code.
2251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  Passes.add(createGlobalsModRefPass());      // IP alias analysis
2261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  Passes.add(createLICMPass());               // Hoist loop invariants
2281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  Passes.add(createLoadValueNumberingPass()); // GVN for load instrs
2291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  Passes.add(createGCSEPass());               // Remove common subexprs
2301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  Passes.add(createDeadStoreEliminationPass()); // Nuke dead stores
2311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2321176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  // Cleanup and simplify the code after the scalar optimizations.
2331176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  Passes.add(createInstructionCombiningPass());
2341176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2351176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  // Delete basic blocks, which optimization passes may have killed...
2361176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  Passes.add(createCFGSimplificationPass());
2371176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2381176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  // Now that we have optimized the program, discard unreachable functions...
2391176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  Passes.add(createGlobalDCEPass());
2401176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2411176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  // Make sure everything is still good.
2421176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  Passes.add(createVerifierPass());
2431176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2441176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  Target.addPassesToEmitFile(Passes, Out, TargetMachine::AssemblyFile, true);
2451176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2461176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  // Run our queue of passes all at once now, efficiently.
2471176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  Passes.run(*M);
2481176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2491176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  return LTO_OPT_SUCCESS;
2501176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
2511176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2521176bdada62cabc6ec4b0308a930e83b679d5d36John Reck///Link all modules together and optimize them using IPO. Generate
2531176bdada62cabc6ec4b0308a930e83b679d5d36John Reck/// native object file using OutputFilename
2541176bdada62cabc6ec4b0308a930e83b679d5d36John Reck/// Return appropriate LTOStatus.
2551176bdada62cabc6ec4b0308a930e83b679d5d36John Reckenum LTOStatus
2561176bdada62cabc6ec4b0308a930e83b679d5d36John ReckLinkTimeOptimizer::optimizeModules(const std::string &OutputFilename,
2571176bdada62cabc6ec4b0308a930e83b679d5d36John Reck				   std::vector<const char *> &exportList)
2581176bdada62cabc6ec4b0308a930e83b679d5d36John Reck{
2591176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  if (modules.empty())
2601176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return LTO_NO_WORK;
2611176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2621176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  std::ios::openmode io_mode =
2631176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    std::ios::out | std::ios::trunc | std::ios::binary;
2641176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  std::string *errMsg = NULL;
2651176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  Module *bigOne = modules[0];
2661176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  Linker theLinker("LinkTimeOptimizer", bigOne, false);
2671176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  for (unsigned i = 1, e = modules.size(); i != e; ++i)
2681176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (theLinker.LinkModules(bigOne, modules[i], errMsg))
2691176bdada62cabc6ec4b0308a930e83b679d5d36John Reck      return LTO_MODULE_MERGE_FAILURE;
2701176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2711176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#if 0
2721176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  // Enable this when -save-temps is used
2731176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  std::ofstream Out("big.bc", io_mode);
2741176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  WriteBytecodeToFile(bigOne, Out, true);
2751176bdada62cabc6ec4b0308a930e83b679d5d36John Reck#endif
2761176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2771176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  // Strip leading underscore because it was added to match names
2781176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  // seen by linker.
2791176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  for (unsigned i = 0, e = exportList.size(); i != e; ++i) {
2801176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    const char *name = exportList[i];
2811176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (strlen(name) > 2 && name[0] == '_')
2821176bdada62cabc6ec4b0308a930e83b679d5d36John Reck      exportList[i] = &name[1];
2831176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  }
2841176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2851176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  sys::Path tmpAsmFilePath("/tmp/");
2861176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  tmpAsmFilePath.createTemporaryFileOnDisk();
2871176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  sys::RemoveFileOnSignal(tmpAsmFilePath);
2881176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2891176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  std::ofstream asmFile(tmpAsmFilePath.c_str(), io_mode);
2901176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  if (!asmFile.is_open() || asmFile.bad()) {
2911176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    if (tmpAsmFilePath.exists())
2921176bdada62cabc6ec4b0308a930e83b679d5d36John Reck      tmpAsmFilePath.eraseFromDisk();
2931176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return LTO_WRITE_FAILURE;
2941176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  }
2951176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
2961176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  enum LTOStatus status = lto_optimize(bigOne, asmFile, exportList);
2971176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  asmFile.close();
2981176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  if (status != LTO_OPT_SUCCESS) {
2991176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    tmpAsmFilePath.eraseFromDisk();
3001176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return status;
3011176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  }
3021176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3031176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  // Run GCC to assemble and link the program into native code.
3041176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  //
3051176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  // Note:
3061176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  //  We can't just assemble and link the file with the system assembler
3071176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  //  and linker because we don't know where to put the _start symbol.
3081176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  //  GCC mysteriously knows how to do it.
3091176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  const sys::Path gcc = FindExecutable("gcc", "/");
3101176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  if (gcc.isEmpty()) {
3111176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    tmpAsmFilePath.eraseFromDisk();
3121176bdada62cabc6ec4b0308a930e83b679d5d36John Reck    return LTO_ASM_FAILURE;
3131176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  }
3141176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3151176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  std::vector<const char*> args;
3161176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  args.push_back(gcc.c_str());
3171176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  args.push_back("-c");
3181176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  args.push_back("-x");
3191176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  args.push_back("assembler");
3201176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  args.push_back("-o");
3211176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  args.push_back(OutputFilename.c_str());
3221176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  args.push_back(tmpAsmFilePath.c_str());
3231176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  args.push_back(0);
3241176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3251176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  int R1 = sys::Program::ExecuteAndWait(gcc, &args[0], 0, 0, 1);
3261176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3271176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  tmpAsmFilePath.eraseFromDisk();
3281176bdada62cabc6ec4b0308a930e83b679d5d36John Reck
3291176bdada62cabc6ec4b0308a930e83b679d5d36John Reck  return LTO_OPT_SUCCESS;
3301176bdada62cabc6ec4b0308a930e83b679d5d36John Reck}
3311176bdada62cabc6ec4b0308a930e83b679d5d36John Reck