Have vvp_vector8_t avoid allocating tiny scalar arrays.(cherry picked from commit 35fe8fae00)
This commit is contained in:
parent
4914b734dc
commit
2e9970a98c
|
|
@ -1758,12 +1758,12 @@ ostream& operator<< (ostream&out, const vvp_vector2_t&that)
|
||||||
vvp_vector8_t::vvp_vector8_t(const vvp_vector8_t&that)
|
vvp_vector8_t::vvp_vector8_t(const vvp_vector8_t&that)
|
||||||
{
|
{
|
||||||
size_ = that.size_;
|
size_ = that.size_;
|
||||||
if (size_==0) {
|
if (size_ <= PTR_THRESH) {
|
||||||
bits_ = 0;
|
memcpy(val_, that.val_, sizeof(val_));
|
||||||
} else {
|
} else {
|
||||||
bits_ = new vvp_scalar_t[size_];
|
ptr_ = new vvp_scalar_t[size_];
|
||||||
for (unsigned idx = 0 ; idx < size_ ; idx += 1)
|
for (unsigned idx = 0 ; idx < size_ ; idx += 1)
|
||||||
bits_[idx] = that.bits_[idx];
|
ptr_[idx] = that.ptr_[idx];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1771,26 +1771,29 @@ vvp_vector8_t::vvp_vector8_t(const vvp_vector4_t&that,
|
||||||
unsigned str0, unsigned str1)
|
unsigned str0, unsigned str1)
|
||||||
: size_(that.size())
|
: size_(that.size())
|
||||||
{
|
{
|
||||||
if (size_ == 0) {
|
if (size_ == 0)
|
||||||
bits_ = 0;
|
|
||||||
return;
|
return;
|
||||||
}
|
|
||||||
|
|
||||||
bits_ = new vvp_scalar_t[size_];
|
vvp_scalar_t*tmp;
|
||||||
|
if (size_ <= PTR_THRESH)
|
||||||
|
tmp = new (val_) vvp_scalar_t[PTR_THRESH];
|
||||||
|
else
|
||||||
|
tmp = ptr_ = new vvp_scalar_t[size_];
|
||||||
|
|
||||||
for (unsigned idx = 0 ; idx < size_ ; idx += 1)
|
for (unsigned idx = 0 ; idx < size_ ; idx += 1)
|
||||||
bits_[idx] = vvp_scalar_t (that.value(idx), str0, str1);
|
tmp[idx] = vvp_scalar_t (that.value(idx), str0, str1);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
vvp_vector8_t& vvp_vector8_t::operator= (const vvp_vector8_t&that)
|
vvp_vector8_t& vvp_vector8_t::operator= (const vvp_vector8_t&that)
|
||||||
{
|
{
|
||||||
// Assign to self.
|
// Assign to self.
|
||||||
if (size_ > 0 && bits_ == that.bits_)
|
if (size_ > PTR_THRESH && that.size_ > PTR_THRESH && ptr_ == that.ptr_)
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
if (size_ != that.size_) {
|
if (size_ != that.size_) {
|
||||||
if (size_ > 0)
|
if (size_ > PTR_THRESH)
|
||||||
delete[]bits_;
|
delete[]ptr_;
|
||||||
size_ = 0;
|
size_ = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1799,13 +1802,19 @@ vvp_vector8_t& vvp_vector8_t::operator= (const vvp_vector8_t&that)
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (that.size_ <= PTR_THRESH) {
|
||||||
|
size_ = that.size_;
|
||||||
|
memcpy(val_, that.val_, sizeof(val_));
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
if (size_ == 0) {
|
if (size_ == 0) {
|
||||||
size_ = that.size_;
|
size_ = that.size_;
|
||||||
bits_ = new vvp_scalar_t[size_];
|
ptr_ = new vvp_scalar_t[size_];
|
||||||
}
|
}
|
||||||
|
|
||||||
for (unsigned idx = 0 ; idx < size_ ; idx += 1)
|
for (unsigned idx = 0 ; idx < size_ ; idx += 1)
|
||||||
bits_[idx] = that.bits_[idx];
|
ptr_[idx] = that.ptr_[idx];
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
@ -1814,9 +1823,12 @@ vvp_vector8_t vvp_vector8_t::subvalue(unsigned base, unsigned wid) const
|
||||||
{
|
{
|
||||||
vvp_vector8_t tmp (wid);
|
vvp_vector8_t tmp (wid);
|
||||||
|
|
||||||
|
vvp_scalar_t* tmp_ptr = tmp.size_<=PTR_THRESH? reinterpret_cast<vvp_scalar_t*>(tmp.val_) : tmp.ptr_;
|
||||||
|
const vvp_scalar_t* ptr = size_<=PTR_THRESH? reinterpret_cast<const vvp_scalar_t*>(val_) : ptr_;
|
||||||
|
|
||||||
unsigned idx = 0;
|
unsigned idx = 0;
|
||||||
while ((idx < wid) && (base+idx < size_)) {
|
while ((idx < wid) && (base+idx < size_)) {
|
||||||
tmp.bits_[idx] = bits_[base+idx];
|
tmp_ptr[idx] = ptr[base+idx];
|
||||||
idx += 1;
|
idx += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1828,10 +1840,13 @@ vvp_vector8_t part_expand(const vvp_vector8_t&that, unsigned wid, unsigned off)
|
||||||
assert(off < wid);
|
assert(off < wid);
|
||||||
vvp_vector8_t tmp (wid);
|
vvp_vector8_t tmp (wid);
|
||||||
|
|
||||||
|
vvp_scalar_t* tmp_ptr = tmp.size_<=vvp_vector8_t::PTR_THRESH? reinterpret_cast<vvp_scalar_t*>(tmp.val_) : tmp.ptr_;
|
||||||
|
const vvp_scalar_t* that_ptr = that.size_<=vvp_vector8_t::PTR_THRESH? reinterpret_cast<const vvp_scalar_t*>(that.val_) : that.ptr_;
|
||||||
|
|
||||||
unsigned idx = off;
|
unsigned idx = off;
|
||||||
|
|
||||||
while (idx < wid && that.size_ > (idx-off)) {
|
while (idx < wid && that.size_ > (idx-off)) {
|
||||||
tmp.bits_[idx] = that.bits_[idx-off];
|
tmp_ptr[idx] = that_ptr[idx-off];
|
||||||
idx += 1;
|
idx += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -21,6 +21,7 @@
|
||||||
|
|
||||||
# include "config.h"
|
# include "config.h"
|
||||||
# include <stddef.h>
|
# include <stddef.h>
|
||||||
|
# include <new>
|
||||||
# include <assert.h>
|
# include <assert.h>
|
||||||
|
|
||||||
#ifdef HAVE_IOSFWD
|
#ifdef HAVE_IOSFWD
|
||||||
|
|
@ -581,8 +582,15 @@ class vvp_vector8_t {
|
||||||
vvp_vector8_t& operator= (const vvp_vector8_t&that);
|
vvp_vector8_t& operator= (const vvp_vector8_t&that);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
// This is the number of vvp_scalar_t objects we can keep in
|
||||||
|
// the val_ buffer. If the vector8 is bigger then this, then
|
||||||
|
// resort to allocations to get a larger buffer.
|
||||||
|
enum { PTR_THRESH = 8 };
|
||||||
unsigned size_;
|
unsigned size_;
|
||||||
vvp_scalar_t*bits_;
|
union {
|
||||||
|
vvp_scalar_t*ptr_;
|
||||||
|
char val_[PTR_THRESH * sizeof(vvp_scalar_t)];
|
||||||
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Resolve uses the default Verilog resolver algorithm to resolve
|
/* Resolve uses the default Verilog resolver algorithm to resolve
|
||||||
|
|
@ -612,17 +620,35 @@ extern ostream& operator<< (ostream&, const vvp_vector8_t&);
|
||||||
inline vvp_vector8_t::vvp_vector8_t(unsigned size)
|
inline vvp_vector8_t::vvp_vector8_t(unsigned size)
|
||||||
: size_(size)
|
: size_(size)
|
||||||
{
|
{
|
||||||
if (size_ == 0) {
|
if (size_ <= PTR_THRESH) {
|
||||||
bits_ = 0;
|
new (val_) vvp_scalar_t[PTR_THRESH];
|
||||||
return;
|
} else {
|
||||||
|
ptr_ = new vvp_scalar_t[size_];
|
||||||
}
|
}
|
||||||
bits_ = new vvp_scalar_t[size_];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline vvp_vector8_t::~vvp_vector8_t()
|
inline vvp_vector8_t::~vvp_vector8_t()
|
||||||
{
|
{
|
||||||
if (size_ > 0)
|
if (size_ > PTR_THRESH)
|
||||||
delete[]bits_;
|
delete[]ptr_;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline vvp_scalar_t vvp_vector8_t::value(unsigned idx) const
|
||||||
|
{
|
||||||
|
assert(idx < size_);
|
||||||
|
if (size_ <= PTR_THRESH)
|
||||||
|
return reinterpret_cast<const vvp_scalar_t*>(val_) [idx];
|
||||||
|
else
|
||||||
|
return ptr_[idx];
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void vvp_vector8_t::set_bit(unsigned idx, vvp_scalar_t val)
|
||||||
|
{
|
||||||
|
assert(idx < size_);
|
||||||
|
if (size_ <= PTR_THRESH)
|
||||||
|
reinterpret_cast<vvp_scalar_t*>(val_) [idx] = val;
|
||||||
|
else
|
||||||
|
ptr_[idx] = val;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Exactly-equal for vvp_vector8_t is common and should be as tight
|
// Exactly-equal for vvp_vector8_t is common and should be as tight
|
||||||
|
|
@ -634,26 +660,17 @@ inline bool vvp_vector8_t::eeq(const vvp_vector8_t&that) const
|
||||||
if (size_ == 0)
|
if (size_ == 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
|
if (size_ <= PTR_THRESH)
|
||||||
|
return 0 == memcmp(val_, that.val_, sizeof(val_));
|
||||||
|
|
||||||
for (unsigned idx = 0 ; idx < size_ ; idx += 1) {
|
for (unsigned idx = 0 ; idx < size_ ; idx += 1) {
|
||||||
if (! bits_[idx] .eeq( that.bits_[idx] ))
|
if (! ptr_[idx] .eeq( that.ptr_[idx] ))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline vvp_scalar_t vvp_vector8_t::value(unsigned idx) const
|
|
||||||
{
|
|
||||||
assert(idx < size_);
|
|
||||||
return bits_[idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void vvp_vector8_t::set_bit(unsigned idx, vvp_scalar_t val)
|
|
||||||
{
|
|
||||||
assert(idx < size_);
|
|
||||||
bits_[idx] = val;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This class implements a pointer that points to an item within a
|
* This class implements a pointer that points to an item within a
|
||||||
* target. The ptr() method returns a pointer to the vvp_net_t, and
|
* target. The ptr() method returns a pointer to the vvp_net_t, and
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue