// OpenSTA, Static Timing Analyzer
// Copyright (c) 2022, Parallax Software, Inc.
// 
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
// 
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
// 
// You should have received a copy of the GNU General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.

#include "ConcreteNetwork.hh"

#include "DisallowCopyAssign.hh"
#include "PatternMatch.hh"
#include "Report.hh"
#include "Liberty.hh"
#include "PortDirection.hh"
#include "ConcreteLibrary.hh"
#include "Network.hh"

namespace sta {

static void
makeChildNetwork(Instance *proto,
		 Instance *parent,
		 ConcreteBindingTbl *parent_bindings,
		 NetworkReader *network);
static void
makeClonePins(Instance *proto,
	      Instance *clone,
	      Instance *clone_view,
	      ConcreteBindingTbl *bindings,
	      Instance *parent,
	      ConcreteBindingTbl *parent_bindings,
	      NetworkReader *network);

NetworkReader *
makeConcreteNetwork()
{
  return new ConcreteNetwork;
}

class ConcreteInstanceChildIterator : public InstanceChildIterator
{
public:
  explicit ConcreteInstanceChildIterator(ConcreteInstanceChildMap *map);
  bool hasNext();
  Instance *next();

private:
  ConcreteInstanceChildMap::ConstIterator iter_;
};

ConcreteInstanceChildIterator::
ConcreteInstanceChildIterator(ConcreteInstanceChildMap *map) :
  iter_(map)
{
}

bool
ConcreteInstanceChildIterator::hasNext()
{
  return iter_.hasNext();
}

Instance *
ConcreteInstanceChildIterator::next()
{
  return reinterpret_cast<Instance*>(iter_.next());
}

class ConcreteInstanceNetIterator : public InstanceNetIterator
{
public:
  explicit ConcreteInstanceNetIterator(ConcreteInstanceNetMap *nets);
  bool hasNext();
  Net *next();

private:
  DISALLOW_COPY_AND_ASSIGN(ConcreteInstanceNetIterator);
  void findNext();

  ConcreteInstanceNetMap::Iterator iter_;
  ConcreteNet *next_;
};

ConcreteInstanceNetIterator::
ConcreteInstanceNetIterator(ConcreteInstanceNetMap *nets):
  iter_(nets),
  next_(nullptr)
{
  findNext();
}

bool
ConcreteInstanceNetIterator::hasNext()
{
  return next_ != nullptr;
}

// Skip nets that have been merged.
void
ConcreteInstanceNetIterator::findNext()
{
  while (iter_.hasNext()) {
    next_ = iter_.next();
    if (next_->mergedInto() == nullptr)
      return;
  }
  next_ = nullptr;
}

Net *
ConcreteInstanceNetIterator::next()
{
  ConcreteNet *next = next_;
  findNext();
  return reinterpret_cast<Net*>(next);
}

////////////////////////////////////////////////////////////////

class ConcreteInstancePinIterator : public InstancePinIterator
{
public:
  ConcreteInstancePinIterator(const ConcreteInstance *inst,
			      int pin_count);
  bool hasNext();
  Pin *next();

private:
  DISALLOW_COPY_AND_ASSIGN(ConcreteInstancePinIterator);
  void findNext();

  ConcretePin **pins_;
  int pin_count_;
  int pin_index_;
  ConcretePin *next_;
};

ConcreteInstancePinIterator::
ConcreteInstancePinIterator(const ConcreteInstance *inst,
			    int pin_count) :
  pins_(inst->pins_),
  pin_count_(pin_count),
  pin_index_(0)
{
  findNext();
}

bool
ConcreteInstancePinIterator::hasNext()
{
  return next_ != nullptr;
}

Pin *
ConcreteInstancePinIterator::next()
{
  ConcretePin *next = next_;
  findNext();
  return reinterpret_cast<Pin*>(next);
}

// Skip over missing pins.
void
ConcreteInstancePinIterator::findNext()
{
  while (pin_index_ < pin_count_) {
    next_ = pins_[pin_index_++];
    if (next_)
      return;
  }
  next_ = nullptr;
}

////////////////////////////////////////////////////////////////

class ConcreteNetPinIterator : public NetPinIterator
{
public:
  explicit ConcreteNetPinIterator(const ConcreteNet *net);
  bool hasNext();
  Pin *next();

private:
  DISALLOW_COPY_AND_ASSIGN(ConcreteNetPinIterator);

  ConcretePin *next_;
};

ConcreteNetPinIterator::ConcreteNetPinIterator(const ConcreteNet *net) :
  next_(net->pins_)
{
}

bool
ConcreteNetPinIterator::hasNext()
{
  return next_ != nullptr;
}

Pin *
ConcreteNetPinIterator::next()
{
  ConcretePin *next = next_;
  next_ = next_->net_next_;
  return reinterpret_cast<Pin*>(next);
}

////////////////////////////////////////////////////////////////

class ConcreteNetTermIterator : public NetTermIterator
{
public:
  explicit ConcreteNetTermIterator(const ConcreteNet *net);
  bool hasNext();
  Term *next();

private:
  DISALLOW_COPY_AND_ASSIGN(ConcreteNetTermIterator);

  ConcreteTerm *next_;
};

ConcreteNetTermIterator::ConcreteNetTermIterator(const ConcreteNet *net) :
  next_(net->terms_)
{
}

bool
ConcreteNetTermIterator::hasNext()
{
  return next_ != nullptr;
}

Term *
ConcreteNetTermIterator::next()
{
  ConcreteTerm *next = next_;
  next_ = next_->net_next_;
  return reinterpret_cast<Term*>(next);
}

////////////////////////////////////////////////////////////////

ConcreteNetwork::ConcreteNetwork() :
  NetworkReader(),
  top_instance_(nullptr),
  link_func_(nullptr)
{
}

ConcreteNetwork::~ConcreteNetwork()
{
  clear();
}

void
ConcreteNetwork::clear()
{
  deleteTopInstance();
  deleteCellNetworkViews();
  library_seq_.deleteContentsClear();
  library_map_.clear();
  Network::clear();
}

void
ConcreteNetwork::deleteTopInstance()
{
  if (top_instance_) {
    deleteInstance(top_instance_);
    top_instance_ = nullptr;
  }
}

void
ConcreteNetwork::deleteCellNetworkViews()
{
  CellNetworkViewMap::Iterator view_iter(cell_network_view_map_);
  while (view_iter.hasNext()) {
    Instance *view = view_iter.next();
    if (view)
      deleteInstance(view);
  }
  cell_network_view_map_.clear();
}

Instance *
ConcreteNetwork::topInstance() const
{
  return top_instance_;
}

////////////////////////////////////////////////////////////////

class ConcreteLibraryIterator1 : public Iterator<Library*>
{
public:
  explicit ConcreteLibraryIterator1(const ConcreteLibrarySeq &lib_seq_);
  virtual bool hasNext();
  virtual Library *next();

private:
  DISALLOW_COPY_AND_ASSIGN(ConcreteLibraryIterator1);

  ConcreteLibraryIterator iter_;
};

ConcreteLibraryIterator1::ConcreteLibraryIterator1(const ConcreteLibrarySeq &lib_seq_):
  iter_(lib_seq_)
{
}

bool
ConcreteLibraryIterator1::hasNext()
{
  return iter_.hasNext();
}

Library *
ConcreteLibraryIterator1::next()
{
  return reinterpret_cast<Library*>(iter_.next());
}

LibraryIterator *
ConcreteNetwork::libraryIterator() const
{
  return new ConcreteLibraryIterator1(library_seq_);
}

////////////////////////////////////////////////////////////////

class ConcreteLibertyLibraryIterator : public Iterator<LibertyLibrary*>
{
public:
  explicit ConcreteLibertyLibraryIterator(const ConcreteNetwork *network);
  virtual ~ConcreteLibertyLibraryIterator();
  virtual bool hasNext();
  virtual LibertyLibrary *next();

private:
  DISALLOW_COPY_AND_ASSIGN(ConcreteLibertyLibraryIterator);
  void findNext();

  ConcreteLibrarySeq::ConstIterator iter_;
  LibertyLibrary *next_;
};

ConcreteLibertyLibraryIterator::
ConcreteLibertyLibraryIterator(const ConcreteNetwork *network):
  iter_(network->library_seq_),
  next_(nullptr)
{
  findNext();
}

ConcreteLibertyLibraryIterator::~ConcreteLibertyLibraryIterator()
{
}

bool
ConcreteLibertyLibraryIterator::hasNext()
{
  return next_ != nullptr;
}

LibertyLibrary *
ConcreteLibertyLibraryIterator::next()
{
  LibertyLibrary *next = next_;
  findNext();
  return next;
}

void
ConcreteLibertyLibraryIterator::findNext()
{
  next_ = nullptr;
  while (iter_.hasNext()) {
    ConcreteLibrary *lib = iter_.next();
    if (lib->isLiberty()) {
      LibertyLibrary *liberty = static_cast<LibertyLibrary*>(lib);
      if (liberty) {
	next_ = liberty;
	break;
      }
    }
  }
}

LibertyLibraryIterator *
ConcreteNetwork::libertyLibraryIterator() const
{
  return new ConcreteLibertyLibraryIterator(this);
}

////////////////////////////////////////////////////////////////

Library *
ConcreteNetwork::makeLibrary(const char *name,
			     const char *filename)
{
  ConcreteLibrary *library = new ConcreteLibrary(name, filename, false);
  addLibrary(library);
  return reinterpret_cast<Library*>(library);
}

LibertyLibrary *
ConcreteNetwork::makeLibertyLibrary(const char *name,
				    const char *filename)
{
  LibertyLibrary *library = new LibertyLibrary(name, filename);
  addLibrary(library);
  return library;
}

void
ConcreteNetwork::addLibrary(ConcreteLibrary *library)
{
  library_seq_.push_back(library);
  library_map_[library->name()] = library;
}

Library *
ConcreteNetwork::findLibrary(const char *name)
{
  return reinterpret_cast<Library*>(library_map_.findKey(name));
}

void
ConcreteNetwork::deleteLibrary(Library *library)
{
  ConcreteLibrary *clib = reinterpret_cast<ConcreteLibrary*>(library);
  library_map_.erase(clib->name());
  library_seq_.eraseObject(clib);
  delete clib;
}

const char *
ConcreteNetwork::name(const Library *library) const
{
  const ConcreteLibrary *clib =
    reinterpret_cast<const ConcreteLibrary*>(library);
  return clib->name();
}

LibertyLibrary *
ConcreteNetwork::findLiberty(const char *name)
{
  ConcreteLibrary *lib =  library_map_.findKey(name);
  if (lib) {
    if (lib->isLiberty())
      return static_cast<LibertyLibrary*>(lib);
    // Potential name conflict
    else {
      for (ConcreteLibrary *lib : library_seq_) {
	if (stringEq(lib->name(), name)
	    && lib->isLiberty())
	  return static_cast<LibertyLibrary*>(lib);
      }
    }
  }
  return nullptr;
}

LibertyLibrary *
ConcreteNetwork::libertyLibrary(Library *library) const
{
  ConcreteLibrary *lib = reinterpret_cast<ConcreteLibrary*>(library);
  return static_cast<LibertyLibrary*>(lib);
}

Cell *
ConcreteNetwork::makeCell(Library *library,
			  const char *name,
			  bool is_leaf,
			  const char *filename)
{
  ConcreteLibrary *clib = reinterpret_cast<ConcreteLibrary*>(library);
  return reinterpret_cast<Cell*>(clib->makeCell(name, is_leaf, filename));
}

Cell *
ConcreteNetwork::findCell(const Library *library,
			  const char *name) const
{
  const ConcreteLibrary *clib =
    reinterpret_cast<const ConcreteLibrary*>(library);
  return reinterpret_cast<Cell*>(clib->findCell(name));
}

Cell *
ConcreteNetwork::findAnyCell(const char *name)
{
  ConcreteLibrarySeq::Iterator lib_iter(library_seq_);
  while (lib_iter.hasNext()) {
    ConcreteLibrary *lib = lib_iter.next();
    ConcreteCell *cell = lib->findCell(name);
    if (cell)
      return reinterpret_cast<Cell*>(cell);
  }
  return nullptr;
}

void
ConcreteNetwork::findCellsMatching(const Library *library,
				   const PatternMatch *pattern,
				   CellSeq *cells) const
{
  const ConcreteLibrary *clib =
    reinterpret_cast<const ConcreteLibrary*>(library);
  clib->findCellsMatching(pattern, cells);
}

void
ConcreteNetwork::deleteCell(Cell *cell)
{
  ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell);
  ConcreteLibrary *clib = ccell->library();
  clib->deleteCell(ccell);
}

////////////////////////////////////////////////////////////////

const char *
ConcreteNetwork::name(const Cell *cell) const
{
  const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
  return ccell->name();
}

void
ConcreteNetwork::setName(Cell *cell,
			 const char *name)
{
  ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell);
  ccell->setName(name);
}

void
ConcreteNetwork::setIsLeaf(Cell *cell,
			   bool is_leaf)
{
  ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell);
  ccell->setIsLeaf(is_leaf);
}

Library *
ConcreteNetwork::library(const Cell *cell) const
{
  const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
  return reinterpret_cast<Library*>(ccell->library());
}

LibertyCell *
ConcreteNetwork::libertyCell(Cell *cell) const
{
  ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell);
  return ccell->libertyCell();
}

const LibertyCell *
ConcreteNetwork::libertyCell(const Cell *cell) const
{
  const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
  return ccell->libertyCell();
}

Cell *
ConcreteNetwork::cell(LibertyCell *cell) const
{
  return reinterpret_cast<Cell*>(cell);
}

const Cell *
ConcreteNetwork::cell(const LibertyCell *cell) const
{
  return reinterpret_cast<const Cell*>(cell);
}

const char *
ConcreteNetwork::filename(const Cell *cell)
{
  const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
  return ccell->filename();
}

Port *
ConcreteNetwork::findPort(const Cell *cell,
			  const char *name) const
{
  const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
  return reinterpret_cast<Port*>(ccell->findPort(name));
}

void
ConcreteNetwork::findPortsMatching(const Cell *cell,
				   const PatternMatch *pattern,
				   PortSeq *ports) const
{
  const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
  ccell->findPortsMatching(pattern, ports);
}

bool
ConcreteNetwork::isLeaf(const Cell *cell) const
{
  const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
  return ccell->isLeaf();
}

Port *
ConcreteNetwork::makePort(Cell *cell,
			  const char *name)
{
  ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell);
  ConcretePort *port = ccell->makePort(name);
  return reinterpret_cast<Port*>(port);
}

Port *
ConcreteNetwork::makeBusPort(Cell *cell,
			     const char *name,
			     int from_index,
			     int to_index)
{
  ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell);
  ConcretePort *port = ccell->makeBusPort(name, from_index, to_index);
  return reinterpret_cast<Port*>(port);
}

void
ConcreteNetwork::groupBusPorts(Cell *cell,
                               std::function<bool(const char*)> port_msb_first)
{
  Library *lib = library(cell);
  ConcreteLibrary *clib = reinterpret_cast<ConcreteLibrary*>(lib);
  ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell);
  ccell->groupBusPorts(clib->busBrktLeft(), clib->busBrktRight(), port_msb_first);
}

Port *
ConcreteNetwork::makeBundlePort(Cell *cell,
				const char *name,
				PortSeq *members)
{
  ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell);
  ConcretePortSeq *cmembers = reinterpret_cast<ConcretePortSeq*>(members);
  ConcretePort *port = ccell->makeBundlePort(name, cmembers);
  return reinterpret_cast<Port*>(port);
}

void
ConcreteNetwork::setDirection(Port *port,
			      PortDirection *dir)
{
  ConcretePort *cport = reinterpret_cast<ConcretePort*>(port);
  cport->setDirection(dir);
}

////////////////////////////////////////////////////////////////

class ConcreteCellPortIterator1 : public CellPortIterator
{
public:
  explicit ConcreteCellPortIterator1(const ConcreteCell *cell);
  ~ConcreteCellPortIterator1();
  virtual bool hasNext() { return iter_->hasNext(); }
  virtual Port *next();

private:
  DISALLOW_COPY_AND_ASSIGN(ConcreteCellPortIterator1);

  ConcreteCellPortIterator *iter_;
};

ConcreteCellPortIterator1::ConcreteCellPortIterator1(const ConcreteCell *cell):
  iter_(cell->portIterator())
{
}

ConcreteCellPortIterator1::~ConcreteCellPortIterator1()
{
  delete iter_;
}

Port *
ConcreteCellPortIterator1::next()
{
  return reinterpret_cast<Port*>(iter_->next());
}

CellPortIterator *
ConcreteNetwork::portIterator(const Cell *cell) const
{
  const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
  return new ConcreteCellPortIterator1(ccell);
}

////////////////////////////////////////////////////////////////

class ConcreteCellPortBitIterator1 : public CellPortIterator
{
public:
  explicit ConcreteCellPortBitIterator1(const ConcreteCell *cell);
  ~ConcreteCellPortBitIterator1();
  virtual bool hasNext() { return iter_->hasNext(); }
  virtual Port *next();

private:
  DISALLOW_COPY_AND_ASSIGN(ConcreteCellPortBitIterator1);

  ConcreteCellPortBitIterator *iter_;
};

ConcreteCellPortBitIterator1::ConcreteCellPortBitIterator1(const ConcreteCell *cell):
  iter_(cell->portBitIterator())
{
}

ConcreteCellPortBitIterator1::~ConcreteCellPortBitIterator1()
{
  delete iter_;
}

Port *
ConcreteCellPortBitIterator1::next()
{
  return reinterpret_cast<Port*>(iter_->next());
}

CellPortBitIterator *
ConcreteNetwork::portBitIterator(const Cell *cell) const
{
  const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
  return new ConcreteCellPortBitIterator1(ccell);
}

int
ConcreteNetwork::portBitCount(const Cell *cell) const
{
  const ConcreteCell *ccell = reinterpret_cast<const ConcreteCell*>(cell);
  return ccell->portBitCount();
}

////////////////////////////////////////////////////////////////

const char *
ConcreteNetwork::name(const Port *port) const
{
  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
  return cport->name();
}

Cell *
ConcreteNetwork::cell(const Port *port) const
{
  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
  return cport->cell();
}

LibertyPort *
ConcreteNetwork::libertyPort(const Port *port) const
{
  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
  return cport->libertyPort();
}

PortDirection *
ConcreteNetwork::direction(const Port *port) const
{
  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
  return cport->direction();
}

bool
ConcreteNetwork::isBundle(const Port *port) const
{
  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
  return cport->isBundle();
}

bool
ConcreteNetwork::isBus(const Port *port) const
{
  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
  return cport->isBus();
}

const char *
ConcreteNetwork::busName(const Port *port) const
{
  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
  return cport->busName();
}

int
ConcreteNetwork::size(const Port *port) const
{
  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
  return cport->size();
}

int
ConcreteNetwork::fromIndex(const Port *port) const
{
  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
  return cport->fromIndex();
}

int
ConcreteNetwork::toIndex(const Port *port) const
{
  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
  return cport->toIndex();
}

Port *
ConcreteNetwork::findBusBit(const Port *port,
			    int index) const
{
  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
  return reinterpret_cast<Port*>(cport->findBusBit(index));
}

Port *
ConcreteNetwork::findMember(const Port *port,
			    int index) const
{
  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
  return reinterpret_cast<Port*>(cport->findMember(index));
}

bool
ConcreteNetwork::hasMembers(const Port *port) const
{
  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
  return cport->hasMembers();
}

////////////////////////////////////////////////////////////////

class ConcretePortMemberIterator1 : public PortMemberIterator
{
public:
  explicit ConcretePortMemberIterator1(const ConcretePort *port);
  ~ConcretePortMemberIterator1();
  virtual bool hasNext() { return iter_->hasNext(); }
  virtual Port *next();

private:
  DISALLOW_COPY_AND_ASSIGN(ConcretePortMemberIterator1);

  ConcretePortMemberIterator *iter_;
};

ConcretePortMemberIterator1::ConcretePortMemberIterator1(const ConcretePort *
							 port) :
  iter_(port->memberIterator())
{
}

ConcretePortMemberIterator1::~ConcretePortMemberIterator1()
{
  delete iter_;
}

Port *
ConcretePortMemberIterator1::next()
{
  return reinterpret_cast<Port*>(iter_->next());
}

PortMemberIterator *
ConcreteNetwork::memberIterator(const Port *port) const
{
  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
  return new ConcretePortMemberIterator1(cport);
}

////////////////////////////////////////////////////////////////

const char *
ConcreteNetwork::name(const Instance *instance) const
{
  const ConcreteInstance *inst =
    reinterpret_cast<const ConcreteInstance*>(instance);
  return inst->name();
}

Cell *
ConcreteNetwork::cell(const Instance *instance) const
{
  const ConcreteInstance *inst =
    reinterpret_cast<const ConcreteInstance*>(instance);
  return inst->cell();
}

Instance *
ConcreteNetwork::parent(const Instance *instance) const
{
  const ConcreteInstance *inst =
    reinterpret_cast<const ConcreteInstance*>(instance);
  return reinterpret_cast<Instance*>(inst->parent());
}

bool
ConcreteNetwork::isLeaf(const Instance *instance) const
{
  const ConcreteInstance *inst =
    reinterpret_cast<const ConcreteInstance*>(instance);
  ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(inst->cell());
  return ccell->isLeaf();
}

Instance *
ConcreteNetwork::findChild(const Instance *parent,
			   const char *name) const
{
  const ConcreteInstance *inst =
    reinterpret_cast<const ConcreteInstance*>(parent);
  return inst->findChild(name);
}

Pin *
ConcreteNetwork::findPin(const Instance *instance,
			 const char *port_name) const
{
  const ConcreteInstance *inst =
    reinterpret_cast<const ConcreteInstance*>(instance);
  return reinterpret_cast<Pin*>(inst->findPin(port_name));
}

Pin *
ConcreteNetwork::findPin(const Instance *instance,
			 const Port *port) const
{
  const ConcreteInstance *inst =
    reinterpret_cast<const ConcreteInstance*>(instance);
  return reinterpret_cast<Pin*>(inst->findPin(port));
}

Net *
ConcreteNetwork::findNet(const Instance *instance,
			 const char *net_name) const
{
  const ConcreteInstance *inst =
    reinterpret_cast<const ConcreteInstance*>(instance);
  return reinterpret_cast<Net*>(inst->findNet(net_name));
}

void
ConcreteNetwork::findInstNetsMatching(const Instance *instance,
				      const PatternMatch *pattern,
				      NetSeq *nets) const
{
  const ConcreteInstance *inst =
    reinterpret_cast<const ConcreteInstance*>(instance);
  inst->findNetsMatching(pattern, nets);
}

////////////////////////////////////////////////////////////////

InstanceChildIterator *
ConcreteNetwork::childIterator(const Instance *instance) const
{
  const ConcreteInstance *inst =
    reinterpret_cast<const ConcreteInstance*>(instance);
  return inst->childIterator();
}

InstancePinIterator *
ConcreteNetwork::pinIterator(const Instance *instance) const
{
  const ConcreteInstance *inst =
    reinterpret_cast<const ConcreteInstance*>(instance);
  ConcreteCell *cell = reinterpret_cast<ConcreteCell*>(inst->cell());
  int pin_count = cell->portBitCount();
  return new ConcreteInstancePinIterator(inst, pin_count);
}

InstanceNetIterator *
ConcreteNetwork::netIterator(const Instance *instance) const
{
  const ConcreteInstance *inst =
    reinterpret_cast<const ConcreteInstance*>(instance);
  return inst->netIterator();
}

////////////////////////////////////////////////////////////////

Instance *
ConcreteNetwork::instance(const Pin *pin) const
{
  const ConcretePin *cpin = reinterpret_cast<const ConcretePin*>(pin);
  return reinterpret_cast<Instance*>(cpin->instance());
}

Net *
ConcreteNetwork::net(const Pin *pin) const
{
  const ConcretePin *cpin = reinterpret_cast<const ConcretePin*>(pin);
  return reinterpret_cast<Net*>(cpin->net());
}

Term *
ConcreteNetwork::term(const Pin *pin) const
{
  const ConcretePin *cpin = reinterpret_cast<const ConcretePin*>(pin);
  return reinterpret_cast<Term*>(cpin->term());
}

Port *
ConcreteNetwork::port(const Pin *pin) const
{
  const ConcretePin *cpin = reinterpret_cast<const ConcretePin*>(pin);
  return reinterpret_cast<Port*>(cpin->port());
}

PortDirection *
ConcreteNetwork::direction(const Pin *pin) const
{
  const ConcretePin *cpin = reinterpret_cast<const ConcretePin*>(pin);
  const ConcretePort *cport = cpin->port();
  return cport->direction();
}

VertexId
ConcreteNetwork::vertexId(const Pin *pin) const
{
  const ConcretePin *cpin = reinterpret_cast<const ConcretePin*>(pin);
  return cpin->vertexId();
}

void
ConcreteNetwork::setVertexId(Pin *pin,
			     VertexId id)
{
  ConcretePin *cpin = reinterpret_cast<ConcretePin*>(pin);
  cpin->setVertexId(id);
}

////////////////////////////////////////////////////////////////

Net *
ConcreteNetwork::net(const Term *term) const
{
  const ConcreteTerm *cterm = reinterpret_cast<const ConcreteTerm*>(term);
  return reinterpret_cast<Net*>(cterm->net());
}

Pin *
ConcreteNetwork::pin(const Term *term) const
{
  const ConcreteTerm *cterm = reinterpret_cast<const ConcreteTerm*>(term);
  return reinterpret_cast<Pin*>(cterm->pin());
}

////////////////////////////////////////////////////////////////

const char *
ConcreteNetwork::name(const Net *net) const
{
  const ConcreteNet *cnet = reinterpret_cast<const ConcreteNet*>(net);
  return cnet->name();
}

Instance *
ConcreteNetwork::instance(const Net *net) const
{
  const ConcreteNet *cnet = reinterpret_cast<const ConcreteNet*>(net);
  return reinterpret_cast<Instance*>(cnet->instance());
}

bool
ConcreteNetwork::isPower(const Net *net) const
{
  return constant_nets_[int(LogicValue::one)].hasKey(const_cast<Net*>(net));
}

bool
ConcreteNetwork::isGround(const Net *net) const
{
  return constant_nets_[int(LogicValue::zero)].hasKey(const_cast<Net*>(net));
}

NetPinIterator *
ConcreteNetwork::pinIterator(const Net *net) const
{
  const ConcreteNet *cnet = reinterpret_cast<const ConcreteNet*>(net);
  return new ConcreteNetPinIterator(cnet);
}

NetTermIterator *
ConcreteNetwork::termIterator(const Net *net) const
{
  const ConcreteNet *cnet = reinterpret_cast<const ConcreteNet*>(net);
  return new ConcreteNetTermIterator(cnet);
}

void
ConcreteNetwork::mergeInto(Net *net,
			   Net *into_net)
{
  ConcreteNet *cnet = reinterpret_cast<ConcreteNet*>(net);
  ConcreteNet *cinto_net = reinterpret_cast<ConcreteNet*>(into_net);
  cnet->mergeInto(cinto_net);
  clearNetDrvrPinMap();
}

Net *
ConcreteNetwork::mergedInto(Net *net)
{
  ConcreteNet *cnet = reinterpret_cast<ConcreteNet*>(net);
  return reinterpret_cast<Net*>(cnet->mergedInto());
}

////////////////////////////////////////////////////////////////

Cell *
ConcreteInstance::cell() const
{
  return reinterpret_cast<Cell*>(cell_);
}

Instance *
ConcreteNetwork::makeInstance(Cell *cell,
			      const char *name,
			      Instance *parent)
{
  ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell);
  return makeConcreteInstance(ccell, name, parent);
}

Instance *
ConcreteNetwork::makeInstance(LibertyCell *cell,
			      const char *name,
			      Instance *parent)
{
  return makeConcreteInstance(cell, name, parent);
}

Instance *
ConcreteNetwork::makeConcreteInstance(ConcreteCell *cell,
				      const char *name,
				      Instance *parent)
{
  ConcreteInstance *cparent =
    reinterpret_cast<ConcreteInstance*>(parent);
  ConcreteInstance *inst = new ConcreteInstance(cell, name, cparent);
  if (parent)
    cparent->addChild(inst);
  return reinterpret_cast<Instance*>(inst);
}

void
ConcreteNetwork::makePins(Instance *inst)
{
  CellPortBitIterator *port_iterator = portBitIterator(cell(inst));
  while (port_iterator->hasNext()) {
    Port *port = port_iterator->next();
    makePin(inst, port, nullptr);
  }
  delete port_iterator;
}

void
ConcreteNetwork::replaceCell(Instance *inst,
			     Cell *cell)
{
  ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell);
  int port_count = ccell->portBitCount();
  ConcreteInstance *cinst = reinterpret_cast<ConcreteInstance*>(inst);
  // Port count picked from Instance instead of Target cells-Dinesh A
  ConcreteCell *instcell = reinterpret_cast<ConcreteCell*>(cinst->cell());
  int inst_port_count = instcell->portBitCount();
  ConcretePin **pins = cinst->pins_;
  ConcretePin **rpins = new ConcretePin*[port_count];
  for (int i = 0; i < port_count; i++) 
    rpins[i] = pins[inst_port_count-1];
  for (int i = 0; i < inst_port_count; i++) {
    ConcretePin *cpin = pins[i];
    if (cpin) {
      ConcretePort *pin_cport = reinterpret_cast<ConcretePort*>(cpin->port());
      ConcretePort *cport = ccell->findPort(pin_cport->name());
      if (cport) {
        rpins[cport->pinIndex()] = cpin;
        cpin->port_ = cport;
      }
    }
  }
  delete [] pins;
  cinst->pins_ = rpins;
  cinst->setCell(ccell);
}

void
ConcreteNetwork::deleteInstance(Instance *inst)
{
  ConcreteInstance *cinst = reinterpret_cast<ConcreteInstance*>(inst);

  // Delete nets first (so children pin deletes are not required).
  ConcreteInstanceNetMap::Iterator net_iter(cinst->nets_);
  while (net_iter.hasNext()) {
    ConcreteNet *cnet = net_iter.next();
    Net *net = reinterpret_cast<Net*>(cnet);
    // Delete terminals connected to net.
    NetTermIterator *term_iter = termIterator(net);
    while (term_iter->hasNext()) {
      ConcreteTerm *term = reinterpret_cast<ConcreteTerm*>(term_iter->next());
      delete term;
    }
    delete term_iter;
    deleteNet(net);
  }

  // Delete children.
  InstanceChildIterator *child_iter = childIterator(inst);
  while (child_iter->hasNext()) {
    Instance *child = child_iter->next();
    deleteInstance(child);
  }
  delete child_iter;

  InstancePinIterator *pin_iter = pinIterator(inst);
  while (pin_iter->hasNext()) {
    Pin *pin = pin_iter->next();
    deletePin(pin);
  }
  delete pin_iter;

  Instance *parent_inst = parent(inst);
  if (parent_inst) {
    ConcreteInstance *cparent =
      reinterpret_cast<ConcreteInstance*>(parent_inst);
    cparent->deleteChild(cinst);
  }
  delete cinst;
}

Pin *
ConcreteNetwork::makePin(Instance *inst,
			 Port *port,
			 Net *net)
{
  ConcreteInstance *cinst = reinterpret_cast<ConcreteInstance*>(inst);
  ConcretePort *cport = reinterpret_cast<ConcretePort*>(port);
  ConcreteNet *cnet = reinterpret_cast<ConcreteNet*>(net);
  ConcretePin *cpin = new ConcretePin(cinst, cport, cnet);
  cinst->addPin(cpin);
  if (cnet)
    connectNetPin(cnet, cpin);
  return reinterpret_cast<Pin*>(cpin);
}

Term *
ConcreteNetwork::makeTerm(Pin *pin,
			  Net *net)
{
  ConcretePin *cpin = reinterpret_cast<ConcretePin*>(pin);
  ConcreteNet *cnet = reinterpret_cast<ConcreteNet*>(net);
  ConcreteTerm *cterm = new ConcreteTerm(cpin, cnet);
  if (cnet)
    cnet->addTerm(cterm);
  cpin->term_ = cterm;
  return reinterpret_cast<Term*>(cterm);
}

Pin *
ConcreteNetwork::connect(Instance *inst,
			 LibertyPort *port,
			 Net *net)
{
  return connect(inst, reinterpret_cast<Port*>(port), net);
}

Pin *
ConcreteNetwork::connect(Instance *inst,
			 Port *port,
			 Net *net)
{
  ConcreteNet *cnet = reinterpret_cast<ConcreteNet*>(net);
  ConcreteInstance *cinst = reinterpret_cast<ConcreteInstance*>(inst);
  ConcretePort *cport = reinterpret_cast<ConcretePort*>(port);
  ConcretePin *cpin = cinst->findPin(port);
  if (cpin) {
    ConcreteNet *prev_net = cpin->net_;
    if (prev_net)
      disconnectNetPin(prev_net, cpin);
  }
  else {
    cpin = new ConcretePin(cinst, cport, cnet);
    cinst->addPin(cpin);
  }
  if (inst == top_instance_) {
    // makeTerm
    ConcreteTerm *cterm = new ConcreteTerm(cpin, cnet);
    cnet->addTerm(cterm);
    cpin->term_ = cterm;
    cpin->net_ = nullptr;
  }
  else {
    cpin->net_ = cnet;
    connectNetPin(cnet, cpin);
  }
  return reinterpret_cast<Pin*>(cpin);
}

void
ConcreteNetwork::connectNetPin(ConcreteNet *cnet,
			       ConcretePin *cpin)
{
  cnet->addPin(cpin);

  // If there are no terminals the net does not span hierarchy levels
  // and it is safe to incrementally update the drivers.
  Pin *pin = reinterpret_cast<Pin*>(cpin);
  if (isDriver(pin)) {
    if (cnet->terms_ == nullptr) {
      Net *net = reinterpret_cast<Net*>(cnet);
      PinSet *drvrs = net_drvr_pin_map_.findKey(net);
      if (drvrs)
	drvrs->insert(pin);
    }
    else
      clearNetDrvrPinMap();
  }
}

void
ConcreteNetwork::disconnectPin(Pin *pin)
{
  ConcretePin *cpin = reinterpret_cast<ConcretePin*>(pin);
  if (reinterpret_cast<Instance*>(cpin->instance()) == top_instance_) {
    ConcreteTerm *cterm = cpin->term_;
    if (cterm) {
      ConcreteNet *cnet = cterm->net_;
      if (cnet) {
	cnet->deleteTerm(cterm);
	clearNetDrvrPinMap();
      }
      cpin->term_ = nullptr;
      delete cterm;
    }
  }
  else {
    ConcreteNet *cnet = cpin->net();
    if (cnet)
      disconnectNetPin(cnet, cpin);
    cpin->net_ = nullptr;
  }
}

void
ConcreteNetwork::disconnectNetPin(ConcreteNet *cnet,
				  ConcretePin *cpin)
{
  cnet->deletePin(cpin);

  Pin *pin = reinterpret_cast<Pin*>(cpin);
  if (isDriver(pin)) {
    ConcreteNet *cnet = cpin->net();
    // If there are no terminals the net does not span hierarchy levels
    // and it is safe to incrementally update the drivers.
    if (cnet->terms_ == nullptr) {
      Net *net = reinterpret_cast<Net*>(cnet);
      PinSet *drvrs = net_drvr_pin_map_.findKey(net);
      if (drvrs)
	drvrs->erase(pin);
    }
    else
      clearNetDrvrPinMap();
  }
}

void
ConcreteNetwork::deletePin(Pin *pin)
{
  ConcretePin *cpin = reinterpret_cast<ConcretePin*>(pin);
  ConcreteNet *cnet = cpin->net();
  if (cnet)
    disconnectNetPin(cnet, cpin);
  ConcreteInstance *cinst =
    reinterpret_cast<ConcreteInstance*>(cpin->instance());
  if (cinst)
    cinst->deletePin(cpin);
  delete cpin;
}

Net *
ConcreteNetwork::makeNet(const char *name,
			 Instance *parent)
{
  ConcreteInstance *cparent = reinterpret_cast<ConcreteInstance*>(parent);
  ConcreteNet *net = new ConcreteNet(name, cparent);
  cparent->addNet(net);
  return reinterpret_cast<Net*>(net);
}

void
ConcreteNetwork::deleteNet(Net *net)
{
  ConcreteNet *cnet = reinterpret_cast<ConcreteNet*>(net);
  ConcreteNetPinIterator pin_iter(cnet);
  while (pin_iter.hasNext()) {
    ConcretePin *pin = reinterpret_cast<ConcretePin*>(pin_iter.next());
    // Do NOT use net->disconnectPin because it would be N^2
    // to delete all of the pins from the net.
    pin->net_ = nullptr;
  }

  constant_nets_[int(LogicValue::zero)].erase(net);
  constant_nets_[int(LogicValue::one)].erase(net);
  PinSet *drvrs = net_drvr_pin_map_.findKey(net);
  if (drvrs) {
    delete drvrs;
    net_drvr_pin_map_.erase(net);
  }

  ConcreteInstance *cinst =
    reinterpret_cast<ConcreteInstance*>(cnet->instance());
  cinst->deleteNet(cnet);
  delete cnet;
}

void
ConcreteNetwork::clearConstantNets()
{
  constant_nets_[int(LogicValue::zero)].clear();
  constant_nets_[int(LogicValue::one)].clear();
}

void
ConcreteNetwork::addConstantNet(Net *net,
				LogicValue value)
{
  if (value == LogicValue::zero
      || value == LogicValue::one)
    constant_nets_[int(value)].insert(net);
}

ConstantPinIterator *
ConcreteNetwork::constantPinIterator()
{
  return new NetworkConstantPinIterator(this,
					constant_nets_[int(LogicValue::zero)],
					constant_nets_[int(LogicValue::one)]);
}

////////////////////////////////////////////////////////////////

// Optimized version of Network::visitConnectedPins.
void
ConcreteNetwork::visitConnectedPins(const Net *net,
				    PinVisitor &visitor,
				    ConstNetSet &visited_nets) const
{
  if (!visited_nets.hasKey(net)) {
    visited_nets.insert(net);
    // Search up from net terminals.
    const ConcreteNet *cnet = reinterpret_cast<const ConcreteNet*>(net);
    for (ConcreteTerm *term = cnet->terms_; term; term = term->net_next_) {
      ConcretePin *above_pin = term->pin_;
      if (above_pin) {
	ConcreteNet *above_net = above_pin->net_;
	if (above_net)
	  visitConnectedPins(reinterpret_cast<Net*>(above_net),
			     visitor, visited_nets);
	else
	  visitor(reinterpret_cast<Pin*>(above_pin));
      }
    }

    // Search down from net pins.
    for (ConcretePin *pin = cnet->pins_; pin; pin = pin->net_next_) {
      visitor(reinterpret_cast<Pin*>(pin));
      ConcreteTerm *below_term = pin->term_;
      if (below_term) {
	ConcreteNet *below_net = below_term->net_;
	if (below_net)
	  visitConnectedPins(reinterpret_cast<Net*>(below_net),
			     visitor, visited_nets);
      }
    }
  }
}

////////////////////////////////////////////////////////////////

ConcreteInstance::ConcreteInstance(ConcreteCell *cell,
				   const char *name,
				   ConcreteInstance *parent) :
  cell_(cell),
  name_(stringCopy(name)),
  parent_(parent),
  children_(nullptr),
  nets_(nullptr)
{
  initPins();
}

void
ConcreteInstance::initPins()
{
  int pin_count = reinterpret_cast<ConcreteCell*>(cell_)->portBitCount();
  if (pin_count) {
    pins_ = new ConcretePin*[pin_count];
    for (int i = 0; i < pin_count; i++)
      pins_[i] = nullptr;
  }
  else
    pins_ = nullptr;
}

ConcreteInstance::~ConcreteInstance()
{
  stringDelete(name_);
  delete [] pins_;
  delete children_;
  delete nets_;
}

Instance *
ConcreteInstance::findChild(const char *name) const
{
  if (children_)
    return reinterpret_cast<Instance*>(children_->findKey(name));
  else
    return nullptr;
}

ConcretePin *
ConcreteInstance::findPin(const char *port_name) const
{
  ConcreteCell *ccell = reinterpret_cast<ConcreteCell*>(cell_);
  const ConcretePort *cport =
    reinterpret_cast<const ConcretePort*>(ccell->findPort(port_name));
  if (cport
      && !cport->isBus())
    return pins_[cport->pinIndex()];
  else
    return nullptr;
}

ConcretePin *
ConcreteInstance::findPin(const Port *port) const
{
  const ConcretePort *cport = reinterpret_cast<const ConcretePort*>(port);
  return pins_[cport->pinIndex()];
}

ConcreteNet *
ConcreteInstance::findNet(const char *net_name) const
{
  ConcreteNet *net = nullptr;
  if (nets_) {
    net = nets_->findKey(net_name);
    // Follow merge pointer to surviving net.
    if (net) {
      while (net->mergedInto())
	net = net->mergedInto();
    }
  }
  return net;
}

void
ConcreteInstance::findNetsMatching(const PatternMatch *pattern,
				   NetSeq *nets) const
{
  if (pattern->hasWildcards()) {
    ConcreteInstanceNetMap::Iterator net_iter(nets_);
    while (net_iter.hasNext()) {
      const char *net_name;
      ConcreteNet *cnet;
      net_iter.next(net_name, cnet);
      if (pattern->match(net_name))
	nets->push_back(reinterpret_cast<Net*>(cnet));
    }
  }
  else {
    ConcreteNet *cnet = findNet(pattern->pattern());
    if (cnet)
      nets->push_back(reinterpret_cast<Net*>(cnet));
  }
}

InstanceNetIterator *
ConcreteInstance::netIterator() const
{
  return reinterpret_cast<InstanceNetIterator*>
    (new ConcreteInstanceNetIterator(nets_));
}

InstanceChildIterator *
ConcreteInstance::childIterator() const
{
  return new ConcreteInstanceChildIterator(children_);
}

void
ConcreteInstance::addChild(ConcreteInstance *child)
{
  if (children_ == nullptr)
    children_ = new ConcreteInstanceChildMap;
  (*children_)[child->name()] = child;
}

void
ConcreteInstance::deleteChild(ConcreteInstance *child)
{
  children_->erase(child->name());
}

void
ConcreteInstance::addPin(ConcretePin *pin)
{
  ConcretePort *cport = reinterpret_cast<ConcretePort *>(pin->port());
  pins_[cport->pinIndex()] = pin;
}

void
ConcreteInstance::deletePin(ConcretePin *pin)
{
  ConcretePort *cport = reinterpret_cast<ConcretePort *>(pin->port());
  pins_[cport->pinIndex()] = nullptr;
}

void
ConcreteInstance::addNet(ConcreteNet *net)
{
  if (nets_ == nullptr)
    nets_ = new ConcreteInstanceNetMap;
  (*nets_)[net->name()] = net;
}

void
ConcreteInstance::addNet(const char *name,
			 ConcreteNet *net)
{
  if (nets_ == nullptr)
    nets_ = new ConcreteInstanceNetMap;
  (*nets_)[name] = net;
}

void
ConcreteInstance::deleteNet(ConcreteNet *net)
{
  nets_->erase(net->name());
}

void
ConcreteInstance::setCell(ConcreteCell *cell)
{
  cell_ = cell;
}

////////////////////////////////////////////////////////////////

ConcretePin::ConcretePin(ConcreteInstance *instance,
			 ConcretePort *port,
			 ConcreteNet *net) :
  instance_(instance),
  port_(port),
  net_(net),
  term_(nullptr),
  net_next_(nullptr),
  net_prev_(nullptr),
  vertex_id_(vertex_id_null)
{
}

const char *
ConcretePin::name() const
{
  return port_->name();
}

void
ConcretePin::setVertexId(VertexId id)
{
  vertex_id_ = id;
}

////////////////////////////////////////////////////////////////

const char *
ConcreteTerm::name() const
{
  ConcretePin *cpin = reinterpret_cast<ConcretePin*>(pin_);
  const ConcretePort *cport =
    reinterpret_cast<const ConcretePort*>(cpin->port());
  return cport->name();
}

ConcreteTerm::ConcreteTerm(ConcretePin *pin,
			   ConcreteNet *net) :
  pin_(pin),
  net_(net),
  net_next_(nullptr)
{
}

////////////////////////////////////////////////////////////////

ConcreteNet::ConcreteNet(const char *name,
			 ConcreteInstance *instance) :
  name_(stringCopy(name)),
  instance_(instance),
  pins_(nullptr),
  terms_(nullptr),
  merged_into_(nullptr)
{
}

ConcreteNet::~ConcreteNet()
{
  stringDelete(name_);
}

// Merged nets are kept around to serve as name aliases.
// Only Instance::findNet and InstanceNetIterator need to know
// the net has been merged.
void
ConcreteNet::mergeInto(ConcreteNet *net)
{
  ConcreteNetPinIterator pin_iter(this);
  while (pin_iter.hasNext()) {
    Pin *pin = pin_iter.next();
    ConcretePin *cpin = reinterpret_cast<ConcretePin*>(pin);
    net->addPin(cpin);
    cpin->net_ = net;
  }
  pins_ = nullptr;
  ConcreteNetTermIterator term_iter(this);
  while (term_iter.hasNext()) {
    Term *term = term_iter.next();
    ConcreteTerm *cterm = reinterpret_cast<ConcreteTerm*>(term);
    net->addTerm(cterm);
    cterm->net_ = net;
  }
  terms_ = nullptr;
  // Leave name map pointing to merged net because otherwise a top
  // level merged net has no pointer to it and it is leaked.
  merged_into_ = net;
}

void
ConcreteNet::addPin(ConcretePin *pin)
{
  if (pins_)
    pins_->net_prev_ = pin;
  pin->net_next_ = pins_;
  pin->net_prev_ = nullptr;
  pins_ = pin;
}

void
ConcreteNet::deletePin(ConcretePin *pin)
{
  ConcretePin *prev = pin->net_prev_;
  ConcretePin *next = pin->net_next_;
  if (prev)
    prev->net_next_ = next;
  if (next)
    next->net_prev_ = prev;
  if (pins_ == pin)
    pins_ = next;
}

void
ConcreteNet::addTerm(ConcreteTerm *term)
{
  ConcreteTerm *next = terms_;
  terms_ = term;
  term->net_next_ = next;
}

void
ConcreteNet::deleteTerm(ConcreteTerm *term)
{
  ConcreteTerm *net_prev_term = nullptr;
  for (ConcreteTerm *net_term=terms_;net_term;net_term=net_term->net_next_) {
    if (net_term == term) {
      if (net_prev_term)
	net_prev_term->net_next_ = term->net_next_;
      else
	terms_ = term->net_next_;
      break;
    }
    net_prev_term = net_term;
  }
}

////////////////////////////////////////////////////////////////

typedef Map<Net*, Net*> BindingMap;

// Binding table used for linking/expanding network.
class ConcreteBindingTbl
{
public:
  explicit ConcreteBindingTbl(NetworkEdit *network);
  Net *ensureBinding(Net *proto_net,
		     Instance *parent);
  Net *find(Net *net);
  void bind(Net *proto_net,
	    Net *clone_net);

private:
  DISALLOW_COPY_AND_ASSIGN(ConcreteBindingTbl);

  BindingMap map_;
  NetworkEdit *network_;
};

void
ConcreteNetwork::setCellNetworkView(Cell *cell,
				    Instance *inst)
{
  cell_network_view_map_[cell] = inst;
}

Instance *
ConcreteNetwork::cellNetworkView(Cell *cell)
{
  return cell_network_view_map_.findKey(cell);
}

void
ConcreteNetwork::readNetlistBefore()
{
  clearConstantNets();
  deleteTopInstance();
  clearNetDrvrPinMap();
}

void
ConcreteNetwork::setTopInstance(Instance *top_inst)
{
  if (top_instance_) {
    deleteInstance(top_instance_);
    clearConstantNets();
    clearNetDrvrPinMap();
  }
  top_instance_ = top_inst;
}

void
ConcreteNetwork::setLinkFunc(LinkNetworkFunc *link)
{
  link_func_ = link;
}

bool
ConcreteNetwork::linkNetwork(const char *top_cell_name,
			     bool make_black_boxes,
			     Report *report)
{
  if (link_func_) {
    clearConstantNets();
    deleteTopInstance();
    top_instance_ = link_func_(top_cell_name, make_black_boxes, report, this);
    return top_instance_ != nullptr;
  }
  else {
    report->error(8, "cell type %s can not be linked.", top_cell_name);
    return false;
  }
}

Instance *
linkReaderNetwork(Cell *top_cell,
		  bool, Report *,
		  NetworkReader *network)
{
  Instance *view = network->cellNetworkView(top_cell);
  if (view) {
    // Seed the recursion for expansion with the top level instance.
    Instance *top_instance = network->makeInstance(top_cell, "", nullptr);
    ConcreteBindingTbl bindings(network);
    makeClonePins(view, top_instance, view, &bindings, nullptr, nullptr, network);
    InstanceChildIterator *child_iter = network->childIterator(view);
    while (child_iter->hasNext()) {
      Instance *child = child_iter->next();
      makeChildNetwork(child, top_instance, &bindings, network);
    }
    delete child_iter;
    network->deleteCellNetworkViews();
    return top_instance;
  }
  return nullptr;
}

static void
makeChildNetwork(Instance *proto,
		 Instance *parent,
		 ConcreteBindingTbl *parent_bindings,
		 NetworkReader *network)
{
  Cell *proto_cell = network->cell(proto);
  Instance *clone = network->makeInstance(proto_cell, network->name(proto),
					  parent);
  if (network->isLeaf(proto_cell))
    makeClonePins(proto, clone, nullptr, nullptr, parent, parent_bindings, network);
  else {
    // Recurse if this isn't a leaf cell.
    ConcreteBindingTbl bindings(network);
    Instance *clone_view = network->cellNetworkView(proto_cell);
    makeClonePins(proto, clone, clone_view, &bindings, parent,
		  parent_bindings, network);
    if (clone_view) {
      InstanceChildIterator *child_iter = network->childIterator(clone_view);
      while (child_iter->hasNext()) {
	Instance *child = child_iter->next();
	makeChildNetwork(child, clone, &bindings, network);
      }
      delete child_iter;
    }
  }
}

static void
makeClonePins(Instance *proto,
	      Instance *clone,
	      Instance *clone_view,
	      ConcreteBindingTbl *bindings,
	      Instance *parent,
	      ConcreteBindingTbl *parent_bindings,
	      NetworkReader *network)
{
  InstancePinIterator *proto_pin_iter = network->pinIterator(proto);
  while (proto_pin_iter->hasNext()) {
    Pin *proto_pin = proto_pin_iter->next();
    Net *proto_net = network->net(proto_pin);
    Port *proto_port = network->port(proto_pin);
    Net *clone_net = nullptr;
    if (proto_net && parent_bindings)
      clone_net = parent_bindings->ensureBinding(proto_net, parent);
    Pin *clone_pin = network->connect(clone, proto_port, clone_net);
    if (clone_view) {
      Pin *clone_proto_pin = network->findPin(clone_view, proto_port);
      Net *clone_proto_net = network->net(clone_proto_pin);
      Net *clone_child_net = nullptr;
      if (clone_proto_net)
	clone_child_net = bindings->ensureBinding(clone_proto_net, clone);
      network->makeTerm(clone_pin, clone_child_net);
    }
  }
  delete proto_pin_iter;
}

////////////////////////////////////////////////////////////////

ConcreteBindingTbl::ConcreteBindingTbl(NetworkEdit *network) :
  network_(network)
{
}

// Follow the merged_into pointers rather than update the
// binding tables up the call tree when nodes are merged
// because the name changes up the hierarchy.
Net *
ConcreteBindingTbl::find(Net *proto_net)
{
  ConcreteNet *net = reinterpret_cast<ConcreteNet*>(map_.findKey(proto_net));
  while (net && net->mergedInto())
    net = net->mergedInto();
  return reinterpret_cast<Net*>(net);
}

void
ConcreteBindingTbl::bind(Net *proto_net,
			 Net *net)
{
  map_[proto_net] = net;
}

Net *
ConcreteBindingTbl::ensureBinding(Net *proto_net,
				  Instance *parent)
{
  Net *net = find(proto_net);
  if (net == nullptr) {
    net = network_->makeNet(network_->name(proto_net), parent);
    map_[proto_net] = net;
  }
  return net;
}

} // namespace
