X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FLTO%2FLTOModule.cpp;h=5083a59900a7dfb3d878571526a409c03821ab27;hb=f15492fd7292563049ace40be9a2e0048e64b8f0;hp=7d3446ebc177e2159818eb9f0cbcd15a1fc1f086;hpb=1e64b30a9b96deeb3e168d415570a8c92488505f;p=oota-llvm.git diff --git a/lib/LTO/LTOModule.cpp b/lib/LTO/LTOModule.cpp index 7d3446ebc17..5083a59900a 100644 --- a/lib/LTO/LTOModule.cpp +++ b/lib/LTO/LTOModule.cpp @@ -15,6 +15,7 @@ #include "llvm/LTO/LTOModule.h" #include "llvm/ADT/Triple.h" #include "llvm/Bitcode/ReaderWriter.h" +#include "llvm/CodeGen/Analysis.h" #include "llvm/IR/Constants.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Metadata.h" @@ -28,7 +29,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" @@ -40,19 +40,14 @@ #include "llvm/Target/TargetLowering.h" #include "llvm/Target/TargetLoweringObjectFile.h" #include "llvm/Target/TargetRegisterInfo.h" +#include "llvm/Target/TargetSubtargetInfo.h" #include "llvm/Transforms/Utils/GlobalStatus.h" #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. @@ -68,40 +63,21 @@ bool LTOModule::isBitcodeFile(const char *path) { return type == sys::fs::file_magic::bitcode; } -/// isBitcodeFileForTarget - Returns 'true' if the file (or memory contents) is -/// LLVM bitcode for the specified triple. -bool LTOModule::isBitcodeFileForTarget(const void *mem, size_t length, - const char *triplePrefix) { - MemoryBuffer *buffer = makeBuffer(mem, length); - if (!buffer) - return false; - return isTargetMatch(buffer, triplePrefix); -} - -bool LTOModule::isBitcodeFileForTarget(const char *path, - const char *triplePrefix) { - std::unique_ptr buffer; - if (MemoryBuffer::getFile(path, buffer)) - return false; - return isTargetMatch(buffer.release(), triplePrefix); -} - -/// isTargetMatch - Returns 'true' if the memory buffer is for the specified -/// target triple. -bool LTOModule::isTargetMatch(MemoryBuffer *buffer, const char *triplePrefix) { +bool LTOModule::isBitcodeForTarget(MemoryBuffer *buffer, + StringRef triplePrefix) { std::string Triple = getBitcodeTargetTriple(buffer, getGlobalContext()); - delete buffer; - return strncmp(Triple.c_str(), triplePrefix, strlen(triplePrefix)) == 0; + return StringRef(Triple).startswith(triplePrefix); } LTOModule *LTOModule::createFromFile(const char *path, TargetOptions options, std::string &errMsg) { - std::unique_ptr buffer; - if (std::error_code ec = MemoryBuffer::getFile(path, buffer)) { - errMsg = ec.message(); + ErrorOr> BufferOrErr = + MemoryBuffer::getFile(path); + if (std::error_code EC = BufferOrErr.getError()) { + errMsg = EC.message(); return nullptr; } - return makeLTOModule(std::move(buffer), options, errMsg); + return makeLTOModule(std::move(BufferOrErr.get()), options, errMsg); } LTOModule *LTOModule::createFromOpenFile(int fd, const char *path, size_t size, @@ -114,13 +90,13 @@ LTOModule *LTOModule::createFromOpenFileSlice(int fd, const char *path, size_t map_size, off_t offset, TargetOptions options, std::string &errMsg) { - std::unique_ptr buffer; - if (std::error_code ec = - MemoryBuffer::getOpenFileSlice(fd, path, buffer, map_size, offset)) { - errMsg = ec.message(); + ErrorOr> BufferOrErr = + MemoryBuffer::getOpenFileSlice(fd, path, map_size, offset); + if (std::error_code EC = BufferOrErr.getError()) { + errMsg = EC.message(); return nullptr; } - return makeLTOModule(std::move(buffer), options, errMsg); + return makeLTOModule(std::move(BufferOrErr.get()), options, errMsg); } LTOModule *LTOModule::createFromBuffer(const void *mem, size_t length, @@ -135,17 +111,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); @@ -166,25 +140,19 @@ LTOModule *LTOModule::makeLTOModule(std::unique_ptr Buffer, CPU = "core2"; else if (Triple.getArch() == llvm::Triple::x86) CPU = "yonah"; - else if (Triple.getArch() == llvm::Triple::arm64 || - Triple.getArch() == llvm::Triple::aarch64) + else if (Triple.getArch() == llvm::Triple::aarch64) CPU = "cyclone"; } TargetMachine *target = march->createTargetMachine(TripleStr, CPU, FeatureStr, options); - m->materializeAllPermanently(); + M->materializeAllPermanently(true); + M->setDataLayout(target->getSubtargetImpl()->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; @@ -197,10 +165,11 @@ LTOModule *LTOModule::makeLTOModule(std::unique_ptr Buffer, } /// Create a MemoryBuffer from a memory range with an optional name. -MemoryBuffer *LTOModule::makeBuffer(const void *mem, size_t length, - StringRef name) { +std::unique_ptr +LTOModule::makeBuffer(const void *mem, size_t length, StringRef name) { const char *startPtr = (const char*)mem; - return MemoryBuffer::getMemBuffer(StringRef(startPtr, length), name, false); + return std::unique_ptr( + MemoryBuffer::getMemBuffer(StringRef(startPtr, length), name, false)); } /// objcClassNameFromExpression - Get string that the data pointer points to. @@ -303,10 +272,20 @@ void LTOModule::addObjCClassRef(const GlobalVariable *clgv) { entry.setValue(info); } -/// addDefinedDataSymbol - Add a data symbol as defined to the list. -void LTOModule::addDefinedDataSymbol(const GlobalValue *v) { +void LTOModule::addDefinedDataSymbol(const object::BasicSymbolRef &Sym) { + SmallString<64> Buffer; + { + raw_svector_ostream OS(Buffer); + Sym.printName(OS); + } + + const GlobalValue *V = IRFile->getSymbolGV(Sym.getRawDataRefImpl()); + addDefinedDataSymbol(Buffer.c_str(), V); +} + +void LTOModule::addDefinedDataSymbol(const char *Name, const GlobalValue *v) { // Add to list of defined symbols. - addDefinedSymbol(v, false); + addDefinedSymbol(Name, v, false); if (!v->hasSection() /* || !isTargetDarwin */) return; @@ -354,46 +333,25 @@ void LTOModule::addDefinedDataSymbol(const GlobalValue *v) { } } -/// addDefinedFunctionSymbol - Add a function symbol as defined to the list. -void LTOModule::addDefinedFunctionSymbol(const Function *f) { - // add to list of defined symbols - addDefinedSymbol(f, true); -} - -static bool canBeHidden(const GlobalValue *GV) { - // FIXME: this is duplicated with another static function in AsmPrinter.cpp - GlobalValue::LinkageTypes L = GV->getLinkage(); - - if (L != GlobalValue::LinkOnceODRLinkage) - return false; - - if (GV->hasUnnamedAddr()) - return true; - - // If it is a non constant variable, it needs to be uniqued across shared - // objects. - if (const GlobalVariable *Var = dyn_cast(GV)) { - if (!Var->isConstant()) - return false; +void LTOModule::addDefinedFunctionSymbol(const object::BasicSymbolRef &Sym) { + SmallString<64> Buffer; + { + raw_svector_ostream OS(Buffer); + Sym.printName(OS); } - GlobalStatus GS; - if (GlobalStatus::analyzeGlobal(GV, GS)) - return false; - - return !GS.IsCompared; + const Function *F = + cast(IRFile->getSymbolGV(Sym.getRawDataRefImpl())); + addDefinedFunctionSymbol(Buffer.c_str(), F); } -/// addDefinedSymbol - Add a defined symbol to the list. -void LTOModule::addDefinedSymbol(const GlobalValue *def, bool isFunction) { - // ignore all llvm.* symbols - if (def->getName().startswith("llvm.")) - return; - - // string is owned by _defines - SmallString<64> Buffer; - _target->getNameWithPrefix(Buffer, def, _mangler); +void LTOModule::addDefinedFunctionSymbol(const char *Name, const Function *F) { + // add to list of defined symbols + addDefinedSymbol(Name, F, true); +} +void LTOModule::addDefinedSymbol(const char *Name, const GlobalValue *def, + bool isFunction) { // set alignment part log2() can have rounding errors uint32_t align = def->getAlignment(); uint32_t attr = align ? countTrailingZeros(align) : 0; @@ -425,19 +383,19 @@ void LTOModule::addDefinedSymbol(const GlobalValue *def, bool isFunction) { attr |= LTO_SYMBOL_SCOPE_HIDDEN; else if (def->hasProtectedVisibility()) attr |= LTO_SYMBOL_SCOPE_PROTECTED; - else if (canBeHidden(def)) + else if (canBeOmittedFromSymbolTable(def)) attr |= LTO_SYMBOL_SCOPE_DEFAULT_CAN_BE_HIDDEN; else attr |= LTO_SYMBOL_SCOPE_DEFAULT; - StringSet::value_type &entry = _defines.GetOrCreateValue(Buffer); + StringSet::value_type &entry = _defines.GetOrCreateValue(Name); entry.setValue(1); // fill information structure NameAndAttributes info; - StringRef Name = entry.getKey(); - info.name = Name.data(); - assert(info.name[Name.size()] == '\0'); + StringRef NameRef = entry.getKey(); + info.name = NameRef.data(); + assert(info.name[NameRef.size()] == '\0'); info.attributes = attr; info.isFunction = isFunction; info.symbol = def; @@ -482,9 +440,9 @@ void LTOModule::addAsmGlobalSymbol(const char *name, } if (info.isFunction) - addDefinedFunctionSymbol(cast(info.symbol)); + addDefinedFunctionSymbol(info.name, cast(info.symbol)); else - addDefinedDataSymbol(info.symbol); + addDefinedDataSymbol(info.name, info.symbol); _symbols.back().attributes &= ~LTO_SYMBOL_SCOPE_MASK; _symbols.back().attributes |= scope; @@ -513,20 +471,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); @@ -539,6 +491,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 @@ -550,90 +504,53 @@ 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(); + if (Flags & object::BasicSymbolRef::SF_FormatSpecific) + continue; + + 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; + } - // 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); - } + auto *F = dyn_cast(GV); + if (IsUndefined) { + addPotentialUndefinedSymbol(Sym, F != nullptr); + continue; + } - // add asm globals - if (addAsmGlobalSymbols(errMsg)) - return true; + if (F) { + addDefinedFunctionSymbol(Sym); + continue; + } - // add aliases - for (const auto &Alias : _module->aliases()) - addDefinedDataSymbol(&Alias); + if (isa(GV)) { + addDefinedDataSymbol(Sym); + continue; + } + + assert(isa(GV)); + addDefinedDataSymbol(Sym); + } // make symbols for all undefines for (StringMap::iterator u =_undefines.begin(), @@ -651,7 +568,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)); @@ -659,8 +576,10 @@ void LTOModule::parseMetadata() { MDString *MDOption = cast(MDOptions->getOperand(ii)); StringRef Op = _linkeropt_strings. GetOrCreateValue(MDOption->getString()).getKey(); - StringRef DepLibName = _target->getTargetLowering()-> - getObjFileLowering().getDepLibFromLinkerOpt(Op); + StringRef DepLibName = _target->getSubtargetImpl() + ->getTargetLowering() + ->getObjFileLowering() + .getDepLibFromLinkerOpt(Op); if (!DepLibName.empty()) _deplibs.push_back(DepLibName.data()); else if (!Op.empty())