Run DCE after a LoopFlatten test to reduce spurious output [nfc]
[llvm-project.git] / llvm / lib / DWARFLinkerParallel / DIEGenerator.h
blobc0bbce0f520143c04f80dbfb9a729d42f9827c27
1 //===- DIEGenerator.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 //===----------------------------------------------------------------------===//
9 #ifndef LLVM_LIB_DWARFLINKERPARALLEL_DIEGENERATOR_H
10 #define LLVM_LIB_DWARFLINKERPARALLEL_DIEGENERATOR_H
12 #include "DWARFLinkerGlobalData.h"
13 #include "DWARFLinkerUnit.h"
14 #include "llvm/CodeGen/DIE.h"
15 #include "llvm/Support/LEB128.h"
17 namespace llvm {
18 namespace dwarflinker_parallel {
20 /// This class is a helper to create output DIE tree.
21 class DIEGenerator {
22 public:
23 DIEGenerator(BumpPtrAllocator &Allocator, DwarfUnit &CU)
24 : Allocator(Allocator), CU(CU) {}
26 /// Creates a DIE of specified tag \p DieTag and \p OutOffset.
27 DIE *createDIE(dwarf::Tag DieTag, uint32_t OutOffset) {
28 OutputDIE = DIE::get(Allocator, DieTag);
30 OutputDIE->setOffset(OutOffset);
32 return OutputDIE;
35 /// Adds a specified \p Child to the current DIE.
36 void addChild(DIE *Child) {
37 assert(Child != nullptr);
38 assert(OutputDIE != nullptr);
40 OutputDIE->addChild(Child);
43 /// Adds specified scalar attribute to the current DIE.
44 std::pair<DIEValue &, size_t> addScalarAttribute(dwarf::Attribute Attr,
45 dwarf::Form AttrForm,
46 uint64_t Value) {
47 return addAttribute(Attr, AttrForm, DIEInteger(Value));
50 /// Adds specified location attribute to the current DIE.
51 std::pair<DIEValue &, size_t> addLocationAttribute(dwarf::Attribute Attr,
52 dwarf::Form AttrForm,
53 ArrayRef<uint8_t> Bytes) {
54 DIELoc *Loc = new (Allocator) DIELoc;
55 for (auto Byte : Bytes)
56 static_cast<DIEValueList *>(Loc)->addValue(
57 Allocator, static_cast<dwarf::Attribute>(0), dwarf::DW_FORM_data1,
58 DIEInteger(Byte));
59 Loc->setSize(Bytes.size());
61 return addAttribute(Attr, AttrForm, Loc);
64 /// Adds specified block or exprloc attribute to the current DIE.
65 std::pair<DIEValue &, size_t> addBlockAttribute(dwarf::Attribute Attr,
66 dwarf::Form AttrForm,
67 ArrayRef<uint8_t> Bytes) {
68 // The expression location data might be updated and exceed the original
69 // size. Check whether the new data fits into the original form.
70 assert((AttrForm == dwarf::DW_FORM_block) ||
71 (AttrForm == dwarf::DW_FORM_exprloc) ||
72 (AttrForm == dwarf::DW_FORM_block1 && Bytes.size() <= UINT8_MAX) ||
73 (AttrForm == dwarf::DW_FORM_block2 && Bytes.size() <= UINT16_MAX) ||
74 (AttrForm == dwarf::DW_FORM_block4 && Bytes.size() <= UINT32_MAX));
76 DIEBlock *Block = new (Allocator) DIEBlock;
77 for (auto Byte : Bytes)
78 static_cast<DIEValueList *>(Block)->addValue(
79 Allocator, static_cast<dwarf::Attribute>(0), dwarf::DW_FORM_data1,
80 DIEInteger(Byte));
81 Block->setSize(Bytes.size());
83 return addAttribute(Attr, AttrForm, Block);
86 /// Adds specified location list attribute to the current DIE.
87 std::pair<DIEValue &, size_t> addLocListAttribute(dwarf::Attribute Attr,
88 dwarf::Form AttrForm,
89 uint64_t Value) {
90 return addAttribute(Attr, AttrForm, DIELocList(Value));
93 /// Adds indexed string attribute.
94 std::pair<DIEValue &, size_t> addIndexedStringAttribute(dwarf::Attribute Attr,
95 dwarf::Form AttrForm,
96 uint64_t Idx) {
97 assert(AttrForm == dwarf::DW_FORM_strx);
98 return addAttribute(Attr, AttrForm, DIEInteger(Idx));
101 /// Adds string attribute with dummy offset to the current DIE.
102 std::pair<DIEValue &, size_t>
103 addStringPlaceholderAttribute(dwarf::Attribute Attr, dwarf::Form AttrForm) {
104 assert(AttrForm == dwarf::DW_FORM_strp ||
105 AttrForm == dwarf::DW_FORM_line_strp);
106 return addAttribute(Attr, AttrForm, DIEInteger(0xBADDEF));
109 /// Adds inplace string attribute to the current DIE.
110 std::pair<DIEValue &, size_t> addInplaceString(dwarf::Attribute Attr,
111 StringRef String) {
112 DIEBlock *Block = new (Allocator) DIEBlock;
113 for (auto Byte : String.bytes())
114 static_cast<DIEValueList *>(Block)->addValue(
115 Allocator, static_cast<dwarf::Attribute>(0), dwarf::DW_FORM_data1,
116 DIEInteger(Byte));
118 static_cast<DIEValueList *>(Block)->addValue(
119 Allocator, static_cast<dwarf::Attribute>(0), dwarf::DW_FORM_data1,
120 DIEInteger(0));
121 Block->setSize(String.size() + 1);
123 DIEValue &ValueRef =
124 *OutputDIE->addValue(Allocator, Attr, dwarf::DW_FORM_string, Block);
125 return std::pair<DIEValue &, size_t>(ValueRef, String.size() + 1);
128 /// Creates appreviations for the current DIE. Returns value of
129 /// abbreviation number.
130 size_t finalizeAbbreviations(bool CHILDREN_yes) {
131 // Create abbreviations for output DIE.
132 DIEAbbrev NewAbbrev = OutputDIE->generateAbbrev();
133 if (CHILDREN_yes)
134 NewAbbrev.setChildrenFlag(dwarf::DW_CHILDREN_yes);
136 CU.assignAbbrev(NewAbbrev);
137 OutputDIE->setAbbrevNumber(NewAbbrev.getNumber());
139 return getULEB128Size(OutputDIE->getAbbrevNumber());
142 protected:
143 template <typename T>
144 std::pair<DIEValue &, size_t> addAttribute(dwarf::Attribute Attr,
145 dwarf::Form AttrForm, T &&Value) {
146 DIEValue &ValueRef =
147 *OutputDIE->addValue(Allocator, Attr, AttrForm, std::forward<T>(Value));
148 unsigned ValueSize = ValueRef.sizeOf(CU.getFormParams());
149 return std::pair<DIEValue &, size_t>(ValueRef, ValueSize);
152 // Allocator for output DIEs and values.
153 BumpPtrAllocator &Allocator;
155 // Unit for the output DIE.
156 DwarfUnit &CU;
158 // OutputDIE.
159 DIE *OutputDIE = nullptr;
162 } // end of namespace dwarflinker_parallel
163 } // end namespace llvm
165 #endif // LLVM_LIB_DWARFLINKERPARALLEL_DIEGENERATOR_H