1 //===- MetadataTracking.cpp - Implement metadata tracking -----------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements Metadata tracking.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "llvm/IR/MetadataTracking.h"
15 #include "llvm/IR/Metadata.h"
16 
17 using namespace llvm;
18 
get(Metadata & MD)19 ReplaceableMetadataImpl *ReplaceableMetadataImpl::get(Metadata &MD) {
20   if (auto *N = dyn_cast<MDNode>(&MD)) {
21     if (auto *U = dyn_cast<UniquableMDNode>(N))
22       return U->ReplaceableUses.get();
23     return cast<MDNodeFwdDecl>(N);
24   }
25   return dyn_cast<ValueAsMetadata>(&MD);
26 }
27 
track(void * Ref,Metadata & MD,OwnerTy Owner)28 bool MetadataTracking::track(void *Ref, Metadata &MD, OwnerTy Owner) {
29   assert(Ref && "Expected live reference");
30   assert((Owner || *static_cast<Metadata **>(Ref) == &MD) &&
31          "Reference without owner must be direct");
32   if (auto *R = ReplaceableMetadataImpl::get(MD)) {
33     R->addRef(Ref, Owner);
34     return true;
35   }
36   return false;
37 }
38 
untrack(void * Ref,Metadata & MD)39 void MetadataTracking::untrack(void *Ref, Metadata &MD) {
40   assert(Ref && "Expected live reference");
41   if (auto *R = ReplaceableMetadataImpl::get(MD))
42     R->dropRef(Ref);
43 }
44 
retrack(void * Ref,Metadata & MD,void * New)45 bool MetadataTracking::retrack(void *Ref, Metadata &MD, void *New) {
46   assert(Ref && "Expected live reference");
47   assert(New && "Expected live reference");
48   assert(Ref != New && "Expected change");
49   if (auto *R = ReplaceableMetadataImpl::get(MD)) {
50     R->moveRef(Ref, New, MD);
51     return true;
52   }
53   return false;
54 }
55 
isReplaceable(const Metadata & MD)56 bool MetadataTracking::isReplaceable(const Metadata &MD) {
57   return ReplaceableMetadataImpl::get(const_cast<Metadata &>(MD));
58 }
59