[llvm] r265464 - [RegisterBankInfo] Implement the methods to create register banks.

Quentin Colombet via llvm-commits llvm-commits at lists.llvm.org
Tue Apr 5 14:06:16 PDT 2016


Author: qcolombet
Date: Tue Apr  5 16:06:15 2016
New Revision: 265464

URL: http://llvm.org/viewvc/llvm-project?rev=265464&view=rev
Log:
[RegisterBankInfo] Implement the methods to create register banks.

Modified:
    llvm/trunk/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
    llvm/trunk/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp

Modified: llvm/trunk/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h?rev=265464&r1=265463&r2=265464&view=diff
==============================================================================
--- llvm/trunk/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h (original)
+++ llvm/trunk/include/llvm/CodeGen/GlobalISel/RegisterBankInfo.h Tue Apr  5 16:06:15 2016
@@ -15,7 +15,7 @@
 #ifndef LLVM_CODEGEN_GLOBALISEL_REGBANKINFO_H
 #define LLVM_CODEGEN_GLOBALISEL_REGBANKINFO_H
 
-#include <memory>
+#include <memory> // For unique_ptr.
 
 namespace llvm {
 class RegisterBank;
@@ -24,20 +24,58 @@ class TargetRegisterInfo;
 /// Holds all the information related to register banks.
 class RegisterBankInfo {
 protected:
+  /// Hold the set of supported register banks.
   std::unique_ptr<RegisterBank[]> RegBanks;
-  unsigned NbOfRegBanks;
+  /// Total number of register banks.
+  unsigned NumRegBanks;
 
-  RegisterBankInfo(unsigned NbOfRegBanks);
+  /// Create a RegisterBankInfo that can accomodate up to \p NumRegBanks
+  /// RegisterBank instances.
+  ///
+  /// \note For the verify method to succeed all the \p NumRegBanks
+  /// must be initialized by createRegisterBank and updated with
+  /// addRegBankCoverage RegisterBank.
+  RegisterBankInfo(unsigned NumRegBanks);
 
   virtual ~RegisterBankInfo();
 
+  /// Create a new register bank with the given parameter and add it
+  /// to RegBanks.
+  /// \pre \p ID must not already be used.
+  /// \pre \p ID < NumRegBanks.
+  void createRegisterBank(unsigned ID, const char *Name);
+
+  /// Add \p RC to the set of register class that the register bank
+  /// identified \p ID covers.
+  /// This method transitively adds all the sub classes of \p RC
+  /// to the set of covered register classes.
+  /// It also adjusts the size of the register bank to reflect the maximal
+  /// size of a value that can be hold into that register bank.
+  ///
+  /// \note This method does *not* add the super classes of \p RC.
+  /// The rationale is if \p ID covers the registers of \p RC, that
+  /// does not necessarily mean that \p ID covers the set of registers
+  /// of RC's superclasses.
+  ///
+  /// \todo TableGen should just generate the BitSet vector for us.
+  void addRegBankCoverage(unsigned ID, const TargetRegisterClass &RC,
+                          const TargetRegisterInfo &TRI);
+
+  /// Get the register bank identified by \p ID.
+  RegisterBank &getRegBank(unsigned ID) {
+    assert(ID < getNumRegBanks() && "Accessing an unknown register bank");
+    return RegBanks[ID];
+  }
+
 public:
   /// Get the register bank identified by \p ID.
   const RegisterBank &getRegBank(unsigned ID) const {
-    assert(ID < NbOfRegBanks && "Accessing an unknown register bank");
-    return RegBanks[ID];
+    return const_cast<RegisterBankInfo *>(this)->getRegBank(ID);
   }
 
+  /// Get the total number of register banks.
+  unsigned getNumRegBanks() const { return NumRegBanks; }
+
   /// Get the cost of a copy from \p B to \p A, or put differently,
   /// get the cost of A = COPY B.
   virtual unsigned copyCost(const RegisterBank &A,

Modified: llvm/trunk/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp?rev=265464&r1=265463&r2=265464&view=diff
==============================================================================
--- llvm/trunk/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp (original)
+++ llvm/trunk/lib/CodeGen/GlobalISel/RegisterBankInfo.cpp Tue Apr  5 16:06:15 2016
@@ -11,18 +11,91 @@
 //===----------------------------------------------------------------------===//
 
 #include "llvm/CodeGen/GlobalISel/RegisterBank.h"
+#include "llvm/ADT/SmallVector.h"
 #include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
 #include "llvm/Target/TargetRegisterInfo.h"
 
+#include <algorithm> // For std::max.
+
 #define DEBUG_TYPE "registerbankinfo"
 
 using namespace llvm;
 
-RegisterBankInfo::RegisterBankInfo(unsigned NbOfRegBanks)
-    : NbOfRegBanks(NbOfRegBanks) {
-  RegBanks.reset(new RegisterBank[NbOfRegBanks]);
+RegisterBankInfo::RegisterBankInfo(unsigned NumRegBanks)
+    : NumRegBanks(NumRegBanks) {
+  RegBanks.reset(new RegisterBank[NumRegBanks]);
 }
 
 RegisterBankInfo::~RegisterBankInfo() {}
 
-void RegisterBankInfo::verify(const TargetRegisterInfo &TRI) const {}
+void RegisterBankInfo::verify(const TargetRegisterInfo &TRI) const {
+  for (unsigned Idx = 0, End = getNumRegBanks(); Idx != End; ++Idx) {
+    const RegisterBank &RegBank = getRegBank(Idx);
+    assert(Idx == RegBank.getID() &&
+           "ID does not match the index in the array");
+    RegBank.verify(TRI);
+  }
+}
+
+void RegisterBankInfo::createRegisterBank(unsigned ID, const char *Name) {
+  RegisterBank &RegBank = getRegBank(ID);
+  assert(RegBank.getID() == RegisterBank::InvalidID &&
+         "A register bank should be created only once");
+  RegBank.ID = ID;
+  RegBank.Name = Name;
+}
+
+void RegisterBankInfo::addRegBankCoverage(unsigned ID,
+                                          const TargetRegisterClass &RC,
+                                          const TargetRegisterInfo &TRI) {
+  RegisterBank &RB = getRegBank(ID);
+  unsigned NbOfRegClasses = TRI.getNumRegClasses();
+  // Check if RB is underconstruction.
+  if (!RB.isValid())
+    RB.ContainedRegClasses.resize(NbOfRegClasses);
+  else if (RB.contains(RC))
+    // If RB already contains this register class, there is nothing
+    // to do.
+    return;
+
+  BitVector &Covered = RB.ContainedRegClasses;
+  SmallVector<unsigned, 8> WorkList;
+
+  WorkList.push_back(RC.getID());
+  Covered.set(RC.getID());
+
+  unsigned &MaxSize = RB.Size;
+  do {
+    unsigned RCId = WorkList.pop_back_val();
+
+    const TargetRegisterClass &CurRC = *TRI.getRegClass(RCId);
+    // Remember the biggest size in bits.
+    MaxSize = std::max(MaxSize, CurRC.getSize() * 8);
+
+    // Walk through all sub register classes and push them into the worklist.
+    const uint32_t *SubClassMask = CurRC.getSubClassMask();
+    // The subclasses mask is broken down into chunks of uint32_t, but it still
+    // represents all register classes.
+    for (unsigned Base = 0; Base < NbOfRegClasses; Base += 32) {
+      unsigned Idx = Base;
+      for (uint32_t Mask = *SubClassMask++; Mask; Mask >>= 1, ++Idx) {
+        unsigned Offset = countTrailingZeros(Mask);
+        unsigned SubRCId = Idx + Offset;
+        if (!Covered.test(SubRCId))
+          WorkList.push_back(SubRCId);
+        // Remember that we saw the sub class.
+        Covered.set(SubRCId);
+        // Move the cursor to the next sub class.
+        // I.e., eat up the zeros then move to the next bit.
+        // This last part is done as part of the loop increment.
+
+        // By construction, Offset must be less than 32.
+        // Otherwise, than means Mask was zero. I.e., no UB.
+        Mask >>= Offset;
+        // Remember that we shifted the base offset.
+        Idx += Offset;
+      }
+    }
+
+  } while (!WorkList.empty());
+}




More information about the llvm-commits mailing list