@@ -60,6 +60,8 @@ class DIEBuilder {
6060 std::unordered_map<uint64_t , uint32_t > DIEIDMap;
6161 };
6262
63+ enum class ProcessingType { DWARF4TUs, DWARF5TUs, CUs };
64+
6365private:
6466 // / Contains information so that we we can update references in locexpr after
6567 // / we calculated all the final DIE offsets.
@@ -83,41 +85,54 @@ class DIEBuilder {
8385 DWARFAbbreviationDeclaration::AttributeSpec AttrSpec;
8486 };
8587
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;
93105 FoldingSet<DIEAbbrev> AbbreviationsSet;
94106 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;
98111
112+ // / Returns current state of the DIEBuilder
113+ State &getState () { return *BuilderState.get (); }
99114 // / Resolve the reference in DIE, if target is not loaded into IR,
100115 // / pre-allocate it. \p RefCU will be updated to the Unit specific by \p
101116 // / 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 );
106121
107122 // / Resolve the reference in DIE, if target is not loaded into IR,
108123 // / pre-allocate it. \p RefCU will be updated to the Unit specific by \p
109124 // / 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);
113129
114130 // / Clone one attribute according to the format. \return the size of this
115131 // / attribute.
116132 void
117133 cloneAttribute (DIE &Die, const DWARFDie &InputDIE, DWARFUnit &U,
118134 const DWARFFormValue &Val,
119- const DWARFAbbreviationDeclaration::AttributeSpec AttrSpec,
120- const std::vector<DWARFUnit *> &DUOffsetList);
135+ const DWARFAbbreviationDeclaration::AttributeSpec AttrSpec);
121136
122137 // / Clone an attribute in string format.
123138 void cloneStringAttribute (
@@ -129,7 +144,7 @@ class DIEBuilder {
129144 void cloneDieReferenceAttribute (
130145 DIE &Die, const DWARFUnit &U, const DWARFDie &InputDIE,
131146 const DWARFAbbreviationDeclaration::AttributeSpec AttrSpec,
132- const DWARFFormValue &Val, const std::vector<DWARFUnit *> &DUOffsetList );
147+ const DWARFFormValue &Val);
133148
134149 // / Clone an attribute in block format.
135150 void cloneBlockAttribute (
@@ -175,23 +190,23 @@ class DIEBuilder {
175190 // / Update the Offset and Size of DIE.
176191 uint32_t computeDIEOffset (const DWARFUnit &CU, DIE &Die, uint32_t &CurOffset);
177192
178- void registerUnit (DWARFUnit &DU);
193+ void registerUnit (DWARFUnit &DU, bool NeedSort );
179194
180195 // / \return the unique ID of \p U if it exists.
181196 std::optional<uint32_t > getUnitId (const DWARFUnit &DU);
182197
183198 DWARFUnitInfo &getUnitInfo (uint32_t UnitId) {
184- return CloneUnitCtxMap[UnitId];
199+ return getState (). CloneUnitCtxMap [UnitId];
185200 }
186201
187202 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 ();
190205
191206 errs () << " BOLT-WARNING: [internal-dwarf-error]: The DIE is not allocated "
192207 " before looking up, some"
193208 << " unexpected corner cases happened.\n " ;
194- return *CloneUnitCtxMap[UnitId].DieInfoVector .front ().get ();
209+ return *getState (). CloneUnitCtxMap [UnitId].DieInfoVector .front ().get ();
195210 }
196211
197212 std::optional<uint32_t > getAllocDIEId (const DWARFUnit &DU,
@@ -223,16 +238,28 @@ class DIEBuilder {
223238
224239 // / Construct IR for \p DU. \p DUOffsetList specific the Unit in current
225240 // / Section.
226- void constructFromUnit (DWARFUnit &DU, std::vector<DWARFUnit *> &DUOffsetList );
241+ void constructFromUnit (DWARFUnit &DU);
227242
228243 // / Construct a DIE for \p DDie in \p U. \p DUOffsetList specific the Unit in
229244 // / 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);
232246
233247public:
234248 DIEBuilder (DWARFContext *DwarfContext, bool IsDWO = false );
235249
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+
236263 // / Returns DWARFUnitInfo for DWARFUnit
237264 DWARFUnitInfo &getUnitInfoByDwarfUnit (const DWARFUnit &DwarfUnit) {
238265 std::optional<uint32_t > UnitId = getUnitId (DwarfUnit);
@@ -247,16 +274,26 @@ class DIEBuilder {
247274 return Abbreviations;
248275 }
249276 DIE *getTypeDIE (DWARFUnit &DU) {
250- if (TypeDIEMap.count (&DU))
251- return TypeDIEMap[&DU];
277+ if (getState (). TypeDIEMap .count (&DU))
278+ return getState (). TypeDIEMap [&DU];
252279
253280 errs () << " BOLT-ERROR: unable to find TypeUnit for Type Unit at offset 0x"
254281 << DU.getOffset () << " \n " ;
255282 return nullptr ;
256283 }
257284
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 (); }
260297
261298 DIE *getUnitDIEbyUnit (const DWARFUnit &DU) {
262299 const DWARFUnitInfo &U = getUnitInfoByDwarfUnit (DU);
@@ -272,37 +309,40 @@ class DIEBuilder {
272309 void finish ();
273310
274311 // 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+ }
276315
277316 DIEValueList::value_iterator addValue (DIEValueList *Die, const DIEValue &V) {
278- return Die->addValue (DIEAlloc, V);
317+ return Die->addValue (getState (). DIEAlloc , V);
279318 }
280319
281320 template <class T >
282321 DIEValueList::value_iterator addValue (DIEValueList *Die,
283322 dwarf::Attribute Attribute,
284323 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));
286326 }
287327
288328 template <class T >
289329 bool replaceValue (DIEValueList *Die, dwarf::Attribute Attribute,
290330 dwarf::Form Form, T &&NewValue) {
291- return Die->replaceValue (DIEAlloc, Attribute, Form,
331+ return Die->replaceValue (getState (). DIEAlloc , Attribute, Form,
292332 std::forward<T>(NewValue));
293333 }
294334
295335 template <class T >
296336 bool replaceValue (DIEValueList *Die, dwarf::Attribute Attribute,
297337 dwarf::Attribute NewAttribute, dwarf::Form Form,
298338 T &&NewValue) {
299- return Die->replaceValue (DIEAlloc, Attribute, NewAttribute, Form,
339+ return Die->replaceValue (getState (). DIEAlloc , Attribute, NewAttribute, Form,
300340 std::forward<T>(NewValue));
301341 }
302342
303343 bool replaceValue (DIEValueList *Die, dwarf::Attribute Attribute,
304344 dwarf::Form Form, DIEValue &NewValue) {
305- return Die->replaceValue (DIEAlloc, Attribute, Form, NewValue);
345+ return Die->replaceValue (getState (). DIEAlloc , Attribute, Form, NewValue);
306346 }
307347
308348 template <class T >
0 commit comments