diff --git a/llvm/lib/Transforms/Utils/LoopUtils.cpp b/llvm/lib/Transforms/Utils/LoopUtils.cpp index 8bb4e17b99dd62..4fb64bdf903591 100644 --- a/llvm/lib/Transforms/Utils/LoopUtils.cpp +++ b/llvm/lib/Transforms/Utils/LoopUtils.cpp @@ -604,6 +604,7 @@ void llvm::deleteDeadLoop(Loop *L, DominatorTree *DT, ScalarEvolution *SE, // Use a map to unique and a vector to guarantee deterministic ordering. llvm::SmallDenseSet DeadDebugSet; llvm::SmallVector DeadDebugInst; + llvm::SmallVector DeadDPValues; if (ExitBlock) { // Given LCSSA form is satisfied, we should not have users of instructions @@ -628,6 +629,24 @@ void llvm::deleteDeadLoop(Loop *L, DominatorTree *DT, ScalarEvolution *SE, "Unexpected user in reachable block"); U.set(Poison); } + + // RemoveDIs: do the same as below for DPValues. + if (Block->IsNewDbgInfoFormat) { + for (DPValue &DPV : + llvm::make_early_inc_range(I.getDbgValueRange())) { + DebugVariable Key(DPV.getVariable(), DPV.getExpression(), + DPV.getDebugLoc().get()); + if (!DeadDebugSet.insert(Key).second) + continue; + // Unlinks the DPV from it's container, for later insertion. + DPV.removeFromParent(); + DeadDPValues.push_back(&DPV); + } + } + + // For one of each variable encountered, preserve a debug intrinsic (set + // to Poison) and transfer it to the loop exit. This terminates any + // variable locations that were set during the loop. auto *DVI = dyn_cast(&I); if (!DVI) continue; @@ -642,12 +661,22 @@ void llvm::deleteDeadLoop(Loop *L, DominatorTree *DT, ScalarEvolution *SE, // be be replaced with undef. Loop invariant values will still be available. // Move dbg.values out the loop so that earlier location ranges are still // terminated and loop invariant assignments are preserved. - Instruction *InsertDbgValueBefore = ExitBlock->getFirstNonPHI(); - assert(InsertDbgValueBefore && + DIBuilder DIB(*ExitBlock->getModule()); + BasicBlock::iterator InsertDbgValueBefore = + ExitBlock->getFirstInsertionPt(); + assert(InsertDbgValueBefore != ExitBlock->end() && "There should be a non-PHI instruction in exit block, else these " "instructions will have no parent."); + for (auto *DVI : DeadDebugInst) - DVI->moveBefore(InsertDbgValueBefore); + DVI->moveBefore(*ExitBlock, InsertDbgValueBefore); + + // Due to the "head" bit in BasicBlock::iterator, we're going to insert + // each DPValue right at the start of the block, wheras dbg.values would be + // repeatedly inserted before the first instruction. To replicate this + // behaviour, do it backwards. + for (DPValue *DPV : llvm::reverse(DeadDPValues)) + ExitBlock->insertDPValueBefore(DPV, InsertDbgValueBefore); } // Remove the block from the reference counting scheme, so that we can diff --git a/llvm/test/Transforms/LoopDeletion/crashbc.ll b/llvm/test/Transforms/LoopDeletion/crashbc.ll index 2ba5e2ca902a19..c01453bbda8171 100644 --- a/llvm/test/Transforms/LoopDeletion/crashbc.ll +++ b/llvm/test/Transforms/LoopDeletion/crashbc.ll @@ -1,5 +1,6 @@ ; Make sure we don't crash when writing bitcode. ; RUN: opt < %s -passes=loop-deletion -o /dev/null +; RUN: opt < %s -passes=loop-deletion -o /dev/null --try-experimental-debuginfo-iterators define void @f() { br label %bb1 diff --git a/llvm/test/Transforms/LoopDeletion/diundef.ll b/llvm/test/Transforms/LoopDeletion/diundef.ll index 14a6e401f9c6f1..7b6178bcc2ae3d 100644 --- a/llvm/test/Transforms/LoopDeletion/diundef.ll +++ b/llvm/test/Transforms/LoopDeletion/diundef.ll @@ -1,4 +1,5 @@ -; RUN: opt %s -passes=loop-deletion -S | FileCheck %s +; RUN: opt %s -passes=loop-deletion -S | FileCheck %s --implicit-check-not=dbg.value +; RUN: opt %s -passes=loop-deletion -S --try-experimental-debuginfo-iterators | FileCheck %s --implicit-check-not=dbg.value target datalayout = "e-m:o-i64:64-f80:128-n8:16:32:64-S128" target triple = "x86_64-apple-macosx10.14.0" @@ -6,6 +7,12 @@ target triple = "x86_64-apple-macosx10.14.0" @a = common local_unnamed_addr global i32 0, align 4, !dbg !0 define i32 @b() local_unnamed_addr !dbg !12 { +; CHECK-LABEL: entry +; CHECK: call void @llvm.dbg.value(metadata i32 0, metadata ![[IVAR:[0-9]+]], +; CHECK-LABEL: for.end: +; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 undef, metadata ![[IVAR]], metadata !DIExpression()), !dbg !17 +; CHECK-NEXT: call void @llvm.dbg.value(metadata i32 undef, metadata ![[JVAR:[0-9]+]], metadata !DIExpression()), !dbg !17 +; CHECK-NEXT: %call = tail call i32 {{.*}} @patatino() entry: call void @llvm.dbg.value(metadata i32 0, metadata !16, metadata !DIExpression()), !dbg !17 br label %for.cond, !dbg !18 @@ -15,11 +22,10 @@ for.cond: ; preds = %for.cond, %entry call void @llvm.dbg.value(metadata i32 %i.0, metadata !16, metadata !DIExpression()), !dbg !17 %inc = add nuw nsw i32 %i.0, 1, !dbg !21 call void @llvm.dbg.value(metadata i32 %inc, metadata !16, metadata !DIExpression()), !dbg !17 + call void @llvm.dbg.value(metadata i32 %inc, metadata !37, metadata !DIExpression()), !dbg !17 %exitcond = icmp ne i32 %inc, 3, !dbg !23 br i1 %exitcond, label %for.cond, label %for.end, !dbg !24, !llvm.loop !25 -; CHECK: call void @llvm.dbg.value(metadata i32 undef, metadata !16, metadata !DIExpression()), !dbg !17 -; CHECK-NEXT: %call = tail call i32 {{.*}} @patatino() for.end: ; preds = %for.cond %call = tail call i32 (...) @patatino() #3, !dbg !27 %0 = load i32, ptr @a, align 4, !dbg !28 @@ -34,6 +40,11 @@ entry: ret i32 0, !dbg !36 } +; CHECK: declare void @llvm.dbg.value(metadata, + +; CHECK: ![[IVAR]] = !DILocalVariable(name: "i", +; CHECK: ![[JVAR]] = !DILocalVariable(name: "j", + declare void @llvm.dbg.value(metadata, metadata, metadata) !llvm.dbg.cu = !{!2} @@ -73,3 +84,4 @@ declare void @llvm.dbg.value(metadata, metadata, metadata) !34 = distinct !DISubprogram(name: "main", scope: !3, file: !3, line: 9, type: !13, scopeLine: 9, flags: DIFlagAllCallsDescribed, spFlags: DISPFlagDefinition | DISPFlagOptimized, unit: !2, retainedNodes: !4) !35 = !DILocation(line: 9, column: 14, scope: !34) !36 = !DILocation(line: 9, column: 19, scope: !34) +!37 = !DILocalVariable(name: "j", scope: !12, file: !3, line: 3, type: !6) diff --git a/llvm/test/Transforms/LoopDeletion/over-defensive-undefing-dbg-values.ll b/llvm/test/Transforms/LoopDeletion/over-defensive-undefing-dbg-values.ll index 8eb1ef8ddd72a0..6f71038a74672c 100644 --- a/llvm/test/Transforms/LoopDeletion/over-defensive-undefing-dbg-values.ll +++ b/llvm/test/Transforms/LoopDeletion/over-defensive-undefing-dbg-values.ll @@ -1,4 +1,5 @@ ; RUN: opt -S %s -passes=loop-deletion | FileCheck %s +; RUN: opt -S %s -passes=loop-deletion --try-experimental-debuginfo-iterators | FileCheck %s ;; static int foo(int Param) __attribute__((always_inline)); ;; static int foo(int Param) { return Param * Param * 2; }