File: DWARFLinkerTypeUnit.h

package info (click to toggle)
llvm-toolchain-18 1%3A18.1.8-18
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 1,908,340 kB
  • sloc: cpp: 6,667,937; ansic: 1,440,452; asm: 883,619; python: 230,549; objc: 76,880; f90: 74,238; lisp: 35,989; pascal: 16,571; sh: 10,229; perl: 7,459; ml: 5,047; awk: 3,523; makefile: 2,987; javascript: 2,149; xml: 892; fortran: 649; cs: 573
file content (140 lines) | stat: -rw-r--r-- 5,110 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
//===- DWARFLinkerTypeUnit.h ------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#ifndef LLVM_DWARFLINKER_PARALLEL_DWARFLINKERTYPEUNIT_H
#define LLVM_DWARFLINKER_PARALLEL_DWARFLINKERTYPEUNIT_H

#include "DWARFLinkerUnit.h"
#include "llvm/CodeGen/DIE.h"
#include "llvm/DebugInfo/DWARF/DWARFDebugLine.h"
#include "llvm/DebugInfo/DWARF/DWARFUnit.h"

namespace llvm {
namespace dwarf_linker {
namespace parallel {

/// Type Unit is used to represent an artificial compilation unit
/// which keeps all type information. This type information is referenced
/// from other compilation units.
class TypeUnit : public DwarfUnit {
public:
  TypeUnit(LinkingGlobalData &GlobalData, unsigned ID,
           std::optional<uint16_t> Language, dwarf::FormParams Format,
           llvm::endianness Endianess);

  /// Generates DIE tree based on information from TypesMap.
  void createDIETree(BumpPtrAllocator &Allocator);

  /// Emits resulting dwarf based on information from DIE tree.
  Error finishCloningAndEmit(const Triple &TargetTriple);

  /// Returns global type pool.
  TypePool &getTypePool() { return Types; }

  /// TypeUnitAccelInfo extends AccelInfo structure with type specific fileds.
  /// We need these additional fields to decide whether OutDIE should have an
  /// accelerator record or not. The TypeEntryBodyPtr can refer to the
  /// declaration DIE and definition DIE corresponding to the type entry.
  /// Only one of them would be used in final output. So if TypeUnitAccelInfo
  /// refers OutDIE which does not match with TypeEntryBodyPtr->getFinalDie()
  /// then such record should be skipped.
  struct TypeUnitAccelInfo : public AccelInfo {
    /// Pointer to the output DIE which owns this accelerator record.
    DIE *OutDIE = nullptr;

    /// Pointer to the type entry body.
    TypeEntryBody *TypeEntryBodyPtr = nullptr;
  };

  /// Enumerates all accelerator records and call \p Handler for each.
  void
  forEachAcceleratorRecord(function_ref<void(AccelInfo &)> Handler) override {
    AcceleratorRecords.forEach([&](TypeUnitAccelInfo &Info) {
      // Check whether current record is for the final DIE.
      assert(Info.TypeEntryBodyPtr != nullptr);

      if (&Info.TypeEntryBodyPtr->getFinalDie() != Info.OutDIE)
        return;

      Info.OutOffset = Info.OutDIE->getOffset();
      Handler(Info);
    });
  }

  /// Returns index for the specified \p String inside .debug_str_offsets.
  uint64_t getDebugStrIndex(const StringEntry *String) override {
    std::unique_lock<std::mutex> LockGuard(DebugStringIndexMapMutex);
    return DebugStringIndexMap.getValueIndex(String);
  }

  /// Adds \p Info to the unit's accelerator records.
  void saveAcceleratorInfo(const TypeUnitAccelInfo &Info) {
    AcceleratorRecords.add(Info);
  }

private:
  /// Type DIEs are partially created at clonning stage. They are organised
  /// as a tree using type entries. This function links DIEs(corresponding
  /// to the type entries) into the tree structure.
  uint64_t finalizeTypeEntryRec(uint64_t OutOffset, DIE *OutDIE,
                                TypeEntry *Entry);

  /// Prepares DIEs to be linked into the tree.
  void prepareDataForTreeCreation();

  /// Add specified \p Dir and \p Filename into the line table
  /// of this type unit.
  uint32_t addFileNameIntoLinetable(StringEntry *Dir, StringEntry *FileName);

  std::pair<dwarf::Form, uint8_t> getScalarFormForValue(uint64_t Value) const;

  uint8_t getSizeByAttrForm(dwarf::Form Form) const;

  struct CmpStringEntryRef {
    bool operator()(const StringEntry *LHS, const StringEntry *RHS) const {
      return LHS->first() < RHS->first();
    }
  };
  struct CmpDirIDStringEntryRef {
    bool operator()(const std::pair<StringEntry *, uint64_t> &LHS,
                    const std::pair<StringEntry *, uint64_t> &RHS) const {
      return LHS.second < RHS.second ||
             (!(RHS.second < LHS.second) &&
              LHS.first->first() < RHS.first->first());
    }
  };

  /// The DW_AT_language of this unit.
  std::optional<uint16_t> Language;

  /// This unit line table.
  DWARFDebugLine::LineTable LineTable;

  /// Data members keeping file names for line table.
  using DirectoriesMapTy = std::map<StringEntry *, size_t, CmpStringEntryRef>;
  using FilenamesMapTy = std::map<std::pair<StringEntry *, uint64_t>, size_t,
                                  CmpDirIDStringEntryRef>;

  DirectoriesMapTy DirectoriesMap;
  FilenamesMapTy FileNamesMap;

  /// Type DIEs tree.
  TypePool Types;

  /// List of accelerator entries for this unit.
  ArrayList<TypeUnitAccelInfo> AcceleratorRecords;

  /// Guard for DebugStringIndexMap.
  std::mutex DebugStringIndexMapMutex;
};

} // end of namespace parallel
} // end of namespace dwarf_linker
} // end of namespace llvm

#endif // LLVM_DWARFLINKER_PARALLEL_DWARFLINKERTYPEUNIT_H