[DebugInfo] Make debug intrinsics to track cloned values in JumpThreading

This patch causes debug value intrinsics outside of cloned blocks in the
Jump Threading pass to correctly point towards any derived values. If it cannot,
it kills them.

Reviewed By: probinson, StephenTozer

Differential Revision: https://reviews.llvm.org/D140404
This commit is contained in:
Ben Mudd
2023-01-23 13:59:41 +00:00
committed by Stephen Tozer
parent 0ece2050da
commit e0374fb2f4
4 changed files with 99 additions and 3 deletions

View File

@@ -28,6 +28,7 @@ template <typename T> class SSAUpdaterTraits;
class Type;
class Use;
class Value;
class DbgValueInst;
/// Helper class for SSA formation on a set of values defined in
/// multiple blocks.
@@ -114,6 +115,15 @@ public:
/// be below it.
void RewriteUse(Use &U);
/// Rewrite debug value intrinsics to conform to a new SSA form.
///
/// This will scout out all the debug value instrinsics associated with
/// the instruction. Anything outside of its block will have its
/// value set to the new SSA value if available, and undef if not.
void UpdateDebugValues(Instruction *I);
void UpdateDebugValues(Instruction *I,
SmallVectorImpl<DbgValueInst *> &DbgValues);
/// Rewrite a use like \c RewriteUse but handling in-block definitions.
///
/// This version of the method can rewrite uses in the same block as
@@ -123,6 +133,7 @@ public:
private:
Value *GetValueAtEndOfBlockInternal(BasicBlock *BB);
void UpdateDebugValue(Instruction *I, DbgValueInst *DbgValue);
};
/// Helper class for promoting a collection of loads and stores into SSA

View File

@@ -40,6 +40,7 @@
#include "llvm/IR/ConstantRange.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/Dominators.h"
#include "llvm/IR/Function.h"
#include "llvm/IR/InstrTypes.h"
@@ -2038,6 +2039,7 @@ void JumpThreadingPass::updateSSA(
// PHI insertion, of which we are prepared to do, clean these up now.
SSAUpdater SSAUpdate;
SmallVector<Use *, 16> UsesToRename;
SmallVector<DbgValueInst *, 4> DbgValues;
for (Instruction &I : *BB) {
// Scan all uses of this instruction to see if it is used outside of its
@@ -2053,8 +2055,16 @@ void JumpThreadingPass::updateSSA(
UsesToRename.push_back(&U);
}
// Find debug values outside of the block
findDbgValues(DbgValues, &I);
DbgValues.erase(remove_if(DbgValues,
[&](const DbgValueInst *DbgVal) {
return DbgVal->getParent() == BB;
}),
DbgValues.end());
// If there are no uses outside the block, we're done with this instruction.
if (UsesToRename.empty())
if (UsesToRename.empty() && DbgValues.empty())
continue;
LLVM_DEBUG(dbgs() << "JT: Renaming non-local uses of: " << I << "\n");
@@ -2067,6 +2077,11 @@ void JumpThreadingPass::updateSSA(
while (!UsesToRename.empty())
SSAUpdate.RewriteUse(*UsesToRename.pop_back_val());
if (!DbgValues.empty()) {
SSAUpdate.UpdateDebugValues(&I, DbgValues);
DbgValues.clear();
}
LLVM_DEBUG(dbgs() << "\n");
}
}

View File

@@ -19,6 +19,7 @@
#include "llvm/IR/BasicBlock.h"
#include "llvm/IR/CFG.h"
#include "llvm/IR/Constants.h"
#include "llvm/IR/DebugInfo.h"
#include "llvm/IR/DebugLoc.h"
#include "llvm/IR/Instruction.h"
#include "llvm/IR/Instructions.h"
@@ -195,6 +196,33 @@ void SSAUpdater::RewriteUse(Use &U) {
U.set(V);
}
void SSAUpdater::UpdateDebugValues(Instruction *I) {
SmallVector<DbgValueInst *, 4> DbgValues;
llvm::findDbgValues(DbgValues, I);
for (auto &DbgValue : DbgValues) {
if (DbgValue->getParent() == I->getParent())
continue;
UpdateDebugValue(I, DbgValue);
}
}
void SSAUpdater::UpdateDebugValues(Instruction *I,
SmallVectorImpl<DbgValueInst *> &DbgValues) {
for (auto &DbgValue : DbgValues) {
UpdateDebugValue(I, DbgValue);
}
}
void SSAUpdater::UpdateDebugValue(Instruction *I, DbgValueInst *DbgValue) {
BasicBlock *UserBB = DbgValue->getParent();
if (HasValueForBlock(UserBB)) {
Value *NewVal = GetValueInMiddleOfBlock(UserBB);
DbgValue->replaceVariableLocationOp(I, NewVal);
}
else
DbgValue->setKillLocation();
}
void SSAUpdater::RewriteUseAfterInsertions(Use &U) {
Instruction *User = cast<Instruction>(U.getUser());

View File

@@ -3,7 +3,7 @@
@a = global i32 0, align 4
; Test that the llvm.dbg.value calls in a threaded block are correctly updated to
; target the locals in their threaded block, and not the unthreaded one.
define void @test2(i32 %cond1, i32 %cond2) {
define void @test1(i32 %cond1, i32 %cond2) {
; CHECK: [[globalptr:@.*]] = global i32 0, align 4
; CHECK: bb.cond2:
; CHECK: call void @llvm.dbg.value(metadata ptr null, metadata ![[DBG1ptr:[0-9]+]], metadata !DIExpression()), !dbg ![[DBG2ptr:[0-9]+]]
@@ -49,6 +49,48 @@ exit: ; preds = %bb.f4, %bb.f3, %bb.
ret void, !dbg !29
}
; This is testing for debug value instrinsics outside of the threaded block pointing to a value
; inside to correctly take any new definitions.
define void @test2(i32 %cond1, i32 %cond2) !dbg !5 {
; CHECK: bb.f3
; CHECK: call void @llvm.dbg.value(metadata ptr @a, metadata !{{[0-9]+}}, metadata !DIExpression()), !dbg !{{[0-9]+}}
; CHECK: bb.f4
; CHECK-NEXT: [[PTR3:%.*]] = phi ptr [ null, %bb.cond2 ]
; CHECK-NEXT: call void @llvm.dbg.value(metadata ptr [[PTR3]], metadata !{{[0-9]+}}, metadata !DIExpression()), !dbg !{{[0-9]+}}
entry:
%tobool = icmp eq i32 %cond1, 0, !dbg !15
br i1 %tobool, label %bb.cond2, label %bb.f1, !dbg !16
bb.f1: ; preds = %entry
call void @f1(), !dbg !17
br label %bb.cond2, !dbg !18
bb.cond2: ; preds = %bb.f1, %entry
%ptr = phi ptr [ null, %bb.f1 ], [ @a, %entry ], !dbg !19
%tobool1 = icmp eq i32 %cond2, 0, !dbg !20
br i1 %tobool1, label %bb.file, label %bb.f2, !dbg !21
bb.f2: ; preds = %bb.cond2
call void @f2(), !dbg !22
br label %exit, !dbg !23
bb.file: ; preds = %bb.cond2
%cmp = icmp eq ptr %ptr, null, !dbg !24
call void @llvm.dbg.value(metadata ptr %ptr, metadata !14, metadata !DIExpression()), !dbg !21
br i1 %cmp, label %bb.f4, label %bb.f3, !dbg !25
bb.f3: ; preds = %bb.file
call void @f3(), !dbg !26
br label %exit, !dbg !27
bb.f4: ; preds = %bb.file
call void @f4(), !dbg !28
br label %exit, !dbg !29
exit: ; preds = %bb.f4, %bb.f3, %bb.f2
ret void, !dbg !29
}
declare void @f1()
declare void @f2()
@@ -95,4 +137,4 @@ attributes #0 = { nocallback nofree nosync nounwind speculatable willreturn memo
!26 = !DILocation(line: 12, column: 1, scope: !5)
!27 = !DILocation(line: 13, column: 1, scope: !5)
!28 = !DILocation(line: 14, column: 1, scope: !5)
!29 = !DILocation(line: 15, column: 1, scope: !5)
!29 = !DILocation(line: 15, column: 1, scope: !5)