#include "llvm/DerivedTypes.h"
#include "llvm/Instructions.h"
#include "llvm/Module.h"
-#include "llvm/ADT/SmallPtrSet.h"
+#include "llvm/TypeFinder.h"
+#include "llvm/ADT/DenseSet.h"
#include "llvm/ADT/Optional.h"
-#include "llvm/Support/raw_ostream.h"
+#include "llvm/ADT/SetVector.h"
+#include "llvm/ADT/SmallPtrSet.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;
//===----------------------------------------------------------------------===//
/// DstResolvedOpaqueTypes - This is the set of opaque types in the
/// destination modules who are getting a body from the source module.
SmallPtrSet<StructType*, 16> DstResolvedOpaqueTypes;
+
public:
-
/// addTypeMapping - Indicate that the specified type in the destination
/// module is conceptually equivalent to the specified type in the source
/// module.
FunctionType *get(FunctionType *T) {return cast<FunctionType>(get((Type*)T));}
+ /// dump - Dump out the type map for debugging purposes.
+ void dump() const {
+ for (DenseMap<Type*, Type*>::const_iterator
+ I = MappedTypes.begin(), E = MappedTypes.end(); I != E; ++I) {
+ dbgs() << "TypeMap: ";
+ I->first->dump();
+ dbgs() << " => ";
+ I->second->dump();
+ dbgs() << '\n';
+ }
+ }
+
private:
Type *getImpl(Type *T);
/// remapType - Implement the ValueMapTypeRemapper interface.
DstResolvedOpaqueTypes.clear();
}
-
/// get - Return the mapped type to use for the specified input type from the
/// source module.
Type *TypeMapTy::get(Type *Ty) {
// Otherwise, rebuild a modified type.
switch (Ty->getTypeID()) {
- default: assert(0 && "unknown derived type to remap");
+ default: llvm_unreachable("unknown derived type to remap");
case Type::ArrayTyID:
return *Entry = ArrayType::get(ElementTypes[0],
cast<ArrayType>(Ty)->getNumElements());
return *Entry = DTy;
}
-
-
//===----------------------------------------------------------------------===//
// ModuleLinker implementation.
//===----------------------------------------------------------------------===//
}
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);
bool linkFunctionProto(Function *SrcF);
bool linkAliasProto(GlobalAlias *SrcA);
+ bool linkModuleFlagsMetadata();
void linkAppendingVarInit(const AppendingVarInfo &AVI);
void linkGlobalInits();
};
}
-
-
/// forceRenaming - The LLVM SymbolTable class autorenames globals that conflict
/// in the symbol table. This is good for all clients except for us. Go
/// through the trouble to force this back.
}
}
-/// CopyGVAttributes - copy additional attributes (those not needed to construct
+/// copyGVAttributes - copy additional attributes (those not needed to construct
/// a GlobalValue) from the SrcGV to the DestGV.
-static void CopyGVAttributes(GlobalValue *DestGV, const GlobalValue *SrcGV) {
+static void copyGVAttributes(GlobalValue *DestGV, const GlobalValue *SrcGV) {
// Use the maximum alignment, rather than just copying the alignment of SrcGV.
unsigned Alignment = std::max(DestGV->getAlignment(), SrcGV->getAlignment());
DestGV->copyAttributesFrom(SrcGV);
if (GlobalValue *DGV = getLinkedToGlobal(I))
TypeMap.addTypeMapping(DGV->getType(), I->getType());
}
-
+
// Incorporate types by name, scanning all the types in the source module.
// 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 }".
- // Though it isn't required for correctness, attempt to link these up to clean
- // up the IR.
- std::vector<StructType*> SrcStructTypes;
- SrcM->findUsedStructTypes(SrcStructTypes);
-
+ TypeFinder SrcStructTypes;
+ SrcStructTypes.run(*SrcM, true);
SmallPtrSet<StructType*, 32> SrcStructTypesSet(SrcStructTypes.begin(),
SrcStructTypes.end());
-
+
+ TypeFinder DstStructTypes;
+ DstStructTypes.run(*DstM, true);
+ SmallPtrSet<StructType*, 32> DstStructTypesSet(DstStructTypes.begin(),
+ DstStructTypes.end());
+
for (unsigned i = 0, e = SrcStructTypes.size(); i != e; ++i) {
StructType *ST = SrcStructTypes[i];
if (!ST->hasName()) continue;
// Check to see if the destination module has a struct with the prefix name.
if (StructType *DST = DstM->getTypeByName(ST->getName().substr(0, DotPos)))
- // Don't use it if this actually came from the source module. They're in
- // the same LLVMContext after all.
- if (!SrcStructTypesSet.count(DST))
+ // Don't use it if this actually came from the source module. They're in
+ // the same LLVMContext after all. Also don't use it unless the type is
+ // actually used in the destination module. This can happen in situations
+ // like this:
+ //
+ // Module A Module B
+ // -------- --------
+ // %Z = type { %A } %B = type { %C.1 }
+ // %A = type { %B.1, [7 x i8] } %C.1 = type { i8* }
+ // %B.1 = type { %C } %A.2 = type { %B.3, [5 x i8] }
+ // %C = type { i8* } %B.3 = type { %C.1 }
+ //
+ // When we link Module B with Module A, the '%B' in Module B is
+ // used. However, that would then use '%C.1'. But when we process '%C.1',
+ // we prefer to take the '%C' version. So we are then left with both
+ // '%C.1' and '%C' being used for the same types. This leads to some
+ // variables using one type and some using the other.
+ if (!SrcStructTypesSet.count(DST) && DstStructTypesSet.count(DST))
TypeMap.addTypeMapping(DST, ST);
}
-
-
+
// Don't bother incorporating aliases, they aren't generally typed well.
// Now that we have discovered all of the type equivalences, get a body for
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.
- CopyGVAttributes(NG, DstGV);
+ copyGVAttributes(NG, DstGV);
AppendingVarInfo AVI;
AVI.NewGV = NG;
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);
+ copyGVAttributes(NewDGV, SGV);
if (NewVisibility)
NewDGV->setVisibility(*NewVisibility);
// bring SF over.
Function *NewDF = Function::Create(TypeMap.get(SF->getFunctionType()),
SF->getLinkage(), SF->getName(), DstM);
- CopyGVAttributes(NewDF, SF);
+ copyGVAttributes(NewDF, SF);
if (NewVisibility)
NewDF->setVisibility(*NewVisibility);
GlobalAlias *NewDA = new GlobalAlias(TypeMap.get(SGA->getType()),
SGA->getLinkage(), SGA->getName(),
/*aliasee*/0, DstM);
- CopyGVAttributes(NewDA, SGA);
+ copyGVAttributes(NewDA, SGA);
if (NewVisibility)
NewDA->setVisibility(*NewVisibility);
}
static void getArrayElements(Constant *C, SmallVectorImpl<Constant*> &Dest) {
- if (ConstantArray *I = dyn_cast<ConstantArray>(C)) {
- for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
- Dest.push_back(I->getOperand(i));
- return;
- }
-
- if (ConstantDataSequential *CDS = dyn_cast<ConstantDataSequential>(C)) {
- for (unsigned i = 0, e = CDS->getNumElements(); i != e; ++i)
- Dest.push_back(CDS->getElementAsConstant(i));
- return;
- }
-
- ConstantAggregateZero *CAZ = cast<ConstantAggregateZero>(C);
- Dest.append(cast<ArrayType>(C->getType())->getNumElements(),
- CAZ->getSequentialElement());
+ unsigned NumElements = cast<ArrayType>(C->getType())->getNumElements();
+
+ for (unsigned i = 0; i != NumElements; ++i)
+ Dest.push_back(C->getAggregateElement(i));
}
void ModuleLinker::linkAppendingVarInit(const AppendingVarInfo &AVI) {
AVI.NewGV->setInitializer(ConstantArray::get(NewType, Elements));
}
-
-// linkGlobalInits - Update the initializers in the Dest module now that all
-// globals that may be referenced are in Dest.
+/// linkGlobalInits - Update the initializers in the Dest module now that all
+/// globals that may be referenced are in Dest.
void ModuleLinker::linkGlobalInits() {
// Loop over all of the globals in the src module, mapping them over as we go
for (Module::const_global_iterator I = SrcM->global_begin(),
}
}
-// linkFunctionBody - Copy the source function over into the dest function and
-// fix up references to values. At this point we know that Dest is an external
-// function, and that Src is not.
+/// linkFunctionBody - Copy the source function over into the dest function and
+/// fix up references to values. At this point we know that Dest is an external
+/// function, and that Src is not.
void ModuleLinker::linkFunctionBody(Function *Dst, Function *Src) {
assert(Src && Dst && Dst->isDeclaration() && !Src->isDeclaration());
}
-
+/// linkAliasBodies - Insert all of the aliases in Src into the Dest module.
void ModuleLinker::linkAliasBodies() {
for (Module::alias_iterator I = SrcM->alias_begin(), E = SrcM->alias_end();
I != E; ++I) {
}
}
-/// linkNamedMDNodes - Insert all of the named mdnodes in Src into the Dest
+/// linkNamedMDNodes - Insert all of the named MDNodes in Src into the Dest
/// module.
void ModuleLinker::linkNamedMDNodes() {
+ const NamedMDNode *SrcModFlags = SrcM->getModuleFlagsMetadata();
for (Module::const_named_metadata_iterator I = SrcM->named_metadata_begin(),
E = SrcM->named_metadata_end(); I != E; ++I) {
+ // Don't link module flags here. Do them separately.
+ if (&*I == SrcModFlags) continue;
NamedMDNode *DestNMD = DstM->getOrInsertNamedMetadata(I->getName());
// Add Src elements into Dest node.
for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i)
RF_None, &TypeMap));
}
}
+
+/// 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() {
+ 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.
+ if (DstModFlags->getNumOperands() == 0) {
+ for (unsigned I = 0, E = SrcModFlags->getNumOperands(); I != E; ++I)
+ DstModFlags->addOperand(SrcModFlags->getOperand(I));
+
+ return false;
+ }
+
+ bool HasErr = false;
+
+ // 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");
+ }
+
+ // 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]);
+ }
+
+ for (SmallSetVector<MDNode*, 8>::iterator
+ II = RequireNodes[ID].begin(), IE = RequireNodes[ID].end();
+ II != IE; ++II)
+ DstModFlags->addOperand(*II);
+ }
+
+ // 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;
+ }
+ }
+
+ if (!HasValue)
+ HasErr = emitError("linking module flags '" + ReqID->getString() +
+ "': does not have the required value");
+ }
+ }
+
+ return HasErr;
+}
bool ModuleLinker::run() {
- assert(DstM && "Null Destination module");
- assert(SrcM && "Null Source Module");
+ assert(DstM && "Null destination module");
+ assert(SrcM && "Null source module");
// Inherit the target data from the source module if the destination module
// doesn't have one already.
// Link in the function bodies that are defined in the source module into
// DstM.
for (Module::iterator SF = SrcM->begin(), E = SrcM->end(); SF != E; ++SF) {
-
// Skip if not linking from source.
if (DoNotLinkFromSource.count(SF)) continue;
}
linkFunctionBody(cast<Function>(ValueMap[SF]), SF);
+ SF->Dematerialize();
}
// Resolve all uses of aliases with aliasees.
linkAliasBodies();
- // Remap all of the named mdnoes in Src into the DstM module. We do this
+ // Remap all of the named MDNodes in Src into the DstM module. We do this
// after linking GlobalValues so that MDNodes that reference GlobalValues
// are properly remapped.
linkNamedMDNodes();
+ // Merge the module flags into the DstM module.
+ if (linkModuleFlagsMetadata())
+ return true;
+
// Process vector of lazily linked in functions.
bool LinkedInAnyFunctions;
do {
// Link in function body.
linkFunctionBody(DF, SF);
-
+ SF->Dematerialize();
+
// "Remove" from vector by setting the element to 0.
*I = 0;
// LinkModules entrypoint.
//===----------------------------------------------------------------------===//
-// LinkModules - This function links two modules together, with the resulting
-// left module modified to be the composite of the two input modules. If an
-// error occurs, true is returned and ErrorMsg (if not null) is set to indicate
-// the problem. Upon failure, the Dest module could be in a modified state, and
-// shouldn't be relied on to be consistent.
+/// LinkModules - This function links two modules together, with the resulting
+/// left module modified to be the composite of the two input modules. If an
+/// error occurs, true is returned and ErrorMsg (if not null) is set to indicate
+/// the problem. Upon failure, the Dest module could be in a modified state,
+/// and shouldn't be relied on to be consistent.
bool Linker::LinkModules(Module *Dest, Module *Src, unsigned Mode,
std::string *ErrorMsg) {
ModuleLinker TheLinker(Dest, Src, Mode);
if (ErrorMsg) *ErrorMsg = TheLinker.ErrorMsg;
return true;
}
-
+
return false;
}
+
+//===----------------------------------------------------------------------===//
+// C API.
+//===----------------------------------------------------------------------===//
+
+LLVMBool LLVMLinkModules(LLVMModuleRef Dest, LLVMModuleRef Src,
+ LLVMLinkerMode Mode, char **OutMessages) {
+ std::string Messages;
+ LLVMBool Result = Linker::LinkModules(unwrap(Dest), unwrap(Src),
+ Mode, OutMessages? &Messages : 0);
+ if (OutMessages)
+ *OutMessages = strdup(Messages.c_str());
+ return Result;
+}