[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