diff options
Diffstat (limited to 'tools/lto')
-rw-r--r-- | tools/lto/LTOModule.cpp | 83 | ||||
-rw-r--r-- | tools/lto/LTOModule.h | 8 |
2 files changed, 55 insertions, 36 deletions
diff --git a/tools/lto/LTOModule.cpp b/tools/lto/LTOModule.cpp index 1c06f27..97e4e54 100644 --- a/tools/lto/LTOModule.cpp +++ b/tools/lto/LTOModule.cpp @@ -204,6 +204,8 @@ void LTOModule::addObjCClass(GlobalVariable *clgv) { const char *symbolName = entry.getKey().data(); info.name = symbolName; info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED; + info.isFunction = false; + info.symbol = clgv; entry.setValue(info); } } @@ -213,11 +215,13 @@ void LTOModule::addObjCClass(GlobalVariable *clgv) { if (objcClassNameFromExpression(c->getOperand(2), className)) { StringSet::value_type &entry = _defines.GetOrCreateValue(className); entry.setValue(1); + NameAndAttributes info; info.name = entry.getKey().data(); - info.attributes = lto_symbol_attributes(LTO_SYMBOL_PERMISSIONS_DATA | - LTO_SYMBOL_DEFINITION_REGULAR | - LTO_SYMBOL_SCOPE_DEFAULT); + info.attributes = LTO_SYMBOL_PERMISSIONS_DATA | + LTO_SYMBOL_DEFINITION_REGULAR | LTO_SYMBOL_SCOPE_DEFAULT; + info.isFunction = false; + info.symbol = clgv; _symbols.push_back(info); } } @@ -242,6 +246,8 @@ void LTOModule::addObjCCategory(GlobalVariable *clgv) { const char *symbolName = entry.getKey().data(); info.name = symbolName; info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED; + info.isFunction = false; + info.symbol = clgv; entry.setValue(info); } @@ -260,6 +266,8 @@ void LTOModule::addObjCClassRef(GlobalVariable *clgv) { const char *symbolName = entry.getKey().data(); info.name = symbolName; info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED; + info.isFunction = false; + info.symbol = clgv; entry.setValue(info); } @@ -332,9 +340,9 @@ void LTOModule::addDefinedSymbol(GlobalValue *def, bool isFunction) { uint32_t attr = align ? CountTrailingZeros_32(def->getAlignment()) : 0; // set permissions part - if (isFunction) + if (isFunction) { attr |= LTO_SYMBOL_PERMISSIONS_CODE; - else { + } else { GlobalVariable *gv = dyn_cast<GlobalVariable>(def); if (gv && gv->isConstant()) attr |= LTO_SYMBOL_PERMISSIONS_RODATA; @@ -366,15 +374,19 @@ void LTOModule::addDefinedSymbol(GlobalValue *def, bool isFunction) { else attr |= LTO_SYMBOL_SCOPE_INTERNAL; - // add to table of symbols - NameAndAttributes info; StringSet::value_type &entry = _defines.GetOrCreateValue(Buffer); entry.setValue(1); + // fill information structure + NameAndAttributes info; StringRef Name = entry.getKey(); info.name = Name.data(); assert(info.name[Name.size()] == '\0'); - info.attributes = (lto_symbol_attributes)attr; + info.attributes = attr; + info.isFunction = isFunction; + info.symbol = def; + + // add to table of symbols _symbols.push_back(info); } @@ -389,13 +401,13 @@ void LTOModule::addAsmGlobalSymbol(const char *name, return; entry.setValue(1); - const char *symbolName = entry.getKey().data(); - uint32_t attr = LTO_SYMBOL_DEFINITION_REGULAR; - attr |= scope; - NameAndAttributes info; - info.name = symbolName; - info.attributes = (lto_symbol_attributes)attr; - _symbols.push_back(info); + + NameAndAttributes &info = _undefines[entry.getKey().data()]; + + if (info.isFunction) + addDefinedFunctionSymbol(cast<Function>(info.symbol)); + else + addDefinedDataSymbol(info.symbol); } /// addAsmGlobalSymbolUndef - Add a global symbol from module-level ASM to the @@ -414,14 +426,16 @@ void LTOModule::addAsmGlobalSymbolUndef(const char *name) { attr |= LTO_SYMBOL_SCOPE_DEFAULT; NameAndAttributes info; info.name = entry.getKey().data(); - info.attributes = (lto_symbol_attributes)attr; + info.attributes = attr; + info.isFunction = false; + info.symbol = 0; entry.setValue(info); } /// addPotentialUndefinedSymbol - Add a symbol which isn't defined just yet to a /// list to be resolved later. -void LTOModule::addPotentialUndefinedSymbol(GlobalValue *decl) { +void LTOModule::addPotentialUndefinedSymbol(GlobalValue *decl, bool isFunc) { // ignore all llvm.* symbols if (decl->getName().startswith("llvm.")) return; @@ -449,6 +463,9 @@ void LTOModule::addPotentialUndefinedSymbol(GlobalValue *decl) { else info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED; + info.isFunction = isFunc; + info.symbol = decl; + entry.setValue(info); } @@ -605,7 +622,7 @@ namespace { } virtual void FinishImpl() {} }; -} +} // end anonymous namespace /// addAsmGlobalSymbols - Add global symbols from module-level ASM to the /// defined or undefined lists. @@ -668,7 +685,7 @@ bool LTOModule::parseSymbols(std::string &errMsg) { // add functions for (Module::iterator f = _module->begin(), e = _module->end(); f != e; ++f) { if (isDeclaration(*f)) - addPotentialUndefinedSymbol(f); + addPotentialUndefinedSymbol(f, true); else addDefinedFunctionSymbol(f); } @@ -677,7 +694,7 @@ bool LTOModule::parseSymbols(std::string &errMsg) { for (Module::global_iterator v = _module->global_begin(), e = _module->global_end(); v != e; ++v) { if (isDeclaration(*v)) - addPotentialUndefinedSymbol(v); + addPotentialUndefinedSymbol(v, false); else addDefinedDataSymbol(v); } @@ -687,24 +704,24 @@ bool LTOModule::parseSymbols(std::string &errMsg) { return true; // add aliases - for (Module::alias_iterator i = _module->alias_begin(), - e = _module->alias_end(); i != e; ++i) { - if (isDeclaration(*i->getAliasedGlobal())) + for (Module::alias_iterator a = _module->alias_begin(), + e = _module->alias_end(); a != e; ++a) { + if (isDeclaration(*a->getAliasedGlobal())) // Is an alias to a declaration. - addPotentialUndefinedSymbol(i); + addPotentialUndefinedSymbol(a, false); else - addDefinedDataSymbol(i); + addDefinedDataSymbol(a); } // make symbols for all undefines - for (StringMap<NameAndAttributes>::iterator it=_undefines.begin(), - e = _undefines.end(); it != e; ++it) { - // if this symbol also has a definition, then don't make an undefine - // because it is a tentative definition - if (_defines.count(it->getKey()) == 0) { - NameAndAttributes info = it->getValue(); - _symbols.push_back(info); - } + for (StringMap<NameAndAttributes>::iterator u =_undefines.begin(), + e = _undefines.end(); u != e; ++u) { + // If this symbol also has a definition, then don't make an undefine because + // it is a tentative definition. + if (_defines.count(u->getKey())) continue; + NameAndAttributes info = u->getValue(); + _symbols.push_back(info); } + return false; } diff --git a/tools/lto/LTOModule.h b/tools/lto/LTOModule.h index 2c52948..e5f6dea 100644 --- a/tools/lto/LTOModule.h +++ b/tools/lto/LTOModule.h @@ -43,8 +43,10 @@ private: typedef llvm::StringMap<uint8_t> StringSet; struct NameAndAttributes { - const char *name; - uint32_t attributes; + const char *name; + uint32_t attributes; + bool isFunction; + llvm::GlobalValue *symbol; }; llvm::OwningPtr<llvm::Module> _module; @@ -134,7 +136,7 @@ private: /// addPotentialUndefinedSymbol - Add a symbol which isn't defined just yet /// to a list to be resolved later. - void addPotentialUndefinedSymbol(llvm::GlobalValue *dcl); + void addPotentialUndefinedSymbol(llvm::GlobalValue *dcl, bool isFunc); /// addDefinedSymbol - Add a defined symbol to the list. void addDefinedSymbol(llvm::GlobalValue *def, bool isFunction); |