aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/Transforms/Utils/Local.cpp
diff options
context:
space:
mode:
authorJeremy Morse <jeremy.morse@sony.com>2023-11-26 22:57:40 +0000
committerGitHub <noreply@github.com>2023-11-26 22:57:40 +0000
commitf0b5527b793413e40bfe1db799d9188e9180b53d (patch)
treeb3440f286ac0d87e82d3c7a78d5c7c08aa4f19cf /llvm/lib/Transforms/Utils/Local.cpp
parent1a08887784484f7ea49c66c188c73527e7764648 (diff)
downloadllvm-f0b5527b793413e40bfe1db799d9188e9180b53d.zip
llvm-f0b5527b793413e40bfe1db799d9188e9180b53d.tar.gz
llvm-f0b5527b793413e40bfe1db799d9188e9180b53d.tar.bz2
[DebugInfo][RemoveDIs] Instrument loop-rotate for DPValues (#72997)
Loop-rotate manually maintains dbg.value intrinsics -- it also needs to manually maintain the replacement for dbg.value intrinsics, DPValue objects. For the most part this patch adds parallel implementations using the new type Some extra juggling is needed when loop-rotate hoists loop-invariant instructions out of the loop: the DPValues attached to such an instruction need to get rotated but not hoisted. Exercised by the new test function invariant_hoist in dbgvalue.ll. There's also a "don't insert duplicate debug intrinsics" facility in LoopRotate. The value and correctness of this isn't clear, but to continue preserving behaviour that's now tested in the "tak_dup" function in dbgvalue.ll. Other things in this patch include a helper DebugVariable constructor for DPValues, a insertDebugValuesForPHIs handler for RemoveDIs (exercised by the new tests), and beefing up the dbg.value checking in dbgvalue.ll to ensure that each record is tested (and that there's an implicit check-not).
Diffstat (limited to 'llvm/lib/Transforms/Utils/Local.cpp')
-rw-r--r--llvm/lib/Transforms/Utils/Local.cpp65
1 files changed, 65 insertions, 0 deletions
diff --git a/llvm/lib/Transforms/Utils/Local.cpp b/llvm/lib/Transforms/Utils/Local.cpp
index 8c6c112..e399329 100644
--- a/llvm/lib/Transforms/Utils/Local.cpp
+++ b/llvm/lib/Transforms/Utils/Local.cpp
@@ -1972,6 +1972,69 @@ bool llvm::LowerDbgDeclare(Function &F) {
return Changed;
}
+// RemoveDIs: re-implementation of insertDebugValuesForPHIs, but which pulls the
+// debug-info out of the block's DPValues rather than dbg.value intrinsics.
+static void insertDPValuesForPHIs(BasicBlock *BB,
+ SmallVectorImpl<PHINode *> &InsertedPHIs) {
+ assert(BB && "No BasicBlock to clone DPValue(s) from.");
+ if (InsertedPHIs.size() == 0)
+ return;
+
+ // Map existing PHI nodes to their DPValues.
+ DenseMap<Value *, DPValue *> DbgValueMap;
+ for (auto &I : *BB) {
+ for (auto &DPV : I.getDbgValueRange()) {
+ for (Value *V : DPV.location_ops())
+ if (auto *Loc = dyn_cast_or_null<PHINode>(V))
+ DbgValueMap.insert({Loc, &DPV});
+ }
+ }
+ if (DbgValueMap.size() == 0)
+ return;
+
+ // Map a pair of the destination BB and old DPValue to the new DPValue,
+ // so that if a DPValue is being rewritten to use more than one of the
+ // inserted PHIs in the same destination BB, we can update the same DPValue
+ // with all the new PHIs instead of creating one copy for each.
+ MapVector<std::pair<BasicBlock *, DPValue *>, DPValue *> NewDbgValueMap;
+ // Then iterate through the new PHIs and look to see if they use one of the
+ // previously mapped PHIs. If so, create a new DPValue that will propagate
+ // the info through the new PHI. If we use more than one new PHI in a single
+ // destination BB with the same old dbg.value, merge the updates so that we
+ // get a single new DPValue with all the new PHIs.
+ for (auto PHI : InsertedPHIs) {
+ BasicBlock *Parent = PHI->getParent();
+ // Avoid inserting a debug-info record into an EH block.
+ if (Parent->getFirstNonPHI()->isEHPad())
+ continue;
+ for (auto VI : PHI->operand_values()) {
+ auto V = DbgValueMap.find(VI);
+ if (V != DbgValueMap.end()) {
+ DPValue *DbgII = cast<DPValue>(V->second);
+ auto NewDI = NewDbgValueMap.find({Parent, DbgII});
+ if (NewDI == NewDbgValueMap.end()) {
+ DPValue *NewDbgII = DbgII->clone();
+ NewDI = NewDbgValueMap.insert({{Parent, DbgII}, NewDbgII}).first;
+ }
+ DPValue *NewDbgII = NewDI->second;
+ // If PHI contains VI as an operand more than once, we may
+ // replaced it in NewDbgII; confirm that it is present.
+ if (is_contained(NewDbgII->location_ops(), VI))
+ NewDbgII->replaceVariableLocationOp(VI, PHI);
+ }
+ }
+ }
+ // Insert the new DPValues into their destination blocks.
+ for (auto DI : NewDbgValueMap) {
+ BasicBlock *Parent = DI.first.first;
+ DPValue *NewDbgII = DI.second;
+ auto InsertionPt = Parent->getFirstInsertionPt();
+ assert(InsertionPt != Parent->end() && "Ill-formed basic block");
+
+ InsertionPt->DbgMarker->insertDPValue(NewDbgII, true);
+ }
+}
+
/// Propagate dbg.value intrinsics through the newly inserted PHIs.
void llvm::insertDebugValuesForPHIs(BasicBlock *BB,
SmallVectorImpl<PHINode *> &InsertedPHIs) {
@@ -1979,6 +2042,8 @@ void llvm::insertDebugValuesForPHIs(BasicBlock *BB,
if (InsertedPHIs.size() == 0)
return;
+ insertDPValuesForPHIs(BB, InsertedPHIs);
+
// Map existing PHI nodes to their dbg.values.
ValueToValueMapTy DbgValueMap;
for (auto &I : *BB) {