File indexing completed on 2026-05-10 08:44:23
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015 #ifndef LLVM_PROFILEDATA_FUNCTIONID_H
0016 #define LLVM_PROFILEDATA_FUNCTIONID_H
0017
0018 #include "llvm/ADT/DenseMapInfo.h"
0019 #include "llvm/ADT/Hashing.h"
0020 #include "llvm/ADT/StringRef.h"
0021 #include "llvm/Support/MD5.h"
0022 #include "llvm/Support/raw_ostream.h"
0023 #include <cstdint>
0024
0025 namespace llvm {
0026 namespace sampleprof {
0027
0028
0029
0030
0031
0032
0033
0034
0035
0036 class FunctionId {
0037
0038 const char *Data = nullptr;
0039
0040
0041
0042 uint64_t LengthOrHashCode = 0;
0043
0044
0045
0046
0047
0048 static int compareMemory(const char *Lhs, const char *Rhs, uint64_t Length) {
0049 if (Lhs == Rhs)
0050 return 0;
0051 if (!Lhs)
0052 return -1;
0053 if (!Rhs)
0054 return 1;
0055 return ::memcmp(Lhs, Rhs, (size_t)Length);
0056 }
0057
0058 public:
0059 FunctionId() = default;
0060
0061
0062 explicit FunctionId(StringRef Str)
0063 : Data(Str.data()), LengthOrHashCode(Str.size()) {
0064 }
0065
0066
0067 explicit FunctionId(uint64_t HashCode)
0068 : LengthOrHashCode(HashCode) {
0069 assert(HashCode != 0);
0070 }
0071
0072
0073
0074
0075
0076 bool equals(const FunctionId &Other) const {
0077 return LengthOrHashCode == Other.LengthOrHashCode &&
0078 compareMemory(Data, Other.Data, LengthOrHashCode) == 0;
0079 }
0080
0081
0082
0083
0084
0085 int compare(const FunctionId &Other) const {
0086 auto Res = compareMemory(
0087 Data, Other.Data, std::min(LengthOrHashCode, Other.LengthOrHashCode));
0088 if (Res != 0)
0089 return Res;
0090 if (LengthOrHashCode == Other.LengthOrHashCode)
0091 return 0;
0092 return LengthOrHashCode < Other.LengthOrHashCode ? -1 : 1;
0093 }
0094
0095
0096
0097 std::string str() const {
0098 if (Data)
0099 return std::string(Data, LengthOrHashCode);
0100 if (LengthOrHashCode != 0)
0101 return std::to_string(LengthOrHashCode);
0102 return std::string();
0103 }
0104
0105
0106
0107
0108 StringRef stringRef() const {
0109 if (Data)
0110 return StringRef(Data, LengthOrHashCode);
0111 assert(LengthOrHashCode == 0 &&
0112 "Cannot convert MD5 FunctionId to StringRef");
0113 return StringRef();
0114 }
0115
0116 friend raw_ostream &operator<<(raw_ostream &OS, const FunctionId &Obj);
0117
0118
0119
0120
0121
0122
0123 uint64_t getHashCode() const {
0124 if (Data)
0125 return MD5Hash(StringRef(Data, LengthOrHashCode));
0126 return LengthOrHashCode;
0127 }
0128
0129 bool empty() const { return LengthOrHashCode == 0; }
0130
0131
0132 bool isStringRef() const { return Data != nullptr; }
0133 };
0134
0135 inline bool operator==(const FunctionId &LHS, const FunctionId &RHS) {
0136 return LHS.equals(RHS);
0137 }
0138
0139 inline bool operator!=(const FunctionId &LHS, const FunctionId &RHS) {
0140 return !LHS.equals(RHS);
0141 }
0142
0143 inline bool operator<(const FunctionId &LHS, const FunctionId &RHS) {
0144 return LHS.compare(RHS) < 0;
0145 }
0146
0147 inline bool operator<=(const FunctionId &LHS, const FunctionId &RHS) {
0148 return LHS.compare(RHS) <= 0;
0149 }
0150
0151 inline bool operator>(const FunctionId &LHS, const FunctionId &RHS) {
0152 return LHS.compare(RHS) > 0;
0153 }
0154
0155 inline bool operator>=(const FunctionId &LHS, const FunctionId &RHS) {
0156 return LHS.compare(RHS) >= 0;
0157 }
0158
0159 inline raw_ostream &operator<<(raw_ostream &OS, const FunctionId &Obj) {
0160 if (Obj.Data)
0161 return OS << StringRef(Obj.Data, Obj.LengthOrHashCode);
0162 if (Obj.LengthOrHashCode != 0)
0163 return OS << Obj.LengthOrHashCode;
0164 return OS;
0165 }
0166
0167 inline uint64_t MD5Hash(const FunctionId &Obj) {
0168 return Obj.getHashCode();
0169 }
0170
0171 inline uint64_t hash_value(const FunctionId &Obj) {
0172 return Obj.getHashCode();
0173 }
0174
0175 }
0176
0177
0178
0179 template <> struct DenseMapInfo<sampleprof::FunctionId, void> {
0180
0181 static inline sampleprof::FunctionId getEmptyKey() {
0182 return sampleprof::FunctionId(~0ULL);
0183 }
0184
0185 static inline sampleprof::FunctionId getTombstoneKey() {
0186 return sampleprof::FunctionId(~1ULL);
0187 }
0188
0189 static unsigned getHashValue(const sampleprof::FunctionId &Val) {
0190 return Val.getHashCode();
0191 }
0192
0193 static bool isEqual(const sampleprof::FunctionId &LHS,
0194 const sampleprof::FunctionId &RHS) {
0195 return LHS == RHS;
0196 }
0197 };
0198
0199 }
0200
0201 namespace std {
0202
0203
0204
0205 template <> struct hash<llvm::sampleprof::FunctionId> {
0206 size_t operator()(const llvm::sampleprof::FunctionId &Val) const {
0207 return Val.getHashCode();
0208 }
0209 };
0210
0211 }
0212
0213 #endif