From 647b3e5bda82e7e85c3851ac58ba856d65a943b9 Mon Sep 17 00:00:00 2001 From: Martin Whitaker Date: Sun, 12 Oct 2008 20:11:31 +0100 Subject: [PATCH] Bias storage of events towards static scopes. This patch modifies the code that finds and combines similar events such that if similar events are found in both static and automatic scopes, the retained event will be in a static scope. This is a performance enhancement, as VVP has more run-time overhead when handling events declared in an automatic scope. --- nodangle.cc | 137 +++++++++++++++++++++++++++++++--------------------- 1 file changed, 82 insertions(+), 55 deletions(-) diff --git a/nodangle.cc b/nodangle.cc index b90eee000..cb24eccfe 100644 --- a/nodangle.cc +++ b/nodangle.cc @@ -37,14 +37,18 @@ class nodangle_f : public functor_t { void event(Design*des, NetEvent*ev); void signal(Design*des, NetNet*sig); - unsigned count_; + unsigned iteration; unsigned stotal, etotal; + bool scontinue, econtinue; + bool scomplete, ecomplete; }; void nodangle_f::event(Design*des, NetEvent*ev) { + if (ecomplete) return; + /* If there are no references to this event, then go right - ahead and delete in. There is no use looking further at + ahead and delete it. There is no use looking further at it. */ if ((ev->nwait() + ev->ntrig() + ev->nexpr()) == 0) { delete ev; @@ -52,58 +56,79 @@ void nodangle_f::event(Design*des, NetEvent*ev) return; } - /* Try to remove duplicate probes from the event. */ - for (unsigned idx = 0 ; idx < ev->nprobe() ; idx += 1) { - unsigned jdx = idx + 1; - while (jdx < ev->nprobe()) { - NetEvProbe*ip = ev->probe(idx); - NetEvProbe*jp = ev->probe(jdx); + if (iteration == 0) { + /* Try to remove duplicate probes from the event. This + is done as a separate initial pass to ensure similar + events are detected as soon as possible in subsequent + iterations. */ + for (unsigned idx = 0 ; idx < ev->nprobe() ; idx += 1) { + unsigned jdx = idx + 1; + while (jdx < ev->nprobe()) { + NetEvProbe*ip = ev->probe(idx); + NetEvProbe*jp = ev->probe(jdx); - if (ip->edge() != jp->edge()) { - jdx += 1; - continue; - } + if (ip->edge() != jp->edge()) { + jdx += 1; + continue; + } - bool fully_connected = true; - for (unsigned jpin = 0; jpin < jp->pin_count(); jpin += 1) { - unsigned ipin = 0; - bool connected_flag = false; - for (ipin = 0 ; ipin < ip->pin_count(); ipin += 1) - if (connected(ip->pin(ipin), jp->pin(jpin))) { - connected_flag = true; - break; - } + bool fully_connected = true; + for (unsigned jpin = 0; jpin < jp->pin_count(); jpin += 1) { + unsigned ipin = 0; + bool connected_flag = false; + for (ipin = 0 ; ipin < ip->pin_count(); ipin += 1) + if (connected(ip->pin(ipin), jp->pin(jpin))) { + connected_flag = true; + break; + } - if (!connected_flag) { - fully_connected = false; - break; - } - } + if (!connected_flag) { + fully_connected = false; + break; + } + } - if (fully_connected) { - delete jp; - } else { - jdx += 1; - } - } + if (fully_connected) { + delete jp; + } else { + jdx += 1; + } + } + } + econtinue = true; + } else { + /* Postpone examining events in an automatic scope until the + third (optional) pass. This will mean similar events are + biased towards being stored in static scopes. */ + if (ev->scope()->is_auto()) { + if (iteration == 1) { + econtinue = true; + return; + } + } else { + if (iteration == 2) { + return; + } + } + + /* Try to find all the events that are similar to me, and + replace their references with references to me. */ + list match; + ev->find_similar_event(match); + for (list::iterator idx = match.begin() + ; idx != match.end() ; idx ++) { + + NetEvent*tmp = *idx; + assert(tmp != ev); + tmp ->replace_event(ev); + } } - - /* Try to find all the events that are similar to me, and - replace their references with references to me. */ - list match; - ev->find_similar_event(match); - for (list::iterator idx = match.begin() - ; idx != match.end() ; idx ++) { - - NetEvent*tmp = *idx; - assert(tmp != ev); - tmp ->replace_event(ev); - } - } void nodangle_f::signal(Design*des, NetNet*sig) { + if (scomplete) return; + /* Cannot delete signals referenced in an expression or an l-value. */ if (sig->get_refs() > 0) @@ -174,7 +199,7 @@ void nodangle_f::signal(Design*des, NetNet*sig) /* If every pin is connected to another significant signal, then I can delete this one. */ if (significant_flags == sig->pin_count()) { - count_ += 1; + scontinue = true; delete sig; stotal += 1; } @@ -183,23 +208,26 @@ void nodangle_f::signal(Design*des, NetNet*sig) void nodangle(Design*des) { nodangle_f fun; - unsigned count_iterations = 0; + fun.iteration = 0; fun.stotal = 0; fun.etotal = 0; - + fun.scomplete = false; + fun.ecomplete = false; do { - fun.count_ = 0; + fun.scontinue = false; + fun.econtinue = false; des->functor(&fun); - count_iterations += 1; + fun.iteration += 1; + fun.scomplete = !fun.scontinue; + fun.ecomplete = !fun.econtinue; if (verbose_flag) { - cout << " ... " << count_iterations << " iterations" + cout << " ... " << fun.iteration << " iterations" << " deleted " << fun.stotal << " dangling signals" - << " and " << fun.etotal << " events." - << " (count=" << fun.count_ << ")" << endl; + << " and " << fun.etotal << " events." << endl; } - } while (fun.count_ > 0); + } while (fun.scontinue || fun.econtinue); } @@ -285,4 +313,3 @@ void nodangle(Design*des) * symbols generated by elaboration and other steps. * */ -