17ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens//===- llvm/IR/TrackingMDRef.h - Tracking Metadata references ---*- C++ -*-===// 27ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// 37ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// The LLVM Compiler Infrastructure 47ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// 57ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// This file is distributed under the University of Illinois Open Source 67ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// License. See LICENSE.TXT for details. 77ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// 87ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens//===----------------------------------------------------------------------===// 97ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// 107ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// References to metadata that track RAUW. 117ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// 127ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens//===----------------------------------------------------------------------===// 137ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 147ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#ifndef LLVM_IR_TRACKINGMDREF_H 157ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#define LLVM_IR_TRACKINGMDREF_H 167ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 177ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#include "llvm/IR/Metadata.h" 187ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 197ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensnamespace llvm { 207ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 217ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// \brief Tracking metadata reference. 227ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// 237ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// This class behaves like \a TrackingVH, but for metadata. 247ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensclass TrackingMDRef { 257ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens Metadata *MD; 267ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 277ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenspublic: 287ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens TrackingMDRef() : MD(nullptr) {} 297ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens explicit TrackingMDRef(Metadata *MD) : MD(MD) { track(); } 307ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 317ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens TrackingMDRef(TrackingMDRef &&X) : MD(X.MD) { retrack(X); } 327ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens TrackingMDRef(const TrackingMDRef &X) : MD(X.MD) { track(); } 337ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens TrackingMDRef &operator=(TrackingMDRef &&X) { 347ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens if (&X == this) 357ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return *this; 367ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 377ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens untrack(); 387ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens MD = X.MD; 397ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens retrack(X); 407ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return *this; 417ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 427ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens TrackingMDRef &operator=(const TrackingMDRef &X) { 437ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens if (&X == this) 447ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return *this; 457ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 467ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens untrack(); 477ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens MD = X.MD; 487ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens track(); 497ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return *this; 507ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 517ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens ~TrackingMDRef() { untrack(); } 527ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 537ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens Metadata *get() const { return MD; } 547ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens operator Metadata *() const { return get(); } 557ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens Metadata *operator->() const { return get(); } 567ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens Metadata &operator*() const { return *get(); } 577ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 587ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens void reset() { 597ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens untrack(); 607ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens MD = nullptr; 617ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 627ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens void reset(Metadata *MD) { 637ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens untrack(); 647ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens this->MD = MD; 657ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens track(); 667ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 677ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 687ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// \brief Check whether this has a trivial destructor. 697ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// 707ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// If \c MD isn't replaceable, the destructor will be a no-op. 717ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens bool hasTrivialDestructor() const { 727ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return !MD || !MetadataTracking::isReplaceable(*MD); 737ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 747ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 757ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens bool operator==(const TrackingMDRef &X) const { return MD == X.MD; } 767ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens bool operator!=(const TrackingMDRef &X) const { return MD != X.MD; } 777ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 787ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capensprivate: 797ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens void track() { 807ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens if (MD) 817ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens MetadataTracking::track(MD); 827ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 837ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens void untrack() { 847ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens if (MD) 857ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens MetadataTracking::untrack(MD); 867ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 877ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens void retrack(TrackingMDRef &X) { 887ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens assert(MD == X.MD && "Expected values to match"); 897ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens if (X.MD) { 907ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens MetadataTracking::retrack(X.MD, MD); 917ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens X.MD = nullptr; 927ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 937ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 947ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}; 957ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 967ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// \brief Typed tracking ref. 977ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// 987ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// Track refererences of a particular type. It's useful to use this for \a 997ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens/// MDNode and \a ValueAsMetadata. 1007ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <class T> class TypedTrackingMDRef { 1017ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens TrackingMDRef Ref; 1027ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1037ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenspublic: 1047ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens TypedTrackingMDRef() {} 1057ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens explicit TypedTrackingMDRef(T *MD) : Ref(static_cast<Metadata *>(MD)) {} 1067ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1077ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens TypedTrackingMDRef(TypedTrackingMDRef &&X) : Ref(std::move(X.Ref)) {} 1087ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens TypedTrackingMDRef(const TypedTrackingMDRef &X) : Ref(X.Ref) {} 1097ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens TypedTrackingMDRef &operator=(TypedTrackingMDRef &&X) { 1107ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens Ref = std::move(X.Ref); 1117ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return *this; 1127ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 1137ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens TypedTrackingMDRef &operator=(const TypedTrackingMDRef &X) { 1147ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens Ref = X.Ref; 1157ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return *this; 1167ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 1177ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1187ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens T *get() const { return (T *)Ref.get(); } 1197ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens operator T *() const { return get(); } 1207ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens T *operator->() const { return get(); } 1217ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens T &operator*() const { return *get(); } 1227ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1237ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens bool operator==(const TypedTrackingMDRef &X) const { return Ref == X.Ref; } 1247ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens bool operator!=(const TypedTrackingMDRef &X) const { return Ref != X.Ref; } 1257ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1267ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens void reset() { Ref.reset(); } 1277ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens void reset(T *MD) { Ref.reset(static_cast<Metadata *>(MD)); } 1287ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1297ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens /// \brief Check whether this has a trivial destructor. 1307ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens bool hasTrivialDestructor() const { return Ref.hasTrivialDestructor(); } 1317ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}; 1327ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1337ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstypedef TypedTrackingMDRef<MDNode> TrackingMDNodeRef; 1347ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstypedef TypedTrackingMDRef<ValueAsMetadata> TrackingValueAsMetadataRef; 1357ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1367ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens// Expose the underlying metadata to casting. 1377ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <> struct simplify_type<TrackingMDRef> { 1387ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typedef Metadata *SimpleType; 1397ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens static SimpleType getSimplifiedValue(TrackingMDRef &MD) { return MD.get(); } 1407ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}; 1417ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1427ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <> struct simplify_type<const TrackingMDRef> { 1437ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typedef Metadata *SimpleType; 1447ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens static SimpleType getSimplifiedValue(const TrackingMDRef &MD) { 1457ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return MD.get(); 1467ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 1477ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}; 1487ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1497ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <class T> struct simplify_type<TypedTrackingMDRef<T>> { 1507ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typedef T *SimpleType; 1517ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens static SimpleType getSimplifiedValue(TypedTrackingMDRef<T> &MD) { 1527ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return MD.get(); 1537ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 1547ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}; 1557ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1567ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capenstemplate <class T> struct simplify_type<const TypedTrackingMDRef<T>> { 1577ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens typedef T *SimpleType; 1587ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens static SimpleType getSimplifiedValue(const TypedTrackingMDRef<T> &MD) { 1597ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens return MD.get(); 1607ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens } 1617ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens}; 1627ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1637ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens} // end namespace llvm 1647ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens 1657ad046f5968d4709c3c68d165387d13f1da7bab6Nicolas Capens#endif 166