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