diff options
author | Eli Bendersky <eliben@chromium.org> | 2013-03-11 15:16:37 -0700 |
---|---|---|
committer | Eli Bendersky <eliben@chromium.org> | 2013-03-11 15:16:37 -0700 |
commit | 23c00401dad33ca247d2818e71540079bed63c5b (patch) | |
tree | df9f25d60f9538fbde84b78cf3c4e4a00eb6c3db /lib/Linker | |
parent | 79da56afe68a0c5b2c2227681014dd13705d78cc (diff) | |
parent | 279b9184c2ff4fea93b198a3519b8cb3a1d8d195 (diff) |
Merge commit '279b9184c2ff4fea93b198a3519b8cb3a1d8d195'
Conflicts:
include/llvm/CodeGen/LexicalScopes.h
include/llvm/MC/MCAsmInfo.h
lib/Linker/LinkArchives.cpp
lib/Linker/LinkItems.cpp
lib/MC/MCAsmInfo.cpp
lib/MC/MCDwarf.cpp
lib/Target/ARM/ARMInstrInfo.td
lib/Target/ARM/ARMSubtarget.cpp
lib/Target/ARM/MCTargetDesc/ARMMCTargetDesc.cpp
lib/Target/Mips/MCTargetDesc/MipsELFObjectWriter.cpp
lib/Target/Mips/MCTargetDesc/MipsMCTargetDesc.cpp
lib/Target/Mips/MipsAsmPrinter.cpp
lib/Target/Mips/MipsDelaySlotFiller.cpp
lib/Target/Mips/MipsISelDAGToDAG.cpp
lib/Target/Mips/MipsSubtarget.cpp
lib/Target/Mips/MipsSubtarget.h
lib/Target/Mips/MipsTargetObjectFile.cpp
lib/Target/X86/MCTargetDesc/X86MCAsmInfo.cpp
lib/Target/X86/X86FastISel.cpp
lib/Target/X86/X86ISelLowering.cpp
lib/Target/X86/X86TargetMachine.cpp
lib/Transforms/CMakeLists.txt
lib/Transforms/LLVMBuild.txt
lib/Transforms/Makefile
test/MC/ARM/arm_instructions.s
test/MC/X86/AlignedBundling/pad-align-to-bundle-end.s
Diffstat (limited to 'lib/Linker')
-rw-r--r-- | lib/Linker/CMakeLists.txt | 2 | ||||
-rw-r--r-- | lib/Linker/LLVMBuild.txt | 2 | ||||
-rw-r--r-- | lib/Linker/LinkModules.cpp | 261 | ||||
-rw-r--r-- | lib/Linker/Linker.cpp | 90 |
4 files changed, 128 insertions, 227 deletions
diff --git a/lib/Linker/CMakeLists.txt b/lib/Linker/CMakeLists.txt index 0b6d2f4218..28f1262a43 100644 --- a/lib/Linker/CMakeLists.txt +++ b/lib/Linker/CMakeLists.txt @@ -1,6 +1,4 @@ add_llvm_library(LLVMLinker - LinkArchives.cpp - LinkItems.cpp LinkModules.cpp Linker.cpp ) diff --git a/lib/Linker/LLVMBuild.txt b/lib/Linker/LLVMBuild.txt index 2b4c232b80..0bb26d0c2a 100644 --- a/lib/Linker/LLVMBuild.txt +++ b/lib/Linker/LLVMBuild.txt @@ -19,4 +19,4 @@ type = Library name = Linker parent = Libraries -required_libraries = Archive BitReader Core Support TransformUtils +required_libraries = Core Support TransformUtils diff --git a/lib/Linker/LinkModules.cpp b/lib/Linker/LinkModules.cpp index 15a4a1e24b..26061c280d 100644 --- a/lib/Linker/LinkModules.cpp +++ b/lib/Linker/LinkModules.cpp @@ -421,13 +421,6 @@ namespace { } void computeTypeMapping(); - bool categorizeModuleFlagNodes(const NamedMDNode *ModFlags, - DenseMap<MDString*, MDNode*> &ErrorNode, - DenseMap<MDString*, MDNode*> &WarningNode, - DenseMap<MDString*, MDNode*> &OverrideNode, - DenseMap<MDString*, - SmallSetVector<MDNode*, 8> > &RequireNodes, - SmallSetVector<MDString*, 16> &SeenIDs); bool linkAppendingVarProto(GlobalVariable *DstGV, GlobalVariable *SrcGV); bool linkGlobalProto(GlobalVariable *SrcGV); @@ -613,7 +606,8 @@ void ModuleLinker::computeTypeMapping() { // Check to see if there is a dot in the name followed by a digit. size_t DotPos = ST->getName().rfind('.'); if (DotPos == 0 || DotPos == StringRef::npos || - ST->getName().back() == '.' || !isdigit(ST->getName()[DotPos+1])) + ST->getName().back() == '.' || + !isdigit(static_cast<unsigned char>(ST->getName()[DotPos+1]))) continue; // Check to see if the destination module has a struct with the prefix name. @@ -1007,67 +1001,16 @@ void ModuleLinker::linkNamedMDNodes() { } } -/// categorizeModuleFlagNodes - Categorize the module flags according to their -/// type: Error, Warning, Override, and Require. -bool ModuleLinker:: -categorizeModuleFlagNodes(const NamedMDNode *ModFlags, - DenseMap<MDString*, MDNode*> &ErrorNode, - DenseMap<MDString*, MDNode*> &WarningNode, - DenseMap<MDString*, MDNode*> &OverrideNode, - DenseMap<MDString*, - SmallSetVector<MDNode*, 8> > &RequireNodes, - SmallSetVector<MDString*, 16> &SeenIDs) { - bool HasErr = false; - - for (unsigned I = 0, E = ModFlags->getNumOperands(); I != E; ++I) { - MDNode *Op = ModFlags->getOperand(I); - ConstantInt *Behavior = cast<ConstantInt>(Op->getOperand(0)); - MDString *ID = cast<MDString>(Op->getOperand(1)); - Value *Val = Op->getOperand(2); - switch (Behavior->getZExtValue()) { - case Module::Error: { - MDNode *&ErrNode = ErrorNode[ID]; - if (!ErrNode) ErrNode = Op; - if (ErrNode->getOperand(2) != Val) - HasErr = emitError("linking module flags '" + ID->getString() + - "': IDs have conflicting values"); - break; - } - case Module::Warning: { - MDNode *&WarnNode = WarningNode[ID]; - if (!WarnNode) WarnNode = Op; - if (WarnNode->getOperand(2) != Val) - errs() << "WARNING: linking module flags '" << ID->getString() - << "': IDs have conflicting values"; - break; - } - case Module::Require: RequireNodes[ID].insert(Op); break; - case Module::Override: { - MDNode *&OvrNode = OverrideNode[ID]; - if (!OvrNode) OvrNode = Op; - if (OvrNode->getOperand(2) != Val) - HasErr = emitError("linking module flags '" + ID->getString() + - "': IDs have conflicting override values"); - break; - } - } - - SeenIDs.insert(ID); - } - - return HasErr; -} - /// linkModuleFlagsMetadata - Merge the linker flags in Src into the Dest /// module. bool ModuleLinker::linkModuleFlagsMetadata() { + // If the source module has no module flags, we are done. const NamedMDNode *SrcModFlags = SrcM->getModuleFlagsMetadata(); if (!SrcModFlags) return false; - NamedMDNode *DstModFlags = DstM->getOrInsertModuleFlagsMetadata(); - // If the destination module doesn't have module flags yet, then just copy // over the source module's flags. + NamedMDNode *DstModFlags = DstM->getOrInsertModuleFlagsMetadata(); if (DstModFlags->getNumOperands() == 0) { for (unsigned I = 0, E = SrcModFlags->getNumOperands(); I != E; ++I) DstModFlags->addOperand(SrcModFlags->getOperand(I)); @@ -1075,87 +1018,137 @@ bool ModuleLinker::linkModuleFlagsMetadata() { return false; } - bool HasErr = false; + // First build a map of the existing module flags and requirements. + DenseMap<MDString*, MDNode*> Flags; + SmallSetVector<MDNode*, 16> Requirements; + for (unsigned I = 0, E = DstModFlags->getNumOperands(); I != E; ++I) { + MDNode *Op = DstModFlags->getOperand(I); + ConstantInt *Behavior = cast<ConstantInt>(Op->getOperand(0)); + MDString *ID = cast<MDString>(Op->getOperand(1)); - // Otherwise, we have to merge them based on their behaviors. First, - // categorize all of the nodes in the modules' module flags. If an error or - // warning occurs, then emit the appropriate message(s). - DenseMap<MDString*, MDNode*> ErrorNode; - DenseMap<MDString*, MDNode*> WarningNode; - DenseMap<MDString*, MDNode*> OverrideNode; - DenseMap<MDString*, SmallSetVector<MDNode*, 8> > RequireNodes; - SmallSetVector<MDString*, 16> SeenIDs; - - HasErr |= categorizeModuleFlagNodes(SrcModFlags, ErrorNode, WarningNode, - OverrideNode, RequireNodes, SeenIDs); - HasErr |= categorizeModuleFlagNodes(DstModFlags, ErrorNode, WarningNode, - OverrideNode, RequireNodes, SeenIDs); - - // Check that there isn't both an error and warning node for a flag. - for (SmallSetVector<MDString*, 16>::iterator - I = SeenIDs.begin(), E = SeenIDs.end(); I != E; ++I) { - MDString *ID = *I; - if (ErrorNode[ID] && WarningNode[ID]) - HasErr = emitError("linking module flags '" + ID->getString() + - "': IDs have conflicting behaviors"); + if (Behavior->getZExtValue() == Module::Require) { + Requirements.insert(cast<MDNode>(Op->getOperand(2))); + } else { + Flags[ID] = Op; + } } - // Early exit if we had an error. - if (HasErr) return true; - - // Get the destination's module flags ready for new operands. - DstModFlags->dropAllReferences(); - - // Add all of the module flags to the destination module. - DenseMap<MDString*, SmallVector<MDNode*, 4> > AddedNodes; - for (SmallSetVector<MDString*, 16>::iterator - I = SeenIDs.begin(), E = SeenIDs.end(); I != E; ++I) { - MDString *ID = *I; - if (OverrideNode[ID]) { - DstModFlags->addOperand(OverrideNode[ID]); - AddedNodes[ID].push_back(OverrideNode[ID]); - } else if (ErrorNode[ID]) { - DstModFlags->addOperand(ErrorNode[ID]); - AddedNodes[ID].push_back(ErrorNode[ID]); - } else if (WarningNode[ID]) { - DstModFlags->addOperand(WarningNode[ID]); - AddedNodes[ID].push_back(WarningNode[ID]); + // Merge in the flags from the source module, and also collect its set of + // requirements. + bool HasErr = false; + for (unsigned I = 0, E = SrcModFlags->getNumOperands(); I != E; ++I) { + MDNode *SrcOp = SrcModFlags->getOperand(I); + ConstantInt *SrcBehavior = cast<ConstantInt>(SrcOp->getOperand(0)); + MDString *ID = cast<MDString>(SrcOp->getOperand(1)); + MDNode *DstOp = Flags.lookup(ID); + unsigned SrcBehaviorValue = SrcBehavior->getZExtValue(); + + // If this is a requirement, add it and continue. + if (SrcBehaviorValue == Module::Require) { + // If the destination module does not already have this requirement, add + // it. + if (Requirements.insert(cast<MDNode>(SrcOp->getOperand(2)))) { + DstModFlags->addOperand(SrcOp); + } + continue; + } + + // If there is no existing flag with this ID, just add it. + if (!DstOp) { + Flags[ID] = SrcOp; + DstModFlags->addOperand(SrcOp); + continue; } - for (SmallSetVector<MDNode*, 8>::iterator - II = RequireNodes[ID].begin(), IE = RequireNodes[ID].end(); - II != IE; ++II) - DstModFlags->addOperand(*II); - } + // Otherwise, perform a merge. + ConstantInt *DstBehavior = cast<ConstantInt>(DstOp->getOperand(0)); + unsigned DstBehaviorValue = DstBehavior->getZExtValue(); + + // If either flag has override behavior, handle it first. + if (DstBehaviorValue == Module::Override) { + // Diagnose inconsistent flags which both have override behavior. + if (SrcBehaviorValue == Module::Override && + SrcOp->getOperand(2) != DstOp->getOperand(2)) { + HasErr |= emitError("linking module flags '" + ID->getString() + + "': IDs have conflicting override values"); + } + continue; + } else if (SrcBehaviorValue == Module::Override) { + // Update the destination flag to that of the source. + DstOp->replaceOperandWith(0, SrcBehavior); + DstOp->replaceOperandWith(2, SrcOp->getOperand(2)); + continue; + } - // Now check that all of the requirements have been satisfied. - for (SmallSetVector<MDString*, 16>::iterator - I = SeenIDs.begin(), E = SeenIDs.end(); I != E; ++I) { - MDString *ID = *I; - SmallSetVector<MDNode*, 8> &Set = RequireNodes[ID]; - - for (SmallSetVector<MDNode*, 8>::iterator - II = Set.begin(), IE = Set.end(); II != IE; ++II) { - MDNode *Node = *II; - MDNode *Val = cast<MDNode>(Node->getOperand(2)); - - MDString *ReqID = cast<MDString>(Val->getOperand(0)); - Value *ReqVal = Val->getOperand(1); - - bool HasValue = false; - for (SmallVectorImpl<MDNode*>::iterator - RI = AddedNodes[ReqID].begin(), RE = AddedNodes[ReqID].end(); - RI != RE; ++RI) { - MDNode *ReqNode = *RI; - if (ReqNode->getOperand(2) == ReqVal) { - HasValue = true; - break; - } + // Diagnose inconsistent merge behavior types. + if (SrcBehaviorValue != DstBehaviorValue) { + HasErr |= emitError("linking module flags '" + ID->getString() + + "': IDs have conflicting behaviors"); + continue; + } + + // Perform the merge for standard behavior types. + switch (SrcBehaviorValue) { + case Module::Require: + case Module::Override: assert(0 && "not possible"); break; + case Module::Error: { + // Emit an error if the values differ. + if (SrcOp->getOperand(2) != DstOp->getOperand(2)) { + HasErr |= emitError("linking module flags '" + ID->getString() + + "': IDs have conflicting values"); } + continue; + } + case Module::Warning: { + // Emit a warning if the values differ. + if (SrcOp->getOperand(2) != DstOp->getOperand(2)) { + errs() << "WARNING: linking module flags '" << ID->getString() + << "': IDs have conflicting values"; + } + continue; + } + case Module::Append: { + MDNode *DstValue = cast<MDNode>(DstOp->getOperand(2)); + MDNode *SrcValue = cast<MDNode>(SrcOp->getOperand(2)); + unsigned NumOps = DstValue->getNumOperands() + SrcValue->getNumOperands(); + Value **VP, **Values = VP = new Value*[NumOps]; + for (unsigned i = 0, e = DstValue->getNumOperands(); i != e; ++i, ++VP) + *VP = DstValue->getOperand(i); + for (unsigned i = 0, e = SrcValue->getNumOperands(); i != e; ++i, ++VP) + *VP = SrcValue->getOperand(i); + DstOp->replaceOperandWith(2, MDNode::get(DstM->getContext(), + ArrayRef<Value*>(Values, + NumOps))); + delete[] Values; + break; + } + case Module::AppendUnique: { + SmallSetVector<Value*, 16> Elts; + MDNode *DstValue = cast<MDNode>(DstOp->getOperand(2)); + MDNode *SrcValue = cast<MDNode>(SrcOp->getOperand(2)); + for (unsigned i = 0, e = DstValue->getNumOperands(); i != e; ++i) + Elts.insert(DstValue->getOperand(i)); + for (unsigned i = 0, e = SrcValue->getNumOperands(); i != e; ++i) + Elts.insert(SrcValue->getOperand(i)); + DstOp->replaceOperandWith(2, MDNode::get(DstM->getContext(), + ArrayRef<Value*>(Elts.begin(), + Elts.end()))); + break; + } + } + } + + // Check all of the requirements. + for (unsigned I = 0, E = Requirements.size(); I != E; ++I) { + MDNode *Requirement = Requirements[I]; + MDString *Flag = cast<MDString>(Requirement->getOperand(0)); + Value *ReqValue = Requirement->getOperand(1); - if (!HasValue) - HasErr = emitError("linking module flags '" + ReqID->getString() + - "': does not have the required value"); + MDNode *Op = Flags[Flag]; + if (!Op || Op->getOperand(2) != ReqValue) { + HasErr |= emitError("linking module flags '" + Flag->getString() + + "': does not have the required value"); + continue; } } diff --git a/lib/Linker/Linker.cpp b/lib/Linker/Linker.cpp index a30363d0ff..c8ea8ff0a9 100644 --- a/lib/Linker/Linker.cpp +++ b/lib/Linker/Linker.cpp @@ -89,93 +89,3 @@ Linker::releaseModule() { Flags = 0; return result; } - -// LoadObject - Read in and parse the bitcode file named by FN and return the -// module it contains (wrapped in an auto_ptr), or auto_ptr<Module>() and set -// Error if an error occurs. -std::auto_ptr<Module> -Linker::LoadObject(const sys::Path &FN) { - std::string ParseErrorMessage; - Module *Result = 0; - - OwningPtr<MemoryBuffer> Buffer; - if (error_code ec = MemoryBuffer::getFileOrSTDIN(FN.c_str(), Buffer)) - ParseErrorMessage = "Error reading file '" + FN.str() + "'" + ": " - + ec.message(); - else - Result = ParseBitcodeFile(Buffer.get(), Context, &ParseErrorMessage); - - if (Result) - return std::auto_ptr<Module>(Result); - Error = "Bitcode file '" + FN.str() + "' could not be loaded"; - if (ParseErrorMessage.size()) - Error += ": " + ParseErrorMessage; - return std::auto_ptr<Module>(); -} - -// IsLibrary - Determine if "Name" is a library in "Directory". Return -// a non-empty sys::Path if its found, an empty one otherwise. -static inline sys::Path IsLibrary(StringRef Name, - const sys::Path &Directory) { - - sys::Path FullPath(Directory); - - // Try the libX.a form - FullPath.appendComponent(("lib" + Name).str()); - FullPath.appendSuffix("a"); - if (FullPath.isArchive()) - return FullPath; - - // Try the libX.bca form - FullPath.eraseSuffix(); - FullPath.appendSuffix("bca"); - if (FullPath.isArchive()) - return FullPath; - - // Try the libX.so (or .dylib) form - FullPath.eraseSuffix(); - FullPath.appendSuffix(sys::Path::GetDLLSuffix()); - if (FullPath.isDynamicLibrary()) // Native shared library? - return FullPath; - if (FullPath.isBitcodeFile()) // .so file containing bitcode? - return FullPath; - - // Try libX form, to make it possible to add dependency on the - // specific version of .so, like liblzma.so.1.0.0 - FullPath.eraseSuffix(); - if (FullPath.isDynamicLibrary()) // Native shared library? - return FullPath; - if (FullPath.isBitcodeFile()) // .so file containing bitcode? - return FullPath; - - // Not found .. fall through - - // Indicate that the library was not found in the directory. - FullPath.clear(); - return FullPath; -} - -/// FindLib - Try to convert Filename into the name of a file that we can open, -/// if it does not already name a file we can open, by first trying to open -/// Filename, then libFilename.[suffix] for each of a set of several common -/// library suffixes, in each of the directories in LibPaths. Returns an empty -/// Path if no matching file can be found. -/// -sys::Path -Linker::FindLib(StringRef Filename) { - // Determine if the pathname can be found as it stands. - sys::Path FilePath(Filename); - if (FilePath.canRead() && - (FilePath.isArchive() || FilePath.isDynamicLibrary())) - return FilePath; - - // Iterate over the directories in Paths to see if we can find the library - // there. - for (unsigned Index = 0; Index != LibPaths.size(); ++Index) { - sys::Path Directory(LibPaths[Index]); - sys::Path FullPath = IsLibrary(Filename, Directory); - if (!FullPath.isEmpty()) - return FullPath; - } - return sys::Path(); -} |