diff options
| author | Derek Schuff <dschuff@chromium.org> | 2013-01-11 15:29:34 -0800 |
|---|---|---|
| committer | Derek Schuff <dschuff@chromium.org> | 2013-01-11 15:29:34 -0800 |
| commit | 0590f4264010a852dc22c9afa16a7df4d004c19a (patch) | |
| tree | 018cedac9a062788c2fdc337165bbabc946b8d29 /lib | |
| parent | b770d0e0636a4b5ad61b1ca661caee67576c05fc (diff) | |
Replace DepLibs bitcode record with metadata
It keeps the same Module interface as the existing/old deplibs feature, but populates the library list from the metadata after reading the bitcode/LL into the Module.
Keeping the same module interface will allow us to keep the existing uses (e.g. in the gold plugin) as they are.
Internally it still uses the LibraryList variable, but uses it basically as a cache backed by the metadata.
BUG=
Review URL: https://codereview.chromium.org/11615013
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/AsmParser/Parser.cpp | 11 | ||||
| -rw-r--r-- | lib/Bitcode/Reader/BitcodeReader.cpp | 4 | ||||
| -rw-r--r-- | lib/Bitcode/Writer/BitcodeWriter.cpp | 3 | ||||
| -rw-r--r-- | lib/Linker/LinkItems.cpp | 28 | ||||
| -rw-r--r-- | lib/Linker/LinkModules.cpp | 15 | ||||
| -rw-r--r-- | lib/Transforms/Utils/CloneModule.cpp | 6 | ||||
| -rw-r--r-- | lib/VMCore/AsmWriter.cpp | 1 | ||||
| -rw-r--r-- | lib/VMCore/Module.cpp | 63 |
8 files changed, 118 insertions, 13 deletions
diff --git a/lib/AsmParser/Parser.cpp b/lib/AsmParser/Parser.cpp index a473e6b713..57b4b64895 100644 --- a/lib/AsmParser/Parser.cpp +++ b/lib/AsmParser/Parser.cpp @@ -31,12 +31,21 @@ Module *llvm::ParseAssembly(MemoryBuffer *F, // If we are parsing into an existing module, do it. if (M) - return LLParser(F, SM, Err, M).Run() ? 0 : M; + // @LOCALMOD-BEGIN + if (LLParser(F, SM, Err, M).Run()) { + return 0; + } + else { + M->convertMetadataToLibraryList(); + return M; + } + // @LOCALMOD-END // Otherwise create a new module. OwningPtr<Module> M2(new Module(F->getBufferIdentifier(), Context)); if (LLParser(F, SM, Err, M2.get()).Run()) return 0; + M2->convertMetadataToLibraryList(); // @LOCALMOD return M2.take(); } diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 6098c1d61c..95650c5260 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -2999,6 +2999,8 @@ Module *llvm::getLazyBitcodeModule(MemoryBuffer *Buffer, R->materializeForwardReferencedFunctions(); + M->convertMetadataToLibraryList(); // @LOCALMOD + return M; } @@ -3020,6 +3022,8 @@ Module *llvm::getStreamedBitcodeModule(const std::string &name, R->materializeForwardReferencedFunctions(); + M->convertMetadataToLibraryList(); // @LOCALMOD + return M; } diff --git a/lib/Bitcode/Writer/BitcodeWriter.cpp b/lib/Bitcode/Writer/BitcodeWriter.cpp index ffe95d8f27..4ee63c486e 100644 --- a/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -1942,6 +1942,9 @@ void llvm::WriteBitcodeToFile(const Module *M, raw_ostream &Out) { SmallVector<char, 0> Buffer; Buffer.reserve(256*1024); + // Convert Deplib info to metadata + M->convertLibraryListToMetadata(); // @LOCALMOD + // If this is darwin or another generic macho target, reserve space for the // header. Triple TT(M->getTargetTriple()); diff --git a/lib/Linker/LinkItems.cpp b/lib/Linker/LinkItems.cpp index 124e5e4e4d..c3e55976bc 100644 --- a/lib/Linker/LinkItems.cpp +++ b/lib/Linker/LinkItems.cpp @@ -51,6 +51,21 @@ Linker::LinkInItems(const ItemList& Items, ItemList& NativeItems) { } } + // @LOCALMOD-BEGIN + // At this point we have processed all the link items provided to us. Since + // we have an aggregated module at this point, the dependent libraries in + // that module should also be aggregated with duplicates eliminated. This is + // now the time to process the dependent libraries to resolve any remaining + // symbols. + bool is_native; + for (Module::lib_iterator I = Composite->lib_begin(), + E = Composite->lib_end(); I != E; ++I) { + if(LinkInLibrary(*I, is_native)) + return true; + if (is_native) + NativeItems.push_back(std::make_pair(*I, true)); + } + // @LOCALMOD-END return false; } @@ -113,7 +128,18 @@ bool Linker::LinkInLibraries(const std::vector<std::string> &Libraries) { for (unsigned i = 0; i < Libraries.size(); ++i) if (LinkInLibrary(Libraries[i], is_native)) return true; - + // @LOCALMOD-BEGIN + // At this point we have processed all the libraries provided to us. Since + // we have an aggregated module at this point, the dependent libraries in + // that module should also be aggregated with duplicates eliminated. This is + // now the time to process the dependent libraries to resolve any remaining + // symbols. + const Module::LibraryListType& DepLibs = Composite->getLibraries(); + for (Module::LibraryListType::const_iterator I = DepLibs.begin(), + E = DepLibs.end(); I != E; ++I) + if (LinkInLibrary(*I, is_native)) + return true; + // @LOCALMOD-END return false; } diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp index 6554d9c429..d2aad0859d 100644 --- a/lib/Linker/LinkModules.cpp +++ b/lib/Linker/LinkModules.cpp @@ -1206,7 +1206,20 @@ bool ModuleLinker::run() { DstM->setModuleInlineAsm(DstM->getModuleInlineAsm()+"\n"+ SrcM->getModuleInlineAsm()); } - + // @LOCALMOD-BEGIN + // Update the destination module's dependent libraries list with the libraries + // from the source module. There's no opportunity for duplicates here as the + // Module ensures that duplicate insertions are discarded. + for (Module::lib_iterator SI = SrcM->lib_begin(), SE = SrcM->lib_end(); + SI != SE; ++SI) + DstM->addLibrary(*SI); + + // If the source library's module id is in the dependent library list of the + // destination library, remove it since that module is now linked in. + StringRef ModuleId = SrcM->getModuleIdentifier(); + if (!ModuleId.empty()) + DstM->removeLibrary(sys::path::stem(ModuleId)); + // @LOCALMOD-END // Loop over all of the linked values to compute type mappings. computeTypeMapping(); diff --git a/lib/Transforms/Utils/CloneModule.cpp b/lib/Transforms/Utils/CloneModule.cpp index 114babd101..29ab5a72c4 100644 --- a/lib/Transforms/Utils/CloneModule.cpp +++ b/lib/Transforms/Utils/CloneModule.cpp @@ -37,7 +37,11 @@ Module *llvm::CloneModule(const Module *M, ValueToValueMapTy &VMap) { New->setDataLayout(M->getDataLayout()); New->setTargetTriple(M->getTargetTriple()); New->setModuleInlineAsm(M->getModuleInlineAsm()); - + // @LOCALMOD-BEGIN + // Copy all of the dependent libraries over. + for (Module::lib_iterator I = M->lib_begin(), E = M->lib_end(); I != E; ++I) + New->addLibrary(*I); + // @LOCALMOD-END // Loop over all of the global variables, making corresponding globals in the // new module. Here we add them to the VMap and to the new Module. We // don't worry about attributes or initializers, they will come later. diff --git a/lib/VMCore/AsmWriter.cpp b/lib/VMCore/AsmWriter.cpp index 4ad08ff8a2..7268e4b684 100644 --- a/lib/VMCore/AsmWriter.cpp +++ b/lib/VMCore/AsmWriter.cpp @@ -2073,6 +2073,7 @@ void Module::print(raw_ostream &ROS, AssemblyAnnotationWriter *AAW) const { SlotTracker SlotTable(this); formatted_raw_ostream OS(ROS); AssemblyWriter W(OS, SlotTable, this, AAW); + convertLibraryListToMetadata(); // @LOCALMOD W.printModule(this); } diff --git a/lib/VMCore/Module.cpp b/lib/VMCore/Module.cpp index e6e7d99afb..206445ee13 100644 --- a/lib/VMCore/Module.cpp +++ b/lib/VMCore/Module.cpp @@ -56,6 +56,7 @@ Module::~Module() { GlobalList.clear(); FunctionList.clear(); AliasList.clear(); + LibraryList.clear(); // @LOCALMOD NamedMDList.clear(); delete ValSymTab; delete static_cast<StringMap<NamedMDNode *> *>(NamedMDSymTab); @@ -451,12 +452,59 @@ void Module::dropAllReferences() { I->dropAllReferences(); } - // @LOCALMOD-BEGIN -// TODO(pdox): -// If possible, use actual bitcode records instead of NamedMetadata. -// This is contingent upon whether we can get these changes upstreamed -// immediately, to avoid creating incompatibilities in the bitcode format. +void Module::convertMetadataToLibraryList() { + LibraryList.clear(); + // Get the DepLib node + NamedMDNode *Node = getNamedMetadata("DepLibs"); + if (!Node) + return; + for (unsigned i = 0; i < Node->getNumOperands(); i++) { + MDString* Mds = dyn_cast_or_null<MDString>( + Node->getOperand(i)->getOperand(0)); + assert(Mds && "Bad NamedMetadata operand"); + LibraryList.push_back(Mds->getString()); + } + // Clear the metadata so the linker won't try to merge it + Node->dropAllReferences(); +} + +void Module::convertLibraryListToMetadata() const { + if (LibraryList.size() == 0) + return; + // Get the DepLib node + NamedMDNode *Node = getNamedMetadata("DepLibs"); + assert(Node && "DepLibs metadata node missing"); + // Erase all existing operands + Node->dropAllReferences(); + // Add all libraries from the library list + for (Module::lib_iterator I = lib_begin(), E = lib_end(); I != E; ++I) { + MDString *value = MDString::get(getContext(), *I); + Node->addOperand(MDNode::get(getContext(), + makeArrayRef(static_cast<Value*>(value)))); + } +} + +void Module::addLibrary(StringRef Lib) { + for (Module::lib_iterator I = lib_begin(), E = lib_end(); I != E; ++I) + if (*I == Lib) + return; + LibraryList.push_back(Lib); + // If the module previously had no deplibs, it may not have the metadata node. + // Ensure it exists now, so that we don't have to create it in + // convertLibraryListToMetadata (which is const) + getOrInsertNamedMetadata("DepLibs"); +} + +void Module::removeLibrary(StringRef Lib) { + LibraryListType::iterator I = LibraryList.begin(); + LibraryListType::iterator E = LibraryList.end(); + for (;I != E; ++I) + if (*I == Lib) { + LibraryList.erase(I); + return; + } +} static std::string ModuleMetaGet(const Module *module, StringRef MetaName) { @@ -559,12 +607,11 @@ Module::dumpMeta(raw_ostream &OS) const { } OS << "\n"; OS << "SOName: " << getSOName() << "\n"; - /* Commented out until we put lib_iterator back for (Module::lib_iterator L = lib_begin(), E = lib_end(); L != E; ++L) { OS << "NeedsLibrary: " << (*L) << "\n"; - }*/ + } std::vector<NeededRecord> NList; getNeededRecords(&NList); for (unsigned i = 0; i < NList.size(); ++i) { @@ -622,12 +669,10 @@ static void getNeededRecordFor(const Module *M, // Place the complete list of needed records in NeededOut. void Module::getNeededRecords(std::vector<NeededRecord> *NeededOut) const { // Iterate through the libraries needed, grabbing each NeededRecord. - /* commented out until we pub lib_iterator back for (lib_iterator I = lib_begin(), E = lib_end(); I != E; ++I) { NeededRecord NR; getNeededRecordFor(this, *I, &NR); NeededOut->push_back(NR); } - */ } // @LOCALMOD-END |
