Skip to content

[LiveDebugVariables] Add basic verification #79846

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 4 commits into
base: main
Choose a base branch
from

Conversation

jayfoad
Copy link
Contributor

@jayfoad jayfoad commented Jan 29, 2024

Add a basic implementation of verifyAnalysis that just checks that the
analysis does not refer to any SlotIndexes for instructions that have
been deleted. This was useful for diagnosing some SlotIndexes-related
problems caused by #67038.

In debug builds, mark slot indexes for deleted instructions as poisoned
and add an isPoisoned method to allow writing assertions elsewhere in
the compiler. This restores some of the functionality that was removed
by 4cf8da9.
Add a basic implementation of verifyAnalysis that just checks that the
analysis does not refer to any SlotIndexes for instructions that have
been deleted. This was useful for diagnosing some SlotIndexes-related
problems caused by llvm#67038.
@llvmbot
Copy link
Member

llvmbot commented Jan 29, 2024

@llvm/pr-subscribers-debuginfo

@llvm/pr-subscribers-llvm-regalloc

Author: Jay Foad (jayfoad)

Changes

Add a basic implementation of verifyAnalysis that just checks that the
analysis does not refer to any SlotIndexes for instructions that have
been deleted. This was useful for diagnosing some SlotIndexes-related
problems caused by #67038.- [SlotIndexes] Implement support for poison checks


Full diff: https://github.com/llvm/llvm-project/pull/79846.diff

4 Files Affected:

  • (modified) llvm/include/llvm/CodeGen/SlotIndexes.h (+27-4)
  • (modified) llvm/lib/CodeGen/LiveDebugVariables.cpp (+17)
  • (modified) llvm/lib/CodeGen/LiveDebugVariables.h (+1)
  • (modified) llvm/lib/CodeGen/SlotIndexes.cpp (+2)
diff --git a/llvm/include/llvm/CodeGen/SlotIndexes.h b/llvm/include/llvm/CodeGen/SlotIndexes.h
index 72f4a6876b6cb14..2b437a0649aac22 100644
--- a/llvm/include/llvm/CodeGen/SlotIndexes.h
+++ b/llvm/include/llvm/CodeGen/SlotIndexes.h
@@ -43,21 +43,40 @@ class raw_ostream;
   /// SlotIndex & SlotIndexes classes for the public interface to this
   /// information.
   class IndexListEntry : public ilist_node<IndexListEntry> {
-    MachineInstr *mi;
+#if NDEBUG
+    // Disable poison checks such that setPoison will do nothing and isPoisoned
+    // will return false.
+    static constexpr unsigned PoisonBits = 0;
+    static constexpr unsigned PoisonVal = 0;
+#else
+    static constexpr unsigned PoisonBits = 1;
+    static constexpr unsigned PoisonVal = 1;
+#endif
+
+    PointerIntPair<MachineInstr *, PoisonBits, unsigned> mi;
     unsigned index;
 
   public:
-    IndexListEntry(MachineInstr *mi, unsigned index) : mi(mi), index(index) {}
+    IndexListEntry(MachineInstr *mi, unsigned index) : mi(mi, 0), index(index) {
+    }
 
-    MachineInstr* getInstr() const { return mi; }
+    MachineInstr* getInstr() const { return mi.getPointer(); }
     void setInstr(MachineInstr *mi) {
-      this->mi = mi;
+      this->mi.setPointer(mi);
     }
 
     unsigned getIndex() const { return index; }
     void setIndex(unsigned index) {
       this->index = index;
     }
+
+    void setPoison() {
+      mi.setInt(PoisonVal);
+    }
+
+    bool isPoisoned() const {
+      return mi.getInt();
+    }
   };
 
   template <>
@@ -285,6 +304,10 @@ class raw_ostream;
     SlotIndex getPrevIndex() const {
       return SlotIndex(&*--listEntry()->getIterator(), getSlot());
     }
+
+    bool isPoisoned() const {
+      return listEntry()->isPoisoned();
+    }
   };
 
   inline raw_ostream& operator<<(raw_ostream &os, SlotIndex li) {
diff --git a/llvm/lib/CodeGen/LiveDebugVariables.cpp b/llvm/lib/CodeGen/LiveDebugVariables.cpp
index 7cb90af5ff173ed..93b9566b21370ad 100644
--- a/llvm/lib/CodeGen/LiveDebugVariables.cpp
+++ b/llvm/lib/CodeGen/LiveDebugVariables.cpp
@@ -492,6 +492,13 @@ class UserValue {
   /// Return DebugLoc of this UserValue.
   const DebugLoc &getDebugLoc() { return dl; }
 
+  void verify() const {
+    for (auto I = locInts.begin(), E = locInts.end(); I != E; ++I) {
+      assert(!I.start().isPoisoned());
+      assert(!I.stop().isPoisoned());
+    }
+  }
+
   void print(raw_ostream &, const TargetRegisterInfo *);
 };
 
@@ -655,6 +662,11 @@ class LDVImpl {
     ModifiedMF = false;
   }
 
+  void verify() const {
+    for (auto [DV, UV] : userVarMap)
+      UV->verify();
+  }
+
   /// Map virtual register to an equivalence class.
   void mapVirtReg(Register VirtReg, UserValue *EC);
 
@@ -1320,6 +1332,11 @@ void LiveDebugVariables::releaseMemory() {
     static_cast<LDVImpl*>(pImpl)->clear();
 }
 
+void LiveDebugVariables::verifyAnalysis() const {
+  if (pImpl)
+    static_cast<LDVImpl *>(pImpl)->verify();
+}
+
 LiveDebugVariables::~LiveDebugVariables() {
   if (pImpl)
     delete static_cast<LDVImpl*>(pImpl);
diff --git a/llvm/lib/CodeGen/LiveDebugVariables.h b/llvm/lib/CodeGen/LiveDebugVariables.h
index 9998ce9e8dad861..c99f11c8565a819 100644
--- a/llvm/lib/CodeGen/LiveDebugVariables.h
+++ b/llvm/lib/CodeGen/LiveDebugVariables.h
@@ -56,6 +56,7 @@ class LLVM_LIBRARY_VISIBILITY LiveDebugVariables : public MachineFunctionPass {
   bool runOnMachineFunction(MachineFunction &) override;
   void releaseMemory() override;
   void getAnalysisUsage(AnalysisUsage &) const override;
+  void verifyAnalysis() const override;
 
   MachineFunctionProperties getSetProperties() const override {
     return MachineFunctionProperties().set(
diff --git a/llvm/lib/CodeGen/SlotIndexes.cpp b/llvm/lib/CodeGen/SlotIndexes.cpp
index 8b80c6ccb438936..762aab2ec2557e3 100644
--- a/llvm/lib/CodeGen/SlotIndexes.cpp
+++ b/llvm/lib/CodeGen/SlotIndexes.cpp
@@ -126,6 +126,7 @@ void SlotIndexes::removeMachineInstrFromMaps(MachineInstr &MI,
   mi2iMap.erase(mi2iItr);
   // FIXME: Eventually we want to actually delete these indexes.
   MIEntry.setInstr(nullptr);
+  MIEntry.setPoison();
 }
 
 void SlotIndexes::removeSingleMachineInstrFromMaps(MachineInstr &MI) {
@@ -152,6 +153,7 @@ void SlotIndexes::removeSingleMachineInstrFromMaps(MachineInstr &MI) {
   } else {
     // FIXME: Eventually we want to actually delete these indexes.
     MIEntry.setInstr(nullptr);
+    MIEntry.setPoison();
   }
 }
 

Copy link

github-actions bot commented Jan 29, 2024

✅ With the latest revision this PR passed the C/C++ code formatter.

@adrian-prantl adrian-prantl requested a review from jmorse January 29, 2024 22:59
@@ -492,6 +492,13 @@ class UserValue {
/// Return DebugLoc of this UserValue.
const DebugLoc &getDebugLoc() { return dl; }

void verify() const {
for (auto I = locInts.begin(), E = locInts.end(); I != E; ++I) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
for (auto I = locInts.begin(), E = locInts.end(); I != E; ++I) {
for (auto I : locInts) {

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this works because I need to call start and stop which are methods on the iterator itself (an instance of IntervalMap::const_iterator).

@dwblaikie dwblaikie requested a review from SLTozer January 30, 2024 00:15
Copy link
Contributor

@SLTozer SLTozer left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Adding the verification SGTM - LiveDebugVariables can be a moderately hot pass (though LiveDebugValues is the real killer) and PointerIntPair can cause a bit of a slowdown compared to just pointer operations, but I expect this won't have a noticeable impact.

@jayfoad
Copy link
Contributor Author

jayfoad commented Jan 30, 2024

Adding the verification SGTM - LiveDebugVariables can be a moderately hot pass (though LiveDebugValues is the real killer) and PointerIntPair can cause a bit of a slowdown compared to just pointer operations, but I expect this won't have a noticeable impact.

I should have mentioned that I cannot commit this patch as-is because it causes lit test failures. I think these are all pre-existing problems with LiveDebugVariables that would need to be fixed. There was some prior discussion about this in the previous iteration of this review, #68703. I'd appreciate any help with understanding or fixing the failures!

Failed Tests (6):
  LLVM :: CodeGen/Thumb2/pr52817.ll
  LLVM :: DebugInfo/ARM/PR26163.ll
  LLVM :: DebugInfo/COFF/fpo-csrs.ll
  LLVM :: DebugInfo/X86/pr34545.ll
  LLVM :: DebugInfo/X86/spill-indirect-nrvo.ll
  LLVM :: tools/llvm-dwarfdump/X86/LTO_CCU_zero_loc_cov.ll

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants