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