llvm-6502/lib/IR/MetadataTracking.cpp
Duncan P. N. Exon Smith ae9e15f914 IR: Split GenericMDNode into MDTuple and UniquableMDNode
Split `GenericMDNode` into two classes (with more descriptive names).

  - `UniquableMDNode` will be a common subclass for `MDNode`s that are
    sometimes uniqued like constants, and sometimes 'distinct'.

    This class gets the (short-lived) RAUW support and related API.

  - `MDTuple` is the basic tuple that has always been returned by
    `MDNode::get()`.  This is as opposed to more specific nodes to be
    added soon, which have additional fields, custom assembly syntax,
    and extra semantics.

    This class gets the hash-related logic, since other sublcasses of
    `UniquableMDNode` may need to hash based on other fields.

To keep this diff from getting too big, I've added casts to `MDTuple`
that won't really scale as new subclasses of `UniquableMDNode` are
added, but I'll clean those up incrementally.

(No functionality change intended.)

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@225682 91177308-0d34-0410-b5e6-96231b3b80d8
2015-01-12 20:09:34 +00:00

59 lines
1.8 KiB
C++

//===- MetadataTracking.cpp - Implement metadata tracking -----------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file implements Metadata tracking.
//
//===----------------------------------------------------------------------===//
#include "llvm/IR/MetadataTracking.h"
#include "llvm/IR/Metadata.h"
using namespace llvm;
ReplaceableMetadataImpl *ReplaceableMetadataImpl::get(Metadata &MD) {
if (auto *N = dyn_cast<MDNode>(&MD)) {
if (auto *U = dyn_cast<UniquableMDNode>(N))
return U->ReplaceableUses.get();
return cast<MDNodeFwdDecl>(N);
}
return dyn_cast<ValueAsMetadata>(&MD);
}
bool MetadataTracking::track(void *Ref, Metadata &MD, OwnerTy Owner) {
assert(Ref && "Expected live reference");
assert((Owner || *static_cast<Metadata **>(Ref) == &MD) &&
"Reference without owner must be direct");
if (auto *R = ReplaceableMetadataImpl::get(MD)) {
R->addRef(Ref, Owner);
return true;
}
return false;
}
void MetadataTracking::untrack(void *Ref, Metadata &MD) {
assert(Ref && "Expected live reference");
if (auto *R = ReplaceableMetadataImpl::get(MD))
R->dropRef(Ref);
}
bool MetadataTracking::retrack(void *Ref, Metadata &MD, void *New) {
assert(Ref && "Expected live reference");
assert(New && "Expected live reference");
assert(Ref != New && "Expected change");
if (auto *R = ReplaceableMetadataImpl::get(MD)) {
R->moveRef(Ref, New, MD);
return true;
}
return false;
}
bool MetadataTracking::isReplaceable(const Metadata &MD) {
return ReplaceableMetadataImpl::get(const_cast<Metadata &>(MD));
}