Skip to content

Commit ddc4935

Browse files
committed
[DebugInfo][RemoveDIs] Don't allocate one DPMarker per instruction (#79345)
This is an optimisation patch that shouldn't have any functional effect. There's no need for all instructions to have a DPMarker attached to them, because not all instructions have adjacent DPValues (aka dbg.values). This patch inserts the appropriate conditionals into functions like BasicBlock::spliceDebugInfo to ensure we don't step on a null pointer when there isn't a DPMarker allocated. Mostly, this is a case of calling createMarker occasionally, which will create a marker on an instruction if there isn't one there already. Also folded into this is the use of adoptDbgValues, which is a natural extension: if we have a sequence of instructions and debug records: %foo = add i32 %0,... # dbg_value { %foo, ... # dbg_value { %bar, ... %baz = add i32 %... %qux = add i32 %... and delete, for example, the %baz instruction, then the dbg_value records would naturally be transferred onto the %qux instruction (they "fall down" onto it). There's no point in creating and splicing DPMarkers in the case shown when %qux doesn't have a DPMarker already, we can instead just change the owner of %baz's DPMarker from %baz to %qux. This also avoids calling setParent on every DPValue. Update LoopRotationUtils: it was relying on each instruction having it's own distinct end(), so that we could express ranges and lack-of-ranges. That's no longer true though: so switch to storing the range of DPValues on the next instruction when we want to consider it's range next time around the loop (see the nearby comment).
1 parent 026f3c1 commit ddc4935

File tree

7 files changed

+121
-60
lines changed

7 files changed

+121
-60
lines changed

llvm/include/llvm/IR/Instruction.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,12 @@ class Instruction : public User,
9090
/// Returns true if any DPValues are attached to this instruction.
9191
bool hasDbgValues() const;
9292

93+
/// Transfer any DPValues on the position \p It onto this instruction,
94+
/// by simply adopting the sequence of DPValues (which is efficient) if
95+
/// possible, by merging two sequences otherwise.
96+
void adoptDbgValues(BasicBlock *BB, InstListType::iterator It,
97+
bool InsertAtHead);
98+
9399
/// Erase any DPValues attached to this instruction.
94100
void dropDbgValues();
95101

llvm/lib/IR/BasicBlock.cpp

Lines changed: 32 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -81,8 +81,10 @@ void BasicBlock::convertToNewDbgValues() {
8181
continue;
8282
}
8383

84-
// Create a marker to store DPValues in. Technically we don't need to store
85-
// one marker per instruction, but that's a future optimisation.
84+
if (DPVals.empty())
85+
continue;
86+
87+
// Create a marker to store DPValues in.
8688
createMarker(&I);
8789
DPMarker *Marker = I.DbgMarker;
8890

@@ -769,6 +771,7 @@ void BasicBlock::flushTerminatorDbgValues() {
769771
return;
770772

771773
// Transfer DPValues from the trailing position onto the terminator.
774+
createMarker(Term);
772775
Term->DbgMarker->absorbDebugValues(*TrailingDPValues, false);
773776
TrailingDPValues->eraseFromParent();
774777
deleteTrailingDPValues();
@@ -812,10 +815,9 @@ void BasicBlock::spliceDebugInfoEmptyBlock(BasicBlock::iterator Dest,
812815
if (!SrcTrailingDPValues)
813816
return;
814817

815-
DPMarker *M = Dest->DbgMarker;
816-
M->absorbDebugValues(*SrcTrailingDPValues, InsertAtHead);
817-
SrcTrailingDPValues->eraseFromParent();
818-
Src->deleteTrailingDPValues();
818+
Dest->adoptDbgValues(Src, Src->end(), InsertAtHead);
819+
// adoptDbgValues should have released the trailing DPValues.
820+
assert(!Src->getTrailingDPValues());
819821
return;
820822
}
821823

@@ -882,16 +884,14 @@ void BasicBlock::spliceDebugInfo(BasicBlock::iterator Dest, BasicBlock *Src,
882884
}
883885

884886
if (First->hasDbgValues()) {
885-
DPMarker *CurMarker = Src->getMarker(First);
886887
// Place them at the front, it would look like this:
887888
// Dest
888889
// |
889890
// this-block:
890891
// Src-block: ~~~~~~~~++++B---B---B---B:::C
891892
// | |
892893
// First Last
893-
CurMarker->absorbDebugValues(*OurTrailingDPValues, true);
894-
OurTrailingDPValues->eraseFromParent();
894+
First->adoptDbgValues(this, end(), true);
895895
} else {
896896
// No current marker, create one and absorb in. (FIXME: we can avoid an
897897
// allocation in the future).
@@ -911,7 +911,8 @@ void BasicBlock::spliceDebugInfo(BasicBlock::iterator Dest, BasicBlock *Src,
911911
if (!MoreDanglingDPValues)
912912
return;
913913

914-
// FIXME: we could avoid an allocation here sometimes.
914+
// FIXME: we could avoid an allocation here sometimes. (adoptDbgValues
915+
// requires an iterator).
915916
DPMarker *LastMarker = Src->createMarker(Last);
916917
LastMarker->absorbDebugValues(*MoreDanglingDPValues, true);
917918
MoreDanglingDPValues->eraseFromParent();
@@ -993,44 +994,50 @@ void BasicBlock::spliceDebugInfoImpl(BasicBlock::iterator Dest, BasicBlock *Src,
993994
// Detach the marker at Dest -- this lets us move the "====" DPValues around.
994995
DPMarker *DestMarker = nullptr;
995996
if (Dest != end()) {
996-
DestMarker = getMarker(Dest);
997-
DestMarker->removeFromParent();
998-
createMarker(&*Dest);
997+
if ((DestMarker = getMarker(Dest)))
998+
DestMarker->removeFromParent();
999999
}
10001000

10011001
// If we're moving the tail range of DPValues (":::"), absorb them into the
10021002
// front of the DPValues at Dest.
10031003
if (ReadFromTail && Src->getMarker(Last)) {
1004-
DPMarker *OntoDest = getMarker(Dest);
10051004
DPMarker *FromLast = Src->getMarker(Last);
1006-
OntoDest->absorbDebugValues(*FromLast, true);
10071005
if (LastIsEnd) {
1008-
FromLast->eraseFromParent();
1009-
Src->deleteTrailingDPValues();
1006+
Dest->adoptDbgValues(Src, Last, true);
1007+
// adoptDbgValues will release any trailers.
1008+
assert(!Src->getTrailingDPValues());
1009+
} else {
1010+
// FIXME: can we use adoptDbgValues here to reduce allocations?
1011+
DPMarker *OntoDest = createMarker(Dest);
1012+
OntoDest->absorbDebugValues(*FromLast, true);
10101013
}
10111014
}
10121015

10131016
// If we're _not_ reading from the head of First, i.e. the "++++" DPValues,
10141017
// move their markers onto Last. They remain in the Src block. No action
10151018
// needed.
10161019
if (!ReadFromHead && First->hasDbgValues()) {
1017-
DPMarker *OntoLast = Src->createMarker(Last);
1018-
DPMarker *FromFirst = Src->createMarker(First);
1019-
OntoLast->absorbDebugValues(*FromFirst,
1020-
true); // Always insert at head of it.
1020+
if (Last != Src->end()) {
1021+
Last->adoptDbgValues(Src, First, true);
1022+
} else {
1023+
DPMarker *OntoLast = Src->createMarker(Last);
1024+
DPMarker *FromFirst = Src->createMarker(First);
1025+
// Always insert at front of Last.
1026+
OntoLast->absorbDebugValues(*FromFirst, true);
1027+
}
10211028
}
10221029

10231030
// Finally, do something with the "====" DPValues we detached.
10241031
if (DestMarker) {
10251032
if (InsertAtHead) {
10261033
// Insert them at the end of the DPValues at Dest. The "::::" DPValues
10271034
// might be in front of them.
1028-
DPMarker *NewDestMarker = getMarker(Dest);
1035+
DPMarker *NewDestMarker = createMarker(Dest);
10291036
NewDestMarker->absorbDebugValues(*DestMarker, false);
10301037
} else {
10311038
// Insert them right at the start of the range we moved, ahead of First
10321039
// and the "++++" DPValues.
1033-
DPMarker *FirstMarker = getMarker(First);
1040+
DPMarker *FirstMarker = createMarker(First);
10341041
FirstMarker->absorbDebugValues(*DestMarker, true);
10351042
}
10361043
DestMarker->eraseFromParent();
@@ -1082,9 +1089,7 @@ void BasicBlock::insertDPValueAfter(DPValue *DPV, Instruction *I) {
10821089
assert(I->getParent() == this);
10831090

10841091
iterator NextIt = std::next(I->getIterator());
1085-
DPMarker *NextMarker = getMarker(NextIt);
1086-
if (!NextMarker)
1087-
NextMarker = createMarker(NextIt);
1092+
DPMarker *NextMarker = createMarker(NextIt);
10881093
NextMarker->insertDPValue(DPV, true);
10891094
}
10901095

@@ -1097,6 +1102,7 @@ void BasicBlock::insertDPValueBefore(DPValue *DPV,
10971102
if (!Where->DbgMarker)
10981103
createMarker(Where);
10991104
bool InsertAtHead = Where.getHeadBit();
1105+
createMarker(&*Where);
11001106
Where->DbgMarker->insertDPValue(DPV, InsertAtHead);
11011107
}
11021108

llvm/lib/IR/DebugProgramInstruction.cpp

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -434,13 +434,23 @@ void DPMarker::removeMarker() {
434434
// instruction. If there isn't a next instruction, put them on the
435435
// "trailing" list.
436436
DPMarker *NextMarker = Owner->getParent()->getNextMarker(Owner);
437-
if (NextMarker == nullptr) {
438-
NextMarker = new DPMarker();
439-
Owner->getParent()->setTrailingDPValues(NextMarker);
437+
if (NextMarker) {
438+
NextMarker->absorbDebugValues(*this, true);
439+
eraseFromParent();
440+
} else {
441+
// We can avoid a deallocation -- just store this marker onto the next
442+
// instruction. Unless we're at the end of the block, in which case this
443+
// marker becomes the trailing marker of a degenerate block.
444+
BasicBlock::iterator NextIt = std::next(Owner->getIterator());
445+
if (NextIt == getParent()->end()) {
446+
getParent()->setTrailingDPValues(this);
447+
MarkedInstr = nullptr;
448+
} else {
449+
NextIt->DbgMarker = this;
450+
MarkedInstr = &*NextIt;
451+
}
440452
}
441-
NextMarker->absorbDebugValues(*this, true);
442-
443-
eraseFromParent();
453+
Owner->DbgMarker = nullptr;
444454
}
445455

446456
void DPMarker::removeFromParent() {

llvm/lib/IR/Instruction.cpp

Lines changed: 48 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -111,11 +111,6 @@ void Instruction::insertAfter(Instruction *InsertPos) {
111111
BasicBlock *DestParent = InsertPos->getParent();
112112

113113
DestParent->getInstList().insertAfter(InsertPos->getIterator(), this);
114-
115-
// No need to manually update DPValues: if we insert after an instruction
116-
// position, then we can never have any DPValues on "this".
117-
if (DestParent->IsNewDbgInfoFormat)
118-
DestParent->createMarker(this);
119114
}
120115

121116
BasicBlock::iterator Instruction::insertInto(BasicBlock *ParentBB,
@@ -138,17 +133,15 @@ void Instruction::insertBefore(BasicBlock &BB,
138133
if (!BB.IsNewDbgInfoFormat)
139134
return;
140135

141-
BB.createMarker(this);
142-
143136
// We've inserted "this": if InsertAtHead is set then it comes before any
144137
// DPValues attached to InsertPos. But if it's not set, then any DPValues
145138
// should now come before "this".
146139
bool InsertAtHead = InsertPos.getHeadBit();
147140
if (!InsertAtHead) {
148141
DPMarker *SrcMarker = BB.getMarker(InsertPos);
149-
// If there's no source marker, InsertPos is very likely end().
150-
if (SrcMarker)
151-
DbgMarker->absorbDebugValues(*SrcMarker, false);
142+
if (SrcMarker && !SrcMarker->empty()) {
143+
adoptDbgValues(&BB, InsertPos, false);
144+
}
152145
}
153146

154147
// If we're inserting a terminator, check if we need to flush out
@@ -212,14 +205,13 @@ void Instruction::moveBeforeImpl(BasicBlock &BB, InstListType::iterator I,
212205
BB.getInstList().splice(I, getParent()->getInstList(), getIterator());
213206

214207
if (BB.IsNewDbgInfoFormat && !Preserve) {
215-
if (!DbgMarker)
216-
BB.createMarker(this);
217208
DPMarker *NextMarker = getParent()->getNextMarker(this);
218209

219210
// If we're inserting at point I, and not in front of the DPValues attached
220211
// there, then we should absorb the DPValues attached to I.
221-
if (NextMarker && !InsertAtHead)
222-
DbgMarker->absorbDebugValues(*NextMarker, false);
212+
if (!InsertAtHead && NextMarker && !NextMarker->empty()) {
213+
adoptDbgValues(&BB, I, false);
214+
}
223215
}
224216

225217
if (isTerminator())
@@ -258,6 +250,48 @@ std::optional<DPValue::self_iterator> Instruction::getDbgReinsertionPosition() {
258250

259251
bool Instruction::hasDbgValues() const { return !getDbgValueRange().empty(); }
260252

253+
void Instruction::adoptDbgValues(BasicBlock *BB, BasicBlock::iterator It,
254+
bool InsertAtHead) {
255+
DPMarker *SrcMarker = BB->getMarker(It);
256+
auto ReleaseTrailingDPValues = [BB, It, SrcMarker]() {
257+
if (BB->end() == It) {
258+
SrcMarker->eraseFromParent();
259+
BB->deleteTrailingDPValues();
260+
}
261+
};
262+
263+
if (!SrcMarker || SrcMarker->StoredDPValues.empty()) {
264+
ReleaseTrailingDPValues();
265+
return;
266+
}
267+
268+
// If we have DPMarkers attached to this instruction, we have to honour the
269+
// ordering of DPValues between this and the other marker. Fall back to just
270+
// absorbing from the source.
271+
if (DbgMarker || It == BB->end()) {
272+
// Ensure we _do_ have a marker.
273+
getParent()->createMarker(this);
274+
DbgMarker->absorbDebugValues(*SrcMarker, InsertAtHead);
275+
276+
// Having transferred everything out of SrcMarker, we _could_ clean it up
277+
// and free the marker now. However, that's a lot of heap-accounting for a
278+
// small amount of memory with a good chance of re-use. Leave it for the
279+
// moment. It will be released when the Instruction is freed in the worst
280+
// case.
281+
// However: if we transferred from a trailing marker off the end of the
282+
// block, it's important to not leave the empty marker trailing. It will
283+
// give a misleading impression that some debug records have been left
284+
// trailing.
285+
ReleaseTrailingDPValues();
286+
} else {
287+
// Optimisation: we're transferring all the DPValues from the source marker
288+
// onto this empty location: just adopt the other instructions marker.
289+
DbgMarker = SrcMarker;
290+
DbgMarker->MarkedInstr = this;
291+
It->DbgMarker = nullptr;
292+
}
293+
}
294+
261295
void Instruction::dropDbgValues() {
262296
if (DbgMarker)
263297
DbgMarker->dropDPValues();

llvm/lib/Transforms/Utils/Local.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2044,7 +2044,7 @@ static void insertDPValuesForPHIs(BasicBlock *BB,
20442044
auto InsertionPt = Parent->getFirstInsertionPt();
20452045
assert(InsertionPt != Parent->end() && "Ill-formed basic block");
20462046

2047-
InsertionPt->DbgMarker->insertDPValue(NewDbgII, true);
2047+
Parent->insertDPValueBefore(NewDbgII, InsertionPt);
20482048
}
20492049
}
20502050

llvm/lib/Transforms/Utils/LoopRotationUtils.cpp

Lines changed: 13 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -596,7 +596,10 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) {
596596
// on the next instruction, here labelled xyzzy, before we hoist %foo.
597597
// Later, we only only clone DPValues from that position (xyzzy) onwards,
598598
// which avoids cloning DPValue "blah" multiple times.
599-
std::optional<DPValue::self_iterator> NextDbgInst = std::nullopt;
599+
// (Stored as a range because it gives us a natural way of testing whether
600+
// there were DPValues on the next instruction before we hoisted things).
601+
iterator_range<DPValue::self_iterator> NextDbgInsts =
602+
(I != E) ? I->getDbgValueRange() : DPMarker::getEmptyDPValueRange();
600603

601604
while (I != E) {
602605
Instruction *Inst = &*I++;
@@ -611,9 +614,10 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) {
611614
!Inst->mayWriteToMemory() && !Inst->isTerminator() &&
612615
!isa<DbgInfoIntrinsic>(Inst) && !isa<AllocaInst>(Inst)) {
613616

614-
if (LoopEntryBranch->getParent()->IsNewDbgInfoFormat) {
617+
if (LoopEntryBranch->getParent()->IsNewDbgInfoFormat &&
618+
!NextDbgInsts.empty()) {
615619
auto DbgValueRange =
616-
LoopEntryBranch->cloneDebugInfoFrom(Inst, NextDbgInst);
620+
LoopEntryBranch->cloneDebugInfoFrom(Inst, NextDbgInsts.begin());
617621
RemapDPValueRange(M, DbgValueRange, ValueMap,
618622
RF_NoModuleLevelChanges | RF_IgnoreMissingLocals);
619623
// Erase anything we've seen before.
@@ -622,7 +626,8 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) {
622626
DPV.eraseFromParent();
623627
}
624628

625-
NextDbgInst = I->getDbgValueRange().begin();
629+
NextDbgInsts = I->getDbgValueRange();
630+
626631
Inst->moveBefore(LoopEntryBranch);
627632

628633
++NumInstrsHoisted;
@@ -635,11 +640,12 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) {
635640

636641
++NumInstrsDuplicated;
637642

638-
if (LoopEntryBranch->getParent()->IsNewDbgInfoFormat) {
639-
auto Range = C->cloneDebugInfoFrom(Inst, NextDbgInst);
643+
if (LoopEntryBranch->getParent()->IsNewDbgInfoFormat &&
644+
!NextDbgInsts.empty()) {
645+
auto Range = C->cloneDebugInfoFrom(Inst, NextDbgInsts.begin());
640646
RemapDPValueRange(M, Range, ValueMap,
641647
RF_NoModuleLevelChanges | RF_IgnoreMissingLocals);
642-
NextDbgInst = std::nullopt;
648+
NextDbgInsts = DPMarker::getEmptyDPValueRange();
643649
// Erase anything we've seen before.
644650
for (DPValue &DPV : make_early_inc_range(Range))
645651
if (DbgIntrinsics.count(makeHash(&DPV)))

llvm/unittests/IR/BasicBlockDbgInfoTest.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -225,10 +225,9 @@ TEST(BasicBlockDbgInfoTest, MarkerOperations) {
225225
// then they would sit "above" the new instruction.
226226
Instr1->insertBefore(BB, BB.end());
227227
EXPECT_EQ(Instr1->DbgMarker->StoredDPValues.size(), 2u);
228-
// However we won't de-allocate the trailing marker until a terminator is
229-
// inserted.
230-
EXPECT_EQ(EndMarker->StoredDPValues.size(), 0u);
231-
EXPECT_EQ(BB.getTrailingDPValues(), EndMarker);
228+
// We should de-allocate the trailing marker when something is inserted
229+
// at end().
230+
EXPECT_EQ(BB.getTrailingDPValues(), nullptr);
232231

233232
// Remove Instr1: now the DPValues will fall down again,
234233
Instr1->removeFromParent();
@@ -394,12 +393,12 @@ TEST(BasicBlockDbgInfoTest, InstrDbgAccess) {
394393
Instruction *CInst = BInst->getNextNode();
395394
Instruction *DInst = CInst->getNextNode();
396395

397-
ASSERT_TRUE(BInst->DbgMarker);
396+
ASSERT_FALSE(BInst->DbgMarker);
398397
ASSERT_TRUE(CInst->DbgMarker);
399398
ASSERT_EQ(CInst->DbgMarker->StoredDPValues.size(), 1u);
400399
DPValue *DPV1 = &*CInst->DbgMarker->StoredDPValues.begin();
401400
ASSERT_TRUE(DPV1);
402-
EXPECT_EQ(BInst->DbgMarker->StoredDPValues.size(), 0u);
401+
EXPECT_FALSE(BInst->hasDbgValues());
403402

404403
// Clone DPValues from one inst to another. Other arguments to clone are
405404
// tested in DPMarker test.

0 commit comments

Comments
 (0)