1 | #ifndef LLVM_DWP_DWPSTRINGPOOL_H |
---|---|
2 | #define LLVM_DWP_DWPSTRINGPOOL_H |
3 | |
4 | #include "llvm/ADT/DenseMap.h" |
5 | #include "llvm/MC/MCSection.h" |
6 | #include "llvm/MC/MCStreamer.h" |
7 | #include <cassert> |
8 | |
9 | namespace llvm { |
10 | class DWPStringPool { |
11 | |
12 | struct CStrDenseMapInfo { |
13 | static inline const char *getEmptyKey() { |
14 | return reinterpret_cast<const char *>(~static_cast<uintptr_t>(0)); |
15 | } |
16 | static inline const char *getTombstoneKey() { |
17 | return reinterpret_cast<const char *>(~static_cast<uintptr_t>(1)); |
18 | } |
19 | static unsigned getHashValue(const char *Val) { |
20 | assert(Val != getEmptyKey() && "Cannot hash the empty key!"); |
21 | assert(Val != getTombstoneKey() && "Cannot hash the tombstone key!"); |
22 | return (unsigned)hash_value(S: StringRef(Val)); |
23 | } |
24 | static bool isEqual(const char *LHS, const char *RHS) { |
25 | if (RHS == getEmptyKey()) |
26 | return LHS == getEmptyKey(); |
27 | if (RHS == getTombstoneKey()) |
28 | return LHS == getTombstoneKey(); |
29 | return strcmp(s1: LHS, s2: RHS) == 0; |
30 | } |
31 | }; |
32 | |
33 | MCStreamer &Out; |
34 | MCSection *Sec; |
35 | DenseMap<const char *, uint32_t, CStrDenseMapInfo> Pool; |
36 | uint32_t Offset = 0; |
37 | |
38 | public: |
39 | DWPStringPool(MCStreamer &Out, MCSection *Sec) : Out(Out), Sec(Sec) {} |
40 | |
41 | uint32_t getOffset(const char *Str, unsigned Length) { |
42 | assert(strlen(Str) + 1 == Length && "Ensure length hint is correct"); |
43 | |
44 | auto Pair = Pool.insert(KV: std::make_pair(x&: Str, y&: Offset)); |
45 | if (Pair.second) { |
46 | Out.switchSection(Section: Sec); |
47 | Out.emitBytes(Data: StringRef(Str, Length)); |
48 | Offset += Length; |
49 | } |
50 | |
51 | return Pair.first->second; |
52 | } |
53 | }; |
54 | } // namespace llvm |
55 | |
56 | #endif // LLVM_DWP_DWPSTRINGPOOL_H |
57 |