diff options
Diffstat (limited to 'tools/lto')
-rw-r--r-- | tools/lto/LTOCodeGenerator.cpp | 38 | ||||
-rw-r--r-- | tools/lto/LTOModule.cpp | 83 | ||||
-rw-r--r-- | tools/lto/LTOModule.h | 3 | ||||
-rw-r--r-- | tools/lto/Makefile | 4 | ||||
-rw-r--r-- | tools/lto/lto.cpp | 14 | ||||
-rw-r--r-- | tools/lto/lto.exports | 1 |
6 files changed, 102 insertions, 41 deletions
diff --git a/tools/lto/LTOCodeGenerator.cpp b/tools/lto/LTOCodeGenerator.cpp index 671348c..adb7102 100644 --- a/tools/lto/LTOCodeGenerator.cpp +++ b/tools/lto/LTOCodeGenerator.cpp @@ -39,9 +39,11 @@ #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/StandardPasses.h" #include "llvm/Support/SystemUtils.h" -#include "llvm/System/Host.h" -#include "llvm/System/Program.h" -#include "llvm/System/Signals.h" +#include "llvm/Support/ToolOutputFile.h" +#include "llvm/Support/Host.h" +#include "llvm/Support/Program.h" +#include "llvm/Support/Signals.h" +#include "llvm/Support/system_error.h" #include "llvm/Config/config.h" #include <cstdlib> #include <unistd.h> @@ -183,7 +185,7 @@ const void* LTOCodeGenerator::compile(size_t* length, std::string& errMsg) { // make unique temp .s file to put generated assembly code sys::Path uniqueAsmPath("lto-llvm.s"); - if ( uniqueAsmPath.createTemporaryFileOnDisk(true, &errMsg) ) + if ( uniqueAsmPath.createTemporaryFileOnDisk(false, &errMsg) ) return NULL; sys::RemoveFileOnSignal(uniqueAsmPath); @@ -208,7 +210,7 @@ const void* LTOCodeGenerator::compile(size_t* length, std::string& errMsg) // make unique temp .o file to put generated object file sys::PathWithStatus uniqueObjPath("lto-llvm.o"); - if ( uniqueObjPath.createTemporaryFileOnDisk(true, &errMsg) ) { + if ( uniqueObjPath.createTemporaryFileOnDisk(false, &errMsg) ) { uniqueAsmPath.eraseFromDisk(); return NULL; } @@ -220,9 +222,12 @@ const void* LTOCodeGenerator::compile(size_t* length, std::string& errMsg) if ( !asmResult ) { // remove old buffer if compile() called twice delete _nativeObjectFile; - + // read .o file into memory buffer - _nativeObjectFile = MemoryBuffer::getFile(uniqueObjStr.c_str(),&errMsg); + OwningPtr<MemoryBuffer> BuffPtr; + if (error_code ec = MemoryBuffer::getFile(uniqueObjStr.c_str(),BuffPtr)) + errMsg = ec.message(); + _nativeObjectFile = BuffPtr.take(); } // remove temp files @@ -342,21 +347,34 @@ void LTOCodeGenerator::applyScopeRestrictions() { // mark which symbols can not be internalized if (!_mustPreserveSymbols.empty()) { - MCContext Context(*_target->getMCAsmInfo()); + MCContext Context(*_target->getMCAsmInfo(), NULL); Mangler mangler(Context, *_target->getTargetData()); std::vector<const char*> mustPreserveList; + SmallString<64> Buffer; for (Module::iterator f = mergedModule->begin(), e = mergedModule->end(); f != e; ++f) { + Buffer.clear(); + mangler.getNameWithPrefix(Buffer, f, false); if (!f->isDeclaration() && - _mustPreserveSymbols.count(mangler.getNameWithPrefix(f))) + _mustPreserveSymbols.count(Buffer)) mustPreserveList.push_back(::strdup(f->getNameStr().c_str())); } for (Module::global_iterator v = mergedModule->global_begin(), e = mergedModule->global_end(); v != e; ++v) { + Buffer.clear(); + mangler.getNameWithPrefix(Buffer, v, false); if (!v->isDeclaration() && - _mustPreserveSymbols.count(mangler.getNameWithPrefix(v))) + _mustPreserveSymbols.count(Buffer)) mustPreserveList.push_back(::strdup(v->getNameStr().c_str())); } + for (Module::alias_iterator a = mergedModule->alias_begin(), + e = mergedModule->alias_end(); a != e; ++a) { + Buffer.clear(); + mangler.getNameWithPrefix(Buffer, a, false); + if (!a->isDeclaration() && + _mustPreserveSymbols.count(Buffer)) + mustPreserveList.push_back(::strdup(a->getNameStr().c_str())); + } passes.add(createInternalizePass(mustPreserveList)); } diff --git a/tools/lto/LTOModule.cpp b/tools/lto/LTOModule.cpp index c7cd585..8562f74 100644 --- a/tools/lto/LTOModule.cpp +++ b/tools/lto/LTOModule.cpp @@ -23,9 +23,10 @@ #include "llvm/Support/SystemUtils.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/MathExtras.h" -#include "llvm/System/Host.h" -#include "llvm/System/Path.h" -#include "llvm/System/Process.h" +#include "llvm/Support/Host.h" +#include "llvm/Support/Path.h" +#include "llvm/Support/Process.h" +#include "llvm/Support/system_error.h" #include "llvm/Target/Mangler.h" #include "llvm/Target/SubtargetFeature.h" #include "llvm/MC/MCAsmInfo.h" @@ -56,23 +57,18 @@ bool LTOModule::isBitcodeFileForTarget(const void *mem, size_t length, bool LTOModule::isBitcodeFileForTarget(const char *path, const char *triplePrefix) { - MemoryBuffer *buffer = MemoryBuffer::getFile(path); - if (buffer == NULL) + OwningPtr<MemoryBuffer> buffer; + if (MemoryBuffer::getFile(path, buffer)) return false; - return isTargetMatch(buffer, triplePrefix); + return isTargetMatch(buffer.take(), triplePrefix); } // Takes ownership of buffer. bool LTOModule::isTargetMatch(MemoryBuffer *buffer, const char *triplePrefix) { - OwningPtr<Module> m(getLazyBitcodeModule(buffer, getGlobalContext())); - // On success, m owns buffer and both are deleted at end of this method. - if (!m) { - delete buffer; - return false; - } - std::string actualTarget = m->getTargetTriple(); - return (strncmp(actualTarget.c_str(), triplePrefix, - strlen(triplePrefix)) == 0); + std::string Triple = getBitcodeTargetTriple(buffer, getGlobalContext()); + delete buffer; + return (strncmp(Triple.c_str(), triplePrefix, + strlen(triplePrefix)) == 0); } @@ -83,9 +79,22 @@ LTOModule::LTOModule(Module *m, TargetMachine *t) LTOModule *LTOModule::makeLTOModule(const char *path, std::string &errMsg) { - OwningPtr<MemoryBuffer> buffer(MemoryBuffer::getFile(path, &errMsg)); - if (!buffer) + OwningPtr<MemoryBuffer> buffer; + if (error_code ec = MemoryBuffer::getFile(path, buffer)) { + errMsg = ec.message(); return NULL; + } + return makeLTOModule(buffer.get(), errMsg); +} + +LTOModule *LTOModule::makeLTOModule(int fd, const char *path, + off_t size, + std::string &errMsg) { + OwningPtr<MemoryBuffer> buffer; + if (error_code ec = MemoryBuffer::getOpenFile(fd, path, buffer, size)) { + errMsg = ec.message(); + return NULL; + } return makeLTOModule(buffer.get(), errMsg); } @@ -306,8 +315,14 @@ void LTOModule::addDefinedSymbol(GlobalValue *def, Mangler &mangler, if (def->getName().startswith("llvm.")) return; + // ignore available_externally + if (def->hasAvailableExternallyLinkage()) + return; + // string is owned by _defines - const char *symbolName = ::strdup(mangler.getNameWithPrefix(def).c_str()); + SmallString<64> Buffer; + mangler.getNameWithPrefix(Buffer, def, false); + const char *symbolName = ::strdup(Buffer.c_str()); // set alignment part log2() can have rounding errors uint32_t align = def->getAlignment(); @@ -325,24 +340,26 @@ void LTOModule::addDefinedSymbol(GlobalValue *def, Mangler &mangler, } // set definition part - if (def->hasWeakLinkage() || def->hasLinkOnceLinkage()) { + if (def->hasWeakLinkage() || def->hasLinkOnceLinkage() || + def->hasLinkerPrivateWeakLinkage() || + def->hasLinkerPrivateWeakDefAutoLinkage()) attr |= LTO_SYMBOL_DEFINITION_WEAK; - } - else if (def->hasCommonLinkage()) { + else if (def->hasCommonLinkage()) attr |= LTO_SYMBOL_DEFINITION_TENTATIVE; - } - else { + else attr |= LTO_SYMBOL_DEFINITION_REGULAR; - } // set scope part if (def->hasHiddenVisibility()) attr |= LTO_SYMBOL_SCOPE_HIDDEN; else if (def->hasProtectedVisibility()) attr |= LTO_SYMBOL_SCOPE_PROTECTED; - else if (def->hasExternalLinkage() || def->hasWeakLinkage() - || def->hasLinkOnceLinkage() || def->hasCommonLinkage()) + else if (def->hasExternalLinkage() || def->hasWeakLinkage() || + def->hasLinkOnceLinkage() || def->hasCommonLinkage() || + def->hasLinkerPrivateWeakLinkage()) attr |= LTO_SYMBOL_SCOPE_DEFAULT; + else if (def->hasLinkerPrivateWeakDefAutoLinkage()) + attr |= LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN; else attr |= LTO_SYMBOL_SCOPE_INTERNAL; @@ -380,7 +397,8 @@ void LTOModule::addPotentialUndefinedSymbol(GlobalValue *decl, if (isa<GlobalAlias>(decl)) return; - std::string name = mangler.getNameWithPrefix(decl); + SmallString<64> name; + mangler.getNameWithPrefix(name, decl, false); // we already have the symbol if (_undefines.find(name) != _undefines.end()) @@ -426,7 +444,7 @@ void LTOModule::lazyParseSymbols() { _symbolsParsed = true; // Use mangler to add GlobalPrefix to names to match linker names. - MCContext Context(*_target->getMCAsmInfo()); + MCContext Context(*_target->getMCAsmInfo(), NULL); Mangler mangler(Context, *_target->getTargetData()); // add functions @@ -472,6 +490,15 @@ void LTOModule::lazyParseSymbols() { pos = inlineAsm.find(glbl, pend); } + // add aliases + for (Module::alias_iterator i = _module->alias_begin(), + e = _module->alias_end(); i != e; ++i) { + if (i->isDeclaration()) + addPotentialUndefinedSymbol(i, mangler); + else + addDefinedDataSymbol(i, mangler); + } + // make symbols for all undefines for (StringMap<NameAndAttributes>::iterator it=_undefines.begin(); it != _undefines.end(); ++it) { diff --git a/tools/lto/LTOModule.h b/tools/lto/LTOModule.h index a19acc0..1794d81 100644 --- a/tools/lto/LTOModule.h +++ b/tools/lto/LTOModule.h @@ -51,6 +51,9 @@ struct LTOModule { static LTOModule* makeLTOModule(const char* path, std::string& errMsg); + static LTOModule* makeLTOModule(int fd, const char *path, + off_t size, + std::string& errMsg); static LTOModule* makeLTOModule(const void* mem, size_t length, std::string& errMsg); diff --git a/tools/lto/Makefile b/tools/lto/Makefile index e157a4c..294c81b 100644 --- a/tools/lto/Makefile +++ b/tools/lto/Makefile @@ -24,6 +24,10 @@ LINK_COMPONENTS := $(TARGETS_TO_BUILD) ipo scalaropts linker bitreader bitwriter include $(LEVEL)/Makefile.common +ifdef LLVM_VERSION_INFO +CXX.Flags += -DLLVM_VERSION_INFO='"$(LLVM_VERSION_INFO)"' +endif + ifeq ($(HOST_OS),Darwin) # Special hack to allow libLTO to have an offset version number. ifdef LLVM_LTO_VERSION_OFFSET diff --git a/tools/lto/lto.cpp b/tools/lto/lto.cpp index 3d7ef0a..7d4871d 100644 --- a/tools/lto/lto.cpp +++ b/tools/lto/lto.cpp @@ -91,6 +91,14 @@ lto_module_t lto_module_create(const char* path) return LTOModule::makeLTOModule(path, sLastErrorString); } +// +// loads an object file from disk +// returns NULL on error (check lto_get_error_message() for details) +// +lto_module_t lto_module_create_from_fd(int fd, const char *path, off_t size) +{ + return LTOModule::makeLTOModule(fd, path, size, sLastErrorString); +} // // loads an object file from memory @@ -132,7 +140,7 @@ void lto_module_set_target_triple(lto_module_t mod, const char *triple) // // returns the number of symbols in the object module // -uint32_t lto_module_get_num_symbols(lto_module_t mod) +unsigned int lto_module_get_num_symbols(lto_module_t mod) { return mod->getSymbolCount(); } @@ -140,7 +148,7 @@ uint32_t lto_module_get_num_symbols(lto_module_t mod) // // returns the name of the ith symbol in the object module // -const char* lto_module_get_symbol_name(lto_module_t mod, uint32_t index) +const char* lto_module_get_symbol_name(lto_module_t mod, unsigned int index) { return mod->getSymbolName(index); } @@ -150,7 +158,7 @@ const char* lto_module_get_symbol_name(lto_module_t mod, uint32_t index) // returns the attributes of the ith symbol in the object module // lto_symbol_attributes lto_module_get_symbol_attribute(lto_module_t mod, - uint32_t index) + unsigned int index) { return mod->getSymbolAttributes(index); } diff --git a/tools/lto/lto.exports b/tools/lto/lto.exports index 4dbf760..a374091 100644 --- a/tools/lto/lto.exports +++ b/tools/lto/lto.exports @@ -1,6 +1,7 @@ lto_get_error_message lto_get_version lto_module_create +lto_module_create_from_fd lto_module_create_from_memory lto_module_get_num_symbols lto_module_get_symbol_attribute |