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

View File

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