summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/Utils
diff options
context:
space:
mode:
authorDavide Italiano <davide@freebsd.org>2018-12-12 23:32:35 +0000
committerDavide Italiano <davide@freebsd.org>2018-12-12 23:32:35 +0000
commit744c3c327fbaa3548c4af62694e7c3eeca8b4f6f (patch)
tree68314761b0aef9188f7c4a07a3f794fd67ebb0c9 /llvm/lib/Transforms/Utils
parent36e03ac6ee91366225f446db6437f184de258be6 (diff)
downloadbcm5719-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/Utils')
-rw-r--r--llvm/lib/Transforms/Utils/LoopUtils.cpp27
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())
OpenPOWER on IntegriCloud