diff options
author | Peter Collingbourne <peter@pcc.me.uk> | 2017-03-31 02:44:50 +0000 |
---|---|---|
committer | Peter Collingbourne <peter@pcc.me.uk> | 2017-03-31 02:44:50 +0000 |
commit | f10698b94035d8c608f92219f63f3bd48549bac4 (patch) | |
tree | 75f2f051a9f27e4b1f61756e7247d902a63d7155 /llvm/lib/LTO/LTO.cpp | |
parent | ae9c74280c6def98fad4d4147163f13250d6cb4f (diff) | |
download | llvm-f10698b94035d8c608f92219f63f3bd48549bac4.zip llvm-f10698b94035d8c608f92219f63f3bd48549bac4.tar.gz llvm-f10698b94035d8c608f92219f63f3bd48549bac4.tar.bz2 |
Revert r299168 and r299169 due to library dependency issues.
http://bb.pgr.jp/builders/i686-mingw32-RA-on-linux/builds/25073/steps/build_llvmclang/logs/stdio
llvm-svn: 299171
Diffstat (limited to 'llvm/lib/LTO/LTO.cpp')
-rw-r--r-- | llvm/lib/LTO/LTO.cpp | 212 |
1 files changed, 127 insertions, 85 deletions
diff --git a/llvm/lib/LTO/LTO.cpp b/llvm/lib/LTO/LTO.cpp index 4885f65..f3d258e 100644 --- a/llvm/lib/LTO/LTO.cpp +++ b/llvm/lib/LTO/LTO.cpp @@ -305,6 +305,14 @@ void llvm::thinLTOInternalizeAndPromoteInIndex( thinLTOInternalizeAndPromoteGUID(I.second, I.first, isExported); } +struct InputFile::InputModule { + BitcodeModule BM; + std::unique_ptr<Module> Mod; + + // The range of ModuleSymbolTable entries for this input module. + size_t SymBegin, SymEnd; +}; + // Requires a destructor for std::vector<InputModule>. InputFile::~InputFile() = default; @@ -325,51 +333,87 @@ Expected<std::unique_ptr<InputFile>> InputFile::create(MemoryBufferRef Object) { return make_error<StringError>("Bitcode file does not contain any modules", inconvertibleErrorCode()); - File->Mods = *BMsOrErr; - - LLVMContext Ctx; - std::vector<Module *> Mods; - std::vector<std::unique_ptr<Module>> OwnedMods; + // Create an InputModule for each module in the InputFile, and add it to the + // ModuleSymbolTable. for (auto BM : *BMsOrErr) { Expected<std::unique_ptr<Module>> MOrErr = - BM.getLazyModule(Ctx, /*ShouldLazyLoadMetadata*/ true, + BM.getLazyModule(File->Ctx, /*ShouldLazyLoadMetadata*/ true, /*IsImporting*/ false); if (!MOrErr) return MOrErr.takeError(); - if ((*MOrErr)->getDataLayoutStr().empty()) - return make_error<StringError>("input module has no datalayout", - inconvertibleErrorCode()); + size_t SymBegin = File->SymTab.symbols().size(); + File->SymTab.addModule(MOrErr->get()); + size_t SymEnd = File->SymTab.symbols().size(); - Mods.push_back(MOrErr->get()); - OwnedMods.push_back(std::move(*MOrErr)); - } + for (const auto &C : (*MOrErr)->getComdatSymbolTable()) { + auto P = File->ComdatMap.insert( + std::make_pair(&C.second, File->Comdats.size())); + assert(P.second); + (void)P; + File->Comdats.push_back(C.first()); + } - SmallVector<char, 0> Symtab; - if (Error E = irsymtab::build(Mods, Symtab, File->Strtab)) - return std::move(E); - - irsymtab::Reader R({Symtab.data(), Symtab.size()}, - {File->Strtab.data(), File->Strtab.size()}); - File->SourceFileName = R.getSourceFileName(); - File->COFFLinkerOpts = R.getCOFFLinkerOpts(); - File->ComdatTable = R.getComdatTable(); - - for (unsigned I = 0; I != Mods.size(); ++I) { - size_t Begin = File->Symbols.size(); - for (const irsymtab::Reader::SymbolRef &Sym : R.module_symbols(I)) - // Skip symbols that are irrelevant to LTO. Note that this condition needs - // to match the one in Skip() in LTO::addRegularLTO(). - if (Sym.isGlobal() && !Sym.isFormatSpecific()) - File->Symbols.push_back(Sym); - File->ModuleSymIndices.push_back({Begin, File->Symbols.size()}); + File->Mods.push_back({BM, std::move(*MOrErr), SymBegin, SymEnd}); } return std::move(File); } +Expected<int> InputFile::Symbol::getComdatIndex() const { + if (!isGV()) + return -1; + const GlobalObject *GO = getGV()->getBaseObject(); + if (!GO) + return make_error<StringError>("Unable to determine comdat of alias!", + inconvertibleErrorCode()); + if (const Comdat *C = GO->getComdat()) { + auto I = File->ComdatMap.find(C); + assert(I != File->ComdatMap.end()); + return I->second; + } + return -1; +} + +Expected<std::string> InputFile::getLinkerOpts() { + std::string LinkerOpts; + raw_string_ostream LOS(LinkerOpts); + // Extract linker options from module metadata. + for (InputModule &Mod : Mods) { + std::unique_ptr<Module> &M = Mod.Mod; + if (auto E = M->materializeMetadata()) + return std::move(E); + if (Metadata *Val = M->getModuleFlag("Linker Options")) { + MDNode *LinkerOptions = cast<MDNode>(Val); + for (const MDOperand &MDOptions : LinkerOptions->operands()) + for (const MDOperand &MDOption : cast<MDNode>(MDOptions)->operands()) + LOS << " " << cast<MDString>(MDOption)->getString(); + } + } + + // Synthesize export flags for symbols with dllexport storage. + const Triple TT(Mods[0].Mod->getTargetTriple()); + Mangler M; + for (const ModuleSymbolTable::Symbol &Sym : SymTab.symbols()) + if (auto *GV = Sym.dyn_cast<GlobalValue*>()) + emitLinkerFlagsForGlobalCOFF(LOS, GV, TT, M); + LOS.flush(); + return LinkerOpts; +} + StringRef InputFile::getName() const { - return Mods[0].getModuleIdentifier(); + return Mods[0].BM.getModuleIdentifier(); +} + +StringRef InputFile::getSourceFileName() const { + return Mods[0].Mod->getSourceFileName(); +} + +iterator_range<InputFile::symbol_iterator> +InputFile::module_symbols(InputModule &IM) { + return llvm::make_range( + symbol_iterator(SymTab.symbols().data() + IM.SymBegin, SymTab, this), + symbol_iterator(SymTab.symbols().data() + IM.SymEnd, SymTab, this)); } LTO::RegularLTOState::RegularLTOState(unsigned ParallelCodeGenParallelismLevel, @@ -393,17 +437,21 @@ LTO::LTO(Config Conf, ThinBackend Backend, LTO::~LTO() = default; // Add the given symbol to the GlobalResolutions map, and resolve its partition. -void LTO::addSymbolToGlobalRes(const InputFile::Symbol &Sym, +void LTO::addSymbolToGlobalRes(SmallPtrSet<GlobalValue *, 8> &Used, + const InputFile::Symbol &Sym, SymbolResolution Res, unsigned Partition) { - auto &GlobalRes = GlobalResolutions[Sym.getName()]; - GlobalRes.UnnamedAddr &= Sym.isUnnamedAddr(); - if (Res.Prevailing) - GlobalRes.IRName = Sym.getIRName(); + GlobalValue *GV = Sym.isGV() ? Sym.getGV() : nullptr; + auto &GlobalRes = GlobalResolutions[Sym.getName()]; + if (GV) { + GlobalRes.UnnamedAddr &= GV->hasGlobalUnnamedAddr(); + if (Res.Prevailing) + GlobalRes.IRName = GV->getName(); + } // Set the partition to external if we know it is used elsewhere, e.g. // it is visible to a regular object, is referenced from llvm.compiler_used, // or was already recorded as being referenced from a different partition. - if (Res.VisibleToRegularObj || Sym.isUsed() || + if (Res.VisibleToRegularObj || (GV && Used.count(GV)) || (GlobalRes.Partition != GlobalResolution::Unknown && GlobalRes.Partition != Partition)) { GlobalRes.Partition = GlobalResolution::External; @@ -447,32 +495,41 @@ Error LTO::add(std::unique_ptr<InputFile> Input, writeToResolutionFile(*Conf.ResolutionFile, Input.get(), Res); const SymbolResolution *ResI = Res.begin(); - for (unsigned I = 0; I != Input->Mods.size(); ++I) - if (Error Err = addModule(*Input, I, ResI, Res.end())) + for (InputFile::InputModule &IM : Input->Mods) + if (Error Err = addModule(*Input, IM, ResI, Res.end())) return Err; assert(ResI == Res.end()); return Error::success(); } -Error LTO::addModule(InputFile &Input, unsigned ModI, +Error LTO::addModule(InputFile &Input, InputFile::InputModule &IM, const SymbolResolution *&ResI, const SymbolResolution *ResE) { - Expected<bool> HasThinLTOSummary = Input.Mods[ModI].hasSummary(); + // FIXME: move to backend + Module &M = *IM.Mod; + + if (M.getDataLayoutStr().empty()) + return make_error<StringError>("input module has no datalayout", + inconvertibleErrorCode()); + + if (!Conf.OverrideTriple.empty()) + M.setTargetTriple(Conf.OverrideTriple); + else if (M.getTargetTriple().empty()) + M.setTargetTriple(Conf.DefaultTriple); + + Expected<bool> HasThinLTOSummary = IM.BM.hasSummary(); if (!HasThinLTOSummary) return HasThinLTOSummary.takeError(); - auto ModSyms = Input.module_symbols(ModI); if (*HasThinLTOSummary) - return addThinLTO(Input.Mods[ModI], ModSyms, ResI, ResE); + return addThinLTO(IM.BM, M, Input.module_symbols(IM), ResI, ResE); else - return addRegularLTO(Input.Mods[ModI], ModSyms, ResI, ResE); + return addRegularLTO(IM.BM, ResI, ResE); } // Add a regular LTO object to the link. -Error LTO::addRegularLTO(BitcodeModule BM, - ArrayRef<InputFile::Symbol> Syms, - const SymbolResolution *&ResI, +Error LTO::addRegularLTO(BitcodeModule BM, const SymbolResolution *&ResI, const SymbolResolution *ResE) { if (!RegularLTO.CombinedModule) { RegularLTO.CombinedModule = @@ -493,6 +550,9 @@ Error LTO::addRegularLTO(BitcodeModule BM, ModuleSymbolTable SymTab; SymTab.addModule(&M); + SmallPtrSet<GlobalValue *, 8> Used; + collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ false); + std::vector<GlobalValue *> Keep; for (GlobalVariable &GV : M.globals()) @@ -504,35 +564,17 @@ Error LTO::addRegularLTO(BitcodeModule BM, if (GlobalObject *GO = GA.getBaseObject()) AliasedGlobals.insert(GO); - // In this function we need IR GlobalValues matching the symbols in Syms - // (which is not backed by a module), so we need to enumerate them in the same - // order. The symbol enumeration order of a ModuleSymbolTable intentionally - // matches the order of an irsymtab, but when we read the irsymtab in - // InputFile::create we omit some symbols that are irrelevant to LTO. The - // Skip() function skips the same symbols from the module as InputFile does - // from the symbol table. - auto MsymI = SymTab.symbols().begin(), MsymE = SymTab.symbols().end(); - auto Skip = [&]() { - while (MsymI != MsymE) { - auto Flags = SymTab.getSymbolFlags(*MsymI); - if ((Flags & object::BasicSymbolRef::SF_Global) && - !(Flags & object::BasicSymbolRef::SF_FormatSpecific)) - return; - ++MsymI; - } - }; - Skip(); - - for (const InputFile::Symbol &Sym : Syms) { + for (const InputFile::Symbol &Sym : + make_range(InputFile::symbol_iterator(SymTab.symbols().begin(), SymTab, + nullptr), + InputFile::symbol_iterator(SymTab.symbols().end(), SymTab, + nullptr))) { assert(ResI != ResE); SymbolResolution Res = *ResI++; - addSymbolToGlobalRes(Sym, Res, 0); + addSymbolToGlobalRes(Used, Sym, Res, 0); - assert(MsymI != MsymE); - ModuleSymbolTable::Symbol Msym = *MsymI++; - Skip(); - - if (GlobalValue *GV = Msym.dyn_cast<GlobalValue *>()) { + if (Sym.isGV()) { + GlobalValue *GV = Sym.getGV(); if (Res.Prevailing) { if (Sym.isUndefined()) continue; @@ -570,7 +612,7 @@ Error LTO::addRegularLTO(BitcodeModule BM, if (Sym.isCommon()) { // FIXME: We should figure out what to do about commons defined by asm. // For now they aren't reported correctly by ModuleSymbolTable. - auto &CommonRes = RegularLTO.Commons[Sym.getIRName()]; + auto &CommonRes = RegularLTO.Commons[Sym.getGV()->getName()]; CommonRes.Size = std::max(CommonRes.Size, Sym.getCommonSize()); CommonRes.Align = std::max(CommonRes.Align, Sym.getCommonAlignment()); CommonRes.Prevailing |= Res.Prevailing; @@ -578,7 +620,6 @@ Error LTO::addRegularLTO(BitcodeModule BM, // FIXME: use proposed local attribute for FinalDefinitionInLinkageUnit. } - assert(MsymI == MsymE); return RegularLTO.Mover->move(std::move(*MOrErr), Keep, [](GlobalValue &, IRMover::ValueAdder) {}, @@ -586,10 +627,15 @@ Error LTO::addRegularLTO(BitcodeModule BM, } // Add a ThinLTO object to the link. -Error LTO::addThinLTO(BitcodeModule BM, - ArrayRef<InputFile::Symbol> Syms, +// FIXME: This function should not need to take as many parameters once we have +// a bitcode symbol table. +Error LTO::addThinLTO(BitcodeModule BM, Module &M, + iterator_range<InputFile::symbol_iterator> Syms, const SymbolResolution *&ResI, const SymbolResolution *ResE) { + SmallPtrSet<GlobalValue *, 8> Used; + collectUsedGlobalVariables(M, Used, /*CompilerUsed*/ false); + Expected<std::unique_ptr<ModuleSummaryIndex>> SummaryOrErr = BM.getSummary(); if (!SummaryOrErr) return SummaryOrErr.takeError(); @@ -599,15 +645,11 @@ Error LTO::addThinLTO(BitcodeModule BM, for (const InputFile::Symbol &Sym : Syms) { assert(ResI != ResE); SymbolResolution Res = *ResI++; - addSymbolToGlobalRes(Sym, Res, ThinLTO.ModuleMap.size() + 1); + addSymbolToGlobalRes(Used, Sym, Res, ThinLTO.ModuleMap.size() + 1); - if (Res.Prevailing) { - if (!Sym.getIRName().empty()) { - auto GUID = GlobalValue::getGUID(GlobalValue::getGlobalIdentifier( - Sym.getIRName(), GlobalValue::ExternalLinkage, "")); - ThinLTO.PrevailingModuleForGUID[GUID] = BM.getModuleIdentifier(); - } - } + if (Res.Prevailing && Sym.isGV()) + ThinLTO.PrevailingModuleForGUID[Sym.getGV()->getGUID()] = + BM.getModuleIdentifier(); } if (!ThinLTO.ModuleMap.insert({BM.getModuleIdentifier(), BM}).second) |