forked from OSchip/llvm-project
Re-commit: [globalisel] Tablegen-erate current Register Bank Information
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. Changes since last commit: The new tablegen pass is now correctly guarded by LLVM_BUILD_GLOBAL_ISEL and this should fix the buildbots however it may not be the whole fix. The previous buildbot failures suggest there may be a memory bug lurking that I'm unable to reproduce (including when using asan) or spot in the source. If they re-occur on this commit then I'll need assistance from the bot owners to track it down. Reviewers: t.p.northover, ab, rovka, qcolombet Reviewed By: qcolombet Subscribers: aditya_nandakumar, rengolin, kristof.beyls, vkalintiris, mgorny, dberris, llvm-commits, rovka Differential Revision: https://reviews.llvm.org/D27338 llvm-svn: 292367
This commit is contained in:
parent
df7c6ef96f
commit
517b61cb69
|
@ -42,7 +42,7 @@ private:
|
||||||
|
|
||||||
public:
|
public:
|
||||||
RegisterBank(unsigned ID, const char *Name, unsigned Size,
|
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.
|
/// Get the identifier of this register bank.
|
||||||
unsigned getID() const { return ID; }
|
unsigned getID() const { return ID; }
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -1344,4 +1344,5 @@ include "llvm/Target/TargetSelectionDAG.td"
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
// Pull in the common support for Global ISel generation.
|
// Pull in the common support for Global ISel generation.
|
||||||
//
|
//
|
||||||
|
include "llvm/Target/GlobalISel/RegisterBank.td"
|
||||||
include "llvm/Target/TargetGlobalISel.td"
|
include "llvm/Target/TargetGlobalISel.td"
|
||||||
|
|
|
@ -19,10 +19,11 @@ using namespace llvm;
|
||||||
|
|
||||||
const unsigned RegisterBank::InvalidID = UINT_MAX;
|
const unsigned RegisterBank::InvalidID = UINT_MAX;
|
||||||
|
|
||||||
RegisterBank::RegisterBank(unsigned ID, const char *Name, unsigned Size,
|
RegisterBank::RegisterBank(
|
||||||
const uint32_t *CoveredClasses)
|
unsigned ID, const char *Name, unsigned Size,
|
||||||
|
const uint32_t *CoveredClasses, unsigned NumRegClasses)
|
||||||
: ID(ID), Name(Name), Size(Size) {
|
: ID(ID), Name(Name), Size(Size) {
|
||||||
ContainedRegClasses.resize(200);
|
ContainedRegClasses.resize(NumRegClasses);
|
||||||
ContainedRegClasses.setBitsInMask(CoveredClasses);
|
ContainedRegClasses.setBitsInMask(CoveredClasses);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -127,6 +127,7 @@ def HasV8_2aOps : SubtargetFeature<"v8.2a", "HasV8_2aOps", "true",
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
include "AArch64RegisterInfo.td"
|
include "AArch64RegisterInfo.td"
|
||||||
|
include "AArch64RegisterBanks.td"
|
||||||
include "AArch64CallingConvention.td"
|
include "AArch64CallingConvention.td"
|
||||||
|
|
||||||
//===----------------------------------------------------------------------===//
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
|
@ -16,204 +16,81 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace llvm {
|
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[]{
|
RegisterBankInfo::PartialMapping AArch64GenRegisterBankInfo::PartMappings[]{
|
||||||
/* StartIdx, Length, RegBank */
|
/* StartIdx, Length, RegBank */
|
||||||
// 0: GPR 32-bit value.
|
// 0: FPR 32-bit value.
|
||||||
{0, 32, AArch64::GPRRegBank},
|
|
||||||
// 1: GPR 64-bit value.
|
|
||||||
{0, 64, AArch64::GPRRegBank},
|
|
||||||
// 2: FPR 32-bit value.
|
|
||||||
{0, 32, AArch64::FPRRegBank},
|
{0, 32, AArch64::FPRRegBank},
|
||||||
// 3: FPR 64-bit value.
|
// 1: FPR 64-bit value.
|
||||||
{0, 64, AArch64::FPRRegBank},
|
{0, 64, AArch64::FPRRegBank},
|
||||||
// 4: FPR 128-bit value.
|
// 2: FPR 128-bit value.
|
||||||
{0, 128, AArch64::FPRRegBank},
|
{0, 128, AArch64::FPRRegBank},
|
||||||
// 5: FPR 256-bit value.
|
// 3: FPR 256-bit value.
|
||||||
{0, 256, AArch64::FPRRegBank},
|
{0, 256, AArch64::FPRRegBank},
|
||||||
// 6: FPR 512-bit value.
|
// 4: FPR 512-bit value.
|
||||||
{0, 512, AArch64::FPRRegBank}};
|
{0, 512, AArch64::FPRRegBank},
|
||||||
|
// 5: GPR 32-bit value.
|
||||||
|
{0, 32, AArch64::GPRRegBank},
|
||||||
|
// 6: GPR 64-bit value.
|
||||||
|
{0, 64, AArch64::GPRRegBank},
|
||||||
|
};
|
||||||
|
|
||||||
// ValueMappings.
|
// ValueMappings.
|
||||||
RegisterBankInfo::ValueMapping AArch64GenRegisterBankInfo::ValMappings[]{
|
RegisterBankInfo::ValueMapping AArch64GenRegisterBankInfo::ValMappings[]{
|
||||||
/* BreakDown, NumBreakDowns */
|
/* BreakDown, NumBreakDowns */
|
||||||
// 3-operands instructions (all binary operations should end up with one of
|
// 3-operands instructions (all binary operations should end up with one of
|
||||||
// those mapping).
|
// those mapping).
|
||||||
// 0: GPR 32-bit value. <-- This must match First3OpsIdx.
|
// 0: FPR 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.
|
|
||||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1},
|
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1},
|
||||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1},
|
{&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},
|
{&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},
|
{&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},
|
{&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},
|
{&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.
|
// 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.
|
// FirstCrossRegCpyIdx.
|
||||||
|
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - 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},
|
||||||
|
{&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},
|
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR32 - PMI_Min], 1},
|
||||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1},
|
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR32 - PMI_Min], 1},
|
||||||
// 23: GPR 64-bit value to FPR 64-bit value.
|
// 33: GPR 64-bit value to FPR 64-bit value. <-- This must match
|
||||||
|
// LastCrossRegCpyIdx.
|
||||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1},
|
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1},
|
||||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
|
{&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_GPR32 - PMI_Min], 1},
|
|
||||||
// 27: FPR 64-bit value to GPR 64-bit value. <-- This must match
|
|
||||||
// LastCrossRegCpyIdx.
|
|
||||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_FPR64 - PMI_Min], 1},
|
|
||||||
{&AArch64GenRegisterBankInfo::PartMappings[PMI_GPR64 - PMI_Min], 1}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
bool AArch64GenRegisterBankInfo::checkPartialMap(unsigned Idx,
|
bool AArch64GenRegisterBankInfo::checkPartialMap(unsigned Idx,
|
||||||
|
@ -301,9 +178,9 @@ AArch64GenRegisterBankInfo::getValueMapping(PartialMappingIdx RBIdx,
|
||||||
|
|
||||||
AArch64GenRegisterBankInfo::PartialMappingIdx
|
AArch64GenRegisterBankInfo::PartialMappingIdx
|
||||||
AArch64GenRegisterBankInfo::BankIDToCopyMapIdx[]{
|
AArch64GenRegisterBankInfo::BankIDToCopyMapIdx[]{
|
||||||
PMI_FirstGPR, // GPR
|
|
||||||
PMI_FirstFPR, // FPR
|
|
||||||
PMI_None, // CCR
|
PMI_None, // CCR
|
||||||
|
PMI_FirstFPR, // FPR
|
||||||
|
PMI_FirstGPR, // GPR
|
||||||
};
|
};
|
||||||
|
|
||||||
const RegisterBankInfo::ValueMapping *
|
const RegisterBankInfo::ValueMapping *
|
||||||
|
|
|
@ -21,6 +21,9 @@
|
||||||
#include "llvm/Target/TargetRegisterInfo.h"
|
#include "llvm/Target/TargetRegisterInfo.h"
|
||||||
#include "llvm/Target/TargetSubtargetInfo.h"
|
#include "llvm/Target/TargetSubtargetInfo.h"
|
||||||
|
|
||||||
|
#define GET_TARGET_REGBANK_IMPL
|
||||||
|
#include "AArch64GenRegisterBank.inc"
|
||||||
|
|
||||||
// This file will be TableGen'ed at some point.
|
// This file will be TableGen'ed at some point.
|
||||||
#include "AArch64GenRegisterBankInfo.def"
|
#include "AArch64GenRegisterBankInfo.def"
|
||||||
|
|
||||||
|
@ -30,9 +33,6 @@ using namespace llvm;
|
||||||
#error "You shouldn't build this"
|
#error "You shouldn't build this"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
AArch64GenRegisterBankInfo::AArch64GenRegisterBankInfo()
|
|
||||||
: RegisterBankInfo(RegBanks, AArch64::NumRegisterBanks) {}
|
|
||||||
|
|
||||||
AArch64RegisterBankInfo::AArch64RegisterBankInfo(const TargetRegisterInfo &TRI)
|
AArch64RegisterBankInfo::AArch64RegisterBankInfo(const TargetRegisterInfo &TRI)
|
||||||
: AArch64GenRegisterBankInfo() {
|
: AArch64GenRegisterBankInfo() {
|
||||||
static bool AlreadyInit = false;
|
static bool AlreadyInit = false;
|
||||||
|
|
|
@ -16,40 +16,30 @@
|
||||||
|
|
||||||
#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
|
#include "llvm/CodeGen/GlobalISel/RegisterBankInfo.h"
|
||||||
|
|
||||||
|
#define GET_REGBANK_DECLARATIONS
|
||||||
|
#include "AArch64GenRegisterBank.inc"
|
||||||
|
|
||||||
namespace llvm {
|
namespace llvm {
|
||||||
|
|
||||||
class TargetRegisterInfo;
|
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 {
|
class AArch64GenRegisterBankInfo : public RegisterBankInfo {
|
||||||
private:
|
|
||||||
static RegisterBank *RegBanks[];
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
AArch64GenRegisterBankInfo();
|
|
||||||
|
|
||||||
enum PartialMappingIdx {
|
enum PartialMappingIdx {
|
||||||
PMI_None = -1,
|
PMI_None = -1,
|
||||||
PMI_GPR32 = 1,
|
PMI_FPR32 = 1,
|
||||||
PMI_GPR64,
|
|
||||||
PMI_FPR32,
|
|
||||||
PMI_FPR64,
|
PMI_FPR64,
|
||||||
PMI_FPR128,
|
PMI_FPR128,
|
||||||
PMI_FPR256,
|
PMI_FPR256,
|
||||||
PMI_FPR512,
|
PMI_FPR512,
|
||||||
|
PMI_GPR32,
|
||||||
|
PMI_GPR64,
|
||||||
PMI_FirstGPR = PMI_GPR32,
|
PMI_FirstGPR = PMI_GPR32,
|
||||||
PMI_LastGPR = PMI_GPR64,
|
PMI_LastGPR = PMI_GPR64,
|
||||||
PMI_FirstFPR = PMI_FPR32,
|
PMI_FirstFPR = PMI_FPR32,
|
||||||
PMI_LastFPR = PMI_FPR512,
|
PMI_LastFPR = PMI_FPR512,
|
||||||
PMI_Min = PMI_FirstGPR,
|
PMI_Min = PMI_FirstFPR,
|
||||||
};
|
};
|
||||||
|
|
||||||
static RegisterBankInfo::PartialMapping PartMappings[];
|
static RegisterBankInfo::PartialMapping PartMappings[];
|
||||||
|
@ -61,7 +51,7 @@ protected:
|
||||||
Last3OpsIdx = 18,
|
Last3OpsIdx = 18,
|
||||||
DistanceBetweenRegBanks = 3,
|
DistanceBetweenRegBanks = 3,
|
||||||
FirstCrossRegCpyIdx = 21,
|
FirstCrossRegCpyIdx = 21,
|
||||||
LastCrossRegCpyIdx = 27,
|
LastCrossRegCpyIdx = 33,
|
||||||
DistanceBetweenCrossRegCpy = 2
|
DistanceBetweenCrossRegCpy = 2
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -90,6 +80,9 @@ protected:
|
||||||
/// register bank with a size of \p Size.
|
/// register bank with a size of \p Size.
|
||||||
static const RegisterBankInfo::ValueMapping *
|
static const RegisterBankInfo::ValueMapping *
|
||||||
getCopyMapping(unsigned DstBankID, unsigned SrcBankID, unsigned Size);
|
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.
|
/// This class provides the information for the target register banks.
|
||||||
|
|
|
@ -0,0 +1,20 @@
|
||||||
|
//=- AArch64RegisterBank.td - Describe the AArch64 Banks -----*- tablegen -*-=//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is distributed under the University of Illinois Open Source
|
||||||
|
// License. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
/// General Purpose Registers: W, X.
|
||||||
|
def GPRRegBank : RegisterBank<"GPR", [GPR64all]>;
|
||||||
|
|
||||||
|
/// Floating Point/Vector Registers: B, H, S, D, Q.
|
||||||
|
def FPRRegBank : RegisterBank<"FPR", [QQQQ]>;
|
||||||
|
|
||||||
|
/// Conditional register: NZCV.
|
||||||
|
def CCRRegBank : RegisterBank<"CCR", [CCR]>;
|
|
@ -14,6 +14,7 @@ tablegen(LLVM AArch64GenSubtargetInfo.inc -gen-subtarget)
|
||||||
tablegen(LLVM AArch64GenDisassemblerTables.inc -gen-disassembler)
|
tablegen(LLVM AArch64GenDisassemblerTables.inc -gen-disassembler)
|
||||||
tablegen(LLVM AArch64GenSystemOperands.inc -gen-searchable-tables)
|
tablegen(LLVM AArch64GenSystemOperands.inc -gen-searchable-tables)
|
||||||
if(LLVM_BUILD_GLOBAL_ISEL)
|
if(LLVM_BUILD_GLOBAL_ISEL)
|
||||||
|
tablegen(LLVM AArch64GenRegisterBank.inc -gen-register-bank)
|
||||||
tablegen(LLVM AArch64GenGlobalISel.inc -gen-global-isel)
|
tablegen(LLVM AArch64GenGlobalISel.inc -gen-global-isel)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,9 @@ const uint32_t GPRCoverageData[] = {
|
||||||
0,
|
0,
|
||||||
};
|
};
|
||||||
|
|
||||||
RegisterBank GPRRegBank(ARM::GPRRegBankID, "GPRB", 32, ARM::GPRCoverageData);
|
// FIXME: The 200 will be replaced by the number of register classes when this is
|
||||||
|
// tablegenerated.
|
||||||
|
RegisterBank GPRRegBank(ARM::GPRRegBankID, "GPRB", 32, ARM::GPRCoverageData, 200);
|
||||||
RegisterBank *RegBanks[] = {&GPRRegBank};
|
RegisterBank *RegBanks[] = {&GPRRegBank};
|
||||||
|
|
||||||
RegisterBankInfo::PartialMapping GPRPartialMapping{0, 32, GPRRegBank};
|
RegisterBankInfo::PartialMapping GPRPartialMapping{0, 32, GPRRegBank};
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
|
@ -27,6 +27,7 @@ add_tablegen(llvm-tblgen LLVM
|
||||||
IntrinsicEmitter.cpp
|
IntrinsicEmitter.cpp
|
||||||
OptParserEmitter.cpp
|
OptParserEmitter.cpp
|
||||||
PseudoLoweringEmitter.cpp
|
PseudoLoweringEmitter.cpp
|
||||||
|
RegisterBankEmitter.cpp
|
||||||
RegisterInfoEmitter.cpp
|
RegisterInfoEmitter.cpp
|
||||||
SearchableTableEmitter.cpp
|
SearchableTableEmitter.cpp
|
||||||
SubtargetEmitter.cpp
|
SubtargetEmitter.cpp
|
||||||
|
|
|
@ -0,0 +1,309 @@
|
||||||
|
//===- RegisterBankEmitter.cpp - Generate a Register Bank Desc. -*- C++ -*-===//
|
||||||
|
//
|
||||||
|
// The LLVM Compiler Infrastructure
|
||||||
|
//
|
||||||
|
// This file is distributed under the University of Illinois Open Source
|
||||||
|
// License. See LICENSE.TXT for details.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
//
|
||||||
|
// This tablegen backend is responsible for emitting a description of a target
|
||||||
|
// register bank for a code generator.
|
||||||
|
//
|
||||||
|
//===----------------------------------------------------------------------===//
|
||||||
|
|
||||||
|
#include "llvm/ADT/BitVector.h"
|
||||||
|
#include "llvm/Support/Debug.h"
|
||||||
|
#include "llvm/TableGen/Error.h"
|
||||||
|
#include "llvm/TableGen/Record.h"
|
||||||
|
#include "llvm/TableGen/TableGenBackend.h"
|
||||||
|
|
||||||
|
#include "CodeGenRegisters.h"
|
||||||
|
|
||||||
|
#define DEBUG_TYPE "register-bank-emitter"
|
||||||
|
|
||||||
|
using namespace llvm;
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
class RegisterBank {
|
||||||
|
|
||||||
|
/// A vector of register classes that are included in the register bank.
|
||||||
|
typedef std::vector<const CodeGenRegisterClass *> RegisterClassesTy;
|
||||||
|
|
||||||
|
private:
|
||||||
|
const Record &TheDef;
|
||||||
|
|
||||||
|
/// The register classes that are covered by the register bank.
|
||||||
|
RegisterClassesTy RCs;
|
||||||
|
|
||||||
|
/// The register class with the largest register size.
|
||||||
|
const CodeGenRegisterClass *RCWithLargestRegsSize;
|
||||||
|
|
||||||
|
public:
|
||||||
|
RegisterBank(const Record &TheDef)
|
||||||
|
: TheDef(TheDef), RCs(), RCWithLargestRegsSize(nullptr) {}
|
||||||
|
|
||||||
|
/// Get the human-readable name for the bank.
|
||||||
|
std::string getName() const { return TheDef.getValueAsString("Name"); }
|
||||||
|
/// Get the name of the enumerator in the ID enumeration.
|
||||||
|
std::string getEnumeratorName() const { return (TheDef.getName() + "ID").str(); }
|
||||||
|
|
||||||
|
/// Get the name of the array holding the register class coverage data;
|
||||||
|
std::string getCoverageArrayName() const {
|
||||||
|
return (TheDef.getName() + "CoverageData").str();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Get the name of the global instance variable.
|
||||||
|
StringRef getInstanceVarName() const { return TheDef.getName(); }
|
||||||
|
|
||||||
|
const Record &getDef() const { return TheDef; }
|
||||||
|
|
||||||
|
/// Get the register classes listed in the RegisterBank.RegisterClasses field.
|
||||||
|
std::vector<const CodeGenRegisterClass *>
|
||||||
|
getExplictlySpecifiedRegisterClasses(
|
||||||
|
CodeGenRegBank &RegisterClassHierarchy) const {
|
||||||
|
std::vector<const CodeGenRegisterClass *> RCs;
|
||||||
|
for (const auto &RCDef : getDef().getValueAsListOfDefs("RegisterClasses"))
|
||||||
|
RCs.push_back(RegisterClassHierarchy.getRegClass(RCDef));
|
||||||
|
return RCs;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Add a register class to the bank without duplicates.
|
||||||
|
void addRegisterClass(const CodeGenRegisterClass *RC) {
|
||||||
|
if (std::find_if(RCs.begin(), RCs.end(),
|
||||||
|
[&RC](const CodeGenRegisterClass *X) {
|
||||||
|
return X == RC;
|
||||||
|
}) != RCs.end())
|
||||||
|
return;
|
||||||
|
|
||||||
|
// FIXME? We really want the register size rather than the spill size
|
||||||
|
// since the spill size may be bigger on some targets with
|
||||||
|
// limited load/store instructions. However, we don't store the
|
||||||
|
// register size anywhere (we could sum the sizes of the subregisters
|
||||||
|
// but there may be additional bits too) and we can't derive it from
|
||||||
|
// the VT's reliably due to Untyped.
|
||||||
|
if (RCWithLargestRegsSize == nullptr)
|
||||||
|
RCWithLargestRegsSize = RC;
|
||||||
|
else if (RCWithLargestRegsSize->SpillSize < RC->SpillSize)
|
||||||
|
RCWithLargestRegsSize = RC;
|
||||||
|
assert(RCWithLargestRegsSize && "RC was nullptr?");
|
||||||
|
|
||||||
|
RCs.emplace_back(RC);
|
||||||
|
}
|
||||||
|
|
||||||
|
const CodeGenRegisterClass *getRCWithLargestRegsSize() const {
|
||||||
|
return RCWithLargestRegsSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
iterator_range<typename RegisterClassesTy::const_iterator>
|
||||||
|
register_classes() const {
|
||||||
|
return llvm::make_range(RCs.begin(), RCs.end());
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
class RegisterBankEmitter {
|
||||||
|
private:
|
||||||
|
RecordKeeper &Records;
|
||||||
|
CodeGenRegBank RegisterClassHierarchy;
|
||||||
|
|
||||||
|
void emitHeader(raw_ostream &OS, const StringRef TargetName,
|
||||||
|
const std::vector<RegisterBank> &Banks);
|
||||||
|
void emitBaseClassDefinition(raw_ostream &OS, const StringRef TargetName,
|
||||||
|
const std::vector<RegisterBank> &Banks);
|
||||||
|
void emitBaseClassImplementation(raw_ostream &OS, const StringRef TargetName,
|
||||||
|
std::vector<RegisterBank> &Banks);
|
||||||
|
|
||||||
|
public:
|
||||||
|
RegisterBankEmitter(RecordKeeper &R)
|
||||||
|
: Records(R), RegisterClassHierarchy(Records) {}
|
||||||
|
|
||||||
|
void run(raw_ostream &OS);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // end anonymous namespace
|
||||||
|
|
||||||
|
/// Emit code to declare the ID enumeration and external global instance
|
||||||
|
/// variables.
|
||||||
|
void RegisterBankEmitter::emitHeader(raw_ostream &OS,
|
||||||
|
const StringRef TargetName,
|
||||||
|
const std::vector<RegisterBank> &Banks) {
|
||||||
|
// <Target>RegisterBankInfo.h
|
||||||
|
OS << "namespace llvm {\n"
|
||||||
|
<< "namespace " << TargetName << " {\n"
|
||||||
|
<< "enum {\n";
|
||||||
|
for (const auto &Bank : Banks)
|
||||||
|
OS << " " << Bank.getEnumeratorName() << ",\n";
|
||||||
|
OS << " NumRegisterBanks,\n"
|
||||||
|
<< "};\n"
|
||||||
|
<< "} // end namespace " << TargetName << "\n"
|
||||||
|
<< "} // end namespace llvm\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Emit declarations of the <Target>GenRegisterBankInfo class.
|
||||||
|
void RegisterBankEmitter::emitBaseClassDefinition(
|
||||||
|
raw_ostream &OS, const StringRef TargetName,
|
||||||
|
const std::vector<RegisterBank> &Banks) {
|
||||||
|
OS << "private:\n"
|
||||||
|
<< " static RegisterBank *RegBanks[];\n\n"
|
||||||
|
<< "protected:\n"
|
||||||
|
<< " " << TargetName << "GenRegisterBankInfo();\n"
|
||||||
|
<< "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Visit each register class belonging to the given register bank.
|
||||||
|
///
|
||||||
|
/// A class belongs to the bank iff any of these apply:
|
||||||
|
/// * It is explicitly specified
|
||||||
|
/// * It is a subclass of a class that is a member.
|
||||||
|
/// * It is a class containing subregisters of the registers of a class that
|
||||||
|
/// is a member. This is known as a subreg-class.
|
||||||
|
///
|
||||||
|
/// This function must be called for each explicitly specified register class.
|
||||||
|
///
|
||||||
|
/// \param RC The register class to search.
|
||||||
|
/// \param Kind A debug string containing the path the visitor took to reach RC.
|
||||||
|
/// \param VisitFn The action to take for each class visited. It may be called
|
||||||
|
/// multiple times for a given class if there are multiple paths
|
||||||
|
/// to the class.
|
||||||
|
static void visitRegisterBankClasses(
|
||||||
|
CodeGenRegBank &RegisterClassHierarchy, const CodeGenRegisterClass *RC,
|
||||||
|
const Twine Kind,
|
||||||
|
std::function<void(const CodeGenRegisterClass *, StringRef)> VisitFn) {
|
||||||
|
// Visit each explicitly named class.
|
||||||
|
VisitFn(RC, Kind.str());
|
||||||
|
|
||||||
|
for (const auto &PossibleSubclass : RegisterClassHierarchy.getRegClasses()) {
|
||||||
|
Twine TmpKind = Kind + " (" + PossibleSubclass.getName() + ")";
|
||||||
|
|
||||||
|
// Visit each subclass of an explicitly named class.
|
||||||
|
if (RC != &PossibleSubclass && RC->hasSubClass(&PossibleSubclass))
|
||||||
|
visitRegisterBankClasses(RegisterClassHierarchy, &PossibleSubclass,
|
||||||
|
TmpKind + " " + RC->getName() + " subclass",
|
||||||
|
VisitFn);
|
||||||
|
|
||||||
|
// Visit each class that contains only subregisters of RC with a common
|
||||||
|
// subregister-index.
|
||||||
|
//
|
||||||
|
// More precisely, PossibleSubclass is a subreg-class iff Reg:SubIdx is in
|
||||||
|
// PossibleSubclass for all registers Reg from RC using any
|
||||||
|
// subregister-index SubReg
|
||||||
|
for (const auto &SubIdx : RegisterClassHierarchy.getSubRegIndices()) {
|
||||||
|
BitVector BV(RegisterClassHierarchy.getRegClasses().size());
|
||||||
|
PossibleSubclass.getSuperRegClasses(&SubIdx, BV);
|
||||||
|
if (BV.test(RC->EnumValue)) {
|
||||||
|
Twine TmpKind2 = TmpKind + " " + RC->getName() +
|
||||||
|
" class-with-subregs: " + RC->getName();
|
||||||
|
VisitFn(&PossibleSubclass, TmpKind2.str());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterBankEmitter::emitBaseClassImplementation(
|
||||||
|
raw_ostream &OS, StringRef TargetName,
|
||||||
|
std::vector<RegisterBank> &Banks) {
|
||||||
|
|
||||||
|
OS << "namespace llvm {\n"
|
||||||
|
<< "namespace " << TargetName << " {\n";
|
||||||
|
for (const auto &Bank : Banks) {
|
||||||
|
std::vector<std::vector<const CodeGenRegisterClass *>> RCsGroupedByWord(
|
||||||
|
(RegisterClassHierarchy.getRegClasses().size() + 31) / 32);
|
||||||
|
|
||||||
|
for (const auto &RC : Bank.register_classes())
|
||||||
|
RCsGroupedByWord[RC->EnumValue / 32].push_back(RC);
|
||||||
|
|
||||||
|
OS << "const uint32_t " << Bank.getCoverageArrayName() << "[] = {\n";
|
||||||
|
unsigned LowestIdxInWord = 0;
|
||||||
|
for (const auto &RCs : RCsGroupedByWord) {
|
||||||
|
OS << " // " << LowestIdxInWord << "-" << (LowestIdxInWord + 31) << "\n";
|
||||||
|
for (const auto &RC : RCs) {
|
||||||
|
Twine QualifiedRegClassID =
|
||||||
|
TargetName + "::" + RC->getName() + "RegClassID";
|
||||||
|
OS << " (1u << (" << QualifiedRegClassID << " - "
|
||||||
|
<< LowestIdxInWord << ")) |\n";
|
||||||
|
}
|
||||||
|
OS << " 0,\n";
|
||||||
|
LowestIdxInWord += 32;
|
||||||
|
}
|
||||||
|
OS << "};\n";
|
||||||
|
}
|
||||||
|
OS << "\n";
|
||||||
|
|
||||||
|
for (const auto &Bank : Banks) {
|
||||||
|
Twine QualifiedBankID = TargetName + "::" + Bank.getEnumeratorName();
|
||||||
|
unsigned Size = Bank.getRCWithLargestRegsSize()->SpillSize;
|
||||||
|
OS << "RegisterBank " << Bank.getInstanceVarName() << "(/* ID */ "
|
||||||
|
<< QualifiedBankID << ", /* Name */ \"" << Bank.getName()
|
||||||
|
<< "\", /* Size */ " << Size << ", "
|
||||||
|
<< "/* CoveredRegClasses */ " << Bank.getCoverageArrayName()
|
||||||
|
<< ", /* NumRegClasses */ "
|
||||||
|
<< RegisterClassHierarchy.getRegClasses().size() << ");\n";
|
||||||
|
}
|
||||||
|
OS << "} // end namespace " << TargetName << "\n"
|
||||||
|
<< "\n";
|
||||||
|
|
||||||
|
OS << "RegisterBank *" << TargetName
|
||||||
|
<< "GenRegisterBankInfo::RegBanks[] = {\n";
|
||||||
|
for (const auto &Bank : Banks)
|
||||||
|
OS << " &" << TargetName << "::" << Bank.getInstanceVarName() << ",\n";
|
||||||
|
OS << "};\n\n";
|
||||||
|
|
||||||
|
OS << TargetName << "GenRegisterBankInfo::" << TargetName
|
||||||
|
<< "GenRegisterBankInfo()\n"
|
||||||
|
<< " : RegisterBankInfo(RegBanks, " << TargetName
|
||||||
|
<< "::NumRegisterBanks) {\n"
|
||||||
|
<< " // Assert that RegBank indices match their ID's\n"
|
||||||
|
<< " unsigned Index = 0;\n"
|
||||||
|
<< "#ifndef NDEBUG\n"
|
||||||
|
<< " for (const auto &RB : RegBanks)\n"
|
||||||
|
<< " assert(Index++ == RB->getID() && \"Index != ID\");\n"
|
||||||
|
<< "#endif // NDEBUG\n"
|
||||||
|
<< "}\n"
|
||||||
|
<< "} // end namespace llvm\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
void RegisterBankEmitter::run(raw_ostream &OS) {
|
||||||
|
std::vector<Record*> Targets = Records.getAllDerivedDefinitions("Target");
|
||||||
|
if (Targets.size() != 1)
|
||||||
|
PrintFatalError("ERROR: Too many or too few subclasses of Target defined!");
|
||||||
|
StringRef TargetName = Targets[0]->getName();
|
||||||
|
|
||||||
|
std::vector<RegisterBank> Banks;
|
||||||
|
for (const auto &V : Records.getAllDerivedDefinitions("RegisterBank")) {
|
||||||
|
RegisterBank Bank(*V);
|
||||||
|
|
||||||
|
for (const CodeGenRegisterClass *RC :
|
||||||
|
Bank.getExplictlySpecifiedRegisterClasses(RegisterClassHierarchy)) {
|
||||||
|
visitRegisterBankClasses(
|
||||||
|
RegisterClassHierarchy, RC, "explicit",
|
||||||
|
[&Bank](const CodeGenRegisterClass *RC, StringRef Kind) {
|
||||||
|
DEBUG(dbgs() << "Added " << RC->getName() << "(" << Kind << ")\n");
|
||||||
|
Bank.addRegisterClass(RC);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
Banks.push_back(Bank);
|
||||||
|
}
|
||||||
|
|
||||||
|
emitSourceFileHeader("Register Bank Source Fragments", OS);
|
||||||
|
OS << "#ifdef GET_REGBANK_DECLARATIONS\n"
|
||||||
|
<< "#undef GET_REGBANK_DECLARATIONS\n";
|
||||||
|
emitHeader(OS, TargetName, Banks);
|
||||||
|
OS << "#endif // GET_REGBANK_DECLARATIONS\n\n"
|
||||||
|
<< "#ifdef GET_TARGET_REGBANK_CLASS\n"
|
||||||
|
<< "#undef GET_TARGET_REGBANK_CLASS\n";
|
||||||
|
emitBaseClassDefinition(OS, TargetName, Banks);
|
||||||
|
OS << "#endif // GET_TARGET_REGBANK_CLASS\n\n"
|
||||||
|
<< "#ifdef GET_TARGET_REGBANK_IMPL\n"
|
||||||
|
<< "#undef GET_TARGET_REGBANK_IMPL\n";
|
||||||
|
emitBaseClassImplementation(OS, TargetName, Banks);
|
||||||
|
OS << "#endif // GET_TARGET_REGBANK_IMPL\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace llvm {
|
||||||
|
|
||||||
|
void EmitRegisterBank(RecordKeeper &RK, raw_ostream &OS) {
|
||||||
|
RegisterBankEmitter(RK).run(OS);
|
||||||
|
}
|
||||||
|
|
||||||
|
} // end namespace llvm
|
|
@ -46,6 +46,7 @@ enum ActionType {
|
||||||
GenAttributes,
|
GenAttributes,
|
||||||
GenSearchableTables,
|
GenSearchableTables,
|
||||||
GenGlobalISel,
|
GenGlobalISel,
|
||||||
|
GenRegisterBank,
|
||||||
};
|
};
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
@ -94,7 +95,9 @@ namespace {
|
||||||
clEnumValN(GenSearchableTables, "gen-searchable-tables",
|
clEnumValN(GenSearchableTables, "gen-searchable-tables",
|
||||||
"Generate generic binary-searchable table"),
|
"Generate generic binary-searchable table"),
|
||||||
clEnumValN(GenGlobalISel, "gen-global-isel",
|
clEnumValN(GenGlobalISel, "gen-global-isel",
|
||||||
"Generate GlobalISel selector")));
|
"Generate GlobalISel selector"),
|
||||||
|
clEnumValN(GenRegisterBank, "gen-register-bank",
|
||||||
|
"Generate registers bank descriptions")));
|
||||||
|
|
||||||
cl::opt<std::string>
|
cl::opt<std::string>
|
||||||
Class("class", cl::desc("Print Enum list for this class"),
|
Class("class", cl::desc("Print Enum list for this class"),
|
||||||
|
@ -182,6 +185,8 @@ bool LLVMTableGenMain(raw_ostream &OS, RecordKeeper &Records) {
|
||||||
break;
|
break;
|
||||||
case GenGlobalISel:
|
case GenGlobalISel:
|
||||||
EmitGlobalISel(Records, OS);
|
EmitGlobalISel(Records, OS);
|
||||||
|
case GenRegisterBank:
|
||||||
|
EmitRegisterBank(Records, OS);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -81,6 +81,7 @@ void EmitCTags(RecordKeeper &RK, raw_ostream &OS);
|
||||||
void EmitAttributes(RecordKeeper &RK, raw_ostream &OS);
|
void EmitAttributes(RecordKeeper &RK, raw_ostream &OS);
|
||||||
void EmitSearchableTables(RecordKeeper &RK, raw_ostream &OS);
|
void EmitSearchableTables(RecordKeeper &RK, raw_ostream &OS);
|
||||||
void EmitGlobalISel(RecordKeeper &RK, raw_ostream &OS);
|
void EmitGlobalISel(RecordKeeper &RK, raw_ostream &OS);
|
||||||
|
void EmitRegisterBank(RecordKeeper &RK, raw_ostream &OS);
|
||||||
|
|
||||||
} // End llvm namespace
|
} // End llvm namespace
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue