From 881c8e0c9ac3eb8d9d20d34b2354ac413f8146b4 Mon Sep 17 00:00:00 2001 From: Alexey Samsonov Date: Wed, 10 Jun 2015 17:37:38 +0000 Subject: [PATCH] [GVN] Set proper debug locations for some instructions created by GVN. Determining proper debug locations for instructions created in PHITransAddr is tricky. We use a simple approach here and simply copy debug locations from instructions computing load address to "corresponding" instructions re-creating the address computation in predecessor basic blocks. This may not always be correct, given all the rearrangement and simplification going on, and debug locations may jump around a lot, as the basic blocks we copy locations between may be very far from each other. Still, this would work good in most simple cases (e.g. when chain of address computing instruction is short, or our mapping turns out to be 1-to-1), and we desire to have *some* reasonable debug locations associated with newly inserted instructions. See http://reviews.llvm.org/D10351 review thread for more details. Test Plan: regression test suite Reviewers: spatel, dblaikie Subscribers: llvm-commits Differential Revision: http://reviews.llvm.org/D10351 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@239479 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Analysis/PHITransAddr.cpp | 7 +++-- lib/Transforms/Scalar/GVN.cpp | 4 +++ test/Transforms/GVN/phi-translate.ll | 45 ++++++++++++++++++++-------- 3 files changed, 41 insertions(+), 15 deletions(-) diff --git a/lib/Analysis/PHITransAddr.cpp b/lib/Analysis/PHITransAddr.cpp index 339f7004af8..8d80c6028ba 100644 --- a/lib/Analysis/PHITransAddr.cpp +++ b/lib/Analysis/PHITransAddr.cpp @@ -386,10 +386,10 @@ InsertPHITranslatedSubExpr(Value *InVal, BasicBlock *CurBB, if (!OpVal) return nullptr; // Otherwise insert a cast at the end of PredBB. - CastInst *New = CastInst::Create(Cast->getOpcode(), - OpVal, InVal->getType(), - InVal->getName()+".phi.trans.insert", + CastInst *New = CastInst::Create(Cast->getOpcode(), OpVal, InVal->getType(), + InVal->getName() + ".phi.trans.insert", PredBB->getTerminator()); + New->setDebugLoc(Inst->getDebugLoc()); NewInsts.push_back(New); return New; } @@ -408,6 +408,7 @@ InsertPHITranslatedSubExpr(Value *InVal, BasicBlock *CurBB, GetElementPtrInst *Result = GetElementPtrInst::Create( GEP->getSourceElementType(), GEPOps[0], makeArrayRef(GEPOps).slice(1), InVal->getName() + ".phi.trans.insert", PredBB->getTerminator()); + Result->setDebugLoc(Inst->getDebugLoc()); Result->setIsInBounds(GEP->isInBounds()); NewInsts.push_back(Result); return Result; diff --git a/lib/Transforms/Scalar/GVN.cpp b/lib/Transforms/Scalar/GVN.cpp index 7770ddcb9d7..17b4bb2629a 100644 --- a/lib/Transforms/Scalar/GVN.cpp +++ b/lib/Transforms/Scalar/GVN.cpp @@ -1695,6 +1695,8 @@ bool GVN::PerformLoadPRE(LoadInst *LI, AvailValInBlkVect &ValuesPerBlock, LI->replaceAllUsesWith(V); if (isa(V)) V->takeName(LI); + if (Instruction *I = dyn_cast(V)) + I->setDebugLoc(LI->getDebugLoc()); if (V->getType()->getScalarType()->isPointerTy()) MD->invalidateCachedPointerInfo(V); markInstructionForDeletion(LI); @@ -1761,6 +1763,8 @@ bool GVN::processNonLocalLoad(LoadInst *LI) { if (isa(V)) V->takeName(LI); + if (Instruction *I = dyn_cast(V)) + I->setDebugLoc(LI->getDebugLoc()); if (V->getType()->getScalarType()->isPointerTy()) MD->invalidateCachedPointerInfo(V); markInstructionForDeletion(LI); diff --git a/test/Transforms/GVN/phi-translate.ll b/test/Transforms/GVN/phi-translate.ll index 6068b05aadf..9e37b882f22 100644 --- a/test/Transforms/GVN/phi-translate.ll +++ b/test/Transforms/GVN/phi-translate.ll @@ -4,28 +4,49 @@ target datalayout = "e-p:64:64:64" ; CHECK-LABEL: @foo( ; CHECK: entry.end_crit_edge: -; CHECK: %n.pre = load i32, i32* %q.phi.trans.insert +; CHECK: %j.phi.trans.insert = sext i32 %x to i64, !dbg [[J_LOC:![0-9]+]] +; CHECK: %q.phi.trans.insert = getelementptr {{.*}}, !dbg [[Q_LOC:![0-9]+]] +; CHECK: %n.pre = load i32, i32* %q.phi.trans.insert, !dbg [[N_LOC:![0-9]+]] ; CHECK: then: ; CHECK: store i32 %z ; CHECK: end: -; CHECK: %n = phi i32 [ %n.pre, %entry.end_crit_edge ], [ %z, %then ] +; CHECK: %n = phi i32 [ %n.pre, %entry.end_crit_edge ], [ %z, %then ], !dbg [[N_LOC]] ; CHECK: ret i32 %n +; CHECK-DAG: [[J_LOC]] = !DILocation(line: 45, column: 1, scope: !{{.*}}) +; CHECK-DAG: [[Q_LOC]] = !DILocation(line: 46, column: 1, scope: !{{.*}}) +; CHECK-DAG: [[N_LOC]] = !DILocation(line: 47, column: 1, scope: !{{.*}}) + @G = external global [100 x i32] define i32 @foo(i32 %x, i32 %z) { entry: - %tobool = icmp eq i32 %z, 0 - br i1 %tobool, label %end, label %then + %tobool = icmp eq i32 %z, 0, !dbg !7 + br i1 %tobool, label %end, label %then, !dbg !7 then: - %i = sext i32 %x to i64 - %p = getelementptr [100 x i32], [100 x i32]* @G, i64 0, i64 %i - store i32 %z, i32* %p - br label %end + %i = sext i32 %x to i64, !dbg !8 + %p = getelementptr [100 x i32], [100 x i32]* @G, i64 0, i64 %i, !dbg !8 + store i32 %z, i32* %p, !dbg !8 + br label %end, !dbg !8 end: - %j = sext i32 %x to i64 - %q = getelementptr [100 x i32], [100 x i32]* @G, i64 0, i64 %j - %n = load i32, i32* %q - ret i32 %n + %j = sext i32 %x to i64, !dbg !9 + %q = getelementptr [100 x i32], [100 x i32]* @G, i64 0, i64 %j, !dbg !10 + %n = load i32, i32* %q, !dbg !11 + ret i32 %n, !dbg !11 } + +!llvm.module.flags = !{!0, !1, !2} +!0 = !{i32 2, !"Dwarf Version", i32 4} +!1 = !{i32 2, !"Debug Info Version", i32 3} +!2 = !{i32 1, !"PIC Level", i32 2} + +!3 = !{} +!4 = !DISubroutineType(types: !3) +!5 = !DIFile(filename: "a.cc", directory: "/tmp") +!6 = !DISubprogram(name: "foo", scope: !5, file: !5, line: 42, type: !4, isLocal: false, isDefinition: true, scopeLine: 43, flags: DIFlagPrototyped, isOptimized: false, function: i32 (i32, i32)* @foo, variables: !3) +!7 = !DILocation(line: 43, column: 1, scope: !6) +!8 = !DILocation(line: 44, column: 1, scope: !6) +!9 = !DILocation(line: 45, column: 1, scope: !6) +!10 = !DILocation(line: 46, column: 1, scope: !6) +!11 = !DILocation(line: 47, column: 1, scope: !6) -- 2.34.1