mirror of
https://github.com/RPCSX/llvm.git
synced 2025-01-23 12:45:47 +00:00
[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:
parent
ef94029809
commit
062bf7c9dd
@ -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,
|
||||
|
@ -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());
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user