1 //===- llvm/IR/MetadataTracking.h - 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 // Low-level functions to enable tracking of metadata that could RAUW. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_IR_METADATATRACKING_H 15 #define LLVM_IR_METADATATRACKING_H 16 17 #include "llvm/ADT/PointerUnion.h" 18 #include "llvm/Support/Casting.h" 19 #include <type_traits> 20 21 namespace llvm { 22 23 class Metadata; 24 class MetadataAsValue; 25 26 /// \brief API for tracking metadata references through RAUW and deletion. 27 /// 28 /// Shared API for updating \a Metadata pointers in subclasses that support 29 /// RAUW. 30 /// 31 /// This API is not meant to be used directly. See \a TrackingMDRef for a 32 /// user-friendly tracking reference. 33 class MetadataTracking { 34 public: 35 /// \brief Track the reference to metadata. 36 /// 37 /// Register \c MD with \c *MD, if the subclass supports tracking. If \c *MD 38 /// gets RAUW'ed, \c MD will be updated to the new address. If \c *MD gets 39 /// deleted, \c MD will be set to \c nullptr. 40 /// 41 /// If tracking isn't supported, \c *MD will not change. 42 /// 43 /// \return true iff tracking is supported by \c MD. track(Metadata * & MD)44 static bool track(Metadata *&MD) { 45 return track(&MD, *MD, static_cast<Metadata *>(nullptr)); 46 } 47 48 /// \brief Track the reference to metadata for \a Metadata. 49 /// 50 /// As \a track(Metadata*&), but with support for calling back to \c Owner to 51 /// tell it that its operand changed. This could trigger \c Owner being 52 /// re-uniqued. track(void * Ref,Metadata & MD,Metadata & Owner)53 static bool track(void *Ref, Metadata &MD, Metadata &Owner) { 54 return track(Ref, MD, &Owner); 55 } 56 57 /// \brief Track the reference to metadata for \a MetadataAsValue. 58 /// 59 /// As \a track(Metadata*&), but with support for calling back to \c Owner to 60 /// tell it that its operand changed. This could trigger \c Owner being 61 /// re-uniqued. track(void * Ref,Metadata & MD,MetadataAsValue & Owner)62 static bool track(void *Ref, Metadata &MD, MetadataAsValue &Owner) { 63 return track(Ref, MD, &Owner); 64 } 65 66 /// \brief Stop tracking a reference to metadata. 67 /// 68 /// Stops \c *MD from tracking \c MD. untrack(Metadata * & MD)69 static void untrack(Metadata *&MD) { untrack(&MD, *MD); } 70 static void untrack(void *Ref, Metadata &MD); 71 72 /// \brief Move tracking from one reference to another. 73 /// 74 /// Semantically equivalent to \c untrack(MD) followed by \c track(New), 75 /// except that ownership callbacks are maintained. 76 /// 77 /// Note: it is an error if \c *MD does not equal \c New. 78 /// 79 /// \return true iff tracking is supported by \c MD. retrack(Metadata * & MD,Metadata * & New)80 static bool retrack(Metadata *&MD, Metadata *&New) { 81 return retrack(&MD, *MD, &New); 82 } 83 static bool retrack(void *Ref, Metadata &MD, void *New); 84 85 /// \brief Check whether metadata is replaceable. 86 static bool isReplaceable(const Metadata &MD); 87 88 typedef PointerUnion<MetadataAsValue *, Metadata *> OwnerTy; 89 90 private: 91 /// \brief Track a reference to metadata for an owner. 92 /// 93 /// Generalized version of tracking. 94 static bool track(void *Ref, Metadata &MD, OwnerTy Owner); 95 }; 96 97 } // end namespace llvm 98 99 #endif 100