@@ -130,11 +130,28 @@ void LiveElementPrinter::addInlinedFunction(DWARFDie FuncDie,
130130 // Map the element's high address (HighPC) to its pointer for fast range end
131131 // lookup.
132132 LiveElementsByEndAddress[FuncHighPC].push_back (LiveElements.back ().get ());
133- // Map the pointer to its DWARF discovery index (ElementIdx) for deterministic
133+ // Map the pointer to its DWARF discovery index for deterministic
134134 // ordering.
135135 ElementPtrToIndex[LiveElements.back ().get ()] = LiveElements.size () - 1 ;
136136}
137137
138+ // / Registers the most recently added LiveVariable into all data structures.
139+ void LiveElementPrinter::registerNewVariable () {
140+ assert (
141+ !LiveElements.empty () &&
142+ " registerNewVariable called before element was added to LiveElements." );
143+ LiveVariable *CurrentVar =
144+ static_cast <LiveVariable *>(LiveElements.back ().get ());
145+ // Map from a LiveElement pointer to its index in the LiveElements.
146+ ElementPtrToIndex[CurrentVar] = LiveElements.size () - 1 ;
147+
148+ if (const auto &Range = CurrentVar->getLocExpr ().Range ) {
149+ // Add the variable to address-based maps.
150+ LiveElementsByAddress[Range->LowPC ].push_back (CurrentVar);
151+ LiveElementsByEndAddress[Range->HighPC ].push_back (CurrentVar);
152+ }
153+ }
154+
138155void LiveElementPrinter::addVariable (DWARFDie FuncDie, DWARFDie VarDie) {
139156 uint64_t FuncLowPC, FuncHighPC, SectionIndex;
140157 FuncDie.getLowAndHighPC (FuncLowPC, FuncHighPC, SectionIndex);
@@ -154,33 +171,21 @@ void LiveElementPrinter::addVariable(DWARFDie FuncDie, DWARFDie VarDie) {
154171 for (const DWARFLocationExpression &LocExpr : *Locs) {
155172 std::unique_ptr<LiveVariable> NewVar;
156173 if (LocExpr.Range ) {
157- NewVar = std::make_unique<LiveVariable>(LocExpr, VarName, U, FuncDie);
174+ LiveElements.emplace_back (
175+ std::make_unique<LiveVariable>(LocExpr, VarName, U, FuncDie));
158176 } else {
159177 // If the LocExpr does not have an associated range, it is valid for
160178 // the whole of the function.
161179 // TODO: technically it is not valid for any range covered by another
162180 // LocExpr, does that happen in reality?
163181 DWARFLocationExpression WholeFuncExpr{
164182 DWARFAddressRange (FuncLowPC, FuncHighPC, SectionIndex), LocExpr.Expr };
165- NewVar =
166- std::make_unique<LiveVariable>(WholeFuncExpr, VarName, U, FuncDie);
183+ LiveElements. emplace_back (
184+ std::make_unique<LiveVariable>(WholeFuncExpr, VarName, U, FuncDie)) ;
167185 }
168186
169- // Add the new variable to all the data structures.
170- if (NewVar) {
171- LiveElements.emplace_back (std::move (NewVar));
172- LiveVariable *CurrentVar =
173- static_cast <LiveVariable *>(LiveElements.back ().get ());
174- // Map from a LiveElement pointer to its index in the LiveElements vector.
175- ElementPtrToIndex.emplace (CurrentVar, LiveElements.size () - 1 );
176- if (CurrentVar->getLocExpr ().Range ) {
177- // Add the variable to address-based maps.
178- LiveElementsByAddress[CurrentVar->getLocExpr ().Range ->LowPC ].push_back (
179- CurrentVar);
180- LiveElementsByEndAddress[CurrentVar->getLocExpr ().Range ->HighPC ]
181- .push_back (CurrentVar);
182- }
183- }
187+ // Register the new variable to all data structures.
188+ registerNewVariable ();
184189 }
185190}
186191
@@ -229,9 +234,8 @@ unsigned LiveElementPrinter::moveToFirstVarColumn(formatted_raw_ostream &OS) {
229234unsigned LiveElementPrinter::getOrCreateColumn (unsigned ElementIdx) {
230235 // Check if the element already has an assigned column.
231236 auto it = ElementToColumn.find (ElementIdx);
232- if (it != ElementToColumn.end ()) {
237+ if (it != ElementToColumn.end ())
233238 return it->second ;
234- }
235239
236240 unsigned ColIdx;
237241 if (!FreeCols.empty ()) {
@@ -268,12 +272,12 @@ void LiveElementPrinter::freeColumn(unsigned ColIdx) {
268272
269273std::vector<unsigned >
270274LiveElementPrinter::getSortedActiveElementIndices () const {
271- // Get all ElementIdx values that currently have an assigned column.
275+ // Get all element indexes that currently have an assigned column.
272276 std::vector<unsigned > Indices;
273277 for (const auto &Pair : ElementToColumn)
274278 Indices.push_back (Pair.first );
275279
276- // Sort by ElementIdx, which is the DWARF discovery order.
280+ // Sort by the DWARF discovery order.
277281 llvm::stable_sort (Indices);
278282 return Indices;
279283}
@@ -350,16 +354,12 @@ void LiveElementPrinter::update(object::SectionedAddress ThisAddr,
350354 return ;
351355
352356 const std::vector<LiveElement *> &ElementList = It->second ;
353- // Get the ElementIdx for sorting and column management.
354357 for (LiveElement *LE : ElementList) {
355358 auto IndexIt = ElementPtrToIndex.find (LE);
356- if (IndexIt == ElementPtrToIndex.end ()) {
357- LLVM_DEBUG (
358- dbgs ()
359- << " Error: LiveElement in map but not in ElementPtrToIndex!\n " );
360- continue ;
361- }
359+ assert (IndexIt != ElementPtrToIndex.end () &&
360+ " LiveElement in address map but missing from index map!" );
362361
362+ // Get the element index for sorting and column management.
363363 unsigned ElementIdx = IndexIt->second ;
364364 // Skip elements that already have a column.
365365 if (ElementToColumn.count (ElementIdx))
@@ -379,8 +379,8 @@ void LiveElementPrinter::update(object::SectionedAddress ThisAddr,
379379 // Collect elements starting at NextAddr (the address immediately
380380 // following the instruction).
381381 CollectNewElements (LiveElementsByAddress.find (NextAddr.Address ));
382- // Sort elements by DWARF discovery order (ElementIdx) for deterministic
383- // column assignment.
382+ // Sort elements by DWARF discovery order for deterministic column
383+ // assignment.
384384 llvm::stable_sort (NewLiveElements, [](const auto &A, const auto &B) {
385385 return A.first < B.first ;
386386 });
@@ -482,10 +482,9 @@ void LiveElementPrinter::printAfterOtherLine(formatted_raw_ostream &OS,
482482void LiveElementPrinter::printBetweenInsts (formatted_raw_ostream &OS,
483483 bool MustPrint) {
484484 bool PrintedSomething = false ;
485- // Get all active elements, sorted by discovery order (ElementIdx) .
485+ // Get all active elements, sorted by discovery order.
486486 std::vector<unsigned > SortedElementIndices = getSortedActiveElementIndices ();
487- // The outer loop iterates over the deterministic DWARF discovery order
488- // (ElementIdx).
487+ // The outer loop iterates over the deterministic DWARF discovery order.
489488 for (unsigned ElementIdx : SortedElementIndices) {
490489 // Look up the physical column index (ColIdx) assigned to this
491490 // element. We use .at() because we are certain the element is active.
@@ -566,51 +565,29 @@ void LiveElementPrinter::printAfterInst(formatted_raw_ostream &OS) {
566565 }
567566}
568567
569- void LiveElementPrinter::printStartLine (formatted_raw_ostream &OS,
570- object::SectionedAddress Addr) {
571- // Only print the start line for inlined functions if DFLimitsOnly is
568+ void LiveElementPrinter::printBoundaryLine (formatted_raw_ostream &OS,
569+ object::SectionedAddress Addr,
570+ bool IsEnd) {
571+ // Only print the start/end line for inlined functions if DFLimitsOnly is
572572 // enabled.
573573 if (DbgInlinedFunctions != DFLimitsOnly)
574574 return ;
575575
576- // Use the map to find all elements that start at the given address.
577- std::vector<unsigned > ElementIndices;
578- auto It = LiveElementsByAddress.find (Addr.Address );
579- if (It != LiveElementsByAddress.end ()) {
580- for (LiveElement *LE : It->second ) {
581- // Look up the ElementIdx from the pointer.
582- auto IndexIt = ElementPtrToIndex.find (LE);
583- if (IndexIt != ElementPtrToIndex.end ())
584- ElementIndices.push_back (IndexIt->second );
585- }
586- }
587-
588- // Sort the indices to ensure deterministic output order (by DWARF discovery
589- // order).
590- llvm::stable_sort (ElementIndices);
591-
592- for (unsigned ElementIdx : ElementIndices) {
593- LiveElement *LE = LiveElements[ElementIdx].get ();
594- LE->printElementLine (OS, Addr, false );
595- }
596- }
597-
598- void LiveElementPrinter::printEndLine (formatted_raw_ostream &OS,
599- object::SectionedAddress Addr) {
600- // Only print the end line for inlined functions if DFLimitsOnly is
601- // enabled.
602- if (DbgInlinedFunctions != DFLimitsOnly)
603- return ;
576+ // Select the appropriate map based on whether we are checking the start
577+ // (LowPC) or end (HighPC) address.
578+ const auto &AddressMap =
579+ IsEnd ? LiveElementsByEndAddress : LiveElementsByAddress;
604580
605- // Use the map to find elements that end at the given address.
581+ // Use the map to find all elements that start/ end at the given address.
606582 std::vector<unsigned > ElementIndices;
607- auto It = LiveElementsByEndAddress .find (Addr.Address );
608- if (It != LiveElementsByEndAddress .end ()) {
583+ auto It = AddressMap .find (Addr.Address );
584+ if (It != AddressMap .end ()) {
609585 for (LiveElement *LE : It->second ) {
610- // Look up the ElementIdx from the pointer.
586+ // Look up the element index from the pointer.
611587 auto IndexIt = ElementPtrToIndex.find (LE);
612- if (IndexIt != ElementPtrToIndex.end ())
613- ElementIndices.push_back (IndexIt->second );
588+ assert (IndexIt != ElementPtrToIndex.end () &&
589+ " LiveElement found in address map but missing index!" );
590+ ElementIndices.push_back (IndexIt->second );
614591 }
615592 }
616593
@@ -620,7 +597,7 @@ void LiveElementPrinter::printEndLine(formatted_raw_ostream &OS,
620597
621598 for (unsigned ElementIdx : ElementIndices) {
622599 LiveElement *LE = LiveElements[ElementIdx].get ();
623- LE->printElementLine (OS, Addr, true );
600+ LE->printElementLine (OS, Addr, IsEnd );
624601 }
625602}
626603
0 commit comments