LLVM 23.0.0git
CASReference.h
Go to the documentation of this file.
1//===- llvm/CAS/CASReference.h ----------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#ifndef LLVM_CAS_CASREFERENCE_H
10#define LLVM_CAS_CASREFERENCE_H
11
12#include "llvm/ADT/ArrayRef.h"
14#include "llvm/ADT/StringRef.h"
15
16namespace llvm {
17
18class raw_ostream;
19
20namespace cas {
21
22class ObjectStore;
23class ObjectHandle;
24class ObjectRef;
25
26/// Base class for references to things in \a ObjectStore.
28protected:
30 static constexpr uint64_t getDenseMapEmptyRef() { return -1ULL; }
31 static constexpr uint64_t getDenseMapTombstoneRef() { return -2ULL; }
32
33public:
34 /// Get an internal reference.
35 uint64_t getInternalRef(const ObjectStore &ExpectedCAS) const {
36#if LLVM_ENABLE_ABI_BREAKING_CHECKS
37 assert(CAS == &ExpectedCAS && "Extracting reference for the wrong CAS");
38#endif
39 return InternalRef;
40 }
41
42 /// Helper functions for DenseMapInfo.
43 unsigned getDenseMapHash() const {
44 return static_cast<unsigned>(llvm::hash_value(InternalRef));
45 }
46 bool isDenseMapEmpty() const { return InternalRef == getDenseMapEmptyRef(); }
47 bool isDenseMapTombstone() const {
48 return InternalRef == getDenseMapTombstoneRef();
49 }
50 bool isDenseMapSentinel() const {
52 }
53
54protected:
55 void print(raw_ostream &OS, const ObjectHandle &This) const;
56 void print(raw_ostream &OS, const ObjectRef &This) const;
57
59#if LLVM_ENABLE_ABI_BREAKING_CHECKS
60 assert(
61 (isDenseMapSentinel() || RHS.isDenseMapSentinel() || CAS == RHS.CAS) &&
62 "Cannot compare across CAS instances");
63#endif
64 return InternalRef == RHS.InternalRef;
65 }
66
67protected:
68 friend class ObjectStore;
69 ReferenceBase(const ObjectStore *CAS, uint64_t InternalRef, bool IsHandle)
70 : InternalRef(InternalRef) {
71#if LLVM_ENABLE_ABI_BREAKING_CHECKS
72 this->CAS = CAS;
73#endif
74 assert(InternalRef != getDenseMapEmptyRef() && "Reserved for DenseMapInfo");
75 assert(InternalRef != getDenseMapTombstoneRef() &&
76 "Reserved for DenseMapInfo");
77 }
79 : InternalRef(getDenseMapEmptyRef()) {}
80
81private:
82 uint64_t InternalRef;
83
84#if LLVM_ENABLE_ABI_BREAKING_CHECKS
85 const ObjectStore *CAS = nullptr;
86#endif
87};
88
89/// Reference to an object in an \a ObjectStore instance.
90///
91/// If you have an ObjectRef, you know the object exists, and you can point at
92/// it from new nodes with \a ObjectStore::store(), but you don't know anything
93/// about it. "Loading" the object is a separate step that may not have
94/// happened yet, and which can fail (due to filesystem corruption) or
95/// introduce latency (if downloading from a remote store).
96///
97/// \a ObjectStore::store() takes a list of these, and these are returned by \a
98/// ObjectStore::forEachRef() and \a ObjectStore::readRef(), which are accessors
99/// for nodes, and \a ObjectStore::getReference().
100///
101/// \a ObjectStore::load() will load the referenced object, and returns \a
102/// ObjectHandle, a variant that knows what kind of entity it is. \a
103/// ObjectStore::getReferenceKind() can expect the type of reference without
104/// asking for unloaded objects to be loaded.
105class ObjectRef : public ReferenceBase {
106 struct DenseMapTag {};
107
108public:
109 friend bool operator==(const ObjectRef &LHS, const ObjectRef &RHS) {
110 return LHS.hasSameInternalRef(RHS);
111 }
112 friend bool operator!=(const ObjectRef &LHS, const ObjectRef &RHS) {
113 return !(LHS == RHS);
114 }
115
116 static ObjectRef getDenseMapEmptyKey() {
117 return ObjectRef(DenseMapEmptyTag{});
118 }
119
120 /// Print internal ref and/or CASID. Only suitable for debugging.
121 void print(raw_ostream &OS) const { return ReferenceBase::print(OS, *this); }
122
123 LLVM_DUMP_METHOD void dump() const;
124
125private:
126 friend class ObjectStore;
127 friend class ReferenceBase;
129 ObjectRef(const ObjectStore &CAS, uint64_t InternalRef)
130 : ReferenceBase(&CAS, InternalRef, /*IsHandle=*/false) {
131 assert(InternalRef != -1ULL && "Reserved for DenseMapInfo");
132 assert(InternalRef != -2ULL && "Reserved for DenseMapInfo");
133 }
134 explicit ObjectRef(DenseMapEmptyTag T) : ReferenceBase(T) {}
135 explicit ObjectRef(ReferenceBase) = delete;
136};
137
138/// Handle to a loaded object in a \a ObjectStore instance.
139///
140/// ObjectHandle encapulates a *loaded* object in the CAS. You need one
141/// of these to inspect the content of an object: to look at its stored
142/// data and references.
143class ObjectHandle : public ReferenceBase {
144public:
145 friend bool operator==(const ObjectHandle &LHS, const ObjectHandle &RHS) {
146 return LHS.hasSameInternalRef(RHS);
147 }
148 friend bool operator!=(const ObjectHandle &LHS, const ObjectHandle &RHS) {
149 return !(LHS == RHS);
150 }
151
152 /// Print internal ref and/or CASID. Only suitable for debugging.
153 void print(raw_ostream &OS) const { return ReferenceBase::print(OS, *this); }
154
155 LLVM_DUMP_METHOD void dump() const;
156
157private:
158 friend class ObjectStore;
159 friend class ReferenceBase;
161 explicit ObjectHandle(ReferenceBase) = delete;
162 ObjectHandle(const ObjectStore &CAS, uint64_t InternalRef)
163 : ReferenceBase(&CAS, InternalRef, /*IsHandle=*/true) {}
164};
165
166} // namespace cas
167
168template <> struct DenseMapInfo<cas::ObjectRef> {
172
173 static unsigned getHashValue(cas::ObjectRef Ref) {
174 return Ref.getDenseMapHash();
175 }
176
178 return LHS == RHS;
179 }
180};
181
182} // namespace llvm
183
184#endif // LLVM_CAS_CASREFERENCE_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
#define LLVM_DUMP_METHOD
Mark debug helper function definitions like dump() that should not be stripped from debug builds.
Definition Compiler.h:661
This file defines DenseMapInfo traits for DenseMap.
#define T
Value * RHS
Value * LHS
Handle to a loaded object in a ObjectStore instance.
void print(raw_ostream &OS) const
Print internal ref and/or CASID. Only suitable for debugging.
friend bool operator!=(const ObjectHandle &LHS, const ObjectHandle &RHS)
LLVM_DUMP_METHOD void dump() const
friend bool operator==(const ObjectHandle &LHS, const ObjectHandle &RHS)
Reference to an object in an ObjectStore instance.
void print(raw_ostream &OS) const
Print internal ref and/or CASID. Only suitable for debugging.
friend bool operator==(const ObjectRef &LHS, const ObjectRef &RHS)
friend class ReferenceBase
friend bool operator!=(const ObjectRef &LHS, const ObjectRef &RHS)
static ObjectRef getDenseMapEmptyKey()
LLVM_DUMP_METHOD void dump() const
friend class ObjectStore
Content-addressable storage for objects.
Definition ObjectStore.h:90
Base class for references to things in ObjectStore.
static constexpr uint64_t getDenseMapTombstoneRef()
uint64_t getInternalRef(const ObjectStore &ExpectedCAS) const
Get an internal reference.
ReferenceBase(DenseMapEmptyTag)
static constexpr uint64_t getDenseMapEmptyRef()
bool isDenseMapTombstone() const
bool isDenseMapEmpty() const
void print(raw_ostream &OS, const ObjectHandle &This) const
bool isDenseMapSentinel() const
ReferenceBase(const ObjectStore *CAS, uint64_t InternalRef, bool IsHandle)
bool hasSameInternalRef(const ReferenceBase &RHS) const
unsigned getDenseMapHash() const
Helper functions for DenseMapInfo.
This class implements an extremely fast bulk output stream that can only output to a stream.
Definition raw_ostream.h:53
This is an optimization pass for GlobalISel generic memory operations.
hash_code hash_value(const FixedPointSemantics &Val)
@ Ref
The access may reference the value stored in memory.
Definition ModRef.h:32
static bool isEqual(cas::ObjectRef LHS, cas::ObjectRef RHS)
static unsigned getHashValue(cas::ObjectRef Ref)
static cas::ObjectRef getEmptyKey()
An information struct used to provide DenseMap with the various necessary components for a given valu...