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