lto.cpp revision 5cbf985dcbc89fba3208e7baf8b6f488b06d3ec9
124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===-lto.cpp - LLVM Link Time Optimizer ----------------------------------===// 224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// The LLVM Compiler Infrastructure 424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This file was developed by Devang Patel and is distributed under 624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// the University of Illinois Open Source License. See LICENSE.TXT for details. 724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===----------------------------------------------------------------------===// 924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 1024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// This file implements the Link Time Optimization library. This library is 1124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// intended to be used by linker to optimize code at link time. 1224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner// 1324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner//===----------------------------------------------------------------------===// 1407c51d09d4b61891cdc37f44bb332dc286b4de2fBenjamin Kramer 15b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton#include "llvm/Module.h" 16b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton#include "llvm/PassManager.h" 1724943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "llvm/Linker.h" 1824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "llvm/Constants.h" 19b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton#include "llvm/DerivedTypes.h" 20ff39f746ebaa3710c44ba49bd9b0a6cf05f60a3fGreg Clayton#include "llvm/SymbolTable.h" 2124943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "llvm/Bytecode/Reader.h" 2224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "llvm/Bytecode/Writer.h" 2324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "llvm/Support/CommandLine.h" 2424943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "llvm/Support/FileUtilities.h" 25e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton#include "llvm/Support/SystemUtils.h" 2624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "llvm/Support/Mangler.h" 27861efb3f6e225e45c45511d6da894633b36025a1Caroline Tice#include "llvm/System/Program.h" 2824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "llvm/System/Signals.h" 2924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "llvm/Analysis/Passes.h" 30a9385537809ef342c843c5ab972e513742652047Greg Clayton#include "llvm/Analysis/Verifier.h" 317508e732818c32e1cfeaaf7d1d507fe3834ce9d2Jim Ingham#include "llvm/Target/SubtargetFeature.h" 3224943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "llvm/Target/TargetData.h" 3324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "llvm/Target/TargetMachine.h" 346e4c5ce0f697eb9899a54854a2a9004e961b0de2Caroline Tice#include "llvm/Target/TargetMachineRegistry.h" 3524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include "llvm/Target/TargetAsmInfo.h" 36a48fe1637ec6a381e500633c087f76662e364c20Sean Callanan#include "llvm/Transforms/IPO.h" 37f18d91c9bbd01152b29d84ab55ad2f0bbc9baf6cSean Callanan#include "llvm/Transforms/Scalar.h" 38ff39f746ebaa3710c44ba49bd9b0a6cf05f60a3fGreg Clayton#include "llvm/Analysis/LoadValueNumbering.h" 391c4642c6ab741d85c98d4288cf922c9a2ef77007Greg Clayton#include "llvm/Support/MathExtras.h" 40cf88b95d435873bd312e716da5701cf3882c5da4Ed Maste#include "llvm/Support/Streams.h" 41e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton#include "llvm/LinkTimeOptimizer.h" 42e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton#include <fstream> 4324943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner#include <ostream> 44613b8739a4d489b7f1c571288d5786768c024205Greg Claytonusing namespace llvm; 4524943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner 4624943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattnerextern "C" 47464c6161464694412b7472129e789248f1cf21b9Greg Claytonllvm::LinkTimeOptimizer *createLLVMOptimizer() 4824943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner{ 4924943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner llvm::LTO *l = new llvm::LTO(); 5024943d2ee8bfaa7cf5893e4709143924157a5c1eChris Lattner return l; 51c6e82e4a323d7a7168b05365c53c9bc2e0d418e3Greg Clayton} 52c6e82e4a323d7a7168b05365c53c9bc2e0d418e3Greg Clayton 53c6e82e4a323d7a7168b05365c53c9bc2e0d418e3Greg Clayton 54c6e82e4a323d7a7168b05365c53c9bc2e0d418e3Greg Clayton 55c6e82e4a323d7a7168b05365c53c9bc2e0d418e3Greg Clayton/// If symbol is not used then make it internal and let optimizer takes 56c6e82e4a323d7a7168b05365c53c9bc2e0d418e3Greg Clayton/// care of it. 57c6e82e4a323d7a7168b05365c53c9bc2e0d418e3Greg Claytonvoid LLVMSymbol::mayBeNotUsed() { 5886827fbccc9a4d1f9993d74940f724d63d826e45Jim Ingham gv->setLinkage(GlobalValue::InternalLinkage); 59c6e82e4a323d7a7168b05365c53c9bc2e0d418e3Greg Clayton} 60c6e82e4a323d7a7168b05365c53c9bc2e0d418e3Greg Clayton 61c6e82e4a323d7a7168b05365c53c9bc2e0d418e3Greg Clayton// Map LLVM LinkageType to LTO LinakgeType 62c6e82e4a323d7a7168b05365c53c9bc2e0d418e3Greg Claytonstatic LTOLinkageTypes 63c6e82e4a323d7a7168b05365c53c9bc2e0d418e3Greg ClaytongetLTOLinkageType(GlobalValue *v) 6473844aa19a7360b662e2be710fc3c969d6c86606Greg Clayton{ 65c6e82e4a323d7a7168b05365c53c9bc2e0d418e3Greg Clayton LTOLinkageTypes lt; 66c6e82e4a323d7a7168b05365c53c9bc2e0d418e3Greg Clayton if (v->hasExternalLinkage()) 676e4c5ce0f697eb9899a54854a2a9004e961b0de2Caroline Tice lt = LTOExternalLinkage; 68c6e82e4a323d7a7168b05365c53c9bc2e0d418e3Greg Clayton else if (v->hasLinkOnceLinkage()) 69c6e82e4a323d7a7168b05365c53c9bc2e0d418e3Greg Clayton lt = LTOLinkOnceLinkage; 702e7f313dc473b036788319690116b324cb44b765Greg Clayton else if (v->hasWeakLinkage()) 712e7f313dc473b036788319690116b324cb44b765Greg Clayton lt = LTOWeakLinkage; 722e7f313dc473b036788319690116b324cb44b765Greg Clayton else 732e7f313dc473b036788319690116b324cb44b765Greg Clayton // Otherwise it is internal linkage for link time optimizer 742e7f313dc473b036788319690116b324cb44b765Greg Clayton lt = LTOInternalLinkage; 752e7f313dc473b036788319690116b324cb44b765Greg Clayton return lt; 76b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham} 77b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham 78b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham// Find exeternal symbols referenced by VALUE. This is a recursive function. 79b794020ffbd6473c59a6e98be044df50abf7fc30Jim Inghamstatic void 80b794020ffbd6473c59a6e98be044df50abf7fc30Jim InghamfindExternalRefs(Value *value, std::set<std::string> &references, 81b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham Mangler &mangler) { 82b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham 83b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham if (GlobalValue *gv = dyn_cast<GlobalValue>(value)) { 84b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham LTOLinkageTypes lt = getLTOLinkageType(gv); 85b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham if (lt != LTOInternalLinkage && strncmp (gv->getName().c_str(), "llvm.", 5)) 86b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham references.insert(mangler.getValueName(gv)); 87b794020ffbd6473c59a6e98be044df50abf7fc30Jim Ingham } 88090f83176695d86197b0e86b67dee4160ec5003dJim Ingham 89090f83176695d86197b0e86b67dee4160ec5003dJim Ingham // GlobalValue, even with InternalLinkage type, may have operands with 90090f83176695d86197b0e86b67dee4160ec5003dJim Ingham // ExternalLinkage type. Do not ignore these operands. 91090f83176695d86197b0e86b67dee4160ec5003dJim Ingham if (Constant *c = dyn_cast<Constant>(value)) 92090f83176695d86197b0e86b67dee4160ec5003dJim Ingham // Handle ConstantExpr, ConstantStruct, ConstantArry etc.. 93090f83176695d86197b0e86b67dee4160ec5003dJim Ingham for (unsigned i = 0, e = c->getNumOperands(); i != e; ++i) 94761afb822b18c46b2ad84be03f372e90ac1e6143Jim Ingham findExternalRefs(c->getOperand(i), references, mangler); 95761afb822b18c46b2ad84be03f372e90ac1e6143Jim Ingham} 96761afb822b18c46b2ad84be03f372e90ac1e6143Jim Ingham 97761afb822b18c46b2ad84be03f372e90ac1e6143Jim Ingham/// If Module with InputFilename is available then remove it from allModules 98761afb822b18c46b2ad84be03f372e90ac1e6143Jim Ingham/// and call delete on it. 99761afb822b18c46b2ad84be03f372e90ac1e6143Jim Inghamvoid 100c6e82e4a323d7a7168b05365c53c9bc2e0d418e3Greg ClaytonLTO::removeModule (const std::string &InputFilename) 101c6e82e4a323d7a7168b05365c53c9bc2e0d418e3Greg Clayton{ 102102b2c2681c9a830afe25bfea35557421905e42cGreg Clayton NameToModuleMap::iterator pos = allModules.find(InputFilename.c_str()); 1036e4c5ce0f697eb9899a54854a2a9004e961b0de2Caroline Tice if (pos == allModules.end()) 104b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton return; 105b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton 106b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton Module *m = pos->second; 107b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton allModules.erase(pos); 108b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton delete m; 109b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton} 110b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton 111b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton/// InputFilename is a LLVM bytecode file. If Module with InputFilename is 112e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton/// available then return it. Otherwise parseInputFilename. 113e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg ClaytonModule * 114e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg ClaytonLTO::getModule(const std::string &InputFilename) 115e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton{ 116ff39f746ebaa3710c44ba49bd9b0a6cf05f60a3fGreg Clayton Module *m = NULL; 117b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton 118b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton NameToModuleMap::iterator pos = allModules.find(InputFilename.c_str()); 119444e35b5fdf15a25a427285650f06f1390e62c75Greg Clayton if (pos != allModules.end()) 120444e35b5fdf15a25a427285650f06f1390e62c75Greg Clayton m = allModules[InputFilename.c_str()]; 121e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton else { 122b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton m = ParseBytecodeFile(InputFilename); 123e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton allModules[InputFilename.c_str()] = m; 124e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton } 125b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton return m; 126e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton} 127e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton 128e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton/// InputFilename is a LLVM bytecode file. Reade this bytecode file and 129b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton/// set corresponding target triplet string. 130b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Claytonvoid 131b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg ClaytonLTO::getTargetTriple(const std::string &InputFilename, 132444e35b5fdf15a25a427285650f06f1390e62c75Greg Clayton std::string &targetTriple) 133444e35b5fdf15a25a427285650f06f1390e62c75Greg Clayton{ 134e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton Module *m = getModule(InputFilename); 135b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton if (m) 136e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton targetTriple = m->getTargetTriple(); 137e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton} 138e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton 139e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton/// InputFilename is a LLVM bytecode file. Read it using bytecode reader. 140e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton/// Collect global functions and symbol names in symbols vector. 141e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton/// Collect external references in references vector. 142ff39f746ebaa3710c44ba49bd9b0a6cf05f60a3fGreg Clayton/// Return LTO_READ_SUCCESS if there is no error. 143b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Claytonenum LTOStatus 144b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg ClaytonLTO::readLLVMObjectFile(const std::string &InputFilename, 145444e35b5fdf15a25a427285650f06f1390e62c75Greg Clayton NameToSymbolMap &symbols, 146444e35b5fdf15a25a427285650f06f1390e62c75Greg Clayton std::set<std::string> &references) 147e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton{ 148e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton Module *m = getModule(InputFilename); 149e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton if (!m) 150e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton return LTO_READ_FAILURE; 151e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton 152e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton // Collect Target info 153e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton getTarget(m); 154ff39f746ebaa3710c44ba49bd9b0a6cf05f60a3fGreg Clayton 155e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton if (!Target) 156b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton return LTO_READ_FAILURE; 157e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton 158e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton // Use mangler to add GlobalPrefix to names to match linker names. 159e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton // FIXME : Instead of hard coding "-" use GlobalPrefix. 160ff39f746ebaa3710c44ba49bd9b0a6cf05f60a3fGreg Clayton Mangler mangler(*m, Target->getTargetAsmInfo()->getGlobalPrefix()); 161e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton modules.push_back(m); 162e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton 163ff39f746ebaa3710c44ba49bd9b0a6cf05f60a3fGreg Clayton for (Module::iterator f = m->begin(), e = m->end(); f != e; ++f) { 164ff39f746ebaa3710c44ba49bd9b0a6cf05f60a3fGreg Clayton 165ff39f746ebaa3710c44ba49bd9b0a6cf05f60a3fGreg Clayton LTOLinkageTypes lt = getLTOLinkageType(f); 166ff39f746ebaa3710c44ba49bd9b0a6cf05f60a3fGreg Clayton 167e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton if (!f->isDeclaration() && lt != LTOInternalLinkage 16836bc5ea5a48c19421d44f559e2165c105657b809Greg Clayton && strncmp (f->getName().c_str(), "llvm.", 5)) { 16936bc5ea5a48c19421d44f559e2165c105657b809Greg Clayton int alignment = ( 16 > f->getAlignment() ? 16 : f->getAlignment()); 17036bc5ea5a48c19421d44f559e2165c105657b809Greg Clayton LLVMSymbol *newSymbol = new LLVMSymbol(lt, f, f->getName(), 17136bc5ea5a48c19421d44f559e2165c105657b809Greg Clayton mangler.getValueName(f), 17236bc5ea5a48c19421d44f559e2165c105657b809Greg Clayton Log2_32(alignment)); 17336bc5ea5a48c19421d44f559e2165c105657b809Greg Clayton symbols[newSymbol->getMangledName()] = newSymbol; 17436bc5ea5a48c19421d44f559e2165c105657b809Greg Clayton allSymbols[newSymbol->getMangledName()] = newSymbol; 17536bc5ea5a48c19421d44f559e2165c105657b809Greg Clayton } 17636bc5ea5a48c19421d44f559e2165c105657b809Greg Clayton 17736bc5ea5a48c19421d44f559e2165c105657b809Greg Clayton // Collect external symbols referenced by this function. 17836bc5ea5a48c19421d44f559e2165c105657b809Greg Clayton for (Function::iterator b = f->begin(), fe = f->end(); b != fe; ++b) 179c86723f0a71f5d929f4543c544d9255da52ea49dHan Ming Ong for (BasicBlock::iterator i = b->begin(), be = b->end(); 18036bc5ea5a48c19421d44f559e2165c105657b809Greg Clayton i != be; ++i) 18136bc5ea5a48c19421d44f559e2165c105657b809Greg Clayton for (unsigned count = 0, total = i->getNumOperands(); 18236bc5ea5a48c19421d44f559e2165c105657b809Greg Clayton count != total; ++count) 18336bc5ea5a48c19421d44f559e2165c105657b809Greg Clayton findExternalRefs(i->getOperand(count), references, mangler); 18436bc5ea5a48c19421d44f559e2165c105657b809Greg Clayton } 18536bc5ea5a48c19421d44f559e2165c105657b809Greg Clayton 18636bc5ea5a48c19421d44f559e2165c105657b809Greg Clayton for (Module::global_iterator v = m->global_begin(), e = m->global_end(); 18736bc5ea5a48c19421d44f559e2165c105657b809Greg Clayton v != e; ++v) { 188ff39f746ebaa3710c44ba49bd9b0a6cf05f60a3fGreg Clayton LTOLinkageTypes lt = getLTOLinkageType(v); 189ff39f746ebaa3710c44ba49bd9b0a6cf05f60a3fGreg Clayton if (!v->isDeclaration() && lt != LTOInternalLinkage 19024bc5d9bfad2a1c562c27e7cf37e1c56d85c45e7Greg Clayton && strncmp (v->getName().c_str(), "llvm.", 5)) { 191ff39f746ebaa3710c44ba49bd9b0a6cf05f60a3fGreg Clayton const TargetData *TD = Target->getTargetData(); 19224bc5d9bfad2a1c562c27e7cf37e1c56d85c45e7Greg Clayton LLVMSymbol *newSymbol = new LLVMSymbol(lt, v, v->getName(), 19324bc5d9bfad2a1c562c27e7cf37e1c56d85c45e7Greg Clayton mangler.getValueName(v), 194a733c04608cc94592a15d27583529588e19db552Greg Clayton TD->getPreferredAlignmentLog(v)); 195b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton symbols[newSymbol->getMangledName()] = newSymbol; 196a733c04608cc94592a15d27583529588e19db552Greg Clayton allSymbols[newSymbol->getMangledName()] = newSymbol; 197b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton 198a733c04608cc94592a15d27583529588e19db552Greg Clayton for (unsigned count = 0, total = v->getNumOperands(); 199b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton count != total; ++count) 200a733c04608cc94592a15d27583529588e19db552Greg Clayton findExternalRefs(v->getOperand(count), references, mangler); 201b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton 202a733c04608cc94592a15d27583529588e19db552Greg Clayton } 203b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton } 204a733c04608cc94592a15d27583529588e19db552Greg Clayton 20524bc5d9bfad2a1c562c27e7cf37e1c56d85c45e7Greg Clayton return LTO_READ_SUCCESS; 20624bc5d9bfad2a1c562c27e7cf37e1c56d85c45e7Greg Clayton} 207b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton 20824bc5d9bfad2a1c562c27e7cf37e1c56d85c45e7Greg Clayton/// Get TargetMachine. 209b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton/// Use module M to find appropriate Target. 21024bc5d9bfad2a1c562c27e7cf37e1c56d85c45e7Greg Claytonvoid 21124bc5d9bfad2a1c562c27e7cf37e1c56d85c45e7Greg ClaytonLTO::getTarget (Module *M) { 21224bc5d9bfad2a1c562c27e7cf37e1c56d85c45e7Greg Clayton 213b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton if (Target) 21424bc5d9bfad2a1c562c27e7cf37e1c56d85c45e7Greg Clayton return; 215b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton 21624bc5d9bfad2a1c562c27e7cf37e1c56d85c45e7Greg Clayton std::string Err; 21724bc5d9bfad2a1c562c27e7cf37e1c56d85c45e7Greg Clayton const TargetMachineRegistry::Entry* March = 218a733c04608cc94592a15d27583529588e19db552Greg Clayton TargetMachineRegistry::getClosestStaticTargetForModule(*M, Err); 219b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton 220a733c04608cc94592a15d27583529588e19db552Greg Clayton if (March == 0) 221b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton return; 222a733c04608cc94592a15d27583529588e19db552Greg Clayton 223a733c04608cc94592a15d27583529588e19db552Greg Clayton // Create target 224a733c04608cc94592a15d27583529588e19db552Greg Clayton std::string Features; 225b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton Target = March->CtorFn(*M, Features); 226a733c04608cc94592a15d27583529588e19db552Greg Clayton} 227b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton 228a733c04608cc94592a15d27583529588e19db552Greg Clayton/// Optimize module M using various IPO passes. Use exportList to 229b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton/// internalize selected symbols. Target platform is selected 230e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton/// based on information available to module M. No new target 231e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton/// features are selected. 232e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Claytonenum LTOStatus 233e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg ClaytonLTO::optimize(Module *M, std::ostream &Out, 234e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton std::vector<const char *> &exportList) 235b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton{ 236e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton // Instantiate the pass manager to organize the passes. 237e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton PassManager Passes; 238e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton 239e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton // Collect Target info 240e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton getTarget(M); 241b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton 242e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton if (!Target) 243e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton return LTO_NO_TARGET; 244e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton 245e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton // Start off with a verification pass. 246e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton Passes.add(createVerifierPass()); 247e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton 248e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton // Add an appropriate TargetData instance for this module... 249e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton Passes.add(new TargetData(*Target->getTargetData())); 250e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton 251e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton // Often if the programmer does not specify proper prototypes for the 252e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton // functions they are calling, they end up calling a vararg version of the 253e4b9c1fb338ee1ada72e6a3c198afb342d68c5c1Greg Clayton // function that does not get a body filled in (the real function has typed 254a733c04608cc94592a15d27583529588e19db552Greg Clayton // arguments). This pass merges the two functions. 255a733c04608cc94592a15d27583529588e19db552Greg Clayton Passes.add(createFunctionResolvingPass()); 256a733c04608cc94592a15d27583529588e19db552Greg Clayton 257a733c04608cc94592a15d27583529588e19db552Greg Clayton // Internalize symbols if export list is nonemty 258a733c04608cc94592a15d27583529588e19db552Greg Clayton if (!exportList.empty()) 259b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton Passes.add(createInternalizePass(exportList)); 260b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton 261b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton // Now that we internalized some globals, see if we can hack on them! 262b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton Passes.add(createGlobalOptimizerPass()); 263b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton 264b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton // Linking modules together can lead to duplicated global constants, only 265b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton // keep one copy of each constant... 266b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton Passes.add(createConstantMergePass()); 267b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton 268b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton // If the -s command line option was specified, strip the symbols out of the 269b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton // resulting program to make it smaller. -s is a GLD option that we are 270b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton // supporting. 271b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton Passes.add(createStripSymbolsPass()); 272b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton 273b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton // Propagate constants at call sites into the functions they call. 274b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton Passes.add(createIPConstantPropagationPass()); 2750c8446cc220c429fb51f8f9864275c8b1c768533Greg Clayton 2760c8446cc220c429fb51f8f9864275c8b1c768533Greg Clayton // Remove unused arguments from functions... 2770c8446cc220c429fb51f8f9864275c8b1c768533Greg Clayton Passes.add(createDeadArgEliminationPass()); 2780c8446cc220c429fb51f8f9864275c8b1c768533Greg Clayton 2790c8446cc220c429fb51f8f9864275c8b1c768533Greg Clayton Passes.add(createFunctionInliningPass()); // Inline small functions 2800c8446cc220c429fb51f8f9864275c8b1c768533Greg Clayton 2810c8446cc220c429fb51f8f9864275c8b1c768533Greg Clayton Passes.add(createPruneEHPass()); // Remove dead EH info 2820c8446cc220c429fb51f8f9864275c8b1c768533Greg Clayton 2830c8446cc220c429fb51f8f9864275c8b1c768533Greg Clayton Passes.add(createGlobalDCEPass()); // Remove dead functions 2840c8446cc220c429fb51f8f9864275c8b1c768533Greg Clayton 2850c8446cc220c429fb51f8f9864275c8b1c768533Greg Clayton // If we didn't decide to inline a function, check to see if we can 2860c8446cc220c429fb51f8f9864275c8b1c768533Greg Clayton // transform it to pass arguments by value instead of by reference. 2870c8446cc220c429fb51f8f9864275c8b1c768533Greg Clayton Passes.add(createArgumentPromotionPass()); 288ff1bbd78581ab2f1e43fbbc8b6e2dc23a9745967Andrew Kaylor 289ff1bbd78581ab2f1e43fbbc8b6e2dc23a9745967Andrew Kaylor // The IPO passes may leave cruft around. Clean up after them. 2900c8446cc220c429fb51f8f9864275c8b1c768533Greg Clayton Passes.add(createInstructionCombiningPass()); 2910c8446cc220c429fb51f8f9864275c8b1c768533Greg Clayton 292b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton Passes.add(createScalarReplAggregatesPass()); // Break up allocas 2930c8446cc220c429fb51f8f9864275c8b1c768533Greg Clayton 294b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton // Run a few AA driven optimizations here and now, to cleanup the code. 29536bc5ea5a48c19421d44f559e2165c105657b809Greg Clayton Passes.add(createGlobalsModRefPass()); // IP alias analysis 2960c8446cc220c429fb51f8f9864275c8b1c768533Greg Clayton 29736bc5ea5a48c19421d44f559e2165c105657b809Greg Clayton Passes.add(createLICMPass()); // Hoist loop invariants 298b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton Passes.add(createLoadValueNumberingPass()); // GVN for load instrs 299b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton Passes.add(createGCSEPass()); // Remove common subexprs 300b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton Passes.add(createDeadStoreEliminationPass()); // Nuke dead stores 301b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton 302b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton // Cleanup and simplify the code after the scalar optimizations. 303b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton Passes.add(createInstructionCombiningPass()); 304b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton 305b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton // Delete basic blocks, which optimization passes may have killed... 306b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton Passes.add(createCFGSimplificationPass()); 307b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton 308b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton // Now that we have optimized the program, discard unreachable functions... 309b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton Passes.add(createGlobalDCEPass()); 310b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton 311b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton // Make sure everything is still good. 3120c8446cc220c429fb51f8f9864275c8b1c768533Greg Clayton Passes.add(createVerifierPass()); 3130c8446cc220c429fb51f8f9864275c8b1c768533Greg Clayton 3140c8446cc220c429fb51f8f9864275c8b1c768533Greg Clayton FunctionPassManager *CodeGenPasses = 3150c8446cc220c429fb51f8f9864275c8b1c768533Greg Clayton new FunctionPassManager(new ExistingModuleProvider(M)); 3160c8446cc220c429fb51f8f9864275c8b1c768533Greg Clayton 317b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton CodeGenPasses->add(new TargetData(*Target->getTargetData())); 318b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton Target->addPassesToEmitFile(*CodeGenPasses, Out, TargetMachine::AssemblyFile, 319b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton true); 320b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton 321b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton // Run our queue of passes all at once now, efficiently. 322b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton Passes.run(*M); 323b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton 324b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton // Run the code generator, if present. 325b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton CodeGenPasses->doInitialization(); 326b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) { 327b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton if (!I->isDeclaration()) 328b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton CodeGenPasses->run(*I); 329b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton } 330b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton CodeGenPasses->doFinalization(); 331b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton 332b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton return LTO_OPT_SUCCESS; 333b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton} 334b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton 335b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton///Link all modules together and optimize them using IPO. Generate 336b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton/// native object file using OutputFilename 337b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton/// Return appropriate LTOStatus. 338b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Claytonenum LTOStatus 339b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg ClaytonLTO::optimizeModules(const std::string &OutputFilename, 340b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton std::vector<const char *> &exportList, 341b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton std::string &targetTriple, 342b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton bool saveTemps, 343b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton const char *FinalOutputFilename) 344b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton{ 345b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton if (modules.empty()) 346b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton return LTO_NO_WORK; 347b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton 348b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton std::ios::openmode io_mode = 349b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton std::ios::out | std::ios::trunc | std::ios::binary; 350b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton std::string *errMsg = NULL; 351b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton Module *bigOne = modules[0]; 352b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton Linker theLinker("LinkTimeOptimizer", bigOne, false); 353b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton for (unsigned i = 1, e = modules.size(); i != e; ++i) 354b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton if (theLinker.LinkModules(bigOne, modules[i], errMsg)) 355b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton return LTO_MODULE_MERGE_FAILURE; 356b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton // all modules have been handed off to the linker. 357b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton modules.clear(); 358b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton 359b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton sys::Path FinalOutputPath(FinalOutputFilename); 360b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton FinalOutputPath.eraseSuffix(); 361b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton 362b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton if (saveTemps) { 363b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton std::string tempFileName(FinalOutputPath.c_str()); 364b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton tempFileName += "0.bc"; 365b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton std::ofstream Out(tempFileName.c_str(), io_mode); 366b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton OStream L(Out); 367b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton WriteBytecodeToFile(bigOne, L); 368b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton } 369b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton 370b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton // Strip leading underscore because it was added to match names 371b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton // seen by linker. 372b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton for (unsigned i = 0, e = exportList.size(); i != e; ++i) { 373b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton const char *name = exportList[i]; 374b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton NameToSymbolMap::iterator itr = allSymbols.find(name); 375b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton if (itr != allSymbols.end()) 376b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton exportList[i] = allSymbols[name]->getName(); 377b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton } 378b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton 379b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton 380b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton std::string ErrMsg; 381b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton sys::Path TempDir = sys::Path::GetTemporaryDirectory(&ErrMsg); 382b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton if (TempDir.isEmpty()) { 383b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton cerr << "lto: " << ErrMsg << "\n"; 384b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton return LTO_WRITE_FAILURE; 385b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton } 386b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton sys::Path tmpAsmFilePath(TempDir); 387b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton if (!tmpAsmFilePath.appendComponent("lto")) { 388b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton cerr << "lto: " << ErrMsg << "\n"; 389b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton TempDir.eraseFromDisk(true); 390b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton return LTO_WRITE_FAILURE; 391b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton } 392b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton if (tmpAsmFilePath.createTemporaryFileOnDisk(&ErrMsg)) { 393b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton cerr << "lto: " << ErrMsg << "\n"; 394b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton TempDir.eraseFromDisk(true); 395a733c04608cc94592a15d27583529588e19db552Greg Clayton return LTO_WRITE_FAILURE; 396a733c04608cc94592a15d27583529588e19db552Greg Clayton } 397a733c04608cc94592a15d27583529588e19db552Greg Clayton sys::RemoveFileOnSignal(tmpAsmFilePath); 398a733c04608cc94592a15d27583529588e19db552Greg Clayton 399a733c04608cc94592a15d27583529588e19db552Greg Clayton std::ofstream asmFile(tmpAsmFilePath.c_str(), io_mode); 400a733c04608cc94592a15d27583529588e19db552Greg Clayton if (!asmFile.is_open() || asmFile.bad()) { 401a733c04608cc94592a15d27583529588e19db552Greg Clayton if (tmpAsmFilePath.exists()) { 402a733c04608cc94592a15d27583529588e19db552Greg Clayton tmpAsmFilePath.eraseFromDisk(); 403a733c04608cc94592a15d27583529588e19db552Greg Clayton TempDir.eraseFromDisk(true); 404a733c04608cc94592a15d27583529588e19db552Greg Clayton } 405a733c04608cc94592a15d27583529588e19db552Greg Clayton return LTO_WRITE_FAILURE; 406a733c04608cc94592a15d27583529588e19db552Greg Clayton } 407a733c04608cc94592a15d27583529588e19db552Greg Clayton 408a733c04608cc94592a15d27583529588e19db552Greg Clayton enum LTOStatus status = optimize(bigOne, asmFile, exportList); 409a733c04608cc94592a15d27583529588e19db552Greg Clayton asmFile.close(); 410a733c04608cc94592a15d27583529588e19db552Greg Clayton if (status != LTO_OPT_SUCCESS) { 411a733c04608cc94592a15d27583529588e19db552Greg Clayton tmpAsmFilePath.eraseFromDisk(); 412a733c04608cc94592a15d27583529588e19db552Greg Clayton TempDir.eraseFromDisk(true); 41324bc5d9bfad2a1c562c27e7cf37e1c56d85c45e7Greg Clayton return status; 41424bc5d9bfad2a1c562c27e7cf37e1c56d85c45e7Greg Clayton } 41524bc5d9bfad2a1c562c27e7cf37e1c56d85c45e7Greg Clayton 41624bc5d9bfad2a1c562c27e7cf37e1c56d85c45e7Greg Clayton if (saveTemps) { 41724bc5d9bfad2a1c562c27e7cf37e1c56d85c45e7Greg Clayton std::string tempFileName(FinalOutputPath.c_str()); 418b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton tempFileName += "1.bc"; 419b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton std::ofstream Out(tempFileName.c_str(), io_mode); 420b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton OStream L(Out); 421b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton WriteBytecodeToFile(bigOne, L); 422b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton } 423b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton 424b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton targetTriple = bigOne->getTargetTriple(); 425b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton 426b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton // Run GCC to assemble and link the program into native code. 427b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton // 4281c4642c6ab741d85c98d4288cf922c9a2ef77007Greg Clayton // Note: 429b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton // We can't just assemble and link the file with the system assembler 430b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton // and linker because we don't know where to put the _start symbol. 431b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton // GCC mysteriously knows how to do it. 432b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton const sys::Path gcc = sys::Program::FindProgramByName("gcc"); 433b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton if (gcc.isEmpty()) { 434b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton tmpAsmFilePath.eraseFromDisk(); 435b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton TempDir.eraseFromDisk(true); 436b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton return LTO_ASM_FAILURE; 437b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton } 438b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton 439b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton std::vector<const char*> args; 440b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton args.push_back(gcc.c_str()); 441b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton args.push_back("-c"); 442b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton args.push_back("-x"); 44336bc5ea5a48c19421d44f559e2165c105657b809Greg Clayton args.push_back("assembler"); 44436bc5ea5a48c19421d44f559e2165c105657b809Greg Clayton args.push_back("-o"); 44536bc5ea5a48c19421d44f559e2165c105657b809Greg Clayton args.push_back(OutputFilename.c_str()); 44636bc5ea5a48c19421d44f559e2165c105657b809Greg Clayton args.push_back(tmpAsmFilePath.c_str()); 44736bc5ea5a48c19421d44f559e2165c105657b809Greg Clayton args.push_back(0); 44836bc5ea5a48c19421d44f559e2165c105657b809Greg Clayton 44936bc5ea5a48c19421d44f559e2165c105657b809Greg Clayton if (sys::Program::ExecuteAndWait(gcc, &args[0], 0, 0, 1, &ErrMsg)) { 45036bc5ea5a48c19421d44f559e2165c105657b809Greg Clayton cerr << "lto: " << ErrMsg << "\n"; 451b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton return LTO_ASM_FAILURE; 452b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton } 453b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton 454b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton tmpAsmFilePath.eraseFromDisk(); 455b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton TempDir.eraseFromDisk(true); 456b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton 457b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton return LTO_OPT_SUCCESS; 458b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton} 459b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton 460b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton/// Unused pure-virtual destructor. Must remain empty. 461b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg ClaytonLinkTimeOptimizer::~LinkTimeOptimizer() {} 462b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton 463b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton/// Destruct LTO. Delete all modules, symbols and target. 464b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg ClaytonLTO::~LTO() { 465b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton 466b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton for (std::vector<Module *>::iterator itr = modules.begin(), e = modules.end(); 467b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton itr != e; ++itr) 468b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton delete *itr; 469b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton 470b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton modules.clear(); 471b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton 472b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton for (NameToSymbolMap::iterator itr = allSymbols.begin(), e = allSymbols.end(); 473b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton itr != e; ++itr) 474b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton delete itr->second; 475b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton 476b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton allSymbols.clear(); 477b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton 478b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton delete Target; 479b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton} 480b72d0f098e45936fa72e26b1a026c603e17e2d6cGreg Clayton