Speed up the connect(Nexus*,Link&) function somewhat.

This simplifies and reorganizes this function in order to improve
the performance of this function by a constant factor. I think we
really need to improve this by an entire order (and not just a
simple factor) but this helps.
This commit is contained in:
Stephen Williams 2009-12-09 08:22:18 -08:00
parent 94fa8955e5
commit 4db4a467ee
2 changed files with 31 additions and 23 deletions

View File

@ -30,30 +30,39 @@
# include <malloc.h>
#endif
void connect(Nexus*l, Link&r)
void Nexus::connect(Link&r)
{
assert(l);
if (l == r.nexus_)
if (this == r.nexus_)
return;
if (name_) {
delete[]name_;
name_ = 0;
}
// Special case: The "r" link is connected to nothing. The
// connect becomes trivially easy.
if (r.nexus_ == 0) {
l->relink(&r);
if (r.get_dir() != Link::INPUT)
driven_ = NO_GUESS;
r.nexus_ = this;
r.next_ = list_;
list_ = &r;
return;
}
Nexus*tmp = r.nexus_;
if (tmp->driven_ != Vz)
driven_ = NO_GUESS;
while (Link*cur = tmp->list_) {
tmp->list_ = cur->next_;
cur->nexus_ = 0;
cur->next_ = 0;
l->relink(cur);
cur->nexus_ = this;
cur->next_ = list_;
list_ = cur;
}
l->driven_ = Nexus::NO_GUESS;
assert(tmp->list_ == 0);
delete tmp;
}
@ -67,8 +76,8 @@ void connect(Link&l, Link&r)
connect(r.nexus_, l);
} else {
Nexus*tmp = new Nexus;
connect(tmp, l);
connect(tmp, r);
tmp->connect(l);
tmp->connect(r);
}
}
@ -89,8 +98,10 @@ Link::~Link()
Nexus* Link::nexus()
{
if (nexus_ == 0)
(new Nexus()) ->relink(this);
if (nexus_ == 0) {
Nexus*tmp = new Nexus;
tmp->relink_(this);
}
return nexus_;
}
@ -373,13 +384,8 @@ void Nexus::unlink(Link*that)
that->next_ = 0;
}
void Nexus::relink(Link*that)
void Nexus::relink_(Link*that)
{
if (name_) {
delete[] name_;
name_ = 0;
}
/* If the link I'm adding is a driver for this nexus, then
cancel my guess of the driven value. */
if (that->get_dir() != Link::INPUT)

View File

@ -81,7 +81,6 @@ extern void join_island(NetPins*obj);
class Link {
friend void connect(Link&, Link&);
friend void connect(Nexus*, Link&);
friend class NetPins;
friend class Nexus;
@ -325,13 +324,14 @@ class NetBranch : public NetPins, public IslandBranch {
class Nexus {
friend void connect(Link&, Link&);
friend void connect(Nexus*, Link&);
friend class Link;
public:
explicit Nexus();
~Nexus();
void connect(Link&r);
const char* name() const;
verinum::V get_init() const;
@ -371,7 +371,7 @@ class Nexus {
private:
Link*list_;
void unlink(Link*);
void relink(Link*);
void relink_(Link*);
mutable char* name_; /* Cache the calculated name for the Nexus. */
mutable ivl_nexus_t t_cookie_;
@ -384,6 +384,8 @@ class Nexus {
Nexus& operator= (const Nexus&);
};
inline void connect(Nexus*l, Link&r) { l->connect(r); }
class NexusSet {
public: