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