[RegisterBankInfo] Implement the methods to create register banks.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@265464 91177308-0d34-0410-b5e6-96231b3b80d8
This commit is contained in:
Quentin Colombet 2016-04-05 21:06:15 +00:00
parent ef94029809
commit 062bf7c9dd
2 changed files with 120 additions and 9 deletions

View File

@ -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,

View File

@ -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());
}