llvm-mirror/lib/IR/MetadataTracking.cpp
Duncan P. N. Exon Smith 6da60093ee IR: Store RAUW support and Context in the same pointer, NFC
Add an `LLVMContext &` to `ReplaceableMetadataImpl`, create a class that
either holds a reference to an `LLVMContext` or owns a
`ReplaceableMetadataImpl`, and use the new class in `MDNode`.

  - This saves a pointer in `UniquableMDNode` at the cost of a pointer
    in `ValueAsMetadata` (which didn't used to store the `LLVMContext`).
    There are far more of the former.
  - Unifies RAUW support between `MDNodeFwdDecl` (which is going away,
    see r226481) and `UniquableMDNode`.

llvm-svn: 226484
2015-01-19 19:02:06 +00:00

56 lines
1.7 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))
return N->Context.getReplaceableUses();
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));
}