aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDerek Schuff <dschuff@chromium.org>2013-01-11 15:29:34 -0800
committerDerek Schuff <dschuff@chromium.org>2013-01-11 15:29:34 -0800
commit0590f4264010a852dc22c9afa16a7df4d004c19a (patch)
tree018cedac9a062788c2fdc337165bbabc946b8d29
parentb770d0e0636a4b5ad61b1ca661caee67576c05fc (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
-rw-r--r--include/llvm/Module.h33
-rw-r--r--lib/AsmParser/Parser.cpp11
-rw-r--r--lib/Bitcode/Reader/BitcodeReader.cpp4
-rw-r--r--lib/Bitcode/Writer/BitcodeWriter.cpp3
-rw-r--r--lib/Linker/LinkItems.cpp28
-rw-r--r--lib/Linker/LinkModules.cpp15
-rw-r--r--lib/Transforms/Utils/CloneModule.cpp6
-rw-r--r--lib/VMCore/AsmWriter.cpp1
-rw-r--r--lib/VMCore/Module.cpp63
-rw-r--r--tools/llc/llc.cpp6
-rw-r--r--tools/lto/LTOCodeGenerator.cpp3
-rw-r--r--tools/pso-stub/pso-stub.cpp3
12 files changed, 153 insertions, 23 deletions
diff --git a/include/llvm/Module.h b/include/llvm/Module.h
index bf9ac51693..ae66edc5a6 100644
--- a/include/llvm/Module.h
+++ b/include/llvm/Module.h
@@ -21,6 +21,7 @@
#include "llvm/GlobalVariable.h"
#include "llvm/Metadata.h"
#include "llvm/Support/DataTypes.h"
+#include <vector> // @LOCALMOD
namespace llvm {
@@ -120,7 +121,10 @@ public:
typedef iplist<GlobalAlias> AliasListType;
/// The type for the list of named metadata.
typedef ilist<NamedMDNode> NamedMDListType;
-
+ // @LOCALMOD-BEGIN
+ /// The type for the list of dependent libraries.
+ typedef std::vector<std::string> LibraryListType;
+ // @LOCALMOD-END
/// The Global Variable iterator.
typedef GlobalListType::iterator global_iterator;
/// The Global Variable constant iterator.
@@ -140,7 +144,10 @@ public:
typedef NamedMDListType::iterator named_metadata_iterator;
/// The named metadata constant interators.
typedef NamedMDListType::const_iterator const_named_metadata_iterator;
-
+ // @LOCALMOD-BEGIN
+ /// The Library list iterator.
+ typedef LibraryListType::const_iterator lib_iterator;
+ // @LOCALMOD-END
/// An enumeration for describing the endianess of the target machine.
enum Endianness { AnyEndianness, LittleEndian, BigEndian };
@@ -205,6 +212,8 @@ private:
GlobalListType GlobalList; ///< The Global Variables in the module
FunctionListType FunctionList; ///< The Functions in the module
AliasListType AliasList; ///< The Aliases in the module
+ // @LOCALMOD
+ LibraryListType LibraryList; ///< The Libraries needed by the module
NamedMDListType NamedMDList; ///< The named metadata in the module
std::string GlobalScopeAsm; ///< Inline Asm at global scope.
ValueSymbolTable *ValSymTab; ///< Symbol table for values
@@ -567,8 +576,28 @@ public:
const_iterator end () const { return FunctionList.end(); }
size_t size() const { return FunctionList.size(); }
bool empty() const { return FunctionList.empty(); }
+ // @LOCALMOD-BEGIN
+/// @}
+/// @name Dependent Library Iteration
+/// @{
+
+ /// @brief Get a constant iterator to beginning of dependent library list.
+ inline lib_iterator lib_begin() const { return LibraryList.begin(); }
+ /// @brief Get a constant iterator to end of dependent library list.
+ inline lib_iterator lib_end() const { return LibraryList.end(); }
+ /// @brief Returns the number of items in the list of libraries.
+ inline size_t lib_size() const { return LibraryList.size(); }
+ void convertMetadataToLibraryList();
+ void convertLibraryListToMetadata() const;
+ /// @brief Add a library to the list of dependent libraries
+ void addLibrary(StringRef Lib);
+ /// @brief Remove a library from the list of dependent libraries
+ void removeLibrary(StringRef Lib);
+ /// @brief Get all the libraries
+ inline const LibraryListType& getLibraries() const { return LibraryList; }
/// @}
+ // @LOCALMOD-END
/// @name Alias Iteration
/// @{
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
diff --git a/tools/llc/llc.cpp b/tools/llc/llc.cpp
index 0f03483fa0..e4294d7a04 100644
--- a/tools/llc/llc.cpp
+++ b/tools/llc/llc.cpp
@@ -216,12 +216,11 @@ void RecordMetadataForSrpc(const Module &mod) {
bool is_shared = (mod.getOutputFormat() == Module::SharedOutputFormat);
std::string soname = mod.getSOName();
NaClRecordObjectInformation(is_shared, soname);
- /* TEMPORARY LOCALMOD until we put back lib_iterator
for (Module::lib_iterator L = mod.lib_begin(),
E = mod.lib_end();
L != E; ++L) {
NaClRecordSharedLibraryDependency(*L);
- } */
+ }
}
#endif // defined(__native_client__) && defined(NACL_SRPC)
// @LOCALMOD-END
@@ -368,10 +367,9 @@ static int compileModule(char **argv, LLVMContext &Context) {
}
// Also set PIC_ for dynamic executables:
// BUG= http://code.google.com/p/nativeclient/issues/detail?id=2351
- /* TEMPORARY LOCALMOD until we put back lib_iterator
if (mod->lib_size() > 0) {
RelocModel = Reloc::PIC_;
- } */
+ }
#endif // defined(__native_client__) && defined(NACL_SRPC)
// @LOCALMOD-END
diff --git a/tools/lto/LTOCodeGenerator.cpp b/tools/lto/LTOCodeGenerator.cpp
index da9b90eff1..70ede89629 100644
--- a/tools/lto/LTOCodeGenerator.cpp
+++ b/tools/lto/LTOCodeGenerator.cpp
@@ -219,8 +219,7 @@ void LTOCodeGenerator::setMergedModuleSOName(const char *soname)
void LTOCodeGenerator::addLibraryDep(const char *lib)
{
Module *mergedModule = _linker.getModule();
- // TEMPORARY: make it compile until we add back addLibrary
- //mergedModule->addLibrary(lib);
+ mergedModule->addLibrary(lib);
}
void LTOCodeGenerator::wrapSymbol(const char *sym)
diff --git a/tools/pso-stub/pso-stub.cpp b/tools/pso-stub/pso-stub.cpp
index fc6e184866..1fdc868499 100644
--- a/tools/pso-stub/pso-stub.cpp
+++ b/tools/pso-stub/pso-stub.cpp
@@ -162,8 +162,7 @@ void TransferLibrariesNeeded(Module *M, const ObjectFile *obj) {
StringRef path;
it->getPath(path);
outs() << "Adding library " << path << "\n";
- // TEMPORARY LOCALMOD
- // make it compile until we add back addLibrary M->addLibrary(path);
+ M->addLibrary(path);
}
}