X-Git-Url: http://plrg.eecs.uci.edu/git/?p=oota-llvm.git;a=blobdiff_plain;f=tools%2Fgold%2Fgold-plugin.cpp;h=9d6540d2d47d5b73050e56733aa7f1d9ec384589;hp=336025637310e8439401665fc7cd447f2ccf6798;hb=e272236d69961cf3686d1d4e5720bc87ec996cd4;hpb=fb1af0a48a61fff1bc70906898b7925280fc81aa diff --git a/tools/gold/gold-plugin.cpp b/tools/gold/gold-plugin.cpp index 33602563731..9d6540d2d47 100644 --- a/tools/gold/gold-plugin.cpp +++ b/tools/gold/gold-plugin.cpp @@ -18,6 +18,7 @@ #include "llvm/Bitcode/ReaderWriter.h" #include "llvm/CodeGen/Analysis.h" #include "llvm/CodeGen/CommandFlags.h" +#include "llvm/IR/Constants.h" #include "llvm/IR/LLVMContext.h" #include "llvm/IR/Module.h" #include "llvm/IR/Verifier.h" @@ -269,15 +270,15 @@ static const GlobalObject *getBaseObject(const GlobalValue &GV) { static ld_plugin_status claim_file_hook(const ld_plugin_input_file *file, int *claimed) { LLVMContext Context; - std::unique_ptr buffer; + MemoryBufferRef BufferRef; + std::unique_ptr Buffer; if (get_view) { const void *view; if (get_view(file->handle, &view) != LDPS_OK) { message(LDPL_ERROR, "Failed to get a view of %s", file->name); return LDPS_ERR; } - buffer.reset(MemoryBuffer::getMemBuffer( - StringRef((char *)view, file->filesize), "", false)); + BufferRef = MemoryBufferRef(StringRef((const char *)view, file->filesize), ""); } else { int64_t offset = 0; // Gold has found what might be IR part-way inside of a file, such as @@ -292,14 +293,16 @@ static ld_plugin_status claim_file_hook(const ld_plugin_input_file *file, message(LDPL_ERROR, EC.message().c_str()); return LDPS_ERR; } - buffer = std::move(BufferOrErr.get()); + Buffer = std::move(BufferOrErr.get()); + BufferRef = Buffer->getMemBufferRef(); } - ErrorOr ObjOrErr = - object::IRObjectFile::createIRObjectFile(buffer->getMemBufferRef(), - Context); + ErrorOr> ObjOrErr = + object::IRObjectFile::createIRObjectFile(BufferRef, Context); std::error_code EC = ObjOrErr.getError(); - if (EC == BitcodeError::InvalidBitcodeSignature) + if (EC == BitcodeError::InvalidBitcodeSignature || + EC == object::object_error::invalid_file_type || + EC == object::object_error::bitcode_section_not_found) return LDPS_OK; *claimed = 1; @@ -309,7 +312,7 @@ static ld_plugin_status claim_file_hook(const ld_plugin_input_file *file, EC.message().c_str()); return LDPS_ERR; } - std::unique_ptr Obj(ObjOrErr.get()); + std::unique_ptr Obj = std::move(*ObjOrErr); Modules.resize(Modules.size() + 1); claimed_file &cf = Modules.back(); @@ -415,18 +418,8 @@ static void keepGlobalValue(GlobalValue &GV, assert(!GV.isDiscardableIfUnused()); } -static bool isDeclaration(const GlobalValue &V) { - if (V.hasAvailableExternallyLinkage()) - return true; - - if (V.isMaterializable()) - return false; - - return V.isDeclaration(); -} - static void internalize(GlobalValue &GV) { - if (isDeclaration(GV)) + if (GV.isDeclarationForLinker()) return; // We get here if there is a matching asm definition. if (!GV.hasLocalLinkage()) GV.setLinkage(GlobalValue::InternalLinkage); @@ -456,6 +449,7 @@ static void drop(GlobalValue &GV) { /*Initializer*/ nullptr); Var->takeName(&Alias); Alias.replaceAllUsesWith(Var); + Alias.eraseFromParent(); } static const char *getResolutionName(ld_plugin_symbol_resolution R) { @@ -481,27 +475,49 @@ static const char *getResolutionName(ld_plugin_symbol_resolution R) { case LDPR_PREVAILING_DEF_IRONLY_EXP: return "PREVAILING_DEF_IRONLY_EXP"; } + llvm_unreachable("Unknown resolution"); } static GlobalObject *makeInternalReplacement(GlobalObject *GO) { Module *M = GO->getParent(); GlobalObject *Ret; if (auto *F = dyn_cast(GO)) { - auto *NewF = Function::Create( - F->getFunctionType(), GlobalValue::InternalLinkage, F->getName(), M); + if (F->isMaterializable()) { + if (F->materialize()) + message(LDPL_FATAL, "LLVM gold plugin has failed to read a function"); + + } + + auto *NewF = Function::Create(F->getFunctionType(), F->getLinkage(), + F->getName(), M); + + ValueToValueMapTy VM; + Function::arg_iterator NewI = NewF->arg_begin(); + for (auto &Arg : F->args()) { + NewI->setName(Arg.getName()); + VM[&Arg] = NewI; + ++NewI; + } + NewF->getBasicBlockList().splice(NewF->end(), F->getBasicBlockList()); + for (auto &BB : *NewF) { + for (auto &Inst : BB) + RemapInstruction(&Inst, VM, RF_IgnoreMissingEntries); + } + Ret = NewF; F->deleteBody(); } else { auto *Var = cast(GO); Ret = new GlobalVariable( *M, Var->getType()->getElementType(), Var->isConstant(), - GlobalValue::InternalLinkage, Var->getInitializer(), Var->getName(), + Var->getLinkage(), Var->getInitializer(), Var->getName(), nullptr, Var->getThreadLocalMode(), Var->getType()->getAddressSpace(), Var->isExternallyInitialized()); Var->setInitializer(nullptr); } Ret->copyAttributesFrom(GO); + Ret->setLinkage(GlobalValue::InternalLinkage); Ret->setComdat(GO->getComdat()); return Ret; @@ -546,13 +562,20 @@ getModuleForFile(LLVMContext &Context, claimed_file &F, raw_fd_ostream *ApiFile, if (get_view(F.handle, &View) != LDPS_OK) message(LDPL_FATAL, "Failed to get a view of file"); - std::unique_ptr Buffer(MemoryBuffer::getMemBuffer( - StringRef((char *)View, File.filesize), "", false)); + llvm::ErrorOr MBOrErr = + object::IRObjectFile::findBitcodeInMemBuffer( + MemoryBufferRef(StringRef((const char *)View, File.filesize), "")); + if (std::error_code EC = MBOrErr.getError()) + message(LDPL_FATAL, "Could not read bitcode from file : %s", + EC.message().c_str()); + + std::unique_ptr Buffer = + MemoryBuffer::getMemBuffer(MBOrErr->getBuffer(), "", false); if (release_input_file(F.handle) != LDPS_OK) message(LDPL_FATAL, "Failed to release file information"); - ErrorOr MOrErr = getLazyBitcodeModule(Buffer, Context); + ErrorOr MOrErr = getLazyBitcodeModule(std::move(Buffer), Context); if (std::error_code EC = MOrErr.getError()) message(LDPL_FATAL, "Could not read bitcode from file : %s", @@ -576,6 +599,15 @@ getModuleForFile(LLVMContext &Context, claimed_file &F, raw_fd_ostream *ApiFile, if (!GV) continue; // Asm symbol. + if (Resolution != LDPR_PREVAILING_DEF_IRONLY && GV->hasCommonLinkage()) { + // Common linkage is special. There is no single symbol that wins the + // resolution. Instead we have to collect the maximum alignment and size. + // The IR linker does that for us if we just pass it every common GV. + // We still have to keep track of LDPR_PREVAILING_DEF_IRONLY so we + // internalize once the IR linker has done its job. + continue; + } + switch (Resolution) { case LDPR_UNKNOWN: llvm_unreachable("Unexpected resolution"); @@ -584,7 +616,7 @@ getModuleForFile(LLVMContext &Context, claimed_file &F, raw_fd_ostream *ApiFile, case LDPR_RESOLVED_EXEC: case LDPR_RESOLVED_DYN: case LDPR_UNDEF: - assert(isDeclaration(*GV)); + assert(GV->isDeclarationForLinker()); break; case LDPR_PREVAILING_DEF_IRONLY: { @@ -602,8 +634,14 @@ getModuleForFile(LLVMContext &Context, claimed_file &F, raw_fd_ostream *ApiFile, keepGlobalValue(*GV, KeptAliases); break; - case LDPR_PREEMPTED_REG: case LDPR_PREEMPTED_IR: + // Gold might have selected a linkonce_odr and preempted a weak_odr. + // In that case we have to make sure we don't end up internalizing it. + if (!GV->isDiscardableIfUnused()) + Maybe.erase(Sym.name); + + // fall-through + case LDPR_PREEMPTED_REG: Drop.insert(GV); break; @@ -625,12 +663,6 @@ getModuleForFile(LLVMContext &Context, claimed_file &F, raw_fd_ostream *ApiFile, Sym.comdat_key = nullptr; } - if (!Drop.empty()) - // This is horrible. Given how lazy loading is implemented, dropping - // the body while there is a materializer present doesn't work, the - // linker will just read the body back. - M->materializeAllPermanently(); - ValueToValueMapTy VM; LocalValueMaterializer Materializer(Drop); for (GlobalAlias *GA : KeptAliases) { @@ -684,7 +716,7 @@ static void codegen(Module &M) { runLTOPasses(M, *TM); PassManager CodeGenPasses; - CodeGenPasses.add(new DataLayoutPass(&M)); + CodeGenPasses.add(new DataLayoutPass()); SmallString<128> Filename; int FD; @@ -745,9 +777,8 @@ static ld_plugin_status allSymbolsReadHook(raw_fd_ostream *ApiFile) { M->setTargetTriple(DefaultTriple); } - std::string ErrMsg; - if (L.linkInModule(M.get(), &ErrMsg)) - message(LDPL_FATAL, "Failed to link module: %s", ErrMsg.c_str()); + if (L.linkInModule(M.get())) + message(LDPL_FATAL, "Failed to link module"); } for (const auto &Name : Internalize) {