arch,cpu,gpu-compute: Further simplify VecRegContainer.

Get rid of VecRegT, and a few redundant or unused methods.

Change-Id: I6c88c40653e1939fe74b8ffb847ef50ab8064670
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/41995
Reviewed-by: Gabe Black <gabe.black@gmail.com>
Maintainer: Gabe Black <gabe.black@gmail.com>
Tested-by: kokoro <noreply+kokoro@google.com>
This commit is contained in:
Gabe Black
2021-02-26 00:07:14 -08:00
parent 0e455475c8
commit 0dade68dae
17 changed files with 60 additions and 218 deletions

View File

@@ -174,33 +174,8 @@ namespace Gcn3ISA
*/
const int RegSizeDWords = sizeof(VecElemU32) / DWordSize;
// typedefs for the various sizes/types of vector regs
using VecRegU8 = ::VecRegT<VecElemU8, NumVecElemPerVecReg, false>;
using VecRegI8 = ::VecRegT<VecElemI8, NumVecElemPerVecReg, false>;
using VecRegU16 = ::VecRegT<VecElemU16, NumVecElemPerVecReg, false>;
using VecRegI16 = ::VecRegT<VecElemI16, NumVecElemPerVecReg, false>;
using VecRegU32 = ::VecRegT<VecElemU32, NumVecElemPerVecReg, false>;
using VecRegI32 = ::VecRegT<VecElemI32, NumVecElemPerVecReg, false>;
using VecRegF32 = ::VecRegT<VecElemF32, NumVecElemPerVecReg, false>;
using VecRegU64 = ::VecRegT<VecElemU64, NumVecElemPerVecReg, false>;
using VecRegI64 = ::VecRegT<VecElemI64, NumVecElemPerVecReg, false>;
using VecRegF64 = ::VecRegT<VecElemF64, NumVecElemPerVecReg, false>;
// non-writeable versions of vector regs
using ConstVecRegU8 = ::VecRegT<VecElemU8, NumVecElemPerVecReg, true>;
using ConstVecRegI8 = ::VecRegT<VecElemI8, NumVecElemPerVecReg, true>;
using ConstVecRegU16 = ::VecRegT<VecElemU16, NumVecElemPerVecReg, true>;
using ConstVecRegI16 = ::VecRegT<VecElemI16, NumVecElemPerVecReg, true>;
using ConstVecRegU32 = ::VecRegT<VecElemU32, NumVecElemPerVecReg, true>;
using ConstVecRegI32 = ::VecRegT<VecElemI32, NumVecElemPerVecReg, true>;
using ConstVecRegF32 = ::VecRegT<VecElemF32, NumVecElemPerVecReg, true>;
using ConstVecRegU64 = ::VecRegT<VecElemU64, NumVecElemPerVecReg, true>;
using ConstVecRegI64 = ::VecRegT<VecElemI64, NumVecElemPerVecReg, true>;
using ConstVecRegF64 = ::VecRegT<VecElemF64, NumVecElemPerVecReg, true>;
using VecRegContainerU8 = VecRegU8::Container;
using VecRegContainerU16 = VecRegU16::Container;
using VecRegContainerU32 = VecRegU32::Container;
using VecRegContainerU64 = VecRegU64::Container;
using VecRegContainerU32 =
VecRegContainer<sizeof(VecElemU32) * NumVecElemPerVecReg>;
struct StatusReg
{

View File

@@ -326,12 +326,8 @@ namespace Gcn3ISA
scRegData.read();
}
using VecRegCont = typename std::conditional<NumDwords == 2,
VecRegContainerU64, typename std::conditional<sizeof(DataType)
== sizeof(VecElemU16), VecRegContainerU16,
typename std::conditional<sizeof(DataType)
== sizeof(VecElemU8), VecRegContainerU8,
VecRegContainerU32>::type>::type>::type;
using VecRegCont =
VecRegContainer<sizeof(DataType) * NumVecElemPerVecReg>;
/**
* whether this operand a scalar or not.

View File

@@ -2396,15 +2396,6 @@ ISA::getCurSveVecLenInBits() const
return (len + 1) * 128;
}
void
ISA::zeroSveVecRegUpperPart(VecRegContainer &vc, unsigned eCount)
{
auto vv = vc.as<uint64_t>();
for (int i = 2; i < eCount; ++i) {
vv[i] = 0;
}
}
void
ISA::serialize(CheckpointOut &cp) const
{

View File

@@ -852,8 +852,16 @@ namespace ArmISA
unsigned getCurSveVecLenInBitsAtReset() const { return sveVL * 128; }
static void zeroSveVecRegUpperPart(VecRegContainer &vc,
unsigned eCount);
template <typename Elem>
static void
zeroSveVecRegUpperPart(Elem *v, unsigned eCount)
{
static_assert(sizeof(Elem) <= sizeof(uint64_t));
eCount *= (sizeof(uint64_t) / sizeof(Elem));
for (int i = 16 / sizeof(Elem); i < eCount; ++i) {
v[i] = 0;
}
}
void serialize(CheckpointOut &cp) const override;
void unserialize(CheckpointIn &cp) override;

View File

@@ -170,7 +170,7 @@ def template SveContigLoadExecute {{
%(rden_code)s;
fault = readMemAtomic(xc, EA, memData.raw_ptr<uint8_t>(),
fault = readMemAtomic(xc, EA, memData.as<uint8_t>(),
memAccessSize, this->memAccessFlags, rdEn);
%(fault_code)s;
@@ -228,7 +228,7 @@ def template SveContigLoadCompleteAcc {{
auto memDataView = memData.as<MemElemType>();
if (xc->readMemAccPredicate()) {
memcpy(memData.raw_ptr<uint8_t>(), pkt->getPtr<uint8_t>(),
memcpy(memData.as<uint8_t>(), pkt->getPtr<uint8_t>(),
pkt->getSize());
}
@@ -265,7 +265,7 @@ def template SveContigStoreExecute {{
}
if (fault == NoFault) {
fault = writeMemAtomic(xc, memData.raw_ptr<uint8_t>(),
fault = writeMemAtomic(xc, memData.as<uint8_t>(),
EA, memAccessSize, this->memAccessFlags, nullptr, wrEn);
}
@@ -303,7 +303,7 @@ def template SveContigStoreInitiateAcc {{
}
if (fault == NoFault) {
fault = writeMemTiming(xc, memData.raw_ptr<uint8_t>(),
fault = writeMemTiming(xc, memData.as<uint8_t>(),
EA, memAccessSize, this->memAccessFlags, nullptr, wrEn);
}
@@ -1001,7 +1001,7 @@ def template SveStructLoadExecute {{
auto memDataView = memData.as<Element>();
if (fault == NoFault) {
fault = readMemAtomic(xc, EA, memData.raw_ptr<uint8_t>(),
fault = readMemAtomic(xc, EA, memData.as<uint8_t>(),
memAccessSize, this->memAccessFlags,
std::vector<bool>(memAccessSize, true));
%(memacc_code)s;
@@ -1059,7 +1059,7 @@ def template SveStructLoadCompleteAcc {{
ArmISA::VecRegContainer memData;
auto memDataView = memData.as<Element>();
memcpy(memData.raw_ptr<uint8_t>(), pkt->getPtr<uint8_t>(),
memcpy(memData.as<uint8_t>(), pkt->getPtr<uint8_t>(),
pkt->getSize());
if (fault == NoFault) {
@@ -1100,7 +1100,7 @@ def template SveStructStoreExecute {{
}
if (fault == NoFault) {
fault = writeMemAtomic(xc, memData.raw_ptr<uint8_t>(),
fault = writeMemAtomic(xc, memData.as<uint8_t>(),
EA, memAccessSize, this->memAccessFlags, nullptr, wrEn);
}
@@ -1138,7 +1138,7 @@ def template SveStructStoreInitiateAcc {{
}
if (fault == NoFault) {
fault = writeMemTiming(xc, memData.raw_ptr<uint8_t>(),
fault = writeMemTiming(xc, memData.as<uint8_t>(),
EA, memAccessSize, this->memAccessFlags, nullptr, wrEn);
}

View File

@@ -126,8 +126,7 @@ Trace::ArmNativeTrace::ThreadState::update(ThreadContext *tc)
changed[STATE_CPSR] = (newState[STATE_CPSR] != oldState[STATE_CPSR]);
for (int i = 0; i < NumVecV7ArchRegs; i++) {
auto vec(tc->readVecReg(RegId(VecRegClass,i))
.as<uint64_t, MaxSveVecLenInDWords>());
auto *vec = tc->readVecReg(RegId(VecRegClass,i)).as<uint64_t>();
newState[STATE_F0 + 2*i] = vec[0];
newState[STATE_F0 + 2*i + 1] = vec[1];
}

View File

@@ -55,9 +55,8 @@ constexpr unsigned NumVecElemPerNeonVecReg = 4;
constexpr unsigned NumVecElemPerVecReg = MaxSveVecLenInWords;
using VecElem = uint32_t;
using VecReg = ::VecRegT<VecElem, NumVecElemPerVecReg, false>;
using ConstVecReg = ::VecRegT<VecElem, NumVecElemPerVecReg, true>;
using VecRegContainer = VecReg::Container;
using VecRegContainer =
::VecRegContainer<NumVecElemPerVecReg * sizeof(VecElem)>;
using VecPredReg = ::VecPredRegT<VecElem, NumVecElemPerVecReg,
VecPredRegHasPackedRepr, false>;

View File

@@ -174,33 +174,8 @@ namespace Gcn3ISA
*/
const int RegSizeDWORDs = sizeof(VecElemU32) / DWORDSize;
// typedefs for the various sizes/types of vector regs
using VecRegU8 = ::VecRegT<VecElemU8, NumVecElemPerVecReg, false>;
using VecRegI8 = ::VecRegT<VecElemI8, NumVecElemPerVecReg, false>;
using VecRegU16 = ::VecRegT<VecElemU16, NumVecElemPerVecReg, false>;
using VecRegI16 = ::VecRegT<VecElemI16, NumVecElemPerVecReg, false>;
using VecRegU32 = ::VecRegT<VecElemU32, NumVecElemPerVecReg, false>;
using VecRegI32 = ::VecRegT<VecElemI32, NumVecElemPerVecReg, false>;
using VecRegF32 = ::VecRegT<VecElemF32, NumVecElemPerVecReg, false>;
using VecRegU64 = ::VecRegT<VecElemU64, NumVecElemPerVecReg, false>;
using VecRegI64 = ::VecRegT<VecElemI64, NumVecElemPerVecReg, false>;
using VecRegF64 = ::VecRegT<VecElemF64, NumVecElemPerVecReg, false>;
// non-writeable versions of vector regs
using ConstVecRegU8 = ::VecRegT<VecElemU8, NumVecElemPerVecReg, true>;
using ConstVecRegI8 = ::VecRegT<VecElemI8, NumVecElemPerVecReg, true>;
using ConstVecRegU16 = ::VecRegT<VecElemU16, NumVecElemPerVecReg, true>;
using ConstVecRegI16 = ::VecRegT<VecElemI16, NumVecElemPerVecReg, true>;
using ConstVecRegU32 = ::VecRegT<VecElemU32, NumVecElemPerVecReg, true>;
using ConstVecRegI32 = ::VecRegT<VecElemI32, NumVecElemPerVecReg, true>;
using ConstVecRegF32 = ::VecRegT<VecElemF32, NumVecElemPerVecReg, true>;
using ConstVecRegU64 = ::VecRegT<VecElemU64, NumVecElemPerVecReg, true>;
using ConstVecRegI64 = ::VecRegT<VecElemI64, NumVecElemPerVecReg, true>;
using ConstVecRegF64 = ::VecRegT<VecElemF64, NumVecElemPerVecReg, true>;
using VecRegContainerU8 = VecRegU8::Container;
using VecRegContainerU16 = VecRegU16::Container;
using VecRegContainerU32 = VecRegU32::Container;
using VecRegContainerU64 = VecRegU64::Container;
using VecRegContainerU32 =
VecRegContainer<sizeof(VecElemU32) * NumVecElemPerVecReg>;
struct StatusReg
{

View File

@@ -97,9 +97,9 @@
#define __ARCH_GENERIC_VEC_REG_HH__
#include <array>
#include <cstdint>
#include <iostream>
#include <string>
#include <type_traits>
#include "base/cprintf.hh"
#include "base/logging.hh"
@@ -107,81 +107,6 @@
constexpr unsigned MaxVecRegLenInBytes = 4096;
template <size_t Sz>
class VecRegContainer;
/** Vector Register Abstraction
* This generic class is a view in a particularization of MVC, to vector
* registers. There is a VecRegContainer that implements the model, and
* contains the data. To that model we can interpose different instantiations
* of VecRegT to view the container as a vector of NumElems elems of type
* VecElem.
* @tparam VecElem Type of each element of the vector.
* @tparam NumElems Amount of components of the vector.
* @tparam Const Indicate if the underlying container can be modified through
* the view.
*/
template <typename VecElem, size_t NumElems, bool Const>
class VecRegT
{
private:
/** Size of the register in bytes. */
static constexpr inline size_t
size()
{
return sizeof(VecElem) * NumElems;
}
public:
/** Container type alias. */
using Container = typename std::conditional<Const,
const VecRegContainer<size()>,
VecRegContainer<size()>>::type;
private:
/** My type alias. */
using MyClass = VecRegT<VecElem, NumElems, Const>;
/** Reference to container. */
Container& container;
public:
/** Constructor. */
VecRegT(Container& cnt) : container(cnt) {};
/** Index operator. */
const VecElem &
operator[](size_t idx) const
{
return container.template raw_ptr<VecElem>()[idx];
}
/** Index operator. */
template<bool Condition = !Const>
typename std::enable_if_t<Condition, VecElem&>
operator[](size_t idx)
{
return container.template raw_ptr<VecElem>()[idx];
}
/** Output stream operator. */
friend std::ostream&
operator<<(std::ostream& os, const MyClass& vr)
{
/* 0-sized is not allowed */
os << "[" << std::hex << (uint32_t)vr[0];
for (uint32_t e = 1; e < vr.size(); e++)
os << " " << std::hex << (uint32_t)vr[e];
os << ']';
return os;
}
/**
* Cast to VecRegContainer&
* It is useful to get the reference to the container for ISA tricks,
* because casting to reference prevents unnecessary copies.
*/
operator Container&() { return container; }
};
/**
* Vector Register Abstraction
* This generic class is the model in a particularization of MVC, to vector
@@ -203,7 +128,6 @@ class VecRegContainer
private:
// 16-byte aligned to support 128bit element view
alignas(16) Container container;
using MyClass = VecRegContainer<SIZE>;
public:
VecRegContainer() {}
@@ -215,19 +139,11 @@ class VecRegContainer
/** Assignment operators. */
/** @{ */
/** From VecRegContainer */
MyClass&
operator=(const MyClass& that)
VecRegContainer<SIZE>&
operator=(const VecRegContainer<SIZE>& that)
{
if (&that == this)
return *this;
return *this = that.container;
}
/** From appropriately sized uint8_t[]. */
MyClass&
operator=(const Container& that)
{
std::memcpy(container.data(), that.data(), SIZE);
if (&that != this)
std::memcpy(container.data(), that.container.data(), SIZE);
return *this;
}
/** @} */
@@ -252,13 +168,6 @@ class VecRegContainer
return !operator==(that);
}
/** Get pointer to bytes. */
template <typename Ret>
const Ret* raw_ptr() const { return (const Ret*)container.data(); }
template <typename Ret>
Ret* raw_ptr() { return (Ret*)container.data(); }
/**
* View interposers.
* Create a view of this container as a vector of VecElems with an
@@ -270,34 +179,37 @@ class VecRegContainer
* @tparam NumElem Amount of elements in the view.
*/
/** @{ */
template <typename VecElem, size_t NumElems=(SIZE / sizeof(VecElem))>
VecRegT<VecElem, NumElems, true>
as() const
{
static_assert(SIZE % sizeof(VecElem) == 0,
"VecElem does not evenly divide the register size");
static_assert(sizeof(VecElem) * NumElems <= SIZE,
"Viewing VecReg as something bigger than it is");
return VecRegT<VecElem, NumElems, true>(*this);
}
template <typename VecElem, size_t NumElems=(SIZE / sizeof(VecElem))>
VecRegT<VecElem, NumElems, false>
template <typename VecElem>
VecElem *
as()
{
static_assert(SIZE % sizeof(VecElem) == 0,
"VecElem does not evenly divide the register size");
static_assert(sizeof(VecElem) * NumElems <= SIZE,
"Viewing VecReg as something bigger than it is");
return VecRegT<VecElem, NumElems, false>(*this);
return (VecElem *)container.data();
}
template <typename VecElem>
const VecElem *
as() const
{
static_assert(SIZE % sizeof(VecElem) == 0,
"VecElem does not evenly divide the register size");
return (VecElem *)container.data();
}
friend std::ostream&
operator<<(std::ostream& os, const MyClass& v)
operator<<(std::ostream& os, const VecRegContainer<SIZE>& v)
{
// When printing for human consumption, break into 4 byte chunks.
ccprintf(os, "[");
size_t count = 0;
for (auto& b: v.container) {
if (count && (count % 4) == 0)
os << "_";
ccprintf(os, "%02x", b);
count++;
}
ccprintf(os, "]");
return os;
}
@@ -305,7 +217,7 @@ class VecRegContainer
/**
* Used for serialization.
*/
friend ShowParam<MyClass>;
friend ShowParam<VecRegContainer<SIZE>>;
};
/**
@@ -325,7 +237,7 @@ struct ParseParam<VecRegContainer<Sz>>
uint8_t b = 0;
if (2 * i < value.size())
b = stoul(str.substr(i * 2, 2), nullptr, 16);
value.template raw_ptr<uint8_t>()[i] = b;
value.template as<uint8_t>()[i] = b;
}
return true;
}
@@ -350,9 +262,8 @@ struct ShowParam<VecRegContainer<Sz>>
/** @{ */
using DummyVecElem = uint32_t;
constexpr unsigned DummyNumVecElemPerVecReg = 2;
using DummyVecReg = VecRegT<DummyVecElem, DummyNumVecElemPerVecReg, false>;
using DummyConstVecReg = VecRegT<DummyVecElem, DummyNumVecElemPerVecReg, true>;
using DummyVecRegContainer = DummyVecReg::Container;
using DummyVecRegContainer =
VecRegContainer<DummyNumVecElemPerVecReg * sizeof(DummyVecElem)>;
constexpr size_t DummyVecRegSizeBytes = DummyNumVecElemPerVecReg *
sizeof(DummyVecElem);
/** @} */

View File

@@ -40,8 +40,6 @@ const int ZeroReg = 0;
// Not applicable to MIPS
using VecElem = ::DummyVecElem;
using VecReg = ::DummyVecReg;
using ConstVecReg = ::DummyConstVecReg;
using VecRegContainer = ::DummyVecRegContainer;
constexpr unsigned NumVecElemPerVecReg = ::DummyNumVecElemPerVecReg;
constexpr size_t VecRegSizeBytes = ::DummyVecRegSizeBytes;

View File

@@ -49,8 +49,6 @@ const RegIndex ZeroReg = 0;
// Not applicable to null
using VecElem = ::DummyVecElem;
using VecReg = ::DummyVecReg;
using ConstVecReg = ::DummyConstVecReg;
using VecRegContainer = ::DummyVecRegContainer;
constexpr unsigned NumVecElemPerVecReg = ::DummyNumVecElemPerVecReg;
constexpr size_t VecRegSizeBytes = ::DummyVecRegSizeBytes;

View File

@@ -40,8 +40,6 @@ namespace PowerISA
// Not applicable to Power
using VecElem = ::DummyVecElem;
using VecReg = ::DummyVecReg;
using ConstVecReg = ::DummyConstVecReg;
using VecRegContainer = ::DummyVecRegContainer;
constexpr unsigned NumVecElemPerVecReg = ::DummyNumVecElemPerVecReg;
constexpr size_t VecRegSizeBytes = ::DummyVecRegSizeBytes;

View File

@@ -93,8 +93,6 @@ static constexpr freg_t freg(uint_fast16_t f) { return {f}; }
// Not applicable to RISC-V
using VecElem = ::DummyVecElem;
using VecReg = ::DummyVecReg;
using ConstVecReg = ::DummyConstVecReg;
using VecRegContainer = ::DummyVecRegContainer;
constexpr unsigned NumVecElemPerVecReg = ::DummyNumVecElemPerVecReg;
constexpr size_t VecRegSizeBytes = ::DummyVecRegSizeBytes;

View File

@@ -37,8 +37,6 @@ namespace SparcISA
// Not applicable to SPARC
using VecElem = ::DummyVecElem;
using VecReg = ::DummyVecReg;
using ConstVecReg = ::DummyConstVecReg;
using VecRegContainer = ::DummyVecRegContainer;
constexpr unsigned NumVecElemPerVecReg = ::DummyNumVecElemPerVecReg;
constexpr size_t VecRegSizeBytes = ::DummyVecRegSizeBytes;

View File

@@ -66,8 +66,6 @@ const int ZeroReg = NUM_INTREGS;
// Not applicable to x86
using VecElem = ::DummyVecElem;
using VecReg = ::DummyVecReg;
using ConstVecReg = ::DummyConstVecReg;
using VecRegContainer = ::DummyVecRegContainer;
constexpr unsigned NumVecElemPerVecReg = ::DummyNumVecElemPerVecReg;
constexpr size_t VecRegSizeBytes = ::DummyVecRegSizeBytes;

View File

@@ -207,7 +207,7 @@ UnifiedRenameMap::switchMode(VecMode newVecMode)
const size_t numElems = vecElemMap.numArchRegs();
const size_t elemsPerVec = numElems / numVecs;
for (uint32_t i = 0; i < numVecs; i++) {
TheISA::VecReg dst = new_RF[i].as<TheISA::VecElem>();
TheISA::VecElem *dst = new_RF[i].as<TheISA::VecElem>();
for (uint32_t l = 0; l < elemsPerVec; l++) {
RegId s_rid(VecElemClass, i, l);
PhysRegIdPtr s_prid = vecElemMap.lookup(s_rid);

View File

@@ -453,7 +453,7 @@ Wavefront::initRegState(HSAQueueEntry *task, int wgSizeInWorkItems)
{
physVgprIdx = computeUnit->registerManager
->mapVgpr(this, regInitIdx);
TheGpuISA::VecRegU32 vgpr_x
TheGpuISA::VecElemU32 *vgpr_x
= raw_vgpr.as<TheGpuISA::VecElemU32>();
for (int lane = 0; lane < workItemId[0].size(); ++lane) {
@@ -469,7 +469,7 @@ Wavefront::initRegState(HSAQueueEntry *task, int wgSizeInWorkItems)
{
physVgprIdx = computeUnit->registerManager
->mapVgpr(this, regInitIdx);
TheGpuISA::VecRegU32 vgpr_y
TheGpuISA::VecElemU32 *vgpr_y
= raw_vgpr.as<TheGpuISA::VecElemU32>();
for (int lane = 0; lane < workItemId[1].size(); ++lane) {
@@ -485,7 +485,7 @@ Wavefront::initRegState(HSAQueueEntry *task, int wgSizeInWorkItems)
{
physVgprIdx = computeUnit->registerManager->
mapVgpr(this, regInitIdx);
TheGpuISA::VecRegU32 vgpr_z
TheGpuISA::VecElemU32 *vgpr_z
= raw_vgpr.as<TheGpuISA::VecElemU32>();
for (int lane = 0; lane < workItemId[2].size(); ++lane) {