diff options
author | Davide Italiano <davide@freebsd.org> | 2018-12-12 23:32:35 +0000 |
---|---|---|
committer | Davide Italiano <davide@freebsd.org> | 2018-12-12 23:32:35 +0000 |
commit | 744c3c327fbaa3548c4af62694e7c3eeca8b4f6f (patch) | |
tree | 68314761b0aef9188f7c4a07a3f794fd67ebb0c9 /llvm/lib/Transforms | |
parent | 36e03ac6ee91366225f446db6437f184de258be6 (diff) | |
download | bcm5719-llvm-744c3c327fbaa3548c4af62694e7c3eeca8b4f6f.tar.gz bcm5719-llvm-744c3c327fbaa3548c4af62694e7c3eeca8b4f6f.zip |
[LoopDeletion] Update debug values after loop deletion.
When loops are deleted, we don't keep track of variables modified inside
the loops, so the DI will contain the wrong value for these.
e.g.
int b() {
int i;
for (i = 0; i < 2; i++)
;
patatino();
return a;
-> 6 patatino();
7 return a;
8 }
9 int main() { b(); }
(lldb) frame var i
(int) i = 0
We mark instead these values as unavailable inserting a
@llvm.dbg.value(undef to make sure we don't end up printing an incorrect
value in the debugger. We could consider doing something fancier,
for, e.g. constants, in the future.
PR39868.
rdar://problem/46418795)
Differential Revision: https://reviews.llvm.org/D55299
llvm-svn: 348988
Diffstat (limited to 'llvm/lib/Transforms')
-rw-r--r-- | llvm/lib/Transforms/Utils/LoopUtils.cpp | 27 |
1 files changed, 27 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Utils/LoopUtils.cpp b/llvm/lib/Transforms/Utils/LoopUtils.cpp index 388553b1783..a5d88d8269f 100644 --- a/llvm/lib/Transforms/Utils/LoopUtils.cpp +++ b/llvm/lib/Transforms/Utils/LoopUtils.cpp @@ -26,9 +26,11 @@ #include "llvm/Analysis/ScalarEvolutionExpressions.h" #include "llvm/Analysis/TargetTransformInfo.h" #include "llvm/Analysis/ValueTracking.h" +#include "llvm/IR/DIBuilder.h" #include "llvm/IR/DomTreeUpdater.h" #include "llvm/IR/Dominators.h" #include "llvm/IR/Instructions.h" +#include "llvm/IR/IntrinsicInst.h" #include "llvm/IR/Module.h" #include "llvm/IR/PatternMatch.h" #include "llvm/IR/ValueHandle.h" @@ -567,6 +569,12 @@ void llvm::deleteDeadLoop(Loop *L, DominatorTree *DT = nullptr, DTU.deleteEdge(Preheader, L->getHeader()); } + // Use a map to unique and a vector to guarantee deterministic ordering. + llvm::SmallDenseMap<std::pair<DIVariable *, DIExpression *>, + DbgVariableIntrinsic *, 4> + DeadDebugMap; + llvm::SmallVector<DbgVariableIntrinsic *, 4> DeadDebugInst; + // Given LCSSA form is satisfied, we should not have users of instructions // within the dead loop outside of the loop. However, LCSSA doesn't take // unreachable uses into account. We handle them here. @@ -591,8 +599,27 @@ void llvm::deleteDeadLoop(Loop *L, DominatorTree *DT = nullptr, "Unexpected user in reachable block"); U.set(Undef); } + auto *DVI = dyn_cast<DbgVariableIntrinsic>(&I); + if (!DVI) + continue; + auto Key = DeadDebugMap.find({DVI->getVariable(), DVI->getExpression()}); + if (Key != DeadDebugMap.end()) + continue; + DeadDebugMap[{DVI->getVariable(), DVI->getExpression()}] = DVI; + DeadDebugInst.push_back(DVI); } + // After the loop has been deleted all the values defined and modified + // inside the loop are going to be unavailable. + // Since debug values in the loop have been deleted, inserting an undef + // dbg.value truncates the range of any dbg.value before the loop where the + // loop used to be. This is particularly important for constant values. + DIBuilder DIB(*ExitBlock->getModule()); + for (auto *DVI : DeadDebugInst) + DIB.insertDbgValueIntrinsic( + UndefValue::get(DVI->getType()), DVI->getVariable(), + DVI->getExpression(), DVI->getDebugLoc(), ExitBlock->getFirstNonPHI()); + // Remove the block from the reference counting scheme, so that we can // delete it freely later. for (auto *Block : L->blocks()) |