diff options
author | Stephen Tozer <Stephen.Tozer@Sony.com> | 2021-03-17 15:04:27 +0000 |
---|---|---|
committer | Stephen Tozer <Stephen.Tozer@Sony.com> | 2021-03-17 16:45:25 +0000 |
commit | 3bfddc25931d44da9b26c092f4e15634712b1459 (patch) | |
tree | 1d46df6ec764c22fd1b16915b688ec105050ec42 /llvm/lib/CodeGen/CodeGenPrepare.cpp | |
parent | 410f09af09b9261f51663773bee01ec7b37e8fd4 (diff) | |
download | llvm-3bfddc25931d44da9b26c092f4e15634712b1459.zip llvm-3bfddc25931d44da9b26c092f4e15634712b1459.tar.gz llvm-3bfddc25931d44da9b26c092f4e15634712b1459.tar.bz2 |
Reapply "[DebugInfo] Handle multiple variable location operands in IR"
Fixed section of code that iterated through a SmallDenseMap and added
instructions in each iteration, causing non-deterministic code; replaced
SmallDenseMap with MapVector to prevent non-determinism.
This reverts commit 01ac6d1587e8613ba4278786e8341f8b492ac941.
Diffstat (limited to 'llvm/lib/CodeGen/CodeGenPrepare.cpp')
-rw-r--r-- | llvm/lib/CodeGen/CodeGenPrepare.cpp | 97 |
1 files changed, 63 insertions, 34 deletions
diff --git a/llvm/lib/CodeGen/CodeGenPrepare.cpp b/llvm/lib/CodeGen/CodeGenPrepare.cpp index 407c176..8e24c86d 100644 --- a/llvm/lib/CodeGen/CodeGenPrepare.cpp +++ b/llvm/lib/CodeGen/CodeGenPrepare.cpp @@ -2873,11 +2873,16 @@ class TypePromotionTransaction { /// Keep track of the debug users. SmallVector<DbgValueInst *, 1> DbgValues; + /// Keep track of the new value so that we can undo it by replacing + /// instances of the new value with the original value. + Value *New; + using use_iterator = SmallVectorImpl<InstructionAndIdx>::iterator; public: /// Replace all the use of \p Inst by \p New. - UsesReplacer(Instruction *Inst, Value *New) : TypePromotionAction(Inst) { + UsesReplacer(Instruction *Inst, Value *New) + : TypePromotionAction(Inst), New(New) { LLVM_DEBUG(dbgs() << "Do: UsersReplacer: " << *Inst << " with " << *New << "\n"); // Record the original uses. @@ -2903,7 +2908,7 @@ class TypePromotionTransaction { // the original debug uses must also be reinstated to maintain the // correctness and utility of debug value instructions. for (auto *DVI : DbgValues) - DVI->replaceVariableLocationOp(DVI->getVariableLocationOp(0), Inst); + DVI->replaceVariableLocationOp(New, Inst); } }; @@ -7903,18 +7908,21 @@ bool CodeGenPrepare::fixupDbgValue(Instruction *I) { DbgValueInst &DVI = *cast<DbgValueInst>(I); // Does this dbg.value refer to a sunk address calculation? - Value *Location = DVI.getVariableLocationOp(0); - WeakTrackingVH SunkAddrVH = SunkAddrs[Location]; - Value *SunkAddr = SunkAddrVH.pointsToAliveValue() ? SunkAddrVH : nullptr; - if (SunkAddr) { - // Point dbg.value at locally computed address, which should give the best - // opportunity to be accurately lowered. This update may change the type of - // pointer being referred to; however this makes no difference to debugging - // information, and we can't generate bitcasts that may affect codegen. - DVI.replaceVariableLocationOp(Location, SunkAddr); - return true; - } - return false; + bool AnyChange = false; + for (Value *Location : DVI.getValues()) { + WeakTrackingVH SunkAddrVH = SunkAddrs[Location]; + Value *SunkAddr = SunkAddrVH.pointsToAliveValue() ? SunkAddrVH : nullptr; + if (SunkAddr) { + // Point dbg.value at locally computed address, which should give the best + // opportunity to be accurately lowered. This update may change the type + // of pointer being referred to; however this makes no difference to + // debugging information, and we can't generate bitcasts that may affect + // codegen. + DVI.replaceVariableLocationOp(Location, SunkAddr); + AnyChange = true; + } + } + return AnyChange; } // A llvm.dbg.value may be using a value before its definition, due to @@ -7933,30 +7941,51 @@ bool CodeGenPrepare::placeDbgValues(Function &F) { if (!DVI) continue; - Instruction *VI = dyn_cast_or_null<Instruction>(DVI->getValue()); + SmallVector<Instruction *, 4> VIs; + for (Value *V : DVI->getValues()) + if (Instruction *VI = dyn_cast_or_null<Instruction>(V)) + VIs.push_back(VI); + + // This DVI may depend on multiple instructions, complicating any + // potential sink. This block takes the defensive approach, opting to + // "undef" the DVI if it has more than one instruction and any of them do + // not dominate DVI. + for (Instruction *VI : VIs) { + if (VI->isTerminator()) + continue; - if (!VI || VI->isTerminator()) - continue; + // If VI is a phi in a block with an EHPad terminator, we can't insert + // after it. + if (isa<PHINode>(VI) && VI->getParent()->getTerminator()->isEHPad()) + continue; - // If VI is a phi in a block with an EHPad terminator, we can't insert - // after it. - if (isa<PHINode>(VI) && VI->getParent()->getTerminator()->isEHPad()) - continue; + // If the defining instruction dominates the dbg.value, we do not need + // to move the dbg.value. + if (DT.dominates(VI, DVI)) + continue; - // If the defining instruction dominates the dbg.value, we do not need - // to move the dbg.value. - if (DT.dominates(VI, DVI)) - continue; + // If we depend on multiple instructions and any of them doesn't + // dominate this DVI, we probably can't salvage it: moving it to + // after any of the instructions could cause us to lose the others. + if (VIs.size() > 1) { + LLVM_DEBUG( + dbgs() + << "Unable to find valid location for Debug Value, undefing:\n" + << *DVI); + DVI->setUndef(); + break; + } - LLVM_DEBUG(dbgs() << "Moving Debug Value before :\n" - << *DVI << ' ' << *VI); - DVI->removeFromParent(); - if (isa<PHINode>(VI)) - DVI->insertBefore(&*VI->getParent()->getFirstInsertionPt()); - else - DVI->insertAfter(VI); - MadeChange = true; - ++NumDbgValueMoved; + LLVM_DEBUG(dbgs() << "Moving Debug Value before :\n" + << *DVI << ' ' << *VI); + DVI->removeFromParent(); + if (isa<PHINode>(VI)) + DVI->insertBefore(&*VI->getParent()->getFirstInsertionPt()); + else + DVI->insertAfter(VI); + MadeChange = true; + ++NumDbgValueMoved; + } } } return MadeChange; |