lto.cpp revision 40e274b5799b13646914b31c622ac857e5929732
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// 1011fdadf407642167c5e2b8a1ed40c66c0c6dbdf2Chris Lattner// This file implements the 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" 356152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel#include "llvm/Target/TargetAsmInfo.h" 36a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel#include "llvm/Transforms/IPO.h" 37a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel#include "llvm/Transforms/Scalar.h" 38a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel#include "llvm/Analysis/LoadValueNumbering.h" 3908fb05c3ac440979021f508bfee073359be46f7eDevang Patel#include "llvm/Support/MathExtras.h" 4068fe61d6a165ea6090008e281330895a21607dafBill Wendling#include "llvm/Support/Streams.h" 41a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel#include "llvm/LinkTimeOptimizer.h" 42a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel#include <fstream> 4368fe61d6a165ea6090008e281330895a21607dafBill Wendling#include <ostream> 44a89d47f54d1f83d328f6169151653bfc742607bfDevang Patelusing namespace llvm; 45a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 46a89d47f54d1f83d328f6169151653bfc742607bfDevang Patelextern "C" 47a89d47f54d1f83d328f6169151653bfc742607bfDevang Patelllvm::LinkTimeOptimizer *createLLVMOptimizer() 48a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel{ 49c7cfbc58ad88f127df6949791401969a09da560fDevang Patel llvm::LTO *l = new llvm::LTO(); 50a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel return l; 51a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel} 52a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 53a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 54a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 55a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel/// If symbol is not used then make it internal and let optimizer takes 56a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel/// care of it. 57a89d47f54d1f83d328f6169151653bfc742607bfDevang Patelvoid LLVMSymbol::mayBeNotUsed() { 58a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel gv->setLinkage(GlobalValue::InternalLinkage); 59a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel} 60a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 61a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel// Map LLVM LinkageType to LTO LinakgeType 62a89d47f54d1f83d328f6169151653bfc742607bfDevang Patelstatic LTOLinkageTypes 63a89d47f54d1f83d328f6169151653bfc742607bfDevang PatelgetLTOLinkageType(GlobalValue *v) 64a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel{ 65a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel LTOLinkageTypes lt; 66a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel if (v->hasExternalLinkage()) 67a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel lt = LTOExternalLinkage; 68a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel else if (v->hasLinkOnceLinkage()) 69a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel lt = LTOLinkOnceLinkage; 70a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel else if (v->hasWeakLinkage()) 71a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel lt = LTOWeakLinkage; 72a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel else 73a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel // Otherwise it is internal linkage for link time optimizer 74a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel lt = LTOInternalLinkage; 75a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel return lt; 76a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel} 77a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 78a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel// Find exeternal symbols referenced by VALUE. This is a recursive function. 79a89d47f54d1f83d328f6169151653bfc742607bfDevang Patelstatic void 8030235dad4b77ed83ca985030aff4fb4767551e5dDevang PatelfindExternalRefs(Value *value, std::set<std::string> &references, 812198f9cec47b4683377d4f4080acb14dd94fad65Devang Patel Mangler &mangler) { 82304d5f2edc954a3ef9904ea6d8f9421f40c9abe4Devang Patel 83304d5f2edc954a3ef9904ea6d8f9421f40c9abe4Devang Patel if (GlobalValue *gv = dyn_cast<GlobalValue>(value)) { 84a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel LTOLinkageTypes lt = getLTOLinkageType(gv); 85a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel if (lt != LTOInternalLinkage && strncmp (gv->getName().c_str(), "llvm.", 5)) 8630235dad4b77ed83ca985030aff4fb4767551e5dDevang Patel references.insert(mangler.getValueName(gv)); 87a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel } 88544ea34a9f7aeef5fa3cbfdaae5933f93f4f68ecDevang Patel 89544ea34a9f7aeef5fa3cbfdaae5933f93f4f68ecDevang Patel // GlobalValue, even with InternalLinkage type, may have operands with 90544ea34a9f7aeef5fa3cbfdaae5933f93f4f68ecDevang Patel // ExternalLinkage type. Do not ignore these operands. 9197d92d50aa52fd7f891ddeaf9e3886305a5a77d9Devang Patel if (Constant *c = dyn_cast<Constant>(value)) 92304d5f2edc954a3ef9904ea6d8f9421f40c9abe4Devang Patel // Handle ConstantExpr, ConstantStruct, ConstantArry etc.. 93304d5f2edc954a3ef9904ea6d8f9421f40c9abe4Devang Patel for (unsigned i = 0, e = c->getNumOperands(); i != e; ++i) 9430235dad4b77ed83ca985030aff4fb4767551e5dDevang Patel findExternalRefs(c->getOperand(i), references, mangler); 95a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel} 96a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 972a4dd685357e2fd248ab458d3bed4ea21350815bDevang Patel/// If Module with InputFilename is available then remove it from allModules 982a4dd685357e2fd248ab458d3bed4ea21350815bDevang Patel/// and call delete on it. 99f2ca21f88f4e38996b6804dfa25fe7a72814736dDevang Patelvoid 100f2ca21f88f4e38996b6804dfa25fe7a72814736dDevang PatelLTO::removeModule (const std::string &InputFilename) 101f2ca21f88f4e38996b6804dfa25fe7a72814736dDevang Patel{ 102f2ca21f88f4e38996b6804dfa25fe7a72814736dDevang Patel NameToModuleMap::iterator pos = allModules.find(InputFilename.c_str()); 1032a4dd685357e2fd248ab458d3bed4ea21350815bDevang Patel if (pos == allModules.end()) 1042a4dd685357e2fd248ab458d3bed4ea21350815bDevang Patel return; 1052a4dd685357e2fd248ab458d3bed4ea21350815bDevang Patel 1062a4dd685357e2fd248ab458d3bed4ea21350815bDevang Patel Module *m = pos->second; 1072a4dd685357e2fd248ab458d3bed4ea21350815bDevang Patel allModules.erase(pos); 1082a4dd685357e2fd248ab458d3bed4ea21350815bDevang Patel delete m; 109f2ca21f88f4e38996b6804dfa25fe7a72814736dDevang Patel} 110f2ca21f88f4e38996b6804dfa25fe7a72814736dDevang Patel 1110701a2f70df66134ead84d4fe86b20b8f28c4fc3Devang Patel/// InputFilename is a LLVM bytecode file. If Module with InputFilename is 1120701a2f70df66134ead84d4fe86b20b8f28c4fc3Devang Patel/// available then return it. Otherwise parseInputFilename. 1130701a2f70df66134ead84d4fe86b20b8f28c4fc3Devang PatelModule * 114c7cfbc58ad88f127df6949791401969a09da560fDevang PatelLTO::getModule(const std::string &InputFilename) 1150701a2f70df66134ead84d4fe86b20b8f28c4fc3Devang Patel{ 1160701a2f70df66134ead84d4fe86b20b8f28c4fc3Devang Patel Module *m = NULL; 1170701a2f70df66134ead84d4fe86b20b8f28c4fc3Devang Patel 1180701a2f70df66134ead84d4fe86b20b8f28c4fc3Devang Patel NameToModuleMap::iterator pos = allModules.find(InputFilename.c_str()); 1190701a2f70df66134ead84d4fe86b20b8f28c4fc3Devang Patel if (pos != allModules.end()) 1200701a2f70df66134ead84d4fe86b20b8f28c4fc3Devang Patel m = allModules[InputFilename.c_str()]; 1210701a2f70df66134ead84d4fe86b20b8f28c4fc3Devang Patel else { 1220701a2f70df66134ead84d4fe86b20b8f28c4fc3Devang Patel m = ParseBytecodeFile(InputFilename); 1230701a2f70df66134ead84d4fe86b20b8f28c4fc3Devang Patel allModules[InputFilename.c_str()] = m; 1240701a2f70df66134ead84d4fe86b20b8f28c4fc3Devang Patel } 1250701a2f70df66134ead84d4fe86b20b8f28c4fc3Devang Patel return m; 1260701a2f70df66134ead84d4fe86b20b8f28c4fc3Devang Patel} 1270701a2f70df66134ead84d4fe86b20b8f28c4fc3Devang Patel 128a291a68161bd37448404dc10c4815d4420cb2d30Devang Patel/// InputFilename is a LLVM bytecode file. Reade this bytecode file and 129a291a68161bd37448404dc10c4815d4420cb2d30Devang Patel/// set corresponding target triplet string. 130a291a68161bd37448404dc10c4815d4420cb2d30Devang Patelvoid 131c7cfbc58ad88f127df6949791401969a09da560fDevang PatelLTO::getTargetTriple(const std::string &InputFilename, 13238187d6a56326d0d6339f09c1ef21d52174d95a8Devang Patel std::string &targetTriple) 133a291a68161bd37448404dc10c4815d4420cb2d30Devang Patel{ 134a291a68161bd37448404dc10c4815d4420cb2d30Devang Patel Module *m = getModule(InputFilename); 135a291a68161bd37448404dc10c4815d4420cb2d30Devang Patel if (m) 136a291a68161bd37448404dc10c4815d4420cb2d30Devang Patel targetTriple = m->getTargetTriple(); 137a291a68161bd37448404dc10c4815d4420cb2d30Devang Patel} 138a291a68161bd37448404dc10c4815d4420cb2d30Devang Patel 139a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel/// InputFilename is a LLVM bytecode file. Read it using bytecode reader. 140a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel/// Collect global functions and symbol names in symbols vector. 141a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel/// Collect external references in references vector. 142a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel/// Return LTO_READ_SUCCESS if there is no error. 143a89d47f54d1f83d328f6169151653bfc742607bfDevang Patelenum LTOStatus 144c7cfbc58ad88f127df6949791401969a09da560fDevang PatelLTO::readLLVMObjectFile(const std::string &InputFilename, 14538187d6a56326d0d6339f09c1ef21d52174d95a8Devang Patel NameToSymbolMap &symbols, 14638187d6a56326d0d6339f09c1ef21d52174d95a8Devang Patel std::set<std::string> &references) 147a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel{ 1480701a2f70df66134ead84d4fe86b20b8f28c4fc3Devang Patel Module *m = getModule(InputFilename); 149a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel if (!m) 150a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel return LTO_READ_FAILURE; 15130235dad4b77ed83ca985030aff4fb4767551e5dDevang Patel 1526152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel // Collect Target info 15308fb05c3ac440979021f508bfee073359be46f7eDevang Patel getTarget(m); 1546152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel 1556152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel if (!Target) 1566152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel return LTO_READ_FAILURE; 1576152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel 15830235dad4b77ed83ca985030aff4fb4767551e5dDevang Patel // Use mangler to add GlobalPrefix to names to match linker names. 15930235dad4b77ed83ca985030aff4fb4767551e5dDevang Patel // FIXME : Instead of hard coding "-" use GlobalPrefix. 1606152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel Mangler mangler(*m, Target->getTargetAsmInfo()->getGlobalPrefix()); 161a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel modules.push_back(m); 162a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 163a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel for (Module::iterator f = m->begin(), e = m->end(); f != e; ++f) { 164a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 165a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel LTOLinkageTypes lt = getLTOLinkageType(f); 166a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 167a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel if (!f->isExternal() && lt != LTOInternalLinkage 1682198f9cec47b4683377d4f4080acb14dd94fad65Devang Patel && strncmp (f->getName().c_str(), "llvm.", 5)) { 16908fb05c3ac440979021f508bfee073359be46f7eDevang Patel int alignment = ( 16 > f->getAlignment() ? 16 : f->getAlignment()); 17030235dad4b77ed83ca985030aff4fb4767551e5dDevang Patel LLVMSymbol *newSymbol = new LLVMSymbol(lt, f, f->getName(), 17108fb05c3ac440979021f508bfee073359be46f7eDevang Patel mangler.getValueName(f), 17208fb05c3ac440979021f508bfee073359be46f7eDevang Patel Log2_32(alignment)); 17330235dad4b77ed83ca985030aff4fb4767551e5dDevang Patel symbols[newSymbol->getMangledName()] = newSymbol; 17430235dad4b77ed83ca985030aff4fb4767551e5dDevang Patel allSymbols[newSymbol->getMangledName()] = newSymbol; 175a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel } 17630235dad4b77ed83ca985030aff4fb4767551e5dDevang Patel 177a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel // Collect external symbols referenced by this function. 178a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel for (Function::iterator b = f->begin(), fe = f->end(); b != fe; ++b) 179a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel for (BasicBlock::iterator i = b->begin(), be = b->end(); 1802198f9cec47b4683377d4f4080acb14dd94fad65Devang Patel i != be; ++i) 1812198f9cec47b4683377d4f4080acb14dd94fad65Devang Patel for (unsigned count = 0, total = i->getNumOperands(); 1822198f9cec47b4683377d4f4080acb14dd94fad65Devang Patel count != total; ++count) 1832198f9cec47b4683377d4f4080acb14dd94fad65Devang Patel findExternalRefs(i->getOperand(count), references, mangler); 184a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel } 185a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 186a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel for (Module::global_iterator v = m->global_begin(), e = m->global_end(); 187a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel v != e; ++v) { 188a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel LTOLinkageTypes lt = getLTOLinkageType(v); 189a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel if (!v->isExternal() && lt != LTOInternalLinkage 1902198f9cec47b4683377d4f4080acb14dd94fad65Devang Patel && strncmp (v->getName().c_str(), "llvm.", 5)) { 19108fb05c3ac440979021f508bfee073359be46f7eDevang Patel const TargetData *TD = Target->getTargetData(); 19230235dad4b77ed83ca985030aff4fb4767551e5dDevang Patel LLVMSymbol *newSymbol = new LLVMSymbol(lt, v, v->getName(), 19308fb05c3ac440979021f508bfee073359be46f7eDevang Patel mangler.getValueName(v), 19408fb05c3ac440979021f508bfee073359be46f7eDevang Patel TD->getPreferredAlignmentLog(v)); 19530235dad4b77ed83ca985030aff4fb4767551e5dDevang Patel symbols[newSymbol->getMangledName()] = newSymbol; 196ed872865d0316ec754d93f703dd39f21745e45caDevang Patel allSymbols[newSymbol->getMangledName()] = newSymbol; 197304d5f2edc954a3ef9904ea6d8f9421f40c9abe4Devang Patel 198304d5f2edc954a3ef9904ea6d8f9421f40c9abe4Devang Patel for (unsigned count = 0, total = v->getNumOperands(); 1992198f9cec47b4683377d4f4080acb14dd94fad65Devang Patel count != total; ++count) 2002198f9cec47b4683377d4f4080acb14dd94fad65Devang Patel findExternalRefs(v->getOperand(count), references, mangler); 201304d5f2edc954a3ef9904ea6d8f9421f40c9abe4Devang Patel 202a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel } 203a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel } 204a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 205a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel return LTO_READ_SUCCESS; 206a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel} 207a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 2086152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel/// Get TargetMachine. 2096152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel/// Use module M to find appropriate Target. 2106152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patelvoid 2116152b7ec25b8d225dc1e146e241d1c6061c8221bDevang PatelLTO::getTarget (Module *M) { 2126152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel 21308fb05c3ac440979021f508bfee073359be46f7eDevang Patel if (Target) 21408fb05c3ac440979021f508bfee073359be46f7eDevang Patel return; 21508fb05c3ac440979021f508bfee073359be46f7eDevang Patel 2166152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel std::string Err; 2176152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel const TargetMachineRegistry::Entry* March = 2186152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel TargetMachineRegistry::getClosestStaticTargetForModule(*M, Err); 2196152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel 2206152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel if (March == 0) 2216152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel return; 2226152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel 2236152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel // Create target 2246152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel std::string Features; 2256152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel Target = March->CtorFn(*M, Features); 2266152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel} 2276152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel 228a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel/// Optimize module M using various IPO passes. Use exportList to 229a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel/// internalize selected symbols. Target platform is selected 230a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel/// based on information available to module M. No new target 231a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel/// features are selected. 2326152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patelenum LTOStatus 2336152b7ec25b8d225dc1e146e241d1c6061c8221bDevang PatelLTO::optimize(Module *M, std::ostream &Out, 2346152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel std::vector<const char *> &exportList) 235a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel{ 236a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel // Instantiate the pass manager to organize the passes. 237a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel PassManager Passes; 238a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 239a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel // Collect Target info 24008fb05c3ac440979021f508bfee073359be46f7eDevang Patel getTarget(M); 2416152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel 2426152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel if (!Target) 243a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel return LTO_NO_TARGET; 244a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 245a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel // Start off with a verification pass. 246a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel Passes.add(createVerifierPass()); 247a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 248a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel // Add an appropriate TargetData instance for this module... 2496152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel Passes.add(new TargetData(*Target->getTargetData())); 250a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 251a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel // Often if the programmer does not specify proper prototypes for the 252a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel // functions they are calling, they end up calling a vararg version of the 253a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel // function that does not get a body filled in (the real function has typed 254a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel // arguments). This pass merges the two functions. 255a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel Passes.add(createFunctionResolvingPass()); 256a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 257a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel // Internalize symbols if export list is nonemty 258a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel if (!exportList.empty()) 259a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel Passes.add(createInternalizePass(exportList)); 260a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 261a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel // Now that we internalized some globals, see if we can hack on them! 262a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel Passes.add(createGlobalOptimizerPass()); 263a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 264a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel // Linking modules together can lead to duplicated global constants, only 265a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel // keep one copy of each constant... 266a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel Passes.add(createConstantMergePass()); 267a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 268a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel // If the -s command line option was specified, strip the symbols out of the 269a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel // resulting program to make it smaller. -s is a GLD option that we are 270a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel // supporting. 271a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel Passes.add(createStripSymbolsPass()); 272a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 273a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel // Propagate constants at call sites into the functions they call. 274a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel Passes.add(createIPConstantPropagationPass()); 275a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 276a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel // Remove unused arguments from functions... 277a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel Passes.add(createDeadArgEliminationPass()); 278a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 279a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel Passes.add(createFunctionInliningPass()); // Inline small functions 280a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 281a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel Passes.add(createPruneEHPass()); // Remove dead EH info 282a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 283a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel Passes.add(createGlobalDCEPass()); // Remove dead functions 284a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 285a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel // If we didn't decide to inline a function, check to see if we can 286a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel // transform it to pass arguments by value instead of by reference. 287a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel Passes.add(createArgumentPromotionPass()); 288a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 289a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel // The IPO passes may leave cruft around. Clean up after them. 290a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel Passes.add(createInstructionCombiningPass()); 291a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 292a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel Passes.add(createScalarReplAggregatesPass()); // Break up allocas 293a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 294a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel // Run a few AA driven optimizations here and now, to cleanup the code. 295a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel Passes.add(createGlobalsModRefPass()); // IP alias analysis 296a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 297a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel Passes.add(createLICMPass()); // Hoist loop invariants 298a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel Passes.add(createLoadValueNumberingPass()); // GVN for load instrs 299a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel Passes.add(createGCSEPass()); // Remove common subexprs 300a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel Passes.add(createDeadStoreEliminationPass()); // Nuke dead stores 301a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 302a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel // Cleanup and simplify the code after the scalar optimizations. 303a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel Passes.add(createInstructionCombiningPass()); 304a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 305a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel // Delete basic blocks, which optimization passes may have killed... 306a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel Passes.add(createCFGSimplificationPass()); 307a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 308a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel // Now that we have optimized the program, discard unreachable functions... 309a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel Passes.add(createGlobalDCEPass()); 310a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 311a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel // Make sure everything is still good. 312a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel Passes.add(createVerifierPass()); 313a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 314998051a2211a5f86b38941de0aca241b34895e1eDevang Patel FunctionPassManager *CodeGenPasses = 315998051a2211a5f86b38941de0aca241b34895e1eDevang Patel new FunctionPassManager(new ExistingModuleProvider(M)); 316998051a2211a5f86b38941de0aca241b34895e1eDevang Patel 3176152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel CodeGenPasses->add(new TargetData(*Target->getTargetData())); 3186152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel Target->addPassesToEmitFile(*CodeGenPasses, Out, TargetMachine::AssemblyFile, 31938187d6a56326d0d6339f09c1ef21d52174d95a8Devang Patel true); 320a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 321a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel // Run our queue of passes all at once now, efficiently. 322a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel Passes.run(*M); 323a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 324998051a2211a5f86b38941de0aca241b34895e1eDevang Patel // Run the code generator, if present. 325998051a2211a5f86b38941de0aca241b34895e1eDevang Patel CodeGenPasses->doInitialization(); 326998051a2211a5f86b38941de0aca241b34895e1eDevang Patel for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) { 327998051a2211a5f86b38941de0aca241b34895e1eDevang Patel if (!I->isExternal()) 328998051a2211a5f86b38941de0aca241b34895e1eDevang Patel CodeGenPasses->run(*I); 329998051a2211a5f86b38941de0aca241b34895e1eDevang Patel } 330998051a2211a5f86b38941de0aca241b34895e1eDevang Patel CodeGenPasses->doFinalization(); 331998051a2211a5f86b38941de0aca241b34895e1eDevang Patel 332a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel return LTO_OPT_SUCCESS; 333a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel} 334a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 335a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel///Link all modules together and optimize them using IPO. Generate 336a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel/// native object file using OutputFilename 337a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel/// Return appropriate LTOStatus. 338a89d47f54d1f83d328f6169151653bfc742607bfDevang Patelenum LTOStatus 339c7cfbc58ad88f127df6949791401969a09da560fDevang PatelLTO::optimizeModules(const std::string &OutputFilename, 34038187d6a56326d0d6339f09c1ef21d52174d95a8Devang Patel std::vector<const char *> &exportList, 34138187d6a56326d0d6339f09c1ef21d52174d95a8Devang Patel std::string &targetTriple, 34238187d6a56326d0d6339f09c1ef21d52174d95a8Devang Patel bool saveTemps, 34338187d6a56326d0d6339f09c1ef21d52174d95a8Devang Patel const char *FinalOutputFilename) 344a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel{ 345a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel if (modules.empty()) 346a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel return LTO_NO_WORK; 347a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 348a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel std::ios::openmode io_mode = 349a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel std::ios::out | std::ios::trunc | std::ios::binary; 350a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel std::string *errMsg = NULL; 351a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel Module *bigOne = modules[0]; 352a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel Linker theLinker("LinkTimeOptimizer", bigOne, false); 353a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel for (unsigned i = 1, e = modules.size(); i != e; ++i) 354a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel if (theLinker.LinkModules(bigOne, modules[i], errMsg)) 355a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel return LTO_MODULE_MERGE_FAILURE; 356a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 35738187d6a56326d0d6339f09c1ef21d52174d95a8Devang Patel sys::Path FinalOutputPath(FinalOutputFilename); 35838187d6a56326d0d6339f09c1ef21d52174d95a8Devang Patel FinalOutputPath.eraseSuffix(); 35938187d6a56326d0d6339f09c1ef21d52174d95a8Devang Patel 36038187d6a56326d0d6339f09c1ef21d52174d95a8Devang Patel if (saveTemps) { 36138187d6a56326d0d6339f09c1ef21d52174d95a8Devang Patel std::string tempFileName(FinalOutputPath.c_str()); 36238187d6a56326d0d6339f09c1ef21d52174d95a8Devang Patel tempFileName += "0.bc"; 36338187d6a56326d0d6339f09c1ef21d52174d95a8Devang Patel std::ofstream Out(tempFileName.c_str(), io_mode); 364e81561909d128c6e2d8033cb5465a49b2596b26aBill Wendling OStream L(Out); 36568fe61d6a165ea6090008e281330895a21607dafBill Wendling WriteBytecodeToFile(bigOne, L, true); 36638187d6a56326d0d6339f09c1ef21d52174d95a8Devang Patel } 367a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 368a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel // Strip leading underscore because it was added to match names 36994a0ac9bea7411bf98512b44b7e9bba42ee9a07fDevang Patel // seen by linker. 370a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel for (unsigned i = 0, e = exportList.size(); i != e; ++i) { 371a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel const char *name = exportList[i]; 372ed872865d0316ec754d93f703dd39f21745e45caDevang Patel NameToSymbolMap::iterator itr = allSymbols.find(name); 373ed872865d0316ec754d93f703dd39f21745e45caDevang Patel if (itr != allSymbols.end()) 374ed872865d0316ec754d93f703dd39f21745e45caDevang Patel exportList[i] = allSymbols[name]->getName(); 375a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel } 376a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 3773f0e5e205772af1529d980cb1fb2c910ef38417cDevang Patel 378e5c9cb5eb6bce502faaedea04014dab46f6540f4Reid Spencer std::string ErrMsg; 3793f0e5e205772af1529d980cb1fb2c910ef38417cDevang Patel sys::Path TempDir = sys::Path::GetTemporaryDirectory(&ErrMsg); 3809f5d48bcb1c6e72363567089242960bfde5171bbDevang Patel if (TempDir.isEmpty()) { 381e81561909d128c6e2d8033cb5465a49b2596b26aBill Wendling cerr << "lto: " << ErrMsg << "\n"; 3829f5d48bcb1c6e72363567089242960bfde5171bbDevang Patel return LTO_WRITE_FAILURE; 3839f5d48bcb1c6e72363567089242960bfde5171bbDevang Patel } 3843f0e5e205772af1529d980cb1fb2c910ef38417cDevang Patel sys::Path tmpAsmFilePath(TempDir); 3853f0e5e205772af1529d980cb1fb2c910ef38417cDevang Patel if (!tmpAsmFilePath.appendComponent("lto")) { 386e81561909d128c6e2d8033cb5465a49b2596b26aBill Wendling cerr << "lto: " << ErrMsg << "\n"; 3873f0e5e205772af1529d980cb1fb2c910ef38417cDevang Patel TempDir.eraseFromDisk(true); 3883f0e5e205772af1529d980cb1fb2c910ef38417cDevang Patel return LTO_WRITE_FAILURE; 3893f0e5e205772af1529d980cb1fb2c910ef38417cDevang Patel } 390e5c9cb5eb6bce502faaedea04014dab46f6540f4Reid Spencer if (tmpAsmFilePath.createTemporaryFileOnDisk(&ErrMsg)) { 391e81561909d128c6e2d8033cb5465a49b2596b26aBill Wendling cerr << "lto: " << ErrMsg << "\n"; 3923f0e5e205772af1529d980cb1fb2c910ef38417cDevang Patel TempDir.eraseFromDisk(true); 393ca64012ac6b21d868ccf2fcc26febd991ef2cc9cDevang Patel return LTO_WRITE_FAILURE; 394e5c9cb5eb6bce502faaedea04014dab46f6540f4Reid Spencer } 395a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel sys::RemoveFileOnSignal(tmpAsmFilePath); 396a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 397a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel std::ofstream asmFile(tmpAsmFilePath.c_str(), io_mode); 398a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel if (!asmFile.is_open() || asmFile.bad()) { 3993f0e5e205772af1529d980cb1fb2c910ef38417cDevang Patel if (tmpAsmFilePath.exists()) { 400a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel tmpAsmFilePath.eraseFromDisk(); 4013f0e5e205772af1529d980cb1fb2c910ef38417cDevang Patel TempDir.eraseFromDisk(true); 4023f0e5e205772af1529d980cb1fb2c910ef38417cDevang Patel } 403a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel return LTO_WRITE_FAILURE; 404a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel } 405a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 4066152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel enum LTOStatus status = optimize(bigOne, asmFile, exportList); 407a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel asmFile.close(); 408a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel if (status != LTO_OPT_SUCCESS) { 409a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel tmpAsmFilePath.eraseFromDisk(); 4103f0e5e205772af1529d980cb1fb2c910ef38417cDevang Patel TempDir.eraseFromDisk(true); 411a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel return status; 412a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel } 413a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 41438187d6a56326d0d6339f09c1ef21d52174d95a8Devang Patel if (saveTemps) { 41538187d6a56326d0d6339f09c1ef21d52174d95a8Devang Patel std::string tempFileName(FinalOutputPath.c_str()); 41638187d6a56326d0d6339f09c1ef21d52174d95a8Devang Patel tempFileName += "1.bc"; 41738187d6a56326d0d6339f09c1ef21d52174d95a8Devang Patel std::ofstream Out(tempFileName.c_str(), io_mode); 418e81561909d128c6e2d8033cb5465a49b2596b26aBill Wendling OStream L(Out); 41968fe61d6a165ea6090008e281330895a21607dafBill Wendling WriteBytecodeToFile(bigOne, L, true); 42038187d6a56326d0d6339f09c1ef21d52174d95a8Devang Patel } 42138187d6a56326d0d6339f09c1ef21d52174d95a8Devang Patel 4222681023488d70303ec788bc8a0a3f5336257830aDevang Patel targetTriple = bigOne->getTargetTriple(); 4232681023488d70303ec788bc8a0a3f5336257830aDevang Patel 424a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel // Run GCC to assemble and link the program into native code. 425a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel // 426a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel // Note: 427a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel // We can't just assemble and link the file with the system assembler 428a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel // and linker because we don't know where to put the _start symbol. 429a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel // GCC mysteriously knows how to do it. 430dc4c38279f6bf3b001515e6723e7b6d79ed378b0Devang Patel const sys::Path gcc = sys::Program::FindProgramByName("gcc"); 431a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel if (gcc.isEmpty()) { 432a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel tmpAsmFilePath.eraseFromDisk(); 4333f0e5e205772af1529d980cb1fb2c910ef38417cDevang Patel TempDir.eraseFromDisk(true); 434a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel return LTO_ASM_FAILURE; 435a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel } 436a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 437a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel std::vector<const char*> args; 438a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel args.push_back(gcc.c_str()); 439a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel args.push_back("-c"); 440a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel args.push_back("-x"); 441a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel args.push_back("assembler"); 442a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel args.push_back("-o"); 443a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel args.push_back(OutputFilename.c_str()); 444a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel args.push_back(tmpAsmFilePath.c_str()); 445a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel args.push_back(0); 446a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 4479f5d48bcb1c6e72363567089242960bfde5171bbDevang Patel if (sys::Program::ExecuteAndWait(gcc, &args[0], 0, 0, 1, &ErrMsg)) { 448e81561909d128c6e2d8033cb5465a49b2596b26aBill Wendling cerr << "lto: " << ErrMsg << "\n"; 4499f5d48bcb1c6e72363567089242960bfde5171bbDevang Patel return LTO_ASM_FAILURE; 4509f5d48bcb1c6e72363567089242960bfde5171bbDevang Patel } 451a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 452a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel tmpAsmFilePath.eraseFromDisk(); 4533f0e5e205772af1529d980cb1fb2c910ef38417cDevang Patel TempDir.eraseFromDisk(true); 454a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel 455a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel return LTO_OPT_SUCCESS; 456a89d47f54d1f83d328f6169151653bfc742607bfDevang Patel} 4576152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel 45840e274b5799b13646914b31c622ac857e5929732Chandler Carruth/// Unused pure-virtual destructor. Must remain empty. 45940e274b5799b13646914b31c622ac857e5929732Chandler CarruthLinkTimeOptimizer::~LinkTimeOptimizer() {} 46040e274b5799b13646914b31c622ac857e5929732Chandler Carruth 4616152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel/// Destruct LTO. Delete all modules, symbols and target. 4626152b7ec25b8d225dc1e146e241d1c6061c8221bDevang PatelLTO::~LTO() { 4636152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel 4646152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel for (std::vector<Module *>::iterator itr = modules.begin(), e = modules.end(); 4656152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel itr != e; ++itr) 4666152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel delete *itr; 4676152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel 4686152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel modules.clear(); 4696152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel 4706152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel for (NameToSymbolMap::iterator itr = allSymbols.begin(), e = allSymbols.end(); 4716152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel itr != e; ++itr) 4726152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel delete itr->second; 4736152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel 4746152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel allSymbols.clear(); 4756152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel 4766152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel delete Target; 4776152b7ec25b8d225dc1e146e241d1c6061c8221bDevang Patel} 478