//===----------------------------------------------------------------------===//
#include "llvm/Linker.h"
-#include "llvm/Constants.h"
-#include "llvm/DerivedTypes.h"
-#include "llvm/Instructions.h"
-#include "llvm/Module.h"
+#include "llvm-c/Linker.h"
#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/Optional.h"
#include "llvm/ADT/SetVector.h"
#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/IR/Constants.h"
+#include "llvm/IR/DerivedTypes.h"
+#include "llvm/IR/Instructions.h"
+#include "llvm/IR/Module.h"
+#include "llvm/IR/TypeFinder.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/Path.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Transforms/Utils/Cloning.h"
#include "llvm/Transforms/Utils/ValueMapper.h"
-#include "llvm-c/Linker.h"
#include <cctype>
using namespace llvm;
if (DATy->getNumElements() != cast<ArrayType>(SrcTy)->getNumElements())
return false;
} else if (VectorType *DVTy = dyn_cast<VectorType>(DstTy)) {
- if (DVTy->getNumElements() != cast<ArrayType>(SrcTy)->getNumElements())
+ if (DVTy->getNumElements() != cast<VectorType>(SrcTy)->getNumElements())
return false;
}
}
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);
// At this point, the destination module may have a type "%foo = { i32 }" for
// example. When the source module got loaded into the same LLVMContext, if
// it had the same type, it would have been renamed to "%foo.42 = { i32 }".
- std::vector<StructType*> SrcStructTypes;
- SrcM->findUsedStructTypes(SrcStructTypes, true);
+ TypeFinder SrcStructTypes;
+ SrcStructTypes.run(*SrcM, true);
SmallPtrSet<StructType*, 32> SrcStructTypesSet(SrcStructTypes.begin(),
SrcStructTypes.end());
- std::vector<StructType*> DstStructTypes;
- DstM->findUsedStructTypes(DstStructTypes, true);
+ TypeFinder DstStructTypes;
+ DstStructTypes.run(*DstM, true);
SmallPtrSet<StructType*, 32> DstStructTypesSet(DstStructTypes.begin(),
DstStructTypes.end());
// 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.
GlobalVariable *NG =
new GlobalVariable(*DstGV->getParent(), NewType, SrcGV->isConstant(),
DstGV->getLinkage(), /*init*/0, /*name*/"", DstGV,
- DstGV->isThreadLocal(),
+ DstGV->getThreadLocalMode(),
DstGV->getType()->getAddressSpace());
// Propagate alignment, visibility and section info.
new GlobalVariable(*DstM, TypeMap.get(SGV->getType()->getElementType()),
SGV->isConstant(), SGV->getLinkage(), /*init*/0,
SGV->getName(), /*insertbefore*/0,
- SGV->isThreadLocal(),
+ SGV->getThreadLocalMode(),
SGV->getType()->getAddressSpace());
// Propagate alignment, visibility and section info.
copyGVAttributes(NewDGV, SGV);
}
}
-/// 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);
- assert(Op->getNumOperands() == 3 && "Invalid module flag metadata!");
- assert(isa<ConstantInt>(Op->getOperand(0)) &&
- "Module flag's first operand must be an integer!");
- assert(isa<MDString>(Op->getOperand(1)) &&
- "Module flag's second operand must be an MDString!");
-
- ConstantInt *Behavior = cast<ConstantInt>(Op->getOperand(0));
- MDString *ID = cast<MDString>(Op->getOperand(1));
- Value *Val = Op->getOperand(2);
- switch (Behavior->getZExtValue()) {
- default:
- assert(false && "Invalid behavior in module flag metadata!");
- break;
- 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));
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;
- assert(isa<MDNode>(Node->getOperand(2)) &&
- "Module flag's third operand must be an MDNode!");
- 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;
+ }
+ }
+ }
- if (!HasValue)
- HasErr = emitError("linking module flags '" + ReqID->getString() +
- "': does not have the required value");
+ // 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);
+
+ MDNode *Op = Flags[Flag];
+ if (!Op || Op->getOperand(2) != ReqValue) {
+ HasErr |= emitError("linking module flags '" + Flag->getString() +
+ "': does not have the required value");
+ continue;
}
}
SrcM->getModuleInlineAsm());
}
- // 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));
-
// Loop over all of the linked values to compute type mappings.
computeTypeMapping();