Make link_drive_constant cache its results in

the Nexus, to improve cprop performance.
This commit is contained in:
steve 2002-06-24 01:49:38 +00:00
parent 6dd80611a1
commit 58c2e12507
8 changed files with 91 additions and 60 deletions

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: cprop.cc,v 1.35 2002/05/26 01:39:02 steve Exp $"
#ident "$Id: cprop.cc,v 1.36 2002/06/24 01:49:38 steve Exp $"
#endif
# include "config.h"
@ -64,8 +64,8 @@ void cprop_functor::lpm_add_sub(Design*des, NetAddSub*obj)
// result. Don't reduce the adder smaller then a 1-bit
// adder. These will be eliminated later.
while ((obj->width() > 1)
&& link_drivers_constant(obj->pin_DataA(0))
&& (driven_value(obj->pin_DataA(0)) == verinum::V0)) {
&& obj->pin_DataA(0).nexus()->drivers_constant()
&& (driven_value(obj->pin_DataA(0)) == verinum::V0)) {
NetAddSub*tmp = 0;
tmp = new NetAddSub(obj->scope(), obj->name(), obj->width()-1);
@ -89,8 +89,8 @@ void cprop_functor::lpm_add_sub(Design*des, NetAddSub*obj)
// Now do the same thing on the B side.
while ((obj->width() > 1)
&& link_drivers_constant(obj->pin_DataB(0))
&& (driven_value(obj->pin_DataB(0)) == verinum::V0)) {
&& obj->pin_DataB(0).nexus()->drivers_constant()
&& (driven_value(obj->pin_DataB(0)) == verinum::V0)) {
NetAddSub*tmp = 0;
tmp = new NetAddSub(obj->scope(), obj->name(), obj->width()-1);
@ -160,9 +160,9 @@ void cprop_functor::lpm_compare_eq_(Design*des, NetCompare*obj)
be completely eliminated and replaced with a constant 0. */
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
if (! link_drivers_constant(obj->pin_DataA(idx)))
if (! obj->pin_DataA(idx).nexus()->drivers_constant())
continue;
if (! link_drivers_constant(obj->pin_DataB(idx)))
if (! obj->pin_DataB(idx).nexus()->drivers_constant())
continue;
if (driven_value(obj->pin_DataA(idx)) ==
driven_value(obj->pin_DataB(idx)))
@ -181,11 +181,11 @@ void cprop_functor::lpm_compare_eq_(Design*des, NetCompare*obj)
unsigned top = obj->width();
for (unsigned idx = 0 ; idx < top ; ) {
if (! link_drivers_constant(obj->pin_DataA(idx))) {
if (! obj->pin_DataA(idx).nexus()->drivers_constant()) {
idx += 1;
continue;
}
if (! link_drivers_constant(obj->pin_DataB(idx))) {
if (! obj->pin_DataB(idx).nexus()->drivers_constant()) {
idx += 1;
continue;
}
@ -310,7 +310,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
on the output of an AND gate. */
while (idx < top) {
if (! link_drivers_constant(obj->pin(idx))) {
if (! obj->pin(idx).nexus()->drivers_constant()) {
idx += 1;
continue;
}
@ -457,7 +457,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
on the output of an OR gate. */
while (idx < top) {
if (! link_drivers_constant(obj->pin(idx))) {
if (! obj->pin(idx).nexus()->drivers_constant()) {
idx += 1;
continue;
}
@ -588,7 +588,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
last input to this position. It's like bubbling
all the 0 inputs to the end. */
while (idx < top) {
if (! link_drivers_constant(obj->pin(idx))) {
if (! obj->pin(idx).nexus()->drivers_constant()) {
idx += 1;
continue;
}
@ -618,7 +618,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
unsigned one = 0, ones = 0;
idx = 1;
while (idx < top) {
if (! link_drivers_constant(obj->pin(idx))) {
if (! obj->pin(idx).nexus()->drivers_constant()) {
idx += 1;
continue;
}
@ -682,7 +682,7 @@ void cprop_functor::lpm_logic(Design*des, NetLogic*obj)
if ((top == 3) && (ones == 1)) {
unsigned save;
if (! link_drivers_constant(obj->pin(1)))
if (! obj->pin(1).nexus()->drivers_constant())
save = 1;
else if (driven_value(obj->pin(1)) != verinum::V1)
save = 1;
@ -777,7 +777,7 @@ void cprop_functor::lpm_mux(Design*des, NetMux*obj)
connected to the select input. */
bool flag = true;
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
if (! link_drivers_constant(obj->pin_Data(idx, 0))) {
if (! obj->pin_Data(idx, 0).nexus()->drivers_constant()) {
flag = false;
break;
}
@ -809,7 +809,7 @@ void cprop_functor::lpm_mux(Design*des, NetMux*obj)
NetMux with an array of BUFIF0 devices. */
flag = true;
for (unsigned idx = 0 ; idx < obj->width() ; idx += 1) {
if (! link_drivers_constant(obj->pin_Data(idx, 1))) {
if (! obj->pin_Data(idx, 1).nexus()->drivers_constant()) {
flag = false;
break;
}
@ -949,6 +949,10 @@ void cprop(Design*des)
/*
* $Log: cprop.cc,v $
* Revision 1.36 2002/06/24 01:49:38 steve
* Make link_drive_constant cache its results in
* the Nexus, to improve cprop performance.
*
* Revision 1.35 2002/05/26 01:39:02 steve
* Carry Verilog 2001 attributes with processes,
* all the way through to the ivl_target API.

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: link_const.cc,v 1.12 2002/06/19 04:18:46 steve Exp $"
#ident "$Id: link_const.cc,v 1.13 2002/06/24 01:49:39 steve Exp $"
#endif
# include "config.h"
@ -30,18 +30,17 @@
* the nexus has a known constant value. If there is a supply net,
* then the nexus again has a known constant value.
*/
bool link_drivers_constant(const Link&lnk)
bool Nexus::drivers_constant() const
{
const Nexus*nex = lnk.nexus();
if (driven_ == VAR)
return false;
if (driven_ != NO_GUESS)
return true;
for (const Link*cur = nex->first_nlink()
; cur ; cur = cur->next_nlink()) {
for (const Link*cur = list_ ; cur ; cur = cur->next_) {
const NetNet*sig;
Link::DIR cur_dir;
if (cur == &lnk)
continue;
cur_dir = cur->get_dir();
if (cur_dir == Link::INPUT)
continue;
@ -74,23 +73,29 @@ bool link_drivers_constant(const Link&lnk)
if (sig->port_type() == NetNet::POUTPUT)
continue;
driven_ = VAR;
return false;
}
if (! dynamic_cast<const NetConst*>(cur->get_obj()))
return false;
/* If there is a supply net, then this nexus will have a
constant value independent of any drivers. */
if (const NetNet*sig = dynamic_cast<const NetNet*>(cur->get_obj()))
switch (sig->type()) {
case NetNet::SUPPLY0:
driven_ = V0;
return true;
case NetNet::SUPPLY1:
driven_ = V1;
return true;
default:
break;
}
if (! dynamic_cast<const NetConst*>(cur->get_obj())) {
driven_ = VAR;
return false;
}
}
return true;
@ -124,6 +129,10 @@ verinum::V driven_value(const Link&lnk)
/*
* $Log: link_const.cc,v $
* Revision 1.13 2002/06/24 01:49:39 steve
* Make link_drive_constant cache its results in
* the Nexus, to improve cprop performance.
*
* Revision 1.12 2002/06/19 04:18:46 steve
* Shuffle link_drivers_constant for speed.
*

View File

@ -19,7 +19,7 @@ const char COPYRIGHT[] =
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: main.cc,v 1.59 2002/06/06 18:57:18 steve Exp $"
#ident "$Id: main.cc,v 1.60 2002/06/24 01:49:39 steve Exp $"
#endif
# include "config.h"
@ -557,6 +557,9 @@ int main(int argc, char*argv[])
}
if (net_path) {
if (verbose_flag)
cerr<<" dumping netlist to " <<net_path<< "..." <<endl;
ofstream out (net_path);
des->dump(out);
}
@ -591,6 +594,10 @@ int main(int argc, char*argv[])
/*
* $Log: main.cc,v $
* Revision 1.60 2002/06/24 01:49:39 steve
* Make link_drive_constant cache its results in
* the Nexus, to improve cprop performance.
*
* Revision 1.59 2002/06/06 18:57:18 steve
* Use standard name for iostream.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: net_link.cc,v 1.6 2002/04/21 04:59:08 steve Exp $"
#ident "$Id: net_link.cc,v 1.7 2002/06/24 01:49:39 steve Exp $"
#endif
# include "config.h"
@ -42,11 +42,15 @@ void connect(Nexus*l, Link&r)
Nexus*tmp = r.nexus_;
while (Link*cur = tmp->first_nlink()) {
tmp->unlink(cur);
while (Link*cur = tmp->list_) {
tmp->list_ = cur->next_;
cur->nexus_ = 0;
cur->next_ = 0;
l->relink(cur);
}
l->driven_ = Nexus::NO_GUESS;
assert(tmp->list_ == 0);
delete tmp;
}
@ -54,22 +58,7 @@ void connect(Nexus*l, Link&r)
void connect(Link&l, Link&r)
{
assert(&l != &r);
assert(l.nexus_);
assert(r.nexus_);
/* If the links are already connected, then we're done. */
if (l.nexus_ == r.nexus_)
return;
Nexus*tmp = r.nexus_;
while (Link*cur = tmp->first_nlink()) {
tmp->unlink(cur);
l.nexus_->relink(cur);
}
assert(tmp->list_ == 0);
assert(l.is_linked(r));
delete tmp;
connect(l.nexus_, r);
}
Link::Link()
@ -226,6 +215,7 @@ Nexus::Nexus()
{
name_ = 0;
list_ = 0;
driven_ = NO_GUESS;
t_cookie_ = 0;
}
@ -445,6 +435,10 @@ unsigned NexusSet::bsearch_(Nexus*that)
/*
* $Log: net_link.cc,v $
* Revision 1.7 2002/06/24 01:49:39 steve
* Make link_drive_constant cache its results in
* the Nexus, to improve cprop performance.
*
* Revision 1.6 2002/04/21 04:59:08 steve
* Add support for conbinational events by finding
* the inputs to expressions and some statements.

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: netlist.h,v 1.245 2002/06/23 18:22:43 steve Exp $"
#ident "$Id: netlist.h,v 1.246 2002/06/24 01:49:39 steve Exp $"
#endif
/*
@ -246,6 +246,11 @@ class Nexus {
Link*first_nlink();
const Link* first_nlink()const;
/* This method returns true if all the possible drivers of
this nexus are constant. It will also return true if there
are no drivers at all. */
bool drivers_constant() const;
void* t_cookie() const;
void* t_cookie(void*) const;
@ -257,6 +262,9 @@ class Nexus {
mutable char* name_; /* Cache the calculated name for the Nexus. */
mutable void* t_cookie_;
enum VALUE { NO_GUESS, V0, V1, Vx, Vz, VAR };
mutable VALUE driven_;
private: // not implemented
Nexus(const Nexus&);
Nexus& operator= (const Nexus&);
@ -2929,6 +2937,10 @@ extern ostream& operator << (ostream&, NetNet::Type);
/*
* $Log: netlist.h,v $
* Revision 1.246 2002/06/24 01:49:39 steve
* Make link_drive_constant cache its results in
* the Nexus, to improve cprop performance.
*
* Revision 1.245 2002/06/23 18:22:43 steve
* spelling error.
*

View File

@ -19,7 +19,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: netmisc.h,v 1.12 2001/02/15 06:59:36 steve Exp $"
#ident "$Id: netmisc.h,v 1.13 2002/06/24 01:49:39 steve Exp $"
#endif
# include "netlist.h"
@ -33,13 +33,6 @@
extern NetExpr*pad_to_width(NetExpr*expr, unsigned wid);
extern NetNet*pad_to_width(Design*des, NetNet*n, unsigned w);
/*
* This local function returns true if all the the possible drivers of
* this link are constant. It will also return true if there are no
* drivers at all.
*/
extern bool link_drivers_constant(const Link&lnk);
/*
* This function returns the value of the constant driving this link,
* or Vz if there is no constant. The results of this function are
@ -64,6 +57,10 @@ extern NetExpr* elab_and_eval(Design*des, NetScope*scope, const PExpr*pe);
/*
* $Log: netmisc.h,v $
* Revision 1.13 2002/06/24 01:49:39 steve
* Make link_drive_constant cache its results in
* the Nexus, to improve cprop performance.
*
* Revision 1.12 2001/02/15 06:59:36 steve
* FreeBSD port has a maintainer now.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: t-dll.cc,v 1.86 2002/06/21 04:59:35 steve Exp $"
#ident "$Id: t-dll.cc,v 1.87 2002/06/24 01:49:39 steve Exp $"
#endif
# include "config.h"
@ -1028,7 +1028,7 @@ void dll_target::lpm_clshift(const NetCLShift*net)
/* Look at the direction input of the device, and select the
shift direction accordingly. */
if (net->pin_Direction().is_linked()) {
assert( link_drivers_constant(net->pin_Direction()) );
assert( net->pin_Direction().nexus()->drivers_constant() );
verinum::V dir = driven_value(net->pin_Direction());
switch (dir) {
@ -1950,6 +1950,10 @@ extern const struct target tgt_dll = { "dll", &dll_target_obj };
/*
* $Log: t-dll.cc,v $
* Revision 1.87 2002/06/24 01:49:39 steve
* Make link_drive_constant cache its results in
* the Nexus, to improve cprop performance.
*
* Revision 1.86 2002/06/21 04:59:35 steve
* Carry integerness throughout the compilation.
*

View File

@ -17,7 +17,7 @@
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
*/
#if !defined(WINNT) && !defined(macintosh)
#ident "$Id: xnfio.cc,v 1.20 2002/05/23 03:08:52 steve Exp $"
#ident "$Id: xnfio.cc,v 1.21 2002/06/24 01:49:39 steve Exp $"
#endif
# include "config.h"
@ -320,7 +320,7 @@ bool xnfio_f::compare_sideb_const(Design*des, NetCompare*dev)
/* Is the B side all constant? */
for (unsigned idx = 0 ; idx < dev->width() ; idx += 1) {
if (! link_drivers_constant(dev->pin_DataB(idx)))
if (! dev->pin_DataB(idx).nexus()->drivers_constant())
return false;
side.set(idx, driven_value(dev->pin_DataB(idx)));
@ -363,6 +363,10 @@ void xnfio(Design*des)
/*
* $Log: xnfio.cc,v $
* Revision 1.21 2002/06/24 01:49:39 steve
* Make link_drive_constant cache its results in
* the Nexus, to improve cprop performance.
*
* Revision 1.20 2002/05/23 03:08:52 steve
* Add language support for Verilog-2001 attribute
* syntax. Hook this support into existing $attribute