mirror of https://github.com/YosysHQ/abc.git
450 lines
13 KiB
C
450 lines
13 KiB
C
/**CFile****************************************************************
|
|
|
|
FileName [fxuHeapS.c]
|
|
|
|
PackageName [MVSIS 2.0: Multi-valued logic synthesis system.]
|
|
|
|
Synopsis [The priority queue for variables.]
|
|
|
|
Author [MVSIS Group]
|
|
|
|
Affiliation [UC Berkeley]
|
|
|
|
Date [Ver. 1.0. Started - February 1, 2003.]
|
|
|
|
Revision [$Id: fxuHeapS.c,v 1.0 2003/02/01 00:00:00 alanmi Exp $]
|
|
|
|
***********************************************************************/
|
|
|
|
#include "fxuInt.h"
|
|
|
|
ABC_NAMESPACE_IMPL_START
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// DECLARATIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
#define FXU_HEAP_SINGLE_WEIGHT(pSingle) ((pSingle)->Weight)
|
|
#define FXU_HEAP_SINGLE_CURRENT(p, pSingle) ((p)->pTree[(pSingle)->HNum])
|
|
#define FXU_HEAP_SINGLE_PARENT_EXISTS(p, pSingle) ((pSingle)->HNum > 1)
|
|
#define FXU_HEAP_SINGLE_CHILD1_EXISTS(p, pSingle) (((pSingle)->HNum << 1) <= p->nItems)
|
|
#define FXU_HEAP_SINGLE_CHILD2_EXISTS(p, pSingle) ((((pSingle)->HNum << 1)+1) <= p->nItems)
|
|
#define FXU_HEAP_SINGLE_PARENT(p, pSingle) ((p)->pTree[(pSingle)->HNum >> 1])
|
|
#define FXU_HEAP_SINGLE_CHILD1(p, pSingle) ((p)->pTree[(pSingle)->HNum << 1])
|
|
#define FXU_HEAP_SINGLE_CHILD2(p, pSingle) ((p)->pTree[((pSingle)->HNum << 1)+1])
|
|
#define FXU_HEAP_SINGLE_ASSERT(p, pSingle) assert( (pSingle)->HNum >= 1 && (pSingle)->HNum <= p->nItemsAlloc )
|
|
|
|
static void Fxu_HeapSingleResize( Fxu_HeapSingle * p );
|
|
static void Fxu_HeapSingleSwap( Fxu_Single ** pSingle1, Fxu_Single ** pSingle2 );
|
|
static void Fxu_HeapSingleMoveUp( Fxu_HeapSingle * p, Fxu_Single * pSingle );
|
|
static void Fxu_HeapSingleMoveDn( Fxu_HeapSingle * p, Fxu_Single * pSingle );
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// FUNCTION DEFINITIONS ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
Fxu_HeapSingle * Fxu_HeapSingleStart()
|
|
{
|
|
Fxu_HeapSingle * p;
|
|
p = ABC_ALLOC( Fxu_HeapSingle, 1 );
|
|
memset( p, 0, sizeof(Fxu_HeapSingle) );
|
|
p->nItems = 0;
|
|
p->nItemsAlloc = 2000;
|
|
p->pTree = ABC_ALLOC( Fxu_Single *, p->nItemsAlloc + 10 );
|
|
p->pTree[0] = NULL;
|
|
return p;
|
|
}
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Fxu_HeapSingleResize( Fxu_HeapSingle * p )
|
|
{
|
|
p->nItemsAlloc *= 2;
|
|
p->pTree = ABC_REALLOC( Fxu_Single *, p->pTree, p->nItemsAlloc + 10 );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Fxu_HeapSingleStop( Fxu_HeapSingle * p )
|
|
{
|
|
int i;
|
|
i = 0;
|
|
ABC_FREE( p->pTree );
|
|
i = 1;
|
|
ABC_FREE( p );
|
|
}
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Fxu_HeapSinglePrint( FILE * pFile, Fxu_HeapSingle * p )
|
|
{
|
|
Fxu_Single * pSingle;
|
|
int Counter = 1;
|
|
int Degree = 1;
|
|
|
|
Fxu_HeapSingleCheck( p );
|
|
fprintf( pFile, "The contents of the heap:\n" );
|
|
fprintf( pFile, "Level %d: ", Degree );
|
|
Fxu_HeapSingleForEachItem( p, pSingle )
|
|
{
|
|
assert( Counter == p->pTree[Counter]->HNum );
|
|
fprintf( pFile, "%2d=%3d ", Counter, FXU_HEAP_SINGLE_WEIGHT(p->pTree[Counter]) );
|
|
if ( ++Counter == (1 << Degree) )
|
|
{
|
|
fprintf( pFile, "\n" );
|
|
Degree++;
|
|
fprintf( pFile, "Level %d: ", Degree );
|
|
}
|
|
}
|
|
fprintf( pFile, "\n" );
|
|
fprintf( pFile, "End of the heap printout.\n" );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Fxu_HeapSingleCheck( Fxu_HeapSingle * p )
|
|
{
|
|
Fxu_Single * pSingle;
|
|
Fxu_HeapSingleForEachItem( p, pSingle )
|
|
{
|
|
assert( pSingle->HNum == p->i );
|
|
Fxu_HeapSingleCheckOne( p, pSingle );
|
|
}
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Fxu_HeapSingleCheckOne( Fxu_HeapSingle * p, Fxu_Single * pSingle )
|
|
{
|
|
int Weight1, Weight2;
|
|
if ( FXU_HEAP_SINGLE_CHILD1_EXISTS(p,pSingle) )
|
|
{
|
|
Weight1 = FXU_HEAP_SINGLE_WEIGHT(pSingle);
|
|
Weight2 = FXU_HEAP_SINGLE_WEIGHT( FXU_HEAP_SINGLE_CHILD1(p,pSingle) );
|
|
assert( Weight1 >= Weight2 );
|
|
}
|
|
if ( FXU_HEAP_SINGLE_CHILD2_EXISTS(p,pSingle) )
|
|
{
|
|
Weight1 = FXU_HEAP_SINGLE_WEIGHT(pSingle);
|
|
Weight2 = FXU_HEAP_SINGLE_WEIGHT( FXU_HEAP_SINGLE_CHILD2(p,pSingle) );
|
|
assert( Weight1 >= Weight2 );
|
|
}
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Fxu_HeapSingleInsert( Fxu_HeapSingle * p, Fxu_Single * pSingle )
|
|
{
|
|
if ( p->nItems == p->nItemsAlloc )
|
|
Fxu_HeapSingleResize( p );
|
|
// put the last entry to the last place and move up
|
|
p->pTree[++p->nItems] = pSingle;
|
|
pSingle->HNum = p->nItems;
|
|
// move the last entry up if necessary
|
|
Fxu_HeapSingleMoveUp( p, pSingle );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Fxu_HeapSingleUpdate( Fxu_HeapSingle * p, Fxu_Single * pSingle )
|
|
{
|
|
FXU_HEAP_SINGLE_ASSERT(p,pSingle);
|
|
if ( FXU_HEAP_SINGLE_PARENT_EXISTS(p,pSingle) &&
|
|
FXU_HEAP_SINGLE_WEIGHT(pSingle) > FXU_HEAP_SINGLE_WEIGHT( FXU_HEAP_SINGLE_PARENT(p,pSingle) ) )
|
|
Fxu_HeapSingleMoveUp( p, pSingle );
|
|
else if ( FXU_HEAP_SINGLE_CHILD1_EXISTS(p,pSingle) &&
|
|
FXU_HEAP_SINGLE_WEIGHT(pSingle) < FXU_HEAP_SINGLE_WEIGHT( FXU_HEAP_SINGLE_CHILD1(p,pSingle) ) )
|
|
Fxu_HeapSingleMoveDn( p, pSingle );
|
|
else if ( FXU_HEAP_SINGLE_CHILD2_EXISTS(p,pSingle) &&
|
|
FXU_HEAP_SINGLE_WEIGHT(pSingle) < FXU_HEAP_SINGLE_WEIGHT( FXU_HEAP_SINGLE_CHILD2(p,pSingle) ) )
|
|
Fxu_HeapSingleMoveDn( p, pSingle );
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Fxu_HeapSingleDelete( Fxu_HeapSingle * p, Fxu_Single * pSingle )
|
|
{
|
|
int Place = pSingle->HNum;
|
|
FXU_HEAP_SINGLE_ASSERT(p,pSingle);
|
|
// put the last entry to the deleted place
|
|
// decrement the number of entries
|
|
p->pTree[Place] = p->pTree[p->nItems--];
|
|
p->pTree[Place]->HNum = Place;
|
|
// move the top entry down if necessary
|
|
Fxu_HeapSingleUpdate( p, p->pTree[Place] );
|
|
pSingle->HNum = 0;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
Fxu_Single * Fxu_HeapSingleReadMax( Fxu_HeapSingle * p )
|
|
{
|
|
if ( p->nItems == 0 )
|
|
return NULL;
|
|
return p->pTree[1];
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
Fxu_Single * Fxu_HeapSingleGetMax( Fxu_HeapSingle * p )
|
|
{
|
|
Fxu_Single * pSingle;
|
|
if ( p->nItems == 0 )
|
|
return NULL;
|
|
// prepare the return value
|
|
pSingle = p->pTree[1];
|
|
pSingle->HNum = 0;
|
|
// put the last entry on top
|
|
// decrement the number of entries
|
|
p->pTree[1] = p->pTree[p->nItems--];
|
|
p->pTree[1]->HNum = 1;
|
|
// move the top entry down if necessary
|
|
Fxu_HeapSingleMoveDn( p, p->pTree[1] );
|
|
return pSingle;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
int Fxu_HeapSingleReadMaxWeight( Fxu_HeapSingle * p )
|
|
{
|
|
if ( p->nItems == 0 )
|
|
return -1;
|
|
return FXU_HEAP_SINGLE_WEIGHT(p->pTree[1]);
|
|
}
|
|
|
|
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Fxu_HeapSingleSwap( Fxu_Single ** pSingle1, Fxu_Single ** pSingle2 )
|
|
{
|
|
Fxu_Single * pSingle;
|
|
int Temp;
|
|
pSingle = *pSingle1;
|
|
*pSingle1 = *pSingle2;
|
|
*pSingle2 = pSingle;
|
|
Temp = (*pSingle1)->HNum;
|
|
(*pSingle1)->HNum = (*pSingle2)->HNum;
|
|
(*pSingle2)->HNum = Temp;
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Fxu_HeapSingleMoveUp( Fxu_HeapSingle * p, Fxu_Single * pSingle )
|
|
{
|
|
Fxu_Single ** ppSingle, ** ppPar;
|
|
ppSingle = &FXU_HEAP_SINGLE_CURRENT(p, pSingle);
|
|
while ( FXU_HEAP_SINGLE_PARENT_EXISTS(p,*ppSingle) )
|
|
{
|
|
ppPar = &FXU_HEAP_SINGLE_PARENT(p,*ppSingle);
|
|
if ( FXU_HEAP_SINGLE_WEIGHT(*ppSingle) > FXU_HEAP_SINGLE_WEIGHT(*ppPar) )
|
|
{
|
|
Fxu_HeapSingleSwap( ppSingle, ppPar );
|
|
ppSingle = ppPar;
|
|
}
|
|
else
|
|
break;
|
|
}
|
|
}
|
|
|
|
/**Function*************************************************************
|
|
|
|
Synopsis []
|
|
|
|
Description []
|
|
|
|
SideEffects []
|
|
|
|
SeeAlso []
|
|
|
|
***********************************************************************/
|
|
void Fxu_HeapSingleMoveDn( Fxu_HeapSingle * p, Fxu_Single * pSingle )
|
|
{
|
|
Fxu_Single ** ppChild1, ** ppChild2, ** ppSingle;
|
|
ppSingle = &FXU_HEAP_SINGLE_CURRENT(p, pSingle);
|
|
while ( FXU_HEAP_SINGLE_CHILD1_EXISTS(p,*ppSingle) )
|
|
{ // if Child1 does not exist, Child2 also does not exists
|
|
|
|
// get the children
|
|
ppChild1 = &FXU_HEAP_SINGLE_CHILD1(p,*ppSingle);
|
|
if ( FXU_HEAP_SINGLE_CHILD2_EXISTS(p,*ppSingle) )
|
|
{
|
|
ppChild2 = &FXU_HEAP_SINGLE_CHILD2(p,*ppSingle);
|
|
|
|
// consider two cases
|
|
if ( FXU_HEAP_SINGLE_WEIGHT(*ppSingle) >= FXU_HEAP_SINGLE_WEIGHT(*ppChild1) &&
|
|
FXU_HEAP_SINGLE_WEIGHT(*ppSingle) >= FXU_HEAP_SINGLE_WEIGHT(*ppChild2) )
|
|
{ // Var is larger than both, skip
|
|
break;
|
|
}
|
|
else
|
|
{ // Var is smaller than one of them, then swap it with larger
|
|
if ( FXU_HEAP_SINGLE_WEIGHT(*ppChild1) >= FXU_HEAP_SINGLE_WEIGHT(*ppChild2) )
|
|
{
|
|
Fxu_HeapSingleSwap( ppSingle, ppChild1 );
|
|
// update the pointer
|
|
ppSingle = ppChild1;
|
|
}
|
|
else
|
|
{
|
|
Fxu_HeapSingleSwap( ppSingle, ppChild2 );
|
|
// update the pointer
|
|
ppSingle = ppChild2;
|
|
}
|
|
}
|
|
}
|
|
else // Child2 does not exist
|
|
{
|
|
// consider two cases
|
|
if ( FXU_HEAP_SINGLE_WEIGHT(*ppSingle) >= FXU_HEAP_SINGLE_WEIGHT(*ppChild1) )
|
|
{ // Var is larger than Child1, skip
|
|
break;
|
|
}
|
|
else
|
|
{ // Var is smaller than Child1, then swap them
|
|
Fxu_HeapSingleSwap( ppSingle, ppChild1 );
|
|
// update the pointer
|
|
ppSingle = ppChild1;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////
|
|
/// END OF FILE ///
|
|
////////////////////////////////////////////////////////////////////////
|
|
ABC_NAMESPACE_IMPL_END
|
|
|