From: Tom Stellard Date: Mon, 30 Jan 2017 15:07:01 +0000 (+0000) Subject: TableGen: Fix infinite recursion in RegisterBankEmitter X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7603d04f82a9398d700b83da5137a3b17db54d2d;p=llvm TableGen: Fix infinite recursion in RegisterBankEmitter 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 --- diff --git a/test/TableGen/RegisterBankEmitter.td b/test/TableGen/RegisterBankEmitter.td new file mode 100644 index 00000000000..88c7ec1f791 --- /dev/null +++ b/test/TableGen/RegisterBankEmitter.td @@ -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]>; diff --git a/utils/TableGen/RegisterBankEmitter.cpp b/utils/TableGen/RegisterBankEmitter.cpp index 816fc3e0a17..bf066412b28 100644 --- a/utils/TableGen/RegisterBankEmitter.cpp +++ b/utils/TableGen/RegisterBankEmitter.cpp @@ -168,7 +168,14 @@ void RegisterBankEmitter::emitBaseClassDefinition( static void visitRegisterBankClasses( CodeGenRegBank &RegisterClassHierarchy, const CodeGenRegisterClass *RC, const Twine Kind, - std::function VisitFn) { + std::function VisitFn, + SmallPtrSetImpl &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 Banks; for (const auto &V : Records.getAllDerivedDefinitions("RegisterBank")) { + SmallPtrSet 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);