LLVM 17.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
18#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 <cctype>
24#include <map>
25#include <sstream>
26
27namespace llvm {
28namespace logicalview {
29
30template <typename T>
31using TypeIsValid = std::bool_constant<std::is_pointer<T>::value>;
32
33// Utility class to help memory management and perform an automatic cleaning.
34template <typename T, unsigned N = 8>
35class LVAutoSmallVector : public SmallVector<T, N> {
36 static_assert(TypeIsValid<T>::value, "T must be a pointer type");
37
38public:
41
43 // Destroy the constructed elements in the vector.
44 for (auto *Item : *this)
45 delete Item;
46 }
47};
48
49// Used to record specific characteristics about the objects.
50template <typename T> class LVProperties {
51 SmallBitVector Bits = SmallBitVector(static_cast<unsigned>(T::LastEntry) + 1);
52
53public:
54 LVProperties() = default;
55
56 void set(T Idx) { Bits[static_cast<unsigned>(Idx)] = 1; }
57 void reset(T Idx) { Bits[static_cast<unsigned>(Idx)] = 0; }
58 bool get(T Idx) const { return Bits[static_cast<unsigned>(Idx)]; }
59};
60
61// Generate get, set and reset 'bool' functions for LVProperties instances.
62// FAMILY: instance name.
63// ENUM: enumeration instance.
64// FIELD: enumerator instance.
65// F1, F2, F3: optional 'set' functions to be called.
66#define BOOL_BIT(FAMILY, ENUM, FIELD) \
67 bool get##FIELD() const { return FAMILY.get(ENUM::FIELD); } \
68 void set##FIELD() { FAMILY.set(ENUM::FIELD); } \
69 void reset##FIELD() { FAMILY.reset(ENUM::FIELD); }
70
71#define BOOL_BIT_1(FAMILY, ENUM, FIELD, F1) \
72 bool get##FIELD() const { return FAMILY.get(ENUM::FIELD); } \
73 void set##FIELD() { \
74 FAMILY.set(ENUM::FIELD); \
75 set##F1(); \
76 } \
77 void reset##FIELD() { FAMILY.reset(ENUM::FIELD); }
78
79#define BOOL_BIT_2(FAMILY, ENUM, FIELD, F1, F2) \
80 bool get##FIELD() const { return FAMILY.get(ENUM::FIELD); } \
81 void set##FIELD() { \
82 FAMILY.set(ENUM::FIELD); \
83 set##F1(); \
84 set##F2(); \
85 } \
86 void reset##FIELD() { FAMILY.reset(ENUM::FIELD); }
87
88#define BOOL_BIT_3(FAMILY, ENUM, FIELD, F1, F2, F3) \
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 set##F3(); \
95 } \
96 void reset##FIELD() { FAMILY.reset(ENUM::FIELD); }
97
98// Generate get, set and reset functions for 'properties'.
99#define PROPERTY(ENUM, FIELD) BOOL_BIT(Properties, ENUM, FIELD)
100#define PROPERTY_1(ENUM, FIELD, F1) BOOL_BIT_1(Properties, ENUM, FIELD, F1)
101#define PROPERTY_2(ENUM, FIELD, F1, F2) \
102 BOOL_BIT_2(Properties, ENUM, FIELD, F1, F2)
103#define PROPERTY_3(ENUM, FIELD, F1, F2, F3) \
104 BOOL_BIT_3(Properties, ENUM, FIELD, F1, F2, F3)
105
106// Generate get, set and reset functions for 'kinds'.
107#define KIND(ENUM, FIELD) BOOL_BIT(Kinds, ENUM, FIELD)
108#define KIND_1(ENUM, FIELD, F1) BOOL_BIT_1(Kinds, ENUM, FIELD, F1)
109#define KIND_2(ENUM, FIELD, F1, F2) BOOL_BIT_2(Kinds, ENUM, FIELD, F1, F2)
110#define KIND_3(ENUM, FIELD, F1, F2, F3) \
111 BOOL_BIT_3(Kinds, ENUM, FIELD, F1, F2, F3)
112
113const int HEX_WIDTH = 12;
114inline FormattedNumber hexValue(uint64_t N, unsigned Width = HEX_WIDTH,
115 bool Upper = false) {
116 return format_hex(N, Width, Upper);
117}
118
119// Output the hexadecimal representation of 'Value' using '[0x%08x]' format.
120inline std::string hexString(uint64_t Value, size_t Width = HEX_WIDTH) {
121 std::string String;
123 Stream << hexValue(Value, Width, false);
124 return Stream.str();
125}
126
127// Get a hexadecimal string representation for the given value.
128inline std::string hexSquareString(uint64_t Value) {
129 return (Twine("[") + Twine(hexString(Value)) + Twine("]")).str();
130}
131
132// Return a string with the First and Others separated by spaces.
133template <typename... Args>
134std::string formatAttributes(const StringRef First, Args... Others) {
135 const auto List = {First, Others...};
136 std::stringstream Stream;
137 size_t Size = 0;
138 for (const StringRef &Item : List) {
139 Stream << (Size ? " " : "") << Item.str();
140 Size = Item.size();
141 }
142 Stream << (Size ? " " : "");
143 return Stream.str();
144}
145
146// Add an item to a map with second being a list.
147template <typename MapType, typename ListType, typename KeyType,
148 typename ValueType>
149void addItem(MapType *Map, KeyType Key, ValueType Value) {
150 ListType *List = nullptr;
151 typename MapType::const_iterator Iter = Map->find(Key);
152 if (Iter != Map->end())
153 List = Iter->second;
154 else {
155 List = new ListType();
156 Map->emplace(Key, List);
157 }
158 List->push_back(Value);
159}
160
161// Delete the map contained list.
162template <typename MapType> void deleteList(MapType &Map) {
163 for (typename MapType::const_reference Entry : Map)
164 delete Entry.second;
165}
166
167// Double map data structure.
168template <typename FirstKeyType, typename SecondKeyType, typename ValueType>
170 static_assert(std::is_pointer<ValueType>::value,
171 "ValueType must be a pointer.");
172 using LVSecondMapType = std::map<SecondKeyType, ValueType>;
173 using LVFirstMapType = std::map<FirstKeyType, LVSecondMapType *>;
174 using LVAuxMapType = std::map<SecondKeyType, FirstKeyType>;
175 using LVValueTypes = std::vector<ValueType>;
176 LVFirstMapType FirstMap;
177 LVAuxMapType AuxMap;
178
179public:
180 LVDoubleMap() = default;
182 for (auto &Entry : FirstMap)
183 delete Entry.second;
184 }
185
186 void add(FirstKeyType FirstKey, SecondKeyType SecondKey, ValueType Value) {
187 LVSecondMapType *SecondMap = nullptr;
188 typename LVFirstMapType::iterator FirstIter = FirstMap.find(FirstKey);
189 if (FirstIter == FirstMap.end()) {
190 SecondMap = new LVSecondMapType();
191 FirstMap.emplace(FirstKey, SecondMap);
192 } else {
193 SecondMap = FirstIter->second;
194 }
195
196 assert(SecondMap && "SecondMap is null.");
197 if (SecondMap && SecondMap->find(SecondKey) == SecondMap->end())
198 SecondMap->emplace(SecondKey, Value);
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 LVSecondMapType *SecondMap = FirstIter->second;
212 return SecondMap;
213 }
214
215 ValueType find(FirstKeyType FirstKey, SecondKeyType SecondKey) const {
216 LVSecondMapType *SecondMap = findMap(FirstKey);
217 if (!SecondMap)
218 return nullptr;
219
220 typename LVSecondMapType::const_iterator SecondIter =
221 SecondMap->find(SecondKey);
222 return (SecondIter != SecondMap->end()) ? SecondIter->second : nullptr;
223 }
224
225 ValueType find(SecondKeyType SecondKey) const {
226 typename LVAuxMapType::const_iterator AuxIter = AuxMap.find(SecondKey);
227 if (AuxIter == AuxMap.end())
228 return nullptr;
229 return find(AuxIter->second, SecondKey);
230 }
231
232 // Return a vector with all the 'ValueType' values.
233 LVValueTypes find() const {
234 LVValueTypes Values;
235 if (FirstMap.empty())
236 return Values;
237 for (typename LVFirstMapType::const_reference FirstEntry : FirstMap) {
238 LVSecondMapType *SecondMap = FirstEntry.second;
239 for (typename LVSecondMapType::const_reference SecondEntry : *SecondMap)
240 Values.push_back(SecondEntry.second);
241 }
242 return Values;
243 }
244};
245
246// Unified and flattened pathnames.
247std::string transformPath(StringRef Path);
248std::string flattenedFilePath(StringRef Path);
249
250inline std::string formattedKind(StringRef Kind) {
251 return (Twine("{") + Twine(Kind) + Twine("}")).str();
252}
253
254inline std::string formattedName(StringRef Name) {
255 return (Twine("'") + Twine(Name) + Twine("'")).str();
256}
257
258inline std::string formattedNames(StringRef Name1, StringRef Name2) {
259 return (Twine("'") + Twine(Name1) + Twine(Name2) + Twine("'")).str();
260}
261
262// These are the values assigned to the debug location record IDs.
263// See DebugInfo/CodeView/CodeViewSymbols.def.
264// S_DEFRANGE 0x113f
265// S_DEFRANGE_SUBFIELD 0x1140
266// S_DEFRANGE_REGISTER 0x1141
267// S_DEFRANGE_FRAMEPOINTER_REL 0x1142
268// S_DEFRANGE_SUBFIELD_REGISTER 0x1143
269// S_DEFRANGE_FRAMEPOINTER_REL_FULL_SCOPE 0x1144
270// S_DEFRANGE_REGISTER_REL 0x1145
271// When recording CodeView debug location, the above values are truncated
272// to a uint8_t value in order to fit the 'OpCode' used for the logical
273// debug location operations.
274// Return the original CodeView enum value.
275inline uint16_t getCodeViewOperationCode(uint8_t Code) { return 0x1100 | Code; }
276
277} // end namespace logicalview
278} // end namespace llvm
279
280#endif // LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVSUPPORT_H
Returns the sub type a function will return at a given Idx Should correspond to the result type of an ExtractValue instruction executed with just that one unsigned Idx
uint64_t Size
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
This file implements the SmallBitVector class.
This file defines the SmallString class.
This is a helper class used for format_hex() and format_decimal().
Definition: Format.h:164
This is a 'bitvector' (really, a variable-sized bit array), optimized for the case when the array is ...
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1200
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:50
Twine - A lightweight data structure for efficiently representing the concatenation of temporary valu...
Definition: Twine.h:81
LLVM Value Representation.
Definition: Value.h:74
typename SmallVector< T, N >::iterator iterator
Definition: LVSupport.h:39
void add(FirstKeyType FirstKey, SecondKeyType SecondKey, ValueType Value)
Definition: LVSupport.h:186
LVValueTypes find() const
Definition: LVSupport.h:233
LVSecondMapType * findMap(FirstKeyType FirstKey) const
Definition: LVSupport.h:206
ValueType find(FirstKeyType FirstKey, SecondKeyType SecondKey) const
Definition: LVSupport.h:215
ValueType find(SecondKeyType SecondKey) const
Definition: LVSupport.h:225
A raw_ostream that writes to an std::string.
Definition: raw_ostream.h:642
std::string & str()
Returns the string's reference.
Definition: raw_ostream.h:660
const int HEX_WIDTH
Definition: LVSupport.h:113
FormattedNumber hexValue(uint64_t N, unsigned Width=HEX_WIDTH, bool Upper=false)
Definition: LVSupport.h:114
std::string hexString(uint64_t Value, size_t Width=HEX_WIDTH)
Definition: LVSupport.h:120
std::bool_constant< std::is_pointer< T >::value > TypeIsValid
Definition: LVSupport.h:31
std::string formattedNames(StringRef Name1, StringRef Name2)
Definition: LVSupport.h:258
void addItem(MapType *Map, KeyType Key, ValueType Value)
Definition: LVSupport.h:149
std::string formattedKind(StringRef Kind)
Definition: LVSupport.h:250
uint16_t getCodeViewOperationCode(uint8_t Code)
Definition: LVSupport.h:275
void deleteList(MapType &Map)
Definition: LVSupport.h:162
std::string hexSquareString(uint64_t Value)
Definition: LVSupport.h:128
std::string transformPath(StringRef Path)
Definition: LVSupport.cpp:27
std::string formattedName(StringRef Name)
Definition: LVSupport.h:254
std::string flattenedFilePath(StringRef Path)
Definition: LVSupport.cpp:44
std::string formatAttributes(const StringRef First, Args... Others)
Definition: LVSupport.h:134
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
FormattedNumber format_hex(uint64_t N, unsigned Width, bool Upper=false)
format_hex - Output N as a fixed width hexadecimal.
Definition: Format.h:186
#define N