Have vvp_vector8_t avoid allocating tiny scalar arrays.(cherry picked from commit 35fe8fae00)

This commit is contained in:
Stephen Williams 2008-06-06 16:36:43 -07:00
parent 4914b734dc
commit 2e9970a98c
2 changed files with 68 additions and 36 deletions

View File

@ -1758,12 +1758,12 @@ ostream& operator<< (ostream&out, const vvp_vector2_t&that)
vvp_vector8_t::vvp_vector8_t(const vvp_vector8_t&that)
{
size_ = that.size_;
if (size_==0) {
bits_ = 0;
if (size_ <= PTR_THRESH) {
memcpy(val_, that.val_, sizeof(val_));
} else {
bits_ = new vvp_scalar_t[size_];
ptr_ = new vvp_scalar_t[size_];
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)
: size_(that.size())
{
if (size_ == 0) {
bits_ = 0;
if (size_ == 0)
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)
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)
{
// Assign to self.
if (size_ > 0 && bits_ == that.bits_)
if (size_ > PTR_THRESH && that.size_ > PTR_THRESH && ptr_ == that.ptr_)
return *this;
if (size_ != that.size_) {
if (size_ > 0)
delete[]bits_;
if (size_ > PTR_THRESH)
delete[]ptr_;
size_ = 0;
}
@ -1799,13 +1802,19 @@ vvp_vector8_t& vvp_vector8_t::operator= (const vvp_vector8_t&that)
return *this;
}
if (that.size_ <= PTR_THRESH) {
size_ = that.size_;
memcpy(val_, that.val_, sizeof(val_));
return *this;
}
if (size_ == 0) {
size_ = that.size_;
bits_ = new vvp_scalar_t[size_];
ptr_ = new vvp_scalar_t[size_];
}
for (unsigned idx = 0 ; idx < size_ ; idx += 1)
bits_[idx] = that.bits_[idx];
ptr_[idx] = that.ptr_[idx];
return *this;
}
@ -1814,9 +1823,12 @@ vvp_vector8_t vvp_vector8_t::subvalue(unsigned base, unsigned wid) const
{
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;
while ((idx < wid) && (base+idx < size_)) {
tmp.bits_[idx] = bits_[base+idx];
tmp_ptr[idx] = ptr[base+idx];
idx += 1;
}
@ -1828,10 +1840,13 @@ vvp_vector8_t part_expand(const vvp_vector8_t&that, unsigned wid, unsigned off)
assert(off < 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;
while (idx < wid && that.size_ > (idx-off)) {
tmp.bits_[idx] = that.bits_[idx-off];
tmp_ptr[idx] = that_ptr[idx-off];
idx += 1;
}

View File

@ -21,6 +21,7 @@
# include "config.h"
# include <stddef.h>
# include <new>
# include <assert.h>
#ifdef HAVE_IOSFWD
@ -581,8 +582,15 @@ class vvp_vector8_t {
vvp_vector8_t& operator= (const vvp_vector8_t&that);
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_;
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
@ -612,17 +620,35 @@ extern ostream& operator<< (ostream&, const vvp_vector8_t&);
inline vvp_vector8_t::vvp_vector8_t(unsigned size)
: size_(size)
{
if (size_ == 0) {
bits_ = 0;
return;
if (size_ <= PTR_THRESH) {
new (val_) vvp_scalar_t[PTR_THRESH];
} else {
ptr_ = new vvp_scalar_t[size_];
}
bits_ = new vvp_scalar_t[size_];
}
inline vvp_vector8_t::~vvp_vector8_t()
{
if (size_ > 0)
delete[]bits_;
if (size_ > PTR_THRESH)
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
@ -634,26 +660,17 @@ inline bool vvp_vector8_t::eeq(const vvp_vector8_t&that) const
if (size_ == 0)
return true;
if (size_ <= PTR_THRESH)
return 0 == memcmp(val_, that.val_, sizeof(val_));
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 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
* target. The ptr() method returns a pointer to the vvp_net_t, and