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