summaryrefslogtreecommitdiffstats
path: root/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
diff options
context:
space:
mode:
authorJeremy Morse <jeremy.morse.llvm@gmail.com>2019-02-13 10:54:53 +0000
committerJeremy Morse <jeremy.morse.llvm@gmail.com>2019-02-13 10:54:53 +0000
commitf10af3f134f2c91b0dcc2bd7fa9e8f700fb05b99 (patch)
treebbd33f980aabb8be4ba7459338d525a6b8e38a65 /llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
parentf8ffb926e206982c57d862d12fe0004a135e014c (diff)
downloadbcm5719-llvm-f10af3f134f2c91b0dcc2bd7fa9e8f700fb05b99.tar.gz
bcm5719-llvm-f10af3f134f2c91b0dcc2bd7fa9e8f700fb05b99.zip
[DebugInfo][InstCombine] Prefer to salvage debuginfo over sinking it
When instcombine sinks an instruction between two basic blocks, it sinks any dbg.value users in the source block with it, to prevent debug use-before-free. However we can do better by attempting to salvage the debug users, which would avoid moving where the variable location changes. If we successfully salvage, still sink a (cloned) dbg.value with the sunk instruction, as the sunk instruction is more likely to be "live" later in the compilation process. If we can't salvage dbg.value users of a sunk instruction, mark the dbg.values in the original block as being undef. This terminates any earlier variable location range, and represents the fact that we've optimized out the variable location for a portion of the program. Differential Revision: https://reviews.llvm.org/D56788 llvm-svn: 353936
Diffstat (limited to 'llvm/lib/Transforms/InstCombine/InstructionCombining.cpp')
-rw-r--r--llvm/lib/Transforms/InstCombine/InstructionCombining.cpp32
1 files changed, 27 insertions, 5 deletions
diff --git a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
index 4d04e3ff99e..8cbf57a97ef 100644
--- a/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
+++ b/llvm/lib/Transforms/InstCombine/InstructionCombining.cpp
@@ -3099,13 +3099,35 @@ static bool TryToSinkInstruction(Instruction *I, BasicBlock *DestBlock) {
++NumSunkInst;
// Also sink all related debug uses from the source basic block. Otherwise we
- // get debug use before the def.
- SmallVector<DbgVariableIntrinsic *, 1> DbgUsers;
+ // get debug use before the def. Attempt to salvage debug uses first, to
+ // maximise the range variables have location for. If we cannot salvage, then
+ // mark the location undef: we know it was supposed to receive a new location
+ // here, but that computation has been sunk.
+ SmallVector<DbgVariableIntrinsic *, 2> DbgUsers;
findDbgUsers(DbgUsers, I);
- for (auto *DII : DbgUsers) {
+ for (auto *DII : reverse(DbgUsers)) {
if (DII->getParent() == SrcBlock) {
- DII->moveBefore(&*InsertPos);
- LLVM_DEBUG(dbgs() << "SINK: " << *DII << '\n');
+ // dbg.value is in the same basic block as the sunk inst, see if we can
+ // salvage it. Clone a new copy of the instruction: on success we need
+ // both salvaged and unsalvaged copies.
+ SmallVector<DbgVariableIntrinsic *, 1> TmpUser{
+ cast<DbgVariableIntrinsic>(DII->clone())};
+
+ if (!salvageDebugInfoForDbgValues(*I, TmpUser)) {
+ // We are unable to salvage: sink the cloned dbg.value, and mark the
+ // original as undef, terminating any earlier variable location.
+ LLVM_DEBUG(dbgs() << "SINK: " << *DII << '\n');
+ TmpUser[0]->insertBefore(&*InsertPos);
+ Value *Undef = UndefValue::get(I->getType());
+ DII->setOperand(0, MetadataAsValue::get(DII->getContext(),
+ ValueAsMetadata::get(Undef)));
+ } else {
+ // We successfully salvaged: place the salvaged dbg.value in the
+ // original location, and move the unmodified dbg.value to sink with
+ // the sunk inst.
+ TmpUser[0]->insertBefore(DII);
+ DII->moveBefore(&*InsertPos);
+ }
}
}
return true;
OpenPOWER on IntegriCloud