summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Utils
diff options
context:
space:
mode:
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>2015-08-03 17:09:38 +0000
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>2015-08-03 17:09:38 +0000
commit4fb46cb818f43805205cf05d7064cb443e04f69c (patch)
tree643c0073cbfd71d13ab494d920f838fb5c1bd7fa /llvm/lib/Transforms/Utils
parent14e67e43a759538e6ab00624c2e50034fea4d015 (diff)
downloadbcm5719-llvm-4fb46cb818f43805205cf05d7064cb443e04f69c.tar.gz
bcm5719-llvm-4fb46cb818f43805205cf05d7064cb443e04f69c.zip
Linker: Move distinct MDNodes instead of cloning
Instead of cloning distinct `MDNode`s when linking in a module, just move them over. The module linker destroys the source module, so the old node would otherwise just be leaked on the context. Create the new node in place. This also reduces the number of cloned uniqued nodes (since it's less likely their operands have changed). This mapping strategy is only correct when we're discarding the source, so the linker turns it on via a ValueMapper flag, `RF_MoveDistinctMDs`. There's nothing observable in terms of `llvm-link` output here: the linked module should be semantically identical. I'll be adding more 'distinct' nodes to the debug info metadata graph in order to break uniquing cycles, so the benefits of this will partly come in future commits. However, we should get some gains immediately, since we have a fair number of 'distinct' `DILocation`s being linked in. llvm-svn: 243883
Diffstat (limited to 'llvm/lib/Transforms/Utils')
-rw-r--r--llvm/lib/Transforms/Utils/ValueMapper.cpp38
1 files changed, 23 insertions, 15 deletions
diff --git a/llvm/lib/Transforms/Utils/ValueMapper.cpp b/llvm/lib/Transforms/Utils/ValueMapper.cpp
index 8daf5468805..d967e0a95c6 100644
--- a/llvm/lib/Transforms/Utils/ValueMapper.cpp
+++ b/llvm/lib/Transforms/Utils/ValueMapper.cpp
@@ -216,9 +216,12 @@ static bool remap(const MDNode *OldNode, MDNode *NewNode,
return AnyChanged;
}
-/// \brief Map a distinct MDNode.
+/// Map a distinct MDNode.
///
-/// Distinct nodes are not uniqued, so they must always recreated.
+/// Whether distinct nodes change is independent of their operands. If \a
+/// RF_MoveDistinctMDs, then they are reused, and their operands remapped in
+/// place; effectively, they're moved from one graph to another. Otherwise,
+/// they're cloned/duplicated, and the new copy's operands are remapped.
static Metadata *mapDistinctNode(const MDNode *Node,
SmallVectorImpl<MDNode *> &Cycles,
ValueToValueMapTy &VM, RemapFlags Flags,
@@ -226,7 +229,11 @@ static Metadata *mapDistinctNode(const MDNode *Node,
ValueMaterializer *Materializer) {
assert(Node->isDistinct() && "Expected distinct node");
- MDNode *NewMD = MDNode::replaceWithDistinct(Node->clone());
+ MDNode *NewMD;
+ if (Flags & RF_MoveDistinctMDs)
+ NewMD = const_cast<MDNode *>(Node);
+ else
+ NewMD = MDNode::replaceWithDistinct(Node->clone());
// Remap the operands. If any change, track those that could be involved in
// uniquing cycles.
@@ -318,20 +325,21 @@ Metadata *llvm::MapMetadata(const Metadata *MD, ValueToValueMapTy &VM,
Metadata *NewMD =
MapMetadataImpl(MD, Cycles, VM, Flags, TypeMapper, Materializer);
- // Resolve cycles underneath MD.
- if (NewMD && NewMD != MD) {
- if (auto *N = dyn_cast<MDNode>(NewMD))
- if (!N->isResolved())
- N->resolveCycles();
-
- for (MDNode *N : Cycles)
- if (!N->isResolved())
- N->resolveCycles();
- } else {
- // Shouldn't get unresolved cycles if nothing was remapped.
- assert(Cycles.empty() && "Expected no unresolved cycles");
+ if ((Flags & RF_NoModuleLevelChanges) ||
+ (MD == NewMD && !(Flags & RF_MoveDistinctMDs))) {
+ assert(Cycles.empty() && "Unresolved cycles without remapping anything?");
+ return NewMD;
}
+ if (auto *N = dyn_cast<MDNode>(NewMD))
+ if (!N->isResolved())
+ N->resolveCycles();
+
+ // Resolve cycles underneath MD.
+ for (MDNode *N : Cycles)
+ if (!N->isResolved())
+ N->resolveCycles();
+
return NewMD;
}
OpenPOWER on IntegriCloud