@@ -60,6 +60,8 @@ class DIEBuilder {
60
60
std::unordered_map<uint64_t , uint32_t > DIEIDMap;
61
61
};
62
62
63
+ enum class ProcessingType { DWARF4TUs, DWARF5TUs, CUs };
64
+
63
65
private:
64
66
// / Contains information so that we we can update references in locexpr after
65
67
// / we calculated all the final DIE offsets.
@@ -83,41 +85,54 @@ class DIEBuilder {
83
85
DWARFAbbreviationDeclaration::AttributeSpec AttrSpec;
84
86
};
85
87
86
- // / A map of Units to Unit Index.
87
- std::unordered_map<uint64_t , uint32_t > UnitIDMap;
88
- // / A map of Type Units to Type DIEs.
89
- std::unordered_map<DWARFUnit *, DIE *> TypeDIEMap;
90
- std::vector<DWARFUnit *> DUList;
91
- std::vector<DWARFUnitInfo> CloneUnitCtxMap;
92
- std::vector<std::pair<DIEInfo *, AddrReferenceInfo>> AddrReferences;
88
+ struct State {
89
+ // / A map of Units to Unit Index.
90
+ std::unordered_map<uint64_t , uint32_t > UnitIDMap;
91
+ // / A map of Type Units to Type DIEs.
92
+ std::unordered_map<DWARFUnit *, DIE *> TypeDIEMap;
93
+ std::list<DWARFUnit *> DUList;
94
+ std::vector<DWARFUnitInfo> CloneUnitCtxMap;
95
+ std::vector<std::pair<DIEInfo *, AddrReferenceInfo>> AddrReferences;
96
+ std::vector<DWARFUnit *> DWARF4TUVector;
97
+ std::vector<DWARFUnit *> DWARF5TUVector;
98
+ std::vector<DWARFUnit *> DWARFCUVector;
99
+ std::vector<LocWithReference> LocWithReferencesToProcess;
100
+ BumpPtrAllocator DIEAlloc;
101
+ ProcessingType Type;
102
+ };
103
+
104
+ std::unique_ptr<State> BuilderState;
93
105
FoldingSet<DIEAbbrev> AbbreviationsSet;
94
106
std::vector<std::unique_ptr<DIEAbbrev>> Abbreviations;
95
- std::vector<DWARFUnit *> DWARF4TUVector;
96
- std::vector<LocWithReference> LocWithReferencesToProcess;
97
- BumpPtrAllocator DIEAlloc;
107
+ DWARFContext *DwarfContext{nullptr };
108
+ bool IsDWO{false };
109
+ uint64_t UnitSize{0 };
110
+ llvm::DenseSet<uint64_t > AllProcessed;
98
111
112
+ // / Returns current state of the DIEBuilder
113
+ State &getState () { return *BuilderState.get (); }
99
114
// / Resolve the reference in DIE, if target is not loaded into IR,
100
115
// / pre-allocate it. \p RefCU will be updated to the Unit specific by \p
101
116
// / RefValue.
102
- DWARFDie resolveDIEReference (const DWARFFormValue &RefValue,
103
- DWARFUnit *&RefCU ,
104
- DWARFDebugInfoEntry &DwarfDebugInfoEntry ,
105
- const std::vector< DWARFUnit *> &DUOffsetList );
117
+ DWARFDie resolveDIEReference (
118
+ const DWARFFormValue &RefValue ,
119
+ const DWARFAbbreviationDeclaration::AttributeSpec AttrSpec ,
120
+ DWARFUnit *&RefCU, DWARFDebugInfoEntry &DwarfDebugInfoEntry );
106
121
107
122
// / Resolve the reference in DIE, if target is not loaded into IR,
108
123
// / pre-allocate it. \p RefCU will be updated to the Unit specific by \p
109
124
// / RefValue.
110
- DWARFDie resolveDIEReference (const uint64_t ReffOffset, DWARFUnit *&RefCU,
111
- DWARFDebugInfoEntry &DwarfDebugInfoEntry,
112
- const std::vector<DWARFUnit *> &DUOffsetList);
125
+ DWARFDie resolveDIEReference (
126
+ const DWARFAbbreviationDeclaration::AttributeSpec AttrSpec,
127
+ const uint64_t ReffOffset, DWARFUnit *&RefCU,
128
+ DWARFDebugInfoEntry &DwarfDebugInfoEntry);
113
129
114
130
// / Clone one attribute according to the format. \return the size of this
115
131
// / attribute.
116
132
void
117
133
cloneAttribute (DIE &Die, const DWARFDie &InputDIE, DWARFUnit &U,
118
134
const DWARFFormValue &Val,
119
- const DWARFAbbreviationDeclaration::AttributeSpec AttrSpec,
120
- const std::vector<DWARFUnit *> &DUOffsetList);
135
+ const DWARFAbbreviationDeclaration::AttributeSpec AttrSpec);
121
136
122
137
// / Clone an attribute in string format.
123
138
void cloneStringAttribute (
@@ -129,7 +144,7 @@ class DIEBuilder {
129
144
void cloneDieReferenceAttribute (
130
145
DIE &Die, const DWARFUnit &U, const DWARFDie &InputDIE,
131
146
const DWARFAbbreviationDeclaration::AttributeSpec AttrSpec,
132
- const DWARFFormValue &Val, const std::vector<DWARFUnit *> &DUOffsetList );
147
+ const DWARFFormValue &Val);
133
148
134
149
// / Clone an attribute in block format.
135
150
void cloneBlockAttribute (
@@ -175,23 +190,23 @@ class DIEBuilder {
175
190
// / Update the Offset and Size of DIE.
176
191
uint32_t computeDIEOffset (const DWARFUnit &CU, DIE &Die, uint32_t &CurOffset);
177
192
178
- void registerUnit (DWARFUnit &DU);
193
+ void registerUnit (DWARFUnit &DU, bool NeedSort );
179
194
180
195
// / \return the unique ID of \p U if it exists.
181
196
std::optional<uint32_t > getUnitId (const DWARFUnit &DU);
182
197
183
198
DWARFUnitInfo &getUnitInfo (uint32_t UnitId) {
184
- return CloneUnitCtxMap[UnitId];
199
+ return getState (). CloneUnitCtxMap [UnitId];
185
200
}
186
201
187
202
DIEInfo &getDIEInfo (uint32_t UnitId, uint32_t DIEId) {
188
- if (CloneUnitCtxMap[UnitId].DieInfoVector .size () > DIEId)
189
- return *CloneUnitCtxMap[UnitId].DieInfoVector [DIEId].get ();
203
+ if (getState (). CloneUnitCtxMap [UnitId].DieInfoVector .size () > DIEId)
204
+ return *getState (). CloneUnitCtxMap [UnitId].DieInfoVector [DIEId].get ();
190
205
191
206
errs () << " BOLT-WARNING: [internal-dwarf-error]: The DIE is not allocated "
192
207
" before looking up, some"
193
208
<< " unexpected corner cases happened.\n " ;
194
- return *CloneUnitCtxMap[UnitId].DieInfoVector .front ().get ();
209
+ return *getState (). CloneUnitCtxMap [UnitId].DieInfoVector .front ().get ();
195
210
}
196
211
197
212
std::optional<uint32_t > getAllocDIEId (const DWARFUnit &DU,
@@ -223,16 +238,28 @@ class DIEBuilder {
223
238
224
239
// / Construct IR for \p DU. \p DUOffsetList specific the Unit in current
225
240
// / Section.
226
- void constructFromUnit (DWARFUnit &DU, std::vector<DWARFUnit *> &DUOffsetList );
241
+ void constructFromUnit (DWARFUnit &DU);
227
242
228
243
// / Construct a DIE for \p DDie in \p U. \p DUOffsetList specific the Unit in
229
244
// / current Section.
230
- DIE *constructDIEFast (DWARFDie &DDie, DWARFUnit &U, uint32_t UnitId,
231
- std::vector<DWARFUnit *> &DUOffsetList);
245
+ DIE *constructDIEFast (DWARFDie &DDie, DWARFUnit &U, uint32_t UnitId);
232
246
233
247
public:
234
248
DIEBuilder (DWARFContext *DwarfContext, bool IsDWO = false );
235
249
250
+ // / Returns enum to what we are currently processing.
251
+ ProcessingType getCurrentProcessingState () { return getState ().Type ; }
252
+
253
+ // / Constructs IR for Type Units.
254
+ void buildTypeUnits (const bool Init = true );
255
+ // / Constructs IR for all the CUs.
256
+ void buildCompileUnits (const bool Init = true );
257
+ // / Constructs IR for CUs in a vector.
258
+ void buildCompileUnits (const std::vector<DWARFUnit *> &CUs);
259
+ // / Preventing implicit conversions.
260
+ template <class T > void buildCompileUnits (T) = delete;
261
+ void buildBoth ();
262
+
236
263
// / Returns DWARFUnitInfo for DWARFUnit
237
264
DWARFUnitInfo &getUnitInfoByDwarfUnit (const DWARFUnit &DwarfUnit) {
238
265
std::optional<uint32_t > UnitId = getUnitId (DwarfUnit);
@@ -247,16 +274,26 @@ class DIEBuilder {
247
274
return Abbreviations;
248
275
}
249
276
DIE *getTypeDIE (DWARFUnit &DU) {
250
- if (TypeDIEMap.count (&DU))
251
- return TypeDIEMap[&DU];
277
+ if (getState (). TypeDIEMap .count (&DU))
278
+ return getState (). TypeDIEMap [&DU];
252
279
253
280
errs () << " BOLT-ERROR: unable to find TypeUnit for Type Unit at offset 0x"
254
281
<< DU.getOffset () << " \n " ;
255
282
return nullptr ;
256
283
}
257
284
258
- std::vector<DWARFUnit *> getDWARF4TUVector () { return DWARF4TUVector; }
259
- bool isEmpty () { return CloneUnitCtxMap.empty (); }
285
+ std::vector<DWARFUnit *> &getDWARF4TUVector () {
286
+ return getState ().DWARF4TUVector ;
287
+ }
288
+ std::vector<DWARFUnit *> &getDWARF5TUVector () {
289
+ return getState ().DWARF5TUVector ;
290
+ }
291
+ std::vector<DWARFUnit *> &getDWARFCUVector () {
292
+ return getState ().DWARFCUVector ;
293
+ }
294
+ // / Returns list of CUs for which IR was build.
295
+ std::list<DWARFUnit *> &getProcessedCUs () { return getState ().DUList ; }
296
+ bool isEmpty () { return getState ().CloneUnitCtxMap .empty (); }
260
297
261
298
DIE *getUnitDIEbyUnit (const DWARFUnit &DU) {
262
299
const DWARFUnitInfo &U = getUnitInfoByDwarfUnit (DU);
@@ -272,37 +309,40 @@ class DIEBuilder {
272
309
void finish ();
273
310
274
311
// Interface to edit DIE
275
- template <class T > T *allocateDIEValue () { return new (DIEAlloc) T; }
312
+ template <class T > T *allocateDIEValue () {
313
+ return new (getState ().DIEAlloc ) T;
314
+ }
276
315
277
316
DIEValueList::value_iterator addValue (DIEValueList *Die, const DIEValue &V) {
278
- return Die->addValue (DIEAlloc, V);
317
+ return Die->addValue (getState (). DIEAlloc , V);
279
318
}
280
319
281
320
template <class T >
282
321
DIEValueList::value_iterator addValue (DIEValueList *Die,
283
322
dwarf::Attribute Attribute,
284
323
dwarf::Form Form, T &&Value) {
285
- return Die->addValue (DIEAlloc, Attribute, Form, std::forward<T>(Value));
324
+ return Die->addValue (getState ().DIEAlloc , Attribute, Form,
325
+ std::forward<T>(Value));
286
326
}
287
327
288
328
template <class T >
289
329
bool replaceValue (DIEValueList *Die, dwarf::Attribute Attribute,
290
330
dwarf::Form Form, T &&NewValue) {
291
- return Die->replaceValue (DIEAlloc, Attribute, Form,
331
+ return Die->replaceValue (getState (). DIEAlloc , Attribute, Form,
292
332
std::forward<T>(NewValue));
293
333
}
294
334
295
335
template <class T >
296
336
bool replaceValue (DIEValueList *Die, dwarf::Attribute Attribute,
297
337
dwarf::Attribute NewAttribute, dwarf::Form Form,
298
338
T &&NewValue) {
299
- return Die->replaceValue (DIEAlloc, Attribute, NewAttribute, Form,
339
+ return Die->replaceValue (getState (). DIEAlloc , Attribute, NewAttribute, Form,
300
340
std::forward<T>(NewValue));
301
341
}
302
342
303
343
bool replaceValue (DIEValueList *Die, dwarf::Attribute Attribute,
304
344
dwarf::Form Form, DIEValue &NewValue) {
305
- return Die->replaceValue (DIEAlloc, Attribute, Form, NewValue);
345
+ return Die->replaceValue (getState (). DIEAlloc , Attribute, Form, NewValue);
306
346
}
307
347
308
348
template <class T >
0 commit comments