LLVM 23.0.0git
LVSupport.h
Go to the documentation of this file.
1//===-- LVSupport.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// This file defines support functions.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVSUPPORT_H
14#define LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVSUPPORT_H
15
16#include "llvm/ADT/Twine.h"
19#include "llvm/Support/Debug.h"
20#include "llvm/Support/Format.h"
21#include "llvm/Support/Path.h"
23#include <bitset>
24#include <cctype>
25#include <map>
26#include <sstream>
27#include <type_traits>
28
29namespace llvm {
30namespace logicalview {
31
32// Returns the unique string pool instance.
34
35using LVStringRefs = std::vector<StringRef>;
36using LVLexicalComponent = std::tuple<StringRef, StringRef>;
38 std::tuple<LVStringRefs::size_type, LVStringRefs::size_type>;
39
40// Used to record specific characteristics about the objects.
41template <typename T> class LVProperties {
42 static constexpr unsigned N_PROPS = static_cast<unsigned>(T::LastEntry);
43 // Use uint32_t as the underlying type if the `T` enum has at most 32
44 // enumerators; otherwise, fallback to the generic `std::bitset` case.
45 std::conditional_t<(N_PROPS > 32), std::bitset<N_PROPS>, uint32_t> Bits{};
46
47public:
48 LVProperties() = default;
49
50 void set(T Idx) {
51 if constexpr (std::is_same_v<decltype(Bits), uint32_t>)
52 Bits |= 1 << static_cast<unsigned>(Idx);
53 else
54 Bits.set(static_cast<unsigned>(Idx));
55 }
56 void reset(T Idx) {
57 if constexpr (std::is_same_v<decltype(Bits), uint32_t>)
58 Bits &= ~(1 << static_cast<unsigned>(Idx));
59 else
60 Bits.reset(static_cast<unsigned>(Idx));
61 }
62 bool get(T Idx) const {
63 if constexpr (std::is_same_v<decltype(Bits), uint32_t>)
64 return Bits & (1 << static_cast<unsigned>(Idx));
65 else
66 return Bits[static_cast<unsigned>(Idx)];
67 }
68};
69
70// Generate get, set and reset 'bool' functions for LVProperties instances.
71// FAMILY: instance name.
72// ENUM: enumeration instance.
73// FIELD: enumerator instance.
74// F1, F2, F3: optional 'set' functions to be called.
75#define BOOL_BIT(FAMILY, ENUM, FIELD) \
76 bool get##FIELD() const { return FAMILY.get(ENUM::FIELD); } \
77 void set##FIELD() { FAMILY.set(ENUM::FIELD); } \
78 void reset##FIELD() { FAMILY.reset(ENUM::FIELD); }
79
80#define BOOL_BIT_1(FAMILY, ENUM, FIELD, F1) \
81 bool get##FIELD() const { return FAMILY.get(ENUM::FIELD); } \
82 void set##FIELD() { \
83 FAMILY.set(ENUM::FIELD); \
84 set##F1(); \
85 } \
86 void reset##FIELD() { FAMILY.reset(ENUM::FIELD); }
87
88#define BOOL_BIT_2(FAMILY, ENUM, FIELD, F1, F2) \
89 bool get##FIELD() const { return FAMILY.get(ENUM::FIELD); } \
90 void set##FIELD() { \
91 FAMILY.set(ENUM::FIELD); \
92 set##F1(); \
93 set##F2(); \
94 } \
95 void reset##FIELD() { FAMILY.reset(ENUM::FIELD); }
96
97#define BOOL_BIT_3(FAMILY, ENUM, FIELD, F1, F2, F3) \
98 bool get##FIELD() const { return FAMILY.get(ENUM::FIELD); } \
99 void set##FIELD() { \
100 FAMILY.set(ENUM::FIELD); \
101 set##F1(); \
102 set##F2(); \
103 set##F3(); \
104 } \
105 void reset##FIELD() { FAMILY.reset(ENUM::FIELD); }
106
107// Generate get, set and reset functions for 'properties'.
108#define PROPERTY(ENUM, FIELD) BOOL_BIT(Properties, ENUM, FIELD)
109#define PROPERTY_1(ENUM, FIELD, F1) BOOL_BIT_1(Properties, ENUM, FIELD, F1)
110#define PROPERTY_2(ENUM, FIELD, F1, F2) \
111 BOOL_BIT_2(Properties, ENUM, FIELD, F1, F2)
112#define PROPERTY_3(ENUM, FIELD, F1, F2, F3) \
113 BOOL_BIT_3(Properties, ENUM, FIELD, F1, F2, F3)
114
115// Generate get, set and reset functions for 'kinds'.
116#define KIND(ENUM, FIELD) BOOL_BIT(Kinds, ENUM, FIELD)
117#define KIND_1(ENUM, FIELD, F1) BOOL_BIT_1(Kinds, ENUM, FIELD, F1)
118#define KIND_2(ENUM, FIELD, F1, F2) BOOL_BIT_2(Kinds, ENUM, FIELD, F1, F2)
119#define KIND_3(ENUM, FIELD, F1, F2, F3) \
120 BOOL_BIT_3(Kinds, ENUM, FIELD, F1, F2, F3)
121
122static constexpr int DEC_WIDTH = 8;
123inline FormattedNumber decValue(uint64_t N, unsigned Width = DEC_WIDTH) {
124 return format_decimal(N, Width);
125}
126
127// Output the decimal representation of 'Value'.
128inline std::string decString(uint64_t Value, size_t Width = DEC_WIDTH) {
129 std::string String;
131 Stream << decValue(Value, Width);
132 return String;
133}
134
135static constexpr int HEX_WIDTH = 12;
136inline FormattedNumber hexValue(uint64_t N, unsigned Width = HEX_WIDTH,
137 bool Upper = false) {
138 return format_hex(N, Width, Upper);
139}
140
141// Output the hexadecimal representation of 'Value' using '[0x%08x]' format.
142inline std::string hexString(uint64_t Value, size_t Width = HEX_WIDTH) {
143 std::string String;
145 Stream << hexValue(Value, Width, false);
146 return String;
147}
148
149// Get a hexadecimal string representation for the given value.
150inline std::string hexSquareString(uint64_t Value) {
151 return (Twine("[") + Twine(hexString(Value)) + Twine("]")).str();
152}
153
154// Return a string with the First and Others separated by spaces.
155template <typename... Args>
156std::string formatAttributes(const StringRef First, Args... Others) {
157 const auto List = {First, Others...};
158 std::stringstream Stream;
159 size_t Size = 0;
160 for (const StringRef &Item : List) {
161 Stream << (Size ? " " : "") << Item.str();
162 Size = Item.size();
163 }
164 Stream << (Size ? " " : "");
165 return Stream.str();
166}
167
168// Add an item to a map with second being a small vector.
169template <typename MapType, typename KeyType, typename ValueType>
170void addItem(MapType *Map, KeyType Key, ValueType Value) {
171 (*Map)[Key].push_back(Value);
172}
173
174// Double map data structure.
175template <typename FirstKeyType, typename SecondKeyType, typename ValueType>
177 static_assert(std::is_pointer<ValueType>::value,
178 "ValueType must be a pointer.");
179 using LVSecondMapType = std::map<SecondKeyType, ValueType>;
180 using LVFirstMapType =
181 std::map<FirstKeyType, std::unique_ptr<LVSecondMapType>>;
182 using LVAuxMapType = std::map<SecondKeyType, FirstKeyType>;
183 using LVValueTypes = std::vector<ValueType>;
184 LVFirstMapType FirstMap;
185 LVAuxMapType AuxMap;
186
187public:
188 void add(FirstKeyType FirstKey, SecondKeyType SecondKey, ValueType Value) {
189 typename LVFirstMapType::iterator FirstIter = FirstMap.find(FirstKey);
190 if (FirstIter == FirstMap.end()) {
191 auto SecondMapSP = std::make_unique<LVSecondMapType>();
192 SecondMapSP->emplace(SecondKey, Value);
193 FirstMap.emplace(FirstKey, std::move(SecondMapSP));
194 } else {
195 LVSecondMapType *SecondMap = FirstIter->second.get();
196 if (SecondMap->find(SecondKey) == SecondMap->end())
197 SecondMap->emplace(SecondKey, Value);
198 }
199
200 typename LVAuxMapType::iterator AuxIter = AuxMap.find(SecondKey);
201 if (AuxIter == AuxMap.end()) {
202 AuxMap.emplace(SecondKey, FirstKey);
203 }
204 }
205
206 LVSecondMapType *findMap(FirstKeyType FirstKey) const {
207 typename LVFirstMapType::const_iterator FirstIter = FirstMap.find(FirstKey);
208 if (FirstIter == FirstMap.end())
209 return nullptr;
210
211 return FirstIter->second.get();
212 }
213
214 ValueType find(FirstKeyType FirstKey, SecondKeyType SecondKey) const {
215 LVSecondMapType *SecondMap = findMap(FirstKey);
216 if (!SecondMap)
217 return nullptr;
218
219 typename LVSecondMapType::const_iterator SecondIter =
220 SecondMap->find(SecondKey);
221 return (SecondIter != SecondMap->end()) ? SecondIter->second : nullptr;
222 }
223
224 ValueType find(SecondKeyType SecondKey) const {
225 typename LVAuxMapType::const_iterator AuxIter = AuxMap.find(SecondKey);
226 if (AuxIter == AuxMap.end())
227 return nullptr;
228 return find(AuxIter->second, SecondKey);
229 }
230
231 // Return a vector with all the 'ValueType' values.
232 LVValueTypes find() const {
233 LVValueTypes Values;
234 if (FirstMap.empty())
235 return Values;
236 for (typename LVFirstMapType::const_reference FirstEntry : FirstMap) {
237 LVSecondMapType &SecondMap = *FirstEntry.second;
238 for (typename LVSecondMapType::const_reference SecondEntry : SecondMap)
239 Values.push_back(SecondEntry.second);
240 }
241 return Values;
242 }
243};
244
245// Unified and flattened pathnames.
246LLVM_ABI std::string transformPath(StringRef Path);
247LLVM_ABI std::string flattenedFilePath(StringRef Path);
248
249inline std::string formattedKind(StringRef Kind) {
250 return (Twine("{") + Twine(Kind) + Twine("}")).str();
251}
252
253inline std::string formattedName(StringRef Name) {
254 return (Twine("'") + Twine(Name) + Twine("'")).str();
255}
256
257inline std::string formattedNames(StringRef Name1, StringRef Name2) {
258 return (Twine("'") + Twine(Name1) + Twine(Name2) + Twine("'")).str();
259}
260
261// The given string represents a symbol or type name with optional enclosing
262// scopes, such as: name, name<..>, scope::name, scope::..::name, etc.
263// The string can have multiple references to template instantiations.
264// It returns the inner most component.
267LLVM_ABI std::string getScopedName(const LVStringRefs &Components,
268 StringRef BaseName = {});
269
270// These are the values assigned to the debug location record IDs.
271// See DebugInfo/CodeView/CodeViewSymbols.def.
272// S_DEFRANGE 0x113f
273// S_DEFRANGE_SUBFIELD 0x1140
274// S_DEFRANGE_REGISTER 0x1141
275// S_DEFRANGE_FRAMEPOINTER_REL 0x1142
276// S_DEFRANGE_SUBFIELD_REGISTER 0x1143
277// S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE 0x1144
278// S_DEFRANGE_REGISTER_REL 0x1145
279// S_DEFRANGE_REGISTER_REL_INDIR 0x1177
280// When recording CodeView debug location, the above values are truncated
281// to a uint8_t value in order to fit the 'OpCode' used for the logical
282// debug location operations.
283// Return the original CodeView enum value.
285
286} // end namespace logicalview
287} // end namespace llvm
288
289#endif // LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVSUPPORT_H
#define LLVM_ABI
Definition Compiler.h:215
#define T
This is a helper class used for format_hex() and format_decimal().
Definition Format.h:134
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition Twine.h:82
LLVM Value Representation.
Definition Value.h:75
void add(FirstKeyType FirstKey, SecondKeyType SecondKey, ValueType Value)
Definition LVSupport.h:188
LVValueTypes find() const
Definition LVSupport.h:232
LVSecondMapType * findMap(FirstKeyType FirstKey) const
Definition LVSupport.h:206
ValueType find(FirstKeyType FirstKey, SecondKeyType SecondKey) const
Definition LVSupport.h:214
ValueType find(SecondKeyType SecondKey) const
Definition LVSupport.h:224
A raw_ostream that writes to an std::string.
std::string decString(uint64_t Value, size_t Width=DEC_WIDTH)
Definition LVSupport.h:128
FormattedNumber hexValue(uint64_t N, unsigned Width=HEX_WIDTH, bool Upper=false)
Definition LVSupport.h:136
std::string hexString(uint64_t Value, size_t Width=HEX_WIDTH)
Definition LVSupport.h:142
std::string formattedNames(StringRef Name1, StringRef Name2)
Definition LVSupport.h:257
LLVM_ABI LVStringPool & getStringPool()
Definition LVSupport.cpp:25
std::string formattedKind(StringRef Kind)
Definition LVSupport.h:249
uint16_t getCodeViewOperationCode(uint8_t Code)
Definition LVSupport.h:284
void addItem(MapType *Map, KeyType Key, ValueType Value)
Definition LVSupport.h:170
static constexpr int HEX_WIDTH
Definition LVSupport.h:135
static constexpr int DEC_WIDTH
Definition LVSupport.h:122
std::string hexSquareString(uint64_t Value)
Definition LVSupport.h:150
LLVM_ABI LVStringRefs getAllLexicalComponents(StringRef Name)
std::vector< StringRef > LVStringRefs
Definition LVSupport.h:35
FormattedNumber decValue(uint64_t N, unsigned Width=DEC_WIDTH)
Definition LVSupport.h:123
LLVM_ABI std::string transformPath(StringRef Path)
Definition LVSupport.cpp:31
LLVM_ABI LVLexicalComponent getInnerComponent(StringRef Name)
std::string formattedName(StringRef Name)
Definition LVSupport.h:253
std::tuple< StringRef, StringRef > LVLexicalComponent
Definition LVSupport.h:36
LLVM_ABI std::string flattenedFilePath(StringRef Path)
Definition LVSupport.cpp:48
std::tuple< LVStringRefs::size_type, LVStringRefs::size_type > LVLexicalIndex
Definition LVSupport.h:37
std::string formatAttributes(const StringRef First, Args... Others)
Definition LVSupport.h:156
LLVM_ABI std::string getScopedName(const LVStringRefs &Components, StringRef BaseName={})
This is an optimization pass for GlobalISel generic memory operations.
FormattedNumber format_decimal(int64_t N, unsigned Width)
format_decimal - Output N as a right justified, fixed-width decimal.
Definition Format.h:181
RelativeUniformCounterPtr Values
Definition InstrProf.h:91
FormattedNumber format_hex(uint64_t N, unsigned Width, bool Upper=false)
format_hex - Output N as a fixed width hexadecimal.
Definition Format.h:156
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Definition ModRef.h:74
PointerUnion< const Value *, const PseudoSourceValue * > ValueType
#define N