Identifier.h
4.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
//===- Identifier.h - MLIR Identifier Class ---------------------*- C++ -*-===//
//
// Part of the MLIR Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
#ifndef MLIR_IR_IDENTIFIER_H
#define MLIR_IR_IDENTIFIER_H
#include "mlir/Support/LLVM.h"
#include "llvm/ADT/DenseMapInfo.h"
#include "llvm/ADT/StringRef.h"
namespace mlir {
class MLIRContext;
/// This class represents a uniqued string owned by an MLIRContext. Strings
/// represented by this type cannot contain nul characters, and may not have a
/// zero length.
///
/// This is a POD type with pointer size, so it should be passed around by
/// value. The underlying data is owned by MLIRContext and is thus immortal for
/// almost all clients.
class Identifier {
public:
/// Return an identifier for the specified string.
static Identifier get(StringRef str, MLIRContext *context);
Identifier(const Identifier &) = default;
Identifier &operator=(const Identifier &other) = default;
/// Return a StringRef for the string.
StringRef strref() const { return StringRef(pointer, size()); }
/// Identifiers implicitly convert to StringRefs.
operator StringRef() const { return strref(); }
/// Return an std::string.
std::string str() const { return strref().str(); }
/// Return a null terminated C string.
const char *c_str() const { return pointer; }
/// Return a pointer to the start of the string data.
const char *data() const { return pointer; }
/// Return the number of bytes in this string.
unsigned size() const { return ::strlen(pointer); }
/// Return true if this identifier is the specified string.
bool is(StringRef string) const { return strref().equals(string); }
const char *begin() const { return pointer; }
const char *end() const { return pointer + size(); }
void print(raw_ostream &os) const;
void dump() const;
const void *getAsOpaquePointer() const {
return static_cast<const void *>(pointer);
}
static Identifier getFromOpaquePointer(const void *pointer) {
return Identifier((const char *)pointer);
}
private:
/// These are the bytes of the string, which is a nul terminated string.
const char *pointer;
explicit Identifier(const char *pointer) : pointer(pointer) {}
};
inline raw_ostream &operator<<(raw_ostream &os, Identifier identifier) {
identifier.print(os);
return os;
}
inline bool operator==(Identifier lhs, Identifier rhs) {
return lhs.data() == rhs.data();
}
inline bool operator!=(Identifier lhs, Identifier rhs) {
return lhs.data() != rhs.data();
}
inline bool operator==(Identifier lhs, StringRef rhs) { return lhs.is(rhs); }
inline bool operator!=(Identifier lhs, StringRef rhs) { return !lhs.is(rhs); }
inline bool operator==(StringRef lhs, Identifier rhs) { return rhs.is(lhs); }
inline bool operator!=(StringRef lhs, Identifier rhs) { return !rhs.is(lhs); }
// Make identifiers hashable.
inline llvm::hash_code hash_value(Identifier arg) {
return llvm::hash_value(arg.strref());
}
} // end namespace mlir
namespace llvm {
// Identifiers hash just like pointers, there is no need to hash the bytes.
template <>
struct DenseMapInfo<mlir::Identifier> {
static mlir::Identifier getEmptyKey() {
auto pointer = llvm::DenseMapInfo<const void *>::getEmptyKey();
return mlir::Identifier::getFromOpaquePointer(pointer);
}
static mlir::Identifier getTombstoneKey() {
auto pointer = llvm::DenseMapInfo<const void *>::getTombstoneKey();
return mlir::Identifier::getFromOpaquePointer(pointer);
}
static unsigned getHashValue(mlir::Identifier Val) {
return DenseMapInfo<const void *>::getHashValue(Val.data());
}
static bool isEqual(mlir::Identifier LHS, mlir::Identifier RHS) {
return LHS == RHS;
}
};
/// The pointer inside of an identifier comes from a StringMap, so its alignment
/// is always at least 4 and probably 8 (on 64-bit machines). Allow LLVM to
/// steal the low bits.
template <>
struct PointerLikeTypeTraits<mlir::Identifier> {
public:
static inline void *getAsVoidPointer(mlir::Identifier I) {
return const_cast<void *>(I.getAsOpaquePointer());
}
static inline mlir::Identifier getFromVoidPointer(void *P) {
return mlir::Identifier::getFromOpaquePointer(P);
}
enum { NumLowBitsAvailable = 2 };
};
} // end namespace llvm
#endif