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