Commit 4a308ced by John Porto

Subzero. X86. Refactors initRegisterSet.

initRegisterSet() for x8632 and x8664 were both huge. This CL refactors those methods to use a pre-initialized table instead of the result of expanding the x-macros. BUG= R=stichnot@chromium.org Review URL: https://codereview.chromium.org/1546373003 .
parent 53611e2c
......@@ -122,21 +122,21 @@
is64To8,is32To8,is16To8,isTrunc8Rcvr,isAhRcvr, aliases */ \
/* xmm registers */ \
X(Reg_xmm0, 0, "xmm0", Reg_xmm0, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
REGLIST1(RegX8632, xmm0)) \
NO_ALIASES()) \
X(Reg_xmm1, 1, "xmm1", Reg_xmm1, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
REGLIST1(RegX8632, xmm1)) \
NO_ALIASES()) \
X(Reg_xmm2, 2, "xmm2", Reg_xmm2, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
REGLIST1(RegX8632, xmm2)) \
NO_ALIASES()) \
X(Reg_xmm3, 3, "xmm3", Reg_xmm3, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
REGLIST1(RegX8632, xmm3)) \
NO_ALIASES()) \
X(Reg_xmm4, 4, "xmm4", Reg_xmm4, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
REGLIST1(RegX8632, xmm4)) \
NO_ALIASES()) \
X(Reg_xmm5, 5, "xmm5", Reg_xmm5, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
REGLIST1(RegX8632, xmm5)) \
NO_ALIASES()) \
X(Reg_xmm6, 6, "xmm6", Reg_xmm6, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
REGLIST1(RegX8632, xmm6)) \
NO_ALIASES()) \
X(Reg_xmm7, 7, "xmm7", Reg_xmm7, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
REGLIST1(RegX8632, xmm7)) \
NO_ALIASES()) \
/* End of xmm register set */
//#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr,
// isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8,
......
......@@ -212,37 +212,37 @@
is64To8,is32To8,is16To8,isTrunc8Rcvr,isAhRcvr, aliases */ \
/* xmm registers */ \
X(Reg_xmm0, 0, "xmm0", Reg_xmm0, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
REGLIST1(RegX8664, xmm0)) \
NO_ALIASES()) \
X(Reg_xmm1, 1, "xmm1", Reg_xmm1, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
REGLIST1(RegX8664, xmm1)) \
NO_ALIASES()) \
X(Reg_xmm2, 2, "xmm2", Reg_xmm2, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
REGLIST1(RegX8664, xmm2)) \
NO_ALIASES()) \
X(Reg_xmm3, 3, "xmm3", Reg_xmm3, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
REGLIST1(RegX8664, xmm3)) \
NO_ALIASES()) \
X(Reg_xmm4, 4, "xmm4", Reg_xmm4, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
REGLIST1(RegX8664, xmm4)) \
NO_ALIASES()) \
X(Reg_xmm5, 5, "xmm5", Reg_xmm5, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
REGLIST1(RegX8664, xmm5)) \
NO_ALIASES()) \
X(Reg_xmm6, 6, "xmm6", Reg_xmm6, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
REGLIST1(RegX8664, xmm6)) \
NO_ALIASES()) \
X(Reg_xmm7, 7, "xmm7", Reg_xmm7, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
REGLIST1(RegX8664, xmm7)) \
NO_ALIASES()) \
X(Reg_xmm8, 8, "xmm8", Reg_xmm8, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
REGLIST1(RegX8664, xmm8)) \
NO_ALIASES()) \
X(Reg_xmm9, 9, "xmm9", Reg_xmm9, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
REGLIST1(RegX8664, xmm9)) \
NO_ALIASES()) \
X(Reg_xmm10, 10, "xmm10", Reg_xmm10, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
REGLIST1(RegX8664, xmm10)) \
NO_ALIASES()) \
X(Reg_xmm11, 11, "xmm11", Reg_xmm11, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
REGLIST1(RegX8664, xmm11)) \
NO_ALIASES()) \
X(Reg_xmm12, 12, "xmm12", Reg_xmm12, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
REGLIST1(RegX8664, xmm12)) \
NO_ALIASES()) \
X(Reg_xmm13, 13, "xmm13", Reg_xmm13, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
REGLIST1(RegX8664, xmm13)) \
NO_ALIASES()) \
X(Reg_xmm14, 14, "xmm14", Reg_xmm14, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
REGLIST1(RegX8664, xmm14)) \
NO_ALIASES()) \
X(Reg_xmm15, 15, "xmm15", Reg_xmm15, 1,0,0,0, 0,0,0,0,0, 1, 0,0,0,0,0, \
REGLIST1(RegX8664, xmm15)) \
NO_ALIASES()) \
/* End of xmm register set */
//#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr,
// isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8,
......
......@@ -19,6 +19,8 @@
// indicates how many register aliases are being provided to the macro. It
// assumes the parameters are register names declared in the "ns"
// namespace/class, but with the common "Reg_" prefix removed for brevity.
#define NO_ALIASES() \
{}
#define REGLIST1(ns, r0) \
{ ns::Reg_##r0 }
#define REGLIST2(ns, r0, r1) \
......
......@@ -271,7 +271,7 @@ template <> struct MachineTraits<TargetX8632> {
static constexpr Type WordType = IceType_i32;
static IceString getRegName(int32_t RegNum) {
static const char *const RegNames[] = {
static const char *const RegNames[RegisterSet::Reg_NUM] = {
#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \
isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \
isTrunc8Rcvr, isAhRcvr, aliases) \
......@@ -285,7 +285,7 @@ template <> struct MachineTraits<TargetX8632> {
}
static GPRRegister getEncodedGPR(int32_t RegNum) {
static const GPRRegister GPRRegs[] = {
static const GPRRegister GPRRegs[RegisterSet::Reg_NUM] = {
#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \
isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \
isTrunc8Rcvr, isAhRcvr, aliases) \
......@@ -300,7 +300,7 @@ template <> struct MachineTraits<TargetX8632> {
}
static ByteRegister getEncodedByteReg(int32_t RegNum) {
static const ByteRegister ByteRegs[] = {
static const ByteRegister ByteRegs[RegisterSet::Reg_NUM] = {
#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \
isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \
isTrunc8Rcvr, isAhRcvr, aliases) \
......@@ -315,7 +315,7 @@ template <> struct MachineTraits<TargetX8632> {
}
static XmmRegister getEncodedXmm(int32_t RegNum) {
static const XmmRegister XmmRegs[] = {
static const XmmRegister XmmRegs[RegisterSet::Reg_NUM] = {
#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \
isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \
isTrunc8Rcvr, isAhRcvr, aliases) \
......@@ -330,7 +330,7 @@ template <> struct MachineTraits<TargetX8632> {
}
static uint32_t getEncoding(int32_t RegNum) {
static const uint32_t Encoding[] = {
static const uint32_t Encoding[RegisterSet::Reg_NUM] = {
#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \
isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \
isTrunc8Rcvr, isAhRcvr, aliases) \
......@@ -344,7 +344,7 @@ template <> struct MachineTraits<TargetX8632> {
}
static int32_t getBaseReg(int32_t RegNum) {
static const int32_t BaseRegs[] = {
static const int32_t BaseRegs[RegisterSet::Reg_NUM] = {
#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \
isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \
isTrunc8Rcvr, isAhRcvr, aliases) \
......@@ -400,6 +400,34 @@ template <> struct MachineTraits<TargetX8632> {
return RegNum;
}
private:
/// SizeOf is used to obtain the size of an initializer list as a constexpr
/// expression. This is only needed until our C++ library is updated to
/// C++ 14 -- which defines constexpr members to std::initializer_list.
class SizeOf {
SizeOf(const SizeOf &) = delete;
SizeOf &operator=(const SizeOf &) = delete;
public:
constexpr SizeOf() : Size(0) {}
template <typename... T>
explicit constexpr SizeOf(T...)
: Size(__length<T...>::value) {}
constexpr SizeT size() const { return Size; }
private:
template <typename T, typename... U> struct __length {
static constexpr std::size_t value = 1 + __length<U...>::value;
};
template <typename T> struct __length<T> {
static constexpr std::size_t value = 1;
};
const std::size_t Size;
};
public:
static void initRegisterSet(
std::array<llvm::SmallBitVector, RCX86_NUM> *TypeToRegisterSet,
std::array<llvm::SmallBitVector, RegisterSet::Reg_NUM> *RegisterAliases,
......@@ -416,29 +444,58 @@ template <> struct MachineTraits<TargetX8632> {
llvm::SmallBitVector AhRcvrRegisters(RegisterSet::Reg_NUM);
llvm::SmallBitVector InvalidRegisters(RegisterSet::Reg_NUM);
ScratchRegs->resize(RegisterSet::Reg_NUM);
static constexpr struct {
uint16_t Val;
int Is64 : 1;
int Is32 : 1;
int Is16 : 1;
int Is8 : 1;
int IsXmm : 1;
int Is64To8 : 1;
int Is32To8 : 1;
int Is16To8 : 1;
int IsTrunc8Rcvr : 1;
int IsAhRcvr : 1;
int Scratch : 1;
#define NUM_ALIASES_BITS 2
SizeT NumAliases : (NUM_ALIASES_BITS + 1);
uint16_t Aliases[1 << NUM_ALIASES_BITS];
#undef NUM_ALIASES_BITS
} X8632RegTable[RegisterSet::Reg_NUM] = {
#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \
isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \
isTrunc8Rcvr, isAhRcvr, aliases) \
(IntegerRegistersI32)[RegisterSet::val] = is32; \
(IntegerRegistersI16)[RegisterSet::val] = is16; \
(IntegerRegistersI8)[RegisterSet::val] = is8; \
(FloatRegisters)[RegisterSet::val] = isXmm; \
(VectorRegisters)[RegisterSet::val] = isXmm; \
(Trunc64To8Registers)[RegisterSet::val] = is64To8; \
(Trunc32To8Registers)[RegisterSet::val] = is32To8; \
(Trunc16To8Registers)[RegisterSet::val] = is16To8; \
(Trunc8RcvrRegisters)[RegisterSet::val] = isTrunc8Rcvr; \
(AhRcvrRegisters)[RegisterSet::val] = isAhRcvr; \
(*RegisterAliases)[RegisterSet::val].resize(RegisterSet::Reg_NUM); \
for (SizeT RegAlias : aliases) { \
assert(!(*RegisterAliases)[RegisterSet::val][RegAlias] && \
"Duplicate alias for " #val); \
(*RegisterAliases)[RegisterSet::val].set(RegAlias); \
{ \
RegisterSet::val, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \
isTrunc8Rcvr, isAhRcvr, scratch, (SizeOf aliases).size(), aliases, \
} \
(*RegisterAliases)[RegisterSet::val].set(RegisterSet::val); \
(*ScratchRegs)[RegisterSet::val] = scratch;
REGX8632_TABLE;
,
REGX8632_TABLE
#undef X
};
for (SizeT ii = 0; ii < llvm::array_lengthof(X8632RegTable); ++ii) {
const auto &Entry = X8632RegTable[ii];
(IntegerRegistersI32)[Entry.Val] = Entry.Is32;
(IntegerRegistersI16)[Entry.Val] = Entry.Is16;
(IntegerRegistersI8)[Entry.Val] = Entry.Is8;
(FloatRegisters)[Entry.Val] = Entry.IsXmm;
(VectorRegisters)[Entry.Val] = Entry.IsXmm;
(Trunc64To8Registers)[Entry.Val] = Entry.Is64To8;
(Trunc32To8Registers)[Entry.Val] = Entry.Is32To8;
(Trunc16To8Registers)[Entry.Val] = Entry.Is16To8;
(Trunc8RcvrRegisters)[Entry.Val] = Entry.IsTrunc8Rcvr;
(AhRcvrRegisters)[Entry.Val] = Entry.IsAhRcvr;
(*RegisterAliases)[Entry.Val].resize(RegisterSet::Reg_NUM);
for (int J = 0; J < Entry.NumAliases; J++) {
SizeT Alias = Entry.Aliases[J];
assert(!(*RegisterAliases)[Entry.Val][Alias] && "Duplicate alias");
(*RegisterAliases)[Entry.Val].set(Alias);
}
(*RegisterAliases)[Entry.Val].set(Entry.Val);
(*ScratchRegs)[Entry.Val] = Entry.Scratch;
}
(*TypeToRegisterSet)[RC_void] = InvalidRegisters;
(*TypeToRegisterSet)[RC_i1] = IntegerRegistersI8;
......
......@@ -27,6 +27,7 @@
#include "IceTargetLoweringX86RegClass.h"
#include <array>
#include <initializer_list>
namespace Ice {
......@@ -296,7 +297,7 @@ template <> struct MachineTraits<TargetX8664> {
static constexpr Type WordType = IceType_i64;
static IceString getRegName(int32_t RegNum) {
static const char *const RegNames[] = {
static const char *const RegNames[RegisterSet::Reg_NUM] = {
#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \
isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \
isTrunc8Rcvr, isAhRcvr, aliases) \
......@@ -310,7 +311,7 @@ template <> struct MachineTraits<TargetX8664> {
}
static GPRRegister getEncodedGPR(int32_t RegNum) {
static const GPRRegister GPRRegs[] = {
static const GPRRegister GPRRegs[RegisterSet::Reg_NUM] = {
#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \
isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \
isTrunc8Rcvr, isAhRcvr, aliases) \
......@@ -325,7 +326,7 @@ template <> struct MachineTraits<TargetX8664> {
}
static ByteRegister getEncodedByteReg(int32_t RegNum) {
static const ByteRegister ByteRegs[] = {
static const ByteRegister ByteRegs[RegisterSet::Reg_NUM] = {
#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \
isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \
isTrunc8Rcvr, isAhRcvr, aliases) \
......@@ -340,7 +341,7 @@ template <> struct MachineTraits<TargetX8664> {
}
static XmmRegister getEncodedXmm(int32_t RegNum) {
static const XmmRegister XmmRegs[] = {
static const XmmRegister XmmRegs[RegisterSet::Reg_NUM] = {
#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \
isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \
isTrunc8Rcvr, isAhRcvr, aliases) \
......@@ -355,7 +356,7 @@ template <> struct MachineTraits<TargetX8664> {
}
static uint32_t getEncoding(int32_t RegNum) {
static const uint32_t Encoding[] = {
static const uint32_t Encoding[RegisterSet::Reg_NUM] = {
#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \
isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \
isTrunc8Rcvr, isAhRcvr, aliases) \
......@@ -369,7 +370,7 @@ template <> struct MachineTraits<TargetX8664> {
}
static inline int32_t getBaseReg(int32_t RegNum) {
static const int32_t BaseRegs[] = {
static const int32_t BaseRegs[RegisterSet::Reg_NUM] = {
#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \
isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \
isTrunc8Rcvr, isAhRcvr, aliases) \
......@@ -450,6 +451,34 @@ public:
}
}
private:
/// SizeOf is used to obtain the size of an initializer list as a constexpr
/// expression. This is only needed until our C++ library is updated to
/// C++ 14 -- which defines constexpr members to std::initializer_list.
class SizeOf {
SizeOf(const SizeOf &) = delete;
SizeOf &operator=(const SizeOf &) = delete;
public:
constexpr SizeOf() : Size(0) {}
template <typename... T>
explicit constexpr SizeOf(T...)
: Size(__length<T...>::value) {}
constexpr SizeT size() const { return Size; }
private:
template <typename T, typename... U> struct __length {
static constexpr std::size_t value = 1 + __length<U...>::value;
};
template <typename T> struct __length<T> {
static constexpr std::size_t value = 1;
};
const std::size_t Size;
};
public:
static void initRegisterSet(
std::array<llvm::SmallBitVector, RCX86_NUM> *TypeToRegisterSet,
std::array<llvm::SmallBitVector, RegisterSet::Reg_NUM> *RegisterAliases,
......@@ -468,30 +497,58 @@ public:
llvm::SmallBitVector InvalidRegisters(RegisterSet::Reg_NUM);
ScratchRegs->resize(RegisterSet::Reg_NUM);
static constexpr struct {
uint16_t Val;
int Is64 : 1;
int Is32 : 1;
int Is16 : 1;
int Is8 : 1;
int IsXmm : 1;
int Is64To8 : 1;
int Is32To8 : 1;
int Is16To8 : 1;
int IsTrunc8Rcvr : 1;
int IsAhRcvr : 1;
int Scratch : 1;
#define NUM_ALIASES_BITS 2
SizeT NumAliases : (NUM_ALIASES_BITS + 1);
uint16_t Aliases[1 << NUM_ALIASES_BITS];
#undef NUM_ALIASES_BITS
} X8664RegTable[RegisterSet::Reg_NUM] = {
#define X(val, encode, name, base, scratch, preserved, stackptr, frameptr, \
isGPR, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \
isTrunc8Rcvr, isAhRcvr, aliases) \
(IntegerRegistersI64)[RegisterSet::val] = is64; \
(IntegerRegistersI32)[RegisterSet::val] = is32; \
(IntegerRegistersI16)[RegisterSet::val] = is16; \
(IntegerRegistersI8)[RegisterSet::val] = is8; \
(FloatRegisters)[RegisterSet::val] = isXmm; \
(VectorRegisters)[RegisterSet::val] = isXmm; \
(Trunc64To8Registers)[RegisterSet::val] = is64To8; \
(Trunc32To8Registers)[RegisterSet::val] = is32To8; \
(Trunc16To8Registers)[RegisterSet::val] = is16To8; \
(Trunc8RcvrRegisters)[RegisterSet::val] = isTrunc8Rcvr; \
(AhRcvrRegisters)[RegisterSet::val] = isAhRcvr; \
(*RegisterAliases)[RegisterSet::val].resize(RegisterSet::Reg_NUM); \
for (SizeT RegAlias : aliases) { \
assert(!(*RegisterAliases)[RegisterSet::val][RegAlias] && \
"Duplicate alias for " #val); \
(*RegisterAliases)[RegisterSet::val].set(RegAlias); \
{ \
RegisterSet::val, is64, is32, is16, is8, isXmm, is64To8, is32To8, is16To8, \
isTrunc8Rcvr, isAhRcvr, scratch, (SizeOf aliases).size(), aliases, \
} \
(*RegisterAliases)[RegisterSet::val].set(RegisterSet::val); \
(*ScratchRegs)[RegisterSet::val] = scratch;
REGX8664_TABLE;
,
REGX8664_TABLE
#undef X
};
for (SizeT ii = 0; ii < llvm::array_lengthof(X8664RegTable); ++ii) {
const auto &Entry = X8664RegTable[ii];
(IntegerRegistersI64)[Entry.Val] = Entry.Is64;
(IntegerRegistersI32)[Entry.Val] = Entry.Is32;
(IntegerRegistersI16)[Entry.Val] = Entry.Is16;
(IntegerRegistersI8)[Entry.Val] = Entry.Is8;
(FloatRegisters)[Entry.Val] = Entry.IsXmm;
(VectorRegisters)[Entry.Val] = Entry.IsXmm;
(Trunc64To8Registers)[Entry.Val] = Entry.Is64To8;
(Trunc32To8Registers)[Entry.Val] = Entry.Is32To8;
(Trunc16To8Registers)[Entry.Val] = Entry.Is16To8;
(Trunc8RcvrRegisters)[Entry.Val] = Entry.IsTrunc8Rcvr;
(AhRcvrRegisters)[Entry.Val] = Entry.IsAhRcvr;
(*RegisterAliases)[Entry.Val].resize(RegisterSet::Reg_NUM);
for (int J = 0; J < Entry.NumAliases; ++J) {
SizeT Alias = Entry.Aliases[J];
assert(!(*RegisterAliases)[Entry.Val][Alias] && "Duplicate alias");
(*RegisterAliases)[Entry.Val].set(Alias);
}
(*RegisterAliases)[Entry.Val].set(Entry.Val);
(*ScratchRegs)[Entry.Val] = Entry.Scratch;
}
(*TypeToRegisterSet)[RC_void] = InvalidRegisters;
(*TypeToRegisterSet)[RC_i1] = IntegerRegistersI8;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment