Skip to content

CodeGen: Eliminate dynamic relocations in the register superclass tables. #119122

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

Merged
merged 6 commits into from
Dec 10, 2024

Conversation

resistor
Copy link
Collaborator

@resistor resistor commented Dec 8, 2024

No description provided.

@s-barannikov s-barannikov requested a review from jayfoad December 8, 2024 15:38
@llvmbot
Copy link
Member

llvmbot commented Dec 8, 2024

@llvm/pr-subscribers-tablegen
@llvm/pr-subscribers-backend-x86

@llvm/pr-subscribers-backend-arm

Author: Owen Anderson (resistor)

Changes

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

6 Files Affected:

  • (modified) llvm/include/llvm/CodeGen/TargetRegisterInfo.h (+32-7)
  • (modified) llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp (+8-8)
  • (modified) llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp (+3-2)
  • (modified) llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp (+9-7)
  • (modified) llvm/lib/Target/X86/X86RegisterInfo.cpp (+3-2)
  • (modified) llvm/utils/TableGen/RegisterInfoEmitter.cpp (+5-6)
diff --git a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
index 292fa3c94969be..c69c5205bf9e3c 100644
--- a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
+++ b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
@@ -42,11 +42,38 @@ class VirtRegMap;
 class LiveIntervals;
 class LiveInterval;
 
+/// TargetSuperClassIterator enumerates all super-registers of RegClass.
+class TargetSuperClassIterator
+    : public iterator_adaptor_base<TargetSuperClassIterator, const unsigned *> {
+public:
+  /// Constructs an end iterator.
+  TargetSuperClassIterator() = default;
+
+  TargetSuperClassIterator(const unsigned *V, const TargetRegisterClass *T) { I = V; }
+
+  const TargetRegisterClass &operator*() const { return *I; }
+
+  using iterator_adaptor_base::operator++;
+
+  bool operator==(const TargetSuperClassIterator &Other) const {
+    // End can be represented either with a nullptr or with a ptr to
+    // a sentinel value of ~0U. They must compare equal.
+    bool SelfIsEnd = !I || *I == ~0U;
+    bool OtherIsEnd = !Other.I || *Other.I == ~0U;
+    if (SelfIsEnd && OtherIsEnd)
+      return true;
+    
+    return I == Other.I;
+  }
+
+  /// Returns true if this iterator is not yet at the end.
+  bool isValid() const { return I && *I != ~0U; }
+};
+
 class TargetRegisterClass {
 public:
   using iterator = const MCPhysReg *;
   using const_iterator = const MCPhysReg *;
-  using sc_iterator = const TargetRegisterClass* const *;
 
   // Instance variables filled by tablegen, do not use!
   const MCRegisterClass *MC;
@@ -67,7 +94,7 @@ class TargetRegisterClass {
   /// Whether a combination of subregisters can cover every register in the
   /// class. See also the CoveredBySubRegs description in Target.td.
   const bool CoveredBySubRegs;
-  const sc_iterator SuperClasses;
+  const unsigned *SuperClasses;
   ArrayRef<MCPhysReg> (*OrderFunc)(const MachineFunction&);
 
   /// Return the register class ID number.
@@ -178,15 +205,13 @@ class TargetRegisterClass {
   /// Returns a NULL-terminated list of super-classes.  The
   /// classes are ordered by ID which is also a topological ordering from large
   /// to small classes.  The list does NOT include the current class.
-  sc_iterator getSuperClasses() const {
-    return SuperClasses;
+  iterator_range<TargetSuperClassIterator> superclasses() const {
+    return make_range({SuperClasses}, TargetSuperClassIterator());
   }
 
   /// Return true if this TargetRegisterClass is a subset
   /// class of at least one other TargetRegisterClass.
-  bool isASubClass() const {
-    return SuperClasses[0] != nullptr;
-  }
+  bool isASubClass() const { return SuperClasses[0] != ~0U; }
 
   /// Returns the preferred order for allocating registers from this register
   /// class in MF. The raw order comes directly from the .td file and may
diff --git a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
index a1f068f0e049bd..ade447871545e9 100644
--- a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
@@ -262,30 +262,30 @@ bool ARMBaseRegisterInfo::isInlineAsmReadOnlyReg(const MachineFunction &MF,
 const TargetRegisterClass *
 ARMBaseRegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC,
                                                const MachineFunction &MF) const {
-  const TargetRegisterClass *Super = RC;
-  TargetRegisterClass::sc_iterator I = RC->getSuperClasses();
+  unsigned SuperID = RC->getID();
+  auto I = RC->superclasses().begin();
   do {
-    switch (Super->getID()) {
+    switch (SuperID) {
     case ARM::GPRRegClassID:
     case ARM::SPRRegClassID:
     case ARM::DPRRegClassID:
     case ARM::GPRPairRegClassID:
-      return Super;
+      return getRegClass(SuperID);
     case ARM::QPRRegClassID:
     case ARM::QQPRRegClassID:
     case ARM::QQQQPRRegClassID:
       if (MF.getSubtarget<ARMSubtarget>().hasNEON())
-        return Super;
+        return getRegClass(SuperID);
       break;
     case ARM::MQPRRegClassID:
     case ARM::MQQPRRegClassID:
     case ARM::MQQQQPRRegClassID:
       if (MF.getSubtarget<ARMSubtarget>().hasMVEIntegerOps())
-        return Super;
+        return getRegClass(SuperID);
       break;
     }
-    Super = *I++;
-  } while (Super);
+    SuperID = *I++;
+  } while (SuperID != ~0U);
   return RC;
 }
 
diff --git a/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp b/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp
index d4d121e4380089..d159d00201ad7a 100644
--- a/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp
@@ -431,8 +431,9 @@ unsigned HexagonRegisterInfo::getHexagonSubRegIndex(
       return WSub[GenIdx];
   }
 
-  if (const TargetRegisterClass *SuperRC = *RC.getSuperClasses())
-    return getHexagonSubRegIndex(*SuperRC, GenIdx);
+  unsigned SuperID = *RC.superclasses().begin();
+  if (SuperID != ~0U)
+    return getHexagonSubRegIndex(*getRegClass(SuperID), GenIdx);
 
   llvm_unreachable("Invalid register class");
 }
diff --git a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp
index 43dfc4108f8384..019d4cfa33fbaf 100644
--- a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp
+++ b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp
@@ -692,21 +692,23 @@ PPCRegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC,
         InflateGPRC++;
     }
 
-    for (const auto *I = RC->getSuperClasses(); *I; ++I) {
-      if (getRegSizeInBits(**I) != getRegSizeInBits(*RC))
+    for (unsigned SuperID : RC->superclasses()) {
+      if (getRegSizeInBits(*getRegClass(SuperID)) != getRegSizeInBits(*RC))
         continue;
 
-      switch ((*I)->getID()) {
+      switch (SuperID) {
       case PPC::VSSRCRegClassID:
-        return Subtarget.hasP8Vector() ? *I : DefaultSuperclass;
+        return Subtarget.hasP8Vector() ? getRegClass(SuperID)
+                                       : DefaultSuperclass;
       case PPC::VSFRCRegClassID:
       case PPC::VSRCRegClassID:
-        return *I;
+        return getRegClass(SuperID);
       case PPC::VSRpRCRegClassID:
-        return Subtarget.pairedVectorMemops() ? *I : DefaultSuperclass;
+        return Subtarget.pairedVectorMemops() ? getRegClass(SuperID)
+                                              : DefaultSuperclass;
       case PPC::ACCRCRegClassID:
       case PPC::UACCRCRegClassID:
-        return Subtarget.hasMMA() ? *I : DefaultSuperclass;
+        return Subtarget.hasMMA() ? getRegClass(SuperID) : DefaultSuperclass;
       }
     }
   }
diff --git a/llvm/lib/Target/X86/X86RegisterInfo.cpp b/llvm/lib/Target/X86/X86RegisterInfo.cpp
index 50db211c99d882..84b9310279fcb3 100644
--- a/llvm/lib/Target/X86/X86RegisterInfo.cpp
+++ b/llvm/lib/Target/X86/X86RegisterInfo.cpp
@@ -123,7 +123,7 @@ X86RegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC,
   const X86Subtarget &Subtarget = MF.getSubtarget<X86Subtarget>();
 
   const TargetRegisterClass *Super = RC;
-  TargetRegisterClass::sc_iterator I = RC->getSuperClasses();
+  auto I = RC->superclasses().begin();
   do {
     switch (Super->getID()) {
     case X86::FR32RegClassID:
@@ -172,7 +172,8 @@ X86RegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC,
       if (getRegSizeInBits(*Super) == getRegSizeInBits(*RC))
         return Super;
     }
-    Super = *I++;
+    Super = I.isValid() ? getRegClass(*I) : nullptr;
+    ++I;
   } while (Super);
   return RC;
 }
diff --git a/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/llvm/utils/TableGen/RegisterInfoEmitter.cpp
index a6f87119aca5ba..a0b4668f152563 100644
--- a/llvm/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/llvm/utils/TableGen/RegisterInfoEmitter.cpp
@@ -1286,8 +1286,8 @@ void RegisterInfoEmitter::runTargetDesc(raw_ostream &OS) {
     }
     OS << "};\n";
 
-    OS << "\nstatic const TargetRegisterClass *const "
-       << "NullRegClasses[] = { nullptr };\n\n";
+    OS << "\nstatic const unsigned "
+       << "NullRegClasses[] = { ~0U };\n\n";
 
     // Emit register class bit mask tables. The first bit mask emitted for a
     // register class, RC, is the set of sub-classes, including RC itself.
@@ -1348,11 +1348,10 @@ void RegisterInfoEmitter::runTargetDesc(raw_ostream &OS) {
       if (Supers.empty())
         continue;
 
-      OS << "static const TargetRegisterClass *const " << RC.getName()
-         << "Superclasses[] = {\n";
+      OS << "static unsigned const " << RC.getName() << "Superclasses[] = {\n";
       for (const auto *Super : Supers)
-        OS << "  &" << Super->getQualifiedName() << "RegClass,\n";
-      OS << "  nullptr\n};\n\n";
+        OS << "  " << Super->getQualifiedIdName() << ",\n";
+      OS << "  ~0U\n};\n\n";
     }
 
     // Emit methods.

@llvmbot
Copy link
Member

llvmbot commented Dec 8, 2024

@llvm/pr-subscribers-backend-powerpc

Author: Owen Anderson (resistor)

Changes

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

6 Files Affected:

  • (modified) llvm/include/llvm/CodeGen/TargetRegisterInfo.h (+32-7)
  • (modified) llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp (+8-8)
  • (modified) llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp (+3-2)
  • (modified) llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp (+9-7)
  • (modified) llvm/lib/Target/X86/X86RegisterInfo.cpp (+3-2)
  • (modified) llvm/utils/TableGen/RegisterInfoEmitter.cpp (+5-6)
diff --git a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
index 292fa3c94969be..c69c5205bf9e3c 100644
--- a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
+++ b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
@@ -42,11 +42,38 @@ class VirtRegMap;
 class LiveIntervals;
 class LiveInterval;
 
+/// TargetSuperClassIterator enumerates all super-registers of RegClass.
+class TargetSuperClassIterator
+    : public iterator_adaptor_base<TargetSuperClassIterator, const unsigned *> {
+public:
+  /// Constructs an end iterator.
+  TargetSuperClassIterator() = default;
+
+  TargetSuperClassIterator(const unsigned *V, const TargetRegisterClass *T) { I = V; }
+
+  const TargetRegisterClass &operator*() const { return *I; }
+
+  using iterator_adaptor_base::operator++;
+
+  bool operator==(const TargetSuperClassIterator &Other) const {
+    // End can be represented either with a nullptr or with a ptr to
+    // a sentinel value of ~0U. They must compare equal.
+    bool SelfIsEnd = !I || *I == ~0U;
+    bool OtherIsEnd = !Other.I || *Other.I == ~0U;
+    if (SelfIsEnd && OtherIsEnd)
+      return true;
+    
+    return I == Other.I;
+  }
+
+  /// Returns true if this iterator is not yet at the end.
+  bool isValid() const { return I && *I != ~0U; }
+};
+
 class TargetRegisterClass {
 public:
   using iterator = const MCPhysReg *;
   using const_iterator = const MCPhysReg *;
-  using sc_iterator = const TargetRegisterClass* const *;
 
   // Instance variables filled by tablegen, do not use!
   const MCRegisterClass *MC;
@@ -67,7 +94,7 @@ class TargetRegisterClass {
   /// Whether a combination of subregisters can cover every register in the
   /// class. See also the CoveredBySubRegs description in Target.td.
   const bool CoveredBySubRegs;
-  const sc_iterator SuperClasses;
+  const unsigned *SuperClasses;
   ArrayRef<MCPhysReg> (*OrderFunc)(const MachineFunction&);
 
   /// Return the register class ID number.
@@ -178,15 +205,13 @@ class TargetRegisterClass {
   /// Returns a NULL-terminated list of super-classes.  The
   /// classes are ordered by ID which is also a topological ordering from large
   /// to small classes.  The list does NOT include the current class.
-  sc_iterator getSuperClasses() const {
-    return SuperClasses;
+  iterator_range<TargetSuperClassIterator> superclasses() const {
+    return make_range({SuperClasses}, TargetSuperClassIterator());
   }
 
   /// Return true if this TargetRegisterClass is a subset
   /// class of at least one other TargetRegisterClass.
-  bool isASubClass() const {
-    return SuperClasses[0] != nullptr;
-  }
+  bool isASubClass() const { return SuperClasses[0] != ~0U; }
 
   /// Returns the preferred order for allocating registers from this register
   /// class in MF. The raw order comes directly from the .td file and may
diff --git a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
index a1f068f0e049bd..ade447871545e9 100644
--- a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
+++ b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.cpp
@@ -262,30 +262,30 @@ bool ARMBaseRegisterInfo::isInlineAsmReadOnlyReg(const MachineFunction &MF,
 const TargetRegisterClass *
 ARMBaseRegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC,
                                                const MachineFunction &MF) const {
-  const TargetRegisterClass *Super = RC;
-  TargetRegisterClass::sc_iterator I = RC->getSuperClasses();
+  unsigned SuperID = RC->getID();
+  auto I = RC->superclasses().begin();
   do {
-    switch (Super->getID()) {
+    switch (SuperID) {
     case ARM::GPRRegClassID:
     case ARM::SPRRegClassID:
     case ARM::DPRRegClassID:
     case ARM::GPRPairRegClassID:
-      return Super;
+      return getRegClass(SuperID);
     case ARM::QPRRegClassID:
     case ARM::QQPRRegClassID:
     case ARM::QQQQPRRegClassID:
       if (MF.getSubtarget<ARMSubtarget>().hasNEON())
-        return Super;
+        return getRegClass(SuperID);
       break;
     case ARM::MQPRRegClassID:
     case ARM::MQQPRRegClassID:
     case ARM::MQQQQPRRegClassID:
       if (MF.getSubtarget<ARMSubtarget>().hasMVEIntegerOps())
-        return Super;
+        return getRegClass(SuperID);
       break;
     }
-    Super = *I++;
-  } while (Super);
+    SuperID = *I++;
+  } while (SuperID != ~0U);
   return RC;
 }
 
diff --git a/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp b/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp
index d4d121e4380089..d159d00201ad7a 100644
--- a/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp
+++ b/llvm/lib/Target/Hexagon/HexagonRegisterInfo.cpp
@@ -431,8 +431,9 @@ unsigned HexagonRegisterInfo::getHexagonSubRegIndex(
       return WSub[GenIdx];
   }
 
-  if (const TargetRegisterClass *SuperRC = *RC.getSuperClasses())
-    return getHexagonSubRegIndex(*SuperRC, GenIdx);
+  unsigned SuperID = *RC.superclasses().begin();
+  if (SuperID != ~0U)
+    return getHexagonSubRegIndex(*getRegClass(SuperID), GenIdx);
 
   llvm_unreachable("Invalid register class");
 }
diff --git a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp
index 43dfc4108f8384..019d4cfa33fbaf 100644
--- a/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp
+++ b/llvm/lib/Target/PowerPC/PPCRegisterInfo.cpp
@@ -692,21 +692,23 @@ PPCRegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC,
         InflateGPRC++;
     }
 
-    for (const auto *I = RC->getSuperClasses(); *I; ++I) {
-      if (getRegSizeInBits(**I) != getRegSizeInBits(*RC))
+    for (unsigned SuperID : RC->superclasses()) {
+      if (getRegSizeInBits(*getRegClass(SuperID)) != getRegSizeInBits(*RC))
         continue;
 
-      switch ((*I)->getID()) {
+      switch (SuperID) {
       case PPC::VSSRCRegClassID:
-        return Subtarget.hasP8Vector() ? *I : DefaultSuperclass;
+        return Subtarget.hasP8Vector() ? getRegClass(SuperID)
+                                       : DefaultSuperclass;
       case PPC::VSFRCRegClassID:
       case PPC::VSRCRegClassID:
-        return *I;
+        return getRegClass(SuperID);
       case PPC::VSRpRCRegClassID:
-        return Subtarget.pairedVectorMemops() ? *I : DefaultSuperclass;
+        return Subtarget.pairedVectorMemops() ? getRegClass(SuperID)
+                                              : DefaultSuperclass;
       case PPC::ACCRCRegClassID:
       case PPC::UACCRCRegClassID:
-        return Subtarget.hasMMA() ? *I : DefaultSuperclass;
+        return Subtarget.hasMMA() ? getRegClass(SuperID) : DefaultSuperclass;
       }
     }
   }
diff --git a/llvm/lib/Target/X86/X86RegisterInfo.cpp b/llvm/lib/Target/X86/X86RegisterInfo.cpp
index 50db211c99d882..84b9310279fcb3 100644
--- a/llvm/lib/Target/X86/X86RegisterInfo.cpp
+++ b/llvm/lib/Target/X86/X86RegisterInfo.cpp
@@ -123,7 +123,7 @@ X86RegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC,
   const X86Subtarget &Subtarget = MF.getSubtarget<X86Subtarget>();
 
   const TargetRegisterClass *Super = RC;
-  TargetRegisterClass::sc_iterator I = RC->getSuperClasses();
+  auto I = RC->superclasses().begin();
   do {
     switch (Super->getID()) {
     case X86::FR32RegClassID:
@@ -172,7 +172,8 @@ X86RegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC,
       if (getRegSizeInBits(*Super) == getRegSizeInBits(*RC))
         return Super;
     }
-    Super = *I++;
+    Super = I.isValid() ? getRegClass(*I) : nullptr;
+    ++I;
   } while (Super);
   return RC;
 }
diff --git a/llvm/utils/TableGen/RegisterInfoEmitter.cpp b/llvm/utils/TableGen/RegisterInfoEmitter.cpp
index a6f87119aca5ba..a0b4668f152563 100644
--- a/llvm/utils/TableGen/RegisterInfoEmitter.cpp
+++ b/llvm/utils/TableGen/RegisterInfoEmitter.cpp
@@ -1286,8 +1286,8 @@ void RegisterInfoEmitter::runTargetDesc(raw_ostream &OS) {
     }
     OS << "};\n";
 
-    OS << "\nstatic const TargetRegisterClass *const "
-       << "NullRegClasses[] = { nullptr };\n\n";
+    OS << "\nstatic const unsigned "
+       << "NullRegClasses[] = { ~0U };\n\n";
 
     // Emit register class bit mask tables. The first bit mask emitted for a
     // register class, RC, is the set of sub-classes, including RC itself.
@@ -1348,11 +1348,10 @@ void RegisterInfoEmitter::runTargetDesc(raw_ostream &OS) {
       if (Supers.empty())
         continue;
 
-      OS << "static const TargetRegisterClass *const " << RC.getName()
-         << "Superclasses[] = {\n";
+      OS << "static unsigned const " << RC.getName() << "Superclasses[] = {\n";
       for (const auto *Super : Supers)
-        OS << "  &" << Super->getQualifiedName() << "RegClass,\n";
-      OS << "  nullptr\n};\n\n";
+        OS << "  " << Super->getQualifiedIdName() << ",\n";
+      OS << "  ~0U\n};\n\n";
     }
 
     // Emit methods.

Copy link
Contributor

@s-barannikov s-barannikov left a comment

Choose a reason for hiding this comment

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

LGTM but please wait for @jayfoad review.

@chandlerc
Copy link
Member

chandlerc commented Dec 9, 2024

Just to give some motivation, this PR (after #118734 merges) will remove another 13% of non-vtable dynamic relocations from the clang binary -- that's over 10k dynamic relocations avoided.

These are also hard to see as no one table is terribly large, but there are a large number of them.

There are also more opportunities remaining here, notably the dynamic relocations required in some of the .*SysRegsList arrays and the <target>MCRegisterClasses arrays.

Also, could the same change done here for superclass tables be done for subreg tables? That's the other one that seems to show up as a lot of separate tables, although not as much as superclasses.

@resistor
Copy link
Collaborator Author

resistor commented Dec 9, 2024

Also, could the same change done here for superclass tables be done for subreg tables? That's the other one that seems to show up as a lot of separate tables, although not as much as superclasses.

I'll take a look at the others once this one is in. I expect some of them to be straight forward, but the ID -> TargetRegisterClass table will be tricky.

@androm3da
Copy link
Member

cc @llvm/pr-subscribers-backend-hexagon

Copy link
Contributor

@jayfoad jayfoad left a comment

Choose a reason for hiding this comment

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

Looks OK to me.

I find the mixture of checking isValid vs checking for an explicit ~0U pretty ugly, but maybe that's inevitable for a sentinel-terminated list.

@resistor
Copy link
Collaborator Author

I find the mixture of checking isValid vs checking for an explicit ~0U pretty ugly, but maybe that's inevitable for a sentinel-terminated list.

I figured out a way to get rid of this, by storing the size of the list. PTAL

Copy link

github-actions bot commented Dec 10, 2024

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

Copy link
Contributor

@jayfoad jayfoad left a comment

Choose a reason for hiding this comment

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

No specific objection to this patch, but it seems like it could still be cleaned up. If we're storing the size of the list then why do we also need a sentinel value? I'd also be inclined to make superclasses() return an ArrayRef instead of iterator_range (but maybe that's just my own personal prejudice against unnecessary iterators).

@resistor
Copy link
Collaborator Author

No specific objection to this patch, but it seems like it could still be cleaned up. If we're storing the size of the list then why do we also need a sentinel value? I'd also be inclined to make superclasses() return an ArrayRef instead of iterator_range (but maybe that's just my own personal prejudice against unnecessary iterators).

Done.

Copy link
Contributor

@jayfoad jayfoad left a comment

Choose a reason for hiding this comment

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

Thanks!

@resistor resistor merged commit c487381 into llvm:main Dec 10, 2024
8 checks passed
@vitalybuka
Copy link
Collaborator

Probably from this patch https://lab.llvm.org/buildbot/#/builders/25/builds/4805 ?

@resistor
Copy link
Collaborator Author

This other patch definitely caused an ASAN failure and I just reverted it: #119138

@resistor
Copy link
Collaborator Author

Looking at the error logs, it definitely appears to be #119138, not this one

@resistor resistor deleted the relro2 branch December 11, 2024 00:32
@vitalybuka
Copy link
Collaborator

I see those as well

/tmp/bot/llvm-project/llvm/lib/Target/X86/X86RegisterInfo.cpp:177:5: runtime error: applying non-zero offset 4 to null pointer
    #0 0x555b8c2b4bd2 in llvm::X86RegisterInfo::getLargestLegalSuperClass(llvm::TargetRegisterClass const*, llvm::MachineFunction const&) const /tmp/bot/llvm-project/llvm/lib/Target/X86/X86RegisterInfo.cpp:177:5
    #1 0x555b8da1d57d in llvm::RegisterClassInfo::compute(llvm::TargetRegisterClass const*) const /tmp/bot/llvm-project/llvm/lib/CodeGen/RegisterClassInfo.cpp:181:16
    #2 0x555b8da1e63b in llvm::RegisterClassInfo::computePSetLimit(unsigned int) const /tmp/bot/llvm-project/llvm/lib/CodeGen/RegisterClassInfo.cpp:223:3
    #3 0x555b8d5f963c in llvm::RegisterClassInfo::getRegPressureSetLimit(unsigned int) const /tmp/bot/llvm-project/llvm/include/llvm/CodeGen/RegisterClassInfo.h:148:25
    #4 0x555b8d5f61ef in llvm::ScheduleDAGMILive::initRegPressure() /tmp/bot/llvm-project/llvm/lib/CodeGen/MachineScheduler.cpp:1312:36
    #5 0x555b8d5fb60c in llvm::ScheduleDAGMILive::schedule() /tmp/bot/llvm-project/llvm/lib/CodeGen/MachineScheduler.cpp:1459:3
    #6 0x555b8d629ab4 in (anonymous namespace)::MachineSchedulerBase::scheduleRegions(llvm::ScheduleDAGInstrs&, bool) /tmp/bot/llvm-project/llvm/lib/CodeGen/MachineScheduler.cpp:650:17
    #7 0x555b8d627618 in (anonymous namespace)::MachineScheduler::runOnMachineFunction(llvm::MachineFunction&) /tmp/bot/llvm-project/llvm/lib/CodeGen/MachineScheduler.cpp:463:3
    #8 0x555b8d430881 in llvm::MachineFunctionPass::runOnFunction(llvm::Function&) /tmp/bot/llvm-project/llvm/lib/CodeGen/MachineFunctionPass.cpp:94:13
    #9 0x555b8e36b1c3 in llvm::FPPassManager::runOnFunction(llvm::Function&) /tmp/bot/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:1406:27
    #10 0x555b8e38227e in llvm::FPPassManager::runOnModule(llvm::Module&) /tmp/bot/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:1452:16
    #11 0x555b8e36cdba in runOnModule /tmp/bot/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:1521:27
    #12 0x555b8e36cdba in llvm::legacy::PassManagerImpl::run(llvm::Module&) /tmp/bot/llvm-project/llvm/lib/IR/LegacyPassManager.cpp:539:44
    #13 0x555b90a72efb in RunCodegenPipeline /tmp/bot/llvm-project/clang/lib/CodeGen/BackendUtil.cpp:1197:19
    #14 0x555b90a72efb in EmitAssembly /tmp/bot/llvm-project/clang/lib/CodeGen/BackendUtil.cpp:1220:3
    #15 0x555b90a72efb in clang::EmitBackendOutput(clang::DiagnosticsEngine&, clang::HeaderSearchOptions const&, clang::CodeGenOptions const&, clang::TargetOptions const&, clang::LangOptions const&, llvm::StringRef, llvm::Module*, clang::BackendAction, llvm::IntrusiveRefCntPtr<llvm::vfs::FileSystem>, std::__1::unique_ptr<llvm::raw_pwrite_stream, std::__1::default_delete<llvm::raw_pwrite_stream>>, clang::BackendConsumer*) /tmp/bot/llvm-project/clang/lib/CodeGen/BackendUtil.cpp:1383:13
    #16 0x555b90adb00e in clang::CodeGenAction::ExecuteAction() /tmp/bot/llvm-project/clang/lib/CodeGen/CodeGenAction.cpp:1217:3
    #17 0x555b9149559c in clang::FrontendAction::Execute() /tmp/bot/llvm-project/clang/lib/Frontend/FrontendAction.cpp:1077:8
    #18 0x555b9138a94d in clang::CompilerInstance::ExecuteAction(clang::FrontendAction&) /tmp/bot/llvm-project/clang/lib/Frontend/CompilerInstance.cpp:1062:33
    #19 0x555b9175ef91 in clang::ExecuteCompilerInvocation(clang::CompilerInstance*) /tmp/bot/llvm-project/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp:296:25
    #20 0x555b886f825f in cc1_main(llvm::ArrayRef<char const*>, char const*, void*) /tmp/bot/llvm-project/clang/tools/driver/cc1_main.cpp:286:15
    #21 0x555b886ed85b in ExecuteCC1Tool(llvm::SmallVectorImpl<char const*>&, llvm::ToolContext const&) /tmp/bot/llvm-project/clang/tools/driver/driver.cpp:218:12
    #22 0x555b886ebaa4 in clang_main(int, char**, llvm::ToolContext const&) /tmp/bot/llvm-project/clang/tools/driver/driver.cpp:259:12

@resistor
Copy link
Collaborator Author

Ok, that's a different error that does come from this commit. Reverting.

resistor added a commit that referenced this pull request Dec 11, 2024
…lass tables. (#119122)"

Reverting due to UBSan failures in X86RegisterInfo::getLargestLegalSuperClass

This reverts commit c487381.
@resistor
Copy link
Collaborator Author

Reverted in e940353

resistor added a commit to resistor/llvm-project that referenced this pull request Dec 11, 2024
…les.

This reapplies llvm#119122 with a fix for UBSAN errors in the X86 backend related
to incrementing a nullptr.
resistor added a commit to resistor/llvm-project that referenced this pull request Dec 11, 2024
…les.

This reapplies llvm#119122 with a fix for UBSAN errors in the X86 backend related
to incrementing a nullptr.
@@ -123,7 +123,8 @@ X86RegisterInfo::getLargestLegalSuperClass(const TargetRegisterClass *RC,
const X86Subtarget &Subtarget = MF.getSubtarget<X86Subtarget>();

const TargetRegisterClass *Super = RC;
TargetRegisterClass::sc_iterator I = RC->getSuperClasses();
auto I = RC->superclasses().begin();
Copy link
Contributor

Choose a reason for hiding this comment

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

I think this code is really trying to iterate over RC and all its (proper) superclasses, so maybe it could be rewritten like:

  for (auto ID : concat<unsigned>({RC->getID()}, RC->superclasses()))

resistor added a commit that referenced this pull request Dec 11, 2024
…les. (#119487)

This reapplies #119122 with a fix for UBSAN errors in the X86 backend
related
to incrementing a nullptr.
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.

7 participants