[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:
@@ -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
|
||||
|
||||
@@ -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");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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());
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user