16
16
#include " llvm/ADT/ArrayRef.h"
17
17
#include " llvm/ADT/MapVector.h"
18
18
#include " llvm/ADT/STLFunctionalExtras.h"
19
- #include " llvm/ADT/StringMap.h"
20
19
#include " llvm/ADT/StringRef.h"
21
20
#include " llvm/BinaryFormat/Dwarf.h"
22
21
#include " llvm/CodeGen/DIE.h"
25
24
#include " llvm/Support/DJB.h"
26
25
#include " llvm/Support/Debug.h"
27
26
#include < cstdint>
27
+ #include < variant>
28
28
#include < vector>
29
29
30
30
// / \file
103
103
namespace llvm {
104
104
105
105
class AsmPrinter ;
106
- class DwarfCompileUnit ;
106
+ class DwarfUnit ;
107
107
class DwarfDebug ;
108
+ class DwarfTypeUnit ;
108
109
class MCSymbol ;
109
110
class raw_ostream ;
110
111
@@ -196,6 +197,9 @@ template <typename DataT> class AccelTable : public AccelTableBase {
196
197
197
198
template <typename ... Types>
198
199
void addName (DwarfStringPoolEntryRef Name, Types &&... Args);
200
+ void clear () { Entries.clear (); }
201
+ void addEntries (AccelTable<DataT> &Table);
202
+ const StringEntries getEntries () const { return Entries; }
199
203
};
200
204
201
205
template <typename AccelTableDataT>
@@ -249,46 +253,93 @@ class AppleAccelTableData : public AccelTableData {
249
253
// / emitDWARF5AccelTable function.
250
254
class DWARF5AccelTableData : public AccelTableData {
251
255
public:
256
+ struct AttributeEncoding {
257
+ dwarf::Index Index;
258
+ dwarf::Form Form;
259
+ };
260
+
252
261
static uint32_t hash (StringRef Name) { return caseFoldingDjbHash (Name); }
253
262
254
- DWARF5AccelTableData (const DIE &Die) : Die(Die) {}
263
+ DWARF5AccelTableData (const DIE &Die, const uint32_t UnitID,
264
+ const bool IsTU = false );
265
+ DWARF5AccelTableData (const uint64_t DieOffset, const unsigned DieTag,
266
+ const unsigned UnitID, const bool IsTU = false )
267
+ : OffsetVal(DieOffset), DieTag(DieTag), UnitID(UnitID), IsTU(IsTU) {}
255
268
256
269
#ifndef NDEBUG
257
270
void print (raw_ostream &OS) const override ;
258
271
#endif
259
272
260
- const DIE &getDie () const { return Die; }
261
- uint64_t getDieOffset () const { return Die.getOffset (); }
262
- unsigned getDieTag () const { return Die.getTag (); }
273
+ uint64_t getDieOffset () const {
274
+ assert (isNormalized () && " Accessing DIE Offset before normalizing." );
275
+ return std::get<uint64_t >(OffsetVal);
276
+ }
277
+ unsigned getDieTag () const { return DieTag; }
278
+ unsigned getUnitID () const { return UnitID; }
279
+ bool isTU () const { return IsTU; }
280
+ void normalizeDIEToOffset () {
281
+ assert (!isNormalized () && " Accessing offset after normalizing." );
282
+ OffsetVal = std::get<const DIE *>(OffsetVal)->getOffset ();
283
+ }
284
+ bool isNormalized () const {
285
+ return std::holds_alternative<uint64_t >(OffsetVal);
286
+ }
263
287
264
288
protected:
265
- const DIE &Die;
289
+ std::variant<const DIE *, uint64_t > OffsetVal;
290
+ uint32_t DieTag : 16 ;
291
+ uint32_t UnitID : 15 ;
292
+ uint32_t IsTU : 1 ;
266
293
267
- uint64_t order () const override { return Die. getOffset (); }
294
+ uint64_t order () const override { return getDieOffset (); }
268
295
};
269
296
270
- class DWARF5AccelTableStaticData : public AccelTableData {
271
- public:
272
- static uint32_t hash (StringRef Name) { return caseFoldingDjbHash (Name); }
273
-
274
- DWARF5AccelTableStaticData (uint64_t DieOffset, unsigned DieTag,
275
- unsigned CUIndex)
276
- : DieOffset(DieOffset), DieTag(DieTag), CUIndex(CUIndex) {}
277
-
278
- #ifndef NDEBUG
279
- void print (raw_ostream &OS) const override ;
280
- #endif
281
-
282
- uint64_t getDieOffset () const { return DieOffset; }
283
- unsigned getDieTag () const { return DieTag; }
284
- unsigned getCUIndex () const { return CUIndex; }
297
+ struct TypeUnitMetaInfo {
298
+ // Symbol for start of the TU section or signature if this is SplitDwarf.
299
+ std::variant<MCSymbol *, uint64_t > LabelOrSignature;
300
+ // Unique ID of Type Unit.
301
+ unsigned UniqueID;
302
+ };
303
+ using TUVectorTy = SmallVector<TypeUnitMetaInfo, 1 >;
304
+ class DWARF5AccelTable : public AccelTable <DWARF5AccelTableData> {
305
+ // Symbols to start of all the TU sections that were generated.
306
+ TUVectorTy TUSymbolsOrHashes;
285
307
286
- protected:
287
- uint64_t DieOffset;
288
- unsigned DieTag;
289
- unsigned CUIndex;
308
+ public:
309
+ struct UnitIndexAndEncoding {
310
+ unsigned Index;
311
+ DWARF5AccelTableData::AttributeEncoding Encoding;
312
+ };
313
+ // / Returns type units that were constructed.
314
+ const TUVectorTy &getTypeUnitsSymbols () { return TUSymbolsOrHashes; }
315
+ // / Add a type unit start symbol.
316
+ void addTypeUnitSymbol (DwarfTypeUnit &U);
317
+ // / Add a type unit Signature.
318
+ void addTypeUnitSignature (DwarfTypeUnit &U);
319
+ // / Convert DIE entries to explicit offset.
320
+ // / Needs to be called after DIE offsets are computed.
321
+ void convertDieToOffset () {
322
+ for (auto &Entry : Entries) {
323
+ for (AccelTableData *Value : Entry.second .Values ) {
324
+ DWARF5AccelTableData *Data = static_cast <DWARF5AccelTableData *>(Value);
325
+ // For TU we normalize as each Unit is emitted.
326
+ // So when this is invoked after CU construction we will be in mixed
327
+ // state.
328
+ if (!Data->isNormalized ())
329
+ Data->normalizeDIEToOffset ();
330
+ }
331
+ }
332
+ }
290
333
291
- uint64_t order () const override { return DieOffset; }
334
+ void addTypeEntries (DWARF5AccelTable &Table) {
335
+ for (auto &Entry : Table.getEntries ()) {
336
+ for (AccelTableData *Value : Entry.second .Values ) {
337
+ DWARF5AccelTableData *Data = static_cast <DWARF5AccelTableData *>(Value);
338
+ addName (Entry.second .Name , Data->getDieOffset (), Data->getDieTag (),
339
+ Data->getUnitID (), true );
340
+ }
341
+ }
342
+ }
292
343
};
293
344
294
345
void emitAppleAccelTableImpl (AsmPrinter *Asm, AccelTableBase &Contents,
@@ -305,16 +356,20 @@ void emitAppleAccelTable(AsmPrinter *Asm, AccelTable<DataT> &Contents,
305
356
emitAppleAccelTableImpl (Asm, Contents, Prefix, SecBegin, DataT::Atoms);
306
357
}
307
358
308
- void emitDWARF5AccelTable (AsmPrinter *Asm,
309
- AccelTable<DWARF5AccelTableData> &Contents,
359
+ void emitDWARF5AccelTable (AsmPrinter *Asm, DWARF5AccelTable &Contents,
310
360
const DwarfDebug &DD,
311
361
ArrayRef<std::unique_ptr<DwarfCompileUnit>> CUs);
312
362
363
+ // / Emit a DWARFv5 Accelerator Table consisting of entries in the specified
364
+ // / AccelTable. The \p CUs contains either symbols keeping offsets to the
365
+ // / start of compilation unit, either offsets to the start of compilation
366
+ // / unit themselves.
313
367
void emitDWARF5AccelTable (
314
- AsmPrinter *Asm, AccelTable<DWARF5AccelTableStaticData> &Contents,
315
- ArrayRef<MCSymbol *> CUs,
316
- llvm::function_ref<unsigned (const DWARF5AccelTableStaticData &)>
317
- getCUIndexForEntry);
368
+ AsmPrinter *Asm, DWARF5AccelTable &Contents,
369
+ ArrayRef<std::variant<MCSymbol *, uint64_t >> CUs,
370
+ llvm::function_ref<std::optional<DWARF5AccelTable::UnitIndexAndEncoding>(
371
+ const DWARF5AccelTableData &)>
372
+ getIndexForEntry);
318
373
319
374
// / Accelerator table data implementation for simple Apple accelerator tables
320
375
// / with just a DIE reference.
0 commit comments