X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FLTO%2FLTOModule.cpp;h=8817c35d9d4b2f06c712cc2be05b0ffb696073e1;hb=93e03df3cf2cc71a1e2550857da84a1c38dc9e82;hp=d9bc9394d4652f6e7454c1cbd612847a6ca34b70;hpb=a2bec69360e1e01f13acbd7946fae2c6adf3346f;p=oota-llvm.git diff --git a/lib/LTO/LTOModule.cpp b/lib/LTO/LTOModule.cpp index d9bc9394d46..8817c35d9d4 100644 --- a/lib/LTO/LTOModule.cpp +++ b/lib/LTO/LTOModule.cpp @@ -29,6 +29,8 @@ #include "llvm/MC/MCSymbol.h" #include "llvm/MC/MCTargetAsmParser.h" #include "llvm/MC/SubtargetFeature.h" +#include "llvm/Object/IRObjectFile.h" +#include "llvm/Object/ObjectFile.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/Host.h" @@ -44,29 +46,47 @@ #include "llvm/Transforms/Utils/GlobalStatus.h" #include using namespace llvm; +using namespace llvm::object; LTOModule::LTOModule(std::unique_ptr Obj, llvm::TargetMachine *TM) : IRFile(std::move(Obj)), _target(TM) {} +LTOModule::LTOModule(std::unique_ptr Obj, + llvm::TargetMachine *TM, + std::unique_ptr Context) + : OwnedContext(std::move(Context)), IRFile(std::move(Obj)), _target(TM) {} + +LTOModule::~LTOModule() {} + /// isBitcodeFile - Returns 'true' if the file (or memory contents) is LLVM /// bitcode. -bool LTOModule::isBitcodeFile(const void *mem, size_t length) { - return sys::fs::identify_magic(StringRef((const char *)mem, length)) == - sys::fs::file_magic::bitcode; +bool LTOModule::isBitcodeFile(const void *Mem, size_t Length) { + ErrorOr BCData = IRObjectFile::findBitcodeInMemBuffer( + MemoryBufferRef(StringRef((const char *)Mem, Length), "")); + return bool(BCData); } -bool LTOModule::isBitcodeFile(const char *path) { - sys::fs::file_magic type; - if (sys::fs::identify_magic(path, type)) +bool LTOModule::isBitcodeFile(const char *Path) { + ErrorOr> BufferOrErr = + MemoryBuffer::getFile(Path); + if (!BufferOrErr) return false; - return type == sys::fs::file_magic::bitcode; + + ErrorOr BCData = IRObjectFile::findBitcodeInMemBuffer( + BufferOrErr.get()->getMemBufferRef()); + return bool(BCData); } -bool LTOModule::isBitcodeForTarget(MemoryBuffer *buffer, - StringRef triplePrefix) { - std::string Triple = getBitcodeTargetTriple(buffer, getGlobalContext()); - return StringRef(Triple).startswith(triplePrefix); +bool LTOModule::isBitcodeForTarget(MemoryBuffer *Buffer, + StringRef TriplePrefix) { + ErrorOr BCOrErr = + IRObjectFile::findBitcodeInMemBuffer(Buffer->getMemBufferRef()); + if (!BCOrErr) + return false; + LLVMContext Context; + std::string Triple = getBitcodeTargetTriple(*BCOrErr, Context); + return StringRef(Triple).startswith(TriplePrefix); } LTOModule *LTOModule::createFromFile(const char *path, TargetOptions options, @@ -78,7 +98,8 @@ LTOModule *LTOModule::createFromFile(const char *path, TargetOptions options, return nullptr; } std::unique_ptr Buffer = std::move(BufferOrErr.get()); - return makeLTOModule(Buffer->getMemBufferRef(), options, errMsg); + return makeLTOModule(Buffer->getMemBufferRef(), options, errMsg, + &getGlobalContext()); } LTOModule *LTOModule::createFromOpenFile(int fd, const char *path, size_t size, @@ -98,29 +119,65 @@ LTOModule *LTOModule::createFromOpenFileSlice(int fd, const char *path, return nullptr; } std::unique_ptr Buffer = std::move(BufferOrErr.get()); - return makeLTOModule(Buffer->getMemBufferRef(), options, errMsg); + return makeLTOModule(Buffer->getMemBufferRef(), options, errMsg, + &getGlobalContext()); } LTOModule *LTOModule::createFromBuffer(const void *mem, size_t length, TargetOptions options, std::string &errMsg, StringRef path) { + return createInContext(mem, length, options, errMsg, path, + &getGlobalContext()); +} + +LTOModule *LTOModule::createInLocalContext(const void *mem, size_t length, + TargetOptions options, + std::string &errMsg, + StringRef path) { + return createInContext(mem, length, options, errMsg, path, nullptr); +} + +LTOModule *LTOModule::createInContext(const void *mem, size_t length, + TargetOptions options, + std::string &errMsg, StringRef path, + LLVMContext *Context) { StringRef Data((const char *)mem, length); MemoryBufferRef Buffer(Data, path); - return makeLTOModule(Buffer, options, errMsg); + return makeLTOModule(Buffer, options, errMsg, Context); +} + +static ErrorOr parseBitcodeFileImpl(MemoryBufferRef Buffer, + LLVMContext &Context, + bool ShouldBeLazy) { + // Find the buffer. + ErrorOr MBOrErr = + IRObjectFile::findBitcodeInMemBuffer(Buffer); + if (std::error_code EC = MBOrErr.getError()) + return EC; + + if (!ShouldBeLazy) + // Parse the full file. + return parseBitcodeFile(*MBOrErr, Context); + + // Parse lazily. + std::unique_ptr LightweightBuf = + MemoryBuffer::getMemBuffer(*MBOrErr, false); + return getLazyBitcodeModule(std::move(LightweightBuf), Context); } LTOModule *LTOModule::makeLTOModule(MemoryBufferRef Buffer, - TargetOptions options, - std::string &errMsg) { - StringRef Data = Buffer.getBuffer(); - StringRef FileName = Buffer.getBufferIdentifier(); - std::unique_ptr MemBuf( - makeBuffer(Data.begin(), Data.size(), FileName)); - if (!MemBuf) - return nullptr; + TargetOptions options, std::string &errMsg, + LLVMContext *Context) { + std::unique_ptr OwnedContext; + if (!Context) { + OwnedContext = llvm::make_unique(); + Context = OwnedContext.get(); + } - ErrorOr MOrErr = - getLazyBitcodeModule(MemBuf.get(), getGlobalContext()); + // If we own a context, we know this is being used only for symbol + // extraction, not linking. Be lazy in that case. + ErrorOr MOrErr = parseBitcodeFileImpl( + Buffer, *Context, /* ShouldBeLazy */ static_cast(OwnedContext)); if (std::error_code EC = MOrErr.getError()) { errMsg = EC.message(); return nullptr; @@ -154,13 +211,16 @@ LTOModule *LTOModule::makeLTOModule(MemoryBufferRef Buffer, TargetMachine *target = march->createTargetMachine(TripleStr, CPU, FeatureStr, options); - M->materializeAllPermanently(true); M->setDataLayout(target->getSubtargetImpl()->getDataLayout()); std::unique_ptr IRObj( new object::IRObjectFile(Buffer, std::move(M))); - LTOModule *Ret = new LTOModule(std::move(IRObj), target); + LTOModule *Ret; + if (OwnedContext) + Ret = new LTOModule(std::move(IRObj), target, std::move(OwnedContext)); + else + Ret = new LTOModule(std::move(IRObj), target); if (Ret->parseSymbols(errMsg)) { delete Ret; @@ -176,8 +236,7 @@ LTOModule *LTOModule::makeLTOModule(MemoryBufferRef Buffer, std::unique_ptr LTOModule::makeBuffer(const void *mem, size_t length, StringRef name) { const char *startPtr = (const char*)mem; - return std::unique_ptr( - MemoryBuffer::getMemBuffer(StringRef(startPtr, length), name, false)); + return MemoryBuffer::getMemBuffer(StringRef(startPtr, length), name, false); } /// objcClassNameFromExpression - Get string that the data pointer points to. @@ -206,27 +265,24 @@ void LTOModule::addObjCClass(const GlobalVariable *clgv) { // second slot in __OBJC,__class is pointer to superclass name std::string superclassName; if (objcClassNameFromExpression(c->getOperand(1), superclassName)) { - NameAndAttributes info; - StringMap::value_type &entry = - _undefines.GetOrCreateValue(superclassName); - if (!entry.getValue().name) { - const char *symbolName = entry.getKey().data(); - info.name = symbolName; + auto IterBool = + _undefines.insert(std::make_pair(superclassName, NameAndAttributes())); + if (IterBool.second) { + NameAndAttributes &info = IterBool.first->second; + info.name = IterBool.first->first().data(); info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED; info.isFunction = false; info.symbol = clgv; - entry.setValue(info); } } // third slot in __OBJC,__class is pointer to class name std::string className; if (objcClassNameFromExpression(c->getOperand(2), className)) { - StringSet::value_type &entry = _defines.GetOrCreateValue(className); - entry.setValue(1); + auto Iter = _defines.insert(className).first; NameAndAttributes info; - info.name = entry.getKey().data(); + info.name = Iter->first().data(); info.attributes = LTO_SYMBOL_PERMISSIONS_DATA | LTO_SYMBOL_DEFINITION_REGULAR | LTO_SYMBOL_SCOPE_DEFAULT; info.isFunction = false; @@ -245,19 +301,17 @@ void LTOModule::addObjCCategory(const GlobalVariable *clgv) { if (!objcClassNameFromExpression(c->getOperand(1), targetclassName)) return; - NameAndAttributes info; - StringMap::value_type &entry = - _undefines.GetOrCreateValue(targetclassName); + auto IterBool = + _undefines.insert(std::make_pair(targetclassName, NameAndAttributes())); - if (entry.getValue().name) + if (!IterBool.second) return; - const char *symbolName = entry.getKey().data(); - info.name = symbolName; + NameAndAttributes &info = IterBool.first->second; + info.name = IterBool.first->first().data(); info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED; info.isFunction = false; info.symbol = clgv; - entry.setValue(info); } /// addObjCClassRef - Parse i386/ppc ObjC class list data structure. @@ -266,18 +320,17 @@ void LTOModule::addObjCClassRef(const GlobalVariable *clgv) { if (!objcClassNameFromExpression(clgv->getInitializer(), targetclassName)) return; - NameAndAttributes info; - StringMap::value_type &entry = - _undefines.GetOrCreateValue(targetclassName); - if (entry.getValue().name) + auto IterBool = + _undefines.insert(std::make_pair(targetclassName, NameAndAttributes())); + + if (!IterBool.second) return; - const char *symbolName = entry.getKey().data(); - info.name = symbolName; + NameAndAttributes &info = IterBool.first->second; + info.name = IterBool.first->first().data(); info.attributes = LTO_SYMBOL_DEFINITION_UNDEFINED; info.isFunction = false; info.symbol = clgv; - entry.setValue(info); } void LTOModule::addDefinedDataSymbol(const object::BasicSymbolRef &Sym) { @@ -396,12 +449,11 @@ void LTOModule::addDefinedSymbol(const char *Name, const GlobalValue *def, else attr |= LTO_SYMBOL_SCOPE_DEFAULT; - StringSet::value_type &entry = _defines.GetOrCreateValue(Name); - entry.setValue(1); + auto Iter = _defines.insert(Name).first; // fill information structure NameAndAttributes info; - StringRef NameRef = entry.getKey(); + StringRef NameRef = Iter->first(); info.name = NameRef.data(); assert(info.name[NameRef.size()] == '\0'); info.attributes = attr; @@ -416,15 +468,13 @@ void LTOModule::addDefinedSymbol(const char *Name, const GlobalValue *def, /// defined list. void LTOModule::addAsmGlobalSymbol(const char *name, lto_symbol_attributes scope) { - StringSet::value_type &entry = _defines.GetOrCreateValue(name); + auto IterBool = _defines.insert(name); // only add new define if not already defined - if (entry.getValue()) + if (!IterBool.second) return; - entry.setValue(1); - - NameAndAttributes &info = _undefines[entry.getKey().data()]; + NameAndAttributes &info = _undefines[IterBool.first->first().data()]; if (info.symbol == nullptr) { // FIXME: This is trying to take care of module ASM like this: @@ -436,7 +486,7 @@ void LTOModule::addAsmGlobalSymbol(const char *name, // much. // fill information structure - info.name = entry.getKey().data(); + info.name = IterBool.first->first().data(); info.attributes = LTO_SYMBOL_PERMISSIONS_DATA | LTO_SYMBOL_DEFINITION_REGULAR | scope; info.isFunction = false; @@ -459,24 +509,21 @@ void LTOModule::addAsmGlobalSymbol(const char *name, /// addAsmGlobalSymbolUndef - Add a global symbol from module-level ASM to the /// undefined list. void LTOModule::addAsmGlobalSymbolUndef(const char *name) { - StringMap::value_type &entry = - _undefines.GetOrCreateValue(name); + auto IterBool = _undefines.insert(std::make_pair(name, NameAndAttributes())); - _asm_undefines.push_back(entry.getKey().data()); + _asm_undefines.push_back(IterBool.first->first().data()); // we already have the symbol - if (entry.getValue().name) + if (!IterBool.second) return; uint32_t attr = LTO_SYMBOL_DEFINITION_UNDEFINED; attr |= LTO_SYMBOL_SCOPE_DEFAULT; - NameAndAttributes info; - info.name = entry.getKey().data(); + NameAndAttributes &info = IterBool.first->second; + info.name = IterBool.first->first().data(); info.attributes = attr; info.isFunction = false; info.symbol = nullptr; - - entry.setValue(info); } /// Add a symbol which isn't defined just yet to a list to be resolved later. @@ -488,16 +535,15 @@ void LTOModule::addPotentialUndefinedSymbol(const object::BasicSymbolRef &Sym, Sym.printName(OS); } - StringMap::value_type &entry = - _undefines.GetOrCreateValue(name); + auto IterBool = _undefines.insert(std::make_pair(name, NameAndAttributes())); // we already have the symbol - if (entry.getValue().name) + if (!IterBool.second) return; - NameAndAttributes info; + NameAndAttributes &info = IterBool.first->second; - info.name = entry.getKey().data(); + info.name = IterBool.first->first().data(); const GlobalValue *decl = IRFile->getSymbolGV(Sym.getRawDataRefImpl()); @@ -508,8 +554,6 @@ void LTOModule::addPotentialUndefinedSymbol(const object::BasicSymbolRef &Sym, info.isFunction = isFunc; info.symbol = decl; - - entry.setValue(info); } /// parseSymbols - Parse the symbols from the module and model-level ASM and add @@ -576,14 +620,17 @@ bool LTOModule::parseSymbols(std::string &errMsg) { /// parseMetadata - Parse metadata from the module void LTOModule::parseMetadata() { // Linker Options - if (Value *Val = getModule().getModuleFlag("Linker Options")) { + if (Metadata *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)); for (unsigned ii = 0, ie = MDOptions->getNumOperands(); ii != ie; ++ii) { MDString *MDOption = cast(MDOptions->getOperand(ii)); - StringRef Op = _linkeropt_strings. - GetOrCreateValue(MDOption->getString()).getKey(); + // FIXME: Make StringSet::insert match Self-Associative Container + // requirements, returning rather than bool, and use that + // here. + StringRef Op = + _linkeropt_strings.insert(MDOption->getString()).first->first(); StringRef DepLibName = _target->getSubtargetImpl() ->getTargetLowering() ->getObjFileLowering()