summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Linker
diff options
context:
space:
mode:
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>2016-04-16 01:29:08 +0000
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>2016-04-16 01:29:08 +0000
commitf0d73f95c15f909c6034f1735632695248bb75a8 (patch)
treeb7f244a7c9f762457852998500c4e62a014516c2 /llvm/lib/Linker
parent2db6f2e508126d237435a4d43af8076bf74f641d (diff)
downloadbcm5719-llvm-f0d73f95c15f909c6034f1735632695248bb75a8.tar.gz
bcm5719-llvm-f0d73f95c15f909c6034f1735632695248bb75a8.zip
ValueMapper: Eliminate cross-file co-recursion, NFC
Eliminate co-recursion of Mapper::mapValue through ValueMaterializer::materializeInitFor, through a major redesign of the ValueMapper.cpp interface. - Expose a ValueMapper class that controls the entry points to the mapping algorithms. - Change IRLinker to use ValueMapper directly, rather than llvm::RemapInstruction, llvm::MapValue, etc. - Use (e.g.) ValueMapper::scheduleMapGlobalInit to add mapping work to a worklist in ValueMapper instead of recursing. There were two fairly major complications. Firstly, IRLinker::linkAppendingVarProto incorporates an on-the-fly IR ugprade that I had to split apart. Long-term, this upgrade should be done in the bitcode reader (and we should only accept the "new" form), but for now I've just made it work and added a FIXME. The hold-op is that we need to deprecate C API that relies on this. Secondly, IRLinker has special logic to correctly implement aliases with comdats, and uses two ValueToValueMapTy instances and two ValueMaterializers. I supported this by allowing clients to register an alternate mapping context, whose MCID can be passed in when scheduling new work. While out of scope for this commit, it should now be straightforward to remove recursion from Mapper::mapValue. llvm-svn: 266503
Diffstat (limited to 'llvm/lib/Linker')
-rw-r--r--llvm/lib/Linker/IRMover.cpp62
1 files changed, 24 insertions, 38 deletions
diff --git a/llvm/lib/Linker/IRMover.cpp b/llvm/lib/Linker/IRMover.cpp
index e4121fedc0a..64c73235777 100644
--- a/llvm/lib/Linker/IRMover.cpp
+++ b/llvm/lib/Linker/IRMover.cpp
@@ -397,8 +397,9 @@ class IRLinker {
bool HasError = false;
- /// Flags to pass to value mapper invocations.
- RemapFlags ValueMapperFlags = RF_MoveDistinctMDs | RF_IgnoreMissingLocals;
+ /// Entry point for mapping values and alternate context for mapping aliases.
+ ValueMapper Mapper;
+ unsigned AliasMCID;
/// Handles cloning of a global values from the source module into
/// the destination module, including setting the attributes and visibility.
@@ -470,7 +471,11 @@ public:
std::unique_ptr<Module> SrcM, ArrayRef<GlobalValue *> ValuesToLink,
std::function<void(GlobalValue &, IRMover::ValueAdder)> AddLazyFor)
: DstM(DstM), SrcM(std::move(SrcM)), AddLazyFor(AddLazyFor), TypeMap(Set),
- GValMaterializer(*this), LValMaterializer(*this) {
+ GValMaterializer(*this), LValMaterializer(*this),
+ Mapper(ValueMap, RF_MoveDistinctMDs | RF_IgnoreMissingLocals, &TypeMap,
+ &GValMaterializer),
+ AliasMCID(Mapper.registerAlternateMappingContext(AliasValueMap,
+ &LValMaterializer)) {
for (GlobalValue *GV : ValuesToLink)
maybeAdd(GV);
}
@@ -712,6 +717,10 @@ Constant *IRLinker::linkAppendingVarProto(GlobalVariable *DstGV,
Type *EltTy = cast<ArrayType>(TypeMap.get(SrcGV->getValueType()))
->getElementType();
+ // FIXME: This upgrade is done during linking to support the C API. Once the
+ // old form is deprecated, we should move this upgrade to
+ // llvm::UpgradeGlobalVariable() and simplify the logic here and in
+ // Mapper::mapAppendingVariable() in ValueMapper.cpp.
StringRef Name = SrcGV->getName();
bool IsNewStructor = false;
bool IsOldStructor = false;
@@ -729,8 +738,10 @@ Constant *IRLinker::linkAppendingVarProto(GlobalVariable *DstGV,
EltTy = StructType::get(SrcGV->getContext(), Tys, false);
}
+ uint64_t DstNumElements = 0;
if (DstGV) {
ArrayType *DstTy = cast<ArrayType>(DstGV->getValueType());
+ DstNumElements = DstTy->getNumElements();
if (!SrcGV->hasAppendingLinkage() || !DstGV->hasAppendingLinkage()) {
emitError(
@@ -774,10 +785,6 @@ Constant *IRLinker::linkAppendingVarProto(GlobalVariable *DstGV,
}
}
- SmallVector<Constant *, 16> DstElements;
- if (DstGV)
- getArrayElements(DstGV->getInitializer(), DstElements);
-
SmallVector<Constant *, 16> SrcElements;
getArrayElements(SrcGV->getInitializer(), SrcElements);
@@ -793,7 +800,7 @@ Constant *IRLinker::linkAppendingVarProto(GlobalVariable *DstGV,
return !shouldLink(DGV, *Key);
}),
SrcElements.end());
- uint64_t NewSize = DstElements.size() + SrcElements.size();
+ uint64_t NewSize = DstNumElements + SrcElements.size();
ArrayType *NewType = ArrayType::get(EltTy, NewSize);
// Create the new global variable.
@@ -810,25 +817,9 @@ Constant *IRLinker::linkAppendingVarProto(GlobalVariable *DstGV,
// Stop recursion.
ValueMap[SrcGV] = Ret;
- for (auto *V : SrcElements) {
- Constant *NewV;
- if (IsOldStructor) {
- auto *S = cast<ConstantStruct>(V);
- auto *E1 = MapValue(S->getOperand(0), ValueMap, ValueMapperFlags,
- &TypeMap, &GValMaterializer);
- auto *E2 = MapValue(S->getOperand(1), ValueMap, ValueMapperFlags,
- &TypeMap, &GValMaterializer);
- Value *Null = Constant::getNullValue(VoidPtrTy);
- NewV =
- ConstantStruct::get(cast<StructType>(EltTy), E1, E2, Null, nullptr);
- } else {
- NewV =
- MapValue(V, ValueMap, ValueMapperFlags, &TypeMap, &GValMaterializer);
- }
- DstElements.push_back(NewV);
- }
-
- NG->setInitializer(ConstantArray::get(NewType, DstElements));
+ Mapper.scheduleMapAppendingVariable(*NG,
+ DstGV ? DstGV->getInitializer() : nullptr,
+ IsOldStructor, SrcElements);
// Replace any uses of the two global variables with uses of the new
// global.
@@ -935,8 +926,7 @@ Constant *IRLinker::linkGlobalValueProto(GlobalValue *SGV, bool ForAlias) {
/// referenced are in Dest.
void IRLinker::linkGlobalInit(GlobalVariable &Dst, GlobalVariable &Src) {
// Figure out what the initializer looks like in the dest module.
- Dst.setInitializer(MapValue(Src.getInitializer(), ValueMap, ValueMapperFlags,
- &TypeMap, &GValMaterializer));
+ Mapper.scheduleMapGlobalInitializer(Dst, *Src.getInitializer());
}
/// Copy the source function over into the dest function and fix up references
@@ -968,15 +958,12 @@ bool IRLinker::linkFunctionBody(Function &Dst, Function &Src) {
Dst.getBasicBlockList().splice(Dst.end(), Src.getBasicBlockList());
// Everything has been moved over. Remap it.
- RemapFunction(Dst, ValueMap, ValueMapperFlags, &TypeMap, &GValMaterializer);
+ Mapper.scheduleRemapFunction(Dst);
return false;
}
void IRLinker::linkAliasBody(GlobalAlias &Dst, GlobalAlias &Src) {
- Constant *Aliasee = Src.getAliasee();
- Constant *Val = MapValue(Aliasee, AliasValueMap, ValueMapperFlags, &TypeMap,
- &LValMaterializer);
- Dst.setAliasee(Val);
+ Mapper.scheduleMapGlobalAliasee(Dst, *Src.getAliasee(), AliasMCID);
}
bool IRLinker::linkGlobalValueBody(GlobalValue &Dst, GlobalValue &Src) {
@@ -1000,9 +987,7 @@ void IRLinker::linkNamedMDNodes() {
NamedMDNode *DestNMD = DstM.getOrInsertNamedMetadata(NMD.getName());
// Add Src elements into Dest node.
for (const MDNode *Op : NMD.operands())
- DestNMD->addOperand(MapMetadata(
- Op, ValueMap, ValueMapperFlags | RF_NullMapMissingGlobalValues,
- &TypeMap, &GValMaterializer));
+ DestNMD->addOperand(Mapper.mapMDNode(*Op));
}
}
@@ -1242,7 +1227,7 @@ bool IRLinker::run() {
continue;
assert(!GV->isDeclaration());
- MapValue(GV, ValueMap, ValueMapperFlags, &TypeMap, &GValMaterializer);
+ Mapper.mapValue(*GV);
if (HasError)
return true;
}
@@ -1250,6 +1235,7 @@ bool IRLinker::run() {
// Note that we are done linking global value bodies. This prevents
// metadata linking from creating new references.
DoneLinkingBodies = true;
+ Mapper.addFlags(RF_NullMapMissingGlobalValues);
// Remap all of the named MDNodes in Src into the DstM module. We do this
// after linking GlobalValues so that MDNodes that reference GlobalValues
OpenPOWER on IntegriCloud