@@ -159,7 +159,8 @@ static void RewriteUsesOfClonedInstructions(BasicBlock *OrigHeader,
159
159
// Replace MetadataAsValue(ValueAsMetadata(OrigHeaderVal)) uses in debug
160
160
// intrinsics.
161
161
SmallVector<DbgValueInst *, 1 > DbgValues;
162
- llvm::findDbgValues (DbgValues, OrigHeaderVal);
162
+ SmallVector<DPValue *, 1 > DPValues;
163
+ llvm::findDbgValues (DbgValues, OrigHeaderVal, &DPValues);
163
164
for (auto &DbgValue : DbgValues) {
164
165
// The original users in the OrigHeader are already using the original
165
166
// definitions.
@@ -180,6 +181,29 @@ static void RewriteUsesOfClonedInstructions(BasicBlock *OrigHeader,
180
181
NewVal = UndefValue::get (OrigHeaderVal->getType ());
181
182
DbgValue->replaceVariableLocationOp (OrigHeaderVal, NewVal);
182
183
}
184
+
185
+ // RemoveDIs: duplicate implementation for non-instruction debug-info
186
+ // storage in DPValues.
187
+ for (DPValue *DPV : DPValues) {
188
+ // The original users in the OrigHeader are already using the original
189
+ // definitions.
190
+ BasicBlock *UserBB = DPV->getMarker ()->getParent ();
191
+ if (UserBB == OrigHeader)
192
+ continue ;
193
+
194
+ // Users in the OrigPreHeader need to use the value to which the
195
+ // original definitions are mapped and anything else can be handled by
196
+ // the SSAUpdater. To avoid adding PHINodes, check if the value is
197
+ // available in UserBB, if not substitute undef.
198
+ Value *NewVal;
199
+ if (UserBB == OrigPreheader)
200
+ NewVal = OrigPreHeaderVal;
201
+ else if (SSA.HasValueForBlock (UserBB))
202
+ NewVal = SSA.GetValueInMiddleOfBlock (UserBB);
203
+ else
204
+ NewVal = UndefValue::get (OrigHeaderVal->getType ());
205
+ DPV->replaceVariableLocationOp (OrigHeaderVal, NewVal);
206
+ }
183
207
}
184
208
}
185
209
@@ -531,6 +555,18 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) {
531
555
break ;
532
556
}
533
557
558
+ // Duplicate implementation for DPValues, the non-instruction format of
559
+ // debug-info records in RemoveDIs.
560
+ auto makeHashDPV = [](const DPValue &D) -> DbgIntrinsicHash {
561
+ auto VarLocOps = D.location_ops ();
562
+ return {{hash_combine_range (VarLocOps.begin (), VarLocOps.end ()),
563
+ D.getVariable ()},
564
+ D.getExpression ()};
565
+ };
566
+ for (Instruction &I : llvm::drop_begin (llvm::reverse (*OrigPreheader)))
567
+ for (const DPValue &DPV : I.getDbgValueRange ())
568
+ DbgIntrinsics.insert (makeHashDPV (DPV));
569
+
534
570
// Remember the local noalias scope declarations in the header. After the
535
571
// rotation, they must be duplicated and the scope must be cloned. This
536
572
// avoids unwanted interaction across iterations.
@@ -539,6 +575,29 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) {
539
575
if (auto *Decl = dyn_cast<NoAliasScopeDeclInst>(&I))
540
576
NoAliasDeclInstructions.push_back (Decl);
541
577
578
+ Module *M = OrigHeader->getModule ();
579
+
580
+ // Track the next DPValue to clone. If we have a sequence where an
581
+ // instruction is hoisted instead of being cloned:
582
+ // DPValue blah
583
+ // %foo = add i32 0, 0
584
+ // DPValue xyzzy
585
+ // %bar = call i32 @foobar()
586
+ // where %foo is hoisted, then the DPValue "blah" will be seen twice, once
587
+ // attached to %foo, then when %foo his hoisted it will "fall down" onto the
588
+ // function call:
589
+ // DPValue blah
590
+ // DPValue xyzzy
591
+ // %bar = call i32 @foobar()
592
+ // causing it to appear attached to the call too.
593
+ //
594
+ // To avoid this, cloneDebugInfoFrom takes an optional "start cloning from
595
+ // here" position to account for this behaviour. We point it at any DPValues
596
+ // on the next instruction, here labelled xyzzy, before we hoist %foo.
597
+ // Later, we only only clone DPValues from that position (xyzzy) onwards,
598
+ // which avoids cloning DPValue "blah" multiple times.
599
+ std::optional<DPValue::self_iterator> NextDbgInst = std::nullopt;
600
+
542
601
while (I != E) {
543
602
Instruction *Inst = &*I++;
544
603
@@ -551,7 +610,17 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) {
551
610
if (L->hasLoopInvariantOperands (Inst) && !Inst->mayReadFromMemory () &&
552
611
!Inst->mayWriteToMemory () && !Inst->isTerminator () &&
553
612
!isa<DbgInfoIntrinsic>(Inst) && !isa<AllocaInst>(Inst)) {
613
+
614
+ if (LoopEntryBranch->getParent ()->IsNewDbgInfoFormat ) {
615
+ auto DbgValueRange =
616
+ LoopEntryBranch->cloneDebugInfoFrom (Inst, NextDbgInst);
617
+ RemapDPValueRange (M, DbgValueRange, ValueMap,
618
+ RF_NoModuleLevelChanges | RF_IgnoreMissingLocals);
619
+ }
620
+
621
+ NextDbgInst = I->getDbgValueRange ().begin ();
554
622
Inst->moveBefore (LoopEntryBranch);
623
+
555
624
++NumInstrsHoisted;
556
625
continue ;
557
626
}
@@ -562,6 +631,17 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) {
562
631
563
632
++NumInstrsDuplicated;
564
633
634
+ if (LoopEntryBranch->getParent ()->IsNewDbgInfoFormat ) {
635
+ auto Range = C->cloneDebugInfoFrom (Inst, NextDbgInst);
636
+ // Erase anything we've seen before.
637
+ for (DPValue &DPV : make_early_inc_range (Range))
638
+ if (DbgIntrinsics.count (makeHashDPV (DPV)))
639
+ DPV.eraseFromParent ();
640
+ RemapDPValueRange (M, Range, ValueMap,
641
+ RF_NoModuleLevelChanges | RF_IgnoreMissingLocals);
642
+ NextDbgInst = std::nullopt;
643
+ }
644
+
565
645
// Eagerly remap the operands of the instruction.
566
646
RemapInstruction (C, ValueMap,
567
647
RF_NoModuleLevelChanges | RF_IgnoreMissingLocals);
@@ -676,6 +756,7 @@ bool LoopRotate::rotateLoop(Loop *L, bool SimplifiedLatch) {
676
756
// OrigPreHeader's old terminator (the original branch into the loop), and
677
757
// remove the corresponding incoming values from the PHI nodes in OrigHeader.
678
758
LoopEntryBranch->eraseFromParent ();
759
+ OrigPreheader->flushTerminatorDbgValues ();
679
760
680
761
// Update MemorySSA before the rewrite call below changes the 1:1
681
762
// instruction:cloned_instruction_or_value mapping.
0 commit comments