LTOModule.cpp revision f0d286b77fe40017192b527e5cc5d87974093d54
177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik//===-LTOModule.cpp - LLVM Link Time Optimizer ----------------------------===// 277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik// 377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik// The LLVM Compiler Infrastructure 477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik// 577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik// This file is distributed under the University of Illinois Open Source 677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik// License. See LICENSE.TXT for details. 777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik// 877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik//===----------------------------------------------------------------------===// 977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik// 1077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik// This file implements the Link Time Optimization library. This library is 1177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik// intended to be used by linker to optimize code at link time. 1277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik// 1377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik//===----------------------------------------------------------------------===// 1477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 15ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik#include "LTOModule.h" 16ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik 1777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik#include "llvm/Module.h" 1877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik#include "llvm/ModuleProvider.h" 19ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik#include "llvm/ADT/OwningPtr.h" 2077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik#include "llvm/Bitcode/ReaderWriter.h" 2177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik#include "llvm/Support/SystemUtils.h" 2277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik#include "llvm/Support/Mangler.h" 2377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik#include "llvm/Support/MemoryBuffer.h" 24ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik#include "llvm/Support/MathExtras.h" 2577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik#include "llvm/System/Path.h" 2690dcff71902ad0d3b3d92b26cce2b9b11bea7ff8Nick Kledzik#include "llvm/System/Process.h" 27604a818463b9a7797f8e2806d6c192949b490300Bill Wendling#include "llvm/Target/SubtargetFeature.h" 2877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik#include "llvm/Target/TargetMachine.h" 2977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik#include "llvm/Target/TargetMachineRegistry.h" 3077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik#include "llvm/Target/TargetAsmInfo.h" 3177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 3277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik#include <fstream> 3377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 3477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzikusing namespace llvm; 3577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 3677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzikbool LTOModule::isBitcodeFile(const void* mem, size_t length) 3777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik{ 3877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik return ( llvm::sys::IdentifyFileType((char*)mem, length) 3977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik == llvm::sys::Bitcode_FileType ); 4077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 4177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 4277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzikbool LTOModule::isBitcodeFile(const char* path) 4377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik{ 4477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik return llvm::sys::Path(path).isBitcodeFile(); 4577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 4677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 47038112a4e0a9afd656f415ab397a230ae5921627Chris Lattnerbool LTOModule::isBitcodeFileForTarget(const void* mem, size_t length, 48038112a4e0a9afd656f415ab397a230ae5921627Chris Lattner const char* triplePrefix) 4977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik{ 5090dcff71902ad0d3b3d92b26cce2b9b11bea7ff8Nick Kledzik MemoryBuffer* buffer = makeBuffer(mem, length); 51ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik if ( buffer == NULL ) 52ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik return false; 53ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik return isTargetMatch(buffer, triplePrefix); 5477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 5577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 56ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik 5777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzikbool LTOModule::isBitcodeFileForTarget(const char* path, 58038112a4e0a9afd656f415ab397a230ae5921627Chris Lattner const char* triplePrefix) 5977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik{ 60038112a4e0a9afd656f415ab397a230ae5921627Chris Lattner MemoryBuffer *buffer = MemoryBuffer::getFile(path); 61038112a4e0a9afd656f415ab397a230ae5921627Chris Lattner if (buffer == NULL) 62ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik return false; 63ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik return isTargetMatch(buffer, triplePrefix); 64ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik} 65ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik 66ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik// takes ownership of buffer 67ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzikbool LTOModule::isTargetMatch(MemoryBuffer* buffer, const char* triplePrefix) 68ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik{ 69ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik OwningPtr<ModuleProvider> mp(getBitcodeModuleProvider(buffer)); 70ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik // on success, mp owns buffer and both are deleted at end of this method 71ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik if ( !mp ) { 72ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik delete buffer; 73ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik return false; 7477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik } 75ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik std::string actualTarget = mp->getModule()->getTargetTriple(); 76ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik return ( strncmp(actualTarget.c_str(), triplePrefix, 77ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik strlen(triplePrefix)) == 0); 7877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 7977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 8077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 8177595fc35642f990bfc5ad05b8e68d4056695ecaNick KledzikLTOModule::LTOModule(Module* m, TargetMachine* t) 8277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik : _module(m), _target(t), _symbolsParsed(false) 8377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik{ 8477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 8577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 86ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick KledzikLTOModule* LTOModule::makeLTOModule(const char* path, std::string& errMsg) 8777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik{ 88038112a4e0a9afd656f415ab397a230ae5921627Chris Lattner OwningPtr<MemoryBuffer> buffer(MemoryBuffer::getFile(path, &errMsg)); 89ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik if ( !buffer ) 90ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik return NULL; 91ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik return makeLTOModule(buffer.get(), errMsg); 9277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 9377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 946b89d928ed86f494964841b95c0f69b89550e873Nick Kledzik/// makeBuffer - create a MemoryBuffer from a memory range. 956b89d928ed86f494964841b95c0f69b89550e873Nick Kledzik/// MemoryBuffer requires the byte past end of the buffer to be a zero. 966b89d928ed86f494964841b95c0f69b89550e873Nick Kledzik/// We might get lucky and already be that way, otherwise make a copy. 976b89d928ed86f494964841b95c0f69b89550e873Nick Kledzik/// Also if next byte is on a different page, don't assume it is readable. 9890dcff71902ad0d3b3d92b26cce2b9b11bea7ff8Nick KledzikMemoryBuffer* LTOModule::makeBuffer(const void* mem, size_t length) 9990dcff71902ad0d3b3d92b26cce2b9b11bea7ff8Nick Kledzik{ 100ed185d6e967456ebb35acf5e7e2f9f80d3a8b11aNick Kledzik const char* startPtr = (char*)mem; 101ed185d6e967456ebb35acf5e7e2f9f80d3a8b11aNick Kledzik const char* endPtr = startPtr+length; 102ed185d6e967456ebb35acf5e7e2f9f80d3a8b11aNick Kledzik if ( (((uintptr_t)endPtr & (sys::Process::GetPageSize()-1)) == 0) 103ed185d6e967456ebb35acf5e7e2f9f80d3a8b11aNick Kledzik || (*endPtr != 0) ) 104ed185d6e967456ebb35acf5e7e2f9f80d3a8b11aNick Kledzik return MemoryBuffer::getMemBufferCopy(startPtr, endPtr); 105ed185d6e967456ebb35acf5e7e2f9f80d3a8b11aNick Kledzik else 106ed185d6e967456ebb35acf5e7e2f9f80d3a8b11aNick Kledzik return MemoryBuffer::getMemBuffer(startPtr, endPtr); 10790dcff71902ad0d3b3d92b26cce2b9b11bea7ff8Nick Kledzik} 10890dcff71902ad0d3b3d92b26cce2b9b11bea7ff8Nick Kledzik 10990dcff71902ad0d3b3d92b26cce2b9b11bea7ff8Nick Kledzik 110ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick KledzikLTOModule* LTOModule::makeLTOModule(const void* mem, size_t length, 111ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik std::string& errMsg) 112ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik{ 11390dcff71902ad0d3b3d92b26cce2b9b11bea7ff8Nick Kledzik OwningPtr<MemoryBuffer> buffer(makeBuffer(mem, length)); 114ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik if ( !buffer ) 115ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik return NULL; 116ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik return makeLTOModule(buffer.get(), errMsg); 117ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik} 11877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 119e4242548976c04183a532695666803fb6a40ba06Bill Wendling/// getFeatureString - Return a string listing the features associated with the 120e4242548976c04183a532695666803fb6a40ba06Bill Wendling/// target triple. 121e4242548976c04183a532695666803fb6a40ba06Bill Wendling/// 122e4242548976c04183a532695666803fb6a40ba06Bill Wendling/// FIXME: This is an inelegant way of specifying the features of a 123e4242548976c04183a532695666803fb6a40ba06Bill Wendling/// subtarget. It would be better if we could encode this information into the 124e4242548976c04183a532695666803fb6a40ba06Bill Wendling/// IR. See <rdar://5972456>. 125e4242548976c04183a532695666803fb6a40ba06Bill Wendlingstd::string getFeatureString(const char *TargetTriple) { 126e4242548976c04183a532695666803fb6a40ba06Bill Wendling SubtargetFeatures Features; 127e4242548976c04183a532695666803fb6a40ba06Bill Wendling 128e4242548976c04183a532695666803fb6a40ba06Bill Wendling if (strncmp(TargetTriple, "powerpc-apple-", 14) == 0) { 129e4242548976c04183a532695666803fb6a40ba06Bill Wendling Features.AddFeature("altivec", true); 130e4242548976c04183a532695666803fb6a40ba06Bill Wendling } else if (strncmp(TargetTriple, "powerpc64-apple-", 16) == 0) { 131e4242548976c04183a532695666803fb6a40ba06Bill Wendling Features.AddFeature("64bit", true); 132e4242548976c04183a532695666803fb6a40ba06Bill Wendling Features.AddFeature("altivec", true); 133e4242548976c04183a532695666803fb6a40ba06Bill Wendling } 134e4242548976c04183a532695666803fb6a40ba06Bill Wendling 135e4242548976c04183a532695666803fb6a40ba06Bill Wendling return Features.getString(); 136e4242548976c04183a532695666803fb6a40ba06Bill Wendling} 137e4242548976c04183a532695666803fb6a40ba06Bill Wendling 138ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick KledzikLTOModule* LTOModule::makeLTOModule(MemoryBuffer* buffer, std::string& errMsg) 13977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik{ 140ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik // parse bitcode buffer 141ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik OwningPtr<Module> m(ParseBitcodeFile(buffer, &errMsg)); 142ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik if ( !m ) 143ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik return NULL; 144ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik // find machine architecture for this module 145ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik const TargetMachineRegistry::entry* march = 146ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik TargetMachineRegistry::getClosestStaticTargetForModule(*m, errMsg); 147604a818463b9a7797f8e2806d6c192949b490300Bill Wendling 148ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik if ( march == NULL ) 149ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik return NULL; 150604a818463b9a7797f8e2806d6c192949b490300Bill Wendling 151ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik // construct LTModule, hand over ownership of module and target 152e4242548976c04183a532695666803fb6a40ba06Bill Wendling std::string FeatureStr = getFeatureString(m->getTargetTriple().c_str()); 153e4242548976c04183a532695666803fb6a40ba06Bill Wendling TargetMachine* target = march->CtorFn(*m, FeatureStr); 154ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik return new LTOModule(m.take(), target); 15577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 15677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 157ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik 158ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzikconst char* LTOModule::getTargetTriple() 15977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik{ 160ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik return _module->getTargetTriple().c_str(); 161ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik} 162ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik 163ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzikvoid LTOModule::addDefinedFunctionSymbol(Function* f, Mangler &mangler) 164ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik{ 165ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik // add to list of defined symbols 166ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik addDefinedSymbol(f, mangler, true); 167ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik 168ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik // add external symbols referenced by this function. 169ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik for (Function::iterator b = f->begin(); b != f->end(); ++b) { 170ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik for (BasicBlock::iterator i = b->begin(); i != b->end(); ++i) { 171ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik for (unsigned count = 0, total = i->getNumOperands(); 172ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik count != total; ++count) { 173ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik findExternalRefs(i->getOperand(count), mangler); 17477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik } 17577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik } 17677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik } 17777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 17877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 179ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzikvoid LTOModule::addDefinedDataSymbol(GlobalValue* v, Mangler &mangler) 180ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik{ 181ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik // add to list of defined symbols 182ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik addDefinedSymbol(v, mangler, false); 18377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 184ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik // add external symbols referenced by this data. 1859178a65263bb1f00bb52a53e4e371f62db27d3bbNick Kledzik for (unsigned count = 0, total = v->getNumOperands(); 186ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik count != total; ++count) { 187ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik findExternalRefs(v->getOperand(count), mangler); 188ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik } 18977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 19077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 191ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik 19277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzikvoid LTOModule::addDefinedSymbol(GlobalValue* def, Mangler &mangler, 19377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik bool isFunction) 19477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik{ 195ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik // string is owned by _defines 19677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik const char* symbolName = ::strdup(mangler.getValueName(def).c_str()); 19777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 19877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik // set alignment part log2() can have rounding errors 19977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik uint32_t align = def->getAlignment(); 200ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik uint32_t attr = align ? CountTrailingZeros_32(def->getAlignment()) : 0; 20177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 20277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik // set permissions part 20377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik if ( isFunction ) 20477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik attr |= LTO_SYMBOL_PERMISSIONS_CODE; 20577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik else { 20677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik GlobalVariable* gv = dyn_cast<GlobalVariable>(def); 20777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik if ( (gv != NULL) && gv->isConstant() ) 20877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik attr |= LTO_SYMBOL_PERMISSIONS_RODATA; 20977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik else 21077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik attr |= LTO_SYMBOL_PERMISSIONS_DATA; 21177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik } 21277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 21377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik // set definition part 21477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik if ( def->hasWeakLinkage() || def->hasLinkOnceLinkage() ) { 215ed1ec3aa6b646a47943fdbdf6148c342f0b5a31fDale Johannesen attr |= LTO_SYMBOL_DEFINITION_WEAK; 21677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik } 2176a6f2dda36f2cff5cc97a2ffe0307da7b330a8b0Dale Johannesen else if ( def->hasCommonLinkage()) { 2186a6f2dda36f2cff5cc97a2ffe0307da7b330a8b0Dale Johannesen attr |= LTO_SYMBOL_DEFINITION_TENTATIVE; 2196a6f2dda36f2cff5cc97a2ffe0307da7b330a8b0Dale Johannesen } 22077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik else { 22177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik attr |= LTO_SYMBOL_DEFINITION_REGULAR; 22277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik } 22377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 22477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik // set scope part 22577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik if ( def->hasHiddenVisibility() ) 22677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik attr |= LTO_SYMBOL_SCOPE_HIDDEN; 227f0d286b77fe40017192b527e5cc5d87974093d54Devang Patel else if ( def->hasExternalLinkage() || def->hasWeakLinkage() 228f0d286b77fe40017192b527e5cc5d87974093d54Devang Patel || def->hasLinkOnceLinkage() ) 22977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik attr |= LTO_SYMBOL_SCOPE_DEFAULT; 23077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik else 23177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik attr |= LTO_SYMBOL_SCOPE_INTERNAL; 23277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 23377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik // add to table of symbols 23477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik NameAndAttributes info; 23577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik info.name = symbolName; 23677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik info.attributes = (lto_symbol_attributes)attr; 23777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik _symbols.push_back(info); 23877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik _defines[info.name] = 1; 23977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 24077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 24177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 242ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzikvoid LTOModule::addPotentialUndefinedSymbol(GlobalValue* decl, Mangler &mangler) 243ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik{ 244ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik const char* name = mangler.getValueName(decl).c_str(); 24577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik // ignore all llvm.* symbols 24677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik if ( strncmp(name, "llvm.", 5) != 0 ) { 24777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik _undefines[name] = 1; 24877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik } 24977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 25077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 25177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 25277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 25377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik// Find exeternal symbols referenced by VALUE. This is a recursive function. 25477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzikvoid LTOModule::findExternalRefs(Value* value, Mangler &mangler) { 25577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 25677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik if (GlobalValue* gv = dyn_cast<GlobalValue>(value)) { 25777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik if ( !gv->hasExternalLinkage() ) 258ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik addPotentialUndefinedSymbol(gv, mangler); 259ed185d6e967456ebb35acf5e7e2f9f80d3a8b11aNick Kledzik // If this is a variable definition, do not recursively process 260ed185d6e967456ebb35acf5e7e2f9f80d3a8b11aNick Kledzik // initializer. It might contain a reference to this variable 261ed185d6e967456ebb35acf5e7e2f9f80d3a8b11aNick Kledzik // and cause an infinite loop. The initializer will be 262ed185d6e967456ebb35acf5e7e2f9f80d3a8b11aNick Kledzik // processed in addDefinedDataSymbol(). 263ed185d6e967456ebb35acf5e7e2f9f80d3a8b11aNick Kledzik return; 26477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik } 265ed185d6e967456ebb35acf5e7e2f9f80d3a8b11aNick Kledzik 26677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik // GlobalValue, even with InternalLinkage type, may have operands with 26777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik // ExternalLinkage type. Do not ignore these operands. 26877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik if (Constant* c = dyn_cast<Constant>(value)) { 26977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik // Handle ConstantExpr, ConstantStruct, ConstantArry etc.. 27077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik for (unsigned i = 0, e = c->getNumOperands(); i != e; ++i) 27177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik findExternalRefs(c->getOperand(i), mangler); 27277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik } 27377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 27477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 275ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzikvoid LTOModule::lazyParseSymbols() 27677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik{ 27777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik if ( !_symbolsParsed ) { 27877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik _symbolsParsed = true; 27977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 28077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik // Use mangler to add GlobalPrefix to names to match linker names. 28177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik Mangler mangler(*_module, _target->getTargetAsmInfo()->getGlobalPrefix()); 28277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 28377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik // add functions 28477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik for (Module::iterator f = _module->begin(); f != _module->end(); ++f) { 285ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik if ( f->isDeclaration() ) 286ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik addPotentialUndefinedSymbol(f, mangler); 287ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik else 288ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik addDefinedFunctionSymbol(f, mangler); 28977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik } 29077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 29177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik // add data 29277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik for (Module::global_iterator v = _module->global_begin(), 29377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik e = _module->global_end(); v != e; ++v) { 294ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik if ( v->isDeclaration() ) 295ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik addPotentialUndefinedSymbol(v, mangler); 296ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik else 297ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik addDefinedDataSymbol(v, mangler); 29877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik } 29977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 30077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik // make symbols for all undefines 30177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik for (StringSet::iterator it=_undefines.begin(); 30277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik it != _undefines.end(); ++it) { 30377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik // if this symbol also has a definition, then don't make an undefine 30477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik // because it is a tentative definition 305ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik if ( _defines.count(it->getKeyData(), it->getKeyData()+ 306ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik it->getKeyLength()) == 0 ) { 30777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik NameAndAttributes info; 30877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik info.name = it->getKeyData(); 30977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED; 31077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik _symbols.push_back(info); 31177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik } 31277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik } 313ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik } 314ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik} 315ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik 316ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik 317ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzikuint32_t LTOModule::getSymbolCount() 318ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik{ 319ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik lazyParseSymbols(); 32077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik return _symbols.size(); 32177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 32277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 32377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 32477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledziklto_symbol_attributes LTOModule::getSymbolAttributes(uint32_t index) 32577595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik{ 326ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik lazyParseSymbols(); 32777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik if ( index < _symbols.size() ) 32877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik return _symbols[index].attributes; 32977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik else 33077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik return lto_symbol_attributes(0); 33177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 33277595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 33377595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzikconst char* LTOModule::getSymbolName(uint32_t index) 33477595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik{ 335ef194ed74033eba099f4f391ffdfc176f9aa6f26Nick Kledzik lazyParseSymbols(); 33677595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik if ( index < _symbols.size() ) 33777595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik return _symbols[index].name; 33877595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik else 33977595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik return NULL; 34077595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik} 34177595fc35642f990bfc5ad05b8e68d4056695ecaNick Kledzik 342