Optimized Nexus handling during code generation.

Once code generation starts, the Nexus structure no longer needs to
support fast insertion/connect operations. So have the code generator
lock down the Nexus structures and adjust the Link lists for optimal
access during readout.
This commit is contained in:
Stephen Williams 2009-12-10 13:20:38 -08:00
parent f7aef3f966
commit 534207bb83
3 changed files with 37 additions and 26 deletions

View File

@ -476,16 +476,20 @@ const Link* Nexus::first_nlink() const
else return 0;
}
ivl_nexus_t Nexus::t_cookie() const
/*
* The t_cookie can be set exactly once. This attaches an ivl_nexus_t
* object to the Nexus, and causes the Link list to be marked up for
* efficient use by the code generator. The change is to give all the
* links a valid nexus_ pointer. This breaks most of the other
* methods, but they are not used during code generation.
*/
void Nexus::t_cookie(ivl_nexus_t val) const
{
return t_cookie_;
}
ivl_nexus_t Nexus::t_cookie(ivl_nexus_t val)const
{
ivl_nexus_t tmp = t_cookie_;
assert(val && !t_cookie_);
t_cookie_ = val;
return tmp;
for (Link*cur = list_->next_ ; cur->nexus_ == 0 ; cur = cur->next_)
cur->nexus_ = const_cast<Nexus*> (this);
}
unsigned Nexus::vector_width() const

View File

@ -491,9 +491,9 @@ const Link& NetDelaySrc::condit_pin() const
NetNet::NetNet(NetScope*s, perm_string n, Type t, unsigned npins)
: NetObj(s, n, 1),
type_(t), port_type_(NOT_A_PORT), data_type_(IVL_VT_NO_TYPE),
signed_(false), isint_(false), is_scalar_(false),
signed_(false), isint_(false), is_scalar_(false), local_flag_(false),
discipline_(0), msb_(npins-1), lsb_(0), dimensions_(0),
s0_(0), e0_(0), local_flag_(false), eref_count_(0), lref_count_(0)
s0_(0), e0_(0), eref_count_(0), lref_count_(0)
{
assert(s);
assert(npins>0);
@ -544,9 +544,10 @@ NetNet::NetNet(NetScope*s, perm_string n, Type t,
long ms, long ls)
: NetObj(s, n, 1), type_(t),
port_type_(NOT_A_PORT), data_type_(IVL_VT_NO_TYPE), signed_(false),
isint_(false), is_scalar_(false), discipline_(0), msb_(ms), lsb_(ls),
isint_(false), is_scalar_(false), local_flag_(false), discipline_(0),
msb_(ms), lsb_(ls),
dimensions_(0), s0_(0), e0_(0),
local_flag_(false), eref_count_(0), lref_count_(0)
eref_count_(0), lref_count_(0)
{
assert(s);
@ -595,9 +596,10 @@ NetNet::NetNet(NetScope*s, perm_string n, Type t,
: NetObj(s, n, calculate_count(array_s, array_e)),
type_(t), port_type_(NOT_A_PORT),
data_type_(IVL_VT_NO_TYPE), signed_(false), isint_(false),
is_scalar_(false), discipline_(0), msb_(ms), lsb_(ls),
is_scalar_(false), local_flag_(false), discipline_(0),
msb_(ms), lsb_(ls),
dimensions_(1), s0_(array_s), e0_(array_e),
local_flag_(false), eref_count_(0), lref_count_(0)
eref_count_(0), lref_count_(0)
{
ivl_assert(*this, s);
if (pin_count() == 0) {

View File

@ -322,9 +322,12 @@ class NetBranch : public NetPins, public IslandBranch {
* the first. The last link also has a non-nil nexus_ pointer back to
* this nexus.
*
* The t_cookie() is a void* that targets can use to store information
* in a Nexus. ivl guarantees that the t_cookie will be 0 when the
* target is invoked.
* The t_cookie() is an ivl_nexus_t that the code generator uses to
* store data in the nexus. When a Nexus is created, this cookie is
* set to nil. The code generator may set the cookie once. This locks
* the nexus, and rewrites the Link list to be optimal for the code
* generator. In the process, *all* of the other methods are no longer
* functional.
*/
class Nexus {
@ -373,8 +376,10 @@ class Nexus {
the value that has been driven. */
verinum::V driven_value() const;
ivl_nexus_t t_cookie() const;
ivl_nexus_t t_cookie(ivl_nexus_t) const;
/* The code generator sets an ivl_nexus_t to attach code
generation details to the nexus. */
ivl_nexus_t t_cookie() const { return t_cookie_; }
void t_cookie(ivl_nexus_t) const;
private:
Link*list_;
@ -662,19 +667,19 @@ class NetNet : public NetObj {
void initialize_value_and_dir(verinum::V init_value, Link::DIR dir);
private:
Type type_;
PortType port_type_;
ivl_variable_type_t data_type_;
bool signed_;
bool isint_; // original type of integer
bool is_scalar_;
Type type_ : 5;
PortType port_type_ : 3;
ivl_variable_type_t data_type_ : 3;
bool signed_ : 1;
bool isint_ : 1; // original type of integer
bool is_scalar_ : 1;
bool local_flag_: 1;
ivl_discipline_t discipline_;
long msb_, lsb_;
const unsigned dimensions_;
long s0_, e0_;
bool local_flag_;
unsigned eref_count_;
unsigned lref_count_;