]> granicus.if.org Git - llvm/commitdiff
TableGen: Fix infinite recursion in RegisterBankEmitter
authorTom Stellard <thomas.stellard@amd.com>
Mon, 30 Jan 2017 15:07:01 +0000 (15:07 +0000)
committerTom Stellard <thomas.stellard@amd.com>
Mon, 30 Jan 2017 15:07:01 +0000 (15:07 +0000)
Summary:
AMDGPU has two register classes with the same set of registers, and this
was causing this tablegen backend would get stuck in infinite recursion.

Reviewers: dsanders

Reviewed By: dsanders

Subscribers: tpr, wdng, llvm-commits

Differential Revision: https://reviews.llvm.org/D29049

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@293483 91177308-0d34-0410-b5e6-96231b3b80d8

test/TableGen/RegisterBankEmitter.td [new file with mode: 0644]
utils/TableGen/RegisterBankEmitter.cpp

diff --git a/test/TableGen/RegisterBankEmitter.td b/test/TableGen/RegisterBankEmitter.td
new file mode 100644 (file)
index 0000000..88c7ec1
--- /dev/null
@@ -0,0 +1,15 @@
+// RUN: llvm-tblgen -gen-register-bank -I %p/../../include %s | FileCheck %s
+
+include "llvm/Target/Target.td"
+
+def MyTarget : Target;
+def R0 : Register<"r0">;
+let Size = 32 in {
+  def ClassA : RegisterClass<"MyTarget", [i32], 32, (add R0)>;
+  def ClassB : RegisterClass<"MyTarget", [i1], 32, (add ClassA)>;
+}
+
+// CHECK: GPRRegBankCoverageData
+// CHECK: MyTarget::ClassARegClassID
+// CHECK: MyTarget::ClassBRegClassID
+def GPRRegBank : RegisterBank<"GPR", [ClassA]>;
index 816fc3e0a17665582d34cb4a41eb3234cd0e7412..bf066412b28607717370f6fc72ffb9da7420293b 100644 (file)
@@ -168,7 +168,14 @@ void RegisterBankEmitter::emitBaseClassDefinition(
 static void visitRegisterBankClasses(
     CodeGenRegBank &RegisterClassHierarchy, const CodeGenRegisterClass *RC,
     const Twine Kind,
-    std::function<void(const CodeGenRegisterClass *, StringRef)> VisitFn) {
+    std::function<void(const CodeGenRegisterClass *, StringRef)> VisitFn,
+    SmallPtrSetImpl<const CodeGenRegisterClass *> &VisitedRCs) {
+
+  // Make sure we only visit each class once to avoid infinite loops.
+  if (VisitedRCs.count(RC))
+    return;
+  VisitedRCs.insert(RC);
+
   // Visit each explicitly named class.
   VisitFn(RC, Kind.str());
 
@@ -180,7 +187,7 @@ static void visitRegisterBankClasses(
     if (RC != &PossibleSubclass && RC->hasSubClass(&PossibleSubclass))
       visitRegisterBankClasses(RegisterClassHierarchy, &PossibleSubclass,
                                TmpKind + " " + RC->getName() + " subclass",
-                               VisitFn);
+                               VisitFn, VisitedRCs);
 
     // Visit each class that contains only subregisters of RC with a common
     // subregister-index.
@@ -273,6 +280,7 @@ void RegisterBankEmitter::run(raw_ostream &OS) {
 
   std::vector<RegisterBank> Banks;
   for (const auto &V : Records.getAllDerivedDefinitions("RegisterBank")) {
+    SmallPtrSet<const CodeGenRegisterClass *, 8> VisitedRCs;
     RegisterBank Bank(*V);
 
     for (const CodeGenRegisterClass *RC :
@@ -282,7 +290,7 @@ void RegisterBankEmitter::run(raw_ostream &OS) {
           [&Bank](const CodeGenRegisterClass *RC, StringRef Kind) {
             DEBUG(dbgs() << "Added " << RC->getName() << "(" << Kind << ")\n");
             Bank.addRegisterClass(RC);
-          });
+          }, VisitedRCs);
     }
 
     Banks.push_back(Bank);