Skip to content

Commit

Permalink
[globalisel] Tablegen-erate current Register Bank Information
Browse files Browse the repository at this point in the history
Summary:
Adds a RegisterBank tablegen class that can be used to declare the register
banks and an associated tablegen pass to generate the necessary code.

Reviewers: t.p.northover, ab, rovka, qcolombet

Subscribers: aditya_nandakumar, rengolin, kristof.beyls, vkalintiris, mgorny, dberris, llvm-commits, rovka

Differential Revision: https://reviews.llvm.org/D27338

llvm-svn: 292132
  • Loading branch information
dsandersllvm committed Jan 16, 2017
1 parent 8da139a commit ab8194d
Show file tree
Hide file tree
Showing 16 changed files with 437 additions and 193 deletions.
2 changes: 1 addition & 1 deletion llvm/include/llvm/CodeGen/GlobalISel/RegisterBank.h
Expand Up @@ -42,7 +42,7 @@ class RegisterBank {

public:
RegisterBank(unsigned ID, const char *Name, unsigned Size,
const uint32_t *ContainedRegClasses);
const uint32_t *ContainedRegClasses, unsigned NumRegClasses);

/// Get the identifier of this register bank.
unsigned getID() const { return ID; }
Expand Down
16 changes: 16 additions & 0 deletions llvm/include/llvm/Target/GlobalISel/RegisterBank.td
@@ -0,0 +1,16 @@
//===- RegisterBank.td - Register bank definitions ---------*- tablegen -*-===//
//
// The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
//
//===----------------------------------------------------------------------===//

class RegisterBank<string name, list<RegisterClass> classes> {
string Name = name;
list<RegisterClass> RegisterClasses = classes;
}
1 change: 1 addition & 0 deletions llvm/include/llvm/Target/Target.td
Expand Up @@ -1344,4 +1344,5 @@ include "llvm/Target/TargetSelectionDAG.td"
//===----------------------------------------------------------------------===//
// Pull in the common support for Global ISel generation.
//
include "llvm/Target/GlobalISel/RegisterBank.td"
include "llvm/Target/TargetGlobalISel.td"
7 changes: 4 additions & 3 deletions llvm/lib/CodeGen/GlobalISel/RegisterBank.cpp
Expand Up @@ -19,10 +19,11 @@ using namespace llvm;

const unsigned RegisterBank::InvalidID = UINT_MAX;

RegisterBank::RegisterBank(unsigned ID, const char *Name, unsigned Size,
const uint32_t *CoveredClasses)
RegisterBank::RegisterBank(
unsigned ID, const char *Name, unsigned Size,
const uint32_t *CoveredClasses, unsigned NumRegClasses)
: ID(ID), Name(Name), Size(Size) {
ContainedRegClasses.resize(200);
ContainedRegClasses.resize(NumRegClasses);
ContainedRegClasses.setBitsInMask(CoveredClasses);
}

Expand Down
1 change: 1 addition & 0 deletions llvm/lib/Target/AArch64/AArch64.td
Expand Up @@ -124,6 +124,7 @@ def HasV8_2aOps : SubtargetFeature<"v8.2a", "HasV8_2aOps", "true",
//===----------------------------------------------------------------------===//

include "AArch64RegisterInfo.td"
include "AArch64RegisterBanks.td"
include "AArch64CallingConvention.td"

//===----------------------------------------------------------------------===//
Expand Down
209 changes: 43 additions & 166 deletions llvm/lib/Target/AArch64/AArch64GenRegisterBankInfo.def
Expand Up @@ -16,204 +16,81 @@
#endif

namespace llvm {
namespace AArch64 {

const uint32_t GPRCoverageData[] = {
// Classes 0-31
(1u << AArch64::GPR32allRegClassID) | (1u << AArch64::GPR32RegClassID) |
(1u << AArch64::GPR32spRegClassID) |
(1u << AArch64::GPR32commonRegClassID) |
(1u << AArch64::GPR32sponlyRegClassID) |
(1u << AArch64::GPR64allRegClassID) | (1u << AArch64::GPR64RegClassID) |
(1u << AArch64::GPR64spRegClassID) |
(1u << AArch64::GPR64commonRegClassID) |
(1u << AArch64::tcGPR64RegClassID) |
(1u << AArch64::GPR64sponlyRegClassID),
// Classes 32-63
0,
// FIXME: The entries below this point can be safely removed once this is
// tablegenerated. It's only needed because of the hardcoded register class
// limit.
// Classes 64-96
0,
// Classes 97-128
0,
// Classes 129-160
0,
// Classes 161-192
0,
// Classes 193-224
0,
};

const uint32_t FPRCoverageData[] = {
// Classes 0-31
(1u << AArch64::FPR8RegClassID) | (1u << AArch64::FPR16RegClassID) |
(1u << AArch64::FPR32RegClassID) | (1u << AArch64::FPR64RegClassID) |
(1u << AArch64::DDRegClassID) | (1u << AArch64::FPR128RegClassID) |
(1u << AArch64::FPR128_loRegClassID) | (1u << AArch64::DDDRegClassID) |
(1u << AArch64::DDDDRegClassID),
// Classes 32-63
(1u << (AArch64::QQRegClassID - 32)) |
(1u << (AArch64::QQ_with_qsub0_in_FPR128_loRegClassID - 32)) |
(1u << (AArch64::QQ_with_qsub1_in_FPR128_loRegClassID - 32)) |
(1u
<< (AArch64::
QQQ_with_qsub1_in_FPR128_lo_and_QQQ_with_qsub2_in_FPR128_loRegClassID -
32)) |
(1u
<< (AArch64::
QQQ_with_qsub0_in_FPR128_lo_and_QQQ_with_qsub2_in_FPR128_loRegClassID -
32)) |
(1u << (AArch64::QQQQRegClassID - 32)) |
(1u << (AArch64::QQQQ_with_qsub0_in_FPR128_loRegClassID - 32)) |
(1u << (AArch64::QQQQ_with_qsub1_in_FPR128_loRegClassID - 32)) |
(1u << (AArch64::QQQQ_with_qsub2_in_FPR128_loRegClassID - 32)) |
(1u << (AArch64::QQQQ_with_qsub3_in_FPR128_loRegClassID - 32)) |
(1u
<< (AArch64::
QQQQ_with_qsub0_in_FPR128_lo_and_QQQQ_with_qsub1_in_FPR128_loRegClassID -
32)) |
(1u
<< (AArch64::
QQQQ_with_qsub1_in_FPR128_lo_and_QQQQ_with_qsub2_in_FPR128_loRegClassID -
32)) |
(1u
<< (AArch64::
QQQQ_with_qsub2_in_FPR128_lo_and_QQQQ_with_qsub3_in_FPR128_loRegClassID -
32)) |
(1u
<< (AArch64::
QQQQ_with_qsub0_in_FPR128_lo_and_QQQQ_with_qsub2_in_FPR128_loRegClassID -
32)) |
(1u
<< (AArch64::
QQQQ_with_qsub1_in_FPR128_lo_and_QQQQ_with_qsub3_in_FPR128_loRegClassID -
32)) |
(1u
<< (AArch64::
QQQQ_with_qsub0_in_FPR128_lo_and_QQQQ_with_qsub3_in_FPR128_loRegClassID -
32)) |
(1u
<< (AArch64::
QQ_with_qsub0_in_FPR128_lo_and_QQ_with_qsub1_in_FPR128_loRegClassID -
32)) |
(1u << (AArch64::QQQRegClassID - 32)) |
(1u << (AArch64::QQQ_with_qsub0_in_FPR128_loRegClassID - 32)) |
(1u << (AArch64::QQQ_with_qsub1_in_FPR128_loRegClassID - 32)) |
(1u << (AArch64::QQQ_with_qsub2_in_FPR128_loRegClassID - 32)) |
(1u
<< (AArch64::
QQQ_with_qsub0_in_FPR128_lo_and_QQQ_with_qsub1_in_FPR128_loRegClassID -
32)),
// FIXME: The entries below this point can be safely removed once this
// is tablegenerated. It's only needed because of the hardcoded register
// class limit.
// Classes 64-96
0,
// Classes 97-128
0,
// Classes 129-160
0,
// Classes 161-192
0,
// Classes 193-224
0,
};

const uint32_t CCRCoverageData[] = {
// Classes 0-31
1u << AArch64::CCRRegClassID,
// Classes 32-63
0,
// FIXME: The entries below this point can be safely removed once this
// is tablegenerated. It's only needed because of the hardcoded register
// class limit.
// Classes 64-96
0,
// Classes 97-128
0,
// Classes 129-160
0,
// Classes 161-192
0,
// Classes 193-224
0,
};

RegisterBank GPRRegBank(AArch64::GPRRegBankID, "GPR", 64, GPRCoverageData);
RegisterBank FPRRegBank(AArch64::FPRRegBankID, "FPR", 512, FPRCoverageData);
RegisterBank CCRRegBank(AArch64::CCRRegBankID, "CCR", 32, CCRCoverageData);
} // end namespace AArch64

RegisterBank *AArch64GenRegisterBankInfo::RegBanks[] = {
&AArch64::GPRRegBank, &AArch64::FPRRegBank, &AArch64::CCRRegBank};

RegisterBankInfo::PartialMapping AArch64GenRegisterBankInfo::PartMappings[]{
/* StartIdx, Length, RegBank */
// 0: GPR 32-bit value.
{0, 32, AArch64::GPRRegBank},
// 1: GPR 64-bit value.
{0, 64, AArch64::GPRRegBank},
// 2: FPR 32-bit value.
// 0: FPR 32-bit value.
{0, 32, AArch64::FPRRegBank},
// 3: FPR 64-bit value.
// 1: FPR 64-bit value.
{0, 64, AArch64::FPRRegBank},
// 4: FPR 128-bit value.
// 2: FPR 128-bit value.
{0, 128, AArch64::FPRRegBank},
// 5: FPR 256-bit value.
// 3: FPR 256-bit value.
{0, 256, AArch64::FPRRegBank},
// 6: FPR 512-bit value.
{0, 512, AArch64::FPRRegBank}};
// 4: FPR 512-bit value.
{0, 512, AArch64::FPRRegBank},
// 5: GPR 32-bit value.
{0, 32, AArch64::GPRRegBank},
// 6: GPR 64-bit value.
{0, 64, AArch64::GPRRegBank},
};

// ValueMappings.
RegisterBankInfo::ValueMapping AArch64GenRegisterBankInfo::ValMappings[]{
/* BreakDown, NumBreakDowns */
// 3-operands instructions (all binary operations should end up with one of
// those mapping).
// 0: GPR 32-bit value. <-- This must match First3OpsIdx.
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1},
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1},
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1},
// 3: GPR 64-bit value.
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1},
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1},
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1},
// 6: FPR 32-bit value.
// 0: FPR 32-bit value. <-- This must match First3OpsIdx.
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1},
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1},
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1},
// 9: FPR 64-bit value.
// 3: FPR 64-bit value.
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
// 12: FPR 128-bit value.
// 6: FPR 128-bit value.
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR128 - PMI_Min], 1},
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR128 - PMI_Min], 1},
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR128 - PMI_Min], 1},
// 15: FPR 256-bit value.
// 9: FPR 256-bit value.
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR256 - PMI_Min], 1},
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR256 - PMI_Min], 1},
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR256 - PMI_Min], 1},
// 18: FPR 512-bit value. <-- This must match Last3OpsIdx.
// 12: FPR 512-bit value.
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR512 - PMI_Min], 1},
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR512 - PMI_Min], 1},
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR512 - PMI_Min], 1},
// 15: GPR 32-bit value.
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1},
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1},
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1},
// 18: GPR 64-bit value. <-- This must match Last3OpsIdx.
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1},
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1},
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1},
// Cross register bank copies.
// 21: GPR 32-bit value to FPR 32-bit value. <-- This must match
// 21: FPR 32-bit value to GPR 32-bit value. <-- This must match
// FirstCrossRegCpyIdx.
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1},
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1},
// 23: GPR 64-bit value to FPR 64-bit value.
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1},
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1},
// 23: FPR 64-bit value to GPR 64-bit value.
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
// 25: FPR 32-bit value to GPR 32-bit value.
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1},
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1},
// 25: FPR 128-bit value to GPR 128-bit value (invalid)
{nullptr, 1},
{nullptr, 1},
// 27: FPR 256-bit value to GPR 256-bit value (invalid)
{nullptr, 1},
{nullptr, 1},
// 29: FPR 512-bit value to GPR 512-bit value (invalid)
{nullptr, 1},
{nullptr, 1},
// 31: GPR 32-bit value to FPR 32-bit value.
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1},
// 27: FPR 64-bit value to GPR 64-bit value. <-- This must match
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1},
// 33: GPR 64-bit value to FPR 64-bit value. <-- This must match
// LastCrossRegCpyIdx.
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1},
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1}
};

bool AArch64GenRegisterBankInfo::checkPartialMap(unsigned Idx,
Expand Down Expand Up @@ -301,9 +178,9 @@ AArch64GenRegisterBankInfo::getValueMapping(PartialMappingIdx RBIdx,

AArch64GenRegisterBankInfo::PartialMappingIdx
AArch64GenRegisterBankInfo::BankIDToCopyMapIdx[]{
PMI_FirstGPR, // GPR
PMI_FirstFPR, // FPR
PMI_None, // CCR
PMI_FirstFPR, // FPR
PMI_FirstGPR, // GPR
};

const RegisterBankInfo::ValueMapping *
Expand Down
6 changes: 3 additions & 3 deletions llvm/lib/Target/AArch64/AArch64RegisterBankInfo.cpp
Expand Up @@ -21,6 +21,9 @@
#include "llvm/Target/TargetRegisterInfo.h"
#include "llvm/Target/TargetSubtargetInfo.h"

#define GET_TARGET_REGBANK_IMPL
#include "AArch64GenRegisterBank.inc"

// This file will be TableGen'ed at some point.
#include "AArch64GenRegisterBankInfo.def"

Expand All @@ -30,9 +33,6 @@ using namespace llvm;
#error "You shouldn't build this"
#endif

AArch64GenRegisterBankInfo::AArch64GenRegisterBankInfo()
: RegisterBankInfo(RegBanks, AArch64::NumRegisterBanks) {}

AArch64RegisterBankInfo::AArch64RegisterBankInfo(const TargetRegisterInfo &TRI)
: AArch64GenRegisterBankInfo() {
static bool AlreadyInit = false;
Expand Down
29 changes: 11 additions & 18 deletions llvm/lib/Target/AArch64/AArch64RegisterBankInfo.h
Expand Up @@ -16,40 +16,30 @@

#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"

#define GET_REGBANK_DECLARATIONS
#include "AArch64GenRegisterBank.inc"

namespace llvm {

class TargetRegisterInfo;

namespace AArch64 {
enum {
GPRRegBankID = 0, /// General Purpose Registers: W, X.
FPRRegBankID = 1, /// Floating Point/Vector Registers: B, H, S, D, Q.
CCRRegBankID = 2, /// Conditional register: NZCV.
NumRegisterBanks
};
} // End AArch64 namespace.

class AArch64GenRegisterBankInfo : public RegisterBankInfo {
private:
static RegisterBank *RegBanks[];

protected:
AArch64GenRegisterBankInfo();

enum PartialMappingIdx {
PMI_None = -1,
PMI_GPR32 = 1,
PMI_GPR64,
PMI_FPR32,
PMI_FPR32 = 1,
PMI_FPR64,
PMI_FPR128,
PMI_FPR256,
PMI_FPR512,
PMI_GPR32,
PMI_GPR64,
PMI_FirstGPR = PMI_GPR32,
PMI_LastGPR = PMI_GPR64,
PMI_FirstFPR = PMI_FPR32,
PMI_LastFPR = PMI_FPR512,
PMI_Min = PMI_FirstGPR,
PMI_Min = PMI_FirstFPR,
};

static RegisterBankInfo::PartialMapping PartMappings[];
Expand All @@ -61,7 +51,7 @@ class AArch64GenRegisterBankInfo : public RegisterBankInfo {
Last3OpsIdx = 18,
DistanceBetweenRegBanks = 3,
FirstCrossRegCpyIdx = 21,
LastCrossRegCpyIdx = 27,
LastCrossRegCpyIdx = 33,
DistanceBetweenCrossRegCpy = 2
};

Expand Down Expand Up @@ -90,6 +80,9 @@ class AArch64GenRegisterBankInfo : public RegisterBankInfo {
/// register bank with a size of \p Size.
static const RegisterBankInfo::ValueMapping *
getCopyMapping(unsigned DstBankID, unsigned SrcBankID, unsigned Size);

#define GET_TARGET_REGBANK_CLASS
#include "AArch64GenRegisterBank.inc"
};

/// This class provides the information for the target register banks.
Expand Down

0 comments on commit ab8194d

Please sign in to comment.