From 203e0b17dd6049d64cb4ed7c4da09747204e6463 Mon Sep 17 00:00:00 2001 From: Jakob Stoklund Olesen Date: Fri, 30 Sep 2011 00:10:40 +0000 Subject: [PATCH] Precompute a bit vector of register sub-classes. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@140827 91177308-0d34-0410-b5e6-96231b3b80d8 --- utils/TableGen/CodeGenRegisters.cpp | 29 +++++++++++++++++++++++++++++ utils/TableGen/CodeGenRegisters.h | 6 ++++++ 2 files changed, 35 insertions(+) diff --git a/utils/TableGen/CodeGenRegisters.cpp b/utils/TableGen/CodeGenRegisters.cpp index 9d0672d6fbb..c7124950124 100644 --- a/utils/TableGen/CodeGenRegisters.cpp +++ b/utils/TableGen/CodeGenRegisters.cpp @@ -388,6 +388,34 @@ const std::string &CodeGenRegisterClass::getName() const { return TheDef->getName(); } +// Compute sub-classes of all register classes. +// Assume the classes are ordered topologically. +void CodeGenRegisterClass:: +computeSubClasses(ArrayRef RegClasses) { + // Visit backwards so sub-classes are seen first. + for (unsigned rci = RegClasses.size(); rci; --rci) { + CodeGenRegisterClass &RC = *RegClasses[rci - 1]; + RC.SubClasses.resize(RegClasses.size()); + RC.SubClasses.set(RC.EnumValue); + + // Normally, all subclasses have IDs >= rci, unless RC is part of a clique. + for (unsigned s = rci; s != RegClasses.size(); ++s) { + if (RC.SubClasses.test(s)) + continue; + CodeGenRegisterClass *SubRC = RegClasses[s]; + if (!RC.hasSubClass(SubRC)) + continue; + // SubRC is a sub-class. Grap all its sub-classes so we won't have to + // check them again. + RC.SubClasses |= SubRC->SubClasses; + } + + // Sweep up missed clique members. They will be immediately preceeding RC. + for (unsigned s = rci - 1; s && RC.hasSubClass(RegClasses[s - 1]); --s) + RC.SubClasses.set(s - 1); + } +} + //===----------------------------------------------------------------------===// // CodeGenRegBank //===----------------------------------------------------------------------===// @@ -435,6 +463,7 @@ CodeGenRegBank::CodeGenRegBank(RecordKeeper &Records) : Records(Records) { array_pod_sort(RegClasses.begin(), RegClasses.end(), TopoOrderRC); for (unsigned i = 0, e = RegClasses.size(); i != e; ++i) RegClasses[i]->EnumValue = i; + CodeGenRegisterClass::computeSubClasses(RegClasses); } CodeGenRegister *CodeGenRegBank::getReg(Record *Def) { diff --git a/utils/TableGen/CodeGenRegisters.h b/utils/TableGen/CodeGenRegisters.h index 8edc541c4f2..ae8f0d4abdf 100644 --- a/utils/TableGen/CodeGenRegisters.h +++ b/utils/TableGen/CodeGenRegisters.h @@ -19,6 +19,7 @@ #include "SetTheory.h" #include "llvm/CodeGen/ValueTypes.h" #include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/BitVector.h" #include "llvm/ADT/DenseMap.h" #include "llvm/ADT/SetVector.h" #include @@ -87,6 +88,8 @@ namespace llvm { CodeGenRegister::Set Members; const std::vector *Elements; std::vector > AltOrders; + // Bit mask of sub-classes including this, indexed by their EnumValue. + BitVector SubClasses; public: Record *TheDef; unsigned EnumValue; @@ -139,6 +142,9 @@ namespace llvm { unsigned getNumOrders() const { return 1 + AltOrders.size(); } CodeGenRegisterClass(CodeGenRegBank&, Record *R); + + // Called by CodeGenRegBank::CodeGenRegBank(). + static void computeSubClasses(ArrayRef); }; // CodeGenRegBank - Represent a target's registers and the relations between