summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Utils/ValueMapper.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'llvm/lib/Transforms/Utils/ValueMapper.cpp')
-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