diff --git a/include/llvm/LTO/LTOModule.h b/include/llvm/LTO/LTOModule.h index 8208b2fb260..c43846a6405 100644 --- a/include/llvm/LTO/LTOModule.h +++ b/include/llvm/LTO/LTOModule.h @@ -16,10 +16,10 @@ #include "llvm-c/lto.h" #include "llvm/ADT/StringMap.h" -#include "llvm/IR/Mangler.h" #include "llvm/IR/Module.h" #include "llvm/MC/MCContext.h" #include "llvm/MC/MCObjectFileInfo.h" +#include "llvm/Object/IRObjectFile.h" #include "llvm/Target/TargetMachine.h" #include #include @@ -46,9 +46,8 @@ private: const GlobalValue *symbol; }; - std::unique_ptr _module; + std::unique_ptr IRFile; std::unique_ptr _target; - MCObjectFileInfo ObjFileInfo; StringSet _linkeropt_strings; std::vector _deplibs; std::vector _linkeropts; @@ -58,12 +57,8 @@ private: StringSet _defines; StringMap _undefines; std::vector _asm_undefines; - MCContext _context; - // Use mangler to add GlobalPrefix to names to match linker names. - Mangler _mangler; - - LTOModule(std::unique_ptr M, TargetMachine *TM); + LTOModule(std::unique_ptr Obj, TargetMachine *TM); public: /// Returns 'true' if the file or memory contents is LLVM bitcode. @@ -100,14 +95,21 @@ public: TargetOptions options, std::string &errMsg, StringRef path = ""); + const Module &getModule() const { + return const_cast(this)->getModule(); + } + Module &getModule() { + return IRFile->getModule(); + } + /// Return the Module's target triple. const std::string &getTargetTriple() { - return _module->getTargetTriple(); + return getModule().getTargetTriple(); } /// Set the Module's target triple. void setTargetTriple(StringRef Triple) { - _module->setTargetTriple(Triple); + getModule().setTargetTriple(Triple); } /// Get the number of symbols @@ -153,9 +155,6 @@ public: return nullptr; } - /// Return the Module. - Module *getLLVVMModule() { return _module.get(); } - const std::vector &getAsmUndefinedRefs() { return _asm_undefines; } @@ -170,23 +169,20 @@ private: bool parseSymbols(std::string &errMsg); /// Add a symbol which isn't defined just yet to a list to be resolved later. - void addPotentialUndefinedSymbol(const GlobalValue *dcl, bool isFunc); + void addPotentialUndefinedSymbol(const object::BasicSymbolRef &Sym, + bool isFunc); /// Add a defined symbol to the list. - void addDefinedSymbol(const char *Name, const GlobalValue *Def, - bool IsFunction); - - /// Add a function symbol as defined to the list. - void addDefinedFunctionSymbol(const Function *f); - void addDefinedFunctionSymbol(const char *Name, const Function *F); + void addDefinedSymbol(const char *Name, const GlobalValue *def, + bool isFunction); /// Add a data symbol as defined to the list. - void addDefinedDataSymbol(const GlobalValue *v); - void addDefinedDataSymbol(const char *Name, const GlobalValue *V); + void addDefinedDataSymbol(const object::BasicSymbolRef &Sym); + void addDefinedDataSymbol(const char*Name, const GlobalValue *v); - /// Add global symbols from module-level ASM to the defined or undefined - /// lists. - bool addAsmGlobalSymbols(std::string &errMsg); + /// Add a function symbol as defined to the list. + void addDefinedFunctionSymbol(const object::BasicSymbolRef &Sym); + void addDefinedFunctionSymbol(const char *Name, const Function *F); /// Add a global symbol from module-level ASM to the defined list. void addAsmGlobalSymbol(const char *, lto_symbol_attributes scope); diff --git a/include/llvm/Object/IRObjectFile.h b/include/llvm/Object/IRObjectFile.h index bc69de40cb5..b33cc263b9b 100644 --- a/include/llvm/Object/IRObjectFile.h +++ b/include/llvm/Object/IRObjectFile.h @@ -28,8 +28,7 @@ class IRObjectFile : public SymbolicFile { std::vector> AsmSymbols; public: - IRObjectFile(std::unique_ptr Object, std::error_code &EC, - LLVMContext &Context); + IRObjectFile(std::unique_ptr Object, std::unique_ptr M); ~IRObjectFile(); void moveSymbolNext(DataRefImpl &Symb) const override; std::error_code printSymbolName(raw_ostream &OS, @@ -39,6 +38,13 @@ public: basic_symbol_iterator symbol_begin_impl() const override; basic_symbol_iterator symbol_end_impl() const override; + const Module &getModule() const { + return const_cast(this)->getModule(); + } + Module &getModule() { + return *M; + } + static inline bool classof(const Binary *v) { return v->isIR(); } diff --git a/lib/LTO/LTOCodeGenerator.cpp b/lib/LTO/LTOCodeGenerator.cpp index a1709f60fff..4b51166a755 100644 --- a/lib/LTO/LTOCodeGenerator.cpp +++ b/lib/LTO/LTOCodeGenerator.cpp @@ -114,7 +114,7 @@ void LTOCodeGenerator::initializeLTOPasses() { } bool LTOCodeGenerator::addModule(LTOModule* mod, std::string& errMsg) { - bool ret = IRLinker.linkInModule(mod->getLLVVMModule(), &errMsg); + bool ret = IRLinker.linkInModule(&mod->getModule(), &errMsg); const std::vector &undefs = mod->getAsmUndefinedRefs(); for (int i = 0, e = undefs.size(); i != e; ++i) diff --git a/lib/LTO/LTOModule.cpp b/lib/LTO/LTOModule.cpp index 45e3a21df72..314831ff6f8 100644 --- a/lib/LTO/LTOModule.cpp +++ b/lib/LTO/LTOModule.cpp @@ -28,7 +28,6 @@ #include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCTargetAsmParser.h" #include "llvm/MC/SubtargetFeature.h" -#include "llvm/Object/RecordStreamer.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Host.h" @@ -44,15 +43,9 @@ #include using namespace llvm; -LTOModule::LTOModule(std::unique_ptr M, TargetMachine *TM) - : _module(std::move(M)), _target(TM), - _context(_target->getMCAsmInfo(), _target->getRegisterInfo(), - &ObjFileInfo), - _mangler(TM->getDataLayout()) { - ObjFileInfo.InitMCObjectFileInfo(TM->getTargetTriple(), - TM->getRelocationModel(), TM->getCodeModel(), - _context); -} +LTOModule::LTOModule(std::unique_ptr Obj, + llvm::TargetMachine *TM) + : IRFile(std::move(Obj)), _target(TM) {} /// isBitcodeFile - Returns 'true' if the file (or memory contents) is LLVM /// bitcode. @@ -115,17 +108,15 @@ LTOModule *LTOModule::createFromBuffer(const void *mem, size_t length, LTOModule *LTOModule::makeLTOModule(std::unique_ptr Buffer, TargetOptions options, std::string &errMsg) { - // parse bitcode buffer - ErrorOr ModuleOrErr = + ErrorOr MOrErr = getLazyBitcodeModule(Buffer.get(), getGlobalContext()); - if (std::error_code EC = ModuleOrErr.getError()) { + if (std::error_code EC = MOrErr.getError()) { errMsg = EC.message(); return nullptr; } - Buffer.release(); - std::unique_ptr m(ModuleOrErr.get()); + std::unique_ptr M(MOrErr.get()); - std::string TripleStr = m->getTargetTriple(); + std::string TripleStr = M->getTargetTriple(); if (TripleStr.empty()) TripleStr = sys::getDefaultTargetTriple(); llvm::Triple Triple(TripleStr); @@ -153,18 +144,13 @@ LTOModule *LTOModule::makeLTOModule(std::unique_ptr Buffer, TargetMachine *target = march->createTargetMachine(TripleStr, CPU, FeatureStr, options); - m->materializeAllPermanently(); + M->materializeAllPermanently(true); + M->setDataLayout(target->getDataLayout()); - LTOModule *Ret = new LTOModule(std::move(m), target); + std::unique_ptr IRObj( + new object::IRObjectFile(std::move(Buffer), std::move(M))); - // We need a MCContext set up in order to get mangled names of private - // symbols. It is a bit odd that we need to report uses and definitions - // of private symbols, but it does look like ld64 expects to be informed - // of at least the ones with an 'l' prefix. - MCContext &Context = Ret->_context; - const TargetLoweringObjectFile &TLOF = - target->getTargetLowering()->getObjFileLowering(); - const_cast(TLOF).Initialize(Context, *target); + LTOModule *Ret = new LTOModule(std::move(IRObj), target); if (Ret->parseSymbols(errMsg)) { delete Ret; @@ -283,9 +269,14 @@ void LTOModule::addObjCClassRef(const GlobalVariable *clgv) { entry.setValue(info); } -void LTOModule::addDefinedDataSymbol(const GlobalValue *V) { +void LTOModule::addDefinedDataSymbol(const object::BasicSymbolRef &Sym) { SmallString<64> Buffer; - _target->getNameWithPrefix(Buffer, V, _mangler); + { + raw_svector_ostream OS(Buffer); + Sym.printName(OS); + } + + const GlobalValue *V = IRFile->getSymbolGV(Sym.getRawDataRefImpl()); addDefinedDataSymbol(Buffer.c_str(), V); } @@ -339,9 +330,15 @@ void LTOModule::addDefinedDataSymbol(const char *Name, const GlobalValue *v) { } } -void LTOModule::addDefinedFunctionSymbol(const Function *F) { +void LTOModule::addDefinedFunctionSymbol(const object::BasicSymbolRef &Sym) { SmallString<64> Buffer; - _target->getNameWithPrefix(Buffer, F, _mangler); + { + raw_svector_ostream OS(Buffer); + Sym.printName(OS); + } + + const Function *F = + cast(IRFile->getSymbolGV(Sym.getRawDataRefImpl())); addDefinedFunctionSymbol(Buffer.c_str(), F); } @@ -376,10 +373,6 @@ static bool canBeHidden(const GlobalValue *GV) { void LTOModule::addDefinedSymbol(const char *Name, const GlobalValue *def, bool isFunction) { - // ignore all llvm.* symbols - if (def->getName().startswith("llvm.")) - return; - // set alignment part log2() can have rounding errors uint32_t align = def->getAlignment(); uint32_t attr = align ? countTrailingZeros(align) : 0; @@ -499,20 +492,14 @@ void LTOModule::addAsmGlobalSymbolUndef(const char *name) { entry.setValue(info); } -/// addPotentialUndefinedSymbol - Add a symbol which isn't defined just yet to a -/// list to be resolved later. -void -LTOModule::addPotentialUndefinedSymbol(const GlobalValue *decl, bool isFunc) { - // ignore all llvm.* symbols - if (decl->getName().startswith("llvm.")) - return; - - // ignore all aliases - if (isa(decl)) - return; - +/// Add a symbol which isn't defined just yet to a list to be resolved later. +void LTOModule::addPotentialUndefinedSymbol(const object::BasicSymbolRef &Sym, + bool isFunc) { SmallString<64> name; - _target->getNameWithPrefix(name, decl, _mangler); + { + raw_svector_ostream OS(name); + Sym.printName(OS); + } StringMap::value_type &entry = _undefines.GetOrCreateValue(name); @@ -525,6 +512,8 @@ LTOModule::addPotentialUndefinedSymbol(const GlobalValue *decl, bool isFunc) { info.name = entry.getKey().data(); + const GlobalValue *decl = IRFile->getSymbolGV(Sym.getRawDataRefImpl()); + if (decl->hasExternalWeakLinkage()) info.attributes = LTO_SYMBOL_DEFINITION_WEAKUNDEF; else @@ -536,91 +525,51 @@ LTOModule::addPotentialUndefinedSymbol(const GlobalValue *decl, bool isFunc) { entry.setValue(info); } -/// addAsmGlobalSymbols - Add global symbols from module-level ASM to the -/// defined or undefined lists. -bool LTOModule::addAsmGlobalSymbols(std::string &errMsg) { - const std::string &inlineAsm = _module->getModuleInlineAsm(); - if (inlineAsm.empty()) - return false; - - std::unique_ptr Streamer(new RecordStreamer(_context)); - MemoryBuffer *Buffer = MemoryBuffer::getMemBuffer(inlineAsm); - SourceMgr SrcMgr; - SrcMgr.AddNewSourceBuffer(Buffer, SMLoc()); - std::unique_ptr Parser( - createMCAsmParser(SrcMgr, _context, *Streamer, *_target->getMCAsmInfo())); - const Target &T = _target->getTarget(); - std::unique_ptr MCII(T.createMCInstrInfo()); - std::unique_ptr STI(T.createMCSubtargetInfo( - _target->getTargetTriple(), _target->getTargetCPU(), - _target->getTargetFeatureString())); - std::unique_ptr TAP( - T.createMCAsmParser(*STI, *Parser.get(), *MCII, - _target->Options.MCOptions)); - if (!TAP) { - errMsg = "target " + std::string(T.getName()) + - " does not define AsmParser."; - return true; - } - - Parser->setTargetParser(*TAP); - if (Parser->Run(false)) - return true; - - for (auto &KV : *Streamer) { - StringRef Key = KV.first(); - RecordStreamer::State Value = KV.second; - if (Value == RecordStreamer::DefinedGlobal) - addAsmGlobalSymbol(Key.data(), LTO_SYMBOL_SCOPE_DEFAULT); - else if (Value == RecordStreamer::Defined) - addAsmGlobalSymbol(Key.data(), LTO_SYMBOL_SCOPE_INTERNAL); - else if (Value == RecordStreamer::Global || - Value == RecordStreamer::Used) - addAsmGlobalSymbolUndef(Key.data()); - } - - return false; -} - -/// isDeclaration - Return 'true' if the global value is a declaration. -static bool isDeclaration(const GlobalValue &V) { - if (V.hasAvailableExternallyLinkage()) - return true; - - if (V.isMaterializable()) - return false; - - return V.isDeclaration(); -} - /// parseSymbols - Parse the symbols from the module and model-level ASM and add /// them to either the defined or undefined lists. 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, true); - else - addDefinedFunctionSymbol(f); + for (auto &Sym : IRFile->symbols()) { + const GlobalValue *GV = IRFile->getSymbolGV(Sym.getRawDataRefImpl()); + uint32_t Flags = Sym.getFlags(); + bool IsUndefined = Flags & object::BasicSymbolRef::SF_Undefined; + + if (!GV) { + SmallString<64> Buffer; + { + raw_svector_ostream OS(Buffer); + Sym.printName(OS); + } + const char *Name = Buffer.c_str(); + + if (IsUndefined) + addAsmGlobalSymbolUndef(Name); + else if (Flags & object::BasicSymbolRef::SF_Global) + addAsmGlobalSymbol(Name, LTO_SYMBOL_SCOPE_DEFAULT); + else + addAsmGlobalSymbol(Name, LTO_SYMBOL_SCOPE_INTERNAL); + continue; + } + + auto *F = dyn_cast(GV); + if (IsUndefined) { + addPotentialUndefinedSymbol(Sym, F != nullptr); + continue; + } + + if (F) { + addDefinedFunctionSymbol(Sym); + continue; + } + + if (isa(GV)) { + addDefinedDataSymbol(Sym); + continue; + } + + assert(isa(GV)); + addDefinedDataSymbol(Sym); } - // add data - for (Module::global_iterator v = _module->global_begin(), - e = _module->global_end(); v != e; ++v) { - if (isDeclaration(*v)) - addPotentialUndefinedSymbol(v, false); - else - addDefinedDataSymbol(v); - } - - // add asm globals - if (addAsmGlobalSymbols(errMsg)) - return true; - - // add aliases - for (const auto &Alias : _module->aliases()) - addDefinedDataSymbol(&Alias); - // make symbols for all undefines for (StringMap::iterator u =_undefines.begin(), e = _undefines.end(); u != e; ++u) { @@ -637,7 +586,7 @@ bool LTOModule::parseSymbols(std::string &errMsg) { /// parseMetadata - Parse metadata from the module void LTOModule::parseMetadata() { // Linker Options - if (Value *Val = _module->getModuleFlag("Linker Options")) { + if (Value *Val = getModule().getModuleFlag("Linker Options")) { MDNode *LinkerOptions = cast(Val); for (unsigned i = 0, e = LinkerOptions->getNumOperands(); i != e; ++i) { MDNode *MDOptions = cast(LinkerOptions->getOperand(i)); diff --git a/lib/Object/IRObjectFile.cpp b/lib/Object/IRObjectFile.cpp index 0639c71d1b0..e927447739e 100644 --- a/lib/Object/IRObjectFile.cpp +++ b/lib/Object/IRObjectFile.cpp @@ -33,14 +33,8 @@ using namespace llvm; using namespace object; IRObjectFile::IRObjectFile(std::unique_ptr Object, - std::error_code &EC, LLVMContext &Context) - : SymbolicFile(Binary::ID_IR, std::move(Object)) { - ErrorOr MOrErr = getLazyBitcodeModule(Data.get(), Context); - if ((EC = MOrErr.getError())) - return; - - M.reset(MOrErr.get()); - + std::unique_ptr Mod) + : SymbolicFile(Binary::ID_IR, std::move(Object)), M(std::move(Mod)) { // If we have a DataLayout, setup a mangler. const DataLayout *DL = M->getDataLayout(); if (!DL) @@ -119,7 +113,11 @@ IRObjectFile::IRObjectFile(std::unique_ptr Object, } } -IRObjectFile::~IRObjectFile() { M->getMaterializer()->releaseBuffer(); } +IRObjectFile::~IRObjectFile() { + GVMaterializer *GVM = M->getMaterializer(); + if (GVM) + GVM->releaseBuffer(); + } static const GlobalValue *getGV(DataRefImpl &Symb) { if ((Symb.p & 3) == 3) @@ -275,10 +273,10 @@ basic_symbol_iterator IRObjectFile::symbol_end_impl() const { ErrorOr llvm::object::IRObjectFile::createIRObjectFile( std::unique_ptr Object, LLVMContext &Context) { - std::error_code EC; - std::unique_ptr Ret( - new IRObjectFile(std::move(Object), EC, Context)); - if (EC) + ErrorOr MOrErr = getLazyBitcodeModule(Object.get(), Context); + if (std::error_code EC = MOrErr.getError()) return EC; - return Ret.release(); + + std::unique_ptr M(MOrErr.get()); + return new IRObjectFile(std::move(Object), std::move(M)); }