diff options
Diffstat (limited to 'src/temp')
40 files changed, 7599 insertions, 1066 deletions
diff --git a/src/temp/deco/deco.h b/src/temp/deco/deco.h new file mode 100644 index 00000000..89119c78 --- /dev/null +++ b/src/temp/deco/deco.h @@ -0,0 +1,699 @@ +/**CFile**************************************************************** + +  FileName    [deco.h] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [A simple decomposition tree/node data structure and its APIs.] + +  Synopsis    [External declarations.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - June 20, 2005.] + +  Revision    [$Id: deco.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ +  +#ifndef __DEC_H__ +#define __DEC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +//////////////////////////////////////////////////////////////////////// +///                          INCLUDES                                /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +///                         PARAMETERS                               /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +///                         BASIC TYPES                              /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Dec_Edge_t_ Dec_Edge_t; +struct Dec_Edge_t_ +{ +    unsigned          fCompl   :  1;   // the complemented bit +    unsigned          Node     : 30;   // the decomposition node pointed by the edge +}; + +typedef struct Dec_Node_t_ Dec_Node_t; +struct Dec_Node_t_ +{ +    Dec_Edge_t        eEdge0;          // the left child of the node +    Dec_Edge_t        eEdge1;          // the right child of the node +    // other info +    void *            pFunc;           // the function of the node (BDD or AIG) +    unsigned          Level    : 16;   // the level of this node in the global AIG +    // printing info  +    unsigned          fNodeOr  :  1;   // marks the original OR node +    unsigned          fCompl0  :  1;   // marks the original complemented edge +    unsigned          fCompl1  :  1;   // marks the original complemented edge +}; + +typedef struct Dec_Graph_t_ Dec_Graph_t; +struct Dec_Graph_t_ +{ +    int               fConst;          // marks the constant 1 graph +    int               nLeaves;         // the number of leaves +    int               nSize;           // the number of nodes (including the leaves)  +    int               nCap;            // the number of allocated nodes +    Dec_Node_t *      pNodes;          // the array of leaves and internal nodes +    Dec_Edge_t        eRoot;           // the pointer to the topmost node +}; + +typedef struct Dec_Man_t_ Dec_Man_t; +struct Dec_Man_t_ +{ +    void *            pMvcMem;         // memory manager for MVC cover (used for factoring) +    Vec_Int_t *       vCubes;          // storage for cubes +    Vec_Int_t *       vLits;           // storage for literals  +    // precomputation information about 4-variable functions +    unsigned short *  puCanons;        // canonical forms +    char *            pPhases;         // canonical phases +    char *            pPerms;          // canonical permutations +    unsigned char *   pMap;            // mapping of functions into class numbers +}; + + +//////////////////////////////////////////////////////////////////////// +///                        ITERATORS                                 /// +//////////////////////////////////////////////////////////////////////// + +// interator throught the leaves +#define Dec_GraphForEachLeaf( pGraph, pLeaf, i )                                              \ +    for ( i = 0; (i < (pGraph)->nLeaves) && (((pLeaf) = Dec_GraphNode(pGraph, i)), 1); i++ ) +// interator throught the internal nodes +#define Dec_GraphForEachNode( pGraph, pAnd, i )                                               \ +    for ( i = (pGraph)->nLeaves; (i < (pGraph)->nSize) && (((pAnd) = Dec_GraphNode(pGraph, i)), 1); i++ ) + +//////////////////////////////////////////////////////////////////////// +///                    FUNCTION DECLARATIONS                         /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [Creates an edge pointing to the node in the given polarity.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline Dec_Edge_t Dec_EdgeCreate( int Node, int fCompl )    +{ +    Dec_Edge_t eEdge = { fCompl, Node };  +    return eEdge;  +} + +/**Function************************************************************* + +  Synopsis    [Converts the edge into unsigned integer.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline unsigned Dec_EdgeToInt( Dec_Edge_t eEdge )    +{ +    return (eEdge.Node << 1) | eEdge.fCompl;  +} + +/**Function************************************************************* + +  Synopsis    [Converts unsigned integer into the edge.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline Dec_Edge_t Dec_IntToEdge( unsigned Edge )    +{ +    return Dec_EdgeCreate( Edge >> 1, Edge & 1 );  +} + +/**Function************************************************************* + +  Synopsis    [Converts the edge into unsigned integer.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline unsigned Dec_EdgeToInt_( Dec_Edge_t eEdge )    +{ +    return *(unsigned *)&eEdge; +} + +/**Function************************************************************* + +  Synopsis    [Converts unsigned integer into the edge.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline Dec_Edge_t Dec_IntToEdge_( unsigned Edge )    +{ +    return *(Dec_Edge_t *)&Edge; +} + +/**Function************************************************************* + +  Synopsis    [Creates a graph with the given number of leaves.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline Dec_Graph_t * Dec_GraphCreate( int nLeaves )    +{ +    Dec_Graph_t * pGraph; +    pGraph = ALLOC( Dec_Graph_t, 1 ); +    memset( pGraph, 0, sizeof(Dec_Graph_t) ); +    pGraph->nLeaves = nLeaves; +    pGraph->nSize = nLeaves; +    pGraph->nCap = 2 * nLeaves + 50; +    pGraph->pNodes = ALLOC( Dec_Node_t, pGraph->nCap ); +    memset( pGraph->pNodes, 0, sizeof(Dec_Node_t) * pGraph->nSize ); +    return pGraph; +} + +/**Function************************************************************* + +  Synopsis    [Creates constant 0 graph.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline Dec_Graph_t * Dec_GraphCreateConst0()    +{ +    Dec_Graph_t * pGraph; +    pGraph = ALLOC( Dec_Graph_t, 1 ); +    memset( pGraph, 0, sizeof(Dec_Graph_t) ); +    pGraph->fConst = 1; +    pGraph->eRoot.fCompl = 1; +    return pGraph; +} + +/**Function************************************************************* + +  Synopsis    [Creates constant 1 graph.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline Dec_Graph_t * Dec_GraphCreateConst1()    +{ +    Dec_Graph_t * pGraph; +    pGraph = ALLOC( Dec_Graph_t, 1 ); +    memset( pGraph, 0, sizeof(Dec_Graph_t) ); +    pGraph->fConst = 1; +    return pGraph; +} + +/**Function************************************************************* + +  Synopsis    [Creates the literal graph.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline Dec_Graph_t * Dec_GraphCreateLeaf( int iLeaf, int nLeaves, int fCompl )    +{ +    Dec_Graph_t * pGraph; +    assert( 0 <= iLeaf && iLeaf < nLeaves ); +    pGraph = Dec_GraphCreate( nLeaves ); +    pGraph->eRoot.Node   = iLeaf; +    pGraph->eRoot.fCompl = fCompl; +    return pGraph; +} + +/**Function************************************************************* + +  Synopsis    [Creates a graph with the given number of leaves.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Dec_GraphFree( Dec_Graph_t * pGraph )    +{ +    FREE( pGraph->pNodes ); +    free( pGraph ); +} + +/**Function************************************************************* + +  Synopsis    [Returns 1 if the graph is a constant.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Dec_GraphIsConst( Dec_Graph_t * pGraph )    +{ +    return pGraph->fConst; +} + +/**Function************************************************************* + +  Synopsis    [Returns 1 if the graph is constant 0.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Dec_GraphIsConst0( Dec_Graph_t * pGraph )    +{ +    return pGraph->fConst && pGraph->eRoot.fCompl; +} + +/**Function************************************************************* + +  Synopsis    [Returns 1 if the graph is constant 1.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Dec_GraphIsConst1( Dec_Graph_t * pGraph )    +{ +    return pGraph->fConst && !pGraph->eRoot.fCompl; +} + +/**Function************************************************************* + +  Synopsis    [Returns 1 if the graph is complemented.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Dec_GraphIsComplement( Dec_Graph_t * pGraph )    +{ +    return pGraph->eRoot.fCompl; +} + +/**Function************************************************************* + +  Synopsis    [Checks if the graph is complemented.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Dec_GraphComplement( Dec_Graph_t * pGraph )    +{ +    pGraph->eRoot.fCompl ^= 1; +} + + +/**Function************************************************************* + +  Synopsis    [Returns the number of leaves.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Dec_GraphLeaveNum( Dec_Graph_t * pGraph )    +{ +    return pGraph->nLeaves; +} + +/**Function************************************************************* + +  Synopsis    [Returns the number of internal nodes.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Dec_GraphNodeNum( Dec_Graph_t * pGraph )    +{ +    return pGraph->nSize - pGraph->nLeaves; +} + +/**Function************************************************************* + +  Synopsis    [Returns the pointer to the node.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline Dec_Node_t * Dec_GraphNode( Dec_Graph_t * pGraph, int i )    +{ +    return pGraph->pNodes + i; +} + +/**Function************************************************************* + +  Synopsis    [Returns the pointer to the node.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline Dec_Node_t * Dec_GraphNodeLast( Dec_Graph_t * pGraph )    +{ +    return pGraph->pNodes + pGraph->nSize - 1; +} + +/**Function************************************************************* + +  Synopsis    [Returns the number of the given node.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Dec_GraphNodeInt( Dec_Graph_t * pGraph, Dec_Node_t * pNode )    +{ +    return pNode - pGraph->pNodes; +} + +/**Function************************************************************* + +  Synopsis    [Check if the graph represents elementary variable.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Dec_GraphIsVar( Dec_Graph_t * pGraph )    +{ +    return pGraph->eRoot.Node < (unsigned)pGraph->nLeaves; +} + +/**Function************************************************************* + +  Synopsis    [Check if the graph represents elementary variable.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Dec_GraphNodeIsVar( Dec_Graph_t * pGraph, Dec_Node_t * pNode )    +{ +    return Dec_GraphNodeInt(pGraph,pNode) < pGraph->nLeaves; +} + +/**Function************************************************************* + +  Synopsis    [Returns the elementary variable elementary variable.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline Dec_Node_t * Dec_GraphVar( Dec_Graph_t * pGraph )    +{ +    assert( Dec_GraphIsVar( pGraph ) ); +    return Dec_GraphNode( pGraph, pGraph->eRoot.Node ); +} + +/**Function************************************************************* + +  Synopsis    [Returns the number of the elementary variable.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Dec_GraphVarInt( Dec_Graph_t * pGraph )    +{ +    assert( Dec_GraphIsVar( pGraph ) ); +    return Dec_GraphNodeInt( pGraph, Dec_GraphVar(pGraph) ); +} + +/**Function************************************************************* + +  Synopsis    [Sets the root of the graph.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Dec_GraphSetRoot( Dec_Graph_t * pGraph, Dec_Edge_t eRoot )    +{ +    pGraph->eRoot = eRoot; +} + +/**Function************************************************************* + +  Synopsis    [Appends a new node to the graph.] + +  Description [This procedure is meant for internal use.] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline Dec_Node_t * Dec_GraphAppendNode( Dec_Graph_t * pGraph )    +{ +    Dec_Node_t * pNode; +    if ( pGraph->nSize == pGraph->nCap ) +    { +        pGraph->pNodes = REALLOC( Dec_Node_t, pGraph->pNodes, 2 * pGraph->nCap );  +        pGraph->nCap   = 2 * pGraph->nCap; +    } +    pNode = pGraph->pNodes + pGraph->nSize++; +    memset( pNode, 0, sizeof(Dec_Node_t) ); +    return pNode; +} + +/**Function************************************************************* + +  Synopsis    [Creates an AND node.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline Dec_Edge_t Dec_GraphAddNodeAnd( Dec_Graph_t * pGraph, Dec_Edge_t eEdge0, Dec_Edge_t eEdge1 ) +{ +    Dec_Node_t * pNode; +    // get the new node +    pNode = Dec_GraphAppendNode( pGraph ); +    // set the inputs and other info +    pNode->eEdge0 = eEdge0; +    pNode->eEdge1 = eEdge1; +    pNode->fCompl0 = eEdge0.fCompl; +    pNode->fCompl1 = eEdge1.fCompl; +    return Dec_EdgeCreate( pGraph->nSize - 1, 0 ); +} + +/**Function************************************************************* + +  Synopsis    [Creates an OR node.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline Dec_Edge_t Dec_GraphAddNodeOr( Dec_Graph_t * pGraph, Dec_Edge_t eEdge0, Dec_Edge_t eEdge1 ) +{ +    Dec_Node_t * pNode; +    // get the new node +    pNode = Dec_GraphAppendNode( pGraph ); +    // set the inputs and other info +    pNode->eEdge0 = eEdge0; +    pNode->eEdge1 = eEdge1; +    pNode->fCompl0 = eEdge0.fCompl; +    pNode->fCompl1 = eEdge1.fCompl; +    // make adjustments for the OR gate +    pNode->fNodeOr = 1; +    pNode->eEdge0.fCompl = !pNode->eEdge0.fCompl; +    pNode->eEdge1.fCompl = !pNode->eEdge1.fCompl; +    return Dec_EdgeCreate( pGraph->nSize - 1, 1 ); +} + +/**Function************************************************************* + +  Synopsis    [Creates an XOR node.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline Dec_Edge_t Dec_GraphAddNodeXor( Dec_Graph_t * pGraph, Dec_Edge_t eEdge0, Dec_Edge_t eEdge1, int Type ) +{ +    Dec_Edge_t eNode0, eNode1, eNode; +    if ( Type == 0 ) +    { +        // derive the first AND +        eEdge0.fCompl ^= 1; +        eNode0 = Dec_GraphAddNodeAnd( pGraph, eEdge0, eEdge1 ); +        eEdge0.fCompl ^= 1; +        // derive the second AND +        eEdge1.fCompl ^= 1; +        eNode1 = Dec_GraphAddNodeAnd( pGraph, eEdge0, eEdge1 ); +        // derive the final OR +        eNode = Dec_GraphAddNodeOr( pGraph, eNode0, eNode1 ); +    } +    else +    { +        // derive the first AND +        eNode0 = Dec_GraphAddNodeAnd( pGraph, eEdge0, eEdge1 ); +        // derive the second AND +        eEdge0.fCompl ^= 1; +        eEdge1.fCompl ^= 1; +        eNode1 = Dec_GraphAddNodeAnd( pGraph, eEdge0, eEdge1 ); +        // derive the final OR +        eNode = Dec_GraphAddNodeOr( pGraph, eNode0, eNode1 ); +        eNode.fCompl ^= 1; +    } +    return eNode; +} + +/**Function************************************************************* + +  Synopsis    [Creates an XOR node.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline Dec_Edge_t Dec_GraphAddNodeMux( Dec_Graph_t * pGraph, Dec_Edge_t eEdgeC, Dec_Edge_t eEdgeT, Dec_Edge_t eEdgeE, int Type ) +{ +    Dec_Edge_t eNode0, eNode1, eNode; +    if ( Type == 0 ) +    { +        // derive the first AND +        eNode0 = Dec_GraphAddNodeAnd( pGraph, eEdgeC, eEdgeT ); +        // derive the second AND +        eEdgeC.fCompl ^= 1; +        eNode1 = Dec_GraphAddNodeAnd( pGraph, eEdgeC, eEdgeE ); +        // derive the final OR +        eNode = Dec_GraphAddNodeOr( pGraph, eNode0, eNode1 ); +    } +    else +    { +        // complement the arguments +        eEdgeT.fCompl ^= 1; +        eEdgeE.fCompl ^= 1; +        // derive the first AND +        eNode0 = Dec_GraphAddNodeAnd( pGraph, eEdgeC, eEdgeT ); +        // derive the second AND +        eEdgeC.fCompl ^= 1; +        eNode1 = Dec_GraphAddNodeAnd( pGraph, eEdgeC, eEdgeE ); +        // derive the final OR +        eNode = Dec_GraphAddNodeOr( pGraph, eNode0, eNode1 ); +        eNode.fCompl ^= 1; +    } +    return eNode; +} + +#ifdef __cplusplus +} +#endif + +#endif + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + diff --git a/src/temp/deco/module.make b/src/temp/deco/module.make new file mode 100644 index 00000000..d6d908e7 --- /dev/null +++ b/src/temp/deco/module.make @@ -0,0 +1 @@ +SRC +=  diff --git a/src/temp/esop/esop.h b/src/temp/esop/esop.h index d6cdff71..5f95f371 100644 --- a/src/temp/esop/esop.h +++ b/src/temp/esop/esop.h @@ -25,8 +25,9 @@  extern "C" {  #endif -#include "stdio.h" +#include <stdio.h>  #include "vec.h" +#include "mem.h"  ////////////////////////////////////////////////////////////////////////  ///                        DECLARATIONS                              /// @@ -34,16 +35,16 @@ extern "C" {  typedef struct Esop_Man_t_      Esop_Man_t;  typedef struct Esop_Cube_t_     Esop_Cube_t; -typedef struct Esop_MmFixed_t_  Esop_MmFixed_t;     +typedef struct Mem_Fixed_t_  Mem_Fixed_t;      struct Esop_Man_t_  {      int               nVars;          // the number of vars      int               nWords;         // the number of words -    Esop_MmFixed_t * pMemMan1;       // memory manager for cubes -    Esop_MmFixed_t * pMemMan2;       // memory manager for cubes -    Esop_MmFixed_t * pMemMan4;       // memory manager for cubes -    Esop_MmFixed_t * pMemMan8;       // memory manager for cubes +    Mem_Fixed_t *     pMemMan1;       // memory manager for cubes +    Mem_Fixed_t *     pMemMan2;       // memory manager for cubes +    Mem_Fixed_t *     pMemMan4;       // memory manager for cubes +    Mem_Fixed_t *     pMemMan8;       // memory manager for cubes      // temporary cubes      Esop_Cube_t *     pOne0;          // tautology cube      Esop_Cube_t *     pOne1;          // tautology cube @@ -99,12 +100,12 @@ static inline void   Esop_CubeXorVar( Esop_Cube_t * p, int Var, int Value ) { p-  static inline int    Esop_BitWordNum( int nBits )                           { return (nBits>>5) + ((nBits&31) > 0);                  }  /*=== esopMem.c ===========================================================*/ -extern Esop_MmFixed_t * Esop_MmFixedStart( int nEntrySize ); -extern void          Esop_MmFixedStop( Esop_MmFixed_t * p, int fVerbose ); -extern char *        Esop_MmFixedEntryFetch( Esop_MmFixed_t * p ); -extern void          Esop_MmFixedEntryRecycle( Esop_MmFixed_t * p, char * pEntry ); -extern void          Esop_MmFixedRestart( Esop_MmFixed_t * p ); -extern int           Esop_MmFixedReadMemUsage( Esop_MmFixed_t * p ); +extern Mem_Fixed_t * Mem_FixedStart( int nEntrySize ); +extern void          Mem_FixedStop( Mem_Fixed_t * p, int fVerbose ); +extern char *        Mem_FixedEntryFetch( Mem_Fixed_t * p ); +extern void          Mem_FixedEntryRecycle( Mem_Fixed_t * p, char * pEntry ); +extern void          Mem_FixedRestart( Mem_Fixed_t * p ); +extern int           Mem_FixedReadMemUsage( Mem_Fixed_t * p );  /*=== esopMin.c ===========================================================*/  extern void          Esop_EsopMinimize( Esop_Man_t * p );  extern void          Esop_EsopAddCube( Esop_Man_t * p, Esop_Cube_t * pCube ); @@ -142,13 +143,13 @@ static inline Esop_Cube_t * Esop_CubeAlloc( Esop_Man_t * p )  {      Esop_Cube_t * pCube;      if ( p->nWords <= 1 ) -        pCube = (Esop_Cube_t *)Esop_MmFixedEntryFetch( p->pMemMan1 ); +        pCube = (Esop_Cube_t *)Mem_FixedEntryFetch( p->pMemMan1 );      else if ( p->nWords <= 2 ) -        pCube = (Esop_Cube_t *)Esop_MmFixedEntryFetch( p->pMemMan2 ); +        pCube = (Esop_Cube_t *)Mem_FixedEntryFetch( p->pMemMan2 );      else if ( p->nWords <= 4 ) -        pCube = (Esop_Cube_t *)Esop_MmFixedEntryFetch( p->pMemMan4 ); +        pCube = (Esop_Cube_t *)Mem_FixedEntryFetch( p->pMemMan4 );      else if ( p->nWords <= 8 ) -        pCube = (Esop_Cube_t *)Esop_MmFixedEntryFetch( p->pMemMan8 ); +        pCube = (Esop_Cube_t *)Mem_FixedEntryFetch( p->pMemMan8 );      pCube->pNext  = NULL;      pCube->nVars  = p->nVars;      pCube->nWords = p->nWords; @@ -211,13 +212,13 @@ static inline Esop_Cube_t * Esop_CubeDup( Esop_Man_t * p, Esop_Cube_t * pCopy )  static inline void Esop_CubeRecycle( Esop_Man_t * p, Esop_Cube_t * pCube )  {      if ( pCube->nWords <= 1 ) -        Esop_MmFixedEntryRecycle( p->pMemMan1, (char *)pCube ); +        Mem_FixedEntryRecycle( p->pMemMan1, (char *)pCube );      else if ( pCube->nWords <= 2 ) -        Esop_MmFixedEntryRecycle( p->pMemMan2, (char *)pCube ); +        Mem_FixedEntryRecycle( p->pMemMan2, (char *)pCube );      else if ( pCube->nWords <= 4 ) -        Esop_MmFixedEntryRecycle( p->pMemMan4, (char *)pCube ); +        Mem_FixedEntryRecycle( p->pMemMan4, (char *)pCube );      else if ( pCube->nWords <= 8 ) -        Esop_MmFixedEntryRecycle( p->pMemMan8, (char *)pCube ); +        Mem_FixedEntryRecycle( p->pMemMan8, (char *)pCube );  }  /**Function************************************************************* @@ -238,16 +239,16 @@ static inline void Esop_CoverRecycle( Esop_Man_t * p, Esop_Cube_t * pCover )          return;      if ( pCover->nWords <= 1 )          Esop_CoverForEachCubeSafe( pCover, pCube, pCube2 ) -            Esop_MmFixedEntryRecycle( p->pMemMan1, (char *)pCube ); +            Mem_FixedEntryRecycle( p->pMemMan1, (char *)pCube );      else if ( pCover->nWords <= 2 )          Esop_CoverForEachCubeSafe( pCover, pCube, pCube2 ) -            Esop_MmFixedEntryRecycle( p->pMemMan2, (char *)pCube ); +            Mem_FixedEntryRecycle( p->pMemMan2, (char *)pCube );      else if ( pCover->nWords <= 4 )          Esop_CoverForEachCubeSafe( pCover, pCube, pCube2 ) -            Esop_MmFixedEntryRecycle( p->pMemMan4, (char *)pCube ); +            Mem_FixedEntryRecycle( p->pMemMan4, (char *)pCube );      else if ( pCover->nWords <= 8 )          Esop_CoverForEachCubeSafe( pCover, pCube, pCube2 ) -            Esop_MmFixedEntryRecycle( p->pMemMan8, (char *)pCube ); +            Mem_FixedEntryRecycle( p->pMemMan8, (char *)pCube );  }  /**Function************************************************************* diff --git a/src/temp/esop/esopMan.c b/src/temp/esop/esopMan.c index e81411f8..5c411349 100644 --- a/src/temp/esop/esopMan.c +++ b/src/temp/esop/esopMan.c @@ -47,10 +47,10 @@ Esop_Man_t * Esop_ManAlloc( int nVars )      memset( pMan, 0, sizeof(Esop_Man_t) );      pMan->nVars    = nVars;      pMan->nWords   = Esop_BitWordNum( nVars * 2 ); -    pMan->pMemMan1 = Esop_MmFixedStart( sizeof(Esop_Cube_t) + sizeof(unsigned) * (1 - 1) ); -    pMan->pMemMan2 = Esop_MmFixedStart( sizeof(Esop_Cube_t) + sizeof(unsigned) * (2 - 1) ); -    pMan->pMemMan4 = Esop_MmFixedStart( sizeof(Esop_Cube_t) + sizeof(unsigned) * (4 - 1) ); -    pMan->pMemMan8 = Esop_MmFixedStart( sizeof(Esop_Cube_t) + sizeof(unsigned) * (8 - 1) ); +    pMan->pMemMan1 = Mem_FixedStart( sizeof(Esop_Cube_t) + sizeof(unsigned) * (1 - 1) ); +    pMan->pMemMan2 = Mem_FixedStart( sizeof(Esop_Cube_t) + sizeof(unsigned) * (2 - 1) ); +    pMan->pMemMan4 = Mem_FixedStart( sizeof(Esop_Cube_t) + sizeof(unsigned) * (4 - 1) ); +    pMan->pMemMan8 = Mem_FixedStart( sizeof(Esop_Cube_t) + sizeof(unsigned) * (8 - 1) );      // allocate storage for the temporary cover      pMan->ppStore = ALLOC( Esop_Cube_t *, pMan->nVars + 1 );      // create tautology cubes @@ -101,10 +101,10 @@ void Esop_ManClean( Esop_Man_t * p, int nSupp )  ***********************************************************************/  void Esop_ManFree( Esop_Man_t * p )  { -    Esop_MmFixedStop ( p->pMemMan1, 0 ); -    Esop_MmFixedStop ( p->pMemMan2, 0 ); -    Esop_MmFixedStop ( p->pMemMan4, 0 ); -    Esop_MmFixedStop ( p->pMemMan8, 0 ); +    Mem_FixedStop ( p->pMemMan1, 0 ); +    Mem_FixedStop ( p->pMemMan2, 0 ); +    Mem_FixedStop ( p->pMemMan4, 0 ); +    Mem_FixedStop ( p->pMemMan8, 0 );      free( p->ppStore );      free( p );  } diff --git a/src/temp/esop/esopMem.c b/src/temp/esop/esopMem.c deleted file mode 100644 index 9d8e7405..00000000 --- a/src/temp/esop/esopMem.c +++ /dev/null @@ -1,274 +0,0 @@ -/**CFile**************************************************************** - -  FileName    [esopMem.c] - -  SystemName  [ABC: Logic synthesis and verification system.] - -  PackageName [Cover manipulation package.] - -  Synopsis    [Memory managers.] - -  Author      [Alan Mishchenko] -   -  Affiliation [UC Berkeley] - -  Date        [Ver. 1.0. Started - June 20, 2005.] - -  Revision    [$Id: esopMem.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] - -***********************************************************************/ - -#include "esop.h" - -//////////////////////////////////////////////////////////////////////// -///                        DECLARATIONS                              /// -//////////////////////////////////////////////////////////////////////// - -struct Esop_MmFixed_t_ -{ -    // information about individual entries -    int           nEntrySize;    // the size of one entry -    int           nEntriesAlloc; // the total number of entries allocated -    int           nEntriesUsed;  // the number of entries in use -    int           nEntriesMax;   // the max number of entries in use -    char *        pEntriesFree;  // the linked list of free entries - -    // this is where the memory is stored -    int           nChunkSize;    // the size of one chunk -    int           nChunksAlloc;  // the maximum number of memory chunks  -    int           nChunks;       // the current number of memory chunks  -    char **       pChunks;       // the allocated memory - -    // statistics -    int           nMemoryUsed;   // memory used in the allocated entries -    int           nMemoryAlloc;  // memory allocated -}; - -struct Esop_MmFlex_t_ -{ -    // information about individual entries -    int           nEntriesUsed;  // the number of entries allocated -    char *        pCurrent;      // the current pointer to free memory -    char *        pEnd;          // the first entry outside the free memory - -    // this is where the memory is stored -    int           nChunkSize;    // the size of one chunk -    int           nChunksAlloc;  // the maximum number of memory chunks  -    int           nChunks;       // the current number of memory chunks  -    char **       pChunks;       // the allocated memory - -    // statistics -    int           nMemoryUsed;   // memory used in the allocated entries -    int           nMemoryAlloc;  // memory allocated -}; - -struct Esop_MmStep_t_ -{ -    int                nMems;    // the number of fixed memory managers employed -    Esop_MmFixed_t **  pMems;    // memory managers: 2^1 words, 2^2 words, etc -    int                nMapSize; // the size of the memory array -    Esop_MmFixed_t **  pMap;     // maps the number of bytes into its memory manager -}; - -//////////////////////////////////////////////////////////////////////// -///                     FUNCTION DEFINITIONS                         /// -//////////////////////////////////////////////////////////////////////// - -/**Function************************************************************* - -  Synopsis    [Allocates memory pieces of fixed size.] - -  Description [The size of the chunk is computed as the minimum of -  1024 entries and 64K. Can only work with entry size at least 4 byte long.] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -Esop_MmFixed_t * Esop_MmFixedStart( int nEntrySize ) -{ -    Esop_MmFixed_t * p; - -    p = ALLOC( Esop_MmFixed_t, 1 ); -    memset( p, 0, sizeof(Esop_MmFixed_t) ); - -    p->nEntrySize    = nEntrySize; -    p->nEntriesAlloc = 0; -    p->nEntriesUsed  = 0; -    p->pEntriesFree  = NULL; - -    if ( nEntrySize * (1 << 10) < (1<<16) ) -        p->nChunkSize = (1 << 10); -    else -        p->nChunkSize = (1<<16) / nEntrySize; -    if ( p->nChunkSize < 8 ) -        p->nChunkSize = 8; - -    p->nChunksAlloc  = 64; -    p->nChunks       = 0; -    p->pChunks       = ALLOC( char *, p->nChunksAlloc ); - -    p->nMemoryUsed   = 0; -    p->nMemoryAlloc  = 0; -    return p; -} - -/**Function************************************************************* - -  Synopsis    [] - -  Description [] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -void Esop_MmFixedStop( Esop_MmFixed_t * p, int fVerbose ) -{ -    int i; -    if ( p == NULL ) -        return; -    if ( fVerbose ) -    { -        printf( "Fixed memory manager: Entry = %5d. Chunk = %5d. Chunks used = %5d.\n", -            p->nEntrySize, p->nChunkSize, p->nChunks ); -        printf( "   Entries used = %8d. Entries peak = %8d. Memory used = %8d. Memory alloc = %8d.\n", -            p->nEntriesUsed, p->nEntriesMax, p->nEntrySize * p->nEntriesUsed, p->nMemoryAlloc ); -    } -    for ( i = 0; i < p->nChunks; i++ ) -        free( p->pChunks[i] ); -    free( p->pChunks ); -    free( p ); -} - -/**Function************************************************************* - -  Synopsis    [] - -  Description [] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -char * Esop_MmFixedEntryFetch( Esop_MmFixed_t * p ) -{ -    char * pTemp; -    int i; - -    // check if there are still free entries -    if ( p->nEntriesUsed == p->nEntriesAlloc ) -    { // need to allocate more entries -        assert( p->pEntriesFree == NULL ); -        if ( p->nChunks == p->nChunksAlloc ) -        { -            p->nChunksAlloc *= 2; -            p->pChunks = REALLOC( char *, p->pChunks, p->nChunksAlloc );  -        } -        p->pEntriesFree = ALLOC( char, p->nEntrySize * p->nChunkSize ); -        p->nMemoryAlloc += p->nEntrySize * p->nChunkSize; -        // transform these entries into a linked list -        pTemp = p->pEntriesFree; -        for ( i = 1; i < p->nChunkSize; i++ ) -        { -            *((char **)pTemp) = pTemp + p->nEntrySize; -            pTemp += p->nEntrySize; -        } -        // set the last link -        *((char **)pTemp) = NULL; -        // add the chunk to the chunk storage -        p->pChunks[ p->nChunks++ ] = p->pEntriesFree; -        // add to the number of entries allocated -        p->nEntriesAlloc += p->nChunkSize; -    } -    // incrememt the counter of used entries -    p->nEntriesUsed++; -    if ( p->nEntriesMax < p->nEntriesUsed ) -        p->nEntriesMax = p->nEntriesUsed; -    // return the first entry in the free entry list -    pTemp = p->pEntriesFree; -    p->pEntriesFree = *((char **)pTemp); -    return pTemp; -} - -/**Function************************************************************* - -  Synopsis    [] - -  Description [] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -void Esop_MmFixedEntryRecycle( Esop_MmFixed_t * p, char * pEntry ) -{ -    // decrement the counter of used entries -    p->nEntriesUsed--; -    // add the entry to the linked list of free entries -    *((char **)pEntry) = p->pEntriesFree; -    p->pEntriesFree = pEntry; -} - -/**Function************************************************************* - -  Synopsis    [] - -  Description [Relocates all the memory except the first chunk.] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -void Esop_MmFixedRestart( Esop_MmFixed_t * p ) -{ -    int i; -    char * pTemp; - -    // deallocate all chunks except the first one -    for ( i = 1; i < p->nChunks; i++ ) -        free( p->pChunks[i] ); -    p->nChunks = 1; -    // transform these entries into a linked list -    pTemp = p->pChunks[0]; -    for ( i = 1; i < p->nChunkSize; i++ ) -    { -        *((char **)pTemp) = pTemp + p->nEntrySize; -        pTemp += p->nEntrySize; -    } -    // set the last link -    *((char **)pTemp) = NULL; -    // set the free entry list -    p->pEntriesFree  = p->pChunks[0]; -    // set the correct statistics -    p->nMemoryAlloc  = p->nEntrySize * p->nChunkSize; -    p->nMemoryUsed   = 0; -    p->nEntriesAlloc = p->nChunkSize; -    p->nEntriesUsed  = 0; -} - -/**Function************************************************************* - -  Synopsis    [] - -  Description [] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -int Esop_MmFixedReadMemUsage( Esop_MmFixed_t * p ) -{ -    return p->nMemoryAlloc; -} - - -//////////////////////////////////////////////////////////////////////// -///                       END OF FILE                                /// -//////////////////////////////////////////////////////////////////////// diff --git a/src/temp/esop/module.make b/src/temp/esop/module.make index cab5e737..1003ccc1 100644 --- a/src/temp/esop/module.make +++ b/src/temp/esop/module.make @@ -1,4 +1,3 @@  SRC +=    src/temp/esop/esopMan.c \ -    src/temp/esop/esopMem.c \      src/temp/esop/esopMin.c \      src/temp/esop/esopUtil.c  diff --git a/src/temp/ivy/ivy.h b/src/temp/ivy/ivy.h index 55ada384..57d8cfd2 100644 --- a/src/temp/ivy/ivy.h +++ b/src/temp/ivy/ivy.h @@ -42,6 +42,11 @@ extern "C" {  typedef struct Ivy_Man_t_            Ivy_Man_t;  typedef struct Ivy_Obj_t_            Ivy_Obj_t; +typedef int                          Ivy_Edge_t; + +// constant edges +#define IVY_CONST0                   1 +#define IVY_CONST1                   0  // object types  typedef enum {  @@ -102,10 +107,12 @@ struct Ivy_Man_t_      int *            pTable;         // structural hash table      int              nTableSize;     // structural hash table size      // various data members +    int              fCatchExor;     // set to 1 to detect EXORs      int              fExtended;      // set to 1 in extended mode      int              nTravIds;       // the traversal ID      int              nLevelMax;      // the maximum level      void *           pData;          // the temporary data +    Vec_Int_t *      vRequired;      // required times      // truth table of the 8-LUTs      unsigned *       pMemory;        // memory for truth tables      Vec_Int_t *      vTruths;        // offset for truth table of each node @@ -118,6 +125,26 @@ struct Ivy_Man_t_  }; +#define IVY_CUT_LIMIT     256 +#define IVY_CUT_INPUT       6 + +typedef struct Ivy_Cut_t_ Ivy_Cut_t; +struct Ivy_Cut_t_ +{ +    short       nSize; +    short       nSizeMax; +    int         pArray[IVY_CUT_INPUT]; +    unsigned    uHash; +}; + +typedef struct Ivy_Store_t_ Ivy_Store_t; +struct Ivy_Store_t_ +{ +    int         nCuts; +    int         nCutsMax; +    Ivy_Cut_t   pCuts[IVY_CUT_LIMIT]; // storage for cuts +}; +  ////////////////////////////////////////////////////////////////////////  ///                      MACRO DEFINITIONS                           ///  //////////////////////////////////////////////////////////////////////// @@ -133,14 +160,6 @@ static inline int          Ivy_InfoHasBit( unsigned * p, int i )  { return (p[(i  static inline void         Ivy_InfoSetBit( unsigned * p, int i )  { p[(i)>>5] |= (1<<((i) & 31));               }  static inline void         Ivy_InfoXorBit( unsigned * p, int i )  { p[(i)>>5] ^= (1<<((i) & 31));               } -static inline int          Ivy_FanCreate( int Id, int fCompl )    { return (Id << 1) | fCompl;                  } -static inline int          Ivy_FanId( int Fan )                   { return Fan >> 1;                            } -static inline int          Ivy_FanCompl( int Fan )                { return Fan & 1;                             } - -static inline int          Ivy_LeafCreate( int Id, int Lat )      { return (Id << 4) | Lat;                     } -static inline int          Ivy_LeafId( int Leaf )                 { return Leaf >> 4;                           } -static inline int          Ivy_LeafLat( int Leaf )                { return Leaf & 15;                           } -  static inline Ivy_Obj_t *  Ivy_Regular( Ivy_Obj_t * p )           { return (Ivy_Obj_t *)((unsigned)(p) & ~01);  }  static inline Ivy_Obj_t *  Ivy_Not( Ivy_Obj_t * p )               { return (Ivy_Obj_t *)((unsigned)(p) ^  01);  }  static inline Ivy_Obj_t *  Ivy_NotCond( Ivy_Obj_t * p, int c )    { return (Ivy_Obj_t *)((unsigned)(p) ^ (c));  } @@ -153,6 +172,19 @@ static inline Ivy_Obj_t *  Ivy_ManPi( Ivy_Man_t * p, int i )      { return p->pO  static inline Ivy_Obj_t *  Ivy_ManPo( Ivy_Man_t * p, int i )      { return p->pObjs + Vec_IntEntry(p->vPos,i);  }  static inline Ivy_Obj_t *  Ivy_ManObj( Ivy_Man_t * p, int i )     { return p->pObjs + i;                        } +static inline Ivy_Edge_t   Ivy_EdgeCreate( int Id, int fCompl )            { return (Id << 1) | fCompl;                  } +static inline int          Ivy_EdgeId( Ivy_Edge_t Edge )                   { return Edge >> 1;                           } +static inline int          Ivy_EdgeIsComplement( Ivy_Edge_t Edge )         { return Edge & 1;                            } +static inline Ivy_Edge_t   Ivy_EdgeRegular( Ivy_Edge_t Edge )              { return (Edge >> 1) << 1;                    } +static inline Ivy_Edge_t   Ivy_EdgeNot( Ivy_Edge_t Edge )                  { return Edge ^ 1;                            } +static inline Ivy_Edge_t   Ivy_EdgeNotCond( Ivy_Edge_t Edge, int fCond )   { return Edge ^ fCond;                        } +static inline Ivy_Edge_t   Ivy_EdgeFromNode( Ivy_Obj_t * pNode )           { return Ivy_EdgeCreate( Ivy_Regular(pNode)->Id, Ivy_IsComplement(pNode) );          } +static inline Ivy_Obj_t *  Ivy_EdgeToNode( Ivy_Man_t * p, Ivy_Edge_t Edge ){ return Ivy_NotCond( Ivy_ManObj(p, Ivy_EdgeId(Edge)), Ivy_EdgeIsComplement(Edge) ); } + +static inline int          Ivy_LeafCreate( int Id, int Lat )      { return (Id << 4) | Lat;                     } +static inline int          Ivy_LeafId( int Leaf )                 { return Leaf >> 4;                           } +static inline int          Ivy_LeafLat( int Leaf )                { return Leaf & 15;                           } +  static inline int          Ivy_ManPiNum( Ivy_Man_t * p )          { return p->nObjs[IVY_PI];                    }  static inline int          Ivy_ManPoNum( Ivy_Man_t * p )          { return p->nObjs[IVY_PO];                    }  static inline int          Ivy_ManAssertNum( Ivy_Man_t * p )      { return p->nObjs[IVY_ASSERT];                } @@ -185,9 +217,9 @@ static inline int          Ivy_ObjIsAnd( Ivy_Obj_t * pObj )       { assert( !Ivy  static inline int          Ivy_ObjIsExor( Ivy_Obj_t * pObj )      { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_EXOR;   }  static inline int          Ivy_ObjIsBuf( Ivy_Obj_t * pObj )       { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_BUF;    }  static inline int          Ivy_ObjIsNode( Ivy_Obj_t * pObj )      { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_AND || pObj->Type == IVY_EXOR; } -static inline int          Ivy_ObjIsTerm( Ivy_Obj_t * pObj )      { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_PI || pObj->Type == IVY_PO || pObj->Type == IVY_ASSERT; } +static inline int          Ivy_ObjIsTerm( Ivy_Obj_t * pObj )      { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_PI  || pObj->Type == IVY_PO || pObj->Type == IVY_ASSERT; }  static inline int          Ivy_ObjIsHash( Ivy_Obj_t * pObj )      { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_AND || pObj->Type == IVY_EXOR || pObj->Type == IVY_LATCH; } -static inline int          Ivy_ObjIsOneFanin( Ivy_Obj_t * pObj )  { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_PO || pObj->Type == IVY_ASSERT || pObj->Type == IVY_BUF || pObj->Type == IVY_LATCH; } +static inline int          Ivy_ObjIsOneFanin( Ivy_Obj_t * pObj )  { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_PO  || pObj->Type == IVY_ASSERT || pObj->Type == IVY_BUF || pObj->Type == IVY_LATCH; }  static inline int          Ivy_ObjIsAndMulti( Ivy_Obj_t * pObj )  { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_ANDM;   }  static inline int          Ivy_ObjIsExorMulti( Ivy_Obj_t * pObj ) { assert( !Ivy_IsComplement(pObj) ); return pObj->Type == IVY_EXORM;  } @@ -227,13 +259,9 @@ static inline Ivy_Obj_t *  Ivy_ObjChild0( Ivy_Obj_t * pObj )      { assert( !Ivy  static inline Ivy_Obj_t *  Ivy_ObjChild1( Ivy_Obj_t * pObj )      { assert( !Ivy_IsComplement(pObj) ); return Ivy_NotCond( Ivy_ObjFanin1(pObj), Ivy_ObjFaninC1(pObj) );   }  static inline int          Ivy_ObjLevelR( Ivy_Obj_t * pObj )      { assert( !Ivy_IsComplement(pObj) ); return pObj->LevelR;                           }  static inline int          Ivy_ObjLevel( Ivy_Obj_t * pObj )       { assert( !Ivy_IsComplement(pObj) ); return pObj->Level;                            } -static inline int          Ivy_ObjLevelNew( Ivy_Obj_t * pObj )    { assert( !Ivy_IsComplement(pObj) ); return 1 + IVY_MAX(Ivy_ObjFanin0(pObj)->Level, Ivy_ObjFanin1(pObj)->Level);       } +static inline int          Ivy_ObjLevelNew( Ivy_Obj_t * pObj )    { assert( !Ivy_IsComplement(pObj) ); return 1 + Ivy_ObjIsExor(pObj) + IVY_MAX(Ivy_ObjFanin0(pObj)->Level, Ivy_ObjFanin1(pObj)->Level);       }  static inline void         Ivy_ObjClean( Ivy_Obj_t * pObj )       {       int IdSaved = pObj->Id;  -    if ( IdSaved == 54 ) -    { -        int x = 0; -    }      memset( pObj, 0, sizeof(Ivy_Obj_t) );       pObj->Id = IdSaved;   } @@ -339,6 +367,8 @@ static inline int          Ivy_ObjFaninNum( Ivy_Obj_t * pObj )  // iterator over all objects, including those currently not used  #define Ivy_ManForEachObj( p, pObj, i )                                                  \      for ( i = 0, pObj = p->pObjs; i < p->ObjIdNext; i++, pObj++ ) +#define Ivy_ManForEachObjReverse( p, pObj, i )                                           \ +    for ( i = p->ObjIdNext - 1, pObj = p->pObjs + i; i >= 0; i--, pObj-- )  // iterator over the primary inputs  #define Ivy_ManForEachPi( p, pObj, i )                                                   \      for ( i = 0; i < Vec_IntSize(p->vPis) && ((pObj) = Ivy_ManPi(p, i)); i++ ) @@ -369,6 +399,9 @@ static inline int          Ivy_ObjFaninNum( Ivy_Obj_t * pObj )  ///                    FUNCTION DECLARATIONS                         ///  //////////////////////////////////////////////////////////////////////// +/*=== ivyBalance.c ========================================================*/ +extern Ivy_Man_t *     Ivy_ManBalance( Ivy_Man_t * p, int fUpdateLevel ); +extern Ivy_Obj_t *     Ivy_NodeBalanceBuildSuper( Vec_Ptr_t * vSuper, Ivy_Type_t Type, int fUpdateLevel );  /*=== ivyCanon.c ========================================================*/  extern Ivy_Obj_t *     Ivy_CanonAnd( Ivy_Obj_t * p0, Ivy_Obj_t * p1 );  extern Ivy_Obj_t *     Ivy_CanonExor( Ivy_Obj_t * p0, Ivy_Obj_t * p1 ); @@ -377,11 +410,13 @@ extern Ivy_Obj_t *     Ivy_CanonLatch( Ivy_Obj_t * pObj, Ivy_Init_t Init );  extern int             Ivy_ManCheck( Ivy_Man_t * p );  /*=== ivyCut.c ==========================================================*/  extern void            Ivy_ManSeqFindCut( Ivy_Obj_t * pNode, Vec_Int_t * vFront, Vec_Int_t * vInside, int nSize ); -/*=== ivyBalance.c ======================================================*/ -extern int             Ivy_ManBalance( Ivy_Man_t * p, int fUpdateLevel ); +extern Ivy_Store_t *   Ivy_NodeFindCutsAll( Ivy_Obj_t * pObj, int nLeaves );  /*=== ivyDfs.c ==========================================================*/  extern Vec_Int_t *     Ivy_ManDfs( Ivy_Man_t * p );  extern Vec_Int_t *     Ivy_ManDfsExt( Ivy_Man_t * p ); +extern void            Ivy_ManCollectCone( Ivy_Obj_t * pObj, Vec_Ptr_t * vFront, Vec_Ptr_t * vCone ); +extern Vec_Vec_t *     Ivy_ManLevelize( Ivy_Man_t * p ); +extern Vec_Int_t *     Ivy_ManRequiredLevels( Ivy_Man_t * p );  /*=== ivyDsd.c ==========================================================*/  extern int             Ivy_TruthDsd( unsigned uTruth, Vec_Int_t * vTree );  extern void            Ivy_TruthDsdPrint( FILE * pFile, Vec_Int_t * vTree ); @@ -399,6 +434,7 @@ extern Ivy_Obj_t *     Ivy_Multi( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type  extern Ivy_Obj_t *     Ivy_Multi1( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type );  extern Ivy_Obj_t *     Ivy_Multi_rec( Ivy_Obj_t ** ppObjs, int nObjs, Ivy_Type_t Type );  extern Ivy_Obj_t *     Ivy_MultiBalance_rec( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type ); +extern int             Ivy_MultiPlus( Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone, Ivy_Type_t Type, int nLimit, Vec_Ptr_t * vSol );  /*=== ivyObj.c ==========================================================*/  extern Ivy_Obj_t *     Ivy_ObjCreate( Ivy_Obj_t * pGhost );  extern Ivy_Obj_t *     Ivy_ObjCreateExt( Ivy_Man_t * p, Ivy_Type_t Type ); @@ -415,8 +451,12 @@ extern Ivy_Obj_t *     Ivy_Exor( Ivy_Obj_t * p0, Ivy_Obj_t * p1 );  extern Ivy_Obj_t *     Ivy_Mux( Ivy_Obj_t * pC, Ivy_Obj_t * p1, Ivy_Obj_t * p0 );  extern Ivy_Obj_t *     Ivy_Maj( Ivy_Obj_t * pA, Ivy_Obj_t * pB, Ivy_Obj_t * pC );  extern Ivy_Obj_t *     Ivy_Miter( Vec_Ptr_t * vPairs ); +/*=== ivyResyn.c =========================================================*/ +extern Ivy_Man_t *     Ivy_ManResyn( Ivy_Man_t * p, int fUpdateLevel );  /*=== ivyRewrite.c =========================================================*/  extern int             Ivy_ManSeqRewrite( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost ); +extern int             Ivy_ManRewriteAlg( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost ); +extern int             Ivy_ManRewritePre( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost, int fVerbose );  /*=== ivyTable.c ========================================================*/  extern Ivy_Obj_t *     Ivy_TableLookup( Ivy_Obj_t * pObj );  extern void            Ivy_TableInsert( Ivy_Obj_t * pObj ); @@ -437,6 +477,8 @@ extern Ivy_Obj_t *     Ivy_ObjRecognizeMux( Ivy_Obj_t * pObj, Ivy_Obj_t ** ppObj  extern unsigned *      Ivy_ManCutTruth( Ivy_Obj_t * pRoot, Vec_Int_t * vLeaves, Vec_Int_t * vNodes, Vec_Int_t * vTruth );  extern Ivy_Obj_t *     Ivy_NodeRealFanin_rec( Ivy_Obj_t * pNode, int iFanin );  extern Vec_Int_t *     Ivy_ManLatches( Ivy_Man_t * p ); +extern int             Ivy_ManReadLevels( Ivy_Man_t * p ); +extern Ivy_Obj_t *     Ivy_ObjReal( Ivy_Obj_t * pObj );  #ifdef __cplusplus  } diff --git a/src/temp/ivy/ivyBalance.c b/src/temp/ivy/ivyBalance.c index bbe69dd9..2e230ed2 100644 --- a/src/temp/ivy/ivyBalance.c +++ b/src/temp/ivy/ivyBalance.c @@ -17,32 +17,18 @@    Revision    [$Id: ivyBalance.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $]  ***********************************************************************/ - +   #include "ivy.h"  ////////////////////////////////////////////////////////////////////////  ///                        DECLARATIONS                              ///  //////////////////////////////////////////////////////////////////////// -static void Ivy_NodeBalance( Ivy_Obj_t * pNode, int fUpdateLevel, Vec_Ptr_t * vFront, Vec_Ptr_t * vSpots ); - -// this procedure returns 1 if the node cannot be expanded -static inline int Ivy_NodeStopFanin( Ivy_Obj_t * pNode, int iFanin ) -{ -    if ( iFanin == 0 ) -        return Ivy_ObjFanin0(pNode)->Type != pNode->Type || Ivy_ObjRefs(Ivy_ObjFanin0(pNode)) > 1 || Ivy_ObjFaninC0(pNode); -    else -        return Ivy_ObjFanin1(pNode)->Type != pNode->Type || Ivy_ObjRefs(Ivy_ObjFanin1(pNode)) > 1 || Ivy_ObjFaninC1(pNode); -} - -// this procedure returns 1 if the node cannot be recursively dereferenced -static inline int Ivy_NodeBalanceDerefFanin( Ivy_Obj_t * pNode, int iFanin ) -{ -    if ( iFanin == 0 ) -        return Ivy_ObjFanin0(pNode)->Type == pNode->Type && Ivy_ObjRefs(Ivy_ObjFanin0(pNode)) == 0 && !Ivy_ObjFaninC0(pNode); -    else -        return Ivy_ObjFanin1(pNode)->Type == pNode->Type && Ivy_ObjRefs(Ivy_ObjFanin1(pNode)) == 0 && !Ivy_ObjFaninC1(pNode); -} +static int         Ivy_NodeBalance_rec( Ivy_Man_t * pNew, Ivy_Obj_t * pObj, Vec_Vec_t * vStore, int Level, int fUpdateLevel ); +static Vec_Ptr_t * Ivy_NodeBalanceCone( Ivy_Obj_t * pObj, Vec_Vec_t * vStore, int Level ); +static int         Ivy_NodeBalanceFindLeft( Vec_Ptr_t * vSuper ); +static void        Ivy_NodeBalancePermute( Vec_Ptr_t * vSuper, int LeftBound, int fExor ); +static void        Ivy_NodeBalancePushUniqueOrderByLevel( Vec_Ptr_t * vStore, Ivy_Obj_t * pObj );  ////////////////////////////////////////////////////////////////////////  ///                     FUNCTION DEFINITIONS                         /// @@ -59,44 +45,41 @@ static inline int Ivy_NodeBalanceDerefFanin( Ivy_Obj_t * pNode, int iFanin )    SeeAlso     []  ***********************************************************************/ -int Ivy_ManBalance( Ivy_Man_t * p, int fUpdateLevel ) +Ivy_Man_t * Ivy_ManBalance( Ivy_Man_t * p, int fUpdateLevel )  { -    Vec_Int_t * vNodes; -    Vec_Ptr_t * vFront, * vSpots; -    Ivy_Obj_t * pNode; -    int i; -    vSpots = Vec_PtrAlloc( 50 ); -    vFront = Vec_PtrAlloc( 50 ); -    vNodes = Ivy_ManDfs( p ); -    Ivy_ManForEachNodeVec( p, vNodes, pNode, i ) +    Ivy_Man_t * pNew; +    Ivy_Obj_t * pObj, * pDriver; +    Vec_Vec_t * vStore; +    int i, NewNodeId; +    // clean the old manager +    Ivy_ManCleanTravId( p ); +    // create the new manager  +    pNew = Ivy_ManStart( Ivy_ManPiNum(p), Ivy_ManPoNum(p), Ivy_ManNodeNum(p) + 20000 ); +    // map the nodes +    Ivy_ManConst1(p)->TravId = Ivy_EdgeFromNode( Ivy_ManConst1(pNew) ); +    Ivy_ManForEachPi( p, pObj, i ) +        pObj->TravId = Ivy_EdgeFromNode( Ivy_ManPi(pNew, i) ); +    // balance the AIG +    vStore = Vec_VecAlloc( 50 ); +    Ivy_ManForEachPo( p, pObj, i )      { -        if ( Ivy_ObjIsBuf(pNode) ) -            continue; -        // fix the fanin buffer problem -        Ivy_NodeFixBufferFanins( pNode ); -        // skip node if it became a buffer -        if ( Ivy_ObjIsBuf(pNode) ) -            continue; -        // skip nodes with one fanout if type of the node is the same as type of the fanout -        // such nodes will be processed when the fanouts are processed -        if ( Ivy_ObjRefs(pNode) == 1 && Ivy_ObjIsExor(pNode) == Ivy_ObjExorFanout(pNode) ) -            continue; -        assert( Ivy_ObjRefs(pNode) > 0 ); -        // do not balance the node if both if its fanins have more than one fanout -        if ( Ivy_NodeStopFanin(pNode, 0) && Ivy_NodeStopFanin(pNode, 1) ) -             continue; -        // try balancing this node -        Ivy_NodeBalance( pNode, fUpdateLevel, vFront, vSpots ); +        pDriver   = Ivy_ObjReal( Ivy_ObjChild0(pObj) ); +        NewNodeId = Ivy_NodeBalance_rec( pNew, Ivy_Regular(pDriver), vStore, 0, fUpdateLevel ); +        NewNodeId = Ivy_EdgeNotCond( NewNodeId, Ivy_IsComplement(pDriver) ); +        Ivy_ObjConnect( Ivy_ManPo(pNew, i), Ivy_EdgeToNode(pNew, NewNodeId) );      } -    Vec_IntFree( vNodes ); -    Vec_PtrFree( vSpots ); -    Vec_PtrFree( vFront ); -    return 1; +    Vec_VecFree( vStore ); +    if ( i = Ivy_ManCleanup( pNew ) ) +        printf( "Cleanup after balancing removed %d dangling nodes.\n", i ); +    // check the resulting AIG +    if ( !Ivy_ManCheck(pNew) ) +        printf( "Ivy_ManBalance(): The check has failed.\n" ); +    return pNew;  }  /**Function************************************************************* -  Synopsis    [Dereferences MFFC of the node.] +  Synopsis    [Procedure used for sorting the nodes in decreasing order of levels.]    Description [] @@ -105,24 +88,19 @@ int Ivy_ManBalance( Ivy_Man_t * p, int fUpdateLevel )    SeeAlso     []  ***********************************************************************/ -void Ivy_NodeBalanceDeref_rec( Ivy_Obj_t * pNode ) +int Ivy_NodeCompareLevelsDecrease( Ivy_Obj_t ** pp1, Ivy_Obj_t ** pp2 )  { -    Ivy_Obj_t * pFan; -    // deref the first fanin -    pFan = Ivy_ObjFanin0(pNode); -    Ivy_ObjRefsDec( pFan ); -    if ( Ivy_NodeBalanceDerefFanin(pNode, 0) ) -        Ivy_NodeBalanceDeref_rec( pFan ); -    // deref the second fanin -    pFan = Ivy_ObjFanin1(pNode); -    Ivy_ObjRefsDec( pFan ); -    if ( Ivy_NodeBalanceDerefFanin(pNode, 1) ) -        Ivy_NodeBalanceDeref_rec( pFan ); +    int Diff = Ivy_Regular(*pp1)->Level - Ivy_Regular(*pp2)->Level; +    if ( Diff > 0 ) +        return -1; +    if ( Diff < 0 )  +        return 1; +    return 0;   }  /**Function************************************************************* -  Synopsis    [Removes nodes inside supergate and determines frontier.] +  Synopsis    [Returns the ID of new node constructed.]    Description [] @@ -131,35 +109,47 @@ void Ivy_NodeBalanceDeref_rec( Ivy_Obj_t * pNode )    SeeAlso     []  ***********************************************************************/ -void Ivy_NodeBalanceCollect_rec( Ivy_Obj_t * pNode, Vec_Ptr_t * vSpots, Vec_Ptr_t * vFront ) +int Ivy_NodeBalance_rec( Ivy_Man_t * pNew, Ivy_Obj_t * pObjOld, Vec_Vec_t * vStore, int Level, int fUpdateLevel )  { -    Ivy_Obj_t * pFanin; -    // skip visited nodes -    if ( Vec_PtrFind(vSpots, pNode) >= 0 ) -        return; -    // collect node -    Vec_PtrPush( vSpots, pNode ); -    // first fanin -    pFanin = Ivy_ObjFanin0(pNode); -    if ( Ivy_ObjRefs(pFanin) == 0 ) -        Ivy_NodeBalanceCollect_rec( pFanin, vSpots, vFront ); -    else if ( Ivy_ObjIsExor(pNode) && Vec_PtrFind(vFront, Ivy_ObjChild0(pNode)) >= 0 ) -        Vec_PtrRemove( vFront, Ivy_ObjChild0(pNode) ); -    else -        Vec_PtrPushUnique( vFront, Ivy_ObjChild0(pNode) ); -    // second fanin -    pFanin = Ivy_ObjFanin1(pNode); -    if ( Ivy_ObjRefs(pFanin) == 0 ) -        Ivy_NodeBalanceCollect_rec( pFanin, vSpots, vFront ); -    else if ( Ivy_ObjIsExor(pNode) && Vec_PtrFind(vFront, Ivy_ObjChild1(pNode)) >= 0 ) -        Vec_PtrRemove( vFront, Ivy_ObjChild1(pNode) ); -    else -        Vec_PtrPushUnique( vFront, Ivy_ObjChild1(pNode) ); +    Ivy_Obj_t * pObjNew; +    Vec_Ptr_t * vSuper; +    int i, NewNodeId; +    assert( !Ivy_IsComplement(pObjOld) ); +    assert( !Ivy_ObjIsBuf(pObjOld) ); +    // return if the result is known +    if ( Ivy_ObjIsConst1(pObjOld) ) +        return pObjOld->TravId; +    if ( pObjOld->TravId ) +        return pObjOld->TravId; +    assert( Ivy_ObjIsNode(pObjOld) ); +    // get the implication supergate +    vSuper = Ivy_NodeBalanceCone( pObjOld, vStore, Level ); +    if ( vSuper->nSize == 0 ) +    { // it means that the supergate contains two nodes in the opposite polarity +        pObjOld->TravId = Ivy_EdgeFromNode( Ivy_ManConst0(pNew) ); +        return pObjOld->TravId; +    } +    if ( vSuper->nSize < 2 ) +        printf( "BUG!\n" ); +    // for each old node, derive the new well-balanced node +    for ( i = 0; i < vSuper->nSize; i++ ) +    { +        NewNodeId = Ivy_NodeBalance_rec( pNew, Ivy_Regular(vSuper->pArray[i]), vStore, Level + 1, fUpdateLevel ); +        NewNodeId = Ivy_EdgeNotCond( NewNodeId, Ivy_IsComplement(vSuper->pArray[i]) ); +        vSuper->pArray[i] = Ivy_EdgeToNode( pNew, NewNodeId ); +    } +    // build the supergate +    pObjNew = Ivy_NodeBalanceBuildSuper( vSuper, Ivy_ObjType(pObjOld), fUpdateLevel ); +    vSuper->nSize = 0; +    // make sure the balanced node is not assigned +    assert( pObjOld->TravId == 0 ); +    pObjOld->TravId = Ivy_EdgeFromNode( pObjNew ); +    return pObjOld->TravId;  }  /**Function************************************************************* -  Synopsis    [Comparison procedure for two nodes by level.] +  Synopsis    [Builds implication supergate.]    Description [] @@ -168,89 +158,107 @@ void Ivy_NodeBalanceCollect_rec( Ivy_Obj_t * pNode, Vec_Ptr_t * vSpots, Vec_Ptr_    SeeAlso     []  ***********************************************************************/ -int Ivy_BalanceCompareByLevel( Ivy_Obj_t ** pp1, Ivy_Obj_t ** pp2 ) +Ivy_Obj_t * Ivy_NodeBalanceBuildSuper( Vec_Ptr_t * vSuper, Ivy_Type_t Type, int fUpdateLevel )  { -    int Level1 = Ivy_ObjLevel( *pp1 ); -    int Level2 = Ivy_ObjLevel( *pp2 ); -    if ( Level1 > Level2 ) -        return -1; -    if ( Level1 < Level2 ) -        return 1; -    return 0; +    Ivy_Obj_t * pObj1, * pObj2; +    int LeftBound; +    assert( vSuper->nSize > 1 ); +    // sort the new nodes by level in the decreasing order +    Vec_PtrSort( vSuper, Ivy_NodeCompareLevelsDecrease ); +    // balance the nodes +    while ( vSuper->nSize > 1 ) +    { +        // find the left bound on the node to be paired +        LeftBound = (!fUpdateLevel)? 0 : Ivy_NodeBalanceFindLeft( vSuper ); +        // find the node that can be shared (if no such node, randomize choice) +        Ivy_NodeBalancePermute( vSuper, LeftBound, Type == IVY_EXOR ); +        // pull out the last two nodes +        pObj1 = Vec_PtrPop(vSuper); +        pObj2 = Vec_PtrPop(vSuper); +        Ivy_NodeBalancePushUniqueOrderByLevel( vSuper, Ivy_Oper(pObj1, pObj2, Type) ); +    } +    return Vec_PtrEntry(vSuper, 0);  }  /**Function************************************************************* -  Synopsis    [Removes nodes inside supergate and determines frontier.] +  Synopsis    [Collects the nodes of the supergate.] -  Description [Return 1 if the output needs to be complemented.] +  Description []    SideEffects []    SeeAlso     []  ***********************************************************************/ -int Ivy_NodeBalancePrepare( Ivy_Obj_t * pNode, Vec_Ptr_t * vFront, Vec_Ptr_t * vSpots ) +int Ivy_NodeBalanceCone_rec( Ivy_Obj_t * pRoot, Ivy_Obj_t * pObj, Vec_Ptr_t * vSuper )  { -    Ivy_Man_t * pMan = Ivy_ObjMan( pNode ); -    Ivy_Obj_t * pObj, * pNext; -    int i, k, Counter = 0; -    // dereference the cone -    Ivy_NodeBalanceDeref_rec( pNode ); -    // collect the frontier and the internal nodes -    Vec_PtrClear( vFront ); -    Vec_PtrClear( vSpots ); -    Ivy_NodeBalanceCollect_rec( pNode, vSpots, vFront ); -    // remove all the nodes -    Vec_PtrForEachEntry( vSpots, pObj, i ) -    { -        // skip the first entry (the node itself) -        if ( i == 0 ) continue; -        // collect the free entries -        Vec_IntPush( pMan->vFree, pObj->Id ); -        Ivy_ObjDelete( pObj, 1 ); -    } -    // sort nodes by level in decreasing order -    qsort( (void *)Vec_PtrArray(vFront), Vec_PtrSize(vFront), sizeof(Ivy_Obj_t *),  -            (int (*)(const void *, const void *))Ivy_BalanceCompareByLevel ); -    // check if there are nodes and their complements -    Counter = 0; -    Vec_PtrForEachEntry( vFront, pObj, i ) +    int RetValue1, RetValue2, i; +    // check if the node is visited +    if ( Ivy_Regular(pObj)->fMarkB )      { -        if ( i == Vec_PtrSize(vFront) - 1 ) -            break; -        pNext = Vec_PtrEntry( vFront, i+1 ); -        if ( Ivy_Regular(pObj) == Ivy_Regular(pNext) ) -        { -            assert( pObj == Ivy_Not(pNext) ); -            Vec_PtrWriteEntry( vFront, i, NULL ); -            Vec_PtrWriteEntry( vFront, i+1, NULL ); -            i++; -            Counter++; -        } -    } -    // if there are no complemented pairs, go ahead and balance -    if ( Counter == 0 ) +        // check if the node occurs in the same polarity +        for ( i = 0; i < vSuper->nSize; i++ ) +            if ( vSuper->pArray[i] == pObj ) +                return 1; +        // check if the node is present in the opposite polarity +        for ( i = 0; i < vSuper->nSize; i++ ) +            if ( vSuper->pArray[i] == Ivy_Not(pObj) ) +                return -1; +        assert( 0 );          return 0; -    // if there are complemented pairs and this is AND, create const 0 -    if ( Counter > 0 && Ivy_ObjIsAnd(pNode) ) +    } +    // if the new node is complemented or a PI, another gate begins +    if ( pObj != pRoot && (Ivy_IsComplement(pObj) || Ivy_ObjType(pObj) != Ivy_ObjType(pRoot) || Ivy_ObjRefs(pObj) > 1) )      { -        Vec_PtrClear( vFront ); -        Vec_PtrPush( vFront, Ivy_ManConst0(pMan) ); +        Vec_PtrPush( vSuper, pObj ); +        Ivy_Regular(pObj)->fMarkB = 1;          return 0;      } -    assert( Counter > 0 && Ivy_ObjIsExor(pNode) ); -    // remove the pairs -    k = 0; -    Vec_PtrForEachEntry( vFront, pObj, i ) -        if ( pObj )  -            Vec_PtrWriteEntry( vFront, k++, pObj ); -    Vec_PtrShrink( vFront, k ); -    // add constant zero node if nothing is left -    if ( Vec_PtrSize(vFront) == 0 ) -        Vec_PtrPush( vFront, Ivy_ManConst0(pMan) ); -    // return 1 if the number of pairs is odd (need to complement the output) -    return Counter & 1; +    assert( !Ivy_IsComplement(pObj) ); +    assert( Ivy_ObjIsNode(pObj) ); +    // go through the branches +    RetValue1 = Ivy_NodeBalanceCone_rec( pRoot, Ivy_ObjReal( Ivy_ObjChild0(pObj) ), vSuper ); +    RetValue2 = Ivy_NodeBalanceCone_rec( pRoot, Ivy_ObjReal( Ivy_ObjChild1(pObj) ), vSuper ); +    if ( RetValue1 == -1 || RetValue2 == -1 ) +        return -1; +    // return 1 if at least one branch has a duplicate +    return RetValue1 || RetValue2; +} + +/**Function************************************************************* + +  Synopsis    [Collects the nodes of the supergate.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Vec_Ptr_t * Ivy_NodeBalanceCone( Ivy_Obj_t * pObj, Vec_Vec_t * vStore, int Level ) +{ +    Vec_Ptr_t * vNodes; +    int RetValue, i; +    assert( !Ivy_IsComplement(pObj) ); +    // extend the storage +    if ( Vec_VecSize( vStore ) <= Level ) +        Vec_VecPush( vStore, Level, 0 ); +    // get the temporary array of nodes +    vNodes = Vec_VecEntry( vStore, Level ); +    Vec_PtrClear( vNodes ); +    // collect the nodes in the implication supergate +    RetValue = Ivy_NodeBalanceCone_rec( pObj, pObj, vNodes ); +    assert( vNodes->nSize > 1 ); +    // unmark the visited nodes +    Vec_PtrForEachEntry( vNodes, pObj, i ) +        Ivy_Regular(pObj)->fMarkB = 0; +    // if we found the node and its complement in the same implication supergate,  +    // return empty set of nodes (meaning that we should use constant-0 node) +    if ( RetValue == -1 ) +        vNodes->nSize = 0; +    return vNodes;  }  /**Function************************************************************* @@ -270,27 +278,27 @@ int Ivy_NodeBalancePrepare( Ivy_Obj_t * pNode, Vec_Ptr_t * vFront, Vec_Ptr_t * v  ***********************************************************************/  int Ivy_NodeBalanceFindLeft( Vec_Ptr_t * vSuper )  { -    Ivy_Obj_t * pNodeRight, * pNodeLeft; +    Ivy_Obj_t * pObjRight, * pObjLeft;      int Current;      // if two or less nodes, pair with the first      if ( Vec_PtrSize(vSuper) < 3 )          return 0;      // set the pointer to the one before the last      Current = Vec_PtrSize(vSuper) - 2; -    pNodeRight = Vec_PtrEntry( vSuper, Current ); +    pObjRight = Vec_PtrEntry( vSuper, Current );      // go through the nodes to the left of this one      for ( Current--; Current >= 0; Current-- )      {          // get the next node on the left -        pNodeLeft = Vec_PtrEntry( vSuper, Current ); +        pObjLeft = Vec_PtrEntry( vSuper, Current );          // if the level of this node is different, quit the loop -        if ( Ivy_Regular(pNodeLeft)->Level != Ivy_Regular(pNodeRight)->Level ) +        if ( Ivy_Regular(pObjLeft)->Level != Ivy_Regular(pObjRight)->Level )              break;      }      Current++;          // get the node, for which the equality holds -    pNodeLeft = Vec_PtrEntry( vSuper, Current ); -    assert( Ivy_Regular(pNodeLeft)->Level == Ivy_Regular(pNodeRight)->Level ); +    pObjLeft = Vec_PtrEntry( vSuper, Current ); +    assert( Ivy_Regular(pObjLeft)->Level == Ivy_Regular(pObjRight)->Level );      return Current;  } @@ -306,9 +314,9 @@ int Ivy_NodeBalanceFindLeft( Vec_Ptr_t * vSuper )    SeeAlso     []  ***********************************************************************/ -void Ivy_NodeBalancePermute( Ivy_Man_t * pMan, Vec_Ptr_t * vSuper, int LeftBound, int fExor ) +void Ivy_NodeBalancePermute( Vec_Ptr_t * vSuper, int LeftBound, int fExor )  { -    Ivy_Obj_t * pNode1, * pNode2, * pNode3, * pGhost; +    Ivy_Obj_t * pObj1, * pObj2, * pObj3, * pGhost;      int RightBound, i;      // get the right bound      RightBound = Vec_PtrSize(vSuper) - 2; @@ -316,19 +324,19 @@ void Ivy_NodeBalancePermute( Ivy_Man_t * pMan, Vec_Ptr_t * vSuper, int LeftBound      if ( LeftBound == RightBound )          return;      // get the two last nodes -    pNode1 = Vec_PtrEntry( vSuper, RightBound + 1 ); -    pNode2 = Vec_PtrEntry( vSuper, RightBound     ); +    pObj1 = Vec_PtrEntry( vSuper, RightBound + 1 ); +    pObj2 = Vec_PtrEntry( vSuper, RightBound     );      // find the first node that can be shared      for ( i = RightBound; i >= LeftBound; i-- )      { -        pNode3 = Vec_PtrEntry( vSuper, i ); -        pGhost = Ivy_ObjCreateGhost( pNode1, pNode3, fExor? IVY_EXOR : IVY_AND, IVY_INIT_NONE ); +        pObj3 = Vec_PtrEntry( vSuper, i ); +        pGhost = Ivy_ObjCreateGhost( pObj1, pObj3, fExor? IVY_EXOR : IVY_AND, IVY_INIT_NONE );          if ( Ivy_TableLookup( pGhost ) )          { -            if ( pNode3 == pNode2 ) +            if ( pObj3 == pObj2 )                  return; -            Vec_PtrWriteEntry( vSuper, i,          pNode2 ); -            Vec_PtrWriteEntry( vSuper, RightBound, pNode3 ); +            Vec_PtrWriteEntry( vSuper, i,          pObj2 ); +            Vec_PtrWriteEntry( vSuper, RightBound, pObj3 );              return;          }      } @@ -336,11 +344,11 @@ void Ivy_NodeBalancePermute( Ivy_Man_t * pMan, Vec_Ptr_t * vSuper, int LeftBound      // we did not find the node to share, randomize choice      {          int Choice = rand() % (RightBound - LeftBound + 1); -        pNode3 = Vec_PtrEntry( vSuper, LeftBound + Choice ); -        if ( pNode3 == pNode2 ) +        pObj3 = Vec_PtrEntry( vSuper, LeftBound + Choice ); +        if ( pObj3 == pObj2 )              return; -        Vec_PtrWriteEntry( vSuper, LeftBound + Choice, pNode2 ); -        Vec_PtrWriteEntry( vSuper, RightBound,         pNode3 ); +        Vec_PtrWriteEntry( vSuper, LeftBound + Choice, pObj2 ); +        Vec_PtrWriteEntry( vSuper, RightBound,         pObj3 );      }  */  } @@ -356,61 +364,22 @@ void Ivy_NodeBalancePermute( Ivy_Man_t * pMan, Vec_Ptr_t * vSuper, int LeftBound    SeeAlso     []  ***********************************************************************/ -void Ivy_NodeBalancePushUniqueOrderByLevel( Vec_Ptr_t * vFront, Ivy_Obj_t * pNode ) +void Ivy_NodeBalancePushUniqueOrderByLevel( Vec_Ptr_t * vStore, Ivy_Obj_t * pObj )  { -    Ivy_Obj_t * pNode1, * pNode2; +    Ivy_Obj_t * pObj1, * pObj2;      int i; -    if ( Vec_PtrPushUnique(vFront, pNode) ) +    if ( Vec_PtrPushUnique(vStore, pObj) )          return;      // find the p of the node -    for ( i = vFront->nSize-1; i > 0; i-- ) +    for ( i = vStore->nSize-1; i > 0; i-- )      { -        pNode1 = vFront->pArray[i  ]; -        pNode2 = vFront->pArray[i-1]; -        if ( Ivy_Regular(pNode1)->Level <= Ivy_Regular(pNode2)->Level ) +        pObj1 = vStore->pArray[i  ]; +        pObj2 = vStore->pArray[i-1]; +        if ( Ivy_Regular(pObj1)->Level <= Ivy_Regular(pObj2)->Level )              break; -        vFront->pArray[i  ] = pNode2; -        vFront->pArray[i-1] = pNode1; -    } -} - -/**Function************************************************************* - -  Synopsis    [Balances one node.] - -  Description [] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -void Ivy_NodeBalance( Ivy_Obj_t * pNode, int fUpdateLevel, Vec_Ptr_t * vFront, Vec_Ptr_t * vSpots ) -{ -    Ivy_Man_t * pMan = Ivy_ObjMan( pNode ); -    Ivy_Obj_t * pFan0, * pFan1, * pNodeNew; -    int fCompl, LeftBound; -    // remove internal nodes and derive the frontier -    fCompl = Ivy_NodeBalancePrepare( pNode, vFront, vSpots ); -    assert( Vec_PtrSize(vFront) > 0 ); -    // balance the nodes -    while ( Vec_PtrSize(vFront) > 1 ) -    { -        // find the left bound on the node to be paired -        LeftBound = (!fUpdateLevel)? 0 : Ivy_NodeBalanceFindLeft( vFront ); -        // find the node that can be shared (if no such node, randomize choice) -        Ivy_NodeBalancePermute( pMan, vFront, LeftBound, Ivy_ObjIsExor(pNode) ); -        // pull out the last two nodes -        pFan0 = Vec_PtrPop(vFront);  assert( !Ivy_ObjIsConst1(Ivy_Regular(pFan0)) ); -        pFan1 = Vec_PtrPop(vFront);  assert( !Ivy_ObjIsConst1(Ivy_Regular(pFan1)) ); -        // create the new node -        pNodeNew = Ivy_ObjCreate( Ivy_ObjCreateGhost(pFan0, pFan1, Ivy_ObjType(pNode), IVY_INIT_NONE) ); -        // add the new node to the frontier -        Ivy_NodeBalancePushUniqueOrderByLevel( vFront, pNodeNew ); +        vStore->pArray[i  ] = pObj2; +        vStore->pArray[i-1] = pObj1;      } -    assert( Vec_PtrSize(vFront) == 1 ); -    // perform the replacement -    Ivy_ObjReplace( pNode, Ivy_NotCond(Vec_PtrPop(vFront), fCompl), 1, 1 );   } diff --git a/src/temp/ivy/ivyCut.c b/src/temp/ivy/ivyCut.c index 57720e17..71a3613c 100644 --- a/src/temp/ivy/ivyCut.c +++ b/src/temp/ivy/ivyCut.c @@ -200,180 +200,6 @@ void Ivy_ManSeqFindCut( Ivy_Obj_t * pRoot, Vec_Int_t * vFront, Vec_Int_t * vInsi -/**Function************************************************************* - -  Synopsis    [Comparison for node pointers.] - -  Description [] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -int Ivy_ManFindAlgCutCompare( Ivy_Obj_t ** pp1, Ivy_Obj_t ** pp2 ) -{ -    if ( *pp1 < *pp2 ) -        return -1; -    if ( *pp1 > *pp2 ) -        return 1; -    return 0; -} - -/**Function************************************************************* - -  Synopsis    [Computing one algebraic cut.] - -  Description [Returns 1 if the tree-leaves of this node where traversed  -  and found to have no external references (and have not been collected).  -  Returns 0 if the tree-leaves have external references and are collected.] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -int Ivy_ManFindAlgCut_rec( Ivy_Obj_t * pRoot, Ivy_Type_t Type, Vec_Ptr_t * vFront ) -{ -    int RetValue0, RetValue1; -    Ivy_Obj_t * pRootR = Ivy_Regular(pRoot); -    assert( Type != IVY_EXOR || !Ivy_IsComplement(pRoot) ); -    // if the node is a buffer skip through it -    if ( Ivy_ObjIsBuf(pRootR) ) -        return Ivy_ManFindAlgCut_rec( Ivy_NotCond(Ivy_ObjChild0(pRootR), Ivy_IsComplement(pRoot)), Type, vFront ); -    // if the node is the end of the tree, return -    if ( Ivy_IsComplement(pRoot) || Ivy_ObjIsCi(pRoot) || Ivy_ObjType(pRoot) != Type ) -    { -        if ( Ivy_ObjRefs(pRootR) == 1 ) -            return 1; -        assert( Ivy_ObjRefs(pRootR) > 1 ); -        Vec_PtrPush( vFront, pRoot ); -        return 0; -    } -    // branch on the node -    assert( Ivy_ObjIsNode(pRoot) ); -    RetValue0 = Ivy_ManFindAlgCut_rec( Ivy_ObjChild0(pRoot), Type, vFront ); -    RetValue1 = Ivy_ManFindAlgCut_rec( Ivy_ObjChild1(pRoot), Type, vFront ); -    // the case when both have no external referenced -    if ( RetValue0 && RetValue1 ) -    { -        if ( Ivy_ObjRefs(pRoot) == 1 ) -            return 1; -        assert( Ivy_ObjRefs(pRoot) > 1 ); -        Vec_PtrPush( vFront, pRoot ); -        return 0; -    } -    // the case when one of them has external references -    if ( RetValue0 ) -        Vec_PtrPush( vFront, Ivy_ObjChild0(pRoot) ); -    if ( RetValue1 ) -        Vec_PtrPush( vFront, Ivy_ObjChild1(pRoot) ); -    return 0; -} - -/**Function************************************************************* - -  Synopsis    [Computing one algebraic cut.] - -  Description [Algebraic cut stops when we hit (a) CI, (b) complemented edge, -  (c) boundary of different gates. Returns 1 if this is a pure tree. -  Returns -1 if the contant 0 is detected. Return 0 if the array can be used.] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -int Ivy_ManFindAlgCut( Ivy_Obj_t * pRoot, Vec_Ptr_t * vFront ) -{ -    Ivy_Obj_t * pObj, * pPrev; -    int RetValue, i, k; -    assert( !Ivy_IsComplement(pRoot) ); -    // clear the frontier and collect the nodes -    Vec_PtrClear( vFront ); -    RetValue = Ivy_ManFindAlgCut_rec( pRoot, Ivy_ObjType(pRoot), vFront ); -    // return if the node is the root of a tree -    if ( RetValue == 1 ) -        return 1; -    // sort the entries to in increasing order -    Vec_PtrSort( vFront, Ivy_ManFindAlgCutCompare ); -    // remove duplicated -    k = 1; -    Vec_PtrForEachEntryStart( vFront, pObj, i, 1 ) -    { -        pPrev = (k == 0 ? NULL : Vec_PtrEntry(vFront, k-1)); -        if ( pObj == pPrev ) -        { -            if ( Ivy_ObjIsExor(pRoot) ) -                k--; -            continue; -        } -        if ( pObj == Ivy_Not(pPrev) ) -            return -1; -        Vec_PtrWriteEntry( vFront, k++, pObj ); -    } -    if ( k == 0 ) -        return -1; -    Vec_PtrShrink( vFront, k ); -    return 0; -} - -/**Function************************************************************* - -  Synopsis    [] - -  Description [] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -void Ivy_ManTestCutsAlg( Ivy_Man_t * p ) -{ -    Vec_Ptr_t * vFront; -    Ivy_Obj_t * pObj, * pTemp; -    int i, k, RetValue; -    vFront = Vec_PtrAlloc( 100 ); -    Ivy_ManForEachObj( p, pObj, i ) -    { -        if ( !Ivy_ObjIsNode(pObj) ) -            continue; -        if ( Ivy_ObjIsMuxType(pObj) ) -        { -            printf( "m " ); -            continue; -        } -        if ( pObj->Id == 509 ) -        { -            int y = 0; -        } - -        RetValue = Ivy_ManFindAlgCut( pObj, vFront ); -        if ( Ivy_ObjIsExor(pObj) ) -            printf( "x" ); -        if ( RetValue == -1 ) -            printf( "Const0 " ); -        else if ( RetValue == 1 || Vec_PtrSize(vFront) <= 2 ) -            printf( ". " ); -        else -            printf( "%d ", Vec_PtrSize(vFront) ); -         -        printf( "( " ); -        Vec_PtrForEachEntry( vFront, pTemp, k ) -            printf( "%d ", Ivy_ObjRefs(Ivy_Regular(pTemp)) ); -        printf( ")\n" ); - -        if ( Vec_PtrSize(vFront) == 5 ) -        { -            int x = 0; -        } -    } -    printf( "\n" ); -    Vec_PtrFree( vFront ); -} - -  /**Function************************************************************* @@ -639,8 +465,8 @@ int Ivy_ManFindBoolCut( Ivy_Obj_t * pRoot, Vec_Ptr_t * vFront, Vec_Ptr_t * vVolu  void Ivy_ManTestCutsBool( Ivy_Man_t * p )  {      Vec_Ptr_t * vFront, * vVolume, * vLeaves; -    Ivy_Obj_t * pObj, * pTemp; -    int i, k, RetValue; +    Ivy_Obj_t * pObj;//, * pTemp; +    int i, RetValue;//, k;      vFront = Vec_PtrAlloc( 100 );      vVolume = Vec_PtrAlloc( 100 );      vLeaves = Vec_PtrAlloc( 100 ); @@ -673,6 +499,376 @@ void Ivy_ManTestCutsBool( Ivy_Man_t * p )      Vec_PtrFree( vLeaves );  } + + +/**Function************************************************************* + +  Synopsis    [Find the hash value of the cut.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline unsigned Ivy_NodeCutHash( Ivy_Cut_t * pCut ) +{ +    int i; +//    for ( i = 1; i < pCut->nSize; i++ ) +//        assert( pCut->pArray[i-1] < pCut->pArray[i] ); +    pCut->uHash = 0; +    for ( i = 0; i < pCut->nSize; i++ ) +        pCut->uHash |= (1 << (pCut->pArray[i] % 31)); +    return pCut->uHash; +} + +/**Function************************************************************* + +  Synopsis    [Removes one node to the cut.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Ivy_NodeCutShrink( Ivy_Cut_t * pCut, int iOld ) +{ +    int i, k; +    for ( i = k = 0; i < pCut->nSize; i++ ) +        if ( pCut->pArray[i] != iOld ) +            pCut->pArray[k++] = pCut->pArray[i]; +    assert( k == pCut->nSize - 1 ); +    pCut->nSize--; +} + +/**Function************************************************************* + +  Synopsis    [Adds one node to the cut.] + +  Description [Returns 1 if the cuts is still okay.] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Ivy_NodeCutExtend( Ivy_Cut_t * pCut, int iNew ) +{ +    int i; +    for ( i = 0; i < pCut->nSize; i++ ) +        if ( pCut->pArray[i] == iNew ) +            return 1; +    // check if there is room +    if ( pCut->nSize == pCut->nSizeMax ) +        return 0; +    // add the new one +    for ( i = pCut->nSize - 1; i >= 0; i-- ) +        if ( pCut->pArray[i] > iNew ) +            pCut->pArray[i+1] = pCut->pArray[i]; +        else +        { +            assert( pCut->pArray[i] < iNew ); +            break; +        } +    pCut->pArray[i+1] = iNew; +    pCut->nSize++; +    return 1; +} + +/**Function************************************************************* + +  Synopsis    [Check if the cut exists.] + +  Description [Returns 1 if the cut exists.] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ivy_NodeCutFindOrAdd( Ivy_Store_t * pCutStore, Ivy_Cut_t * pCutNew ) +{ +    Ivy_Cut_t * pCut; +    int i, k; +    assert( pCutNew->uHash ); +    // try to find the cut +    for ( i = 0; i < pCutStore->nCuts; i++ ) +    { +        pCut = pCutStore->pCuts + i; +        if ( pCut->uHash == pCutNew->uHash && pCut->nSize == pCutNew->nSize ) +        { +            for ( k = 0; k < pCutNew->nSize; k++ ) +                if ( pCut->pArray[k] != pCutNew->pArray[k] ) +                    break; +            if ( k == pCutNew->nSize ) +                return 1; +        } +    } +    assert( pCutStore->nCuts < pCutStore->nCutsMax ); +    // add the cut +    pCut = pCutStore->pCuts + pCutStore->nCuts++; +    *pCut = *pCutNew; +    return 0; +} + +/**Function************************************************************* + +  Synopsis    [Returns 1 if pDom is contained in pCut.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Ivy_CutCheckDominance( Ivy_Cut_t * pDom, Ivy_Cut_t * pCut ) +{ +    int i, k; +    for ( i = 0; i < pDom->nSize; i++ ) +    { +        for ( k = 0; k < pCut->nSize; k++ ) +            if ( pDom->pArray[i] == pCut->pArray[k] ) +                break; +        if ( k == pCut->nSize ) // node i in pDom is not contained in pCut +            return 0; +    } +    // every node in pDom is contained in pCut +    return 1; +} + +/**Function************************************************************* + +  Synopsis    [Check if the cut exists.] + +  Description [Returns 1 if the cut exists.] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ivy_NodeCutFindOrAddFilter( Ivy_Store_t * pCutStore, Ivy_Cut_t * pCutNew ) +{ +    Ivy_Cut_t * pCut; +    int i, k; +    assert( pCutNew->uHash ); +    // try to find the cut +    for ( i = 0; i < pCutStore->nCuts; i++ ) +    { +        pCut = pCutStore->pCuts + i; +        if ( pCut->nSize == 0 ) +            continue; +        if ( pCut->nSize == pCutNew->nSize ) +        { +            if ( pCut->uHash == pCutNew->uHash ) +            { +                for ( k = 0; k < pCutNew->nSize; k++ ) +                    if ( pCut->pArray[k] != pCutNew->pArray[k] ) +                        break; +                if ( k == pCutNew->nSize ) +                    return 1; +            } +            continue; +        } +        if ( pCut->nSize < pCutNew->nSize ) +        { +            // skip the non-contained cuts +            if ( (pCut->uHash & pCutNew->uHash) != pCut->uHash ) +                continue; +            // check containment seriously +            if ( Ivy_CutCheckDominance( pCut, pCutNew ) ) +                return 1; +            continue; +        } +        // check potential containment of other cut + +        // skip the non-contained cuts +        if ( (pCut->uHash & pCutNew->uHash) != pCutNew->uHash ) +            continue; +        // check containment seriously +        if ( Ivy_CutCheckDominance( pCutNew, pCut ) ) +        { +            // remove the current cut +//            --pCutStore->nCuts; +//            for ( k = i; k < pCutStore->nCuts; k++ ) +//                pCutStore->pCuts[k] = pCutStore->pCuts[k+1]; +//            i--; +            pCut->nSize = 0; +        } +    } +    assert( pCutStore->nCuts < pCutStore->nCutsMax ); +    // add the cut +    pCut = pCutStore->pCuts + pCutStore->nCuts++; +    *pCut = *pCutNew; +    return 0; +} + +/**Function************************************************************* + +  Synopsis    [Print the cut.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ivy_NodeCompactCuts( Ivy_Store_t * pCutStore ) +{ +    Ivy_Cut_t * pCut; +    int i, k; +    for ( i = k = 0; i < pCutStore->nCuts; i++ ) +    { +        pCut = pCutStore->pCuts + i; +        if ( pCut->nSize == 0 ) +            continue; +        pCutStore->pCuts[k++] = *pCut; +    } +    pCutStore->nCuts = k; +} + +/**Function************************************************************* + +  Synopsis    [Print the cut.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ivy_NodePrintCut( Ivy_Cut_t * pCut ) +{ +    int i; +    assert( pCut->nSize > 0 ); +    printf( "%d : {", pCut->nSize ); +    for ( i = 0; i < pCut->nSize; i++ ) +        printf( " %d", pCut->pArray[i] ); +    printf( " }\n" ); +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ivy_NodePrintCuts( Ivy_Store_t * pCutStore ) +{ +    int i; +    printf( "Node %d\n", pCutStore->pCuts[0].pArray[0] ); +    for ( i = 0; i < pCutStore->nCuts; i++ ) +        Ivy_NodePrintCut( pCutStore->pCuts + i ); +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Ivy_Store_t * Ivy_NodeFindCutsAll( Ivy_Obj_t * pObj, int nLeaves ) +{ +    static Ivy_Store_t CutStore, * pCutStore = &CutStore; +    Ivy_Cut_t CutNew, * pCutNew = &CutNew, * pCut; +    Ivy_Man_t * pMan = Ivy_ObjMan(pObj); +    Ivy_Obj_t * pLeaf; +    int i, k; + +    assert( nLeaves <= IVY_CUT_INPUT ); + +    // start the structure +    pCutStore->nCuts = 0; +    pCutStore->nCutsMax = IVY_CUT_LIMIT; +    // start the trivial cut +    pCutNew->uHash = 0; +    pCutNew->nSize = 1; +    pCutNew->nSizeMax = nLeaves; +    pCutNew->pArray[0] = pObj->Id; +    Ivy_NodeCutHash( pCutNew ); +    // add the trivial cut +    Ivy_NodeCutFindOrAdd( pCutStore, pCutNew ); +    assert( pCutStore->nCuts == 1 ); + +    // explore the cuts +    for ( i = 0; i < pCutStore->nCuts; i++ ) +    { +        // expand this cut +        pCut = pCutStore->pCuts + i; +        if ( pCut->nSize == 0 ) +            continue; +        for ( k = 0; k < pCut->nSize; k++ ) +        { +            pLeaf = Ivy_ObjObj( pObj, pCut->pArray[k] ); +            if ( Ivy_ObjIsCi(pLeaf) ) +                continue; +            *pCutNew = *pCut; +            Ivy_NodeCutShrink( pCutNew, pLeaf->Id ); +            if ( !Ivy_NodeCutExtend( pCutNew, Ivy_ObjFaninId0(pLeaf) ) ) +                continue; +            if ( Ivy_ObjIsNode(pLeaf) && !Ivy_NodeCutExtend( pCutNew, Ivy_ObjFaninId1(pLeaf) ) ) +                continue; +            Ivy_NodeCutHash( pCutNew ); +            Ivy_NodeCutFindOrAddFilter( pCutStore, pCutNew ); +            if ( pCutStore->nCuts == IVY_CUT_LIMIT ) +                break; +        } +        if ( pCutStore->nCuts == IVY_CUT_LIMIT ) +            break; +    } +    Ivy_NodeCompactCuts( pCutStore ); +//    Ivy_NodePrintCuts( pCutStore ); +    return pCutStore; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ivy_ManTestCutsAll( Ivy_Man_t * p ) +{ +    Ivy_Obj_t * pObj; +    int i, nCutsCut, nCutsTotal, nNodeTotal, nNodeOver; +    int clk = clock(); +    nNodeTotal = nNodeOver = 0; +    nCutsTotal = -Ivy_ManNodeNum(p); +    Ivy_ManForEachObj( p, pObj, i ) +    { +        if ( !Ivy_ObjIsNode(pObj) ) +            continue; +        nCutsCut    = Ivy_NodeFindCutsAll( pObj, 4 )->nCuts; +        nCutsTotal += nCutsCut; +        nNodeOver  += (nCutsCut == IVY_CUT_LIMIT); +        nNodeTotal++; +    } +    printf( "Total cuts = %6d. Trivial = %6d.   Nodes = %6d. Satur = %6d.  ",  +        nCutsTotal, Ivy_ManPiNum(p) + Ivy_ManNodeNum(p), nNodeTotal, nNodeOver ); +    PRT( "Time", clock() - clk ); +} +  ////////////////////////////////////////////////////////////////////////  ///                       END OF FILE                                ///  //////////////////////////////////////////////////////////////////////// diff --git a/src/temp/ivy/ivyDfs.c b/src/temp/ivy/ivyDfs.c index 2db80b00..2dc3bac8 100644 --- a/src/temp/ivy/ivyDfs.c +++ b/src/temp/ivy/ivyDfs.c @@ -69,6 +69,9 @@ Vec_Int_t * Ivy_ManDfs( Ivy_Man_t * p )      Vec_Int_t * vNodes;      Ivy_Obj_t * pObj;      int i; +    // make sure the nodes are not marked +    Ivy_ManForEachObj( p, pObj, i ) +        assert( !pObj->fMarkA && !pObj->fMarkB );      // collect the nodes      vNodes = Vec_IntAlloc( Ivy_ManNodeNum(p) );      if ( Ivy_ManLatchNum(p) > 0 ) @@ -107,7 +110,7 @@ void Ivy_ManDfsExt_rec( Ivy_Obj_t * pObj, Vec_Int_t * vNodes )      // traverse the fanins      vFanins = Ivy_ObjGetFanins( pObj );      Vec_IntForEachEntry( vFanins, Fanin, i ) -        Ivy_ManDfsExt_rec( Ivy_ObjObj(pObj, Ivy_FanId(Fanin)), vNodes ); +        Ivy_ManDfsExt_rec( Ivy_ObjObj(pObj, Ivy_EdgeId(Fanin)), vNodes );      // add the node      Vec_IntPush( vNodes, pObj->Id );  }  @@ -134,7 +137,7 @@ Vec_Int_t * Ivy_ManDfsExt( Ivy_Man_t * p )      vNodes = Vec_IntAlloc( 10 );      Ivy_ManForEachPo( p, pObj, i )      { -        pFanin = Ivy_ManObj( p, Ivy_FanId( Ivy_ObjReadFanin(pObj,0) ) ); +        pFanin = Ivy_ManObj( p, Ivy_EdgeId( Ivy_ObjReadFanin(pObj,0) ) );          Ivy_ManDfsExt_rec( pFanin, vNodes );      }      Ivy_ManForEachNodeVec( p, vNodes, pObj, i ) @@ -145,6 +148,132 @@ Vec_Int_t * Ivy_ManDfsExt( Ivy_Man_t * p )      return vNodes;  } +/**Function************************************************************* + +  Synopsis    [Collects nodes in the cone.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ivy_ManCollectCone_rec( Ivy_Obj_t * pObj, Vec_Ptr_t * vCone ) +{ +    if ( pObj->fMarkA ) +        return; +    if ( Ivy_ObjIsBuf(pObj) ) +    { +        Ivy_ManCollectCone_rec( Ivy_ObjFanin0(pObj), vCone ); +        Vec_PtrPush( vCone, pObj ); +        return; +    } +    assert( Ivy_ObjIsNode(pObj) ); +    Ivy_ManCollectCone_rec( Ivy_ObjFanin0(pObj), vCone ); +    Ivy_ManCollectCone_rec( Ivy_ObjFanin1(pObj), vCone ); +    Vec_PtrPushUnique( vCone, pObj ); +} + +/**Function************************************************************* + +  Synopsis    [Collects nodes in the cone.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ivy_ManCollectCone( Ivy_Obj_t * pObj, Vec_Ptr_t * vFront, Vec_Ptr_t * vCone ) +{ +    Ivy_Obj_t * pTemp; +    int i; +    assert( !Ivy_IsComplement(pObj) ); +    assert( Ivy_ObjIsNode(pObj) ); +    // mark the nodes +    Vec_PtrForEachEntry( vFront, pTemp, i ) +        Ivy_Regular(pTemp)->fMarkA = 1; +    assert( pObj->fMarkA == 0 ); +    // collect the cone +    Vec_PtrClear( vCone ); +    Ivy_ManCollectCone_rec( pObj, vCone ); +    // unmark the nodes +    Vec_PtrForEachEntry( vFront, pTemp, i ) +        Ivy_Regular(pTemp)->fMarkA = 0; +} + +/**Function************************************************************* + +  Synopsis    [Returns the nodes by level.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Vec_Vec_t * Ivy_ManLevelize( Ivy_Man_t * p ) +{ +    Vec_Vec_t * vNodes; +    Ivy_Obj_t * pObj; +    int i; +    vNodes = Vec_VecAlloc( 100 ); +    Ivy_ManForEachObj( p, pObj, i ) +    { +        assert( !Ivy_ObjIsBuf(pObj) ); +        if ( Ivy_ObjIsNode(pObj) ) +            Vec_VecPush( vNodes, pObj->Level, pObj ); +    } +    return vNodes; +} + +/**Function************************************************************* + +  Synopsis    [Computes required levels for each node.] + +  Description [Assumes topological ordering of the nodes.] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Vec_Int_t * Ivy_ManRequiredLevels( Ivy_Man_t * p ) +{ +    Ivy_Obj_t * pObj; +    Vec_Int_t * vLevelsR; +    Vec_Vec_t * vNodes; +    int i, k, Level, LevelMax; +    assert( p->vRequired == NULL ); +    // start the required times +    vLevelsR = Vec_IntStart( Ivy_ManObjIdNext(p) ); +    // iterate through the nodes in the reverse order +    vNodes = Ivy_ManLevelize( p ); +    Vec_VecForEachEntryReverseReverse( vNodes, pObj, i, k ) +    { +        Level = Vec_IntEntry( vLevelsR, pObj->Id ) + 1 + Ivy_ObjIsExor(pObj); +        if ( Vec_IntEntry( vLevelsR, Ivy_ObjFaninId0(pObj) ) < Level ) +            Vec_IntWriteEntry( vLevelsR, Ivy_ObjFaninId0(pObj), Level ); +        if ( Vec_IntEntry( vLevelsR, Ivy_ObjFaninId1(pObj) ) < Level ) +            Vec_IntWriteEntry( vLevelsR, Ivy_ObjFaninId1(pObj), Level ); +    } +    Vec_VecFree( vNodes ); +    // convert it into the required times +    LevelMax = Ivy_ManReadLevels( p ); +//printf( "max %5d\n",LevelMax ); +    Ivy_ManForEachObj( p, pObj, i ) +    { +        Level = Vec_IntEntry( vLevelsR, pObj->Id ); +        Vec_IntWriteEntry( vLevelsR, pObj->Id, LevelMax - Level ); +//printf( "%5d : %5d %5d\n", pObj->Id, Level, LevelMax - Level ); +    } +    p->vRequired = vLevelsR; +    return vLevelsR; +} +  ////////////////////////////////////////////////////////////////////////  ///                       END OF FILE                                ///  //////////////////////////////////////////////////////////////////////// diff --git a/src/temp/ivy/ivyMan.c b/src/temp/ivy/ivyMan.c index 04c31f3d..2ff90aa9 100644 --- a/src/temp/ivy/ivyMan.c +++ b/src/temp/ivy/ivyMan.c @@ -48,6 +48,7 @@ Ivy_Man_t * Ivy_ManStart( int nPis, int nPos, int nNodesMax )      p = ALLOC( Ivy_Man_t, 1 );      memset( p, 0, sizeof(Ivy_Man_t) );      p->nTravIds = 1; +    p->fCatchExor = 1;      // AIG nodes      p->nObjsAlloc = 1 + nPis + nPos + nNodesMax;  //    p->nObjsAlloc += (p->nObjsAlloc & 1); // make it even @@ -191,12 +192,13 @@ void Ivy_ManPrintStats( Ivy_Man_t * p )      {      printf( "A = %d. ",     Ivy_ManAndNum(p) );      printf( "X = %d. ",     Ivy_ManExorNum(p) ); -    printf( "B = %d. ",     Ivy_ManBufNum(p) ); +    printf( "B = %4d. ",     Ivy_ManBufNum(p) );      } -    printf( "MaxID = %d. ", p->ObjIdNext-1 ); -    printf( "All = %d. ",   p->nObjsAlloc ); +//    printf( "MaxID = %d. ", p->ObjIdNext-1 ); +//    printf( "All = %d. ",   p->nObjsAlloc );      printf( "Cre = %d. ",   p->nCreated );      printf( "Del = %d. ",   p->nDeleted ); +    printf( "Lev = %d. ",   Ivy_ManReadLevels(p) );      printf( "\n" );  } diff --git a/src/temp/ivy/ivyMulti.c b/src/temp/ivy/ivyMulti.c index 059d1500..e2a44e2d 100644 --- a/src/temp/ivy/ivyMulti.c +++ b/src/temp/ivy/ivyMulti.c @@ -24,22 +24,18 @@  ///                        DECLARATIONS                              ///  //////////////////////////////////////////////////////////////////////// -typedef struct Ivy_Eval_t_ Ivy_Eval_t; -struct Ivy_Eval_t_ +#define IVY_EVAL_LIMIT    128 + +typedef struct Ivy_Eva_t_ Ivy_Eva_t; +struct Ivy_Eva_t_  { -    unsigned Mask   :  5;  // the mask of covered nodes -    unsigned Weight :  3;  // the number of covered nodes -    unsigned Cost   :  4;  // the number of overlapping nodes -    unsigned Level  : 12;  // the level of this node -    unsigned Fan0   :  4;  // the first fanin -    unsigned Fan1   :  4;  // the second fanin +    Ivy_Obj_t * pArg;     // the argument node +    unsigned    Mask;     // the mask of covered nodes +    int         Weight;   // the number of covered nodes  }; -static Ivy_Obj_t * Ivy_MultiBuild_rec( Ivy_Eval_t * pEvals, int iNum, Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type ); -static void        Ivy_MultiSort( Ivy_Obj_t ** pArgs, int nArgs ); -static int         Ivy_MultiPushUniqueOrderByLevel( Ivy_Obj_t ** pArray, int nArgs, Ivy_Obj_t * pNode ); -static Ivy_Obj_t * Ivy_MultiEval( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type ); - +static void Ivy_MultiPrint( Ivy_Eva_t * pEvals, int nLeaves, int nEvals ); +static int Ivy_MultiCover( Ivy_Eva_t * pEvals, int nLeaves, int nEvals, int nLimit, Vec_Ptr_t * vSols );  ////////////////////////////////////////////////////////////////////////  ///                     FUNCTION DEFINITIONS                         /// @@ -47,212 +43,121 @@ static Ivy_Obj_t * Ivy_MultiEval( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type  /**Function************************************************************* -  Synopsis    [Constructs the well-balanced tree of gates.] - -  Description [Disregards levels and possible logic sharing.] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -Ivy_Obj_t * Ivy_Multi_rec( Ivy_Obj_t ** ppObjs, int nObjs, Ivy_Type_t Type ) -{ -    Ivy_Obj_t * pObj1, * pObj2; -    if ( nObjs == 1 ) -        return ppObjs[0]; -    pObj1 = Ivy_Multi_rec( ppObjs,           nObjs/2,         Type ); -    pObj2 = Ivy_Multi_rec( ppObjs + nObjs/2, nObjs - nObjs/2, Type ); -    return Ivy_Oper( pObj1, pObj2, Type ); -} - -/**Function************************************************************* -    Synopsis    [Constructs a balanced tree while taking sharing into account.] -  Description [] +  Description [Returns 1 if the implementation exists.]    SideEffects []    SeeAlso     []  ***********************************************************************/ -Ivy_Obj_t * Ivy_Multi( Ivy_Obj_t ** pArgsInit, int nArgs, Ivy_Type_t Type ) +int Ivy_MultiPlus( Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone, Ivy_Type_t Type, int nLimit, Vec_Ptr_t * vSols )  { -    static char NumBits[32] = {0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5}; -    static Ivy_Eval_t pEvals[15+15*14/2]; -    static Ivy_Obj_t * pArgs[16]; -    Ivy_Eval_t * pEva, * pEvaBest; -    int nArgsNew, nEvals, i, k; -    Ivy_Obj_t * pTemp; - -    // consider the case of one argument -    assert( nArgs > 0 ); -    if ( nArgs == 1 ) -        return pArgsInit[0]; -    // consider the case of two arguments -    if ( nArgs == 2 ) -        return Ivy_Oper( pArgsInit[0], pArgsInit[1], Type ); - -//Ivy_MultiEval( pArgsInit, nArgs, Type ); printf( "\n" ); - -    // set the initial ones -    for ( i = 0; i < nArgs; i++ ) +    static Ivy_Eva_t pEvals[IVY_EVAL_LIMIT]; +    Ivy_Eva_t * pEval, * pFan0, * pFan1; +    Ivy_Obj_t * pObj, * pTemp; +    int nEvals, nEvalsOld, i, k, x, nLeaves; +    unsigned uMaskAll; + +    // consider special cases +    nLeaves = Vec_PtrSize(vLeaves); +    assert( nLeaves > 2 ); +    if ( nLeaves > 32 || nLeaves + Vec_PtrSize(vCone) > IVY_EVAL_LIMIT ) +        return 0; +//    if ( nLeaves == 1 ) +//        return Vec_PtrEntry( vLeaves, 0 ); +//    if ( nLeaves == 2 ) +//        return Ivy_Oper( Vec_PtrEntry(vLeaves, 0), Vec_PtrEntry(vLeaves, 1), Type ); + +    // set the leaf entries +    uMaskAll = ((1 << nLeaves) - 1); +    nEvals = 0; +    Vec_PtrForEachEntry( vLeaves, pObj, i )      { -        pArgs[i] = pArgsInit[i]; -        pEva = pEvals + i; -        pEva->Mask   = (1 << i); -        pEva->Weight = 1; -        pEva->Cost   = 0;  -        pEva->Level  = Ivy_Regular(pArgs[i])->Level;  -        pEva->Fan0   = 0;  -        pEva->Fan1   = 0;  +        pEval = pEvals + nEvals; +        pEval->pArg   = pObj; +        pEval->Mask   = (1 << nEvals); +        pEval->Weight = 1; +        // mark the leaf +        Ivy_Regular(pObj)->TravId = nEvals; +        nEvals++;      } -    // find the available nodes -    pEvaBest = pEvals; -    nArgsNew = nArgs; -    for ( i = 1; i < nArgsNew; i++ ) -    for ( k = 0; k < i; k++ ) -        if ( pTemp = Ivy_TableLookup(Ivy_ObjCreateGhost(pArgs[k], pArgs[i], Type, IVY_INIT_NONE)) ) -        { -            pEva = pEvals + nArgsNew; -            pEva->Mask   = pEvals[k].Mask | pEvals[i].Mask; -            pEva->Weight = NumBits[pEva->Mask]; -            pEva->Cost   = pEvals[k].Cost + pEvals[i].Cost + NumBits[pEvals[k].Mask & pEvals[i].Mask];  -            pEva->Level  = 1 + IVY_MAX(pEvals[k].Level, pEvals[i].Level);  -            pEva->Fan0   = k;  -            pEva->Fan1   = i;  -//            assert( pEva->Level == (unsigned)Ivy_ObjLevel(pTemp) ); -            // compare -            if ( pEvaBest->Weight < pEva->Weight || -                 pEvaBest->Weight == pEva->Weight && pEvaBest->Cost > pEva->Cost || -                 pEvaBest->Weight == pEva->Weight && pEvaBest->Cost == pEva->Cost && pEvaBest->Level > pEva->Level ) -                 pEvaBest = pEva; -            // save the argument -            pArgs[nArgsNew++] = pTemp; -            if ( nArgsNew == 15 ) -                goto Outside; -        } -Outside: - -//    printf( "Best = %d.\n", pEvaBest - pEvals ); - -    // the case of no common nodes -    if ( nArgsNew == nArgs ) +    // propagate masks through the cone +    Vec_PtrForEachEntry( vCone, pObj, i )      { -        Ivy_MultiSort( pArgs, nArgs ); -        return Ivy_MultiBalance_rec( pArgs, nArgs, Type ); +        pObj->TravId = nEvals + i; +        if ( Ivy_ObjIsBuf(pObj) ) +            pEvals[pObj->TravId].Mask = pEvals[Ivy_ObjFanin0(pObj)->TravId].Mask; +        else +            pEvals[pObj->TravId].Mask = pEvals[Ivy_ObjFanin0(pObj)->TravId].Mask | pEvals[Ivy_ObjFanin1(pObj)->TravId].Mask;      } -    // the case of one common node -    if ( nArgsNew == nArgs + 1 ) + +    // set the internal entries +    Vec_PtrForEachEntry( vCone, pObj, i )      { -        assert( pEvaBest - pEvals == nArgs ); -        k = 0; -        for ( i = 0; i < nArgs; i++ ) -            if ( i != (int)pEvaBest->Fan0 && i != (int)pEvaBest->Fan1 ) -                pArgs[k++] = pArgs[i]; -        pArgs[k++] = pArgs[nArgs]; -        assert( k == nArgs - 1 ); -        nArgs = k; -        Ivy_MultiSort( pArgs, nArgs ); -        return Ivy_MultiBalance_rec( pArgs, nArgs, Type ); +        if ( i == Vec_PtrSize(vCone) - 1 ) +            break; +        // skip buffers +        if ( Ivy_ObjIsBuf(pObj) ) +            continue; +        // skip nodes without external fanout +        if ( Ivy_ObjRefs(pObj) == 0 ) +            continue; +        assert( !Ivy_IsComplement(pObj) ); +        pEval = pEvals + nEvals; +        pEval->pArg   = pObj; +        pEval->Mask   = pEvals[pObj->TravId].Mask; +        pEval->Weight = Extra_WordCountOnes(pEval->Mask); +        // mark the node +        pObj->TravId = nEvals; +        nEvals++;      } -    // the case when there is a node that covers everything -    if ( (int)pEvaBest->Mask == ((1 << nArgs) - 1) ) -        return Ivy_MultiBuild_rec( pEvals, pEvaBest - pEvals, pArgs, nArgsNew, Type );  -    // evaluate node pairs -    nEvals = nArgsNew; -    for ( i = 1; i < nArgsNew; i++ ) +    // find the available nodes +    nEvalsOld = nEvals; +    for ( i = 1; i < nEvals; i++ )      for ( k = 0; k < i; k++ )      { -        pEva = pEvals + nEvals; -        pEva->Mask   = pEvals[k].Mask | pEvals[i].Mask; -        pEva->Weight = NumBits[pEva->Mask]; -        pEva->Cost   = pEvals[k].Cost + pEvals[i].Cost + NumBits[pEvals[k].Mask & pEvals[i].Mask];  -        pEva->Level  = 1 + IVY_MAX(pEvals[k].Level, pEvals[i].Level);  -        pEva->Fan0   = k;  -        pEva->Fan1   = i;  -        // compare -        if ( pEvaBest->Weight < pEva->Weight || -             pEvaBest->Weight == pEva->Weight && pEvaBest->Cost > pEva->Cost || -             pEvaBest->Weight == pEva->Weight && pEvaBest->Cost == pEva->Cost && pEvaBest->Level > pEva->Level ) -             pEvaBest = pEva; +        pFan0 = pEvals + i; +        pFan1 = pEvals + k; +        pTemp = Ivy_TableLookup(Ivy_ObjCreateGhost(pFan0->pArg, pFan1->pArg, Type, IVY_INIT_NONE)); +        // skip nodes in the cone +        if ( pTemp == NULL || pTemp->fMarkB ) +            continue; +        // skip the leaves +        for ( x = 0; x < nLeaves; x++ ) +            if ( pTemp == Ivy_Regular(vLeaves->pArray[x]) ) +                break; +        if ( x < nLeaves ) +            continue; +        pEval = pEvals + nEvals; +        pEval->pArg   = pTemp; +        pEval->Mask   = pFan0->Mask | pFan1->Mask; +        pEval->Weight = (pFan0->Mask & pFan1->Mask) ? Extra_WordCountOnes(pEval->Mask) : pFan0->Weight + pFan1->Weight;          // save the argument +        pObj->TravId = nEvals;          nEvals++; +        // quit if the number of entries exceeded the limit +        if ( nEvals == IVY_EVAL_LIMIT ) +            goto Outside; +        // quit if we found an acceptable implementation +        if ( pEval->Mask == uMaskAll ) +            goto Outside;      } -    assert( pEvaBest - pEvals >= nArgsNew ); - -//    printf( "Used (%d, %d).\n", pEvaBest->Fan0, pEvaBest->Fan1 ); - -    // get the best implementation -    pTemp = Ivy_MultiBuild_rec( pEvals, pEvaBest - pEvals, pArgs, nArgsNew, Type ); - -    // collect those not covered by EvaBest -    k = 0; -    for ( i = 0; i < nArgs; i++ ) -        if ( (pEvaBest->Mask & (1 << i)) == 0 ) -            pArgs[k++] = pArgs[i]; -    pArgs[k++] = pTemp; -    assert( k == nArgs - (int)pEvaBest->Weight + 1 ); -    nArgs = k; -    Ivy_MultiSort( pArgs, nArgs ); -    return Ivy_MultiBalance_rec( pArgs, nArgs, Type ); -} - -/**Function************************************************************* - -  Synopsis    [Implements multi-input AND/EXOR operation.] - -  Description [] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -Ivy_Obj_t * Ivy_MultiBuild_rec( Ivy_Eval_t * pEvals, int iNum, Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type ) -{ -    Ivy_Obj_t * pNode0, * pNode1; -    if ( iNum < nArgs ) -        return pArgs[iNum]; -    pNode0 = Ivy_MultiBuild_rec( pEvals, pEvals[iNum].Fan0, pArgs, nArgs, Type ); -    pNode1 = Ivy_MultiBuild_rec( pEvals, pEvals[iNum].Fan1, pArgs, nArgs, Type ); -    return Ivy_Oper( pNode0, pNode1, Type ); -} - -/**Function************************************************************* - -  Synopsis    [Selection-sorts the nodes in the decreasing over of level.] - -  Description [] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -void Ivy_MultiSort( Ivy_Obj_t ** pArgs, int nArgs ) -{ -    Ivy_Obj_t * pTemp; -    int i, j, iBest; +Outside: -    for ( i = 0; i < nArgs-1; i++ ) -    { -        iBest = i; -        for ( j = i+1; j < nArgs; j++ ) -            if ( Ivy_Regular(pArgs[j])->Level > Ivy_Regular(pArgs[iBest])->Level ) -                iBest = j; -        pTemp = pArgs[i];  -        pArgs[i] = pArgs[iBest];  -        pArgs[iBest] = pTemp; -    } +//    Ivy_MultiPrint( pEvals, nLeaves, nEvals ); +    if ( !Ivy_MultiCover( pEvals, nLeaves, nEvals, nLimit, vSols ) ) +        return 0; +    assert( Vec_PtrSize( vSols ) > 0 ); +    return 1;  }  /**Function************************************************************* -  Synopsis    [Inserts a new node in the order by levels.] +  Synopsis    [Computes how many uncovered ones this one covers.]    Description [] @@ -261,32 +166,28 @@ void Ivy_MultiSort( Ivy_Obj_t ** pArgs, int nArgs )    SeeAlso     []  ***********************************************************************/ -int Ivy_MultiPushUniqueOrderByLevel( Ivy_Obj_t ** pArray, int nArgs, Ivy_Obj_t * pNode ) +void Ivy_MultiPrint( Ivy_Eva_t * pEvals, int nLeaves, int nEvals )  { -    Ivy_Obj_t * pNode1, * pNode2; -    int i; -    // try to find the node in the array -    for ( i = 0; i < nArgs; i++ ) -        if ( pArray[i] == pNode ) -            return nArgs; -    // put the node last -    pArray[nArgs++] = pNode; -    // find the place to put the new node -    for ( i = nArgs-1; i > 0; i-- ) +    Ivy_Eva_t * pEval; +    int i, k; +    for ( i = nLeaves; i < nEvals; i++ )      { -        pNode1 = pArray[i  ]; -        pNode2 = pArray[i-1]; -        if ( Ivy_Regular(pNode1)->Level <= Ivy_Regular(pNode2)->Level ) -            break; -        pArray[i  ] = pNode2; -        pArray[i-1] = pNode1; +        pEval = pEvals + i; +        printf( "%2d  (id = %5d)  : |", i-nLeaves, Ivy_ObjId(pEval->pArg) ); +        for ( k = 0; k < nLeaves; k++ ) +        { +            if ( pEval->Mask & (1 << k) ) +                printf( "+" ); +            else +                printf( " " ); +        } +        printf( "|  Lev = %d.\n", Ivy_ObjLevel(pEval->pArg) );      } -    return nArgs;  }  /**Function************************************************************* -  Synopsis    [Balances the array recursively.] +  Synopsis    [Computes how many uncovered ones this one covers.]    Description [] @@ -295,129 +196,102 @@ int Ivy_MultiPushUniqueOrderByLevel( Ivy_Obj_t ** pArray, int nArgs, Ivy_Obj_t *    SeeAlso     []  ***********************************************************************/ -Ivy_Obj_t * Ivy_MultiBalance_rec( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type ) +static inline int Ivy_MultiWeight( unsigned uMask, int nMaskOnes, unsigned uFound )  { -    Ivy_Obj_t * pNodeNew; -    // consider the case of one argument -    assert( nArgs > 0 ); -    if ( nArgs == 1 ) -        return pArgs[0]; -    // consider the case of two arguments -    if ( nArgs == 2 ) -        return Ivy_Oper( pArgs[0], pArgs[1], Type ); -    // get the last two nodes -    pNodeNew = Ivy_Oper( pArgs[nArgs-1], pArgs[nArgs-2], Type ); -    // add the new node -    nArgs = Ivy_MultiPushUniqueOrderByLevel( pArgs, nArgs - 2, pNodeNew ); -    return Ivy_MultiBalance_rec( pArgs, nArgs, Type ); +    assert( uMask & ~uFound ); +    if ( (uMask & uFound) == 0 ) +        return nMaskOnes; +    return Extra_WordCountOnes( uMask & ~uFound );  }  /**Function************************************************************* -  Synopsis    [Implements multi-input AND/EXOR operation.] +  Synopsis    [Finds the cover.] -  Description [] +  Description [Returns 1 if the cover is found.]    SideEffects []    SeeAlso     []  ***********************************************************************/ -Ivy_Obj_t * Ivy_MultiEval( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type ) +int Ivy_MultiCover( Ivy_Eva_t * pEvals, int nLeaves, int nEvals, int nLimit, Vec_Ptr_t * vSols )  { -    Ivy_Obj_t * pTemp; -    int i, k; -    int nArgsOld = nArgs; -    for ( i = 0; i < nArgs; i++ ) -        printf( "%d[%d] ", i, Ivy_Regular(pArgs[i])->Level ); -    for ( i = 1; i < nArgs; i++ ) -        for ( k = 0; k < i; k++ ) +    int fVerbose = 0; +    Ivy_Eva_t * pEval, * pEvalBest; +    unsigned uMaskAll, uFound, uTemp; +    int i, k, BestK, WeightBest, WeightCur, LevelBest, LevelCur; +    uMaskAll = (nLeaves == 32)? (~(unsigned)0) : ((1 << nLeaves) - 1); +    uFound = 0; +    // solve the covering problem +    if ( fVerbose ) +    printf( "Solution:  " ); +    Vec_PtrClear( vSols ); +    for ( i = 0; i < nLimit; i++ ) +    { +        BestK = -1; +        for ( k = nEvals - 1; k >= 0; k-- )          { -            pTemp = Ivy_TableLookup(Ivy_ObjCreateGhost(pArgs[k], pArgs[i], Type, IVY_INIT_NONE)); -            if ( pTemp != NULL ) +            pEval = pEvals + k; +            if ( (pEval->Mask & ~uFound) == 0 ) +                continue; +            if ( BestK == -1 )              { -                printf( "%d[%d]=(%d,%d) ", nArgs, Ivy_Regular(pTemp)->Level, k, i ); -                pArgs[nArgs++] = pTemp; +                BestK      = k; +                pEvalBest  = pEval; +                WeightBest = Ivy_MultiWeight( pEvalBest->Mask, pEvalBest->Weight, uFound ); +                LevelBest  = Ivy_ObjLevel( Ivy_Regular(pEvalBest->pArg) ); +                continue; +            } +            // compare BestK and the new one (k) +            WeightCur = Ivy_MultiWeight( pEval->Mask, pEval->Weight, uFound ); +            LevelCur = Ivy_ObjLevel( Ivy_Regular(pEval->pArg) ); +            if ( WeightBest < WeightCur ||  +                (WeightBest == WeightCur && LevelBest > LevelCur) ) +            { +                BestK      = k; +                pEvalBest  = pEval; +                WeightBest = WeightCur; +                LevelBest  = LevelCur;              }          } -    printf( "     ((%d/%d))    ", nArgsOld, nArgs-nArgsOld ); -    return NULL; -} - - - -/**Function************************************************************* - -  Synopsis    [Old code.] - -  Description [] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -Ivy_Obj_t * Ivy_Multi1( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type ) -{ -    Ivy_Obj_t * pArgsRef[5], * pTemp; -    int i, k, m, nArgsNew, Counter = 0; -  -     -//Ivy_MultiEval( pArgs, nArgs, Type );  printf( "\n" ); - - -    assert( Type == IVY_AND || Type == IVY_EXOR ); -    assert( nArgs > 0 ); -    if ( nArgs == 1 ) -        return pArgs[0]; - -    // find the nodes with more than one fanout -    nArgsNew = 0; -    for ( i = 0; i < nArgs; i++ ) -        if ( Ivy_ObjRefs( Ivy_Regular(pArgs[i]) ) > 0 ) -            pArgsRef[nArgsNew++] = pArgs[i]; - -    // go through pairs -    if ( nArgsNew >= 2 ) -    for ( i = 0; i < nArgsNew; i++ ) -    for ( k = i + 1; k < nArgsNew; k++ ) -        if ( pTemp = Ivy_TableLookup(Ivy_ObjCreateGhost(pArgsRef[i], pArgsRef[k], Type, IVY_INIT_NONE)) ) -            Counter++; -//    printf( "%d", Counter ); -             -    // go through pairs -    if ( nArgsNew >= 2 ) -    for ( i = 0; i < nArgsNew; i++ ) -    for ( k = i + 1; k < nArgsNew; k++ ) -        if ( pTemp = Ivy_TableLookup(Ivy_ObjCreateGhost(pArgsRef[i], pArgsRef[k], Type, IVY_INIT_NONE)) ) +        assert( BestK != -1 ); +        // if the cost is only 1, take the leaf +        if ( WeightBest == 1 && BestK >= nLeaves )          { -            nArgsNew = 0; -            for ( m = 0; m < nArgs; m++ ) -                if ( pArgs[m] != pArgsRef[i] && pArgs[m] != pArgsRef[k] ) -                    pArgs[nArgsNew++] = pArgs[m]; -            pArgs[nArgsNew++] = pTemp; -            assert( nArgsNew == nArgs - 1 ); -            return Ivy_Multi1( pArgs, nArgsNew, Type ); +            uTemp = (pEvalBest->Mask & ~uFound); +            for ( k = 0; k < nLeaves; k++ ) +                if ( uTemp & (1 << k) ) +                    break; +            assert( k < nLeaves ); +            BestK     = k; +            pEvalBest = pEvals + BestK;          } -    return Ivy_Multi_rec( pArgs, nArgs, Type ); -} - -/**Function************************************************************* - -  Synopsis    [Old code.] - -  Description [] -                -  SideEffects [] - -  SeeAlso     [] - -***********************************************************************/ -Ivy_Obj_t * Ivy_Multi2( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type ) -{ -    assert( Type == IVY_AND || Type == IVY_EXOR ); -    assert( nArgs > 0 ); -    return Ivy_Multi_rec( pArgs, nArgs, Type ); +        if ( fVerbose ) +        { +            if ( BestK < nLeaves ) +                printf( "L(%d) ", BestK ); +            else +                printf( "%d ", BestK - nLeaves ); +        } +        // update the found set +        Vec_PtrPush( vSols, pEvalBest->pArg ); +        uFound |= pEvalBest->Mask; +        if ( uFound == uMaskAll ) +            break; +    } +    if ( uFound == uMaskAll ) +    { +        if ( fVerbose ) +            printf( "  Found \n\n" ); +        return 1; +    } +    else +    { +        if ( fVerbose ) +            printf( "  Not found \n\n" ); +        return 0; +    }  }  //////////////////////////////////////////////////////////////////////// diff --git a/src/temp/ivy/ivyMulti8.c b/src/temp/ivy/ivyMulti8.c new file mode 100644 index 00000000..059d1500 --- /dev/null +++ b/src/temp/ivy/ivyMulti8.c @@ -0,0 +1,427 @@ +/**CFile**************************************************************** + +  FileName    [ivyMulti.c] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [And-Inverter Graph package.] + +  Synopsis    [Constructing multi-input AND/EXOR gates.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - May 11, 2006.] + +  Revision    [$Id: ivyMulti.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "ivy.h" + +//////////////////////////////////////////////////////////////////////// +///                        DECLARATIONS                              /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Ivy_Eval_t_ Ivy_Eval_t; +struct Ivy_Eval_t_ +{ +    unsigned Mask   :  5;  // the mask of covered nodes +    unsigned Weight :  3;  // the number of covered nodes +    unsigned Cost   :  4;  // the number of overlapping nodes +    unsigned Level  : 12;  // the level of this node +    unsigned Fan0   :  4;  // the first fanin +    unsigned Fan1   :  4;  // the second fanin +}; + +static Ivy_Obj_t * Ivy_MultiBuild_rec( Ivy_Eval_t * pEvals, int iNum, Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type ); +static void        Ivy_MultiSort( Ivy_Obj_t ** pArgs, int nArgs ); +static int         Ivy_MultiPushUniqueOrderByLevel( Ivy_Obj_t ** pArray, int nArgs, Ivy_Obj_t * pNode ); +static Ivy_Obj_t * Ivy_MultiEval( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type ); + + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [Constructs the well-balanced tree of gates.] + +  Description [Disregards levels and possible logic sharing.] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Ivy_Obj_t * Ivy_Multi_rec( Ivy_Obj_t ** ppObjs, int nObjs, Ivy_Type_t Type ) +{ +    Ivy_Obj_t * pObj1, * pObj2; +    if ( nObjs == 1 ) +        return ppObjs[0]; +    pObj1 = Ivy_Multi_rec( ppObjs,           nObjs/2,         Type ); +    pObj2 = Ivy_Multi_rec( ppObjs + nObjs/2, nObjs - nObjs/2, Type ); +    return Ivy_Oper( pObj1, pObj2, Type ); +} + +/**Function************************************************************* + +  Synopsis    [Constructs a balanced tree while taking sharing into account.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Ivy_Obj_t * Ivy_Multi( Ivy_Obj_t ** pArgsInit, int nArgs, Ivy_Type_t Type ) +{ +    static char NumBits[32] = {0,1,1,2,1,2,2,3,1,2,2,3,2,3,3,4,1,2,2,3,2,3,3,4,2,3,3,4,3,4,4,5}; +    static Ivy_Eval_t pEvals[15+15*14/2]; +    static Ivy_Obj_t * pArgs[16]; +    Ivy_Eval_t * pEva, * pEvaBest; +    int nArgsNew, nEvals, i, k; +    Ivy_Obj_t * pTemp; + +    // consider the case of one argument +    assert( nArgs > 0 ); +    if ( nArgs == 1 ) +        return pArgsInit[0]; +    // consider the case of two arguments +    if ( nArgs == 2 ) +        return Ivy_Oper( pArgsInit[0], pArgsInit[1], Type ); + +//Ivy_MultiEval( pArgsInit, nArgs, Type ); printf( "\n" ); + +    // set the initial ones +    for ( i = 0; i < nArgs; i++ ) +    { +        pArgs[i] = pArgsInit[i]; +        pEva = pEvals + i; +        pEva->Mask   = (1 << i); +        pEva->Weight = 1; +        pEva->Cost   = 0;  +        pEva->Level  = Ivy_Regular(pArgs[i])->Level;  +        pEva->Fan0   = 0;  +        pEva->Fan1   = 0;  +    } + +    // find the available nodes +    pEvaBest = pEvals; +    nArgsNew = nArgs; +    for ( i = 1; i < nArgsNew; i++ ) +    for ( k = 0; k < i; k++ ) +        if ( pTemp = Ivy_TableLookup(Ivy_ObjCreateGhost(pArgs[k], pArgs[i], Type, IVY_INIT_NONE)) ) +        { +            pEva = pEvals + nArgsNew; +            pEva->Mask   = pEvals[k].Mask | pEvals[i].Mask; +            pEva->Weight = NumBits[pEva->Mask]; +            pEva->Cost   = pEvals[k].Cost + pEvals[i].Cost + NumBits[pEvals[k].Mask & pEvals[i].Mask];  +            pEva->Level  = 1 + IVY_MAX(pEvals[k].Level, pEvals[i].Level);  +            pEva->Fan0   = k;  +            pEva->Fan1   = i;  +//            assert( pEva->Level == (unsigned)Ivy_ObjLevel(pTemp) ); +            // compare +            if ( pEvaBest->Weight < pEva->Weight || +                 pEvaBest->Weight == pEva->Weight && pEvaBest->Cost > pEva->Cost || +                 pEvaBest->Weight == pEva->Weight && pEvaBest->Cost == pEva->Cost && pEvaBest->Level > pEva->Level ) +                 pEvaBest = pEva; +            // save the argument +            pArgs[nArgsNew++] = pTemp; +            if ( nArgsNew == 15 ) +                goto Outside; +        } +Outside: + +//    printf( "Best = %d.\n", pEvaBest - pEvals ); + +    // the case of no common nodes +    if ( nArgsNew == nArgs ) +    { +        Ivy_MultiSort( pArgs, nArgs ); +        return Ivy_MultiBalance_rec( pArgs, nArgs, Type ); +    } +    // the case of one common node +    if ( nArgsNew == nArgs + 1 ) +    { +        assert( pEvaBest - pEvals == nArgs ); +        k = 0; +        for ( i = 0; i < nArgs; i++ ) +            if ( i != (int)pEvaBest->Fan0 && i != (int)pEvaBest->Fan1 ) +                pArgs[k++] = pArgs[i]; +        pArgs[k++] = pArgs[nArgs]; +        assert( k == nArgs - 1 ); +        nArgs = k; +        Ivy_MultiSort( pArgs, nArgs ); +        return Ivy_MultiBalance_rec( pArgs, nArgs, Type ); +    } +    // the case when there is a node that covers everything +    if ( (int)pEvaBest->Mask == ((1 << nArgs) - 1) ) +        return Ivy_MultiBuild_rec( pEvals, pEvaBest - pEvals, pArgs, nArgsNew, Type );  + +    // evaluate node pairs +    nEvals = nArgsNew; +    for ( i = 1; i < nArgsNew; i++ ) +    for ( k = 0; k < i; k++ ) +    { +        pEva = pEvals + nEvals; +        pEva->Mask   = pEvals[k].Mask | pEvals[i].Mask; +        pEva->Weight = NumBits[pEva->Mask]; +        pEva->Cost   = pEvals[k].Cost + pEvals[i].Cost + NumBits[pEvals[k].Mask & pEvals[i].Mask];  +        pEva->Level  = 1 + IVY_MAX(pEvals[k].Level, pEvals[i].Level);  +        pEva->Fan0   = k;  +        pEva->Fan1   = i;  +        // compare +        if ( pEvaBest->Weight < pEva->Weight || +             pEvaBest->Weight == pEva->Weight && pEvaBest->Cost > pEva->Cost || +             pEvaBest->Weight == pEva->Weight && pEvaBest->Cost == pEva->Cost && pEvaBest->Level > pEva->Level ) +             pEvaBest = pEva; +        // save the argument +        nEvals++; +    } +    assert( pEvaBest - pEvals >= nArgsNew ); + +//    printf( "Used (%d, %d).\n", pEvaBest->Fan0, pEvaBest->Fan1 ); + +    // get the best implementation +    pTemp = Ivy_MultiBuild_rec( pEvals, pEvaBest - pEvals, pArgs, nArgsNew, Type ); + +    // collect those not covered by EvaBest +    k = 0; +    for ( i = 0; i < nArgs; i++ ) +        if ( (pEvaBest->Mask & (1 << i)) == 0 ) +            pArgs[k++] = pArgs[i]; +    pArgs[k++] = pTemp; +    assert( k == nArgs - (int)pEvaBest->Weight + 1 ); +    nArgs = k; +    Ivy_MultiSort( pArgs, nArgs ); +    return Ivy_MultiBalance_rec( pArgs, nArgs, Type ); +} + +/**Function************************************************************* + +  Synopsis    [Implements multi-input AND/EXOR operation.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Ivy_Obj_t * Ivy_MultiBuild_rec( Ivy_Eval_t * pEvals, int iNum, Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type ) +{ +    Ivy_Obj_t * pNode0, * pNode1; +    if ( iNum < nArgs ) +        return pArgs[iNum]; +    pNode0 = Ivy_MultiBuild_rec( pEvals, pEvals[iNum].Fan0, pArgs, nArgs, Type ); +    pNode1 = Ivy_MultiBuild_rec( pEvals, pEvals[iNum].Fan1, pArgs, nArgs, Type ); +    return Ivy_Oper( pNode0, pNode1, Type ); +} + +/**Function************************************************************* + +  Synopsis    [Selection-sorts the nodes in the decreasing over of level.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ivy_MultiSort( Ivy_Obj_t ** pArgs, int nArgs ) +{ +    Ivy_Obj_t * pTemp; +    int i, j, iBest; + +    for ( i = 0; i < nArgs-1; i++ ) +    { +        iBest = i; +        for ( j = i+1; j < nArgs; j++ ) +            if ( Ivy_Regular(pArgs[j])->Level > Ivy_Regular(pArgs[iBest])->Level ) +                iBest = j; +        pTemp = pArgs[i];  +        pArgs[i] = pArgs[iBest];  +        pArgs[iBest] = pTemp; +    } +} + +/**Function************************************************************* + +  Synopsis    [Inserts a new node in the order by levels.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ivy_MultiPushUniqueOrderByLevel( Ivy_Obj_t ** pArray, int nArgs, Ivy_Obj_t * pNode ) +{ +    Ivy_Obj_t * pNode1, * pNode2; +    int i; +    // try to find the node in the array +    for ( i = 0; i < nArgs; i++ ) +        if ( pArray[i] == pNode ) +            return nArgs; +    // put the node last +    pArray[nArgs++] = pNode; +    // find the place to put the new node +    for ( i = nArgs-1; i > 0; i-- ) +    { +        pNode1 = pArray[i  ]; +        pNode2 = pArray[i-1]; +        if ( Ivy_Regular(pNode1)->Level <= Ivy_Regular(pNode2)->Level ) +            break; +        pArray[i  ] = pNode2; +        pArray[i-1] = pNode1; +    } +    return nArgs; +} + +/**Function************************************************************* + +  Synopsis    [Balances the array recursively.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Ivy_Obj_t * Ivy_MultiBalance_rec( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type ) +{ +    Ivy_Obj_t * pNodeNew; +    // consider the case of one argument +    assert( nArgs > 0 ); +    if ( nArgs == 1 ) +        return pArgs[0]; +    // consider the case of two arguments +    if ( nArgs == 2 ) +        return Ivy_Oper( pArgs[0], pArgs[1], Type ); +    // get the last two nodes +    pNodeNew = Ivy_Oper( pArgs[nArgs-1], pArgs[nArgs-2], Type ); +    // add the new node +    nArgs = Ivy_MultiPushUniqueOrderByLevel( pArgs, nArgs - 2, pNodeNew ); +    return Ivy_MultiBalance_rec( pArgs, nArgs, Type ); +} + +/**Function************************************************************* + +  Synopsis    [Implements multi-input AND/EXOR operation.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Ivy_Obj_t * Ivy_MultiEval( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type ) +{ +    Ivy_Obj_t * pTemp; +    int i, k; +    int nArgsOld = nArgs; +    for ( i = 0; i < nArgs; i++ ) +        printf( "%d[%d] ", i, Ivy_Regular(pArgs[i])->Level ); +    for ( i = 1; i < nArgs; i++ ) +        for ( k = 0; k < i; k++ ) +        { +            pTemp = Ivy_TableLookup(Ivy_ObjCreateGhost(pArgs[k], pArgs[i], Type, IVY_INIT_NONE)); +            if ( pTemp != NULL ) +            { +                printf( "%d[%d]=(%d,%d) ", nArgs, Ivy_Regular(pTemp)->Level, k, i ); +                pArgs[nArgs++] = pTemp; +            } +        } +    printf( "     ((%d/%d))    ", nArgsOld, nArgs-nArgsOld ); +    return NULL; +} + + + +/**Function************************************************************* + +  Synopsis    [Old code.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Ivy_Obj_t * Ivy_Multi1( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type ) +{ +    Ivy_Obj_t * pArgsRef[5], * pTemp; +    int i, k, m, nArgsNew, Counter = 0; +  +     +//Ivy_MultiEval( pArgs, nArgs, Type );  printf( "\n" ); + + +    assert( Type == IVY_AND || Type == IVY_EXOR ); +    assert( nArgs > 0 ); +    if ( nArgs == 1 ) +        return pArgs[0]; + +    // find the nodes with more than one fanout +    nArgsNew = 0; +    for ( i = 0; i < nArgs; i++ ) +        if ( Ivy_ObjRefs( Ivy_Regular(pArgs[i]) ) > 0 ) +            pArgsRef[nArgsNew++] = pArgs[i]; + +    // go through pairs +    if ( nArgsNew >= 2 ) +    for ( i = 0; i < nArgsNew; i++ ) +    for ( k = i + 1; k < nArgsNew; k++ ) +        if ( pTemp = Ivy_TableLookup(Ivy_ObjCreateGhost(pArgsRef[i], pArgsRef[k], Type, IVY_INIT_NONE)) ) +            Counter++; +//    printf( "%d", Counter ); +             +    // go through pairs +    if ( nArgsNew >= 2 ) +    for ( i = 0; i < nArgsNew; i++ ) +    for ( k = i + 1; k < nArgsNew; k++ ) +        if ( pTemp = Ivy_TableLookup(Ivy_ObjCreateGhost(pArgsRef[i], pArgsRef[k], Type, IVY_INIT_NONE)) ) +        { +            nArgsNew = 0; +            for ( m = 0; m < nArgs; m++ ) +                if ( pArgs[m] != pArgsRef[i] && pArgs[m] != pArgsRef[k] ) +                    pArgs[nArgsNew++] = pArgs[m]; +            pArgs[nArgsNew++] = pTemp; +            assert( nArgsNew == nArgs - 1 ); +            return Ivy_Multi1( pArgs, nArgsNew, Type ); +        } +    return Ivy_Multi_rec( pArgs, nArgs, Type ); +} + +/**Function************************************************************* + +  Synopsis    [Old code.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Ivy_Obj_t * Ivy_Multi2( Ivy_Obj_t ** pArgs, int nArgs, Ivy_Type_t Type ) +{ +    assert( Type == IVY_AND || Type == IVY_EXOR ); +    assert( nArgs > 0 ); +    return Ivy_Multi_rec( pArgs, nArgs, Type ); +} + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/temp/ivy/ivyObj.c b/src/temp/ivy/ivyObj.c index 5d063525..703218bb 100644 --- a/src/temp/ivy/ivyObj.c +++ b/src/temp/ivy/ivyObj.c @@ -51,6 +51,7 @@ Ivy_Obj_t * Ivy_ObjCreate( Ivy_Obj_t * pGhost )      // realloc the node array      if ( p->ObjIdNext == p->nObjsAlloc )      { +        printf( "AIG manager is being resized. In the current release, it is not allowed!\n" );          Ivy_ManGrow( p );          pGhost = Ivy_ManGhost( p );      } diff --git a/src/temp/ivy/ivyOper.c b/src/temp/ivy/ivyOper.c index a10ba343..96f78165 100644 --- a/src/temp/ivy/ivyOper.c +++ b/src/temp/ivy/ivyOper.c @@ -81,7 +81,7 @@ Ivy_Obj_t * Ivy_Oper( Ivy_Obj_t * p0, Ivy_Obj_t * p1, Ivy_Type_t Type )  Ivy_Obj_t * Ivy_And( Ivy_Obj_t * p0, Ivy_Obj_t * p1 )  {      Ivy_Obj_t * pConst1 = Ivy_ObjConst1(Ivy_Regular(p0)); -    Ivy_Obj_t * pFan0, * pFan1; +//    Ivy_Obj_t * pFan0, * pFan1;      // check trivial cases      if ( p0 == p1 )          return p0; @@ -92,8 +92,8 @@ Ivy_Obj_t * Ivy_And( Ivy_Obj_t * p0, Ivy_Obj_t * p1 )      if ( Ivy_Regular(p1) == pConst1 )          return p1 == pConst1 ? p0 : Ivy_Not(pConst1);      // check if it can be an EXOR gate -    if ( Ivy_ObjIsExorType( p0, p1, &pFan0, &pFan1 ) ) -        return Ivy_CanonExor( pFan0, pFan1 ); +//    if ( Ivy_ObjIsExorType( p0, p1, &pFan0, &pFan1 ) ) +//        return Ivy_CanonExor( pFan0, pFan1 );      return Ivy_CanonAnd( p0, p1 );  } diff --git a/src/temp/ivy/ivyResyn.c b/src/temp/ivy/ivyResyn.c new file mode 100644 index 00000000..2d65e7f7 --- /dev/null +++ b/src/temp/ivy/ivyResyn.c @@ -0,0 +1,96 @@ +/**CFile**************************************************************** + +  FileName    [ivyResyn.c] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [And-Inverter Graph package.] + +  Synopsis    [AIG rewriting script.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - May 11, 2006.] + +  Revision    [$Id: ivyResyn.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "ivy.h" + +//////////////////////////////////////////////////////////////////////// +///                        DECLARATIONS                              /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [Performs several passes of rewriting on the AIG.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Ivy_Man_t * Ivy_ManResyn( Ivy_Man_t * pMan, int fUpdateLevel ) +{ +    int clk, fVerbose = 0; +    Ivy_Man_t * pTemp; + +if ( fVerbose ) Ivy_ManPrintStats( pMan ); +clk = clock(); +    pMan = Ivy_ManBalance( pMan, fUpdateLevel ); +if ( fVerbose ) { PRT( "Balance", clock() - clk ); } +if ( fVerbose ) Ivy_ManPrintStats( pMan ); + +//    Ivy_ManRewriteAlg( pMan, fUpdateLevel, 0 ); +clk = clock(); +    Ivy_ManRewritePre( pMan, fUpdateLevel, 0, 0 ); +if ( fVerbose ) { PRT( "Rewrite", clock() - clk ); } +if ( fVerbose ) Ivy_ManPrintStats( pMan ); + +clk = clock(); +    pMan = Ivy_ManBalance( pTemp = pMan, fUpdateLevel ); +    Ivy_ManStop( pTemp ); +if ( fVerbose ) { PRT( "Balance", clock() - clk ); } +if ( fVerbose ) Ivy_ManPrintStats( pMan ); + +//    Ivy_ManRewriteAlg( pMan, fUpdateLevel, 1 ); +clk = clock(); +if ( fVerbose ) Ivy_ManRewritePre( pMan, fUpdateLevel, 1, 0 ); +if ( fVerbose ) { PRT( "Rewrite", clock() - clk ); } +if ( fVerbose ) Ivy_ManPrintStats( pMan ); + +clk = clock(); +    pMan = Ivy_ManBalance( pTemp = pMan, fUpdateLevel ); +    Ivy_ManStop( pTemp ); +if ( fVerbose ) { PRT( "Balance", clock() - clk ); } +if ( fVerbose ) Ivy_ManPrintStats( pMan ); + +//    Ivy_ManRewriteAlg( pMan, fUpdateLevel, 1 ); +clk = clock(); +    Ivy_ManRewritePre( pMan, fUpdateLevel, 1, 0 ); +if ( fVerbose ) { PRT( "Rewrite", clock() - clk ); } +if ( fVerbose ) Ivy_ManPrintStats( pMan ); + +clk = clock(); +    pMan = Ivy_ManBalance( pTemp = pMan, fUpdateLevel ); +    Ivy_ManStop( pTemp ); +if ( fVerbose ) { PRT( "Balance", clock() - clk ); } +if ( fVerbose ) Ivy_ManPrintStats( pMan ); +    return pMan; +} + + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/temp/ivy/ivyRwrAlg.c b/src/temp/ivy/ivyRwrAlg.c new file mode 100644 index 00000000..234827ff --- /dev/null +++ b/src/temp/ivy/ivyRwrAlg.c @@ -0,0 +1,408 @@ +/**CFile**************************************************************** + +  FileName    [ivyRwrAlg.c] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [And-Inverter Graph package.] + +  Synopsis    [Algebraic AIG rewriting.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - May 11, 2006.] + +  Revision    [$Id: ivyRwrAlg.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "ivy.h" + +//////////////////////////////////////////////////////////////////////// +///                        DECLARATIONS                              /// +//////////////////////////////////////////////////////////////////////// + +static int Ivy_ManFindAlgCut( Ivy_Obj_t * pRoot, Vec_Ptr_t * vFront, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone ); +static Ivy_Obj_t * Ivy_NodeRewriteAlg( Ivy_Obj_t * pObj, Vec_Ptr_t * vFront, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone, Vec_Ptr_t * vSols, int LevelR, int fUseZeroCost ); +static int Ivy_NodeCountMffc( Ivy_Obj_t * pNode ); + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [Algebraic AIG rewriting.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ivy_ManRewriteAlg( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost ) +{ +    Vec_Int_t * vRequired; +    Vec_Ptr_t * vFront, * vLeaves, * vCone, * vSol; +    Ivy_Obj_t * pObj, * pResult; +    int i, RetValue, LevelR, nNodesOld; +    int CountUsed, CountUndo; +    vRequired = fUpdateLevel? Ivy_ManRequiredLevels( p ) : NULL; +    vFront    = Vec_PtrAlloc( 100 ); +    vLeaves   = Vec_PtrAlloc( 100 ); +    vCone     = Vec_PtrAlloc( 100 ); +    vSol      = Vec_PtrAlloc( 100 ); +    // go through the nodes in the topological order +    CountUsed = CountUndo = 0; +    nNodesOld = Ivy_ManObjIdNext(p); +    Ivy_ManForEachObj( p, pObj, i ) +    { +        assert( !Ivy_ObjIsBuf(pObj) ); +        if ( i >= nNodesOld ) +            break; +        // skip no-nodes and MUX roots +        if ( !Ivy_ObjIsNode(pObj) || Ivy_ObjIsExor(pObj) || Ivy_ObjIsMuxType(pObj) ) +            continue; +//        if ( pObj->Id > 297 ) // 296 --- 297  +//            break; +        if ( pObj->Id == 297 ) +        { +            int x = 0; +        } +        // get the largest algebraic cut +        RetValue = Ivy_ManFindAlgCut( pObj, vFront, vLeaves, vCone ); +        // the case of a trivial tree cut +        if ( RetValue == 1 ) +            continue; +        // the case of constant 0 cone +        if ( RetValue == -1 ) +        { +            Ivy_ObjReplace( pObj, Ivy_ManConst0(p), 1, 0 );  +            continue; +        } +        assert( Vec_PtrSize(vLeaves) > 2 ); +        // get the required level for this node +        LevelR = vRequired? Vec_IntEntry(vRequired, pObj->Id) : 1000000; +        // create a new cone +        pResult = Ivy_NodeRewriteAlg( pObj, vFront, vLeaves, vCone, vSol, LevelR, fUseZeroCost ); +        if ( pResult == NULL || pResult == pObj ) +            continue; +        assert( Vec_PtrSize(vSol) == 1 || !Ivy_IsComplement(pResult) ); +        if ( Ivy_ObjLevel(Ivy_Regular(pResult)) > LevelR && Ivy_ObjRefs(Ivy_Regular(pResult)) == 0 ) +            Ivy_ObjDelete_rec(Ivy_Regular(pResult), 1), CountUndo++; +        else +            Ivy_ObjReplace( pObj, pResult, 1, 0 ), CountUsed++;  +    } +    printf( "Used = %d. Undo = %d.\n", CountUsed, CountUndo ); +    Vec_PtrFree( vFront ); +    Vec_PtrFree( vCone ); +    Vec_PtrFree( vSol ); +    if ( vRequired ) Vec_IntFree( vRequired ); +    if ( i = Ivy_ManCleanup(p) ) +        printf( "Cleanup after rewriting removed %d dangling nodes.\n", i ); +    if ( !Ivy_ManCheck(p) ) +        printf( "Ivy_ManRewriteAlg(): The check has failed.\n" ); +    return 1; +} + +/**Function************************************************************* + +  Synopsis    [Analizes one node.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Ivy_Obj_t * Ivy_NodeRewriteAlg( Ivy_Obj_t * pObj, Vec_Ptr_t * vFront, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone, Vec_Ptr_t * vSols, int LevelR, int fUseZeroCost ) +{ +    int fVerbose = 0; +    Ivy_Obj_t * pTemp; +    int k, Counter, nMffc, RetValue; + +    if ( fVerbose ) +    { +        if ( Ivy_ObjIsExor(pObj) ) +            printf( "x " ); +        else +            printf( "  " ); +    } + +/*        +    printf( "%d ", Vec_PtrSize(vFront) ); +    printf( "( " ); +    Vec_PtrForEachEntry( vFront, pTemp, k ) +        printf( "%d ", Ivy_ObjRefs(Ivy_Regular(pTemp)) ); +    printf( ")\n" ); +*/ +    // collect nodes in the cone +    if ( Ivy_ObjIsExor(pObj) ) +        Ivy_ManCollectCone( pObj, vFront, vCone ); +    else +        Ivy_ManCollectCone( pObj, vLeaves, vCone ); + +    // deref nodes in the cone +    Vec_PtrForEachEntry( vCone, pTemp, k ) +    { +        Ivy_ObjRefsDec( Ivy_ObjFanin0(pTemp) ); +        Ivy_ObjRefsDec( Ivy_ObjFanin1(pTemp) ); +        pTemp->fMarkB = 1; +    } + +    // count the MFFC size +    Vec_PtrForEachEntry( vFront, pTemp, k ) +        Ivy_Regular(pTemp)->fMarkA = 1; +    nMffc = Ivy_NodeCountMffc( pObj ); +    Vec_PtrForEachEntry( vFront, pTemp, k ) +        Ivy_Regular(pTemp)->fMarkA = 0; + +    if ( fVerbose ) +    { +    Counter = 0; +    Vec_PtrForEachEntry( vCone, pTemp, k ) +        Counter += (Ivy_ObjRefs(pTemp) > 0); +    printf( "%5d : Leaves = %2d. Cone = %2d. ConeRef = %2d.   Mffc = %d.   Lev = %d.  LevR = %d.\n",  +        pObj->Id, Vec_PtrSize(vFront), Vec_PtrSize(vCone), Counter-1, nMffc, Ivy_ObjLevel(pObj), LevelR ); +    } +/* +    printf( "Leaves:" ); +    Vec_PtrForEachEntry( vLeaves, pTemp, k ) +        printf( " %d%s", Ivy_Regular(pTemp)->Id, Ivy_IsComplement(pTemp)? "\'" : "" ); +    printf( "\n" ); +    printf( "Cone:\n" ); +    Vec_PtrForEachEntry( vCone, pTemp, k ) +        printf( " %5d = %d%s %d%s\n", pTemp->Id, +            Ivy_ObjFaninId0(pTemp), Ivy_ObjFaninC0(pTemp)? "\'" : "", +            Ivy_ObjFaninId1(pTemp), Ivy_ObjFaninC1(pTemp)? "\'" : "" ); +*/ + +    RetValue = Ivy_MultiPlus( vLeaves, vCone, Ivy_ObjType(pObj), nMffc + fUseZeroCost, vSols ); + +    // ref nodes in the cone +    Vec_PtrForEachEntry( vCone, pTemp, k ) +    { +        Ivy_ObjRefsInc( Ivy_ObjFanin0(pTemp) ); +        Ivy_ObjRefsInc( Ivy_ObjFanin1(pTemp) ); +        pTemp->fMarkA = 0; +        pTemp->fMarkB = 0; +    } + +    if ( !RetValue ) +        return NULL; + +    if ( Vec_PtrSize( vSols ) == 1 ) +        return Vec_PtrEntry( vSols, 0 ); +    return Ivy_NodeBalanceBuildSuper( vSols, Ivy_ObjType(pObj), 1 ); +} + +/**Function************************************************************* + +  Synopsis    [Comparison for node pointers.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ivy_NodeCountMffc_rec( Ivy_Obj_t * pNode ) +{ +    if ( Ivy_ObjRefs(pNode) > 0 || Ivy_ObjIsCi(pNode) || pNode->fMarkA ) +        return 0; +    assert( pNode->fMarkB ); +    pNode->fMarkA = 1; +//    printf( "%d ", pNode->Id ); +    if ( Ivy_ObjIsBuf(pNode) ) +        return Ivy_NodeCountMffc_rec( Ivy_ObjFanin0(pNode) ); +    return 1 + Ivy_NodeCountMffc_rec( Ivy_ObjFanin0(pNode) ) + Ivy_NodeCountMffc_rec( Ivy_ObjFanin1(pNode) ); +} + +/**Function************************************************************* + +  Synopsis    [Comparison for node pointers.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ivy_NodeCountMffc( Ivy_Obj_t * pNode ) +{ +    assert( pNode->fMarkB ); +    return 1 + Ivy_NodeCountMffc_rec( Ivy_ObjFanin0(pNode) ) + Ivy_NodeCountMffc_rec( Ivy_ObjFanin1(pNode) ); +} + +/**Function************************************************************* + +  Synopsis    [Comparison for node pointers.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ivy_ManFindAlgCutCompare( Ivy_Obj_t ** pp1, Ivy_Obj_t ** pp2 ) +{ +    if ( *pp1 < *pp2 ) +        return -1; +    if ( *pp1 > *pp2 ) +        return 1; +    return 0; +} + +/**Function************************************************************* + +  Synopsis    [Computing one algebraic cut.] + +  Description [Returns 1 if the tree-leaves of this node where traversed  +  and found to have no external references (and have not been collected).  +  Returns 0 if the tree-leaves have external references and are collected.] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ivy_ManFindAlgCut_rec( Ivy_Obj_t * pObj, Ivy_Type_t Type, Vec_Ptr_t * vFront, Vec_Ptr_t * vCone ) +{ +    int RetValue0, RetValue1; +    Ivy_Obj_t * pObjR = Ivy_Regular(pObj); +    assert( !Ivy_ObjIsBuf(pObjR) ); +    assert( Type != IVY_EXOR || !Ivy_IsComplement(pObj) ); + +    // make sure the node is not visited twice in different polarities +    if ( Ivy_IsComplement(pObj) ) +    { // if complemented, mark B +        if ( pObjR->fMarkA ) +            return -1; +        pObjR->fMarkB = 1; +    } +    else +    { // if non-complicated, mark A +        if ( pObjR->fMarkB ) +            return -1; +        pObjR->fMarkA = 1; +    } +    Vec_PtrPush( vCone, pObjR ); + +    // if the node is the end of the tree, return +    if ( Ivy_IsComplement(pObj) || Ivy_ObjType(pObj) != Type ) +    { +        if ( Ivy_ObjRefs(pObjR) == 1 ) +            return 1; +        assert( Ivy_ObjRefs(pObjR) > 1 ); +        Vec_PtrPush( vFront, pObj ); +        return 0; +    } + +    // branch on the node +    assert( !Ivy_IsComplement(pObj) ); +    assert( Ivy_ObjIsNode(pObj) ); +    // what if buffer has more than one fanout??? +    RetValue0 = Ivy_ManFindAlgCut_rec( Ivy_ObjReal( Ivy_ObjChild0(pObj) ), Type, vFront, vCone ); +    RetValue1 = Ivy_ManFindAlgCut_rec( Ivy_ObjReal( Ivy_ObjChild1(pObj) ), Type, vFront, vCone ); +    if ( RetValue0 == -1 || RetValue1 == -1 ) +        return -1; + +    // the case when both have no external references +    if ( RetValue0 && RetValue1 ) +    { +        if ( Ivy_ObjRefs(pObj) == 1 ) +            return 1; +        assert( Ivy_ObjRefs(pObj) > 1 ); +        Vec_PtrPush( vFront, pObj ); +        return 0; +    } +    // the case when one of them has external references +    if ( RetValue0 ) +        Vec_PtrPush( vFront, Ivy_ObjReal( Ivy_ObjChild0(pObj) ) ); +    if ( RetValue1 ) +        Vec_PtrPush( vFront, Ivy_ObjReal( Ivy_ObjChild1(pObj) ) ); +    return 0; +} + +/**Function************************************************************* + +  Synopsis    [Computing one algebraic cut.] + +  Description [Algebraic cut stops when we hit (a) CI, (b) complemented edge, +  (c) boundary of different gates. Returns 1 if this is a pure tree. +  Returns -1 if the contant 0 is detected. Return 0 if the array can be used.] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ivy_ManFindAlgCut( Ivy_Obj_t * pRoot, Vec_Ptr_t * vFront, Vec_Ptr_t * vLeaves, Vec_Ptr_t * vCone ) +{ +    Ivy_Obj_t * pObj, * pPrev; +    int RetValue, i; +    assert( !Ivy_IsComplement(pRoot) ); +    assert( Ivy_ObjIsNode(pRoot) ); +    // clear the frontier and collect the nodes +    Vec_PtrClear( vCone ); +    Vec_PtrClear( vFront ); +    Vec_PtrClear( vLeaves ); +    RetValue = Ivy_ManFindAlgCut_rec( pRoot, Ivy_ObjType(pRoot), vFront, vCone ); +    // clean the marks +    Vec_PtrForEachEntry( vCone, pObj, i ) +        pObj->fMarkA = pObj->fMarkB = 0; +    // quit if the same node is found in both polarities +    if ( RetValue == -1 ) +        return -1; +    // return if the node is the root of a tree +    if ( RetValue == 1 ) +        return 1; +    // return if the cut is composed of two nodes +    if ( Vec_PtrSize(vFront) <= 2 ) +        return 1; +    // sort the entries in increasing order +    Vec_PtrSort( vFront, Ivy_ManFindAlgCutCompare ); +    // remove duplicates from vFront and save the nodes in vLeaves +    pPrev = Vec_PtrEntry(vFront, 0); +    Vec_PtrPush( vLeaves, pPrev ); +    Vec_PtrForEachEntryStart( vFront, pObj, i, 1 ) +    { +        // compare current entry and the previous entry +        if ( pObj == pPrev ) +        { +            if ( Ivy_ObjIsExor(pRoot) ) // A <+> A = 0 +            { +                // vLeaves are no longer structural support of pRoot!!! +                Vec_PtrPop(vLeaves);   +                pPrev = Vec_PtrSize(vLeaves) == 0 ? NULL : Vec_PtrEntryLast(vLeaves); +            } +            continue; +        } +        if ( pObj == Ivy_Not(pPrev) ) +        { +            assert( Ivy_ObjIsAnd(pRoot) ); +            return -1; +        } +        pPrev = pObj; +        Vec_PtrPush( vLeaves, pObj ); +    } +    if ( Vec_PtrSize(vLeaves) == 0 ) +        return -1; +    if ( Vec_PtrSize(vLeaves) <= 2 ) +        return 1; +    return 0; +} + + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/temp/ivy/ivyRwrPre.c b/src/temp/ivy/ivyRwrPre.c new file mode 100644 index 00000000..243ab261 --- /dev/null +++ b/src/temp/ivy/ivyRwrPre.c @@ -0,0 +1,597 @@ +/**CFile**************************************************************** + +  FileName    [ivyRwtPre.c] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [And-Inverter Graph package.] + +  Synopsis    [Rewriting based on precomputation.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - May 11, 2006.] + +  Revision    [$Id: ivyRwtPre.c,v 1.00 2006/05/11 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "ivy.h" +#include "deco.h" +#include "rwt.h" + +//////////////////////////////////////////////////////////////////////// +///                        DECLARATIONS                              /// +//////////////////////////////////////////////////////////////////////// + +static unsigned Ivy_NodeGetTruth( Ivy_Obj_t * pObj, int * pNums, int nNums ); +static int Ivy_NodeMffcLabel( Ivy_Obj_t * pObj ); +static int Rwt_NodeRewrite( Rwt_Man_t * p, Ivy_Obj_t * pNode, int fUpdateLevel, int fUseZeroCost ); +static Dec_Graph_t * Rwt_CutEvaluate( Rwt_Man_t * p, Ivy_Obj_t * pRoot, Ivy_Cut_t * pCut,  +    Vec_Ptr_t * vFaninsCur, int nNodesSaved, int LevelMax, int * pGainBest, unsigned uTruth ); + +static int Ivy_GraphToNetworkCount( Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMax, int LevelMax ); +static void Ivy_GraphUpdateNetwork( Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain ); + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [Performs incremental rewriting of the AIG.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ivy_ManRewritePre( Ivy_Man_t * p, int fUpdateLevel, int fUseZeroCost, int fVerbose ) +{ +    Rwt_Man_t * pManRwt; +    Ivy_Obj_t * pNode; +    int i, nNodes, nGain; +    int clk, clkStart = clock(); +    // start the rewriting manager +    pManRwt = Rwt_ManStart( 0 ); +    if ( pManRwt == NULL ) +        return 0; +    // compute the reverse levels if level update is requested +    if ( fUpdateLevel ) +        Ivy_ManRequiredLevels( p ); +    // resynthesize each node once +    nNodes = Ivy_ManObjIdNext( p ); +    Ivy_ManForEachObj( p, pNode, i ) +    { +        if ( !Ivy_ObjIsNode(pNode) ) +            continue; +        // fix the fanin buffer problem +        Ivy_NodeFixBufferFanins( pNode ); +        if ( Ivy_ObjIsBuf(pNode) ) +            continue; +        // stop if all nodes have been tried once +        if ( i >= nNodes ) +            break; +        // skip the nodes with many fanouts +//        if ( Ivy_ObjRefs(pNode) > 1000 ) +//            continue; +        // for each cut, try to resynthesize it +        nGain = Rwt_NodeRewrite( pManRwt, pNode, fUpdateLevel, fUseZeroCost ); +        if ( nGain > 0 || nGain == 0 && fUseZeroCost ) +        { +            Dec_Graph_t * pGraph = Rwt_ManReadDecs(pManRwt); +            int fCompl           = Rwt_ManReadCompl(pManRwt); +/* +            { +                Ivy_Obj_t * pObj; +                int i; +                printf( "USING: (" ); +                Vec_PtrForEachEntry( Rwt_ManReadLeaves(pManRwt), pObj, i ) +                    printf( "%d ", Ivy_ObjFanoutNum(Ivy_Regular(pObj)) ); +                printf( ")   Gain = %d.\n", nGain ); +            } +            if ( nGain > 0 ) +            { // print stats on the MFFC +                extern void Ivy_NodeMffsConeSuppPrint( Ivy_Obj_t * pNode ); +                printf( "Node %6d : Gain = %4d  ", pNode->Id, nGain ); +                Ivy_NodeMffsConeSuppPrint( pNode ); +            } +*/ +            // complement the FF if needed +clk = clock(); +            if ( fCompl ) Dec_GraphComplement( pGraph ); +            Ivy_GraphUpdateNetwork( pNode, pGraph, fUpdateLevel, nGain ); +            if ( fCompl ) Dec_GraphComplement( pGraph ); +Rwt_ManAddTimeUpdate( pManRwt, clock() - clk ); +        } +    } +Rwt_ManAddTimeTotal( pManRwt, clock() - clkStart ); +    // print stats +    if ( fVerbose ) +        Rwt_ManPrintStats( pManRwt ); +    // delete the managers +    Rwt_ManStop( pManRwt ); +    // fix the levels +    if ( fUpdateLevel ) +        Vec_IntFree( p->vRequired ), p->vRequired = NULL; +    // check +    if ( i = Ivy_ManCleanup(p) ) +        printf( "Cleanup after rewriting removed %d dangling nodes.\n", i ); +    if ( !Ivy_ManCheck(p) ) +        printf( "Ivy_ManRewritePre(): The check has failed.\n" ); +    return 1; +} + +/**Function************************************************************* + +  Synopsis    [Performs rewriting for one node.] + +  Description [This procedure considers all the cuts computed for the node +  and tries to rewrite each of them using the "forest" of different AIG +  structures precomputed and stored in the RWR manager.  +  Determines the best rewriting and computes the gain in the number of AIG +  nodes in the final network. In the end, p->vFanins contains information  +  about the best cut that can be used for rewriting, while p->pGraph gives  +  the decomposition dag (represented using decomposition graph data structure). +  Returns gain in the number of nodes or -1 if node cannot be rewritten.] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Rwt_NodeRewrite( Rwt_Man_t * p, Ivy_Obj_t * pNode, int fUpdateLevel, int fUseZeroCost ) +{ +    int fVeryVerbose = 0; +    Dec_Graph_t * pGraph; +    Ivy_Store_t * pStore; +    Ivy_Cut_t * pCut; +    Ivy_Obj_t * pFanin; +    unsigned uPhase, uTruthBest, uTruth; +    char * pPerm; +    int Required, nNodesSaved, nNodesSaveCur; +    int i, c, GainCur, GainBest = -1; +    int clk, clk2; + +    p->nNodesConsidered++; +    // get the required times +    Required = fUpdateLevel? Vec_IntEntry( Ivy_ObjMan(pNode)->vRequired, pNode->Id ) : 1000000; +    // get the node's cuts +clk = clock(); +    pStore = Ivy_NodeFindCutsAll( pNode, 5 ); +p->timeCut += clock() - clk; + +    // go through the cuts +clk = clock(); +    for ( c = 1; c < pStore->nCuts; c++ ) +    { +        pCut = pStore->pCuts + c; +        // consider only 4-input cuts +        if ( pCut->nSize != 4 ) +            continue; +        // skip the cuts with buffers +        for ( i = 0; i < (int)pCut->nSize; i++ ) +            if ( Ivy_ObjIsBuf( Ivy_ObjObj(pNode, pCut->pArray[i]) ) ) +                break; +        if ( i != pCut->nSize ) +            continue; + +//        if ( pNode->Id == 82 ) +//            Ivy_NodePrintCut( pCut ); + +        // get the fanin permutation +clk2 = clock(); +        uTruth = 0xFFFF & Ivy_NodeGetTruth( pNode, pCut->pArray, pCut->nSize );  // truth table +p->timeTruth += clock() - clk2; +        pPerm = p->pPerms4[ p->pPerms[uTruth] ]; +        uPhase = p->pPhases[uTruth]; +        // collect fanins with the corresponding permutation/phase +        Vec_PtrClear( p->vFaninsCur ); +        Vec_PtrFill( p->vFaninsCur, (int)pCut->nSize, 0 ); +        for ( i = 0; i < (int)pCut->nSize; i++ ) +        { +            pFanin = Ivy_ObjObj( pNode, pCut->pArray[pPerm[i]] ); +            assert( Ivy_ObjIsNode(pFanin) || Ivy_ObjIsCi(pFanin) ); +            pFanin = Ivy_NotCond(pFanin, ((uPhase & (1<<i)) > 0) ); +            Vec_PtrWriteEntry( p->vFaninsCur, i, pFanin ); +        } +clk2 = clock(); +/* +        printf( "Considering: (" ); +        Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i ) +            printf( "%d ", Ivy_ObjFanoutNum(Ivy_Regular(pFanin)) ); +        printf( ")\n" ); +*/ +        // mark the fanin boundary  +        Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i ) +            Ivy_ObjRefsInc( Ivy_Regular(pFanin) ); +        // label MFFC with current ID +        Ivy_ManIncrementTravId( Ivy_ObjMan(pNode) ); +        nNodesSaved = Ivy_NodeMffcLabel( pNode ); +        // unmark the fanin boundary +        Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i ) +            Ivy_ObjRefsDec( Ivy_Regular(pFanin) ); +p->timeMffc += clock() - clk2; + +        // evaluate the cut +clk2 = clock(); +        pGraph = Rwt_CutEvaluate( p, pNode, pCut, p->vFaninsCur, nNodesSaved, Required, &GainCur, uTruth ); +p->timeEval += clock() - clk2; + +        // check if the cut is better than the current best one +        if ( pGraph != NULL && GainBest < GainCur ) +        { +            // save this form +            nNodesSaveCur = nNodesSaved; +            GainBest  = GainCur; +            p->pGraph  = pGraph; +            p->fCompl = ((uPhase & (1<<4)) > 0); +            uTruthBest = uTruth; +            // collect fanins in the +            Vec_PtrClear( p->vFanins ); +            Vec_PtrForEachEntry( p->vFaninsCur, pFanin, i ) +                Vec_PtrPush( p->vFanins, pFanin ); +        } +    } +p->timeRes += clock() - clk; + +    if ( GainBest == -1 ) +        return -1; + +//    printf( "%d", nNodesSaveCur - GainBest ); +/* +    if ( GainBest > 0 ) +    { +        if ( Rwt_CutIsintean( pNode, p->vFanins ) ) +            printf( "b" ); +        else +        { +            printf( "Node %d : ", pNode->Id ); +            Vec_PtrForEachEntry( p->vFanins, pFanin, i ) +                printf( "%d ", Ivy_Regular(pFanin)->Id ); +            printf( "a" ); +        } +    } +*/ +/* +    if ( GainBest > 0 ) +        if ( p->fCompl ) +            printf( "c" ); +        else +            printf( "." ); +*/ + +    // copy the leaves +    Vec_PtrForEachEntry( p->vFanins, pFanin, i ) +        Dec_GraphNode(p->pGraph, i)->pFunc = pFanin; + +    p->nScores[p->pMap[uTruthBest]]++; +    p->nNodesGained += GainBest; +    if ( fUseZeroCost || GainBest > 0 ) +        p->nNodesRewritten++; + +    // report the progress +    if ( fVeryVerbose && GainBest > 0 ) +    { +        printf( "Node %6d :   ", Ivy_ObjId(pNode) ); +        printf( "Fanins = %d. ", p->vFanins->nSize ); +        printf( "Save = %d.  ", nNodesSaveCur ); +        printf( "Add = %d.  ",  nNodesSaveCur-GainBest ); +        printf( "GAIN = %d.  ", GainBest ); +        printf( "Cone = %d.  ", p->pGraph? Dec_GraphNodeNum(p->pGraph) : 0 ); +        printf( "Class = %d.  ", p->pMap[uTruthBest] ); +        printf( "\n" ); +    } +    return GainBest; +} + + +/**Function************************************************************* + +  Synopsis    [References/references the node and returns MFFC size.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ivy_NodeRefDeref( Ivy_Obj_t * pNode, int fReference, int fLabel ) +{ +    Ivy_Obj_t * pNode0, * pNode1; +    int Counter; +    // label visited nodes +    if ( fLabel ) +        Ivy_ObjSetTravIdCurrent( pNode ); +    // skip the CI +    if ( Ivy_ObjIsCi(pNode) ) +        return 0; +    assert( Ivy_ObjIsNode(pNode) || Ivy_ObjIsBuf(pNode) ); +    // process the internal node +    pNode0 = Ivy_ObjFanin0(pNode); +    pNode1 = Ivy_ObjFanin1(pNode); +    Counter = Ivy_ObjIsNode(pNode); +    if ( fReference ) +    { +        if ( pNode0->nRefs++ == 0 ) +            Counter += Ivy_NodeRefDeref( pNode0, fReference, fLabel ); +        if ( Ivy_ObjIsNode(pNode) && pNode1->nRefs++ == 0 ) +            Counter += Ivy_NodeRefDeref( pNode1, fReference, fLabel ); +    } +    else +    { +        assert( pNode0->nRefs > 0 ); +        assert( pNode1->nRefs > 0 ); +        if ( --pNode0->nRefs == 0 ) +            Counter += Ivy_NodeRefDeref( pNode0, fReference, fLabel ); +        if ( Ivy_ObjIsNode(pNode) && --pNode1->nRefs == 0 ) +            Counter += Ivy_NodeRefDeref( pNode1, fReference, fLabel ); +    } +    return Counter; +} + +/**Function************************************************************* + +  Synopsis    [Computes the size of MFFC and labels nodes with the current TravId.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ivy_NodeMffcLabel( Ivy_Obj_t * pNode ) +{ +    int nConeSize1, nConeSize2; +    assert( !Ivy_IsComplement( pNode ) ); +    assert( Ivy_ObjIsNode( pNode ) ); +    nConeSize1 = Ivy_NodeRefDeref( pNode, 0, 1 ); // dereference +    nConeSize2 = Ivy_NodeRefDeref( pNode, 1, 0 ); // reference +    assert( nConeSize1 == nConeSize2 ); +    assert( nConeSize1 > 0 ); +    return nConeSize1; +} + +/**Function************************************************************* + +  Synopsis    [Computes the truth table.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +unsigned Ivy_NodeGetTruth_rec( Ivy_Obj_t * pObj, int * pNums, int nNums ) +{ +    static unsigned uMasks[5] = { 0xAAAAAAAA, 0xCCCCCCCC, 0xF0F0F0F0, 0xFF00FF00, 0xFFFF0000 }; +    unsigned uTruth0, uTruth1; +    int i; +    for ( i = 0; i < nNums; i++ ) +        if ( pObj->Id == pNums[i] ) +            return uMasks[i]; +    assert( Ivy_ObjIsNode(pObj) || Ivy_ObjIsBuf(pObj) ); +    uTruth0 = Ivy_NodeGetTruth_rec( Ivy_ObjFanin0(pObj), pNums, nNums ); +    if ( Ivy_ObjFaninC0(pObj) ) +        uTruth0 = ~uTruth0; +    if ( Ivy_ObjIsBuf(pObj) ) +        return uTruth0; +    uTruth1 = Ivy_NodeGetTruth_rec( Ivy_ObjFanin1(pObj), pNums, nNums ); +    if ( Ivy_ObjFaninC1(pObj) ) +        uTruth1 = ~uTruth1; +    return uTruth0 & uTruth1; +} + + +/**Function************************************************************* + +  Synopsis    [Computes the truth table.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +unsigned Ivy_NodeGetTruth( Ivy_Obj_t * pObj, int * pNums, int nNums ) +{ +    assert( nNums < 6 ); +    return Ivy_NodeGetTruth_rec( pObj, pNums, nNums ); +} + +/**Function************************************************************* + +  Synopsis    [Evaluates the cut.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Dec_Graph_t * Rwt_CutEvaluate( Rwt_Man_t * p, Ivy_Obj_t * pRoot, Ivy_Cut_t * pCut, Vec_Ptr_t * vFaninsCur, int nNodesSaved, int LevelMax, int * pGainBest, unsigned uTruth ) +{ +    Vec_Ptr_t * vSubgraphs; +    Dec_Graph_t * pGraphBest, * pGraphCur; +    Rwt_Node_t * pNode, * pFanin; +    int nNodesAdded, GainBest, i, k; +    // find the matching class of subgraphs +    vSubgraphs = Vec_VecEntry( p->vClasses, p->pMap[uTruth] ); +    p->nSubgraphs += vSubgraphs->nSize; +    // determine the best subgraph +    GainBest = -1; +    Vec_PtrForEachEntry( vSubgraphs, pNode, i ) +    { +        // get the current graph +        pGraphCur = (Dec_Graph_t *)pNode->pNext; +        // copy the leaves +        Vec_PtrForEachEntry( vFaninsCur, pFanin, k ) +            Dec_GraphNode(pGraphCur, k)->pFunc = pFanin; +        // detect how many unlabeled nodes will be reused +        nNodesAdded = Ivy_GraphToNetworkCount( pRoot, pGraphCur, nNodesSaved, LevelMax ); +        if ( nNodesAdded == -1 ) +            continue; +        assert( nNodesSaved >= nNodesAdded ); +        // count the gain at this node +        if ( GainBest < nNodesSaved - nNodesAdded ) +        { +            GainBest   = nNodesSaved - nNodesAdded; +            pGraphBest = pGraphCur; +        } +    } +    if ( GainBest == -1 ) +        return NULL; +    *pGainBest = GainBest; +    return pGraphBest; +} + + +/**Function************************************************************* + +  Synopsis    [Counts the number of new nodes added when using this graph.] + +  Description [AIG nodes for the fanins should be assigned to pNode->pFunc  +  of the leaves of the graph before calling this procedure.  +  Returns -1 if the number of nodes and levels exceeded the given limit or  +  the number of levels exceeded the maximum allowed level.] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ivy_GraphToNetworkCount( Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int NodeMax, int LevelMax ) +{ +    Dec_Node_t * pNode, * pNode0, * pNode1; +    Ivy_Obj_t * pAnd, * pAnd0, * pAnd1; +    int i, Counter, LevelNew, LevelOld; +    // check for constant function or a literal +    if ( Dec_GraphIsConst(pGraph) || Dec_GraphIsVar(pGraph) ) +        return 0; +    // set the levels of the leaves +    Dec_GraphForEachLeaf( pGraph, pNode, i ) +        pNode->Level = Ivy_Regular(pNode->pFunc)->Level; +    // compute the AIG size after adding the internal nodes +    Counter = 0; +    Dec_GraphForEachNode( pGraph, pNode, i ) +    { +        // get the children of this node +        pNode0 = Dec_GraphNode( pGraph, pNode->eEdge0.Node ); +        pNode1 = Dec_GraphNode( pGraph, pNode->eEdge1.Node ); +        // get the AIG nodes corresponding to the children  +        pAnd0 = pNode0->pFunc;  +        pAnd1 = pNode1->pFunc;  +        if ( pAnd0 && pAnd1 ) +        { +            // if they are both present, find the resulting node +            pAnd0 = Ivy_NotCond( pAnd0, pNode->eEdge0.fCompl ); +            pAnd1 = Ivy_NotCond( pAnd1, pNode->eEdge1.fCompl ); +            pAnd  = Ivy_TableLookup( Ivy_ObjCreateGhost(pAnd0, pAnd1, IVY_AND, IVY_INIT_NONE) ); +            // return -1 if the node is the same as the original root +            if ( Ivy_Regular(pAnd) == pRoot ) +                return -1; +        } +        else +            pAnd = NULL; +        // count the number of added nodes +        if ( pAnd == NULL || Ivy_ObjIsTravIdCurrent(Ivy_Regular(pAnd)) ) +        { +            if ( ++Counter > NodeMax ) +                return -1; +        } +        // count the number of new levels +        LevelNew = 1 + RWT_MAX( pNode0->Level, pNode1->Level ); +        if ( pAnd ) +        { +            if ( Ivy_Regular(pAnd) == Ivy_ObjConst1(pRoot) ) +                LevelNew = 0; +            else if ( Ivy_Regular(pAnd) == Ivy_Regular(pAnd0) ) +                LevelNew = (int)Ivy_Regular(pAnd0)->Level; +            else if ( Ivy_Regular(pAnd) == Ivy_Regular(pAnd1) ) +                LevelNew = (int)Ivy_Regular(pAnd1)->Level; +            LevelOld = (int)Ivy_Regular(pAnd)->Level; +//            assert( LevelNew == LevelOld ); +        } +        if ( LevelNew > LevelMax ) +            return -1; +        pNode->pFunc = pAnd; +        pNode->Level = LevelNew; +    } +    return Counter; +} + +/**Function************************************************************* + +  Synopsis    [Transforms the decomposition graph into the AIG.] + +  Description [AIG nodes for the fanins should be assigned to pNode->pFunc +  of the leaves of the graph before calling this procedure.] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Ivy_Obj_t * Ivy_GraphToNetwork( Ivy_Man_t * pMan, Dec_Graph_t * pGraph ) +{ +    Ivy_Obj_t * pAnd0, * pAnd1; +    Dec_Node_t * pNode; +    int i; +    // check for constant function +    if ( Dec_GraphIsConst(pGraph) ) +        return Ivy_NotCond( Ivy_ManConst1(pMan), Dec_GraphIsComplement(pGraph) ); +    // check for a literal +    if ( Dec_GraphIsVar(pGraph) ) +        return Ivy_NotCond( Dec_GraphVar(pGraph)->pFunc, Dec_GraphIsComplement(pGraph) ); +    // build the AIG nodes corresponding to the AND gates of the graph +    Dec_GraphForEachNode( pGraph, pNode, i ) +    { +        pAnd0 = Ivy_NotCond( Dec_GraphNode(pGraph, pNode->eEdge0.Node)->pFunc, pNode->eEdge0.fCompl );  +        pAnd1 = Ivy_NotCond( Dec_GraphNode(pGraph, pNode->eEdge1.Node)->pFunc, pNode->eEdge1.fCompl );  +        pNode->pFunc = Ivy_And( pAnd0, pAnd1 ); +    } +    // complement the result if necessary +    return Ivy_NotCond( pNode->pFunc, Dec_GraphIsComplement(pGraph) ); +} + +/**Function************************************************************* + +  Synopsis    [Replaces MFFC of the node by the new factored form.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ivy_GraphUpdateNetwork( Ivy_Obj_t * pRoot, Dec_Graph_t * pGraph, int fUpdateLevel, int nGain ) +{ +    Ivy_Obj_t * pRootNew; +    int nNodesNew, nNodesOld; +    nNodesOld = Ivy_ManNodeNum(Ivy_ObjMan(pRoot)); +    // create the new structure of nodes +    pRootNew = Ivy_GraphToNetwork( Ivy_ObjMan(pRoot), pGraph ); +    // remove the old nodes +//    Ivy_AigReplace( pMan->pManFunc, pRoot, pRootNew, fUpdateLevel ); +    Ivy_ObjReplace( pRoot, pRootNew, 1, 0 ); +    // compare the gains +    nNodesNew = Ivy_ManNodeNum(Ivy_ObjMan(pRoot)); +    assert( nGain <= nNodesOld - nNodesNew ); +} + + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/temp/ivy/ivyUtil.c b/src/temp/ivy/ivyUtil.c index 590affd7..3d1ac335 100644 --- a/src/temp/ivy/ivyUtil.c +++ b/src/temp/ivy/ivyUtil.c @@ -362,6 +362,222 @@ Vec_Int_t * Ivy_ManLatches( Ivy_Man_t * p )      return vLatches;  } +/**Function************************************************************* + +  Synopsis    [Collect the latches.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ivy_ManReadLevels( Ivy_Man_t * p ) +{ +    Ivy_Obj_t * pObj; +    int i, LevelMax = 0; +    Ivy_ManForEachPo( p, pObj, i ) +    { +        pObj = Ivy_ObjFanin0(pObj); +        LevelMax = IVY_MAX( LevelMax, (int)pObj->Level ); +    } +    return LevelMax; +} + +/**Function************************************************************* + +  Synopsis    [Returns the real fanin.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Ivy_Obj_t * Ivy_ObjReal( Ivy_Obj_t * pObj ) +{ +    Ivy_Obj_t * pFanin; +    if ( !Ivy_ObjIsBuf( Ivy_Regular(pObj) ) ) +        return pObj; +    pFanin = Ivy_ObjReal( Ivy_ObjChild0(Ivy_Regular(pObj)) ); +    return Ivy_NotCond( pFanin, Ivy_IsComplement(pObj) ); +} + + + +/**Function************************************************************* + +  Synopsis    [Checks if the cube has exactly one 1.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Ivy_TruthHasOneOne( unsigned uCube ) +{ +    return (uCube & (uCube - 1)) == 0; +} + +/**Function************************************************************* + +  Synopsis    [Checks if two cubes are distance-1.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Ivy_TruthCubesDist1( unsigned uCube1, unsigned uCube2 ) +{ +    unsigned uTemp = uCube1 | uCube2; +    return Ivy_TruthHasOneOne( (uTemp >> 1) & uTemp & 0x55555555 ); +} + +/**Function************************************************************* + +  Synopsis    [Checks if two cubes differ in only one literal.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Ivy_TruthCubesDiff1( unsigned uCube1, unsigned uCube2 ) +{ +    unsigned uTemp = uCube1 ^ uCube2; +    return Ivy_TruthHasOneOne( ((uTemp >> 1) | uTemp) & 0x55555555 ); +} + +/**Function************************************************************* + +  Synopsis    [Combines two distance 1 cubes.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline unsigned Ivy_TruthCubesMerge( unsigned uCube1, unsigned uCube2 ) +{ +    unsigned uTemp; +    uTemp = uCube1 | uCube2; +    uTemp &= (uTemp >> 1) & 0x55555555; +    assert( Ivy_TruthHasOneOne(uTemp) ); +    uTemp |= (uTemp << 1); +    return (uCube1 | uCube2) ^ uTemp; +} + +/**Function************************************************************* + +  Synopsis    [Estimates the number of AIG nodes in the truth table.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Ivy_TruthEstimateNodes( unsigned * pTruth, int nVars ) +{ +    static unsigned short uResult[256]; +    static unsigned short uCover[81*81]; +    static char pVarCount[81*81]; +    int nMints, uCube, uCubeNew, i, k, c, nCubes, nRes, Counter; +    assert( nVars <= 8 ); +    // create the cover +    nCubes = 0; +    nMints = (1 << nVars); +    for ( i = 0; i < nMints; i++ ) +        if ( pTruth[i/32] & (1 << (i & 31)) ) +        { +            uCube = 0; +            for ( k = 0; k < nVars; k++ ) +                if ( i & (1 << k) ) +                    uCube |= (1 << ((k<<1)+1)); +                else +                    uCube |= (1 << ((k<<1)+0)); +            uCover[nCubes] = uCube; +            pVarCount[nCubes] = nVars; +            nCubes++; +//            Extra_PrintBinary( stdout, &uCube, 8 ); printf( "\n" ); +        } +    assert( nCubes <= 256 ); +    // reduce the cover by building larger cubes +    for ( i = 1; i < nCubes; i++ ) +        for ( k = 0; k < i; k++ ) +            if ( pVarCount[i] && pVarCount[i] == pVarCount[k] && Ivy_TruthCubesDist1(uCover[i], uCover[k]) ) +            { +                uCubeNew = Ivy_TruthCubesMerge(uCover[i], uCover[k]); +                for ( c = i; c < nCubes; c++ ) +                    if ( uCubeNew == uCover[c] ) +                        break; +                if ( c != nCubes ) +                    continue; +                uCover[nCubes] = uCubeNew; +                pVarCount[nCubes] = pVarCount[i] - 1; +                nCubes++; +                assert( nCubes < 81*81 ); +//                Extra_PrintBinary( stdout, &uCubeNew, 8 ); printf( "\n" ); +//                c = c; +            } +    // compact the cover +    nRes = 0; +    for ( i = nCubes -1; i >= 0; i-- ) +    { +        for ( k = 0; k < nRes; k++ ) +            if ( (uCover[i] & uResult[k]) == uResult[k] ) +                break; +        if ( k != nRes ) +            continue; +        uResult[nRes++] = uCover[i]; +    } +    // count the number of literals +    Counter = 0; +    for ( i = 0; i < nRes; i++ ) +    { +        for ( k = 0; k < nVars; k++ ) +            if ( uResult[i] & (3 << (k<<1)) ) +                Counter++; +    } +    return Counter; +} + +/**Function************************************************************* + +  Synopsis    [Tests the cover procedure.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Ivy_TruthEstimateNodesTest() +{ +    unsigned uTruth[8]; +    int i; +    for ( i = 0; i < 8; i++ ) +        uTruth[i] = ~(unsigned)0; +    uTruth[3] ^= (1 << 13); +//    uTruth[4] = 0xFFFFF; +//    uTruth[0] = 0xFF; +//    uTruth[0] ^= (1 << 3); +    printf( "Number = %d.\n", Ivy_TruthEstimateNodes(uTruth, 8) ); +} +  ////////////////////////////////////////////////////////////////////////  ///                       END OF FILE                                ///  //////////////////////////////////////////////////////////////////////// diff --git a/src/temp/ivy/module.make b/src/temp/ivy/module.make index beadb8b9..f697910b 100644 --- a/src/temp/ivy/module.make +++ b/src/temp/ivy/module.make @@ -8,7 +8,8 @@ SRC +=    src/temp/ivy/ivyBalance.c \      src/temp/ivy/ivyMulti.c \      src/temp/ivy/ivyObj.c \      src/temp/ivy/ivyOper.c \ -    src/temp/ivy/ivyRewrite.c \ +    src/temp/ivy/ivyResyn.c \ +    src/temp/ivy/ivyRwrPre.c \      src/temp/ivy/ivySeq.c \      src/temp/ivy/ivyTable.c \      src/temp/ivy/ivyUndo.c \ diff --git a/src/temp/mem/mem.c b/src/temp/mem/mem.c new file mode 100644 index 00000000..26d6485d --- /dev/null +++ b/src/temp/mem/mem.c @@ -0,0 +1,560 @@ +/**CFile**************************************************************** + +  FileName    [esopMem.c] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [Cover manipulation package.] + +  Synopsis    [Memory managers.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - June 20, 2005.] + +  Revision    [$Id: esopMem.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <assert.h> +#include "mem.h" + +//////////////////////////////////////////////////////////////////////// +///                        DECLARATIONS                              /// +//////////////////////////////////////////////////////////////////////// + +struct Mem_Fixed_t_ +{ +    // information about individual entries +    int           nEntrySize;    // the size of one entry +    int           nEntriesAlloc; // the total number of entries allocated +    int           nEntriesUsed;  // the number of entries in use +    int           nEntriesMax;   // the max number of entries in use +    char *        pEntriesFree;  // the linked list of free entries + +    // this is where the memory is stored +    int           nChunkSize;    // the size of one chunk +    int           nChunksAlloc;  // the maximum number of memory chunks  +    int           nChunks;       // the current number of memory chunks  +    char **       pChunks;       // the allocated memory + +    // statistics +    int           nMemoryUsed;   // memory used in the allocated entries +    int           nMemoryAlloc;  // memory allocated +}; + +struct Mem_Flex_t_ +{ +    // information about individual entries +    int           nEntriesUsed;  // the number of entries allocated +    char *        pCurrent;      // the current pointer to free memory +    char *        pEnd;          // the first entry outside the free memory + +    // this is where the memory is stored +    int           nChunkSize;    // the size of one chunk +    int           nChunksAlloc;  // the maximum number of memory chunks  +    int           nChunks;       // the current number of memory chunks  +    char **       pChunks;       // the allocated memory + +    // statistics +    int           nMemoryUsed;   // memory used in the allocated entries +    int           nMemoryAlloc;  // memory allocated +}; + +struct Mem_Step_t_ +{ +    int             nMems;    // the number of fixed memory managers employed +    Mem_Fixed_t **  pMems;    // memory managers: 2^1 words, 2^2 words, etc +    int             nMapSize; // the size of the memory array +    Mem_Fixed_t **  pMap;     // maps the number of bytes into its memory manager +}; + +#define ALLOC(type, num)     ((type *) malloc(sizeof(type) * (num))) +#define FREE(obj)             ((obj) ? (free((char *) (obj)), (obj) = 0) : 0) +#define REALLOC(type, obj, num)    \ +        ((obj) ? ((type *) realloc((char *)(obj), sizeof(type) * (num))) : \ +         ((type *) malloc(sizeof(type) * (num)))) + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [Allocates memory pieces of fixed size.] + +  Description [The size of the chunk is computed as the minimum of +  1024 entries and 64K. Can only work with entry size at least 4 byte long.] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Mem_Fixed_t * Mem_FixedStart( int nEntrySize ) +{ +    Mem_Fixed_t * p; + +    p = ALLOC( Mem_Fixed_t, 1 ); +    memset( p, 0, sizeof(Mem_Fixed_t) ); + +    p->nEntrySize    = nEntrySize; +    p->nEntriesAlloc = 0; +    p->nEntriesUsed  = 0; +    p->pEntriesFree  = NULL; + +    if ( nEntrySize * (1 << 10) < (1<<16) ) +        p->nChunkSize = (1 << 10); +    else +        p->nChunkSize = (1<<16) / nEntrySize; +    if ( p->nChunkSize < 8 ) +        p->nChunkSize = 8; + +    p->nChunksAlloc  = 64; +    p->nChunks       = 0; +    p->pChunks       = ALLOC( char *, p->nChunksAlloc ); + +    p->nMemoryUsed   = 0; +    p->nMemoryAlloc  = 0; +    return p; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Mem_FixedStop( Mem_Fixed_t * p, int fVerbose ) +{ +    int i; +    if ( p == NULL ) +        return; +    if ( fVerbose ) +    { +        printf( "Fixed memory manager: Entry = %5d. Chunk = %5d. Chunks used = %5d.\n", +            p->nEntrySize, p->nChunkSize, p->nChunks ); +        printf( "   Entries used = %8d. Entries peak = %8d. Memory used = %8d. Memory alloc = %8d.\n", +            p->nEntriesUsed, p->nEntriesMax, p->nEntrySize * p->nEntriesUsed, p->nMemoryAlloc ); +    } +    for ( i = 0; i < p->nChunks; i++ ) +        free( p->pChunks[i] ); +    free( p->pChunks ); +    free( p ); +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +char * Mem_FixedEntryFetch( Mem_Fixed_t * p ) +{ +    char * pTemp; +    int i; + +    // check if there are still free entries +    if ( p->nEntriesUsed == p->nEntriesAlloc ) +    { // need to allocate more entries +        assert( p->pEntriesFree == NULL ); +        if ( p->nChunks == p->nChunksAlloc ) +        { +            p->nChunksAlloc *= 2; +            p->pChunks = REALLOC( char *, p->pChunks, p->nChunksAlloc );  +        } +        p->pEntriesFree = ALLOC( char, p->nEntrySize * p->nChunkSize ); +        p->nMemoryAlloc += p->nEntrySize * p->nChunkSize; +        // transform these entries into a linked list +        pTemp = p->pEntriesFree; +        for ( i = 1; i < p->nChunkSize; i++ ) +        { +            *((char **)pTemp) = pTemp + p->nEntrySize; +            pTemp += p->nEntrySize; +        } +        // set the last link +        *((char **)pTemp) = NULL; +        // add the chunk to the chunk storage +        p->pChunks[ p->nChunks++ ] = p->pEntriesFree; +        // add to the number of entries allocated +        p->nEntriesAlloc += p->nChunkSize; +    } +    // incrememt the counter of used entries +    p->nEntriesUsed++; +    if ( p->nEntriesMax < p->nEntriesUsed ) +        p->nEntriesMax = p->nEntriesUsed; +    // return the first entry in the free entry list +    pTemp = p->pEntriesFree; +    p->pEntriesFree = *((char **)pTemp); +    return pTemp; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Mem_FixedEntryRecycle( Mem_Fixed_t * p, char * pEntry ) +{ +    // decrement the counter of used entries +    p->nEntriesUsed--; +    // add the entry to the linked list of free entries +    *((char **)pEntry) = p->pEntriesFree; +    p->pEntriesFree = pEntry; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [Relocates all the memory except the first chunk.] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Mem_FixedRestart( Mem_Fixed_t * p ) +{ +    int i; +    char * pTemp; + +    // deallocate all chunks except the first one +    for ( i = 1; i < p->nChunks; i++ ) +        free( p->pChunks[i] ); +    p->nChunks = 1; +    // transform these entries into a linked list +    pTemp = p->pChunks[0]; +    for ( i = 1; i < p->nChunkSize; i++ ) +    { +        *((char **)pTemp) = pTemp + p->nEntrySize; +        pTemp += p->nEntrySize; +    } +    // set the last link +    *((char **)pTemp) = NULL; +    // set the free entry list +    p->pEntriesFree  = p->pChunks[0]; +    // set the correct statistics +    p->nMemoryAlloc  = p->nEntrySize * p->nChunkSize; +    p->nMemoryUsed   = 0; +    p->nEntriesAlloc = p->nChunkSize; +    p->nEntriesUsed  = 0; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Mem_FixedReadMemUsage( Mem_Fixed_t * p ) +{ +    return p->nMemoryAlloc; +} + + + +/**Function************************************************************* + +  Synopsis    [Allocates entries of flexible size.] + +  Description [Can only work with entry size at least 4 byte long.] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Mem_Flex_t * Mem_FlexStart() +{ +    Mem_Flex_t * p; + +    p = ALLOC( Mem_Flex_t, 1 ); +    memset( p, 0, sizeof(Mem_Flex_t) ); + +    p->nEntriesUsed  = 0; +    p->pCurrent      = NULL; +    p->pEnd          = NULL; + +    p->nChunkSize    = (1 << 12); +    p->nChunksAlloc  = 64; +    p->nChunks       = 0; +    p->pChunks       = ALLOC( char *, p->nChunksAlloc ); + +    p->nMemoryUsed   = 0; +    p->nMemoryAlloc  = 0; +    return p; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Mem_FlexStop( Mem_Flex_t * p, int fVerbose ) +{ +    int i; +    if ( p == NULL ) +        return; +    if ( fVerbose ) +    { +        printf( "Flexible memory manager: Chunk size = %d. Chunks used = %d.\n", +            p->nChunkSize, p->nChunks ); +        printf( "   Entries used = %d. Memory used = %d. Memory alloc = %d.\n", +            p->nEntriesUsed, p->nMemoryUsed, p->nMemoryAlloc ); +    } +    for ( i = 0; i < p->nChunks; i++ ) +        free( p->pChunks[i] ); +    free( p->pChunks ); +    free( p ); +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +char * Mem_FlexEntryFetch( Mem_Flex_t * p, int nBytes ) +{ +    char * pTemp; +    // check if there are still free entries +    if ( p->pCurrent == NULL || p->pCurrent + nBytes > p->pEnd ) +    { // need to allocate more entries +        if ( p->nChunks == p->nChunksAlloc ) +        { +            p->nChunksAlloc *= 2; +            p->pChunks = REALLOC( char *, p->pChunks, p->nChunksAlloc );  +        } +        if ( nBytes > p->nChunkSize ) +        { +            // resize the chunk size if more memory is requested than it can give +            // (ideally, this should never happen) +            p->nChunkSize = 2 * nBytes; +        } +        p->pCurrent = ALLOC( char, p->nChunkSize ); +        p->pEnd     = p->pCurrent + p->nChunkSize; +        p->nMemoryAlloc += p->nChunkSize; +        // add the chunk to the chunk storage +        p->pChunks[ p->nChunks++ ] = p->pCurrent; +    } +    assert( p->pCurrent + nBytes <= p->pEnd ); +    // increment the counter of used entries +    p->nEntriesUsed++; +    // keep track of the memory used +    p->nMemoryUsed += nBytes; +    // return the next entry +    pTemp = p->pCurrent; +    p->pCurrent += nBytes; +    return pTemp; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Mem_FlexReadMemUsage( Mem_Flex_t * p ) +{ +    return p->nMemoryAlloc; +} + + + + + +/**Function************************************************************* + +  Synopsis    [Starts the hierarchical memory manager.] + +  Description [This manager can allocate entries of any size. +  Iternally they are mapped into the entries with the number of bytes +  equal to the power of 2. The smallest entry size is 8 bytes. The +  next one is 16 bytes etc. So, if the user requests 6 bytes, he gets  +  8 byte entry. If we asks for 25 bytes, he gets 32 byte entry etc. +  The input parameters "nSteps" says how many fixed memory managers +  are employed internally. Calling this procedure with nSteps equal +  to 10 results in 10 hierarchically arranged internal memory managers,  +  which can allocate up to 4096 (1Kb) entries. Requests for larger  +  entries are handed over to malloc() and then free()ed.] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Mem_Step_t * Mem_StepStart( int nSteps ) +{ +    Mem_Step_t * p; +    int i, k; +    p = ALLOC( Mem_Step_t, 1 ); +    memset( p, 0, sizeof(Mem_Step_t) ); +    p->nMems = nSteps; +    // start the fixed memory managers +    p->pMems = ALLOC( Mem_Fixed_t *, p->nMems ); +    for ( i = 0; i < p->nMems; i++ ) +        p->pMems[i] = Mem_FixedStart( (8<<i) ); +    // set up the mapping of the required memory size into the corresponding manager +    p->nMapSize = (4<<p->nMems); +    p->pMap = ALLOC( Mem_Fixed_t *, p->nMapSize+1 ); +    p->pMap[0] = NULL; +    for ( k = 1; k <= 4; k++ ) +        p->pMap[k] = p->pMems[0]; +    for ( i = 0; i < p->nMems; i++ ) +        for ( k = (4<<i)+1; k <= (8<<i); k++ ) +            p->pMap[k] = p->pMems[i]; +//for ( i = 1; i < 100; i ++ ) +//printf( "%10d: size = %10d\n", i, p->pMap[i]->nEntrySize ); +    return p; +} + +/**Function************************************************************* + +  Synopsis    [Stops the memory manager.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Mem_StepStop( Mem_Step_t * p, int fVerbose ) +{ +    int i; +    for ( i = 0; i < p->nMems; i++ ) +        Mem_FixedStop( p->pMems[i], fVerbose ); +//    if ( p->pLargeChunks )  +//    { +//      for ( i = 0; i < p->nLargeChunks; i++ ) +//          free( p->pLargeChunks[i] ); +//      free( p->pLargeChunks ); +//    } +    free( p->pMems ); +    free( p->pMap ); +    free( p ); +} + +/**Function************************************************************* + +  Synopsis    [Creates the entry.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +char * Mem_StepEntryFetch( Mem_Step_t * p, int nBytes ) +{ +    if ( nBytes == 0 ) +        return NULL; +    if ( nBytes > p->nMapSize ) +    { +//        printf( "Allocating %d bytes.\n", nBytes ); +/* +        if ( p->nLargeChunks == p->nLargeChunksAlloc ) +        { +            if ( p->nLargeChunksAlloc == 0 ) +                p->nLargeChunksAlloc = 5; +            p->nLargeChunksAlloc *= 2; +            p->pLargeChunks = REALLOC( char *, p->pLargeChunks, p->nLargeChunksAlloc );  +        } +        p->pLargeChunks[ p->nLargeChunks++ ] = ALLOC( char, nBytes ); +        return p->pLargeChunks[ p->nLargeChunks - 1 ]; +*/ +        return ALLOC( char, nBytes ); +    } +    return Mem_FixedEntryFetch( p->pMap[nBytes] ); +} + + +/**Function************************************************************* + +  Synopsis    [Recycles the entry.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Mem_StepEntryRecycle( Mem_Step_t * p, char * pEntry, int nBytes ) +{ +    if ( nBytes == 0 ) +        return; +    if ( nBytes > p->nMapSize ) +    { +        free( pEntry ); +        return; +    } +    Mem_FixedEntryRecycle( p->pMap[nBytes], pEntry ); +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Mem_StepReadMemUsage( Mem_Step_t * p ) +{ +    int i, nMemTotal = 0; +    for ( i = 0; i < p->nMems; i++ ) +        nMemTotal += p->pMems[i]->nMemoryAlloc; +    return nMemTotal; +} + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// diff --git a/src/temp/mem/mem.h b/src/temp/mem/mem.h new file mode 100644 index 00000000..21296d99 --- /dev/null +++ b/src/temp/mem/mem.h @@ -0,0 +1,70 @@ +/**CFile**************************************************************** + +  FileName    [mem.h] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [Memory management.] + +  Synopsis    [External declarations.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - June 20, 2005.] + +  Revision    [$Id: mem.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#ifndef __MEM_H__ +#define __MEM_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +//////////////////////////////////////////////////////////////////////// +///                        DECLARATIONS                              /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Mem_Fixed_t_    Mem_Fixed_t;     +typedef struct Mem_Flex_t_     Mem_Flex_t;      +typedef struct Mem_Step_t_     Mem_Step_t;      + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// +  +/*=== mem.c ===========================================================*/ +// fixed-size-block memory manager +extern Mem_Fixed_t * Mem_FixedStart( int nEntrySize ); +extern void          Mem_FixedStop( Mem_Fixed_t * p, int fVerbose ); +extern char *        Mem_FixedEntryFetch( Mem_Fixed_t * p ); +extern void          Mem_FixedEntryRecycle( Mem_Fixed_t * p, char * pEntry ); +extern void          Mem_FixedRestart( Mem_Fixed_t * p ); +extern int           Mem_FixedReadMemUsage( Mem_Fixed_t * p ); +// flexible-size-block memory manager +extern Mem_Flex_t *  Mem_FlexStart(); +extern void          Mem_FlexStop( Mem_Flex_t * p, int fVerbose ); +extern char *        Mem_FlexEntryFetch( Mem_Flex_t * p, int nBytes ); +extern int           Mem_FlexReadMemUsage( Mem_Flex_t * p ); +// hierarchical memory manager +extern Mem_Step_t *  Mem_StepStart( int nSteps ); +extern void          Mem_StepStop( Mem_Step_t * p, int fVerbose ); +extern char *        Mem_StepEntryFetch( Mem_Step_t * p, int nBytes ); +extern void          Mem_StepEntryRecycle( Mem_Step_t * p, char * pEntry, int nBytes ); +extern int           Mem_StepReadMemUsage( Mem_Step_t * p ); + +#ifdef __cplusplus +} +#endif + +#endif + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/temp/mem/module.make b/src/temp/mem/module.make new file mode 100644 index 00000000..5e4d1d6a --- /dev/null +++ b/src/temp/mem/module.make @@ -0,0 +1 @@ +SRC +=    src/temp/mem/mem.c  diff --git a/src/temp/player/player.h b/src/temp/player/player.h index 9ecad35b..cf0e8e01 100644 --- a/src/temp/player/player.h +++ b/src/temp/player/player.h @@ -40,8 +40,8 @@ typedef struct Pla_Obj_t_  Pla_Obj_t;  struct Pla_Obj_t_  {      unsigned          fFixed :  1;  // fixed node -    unsigned          Depth  :  7;  // the depth in terms of LUTs/PLAs -    unsigned          nRefs  : 24;  // the number of references +    unsigned          Depth  : 31;  // the depth in terms of LUTs/PLAs +    int               nRefs;        // the number of references      Vec_Int_t         vSupp[2];     // supports in two frames      Esop_Cube_t *     pCover[2];    // esops in two frames  }; diff --git a/src/temp/player/playerAbc.c b/src/temp/player/playerAbc.c index 9cc342d9..24273ffe 100644 --- a/src/temp/player/playerAbc.c +++ b/src/temp/player/playerAbc.c @@ -45,8 +45,10 @@ static Abc_Ntk_t * Ivy_ManToAbc( Abc_Ntk_t * pNtkOld, Ivy_Man_t * p );  ***********************************************************************/  void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int fVerbose )  { +    int fUseRewriting = 1;      Ivy_Man_t * pMan, * pManExt;      Abc_Ntk_t * pNtkAig; +      if ( !Abc_NtkIsStrash(pNtk) )          return NULL;      // convert to the new AIG manager @@ -60,6 +62,14 @@ void * Abc_NtkPlayer( void * pNtk, int nLutMax, int nPlaMax, int fVerbose )      }      if ( fVerbose )          Ivy_ManPrintStats( pMan ); +    if ( fUseRewriting ) +    { +        // simplify +        pMan = Ivy_ManResyn( pManExt = pMan, 1 ); +        Ivy_ManStop( pManExt ); +        if ( fVerbose ) +            Ivy_ManPrintStats( pMan ); +    }      // perform decomposition/mapping into PLAs/LUTs      pManExt = Pla_ManDecompose( pMan, nLutMax, nPlaMax, fVerbose );      Ivy_ManStop( pMan ); @@ -150,10 +160,10 @@ Abc_Ntk_t * Ivy_ManToAbc( Abc_Ntk_t * pNtkOld, Ivy_Man_t * pMan )          pObjNew = Abc_NtkCreateNode( pNtkNew );          Vec_IntForEachEntry( vIvyFanins, Fanin, k )          { -            pIvyFanin = Ivy_ObjObj( pIvyNode, Ivy_FanId(Fanin) ); +            pIvyFanin = Ivy_ObjObj( pIvyNode, Ivy_EdgeId(Fanin) );              pFaninNew = Abc_NtkObj( pNtkNew, pIvyFanin->TravId );              Abc_ObjAddFanin( pObjNew, pFaninNew ); -            pCompls[k] = Ivy_FanCompl(Fanin); +            pCompls[k] = Ivy_EdgeIsComplement(Fanin);              assert( Ivy_ObjIsAndMulti(pIvyNode) || nFanins == 1 || pCompls[k] == 0 ); // EXOR/LUT cannot have complemented fanins          }          assert( k <= PLAYER_FANIN_LIMIT ); @@ -176,10 +186,10 @@ Abc_Ntk_t * Ivy_ManToAbc( Abc_Ntk_t * pNtkOld, Ivy_Man_t * pMan )          // get the old fanin of the PO node          vIvyFanins = Ivy_ObjGetFanins( Ivy_ManPo(pMan, i) );          Fanin     = Vec_IntEntry( vIvyFanins, 0 ); -        pIvyFanin = Ivy_ManObj( pMan, Ivy_FanId(Fanin) ); +        pIvyFanin = Ivy_ManObj( pMan, Ivy_EdgeId(Fanin) );          // get the new ABC node corresponding to the old fanin          pFaninNew = Abc_NtkObj( pNtkNew, pIvyFanin->TravId ); -        if ( Ivy_FanCompl(Fanin) ) // complement +        if ( Ivy_EdgeIsComplement(Fanin) ) // complement          {  //            pFaninNew = Abc_NodeCreateInv(pNtkNew, pFaninNew);              if ( Abc_ObjIsCi(pFaninNew) ) diff --git a/src/temp/player/playerBuild.c b/src/temp/player/playerBuild.c index a7b06f03..b23c0c16 100644 --- a/src/temp/player/playerBuild.c +++ b/src/temp/player/playerBuild.c @@ -62,7 +62,7 @@ Ivy_Man_t * Pla_ManToAig( Ivy_Man_t * pOld )      {          pObjNew = Pla_ManToAig_rec( pNew, Ivy_ObjFanin0(pObjOld) );          Ivy_ObjStartFanins( Ivy_ManPo(pNew, i), 1 ); -        Ivy_ObjAddFanin( Ivy_ManPo(pNew, i), Ivy_FanCreate(pObjNew->Id, Ivy_ObjFaninC0(pObjOld)) ); +        Ivy_ObjAddFanin( Ivy_ManPo(pNew, i), Ivy_EdgeCreate(pObjNew->Id, Ivy_ObjFaninC0(pObjOld)) );      }      // compute the LUT functions      Pla_ManToAigLutFuncs( pNew, pOld );  @@ -118,7 +118,7 @@ Ivy_Obj_t * Pla_ManToAig_rec( Ivy_Man_t * pNew, Ivy_Obj_t * pObjOld )          Vec_IntForEachEntry( vSupp, Entry, i )          {              pFaninOld = Ivy_ObjObj( pObjOld, Entry ); -            Ivy_ObjAddFanin( Ivy_ManObj(pNew, ObjNewId), Ivy_FanCreate(pFaninOld->TravId, 0) ); +            Ivy_ObjAddFanin( Ivy_ManObj(pNew, ObjNewId), Ivy_EdgeCreate(pFaninOld->TravId, 0) );          }          // get the new object          pObjNew = Ivy_ManObj(pNew, ObjNewId); @@ -140,7 +140,7 @@ Ivy_Obj_t * Pla_ManToAig_rec( Ivy_Man_t * pNew, Ivy_Obj_t * pObjOld )              Esop_CoverForEachCube( pCover, pCube )              {                  pFaninNew = Ivy_ManToAigCube( pNew, pObjOld, pCube, vSupp ); -                Ivy_ObjAddFanin( Ivy_ManObj(pNew, ObjNewId), Ivy_FanCreate(pFaninNew->Id, 0) ); +                Ivy_ObjAddFanin( Ivy_ManObj(pNew, ObjNewId), Ivy_EdgeCreate(pFaninNew->Id, 0) );              }              // get the new object              pObjNew = Ivy_ManObj(pNew, ObjNewId); @@ -168,7 +168,7 @@ Ivy_Obj_t * Ivy_ManToAigConst( Ivy_Man_t * pNew, int fConst1 )      Ivy_Obj_t * pObjNew;      pObjNew = Ivy_ObjCreateExt( pNew, IVY_ANDM );      Ivy_ObjStartFanins( pObjNew, 1 ); -    Ivy_ObjAddFanin( pObjNew, Ivy_FanCreate(0, !fConst1) ); +    Ivy_ObjAddFanin( pObjNew, Ivy_EdgeCreate(0, !fConst1) );      return pObjNew;  } @@ -201,7 +201,7 @@ Ivy_Obj_t * Ivy_ManToAigCube( Ivy_Man_t * pNew, Ivy_Obj_t * pObjOld, Esop_Cube_t          if ( Value == 3 )              continue;          pFaninOld = Ivy_ObjObj( pObjOld, Vec_IntEntry(vSupp, i) ); -        Ivy_ObjAddFanin( pObjNew, Ivy_FanCreate( pFaninOld->TravId, Value==1 ) ); +        Ivy_ObjAddFanin( pObjNew, Ivy_EdgeCreate( pFaninOld->TravId, Value==1 ) );      }      assert( Ivy_ObjFaninNum(pObjNew) == (int)pCube->nLits );      return pObjNew; @@ -262,7 +262,7 @@ int Pla_ManToAigLutFuncs( Ivy_Man_t * pNew, Ivy_Man_t * pOld )              // point it to the constant 1 node              vFanins = Ivy_ObjGetFanins( pObjNew );              Vec_IntClear( vFanins ); -            Vec_IntPush( vFanins, Ivy_FanCreate(0, 1) ); +            Vec_IntPush( vFanins, Ivy_EdgeCreate(0, 1) );          }          memcpy( pTruth, pComputed, sizeof(unsigned) * 8 );  //        Extra_PrintBinary( stdout, pTruth, 16 ); printf( "\n" ); diff --git a/src/temp/player/playerCore.c b/src/temp/player/playerCore.c index 3cd3d8a8..258a3336 100644 --- a/src/temp/player/playerCore.c +++ b/src/temp/player/playerCore.c @@ -221,6 +221,7 @@ int Pla_ManDecomposeNode( Pla_Man_t * p, Ivy_Obj_t * pObj )          if ( pStr1->fFixed == 0 )  Pla_ManCountDecNodes( p, pStr1 );          pStr1->fFixed = 1;      } +    assert( pStr->Depth );      // free some of the covers to save memory      assert( pStr0->nRefs > 0 ); diff --git a/src/temp/player/playerUtil.c b/src/temp/player/playerUtil.c index 1b361839..ced2d6b7 100644 --- a/src/temp/player/playerUtil.c +++ b/src/temp/player/playerUtil.c @@ -309,7 +309,7 @@ void Pla_ManComputeStats( Ivy_Man_t * p, Vec_Int_t * vNodes )          vFanins = Ivy_ObjGetFanins( pObj );          Vec_IntForEachEntry( vFanins, Fanin, k )          { -            pFanin = Ivy_ManObj(p, Ivy_FanId(Fanin)); +            pFanin = Ivy_ManObj(p, Ivy_EdgeId(Fanin));              pObj->Level = IVY_MAX( pObj->Level, pFanin->Level );          }          pObj->Level += 1; @@ -335,7 +335,7 @@ void Pla_ManComputeStats( Ivy_Man_t * p, Vec_Int_t * vNodes )      Ivy_ManForEachPo( p, pObj, i )      {          Fanin = Ivy_ObjReadFanin(pObj, 0); -        pFanin = Ivy_ManObj( p, Ivy_FanId(Fanin) ); +        pFanin = Ivy_ManObj( p, Ivy_EdgeId(Fanin) );          pObj->Level = pFanin->Level;          Delay = IVY_MAX( Delay, (int)pObj->Level );      } diff --git a/src/temp/rwt/module.make b/src/temp/rwt/module.make new file mode 100644 index 00000000..8bbde36d --- /dev/null +++ b/src/temp/rwt/module.make @@ -0,0 +1,3 @@ +SRC +=  src/temp/rwt/rwtDec.c \ +    src/temp/rwt/rwtMan.c \ +    src/temp/rwt/rwtUtil.c diff --git a/src/temp/rwt/rwt.h b/src/temp/rwt/rwt.h new file mode 100644 index 00000000..f9c4dc51 --- /dev/null +++ b/src/temp/rwt/rwt.h @@ -0,0 +1,153 @@ +/**CFile**************************************************************** + +  FileName    [rwt.h] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [DAG-aware AIG rewriting package.] + +  Synopsis    [External declarations.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - June 20, 2005.] + +  Revision    [$Id: rwt.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ +  +#ifndef __RWT_H__ +#define __RWT_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +//////////////////////////////////////////////////////////////////////// +///                          INCLUDES                                /// +//////////////////////////////////////////////////////////////////////// + +#include "mem.h" +#include "vec.h" + +//////////////////////////////////////////////////////////////////////// +///                         PARAMETERS                               /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +///                         BASIC TYPES                              /// +//////////////////////////////////////////////////////////////////////// +  +#define RWT_LIMIT  1048576/4  // ((1 << 20)  +#define RWT_MIN(a,b)      (((a) < (b))? (a) : (b)) +#define RWT_MAX(a,b)      (((a) > (b))? (a) : (b)) + +typedef struct Rwt_Man_t_   Rwt_Man_t; +typedef struct Rwt_Node_t_  Rwt_Node_t; + +struct Rwt_Man_t_ +{ +    // internal lookups +    int                nFuncs;           // number of four var functions +    unsigned short *   puCanons;         // canonical forms +    char *             pPhases;          // canonical phases +    char *             pPerms;           // canonical permutations +    unsigned char *    pMap;             // mapping of functions into class numbers +    unsigned short *   pMapInv;          // mapping of classes into functions +    char *             pPractical;       // practical NPN classes +    char **            pPerms4;          // four-var permutations +    // node space +    Vec_Ptr_t *        vForest;          // all the nodes +    Rwt_Node_t **      pTable;           // the hash table of nodes by their canonical form +    Vec_Vec_t *        vClasses;         // the nodes of the equivalence classes +    Mem_Fixed_t *      pMmNode;          // memory for nodes and cuts +    // statistical variables +    int                nTravIds;         // the counter of traversal IDs +    int                nConsidered;      // the number of nodes considered +    int                nAdded;           // the number of nodes added to lists +    int                nClasses;         // the number of NN classes +    // the result of resynthesis +    int                fCompl;           // indicates if the output of FF should be complemented +    void *             pGraph;           // the decomposition tree (temporary) +    Vec_Ptr_t *        vFanins;          // the fanins array (temporary) +    Vec_Ptr_t *        vFaninsCur;       // the fanins array (temporary) +    Vec_Int_t *        vLevNums;         // the array of levels (temporary) +    Vec_Ptr_t *        vNodesTemp;       // the nodes in MFFC (temporary) +    // node statistics +    int                nNodesConsidered; +    int                nNodesRewritten; +    int                nNodesGained; +    int                nScores[222]; +    int                nCutsGood; +    int                nCutsBad; +    int                nSubgraphs; +    // runtime statistics +    int                timeStart; +    int                timeTruth; +    int                timeCut; +    int                timeRes; +    int                timeEval; +    int                timeMffc; +    int                timeUpdate; +    int                timeTotal; +}; + +struct Rwt_Node_t_ // 24 bytes +{ +    int                Id;               // ID  +    int                TravId;           // traversal ID +    unsigned           uTruth : 16;      // truth table +    unsigned           Volume :  8;      // volume +    unsigned           Level  :  6;      // level +    unsigned           fUsed  :  1;      // mark +    unsigned           fExor  :  1;      // mark +    Rwt_Node_t *       p0;               // first child +    Rwt_Node_t *       p1;               // second child +    Rwt_Node_t *       pNext;            // next in the table +}; + +// manipulation of complemented attributes +static inline int          Rwt_IsComplement( Rwt_Node_t * p )    { return (int)(((unsigned)p) & 01);            } +static inline Rwt_Node_t * Rwt_Regular( Rwt_Node_t * p )         { return (Rwt_Node_t *)((unsigned)(p) & ~01);  } +static inline Rwt_Node_t * Rwt_Not( Rwt_Node_t * p )             { return (Rwt_Node_t *)((unsigned)(p) ^  01);  } +static inline Rwt_Node_t * Rwt_NotCond( Rwt_Node_t * p, int c )  { return (Rwt_Node_t *)((unsigned)(p) ^ (c));  } + +//////////////////////////////////////////////////////////////////////// +///                      MACRO DEFINITIONS                           /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +///                    FUNCTION DECLARATIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/*=== rwrDec.c ========================================================*/ +extern void              Rwt_ManPreprocess( Rwt_Man_t * p ); +/*=== rwrMan.c ========================================================*/ +extern Rwt_Man_t *       Rwt_ManStart( int fPrecompute ); +extern void              Rwt_ManStop( Rwt_Man_t * p ); +extern void              Rwt_ManPrintStats( Rwt_Man_t * p ); +extern void              Rwt_ManPrintStatsFile( Rwt_Man_t * p ); +extern void *            Rwt_ManReadDecs( Rwt_Man_t * p ); +extern Vec_Ptr_t *       Rwt_ManReadLeaves( Rwt_Man_t * p ); +extern int               Rwt_ManReadCompl( Rwt_Man_t * p ); +extern void              Rwt_ManAddTimeCuts( Rwt_Man_t * p, int Time ); +extern void              Rwt_ManAddTimeUpdate( Rwt_Man_t * p, int Time ); +extern void              Rwt_ManAddTimeTotal( Rwt_Man_t * p, int Time ); +/*=== rwrUtil.c ========================================================*/ +extern void              Rwt_ManLoadFromArray( Rwt_Man_t * p, int fVerbose ); +extern char *            Rwt_ManGetPractical( Rwt_Man_t * p ); +extern Rwt_Node_t *      Rwt_ManAddVar( Rwt_Man_t * p, unsigned uTruth, int fPrecompute ); +extern void              Rwt_ManIncTravId( Rwt_Man_t * p ); + +#ifdef __cplusplus +} +#endif + +#endif + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + diff --git a/src/temp/rwt/rwtDec.c b/src/temp/rwt/rwtDec.c new file mode 100644 index 00000000..98019629 --- /dev/null +++ b/src/temp/rwt/rwtDec.c @@ -0,0 +1,150 @@ +/**CFile**************************************************************** + +  FileName    [rwtDec.c] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [DAG-aware AIG rewriting package.] + +  Synopsis    [Evaluation and decomposition procedures.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - June 20, 2005.] + +  Revision    [$Id: rwtDec.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "rwt.h" +#include "deco.h" + +//////////////////////////////////////////////////////////////////////// +///                        DECLARATIONS                              /// +//////////////////////////////////////////////////////////////////////// + +static Dec_Graph_t * Rwt_NodePreprocess( Rwt_Man_t * p, Rwt_Node_t * pNode ); +static Dec_Edge_t    Rwt_TravCollect_rec( Rwt_Man_t * p, Rwt_Node_t * pNode, Dec_Graph_t * pGraph ); + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [Preprocesses computed library of subgraphs.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Rwt_ManPreprocess( Rwt_Man_t * p ) +{ +    Dec_Graph_t * pGraph; +    Rwt_Node_t * pNode; +    int i, k; +    // put the nodes into the structure +    p->pMapInv  = ALLOC( unsigned short, 222 ); +    memset( p->pMapInv, 0, sizeof(unsigned short) * 222 ); +    p->vClasses = Vec_VecStart( 222 ); +    for ( i = 0; i < p->nFuncs; i++ ) +    { +        if ( p->pTable[i] == NULL ) +            continue; +        // consider all implementations of this function +        for ( pNode = p->pTable[i]; pNode; pNode = pNode->pNext ) +        { +            assert( pNode->uTruth == p->pTable[i]->uTruth ); +            assert( p->pMap[pNode->uTruth] >= 0 && p->pMap[pNode->uTruth] < 222 ); +            Vec_VecPush( p->vClasses, p->pMap[pNode->uTruth], pNode ); +            p->pMapInv[ p->pMap[pNode->uTruth] ] = p->puCanons[pNode->uTruth]; +        } +    } +    // compute decomposition forms for each node and verify them +    Vec_VecForEachEntry( p->vClasses, pNode, i, k ) +    { +        pGraph = Rwt_NodePreprocess( p, pNode ); +        pNode->pNext = (Rwt_Node_t *)pGraph; +//        assert( pNode->uTruth == (Dec_GraphDeriveTruth(pGraph) & 0xFFFF) ); +    } +} + +/**Function************************************************************* + +  Synopsis    [Preprocesses subgraphs rooted at this node.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Dec_Graph_t * Rwt_NodePreprocess( Rwt_Man_t * p, Rwt_Node_t * pNode ) +{ +    Dec_Graph_t * pGraph; +    Dec_Edge_t eRoot; +    assert( !Rwt_IsComplement(pNode) ); +    // consider constant +    if ( pNode->uTruth == 0 ) +        return Dec_GraphCreateConst0(); +    // consider the case of elementary var +    if ( pNode->uTruth == 0x00FF ) +        return Dec_GraphCreateLeaf( 3, 4, 1 ); +    // start the subgraphs +    pGraph = Dec_GraphCreate( 4 ); +    // collect the nodes +    Rwt_ManIncTravId( p ); +    eRoot = Rwt_TravCollect_rec( p, pNode, pGraph ); +    Dec_GraphSetRoot( pGraph, eRoot ); +    return pGraph; +} + +/**Function************************************************************* + +  Synopsis    [Adds one node.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Dec_Edge_t Rwt_TravCollect_rec( Rwt_Man_t * p, Rwt_Node_t * pNode, Dec_Graph_t * pGraph ) +{ +    Dec_Edge_t eNode0, eNode1, eNode; +    // elementary variable +    if ( pNode->fUsed ) +        return Dec_EdgeCreate( pNode->Id - 1, 0 ); +    // previously visited node +    if ( pNode->TravId == p->nTravIds ) +        return Dec_IntToEdge( pNode->Volume ); +    pNode->TravId = p->nTravIds; +    // solve for children +    eNode0 = Rwt_TravCollect_rec( p, Rwt_Regular(pNode->p0), pGraph ); +    if ( Rwt_IsComplement(pNode->p0) )     +        eNode0.fCompl = !eNode0.fCompl; +    eNode1 = Rwt_TravCollect_rec( p, Rwt_Regular(pNode->p1), pGraph ); +    if ( Rwt_IsComplement(pNode->p1) )     +        eNode1.fCompl = !eNode1.fCompl; +    // create the decomposition node(s) +    if ( pNode->fExor ) +        eNode = Dec_GraphAddNodeXor( pGraph, eNode0, eNode1, 0 ); +    else +        eNode = Dec_GraphAddNodeAnd( pGraph, eNode0, eNode1 ); +    // save the result +    pNode->Volume = Dec_EdgeToInt( eNode ); +    return eNode; +} + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/temp/rwt/rwtMan.c b/src/temp/rwt/rwtMan.c new file mode 100644 index 00000000..5f077c8d --- /dev/null +++ b/src/temp/rwt/rwtMan.c @@ -0,0 +1,358 @@ +/**CFile**************************************************************** + +  FileName    [rwtMan.c] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [DAG-aware AIG rewriting package.] + +  Synopsis    [Rewriting manager.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - June 20, 2005.] + +  Revision    [$Id: rwtMan.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "rwt.h" +#include "deco.h" + +//////////////////////////////////////////////////////////////////////// +///                        DECLARATIONS                              /// +//////////////////////////////////////////////////////////////////////// + +static unsigned short * s_puCanons = NULL;  +static char *           s_pPhases = NULL;  +static char *           s_pPerms = NULL;  +static unsigned char *  s_pMap = NULL; + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [Starts residual rewriting manager.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Rwt_ManGlobalStart() +{  +    if ( s_puCanons == NULL ) +        Extra_Truth4VarNPN( &s_puCanons, &s_pPhases, &s_pPerms, &s_pMap ); +} + +/**Function************************************************************* + +  Synopsis    [Starts residual rewriting manager.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Rwt_ManGlobalStop() +{  +    if ( s_puCanons == NULL )  free( s_puCanons ); +    if ( s_pPhases == NULL )   free( s_pPhases ); +    if ( s_pPerms == NULL )    free( s_pPerms ); +    if ( s_pMap == NULL )      free( s_pMap ); +}  + +/**Function************************************************************* + +  Synopsis    [Starts rewriting manager.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Rwt_Man_t * Rwt_ManStart( int fPrecompute ) +{ +    Rwt_Man_t * p; +    int clk = clock(); +clk = clock(); +    p = ALLOC( Rwt_Man_t, 1 ); +    memset( p, 0, sizeof(Rwt_Man_t) ); +    p->nFuncs = (1<<16); +    // copy the global tables +    Rwt_ManGlobalStart(); +    p->puCanons = s_puCanons;  +    p->pPhases  = s_pPhases;  +    p->pPerms   = s_pPerms;  +    p->pMap     = s_pMap;  +    // initialize practical NPN classes +    p->pPractical  = Rwt_ManGetPractical( p ); +    // create the table +    p->pTable = ALLOC( Rwt_Node_t *, p->nFuncs ); +    memset( p->pTable, 0, sizeof(Rwt_Node_t *) * p->nFuncs ); +    // create the elementary nodes +    p->pMmNode  = Mem_FixedStart( sizeof(Rwt_Node_t) ); +    p->vForest  = Vec_PtrAlloc( 100 ); +    Rwt_ManAddVar( p, 0x0000, fPrecompute ); // constant 0 +    Rwt_ManAddVar( p, 0xAAAA, fPrecompute ); // var A +    Rwt_ManAddVar( p, 0xCCCC, fPrecompute ); // var B +    Rwt_ManAddVar( p, 0xF0F0, fPrecompute ); // var C +    Rwt_ManAddVar( p, 0xFF00, fPrecompute ); // var D +    p->nClasses = 5; +    // other stuff +    p->nTravIds   = 1; +    p->pPerms4    = Extra_Permutations( 4 ); +    p->vLevNums   = Vec_IntAlloc( 50 ); +    p->vFanins    = Vec_PtrAlloc( 50 ); +    p->vFaninsCur = Vec_PtrAlloc( 50 ); +    p->vNodesTemp = Vec_PtrAlloc( 50 ); +    if ( fPrecompute ) +    {   // precompute subgraphs +//        Rwt_ManPrecompute( p ); +//        Rwt_ManPrint( p ); +//        Rwt_ManWriteToArray( p ); +    } +    else +    {   // load saved subgraphs +        Rwt_ManLoadFromArray( p, 0 ); +//        Rwt_ManPrint( p ); +        Rwt_ManPreprocess( p ); +    } +p->timeStart = clock() - clk; +    return p; +} + +/**Function************************************************************* + +  Synopsis    [Stops rewriting manager.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Rwt_ManStop( Rwt_Man_t * p ) +{ +    if ( p->vClasses ) +    { +        Rwt_Node_t * pNode; +        int i, k; +        Vec_VecForEachEntry( p->vClasses, pNode, i, k ) +            Dec_GraphFree( (Dec_Graph_t *)pNode->pNext ); +    } +    if ( p->vClasses )  Vec_VecFree( p->vClasses ); +    Vec_PtrFree( p->vNodesTemp ); +    Vec_PtrFree( p->vForest ); +    Vec_IntFree( p->vLevNums ); +    Vec_PtrFree( p->vFanins ); +    Vec_PtrFree( p->vFaninsCur ); +    Mem_FixedStop( p->pMmNode, 0 ); +    FREE( p->pMapInv ); +    free( p->pTable ); +    free( p->pPractical ); +    free( p->pPerms4 ); +    free( p ); +} + +/**Function************************************************************* + +  Synopsis    [Stops the resynthesis manager.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Rwt_ManPrintStats( Rwt_Man_t * p ) +{ +    int i, Counter = 0; +    for ( i = 0; i < 222; i++ ) +        Counter += (p->nScores[i] > 0); + +    printf( "Rewriting statistics:\n" ); +    printf( "Total cuts tries  = %8d.\n", p->nCutsGood ); +    printf( "Bad cuts found    = %8d.\n", p->nCutsBad ); +    printf( "Total subgraphs   = %8d.\n", p->nSubgraphs ); +    printf( "Used NPN classes  = %8d.\n", Counter ); +    printf( "Nodes considered  = %8d.\n", p->nNodesConsidered ); +    printf( "Nodes rewritten   = %8d.\n", p->nNodesRewritten ); +    printf( "Calculated gain   = %8d.\n", p->nNodesGained     ); +    PRT( "Start       ", p->timeStart ); +    PRT( "Cuts        ", p->timeCut ); +    PRT( "Truth       ", p->timeTruth ); +    PRT( "Resynthesis ", p->timeRes ); +    PRT( "    Mffc    ", p->timeMffc ); +    PRT( "    Eval    ", p->timeEval ); +    PRT( "Update      ", p->timeUpdate ); +    PRT( "TOTAL       ", p->timeTotal ); + + +    printf( "The scores are:\n" ); +    for ( i = 0; i < 222; i++ ) +        if ( p->nScores[i] > 0 ) +        { +            extern void Ivy_TruthDsdComputePrint( unsigned uTruth ); +            printf( "%3d = %8d  canon = %5d  ", i, p->nScores[i], p->pMapInv[i] ); +            Ivy_TruthDsdComputePrint( (unsigned)p->pMapInv[i] | ((unsigned)p->pMapInv[i] << 16) ); +        } +    printf( "\n" ); + +} + +/**Function************************************************************* + +  Synopsis    [Stops the resynthesis manager.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Rwt_ManPrintStatsFile( Rwt_Man_t * p ) +{ +    FILE * pTable; +    pTable = fopen( "stats.txt", "a+" ); +    fprintf( pTable, "%d ", p->nCutsGood ); +    fprintf( pTable, "%d ", p->nSubgraphs ); +    fprintf( pTable, "%d ", p->nNodesRewritten ); +    fprintf( pTable, "%d", p->nNodesGained ); +    fprintf( pTable, "\n" ); +    fclose( pTable ); +} + +/**Function************************************************************* + +  Synopsis    [Stops the resynthesis manager.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void * Rwt_ManReadDecs( Rwt_Man_t * p ) +{ +    return p->pGraph; +} + +/**Function************************************************************* + +  Synopsis    [Stops the resynthesis manager.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Vec_Ptr_t * Rwt_ManReadLeaves( Rwt_Man_t * p ) +{ +    return p->vFanins; +} + +/**Function************************************************************* + +  Synopsis    [Stops the resynthesis manager.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Rwt_ManReadCompl( Rwt_Man_t * p ) +{ +    return p->fCompl; +} + +/**Function************************************************************* + +  Synopsis    [Stops the resynthesis manager.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Rwt_ManAddTimeCuts( Rwt_Man_t * p, int Time ) +{ +    p->timeCut += Time; +} + +/**Function************************************************************* + +  Synopsis    [Stops the resynthesis manager.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Rwt_ManAddTimeUpdate( Rwt_Man_t * p, int Time ) +{ +    p->timeUpdate += Time; +} + +/**Function************************************************************* + +  Synopsis    [Stops the resynthesis manager.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Rwt_ManAddTimeTotal( Rwt_Man_t * p, int Time ) +{ +    p->timeTotal += Time; +} + + +/**Function************************************************************* + +  Synopsis    [Precomputes AIG subgraphs.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Rwt_Precompute() +{ +    Rwt_Man_t * p; +    p = Rwt_ManStart( 1 ); +    Rwt_ManStop( p ); +} + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + + diff --git a/src/temp/rwt/rwtUtil.c b/src/temp/rwt/rwtUtil.c new file mode 100644 index 00000000..af3e1893 --- /dev/null +++ b/src/temp/rwt/rwtUtil.c @@ -0,0 +1,665 @@ +/**CFile**************************************************************** + +  FileName    [rwtUtil.c] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [DAG-aware AIG rewriting package.] + +  Synopsis    [Various utilities.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - June 20, 2005.] + +  Revision    [$Id: rwtUtil.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ + +#include "rwt.h" + +//////////////////////////////////////////////////////////////////////// +///                        DECLARATIONS                              /// +//////////////////////////////////////////////////////////////////////// + +// precomputed data +#ifdef _WIN32 +unsigned short s_RwtPracticalClasses[]; +unsigned short s_RwtAigSubgraphs[]; +#else +static unsigned short s_RwtPracticalClasses[]; +static unsigned short s_RwtAigSubgraphs[]; +#endif + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [Adds the node to the end of the list.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Rwt_ListAddToTail( Rwt_Node_t ** ppList, Rwt_Node_t * pNode ) +{ +    Rwt_Node_t * pTemp; +    // find the last one +    for ( pTemp = *ppList; pTemp; pTemp = pTemp->pNext ) +        ppList = &pTemp->pNext; +    // attach at the end +    *ppList = pNode; +} + +/**Function************************************************************* + +  Synopsis    [Adds one node.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Rwt_Node_t * Rwt_ManAddVar( Rwt_Man_t * p, unsigned uTruth, int fPrecompute ) +{ +    Rwt_Node_t * pNew; +    pNew = (Rwt_Node_t *)Mem_FixedEntryFetch( p->pMmNode ); +    pNew->Id     = p->vForest->nSize; +    pNew->TravId = 0; +    pNew->uTruth = uTruth; +    pNew->Level  = 0; +    pNew->Volume = 0; +    pNew->fUsed  = 1; +    pNew->fExor  = 0; +    pNew->p0     = NULL; +    pNew->p1     = NULL;     +    pNew->pNext  = NULL; +    Vec_PtrPush( p->vForest, pNew ); +    if ( fPrecompute ) +        Rwt_ListAddToTail( p->pTable + uTruth, pNew ); +    return pNew; +} + +/**Function************************************************************* + +  Synopsis    [Adds one node.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +Rwt_Node_t * Rwt_ManAddNode( Rwt_Man_t * p, Rwt_Node_t * p0, Rwt_Node_t * p1, int fExor, int Level, int Volume ) +{ +    Rwt_Node_t * pNew; +    unsigned uTruth; +    // compute truth table, leve, volume +    p->nConsidered++; +    if ( fExor ) +        uTruth = (p0->uTruth ^ p1->uTruth); +    else +        uTruth = (Rwt_IsComplement(p0)? ~Rwt_Regular(p0)->uTruth : Rwt_Regular(p0)->uTruth) &  +                 (Rwt_IsComplement(p1)? ~Rwt_Regular(p1)->uTruth : Rwt_Regular(p1)->uTruth) & 0xFFFF; +    // create the new node +    pNew = (Rwt_Node_t *)Mem_FixedEntryFetch( p->pMmNode ); +    pNew->Id     = p->vForest->nSize; +    pNew->TravId = 0; +    pNew->uTruth = uTruth; +    pNew->Level  = Level; +    pNew->Volume = Volume; +    pNew->fUsed  = 0; +    pNew->fExor  = fExor; +    pNew->p0     = p0; +    pNew->p1     = p1; +    pNew->pNext  = NULL; +    Vec_PtrPush( p->vForest, pNew ); +    // do not add if the node is not essential +    if ( uTruth != p->puCanons[uTruth] ) +        return pNew; + +    // add to the list +    p->nAdded++; +    if ( p->pTable[uTruth] == NULL ) +        p->nClasses++; +    Rwt_ListAddToTail( p->pTable + uTruth, pNew ); +    return pNew; +} + +/**Function************************************************************* + +  Synopsis    [Adds one node.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Rwt_Trav_rec( Rwt_Man_t * p, Rwt_Node_t * pNode, int * pVolume ) +{ +    if ( pNode->fUsed || pNode->TravId == p->nTravIds ) +        return; +    pNode->TravId = p->nTravIds; +    (*pVolume)++; +    if ( pNode->fExor ) +        (*pVolume)++; +    Rwt_Trav_rec( p, Rwt_Regular(pNode->p0), pVolume ); +    Rwt_Trav_rec( p, Rwt_Regular(pNode->p1), pVolume ); +} + +/**Function************************************************************* + +  Synopsis    [Adds one node.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Rwt_ManIncTravId( Rwt_Man_t * p ) +{ +    Rwt_Node_t * pNode; +    int i; +    if ( p->nTravIds++ < 0x8FFFFFFF ) +        return; +    Vec_PtrForEachEntry( p->vForest, pNode, i ) +        pNode->TravId = 0; +    p->nTravIds = 1; +} + +/**Function************************************************************* + +  Synopsis    [Adds one node.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +int Rwt_ManNodeVolume( Rwt_Man_t * p, Rwt_Node_t * p0, Rwt_Node_t * p1 ) +{ +    int Volume = 0; +    Rwt_ManIncTravId( p ); +    Rwt_Trav_rec( p, p0, &Volume ); +    Rwt_Trav_rec( p, p1, &Volume ); +    return Volume; +} + +/**Function************************************************************* + +  Synopsis    [Loads data.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +void Rwt_ManLoadFromArray( Rwt_Man_t * p, int fVerbose ) +{ +    unsigned short * pArray = s_RwtAigSubgraphs; +    Rwt_Node_t * p0, * p1; +    unsigned Entry0, Entry1; +    int Level, Volume, nEntries, fExor; +    int i, clk = clock(); + +    // reconstruct the forest +    for ( i = 0; ; i++ ) +    { +        Entry0 = pArray[2*i + 0]; +        Entry1 = pArray[2*i + 1]; +        if ( Entry0 == 0 && Entry1 == 0 ) +            break; +        // get EXOR flag +        fExor = (Entry0 & 1); +        Entry0 >>= 1; +        // get the nodes +        p0 = p->vForest->pArray[Entry0 >> 1]; +        p1 = p->vForest->pArray[Entry1 >> 1]; +        // compute the level and volume of the new nodes +        Level  = 1 + RWT_MAX( p0->Level, p1->Level ); +        Volume = 1 + Rwt_ManNodeVolume( p, p0, p1 ); +        // set the complemented attributes +        p0 = Rwt_NotCond( p0, (Entry0 & 1) ); +        p1 = Rwt_NotCond( p1, (Entry1 & 1) ); +        // add the node +//        Rwt_ManTryNode( p, p0, p1, Level, Volume ); +        Rwt_ManAddNode( p, p0, p1, fExor, Level, Volume + fExor ); +    } +    nEntries = i - 1; +    if ( fVerbose ) +    { +        printf( "The number of classes = %d. Canonical nodes = %d.\n", p->nClasses, p->nAdded ); +        printf( "The number of nodes loaded = %d.  ", nEntries );  PRT( "Loading", clock() - clk ); +    } +} + +/**Function************************************************************* + +  Synopsis    [Create practical classes.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +char * Rwt_ManGetPractical( Rwt_Man_t * p ) +{ +    char * pPractical; +    int i; +    pPractical = ALLOC( char, p->nFuncs ); +    memset( pPractical, 0, sizeof(char) * p->nFuncs ); +    pPractical[0] = 1; +    for ( i = 1; ; i++ ) +    { +        if ( s_RwtPracticalClasses[i] == 0 ) +            break; +        pPractical[ s_RwtPracticalClasses[i] ] = 1; +    } +    return pPractical; +} + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + +// the following 135 practical NPN classes of 4-variable functions were computed +// by considering all 4-input cuts appearing in IWLS, MCNC, and ISCAS benchmarks +static unsigned short s_RwtPracticalClasses[] =  +{ +    0x0000, 0x0001, 0x0003, 0x0006, 0x0007, 0x000f, 0x0016, 0x0017, 0x0018, 0x0019, 0x001b,  +    0x001e, 0x001f, 0x003c, 0x003d, 0x003f, 0x0069, 0x006b, 0x006f, 0x007e, 0x007f, 0x00ff,  +    0x0116, 0x0118, 0x0119, 0x011a, 0x011b, 0x011e, 0x011f, 0x012c, 0x012d, 0x012f, 0x013c,  +    0x013d, 0x013e, 0x013f, 0x0168, 0x0169, 0x016f, 0x017f, 0x0180, 0x0181, 0x0182, 0x0183,  +    0x0186, 0x0189, 0x018b, 0x018f, 0x0198, 0x0199, 0x019b, 0x01a8, 0x01a9, 0x01aa, 0x01ab,  +    0x01ac, 0x01ad, 0x01ae, 0x01af, 0x01bf, 0x01e9, 0x01ea, 0x01eb, 0x01ee, 0x01ef, 0x01fe,  +    0x033c, 0x033d, 0x033f, 0x0356, 0x0357, 0x0358, 0x0359, 0x035a, 0x035b, 0x035f, 0x0368,  +    0x0369, 0x036c, 0x036e, 0x037d, 0x03c0, 0x03c1, 0x03c3, 0x03c7, 0x03cf, 0x03d4, 0x03d5,  +    0x03d7, 0x03d8, 0x03d9, 0x03dc, 0x03dd, 0x03de, 0x03fc, 0x0660, 0x0661, 0x0666, 0x0669,  +    0x066f, 0x0676, 0x067e, 0x0690, 0x0696, 0x0697, 0x069f, 0x06b1, 0x06b6, 0x06f0, 0x06f2,  +    0x06f6, 0x06f9, 0x0776, 0x0778, 0x07b0, 0x07b1, 0x07b4, 0x07bc, 0x07f0, 0x07f2, 0x07f8,  +    0x0ff0, 0x1683, 0x1696, 0x1698, 0x169e, 0x16e9, 0x178e, 0x17e8, 0x18e7, 0x19e6, 0x1be4,  +    0x1ee1, 0x3cc3, 0x6996, 0x0000 +}; + +static unsigned short s_RwtAigSubgraphs[] =  +{ +    0x0008,0x0002, 0x000a,0x0002, 0x0008,0x0003, 0x000a,0x0003, 0x0009,0x0002,  +    0x000c,0x0002, 0x000e,0x0002, 0x000c,0x0003, 0x000e,0x0003, 0x000d,0x0002,  +    0x000c,0x0004, 0x000e,0x0004, 0x000c,0x0005, 0x000e,0x0005, 0x000d,0x0004,  +    0x0010,0x0002, 0x0012,0x0002, 0x0010,0x0003, 0x0012,0x0003, 0x0011,0x0002,  +    0x0010,0x0004, 0x0012,0x0004, 0x0010,0x0005, 0x0012,0x0005, 0x0011,0x0004,  +    0x0010,0x0006, 0x0012,0x0006, 0x0010,0x0007, 0x0012,0x0007, 0x0011,0x0006,  +    0x0016,0x0005, 0x0014,0x0006, 0x0016,0x0006, 0x0014,0x0007, 0x0016,0x0007,  +    0x0015,0x0006, 0x0014,0x0008, 0x0016,0x0008, 0x0014,0x0009, 0x0016,0x0009,  +    0x0015,0x0008, 0x0018,0x0006, 0x001a,0x0006, 0x0018,0x0007, 0x001a,0x0007,  +    0x0019,0x0006, 0x0018,0x0009, 0x001a,0x0009, 0x0019,0x0008, 0x001e,0x0005,  +    0x001c,0x0006, 0x001e,0x0006, 0x001c,0x0007, 0x001e,0x0007, 0x001d,0x0006,  +    0x001c,0x0008, 0x001e,0x0008, 0x001c,0x0009, 0x001e,0x0009, 0x001d,0x0008,  +    0x0020,0x0006, 0x0022,0x0006, 0x0020,0x0007, 0x0022,0x0007, 0x0021,0x0006,  +    0x0020,0x0008, 0x0022,0x0008, 0x0020,0x0009, 0x0022,0x0009, 0x0021,0x0008,  +    0x0024,0x0006, 0x0026,0x0006, 0x0024,0x0007, 0x0026,0x0007, 0x0025,0x0006,  +    0x0026,0x0008, 0x0024,0x0009, 0x0026,0x0009, 0x0025,0x0008, 0x0028,0x0004,  +    0x002a,0x0004, 0x0028,0x0005, 0x002a,0x0007, 0x0028,0x0008, 0x002a,0x0009,  +    0x0029,0x0008, 0x002a,0x000b, 0x0029,0x000a, 0x002a,0x000f, 0x0029,0x000e,  +    0x002a,0x0011, 0x002a,0x0013, 0x002c,0x0004, 0x002e,0x0004, 0x002c,0x0005,  +    0x002c,0x0009, 0x002e,0x0009, 0x002d,0x0008, 0x002d,0x000c, 0x002e,0x000f,  +    0x002e,0x0011, 0x002e,0x0012, 0x0030,0x0004, 0x0032,0x0007, 0x0032,0x0009,  +    0x0031,0x0008, 0x0032,0x000b, 0x0032,0x000d, 0x0032,0x000f, 0x0031,0x000e,  +    0x0032,0x0013, 0x0034,0x0004, 0x0036,0x0004, 0x0034,0x0005, 0x0036,0x0005,  +    0x0035,0x0004, 0x0036,0x0008, 0x0034,0x0009, 0x0036,0x0009, 0x0035,0x0008,  +    0x0036,0x000b, 0x0036,0x000d, 0x0036,0x0011, 0x0035,0x0010, 0x0036,0x0013,  +    0x0038,0x0004, 0x0039,0x0004, 0x0038,0x0009, 0x003a,0x0009, 0x0039,0x0008,  +    0x0038,0x000b, 0x003a,0x000b, 0x003a,0x000d, 0x003a,0x0011, 0x003a,0x0012,  +    0x0038,0x0013, 0x003a,0x0013, 0x003c,0x0002, 0x003e,0x0002, 0x003c,0x0003,  +    0x003e,0x0005, 0x003e,0x0007, 0x003c,0x0008, 0x003e,0x0008, 0x003c,0x0009,  +    0x003e,0x0009, 0x003d,0x0008, 0x003e,0x000d, 0x003e,0x0011, 0x003e,0x0013,  +    0x003e,0x0017, 0x003e,0x001b, 0x003e,0x001d, 0x0040,0x0002, 0x0042,0x0002,  +    0x0042,0x0005, 0x0041,0x0006, 0x0042,0x0008, 0x0041,0x0008, 0x0042,0x000d,  +    0x0042,0x0011, 0x0042,0x0015, 0x0042,0x0019, 0x0042,0x001b, 0x0042,0x001c,  +    0x0041,0x001c, 0x0044,0x0002, 0x0046,0x0003, 0x0045,0x0004, 0x0046,0x0007,  +    0x0045,0x0008, 0x0046,0x000b, 0x0046,0x000f, 0x0046,0x0013, 0x0045,0x0012,  +    0x0046,0x0017, 0x0046,0x001b, 0x0046,0x0021, 0x0048,0x0002, 0x004a,0x0002,  +    0x0048,0x0003, 0x004a,0x0003, 0x0049,0x0002, 0x0048,0x0008, 0x004a,0x0008,  +    0x0048,0x0009, 0x004a,0x0009, 0x0049,0x0008, 0x004a,0x000b, 0x004a,0x000f,  +    0x004a,0x0011, 0x004a,0x0012, 0x004a,0x0013, 0x004a,0x0015, 0x004a,0x0019,  +    0x004a,0x001b, 0x004a,0x001d, 0x004c,0x0002, 0x004c,0x0003, 0x004d,0x0002,  +    0x004c,0x0008, 0x004e,0x0008, 0x004c,0x0009, 0x004e,0x0009, 0x004d,0x0008,  +    0x004c,0x000b, 0x004e,0x000b, 0x004c,0x000f, 0x004e,0x000f, 0x004e,0x0011,  +    0x004c,0x0012, 0x004c,0x0013, 0x004e,0x0013, 0x004e,0x0015, 0x004c,0x0017,  +    0x004e,0x0019, 0x004c,0x001b, 0x004e,0x001b, 0x004c,0x001c, 0x004c,0x001d,  +    0x004e,0x001d, 0x0050,0x0004, 0x0052,0x0004, 0x0050,0x0006, 0x0052,0x0009,  +    0x0052,0x000d, 0x0052,0x000f, 0x0052,0x0013, 0x0052,0x0017, 0x0052,0x0019,  +    0x0052,0x001d, 0x0052,0x001f, 0x0052,0x0021, 0x0052,0x0023, 0x0052,0x0024,  +    0x0052,0x0025, 0x0051,0x0024, 0x0052,0x0027, 0x0054,0x0004, 0x0056,0x0004,  +    0x0054,0x0005, 0x0056,0x0006, 0x0054,0x0007, 0x0056,0x0011, 0x0056,0x001b,  +    0x0056,0x001e, 0x0054,0x001f, 0x0056,0x001f, 0x0056,0x0020, 0x0054,0x0021,  +    0x0055,0x0020, 0x0056,0x0024, 0x0054,0x0025, 0x0056,0x0025, 0x0055,0x0024,  +    0x0054,0x0027, 0x0056,0x0027, 0x0055,0x0026, 0x005a,0x0007, 0x005a,0x0009,  +    0x005a,0x000b, 0x005a,0x0015, 0x005a,0x001f, 0x0059,0x0020, 0x0058,0x0024,  +    0x005a,0x0024, 0x005a,0x0027, 0x0059,0x0026, 0x005c,0x0004, 0x005e,0x0004,  +    0x005c,0x0005, 0x005e,0x0006, 0x005c,0x0007, 0x005d,0x0006, 0x005e,0x000d,  +    0x005e,0x0013, 0x005e,0x0017, 0x005c,0x001f, 0x005d,0x001e, 0x005e,0x0020,  +    0x005e,0x0021, 0x005e,0x0022, 0x005e,0x0023, 0x005c,0x0024, 0x005e,0x0024,  +    0x005c,0x0025, 0x005e,0x0025, 0x005d,0x0024, 0x005e,0x0026, 0x005e,0x0027,  +    0x0062,0x0004, 0x0061,0x0004, 0x0062,0x0006, 0x0061,0x0006, 0x0060,0x000f,  +    0x0060,0x0013, 0x0062,0x0013, 0x0060,0x0019, 0x0062,0x001c, 0x0060,0x001d,  +    0x0062,0x001d, 0x0062,0x001f, 0x0060,0x0021, 0x0060,0x0023, 0x0062,0x0024,  +    0x0060,0x0027, 0x0061,0x0026, 0x0064,0x0002, 0x0066,0x0002, 0x0064,0x0006,  +    0x0066,0x0007, 0x0066,0x0009, 0x0066,0x000d, 0x0066,0x0013, 0x0066,0x0015,  +    0x0066,0x0017, 0x0066,0x0019, 0x0066,0x001a, 0x0065,0x001a, 0x0066,0x001f,  +    0x0066,0x0023, 0x0066,0x0027, 0x0066,0x002f, 0x0066,0x0030, 0x006a,0x0002,  +    0x0068,0x0003, 0x0068,0x0006, 0x006a,0x0006, 0x006a,0x0011, 0x0068,0x0016,  +    0x0068,0x0017, 0x006a,0x0017, 0x006a,0x001a, 0x006a,0x001b, 0x006a,0x0025,  +    0x006a,0x002d, 0x006e,0x0003, 0x006e,0x0007, 0x006e,0x0009, 0x006e,0x000b,  +    0x006e,0x0015, 0x006e,0x0016, 0x006e,0x0017, 0x006c,0x001a, 0x006e,0x001a,  +    0x006e,0x001f, 0x006e,0x002b, 0x006e,0x0035, 0x0070,0x0002, 0x0070,0x0003,  +    0x0072,0x0006, 0x0070,0x0007, 0x0071,0x0006, 0x0072,0x000b, 0x0072,0x000f,  +    0x0072,0x0013, 0x0070,0x0015, 0x0071,0x0014, 0x0072,0x0017, 0x0072,0x0018,  +    0x0070,0x0019, 0x0072,0x0019, 0x0070,0x001a, 0x0070,0x001b, 0x0072,0x001b,  +    0x0071,0x001a, 0x0072,0x0021, 0x0072,0x0029, 0x0076,0x0002, 0x0076,0x0003,  +    0x0075,0x0002, 0x0076,0x0006, 0x0074,0x0007, 0x0076,0x0007, 0x0075,0x0006,  +    0x0076,0x000d, 0x0076,0x0011, 0x0076,0x0013, 0x0075,0x0014, 0x0076,0x0019,  +    0x0076,0x001a, 0x0076,0x001b, 0x0075,0x001c, 0x0074,0x0023, 0x0075,0x0022,  +    0x0074,0x0026, 0x0076,0x0026, 0x0074,0x0027, 0x0076,0x002b, 0x0076,0x002f,  +    0x0078,0x0002, 0x0078,0x0004, 0x007a,0x0004, 0x007a,0x0005, 0x0079,0x0004,  +    0x007a,0x0009, 0x007a,0x000a, 0x007a,0x000b, 0x007a,0x000d, 0x007a,0x000f,  +    0x007a,0x0010, 0x007a,0x0011, 0x007a,0x0012, 0x007a,0x0013, 0x007a,0x0017,  +    0x007a,0x001b, 0x007a,0x0021, 0x007a,0x0027, 0x007a,0x002b, 0x007a,0x002f,  +    0x007a,0x0030, 0x0079,0x0034, 0x007a,0x0039, 0x007a,0x003a, 0x007e,0x0002,  +    0x007c,0x0004, 0x007e,0x0004, 0x007e,0x000c, 0x007c,0x000d, 0x007e,0x0011,  +    0x007e,0x0013, 0x007e,0x001b, 0x007e,0x0025, 0x007e,0x002d, 0x007e,0x0037,  +    0x0082,0x0003, 0x0082,0x0005, 0x0082,0x0009, 0x0082,0x000b, 0x0080,0x0010,  +    0x0082,0x0010, 0x0082,0x0012, 0x0082,0x0015, 0x0082,0x001f, 0x0082,0x002b,  +    0x0082,0x0035, 0x0082,0x0039, 0x0082,0x003f, 0x0084,0x0002, 0x0086,0x0002,  +    0x0084,0x0003, 0x0086,0x0003, 0x0085,0x0002, 0x0086,0x0004, 0x0084,0x0005,  +    0x0085,0x0004, 0x0086,0x000a, 0x0084,0x000b, 0x0085,0x000a, 0x0086,0x000d,  +    0x0086,0x000e, 0x0086,0x000f, 0x0084,0x0010, 0x0084,0x0011, 0x0086,0x0011,  +    0x0085,0x0010, 0x0084,0x0012, 0x0084,0x0013, 0x0086,0x0013, 0x0085,0x0012,  +    0x0086,0x0019, 0x0086,0x0023, 0x0086,0x0029, 0x0086,0x0033, 0x0086,0x0039,  +    0x008a,0x0003, 0x0089,0x0002, 0x0088,0x0004, 0x008a,0x0004, 0x0088,0x0005,  +    0x0089,0x0004, 0x008a,0x000b, 0x008a,0x0010, 0x0088,0x0011, 0x008a,0x0011,  +    0x0089,0x0010, 0x0088,0x0012, 0x008a,0x0012, 0x0089,0x0012, 0x008a,0x0017,  +    0x008a,0x001b, 0x0089,0x0020, 0x008a,0x0025, 0x0088,0x0027, 0x008a,0x002b,  +    0x008a,0x002f, 0x008a,0x0039, 0x0088,0x003a, 0x008d,0x0044, 0x0092,0x0009,  +    0x0092,0x0025, 0x0092,0x0029, 0x0092,0x002d, 0x0092,0x0033, 0x0092,0x0037,  +    0x0092,0x003d, 0x0092,0x0041, 0x0095,0x0002, 0x0095,0x0004, 0x0095,0x0010,  +    0x0095,0x0012, 0x0096,0x0021, 0x0096,0x0029, 0x0095,0x002e, 0x0096,0x0030,  +    0x0096,0x0033, 0x0096,0x003a, 0x0096,0x0043, 0x009a,0x0008, 0x009a,0x0009,  +    0x0099,0x0008, 0x009a,0x0011, 0x009a,0x0023, 0x009a,0x0033, 0x009a,0x003d,  +    0x009a,0x0044, 0x009a,0x0045, 0x0099,0x0044, 0x009d,0x0002, 0x009e,0x0008,  +    0x009c,0x0009, 0x009e,0x0009, 0x009d,0x0008, 0x009e,0x0011, 0x009d,0x0010,  +    0x009e,0x001f, 0x009e,0x003f, 0x00a0,0x0009, 0x00a0,0x0011, 0x00a2,0x0030,  +    0x00a2,0x0033, 0x00a6,0x0006, 0x00a6,0x0007, 0x00a6,0x0011, 0x00a6,0x0044,  +    0x00a6,0x004b, 0x00aa,0x0007, 0x00aa,0x0015, 0x00ae,0x0006, 0x00ae,0x0011,  +    0x00ae,0x001b, 0x00ae,0x0025, 0x00ae,0x003d, 0x00ae,0x0041, 0x00ae,0x0043,  +    0x00ae,0x0045, 0x00b2,0x0006, 0x00b0,0x0007, 0x00b1,0x0006, 0x00b2,0x0017,  +    0x00b1,0x0016, 0x00b0,0x0019, 0x00b2,0x0021, 0x00b2,0x003d, 0x00b5,0x004a,  +    0x00ba,0x0009, 0x00ba,0x000f, 0x00bc,0x0009, 0x00be,0x0009, 0x00be,0x000f,  +    0x00bd,0x000e, 0x00be,0x0017, 0x00c2,0x0009, 0x00c2,0x0019, 0x00c2,0x001f,  +    0x00c2,0x0033, 0x00c6,0x0009, 0x00c5,0x000e, 0x00c6,0x0015, 0x00c6,0x0023,  +    0x00c4,0x002d, 0x00c6,0x002f, 0x00c5,0x002e, 0x00c6,0x0045, 0x00ce,0x0007,  +    0x00ce,0x0021, 0x00ce,0x0023, 0x00ce,0x0025, 0x00ce,0x0027, 0x00ce,0x0033,  +    0x00ce,0x003d, 0x00d2,0x0006, 0x00d0,0x0015, 0x00d0,0x001b, 0x00d2,0x001b,  +    0x00d1,0x001a, 0x00d0,0x001f, 0x00d2,0x0025, 0x00d1,0x0024, 0x00d2,0x0037,  +    0x00d2,0x0041, 0x00d2,0x0045, 0x00d9,0x0044, 0x00e1,0x0004, 0x00e2,0x000d,  +    0x00e2,0x0021, 0x00e0,0x003a, 0x00e6,0x003d, 0x00e6,0x0061, 0x00e6,0x0067,  +    0x00e9,0x0004, 0x00ea,0x0008, 0x00ea,0x0009, 0x00ea,0x0039, 0x00e9,0x0038,  +    0x00ea,0x003f, 0x00ec,0x000d, 0x00ee,0x000d, 0x00ee,0x0037, 0x00f2,0x003d,  +    0x00f2,0x0062, 0x00f5,0x0002, 0x00fa,0x0017, 0x00fa,0x003d, 0x00fe,0x0006,  +    0x00fd,0x0006, 0x00fc,0x0015, 0x00fe,0x001b, 0x00fc,0x0025, 0x00fe,0x0025,  +    0x00fd,0x0024, 0x00fe,0x0041, 0x00fe,0x004d, 0x00fd,0x004e, 0x0101,0x0014,  +    0x0106,0x004d, 0x010a,0x0009, 0x010a,0x000b, 0x0109,0x000a, 0x010a,0x004f,  +    0x010a,0x0058, 0x010e,0x0008, 0x010c,0x0009, 0x010e,0x0009, 0x010d,0x0008,  +    0x010e,0x000b, 0x010e,0x002b, 0x010d,0x002a, 0x010e,0x0035, 0x010e,0x003d,  +    0x010e,0x003f, 0x010e,0x0049, 0x010e,0x0057, 0x010d,0x0056, 0x010d,0x0058,  +    0x0111,0x0004, 0x0111,0x0006, 0x0110,0x0009, 0x0112,0x0009, 0x0111,0x0008,  +    0x0112,0x002f, 0x0110,0x0035, 0x0110,0x0037, 0x0112,0x0039, 0x0112,0x003d,  +    0x0112,0x003f, 0x0112,0x0045, 0x0111,0x0044, 0x0112,0x004b, 0x0112,0x0059,  +    0x0112,0x0069, 0x0112,0x007f, 0x0116,0x0009, 0x0115,0x0008, 0x0114,0x000b,  +    0x0116,0x000b, 0x0116,0x0058, 0x011a,0x0015, 0x011a,0x001f, 0x011a,0x002b,  +    0x011a,0x003f, 0x011a,0x0049, 0x011a,0x0085, 0x011e,0x0007, 0x011e,0x0019,  +    0x011e,0x001b, 0x011e,0x0023, 0x011e,0x0027, 0x011e,0x002f, 0x011e,0x0043,  +    0x011e,0x004b, 0x011e,0x004e, 0x011e,0x004f, 0x011e,0x005f, 0x011e,0x0061,  +    0x011e,0x0065, 0x011e,0x0083, 0x0122,0x0006, 0x0120,0x0007, 0x0122,0x0007,  +    0x0121,0x0006, 0x0122,0x0049, 0x0121,0x004e, 0x0122,0x008f, 0x0125,0x0004,  +    0x0124,0x0007, 0x0125,0x0006, 0x0124,0x001b, 0x0126,0x001b, 0x0126,0x0045,  +    0x0126,0x0087, 0x0128,0x0007, 0x0129,0x0006, 0x012a,0x0019, 0x012a,0x003d,  +    0x012a,0x0051, 0x012a,0x0065, 0x012a,0x0083, 0x012d,0x005a, 0x0132,0x0009,  +    0x0132,0x008f, 0x0134,0x0009, 0x0135,0x003e, 0x013a,0x003d, 0x013a,0x0044,  +    0x0139,0x0044, 0x013e,0x0009, 0x013d,0x0008, 0x013c,0x003d, 0x013c,0x0044,  +    0x013c,0x0053, 0x013e,0x008f, 0x013e,0x0095, 0x0142,0x0044, 0x0142,0x0097,  +    0x0142,0x009e, 0x0144,0x0007, 0x0148,0x0015, 0x0148,0x001c, 0x0148,0x001f,  +    0x0148,0x0026, 0x0149,0x0086, 0x014d,0x0006, 0x014e,0x0044, 0x014d,0x0048,  +    0x014e,0x009e, 0x0152,0x0009, 0x0151,0x00a6, 0x0155,0x0030, 0x015d,0x003a,  +    0x0162,0x009e, 0x0164,0x000f, 0x0164,0x0013, 0x0169,0x000e, 0x0174,0x0009,  +    0x0179,0x0008, 0x0180,0x0009, 0x0181,0x0044, 0x0186,0x0044, 0x0185,0x0044,  +    0x018a,0x0068, 0x0195,0x004e, 0x01a6,0x0009, 0x01a5,0x0008, 0x01b1,0x003a,  +    0x01c4,0x0029, 0x01c4,0x0030, 0x01ca,0x008f, 0x01ca,0x0095, 0x01cc,0x0029,  +    0x01cc,0x0033, 0x01ce,0x003d, 0x01d6,0x00b2, 0x01d8,0x0009, 0x01d9,0x002a,  +    0x01d9,0x0056, 0x01d9,0x00a4, 0x01dd,0x003a, 0x01e2,0x00b2, 0x01e6,0x0013,  +    0x01e6,0x009f, 0x01e6,0x00ba, 0x01e6,0x00c0, 0x01e6,0x00d3, 0x01e6,0x00d5,  +    0x01e6,0x00e5, 0x01e8,0x0005, 0x01f2,0x0013, 0x01f2,0x0095, 0x01f2,0x009f,  +    0x01f2,0x00ba, 0x01f2,0x00c0, 0x01f2,0x00d3, 0x0202,0x008f, 0x0202,0x0095,  +    0x0202,0x00f3, 0x0202,0x00f9, 0x020a,0x0044, 0x0209,0x00b4, 0x020e,0x0009,  +    0x020d,0x0008, 0x020c,0x003d, 0x020c,0x0044, 0x020c,0x0053, 0x020e,0x008f,  +    0x020e,0x0095, 0x020c,0x00b1, 0x020e,0x00f3, 0x020e,0x00f9, 0x0210,0x0013,  +    0x0211,0x0024, 0x0210,0x0026, 0x0219,0x0004, 0x021e,0x008f, 0x021e,0x0095,  +    0x0221,0x003a, 0x0230,0x0009, 0x0236,0x0009, 0x0234,0x0029, 0x0234,0x0030,  +    0x0234,0x0033, 0x0234,0x003a, 0x0234,0x003d, 0x0234,0x0044, 0x0235,0x00a6,  +    0x023a,0x0009, 0x023d,0x003a, 0x0245,0x0044, 0x0249,0x003a, 0x024e,0x009e,  +    0x024e,0x0106, 0x0251,0x0026, 0x0258,0x0013, 0x0259,0x0024, 0x0258,0x0061,  +    0x0259,0x0086, 0x0258,0x00c7, 0x0258,0x00df, 0x0259,0x00ec, 0x0258,0x00fc,  +    0x025d,0x0024, 0x025d,0x00de, 0x0260,0x00f6, 0x0268,0x0009, 0x0269,0x0044,  +    0x0268,0x00f3, 0x0268,0x00f9, 0x026d,0x003a, 0x0270,0x0068, 0x0275,0x003a,  +    0x027a,0x0044, 0x0279,0x0044, 0x027e,0x007e, 0x0281,0x0044, 0x0285,0x0008,  +    0x028d,0x0006, 0x028d,0x00d2, 0x0295,0x00cc, 0x0296,0x00f6, 0x0295,0x00f8,  +    0x0299,0x0030, 0x029e,0x007e, 0x029d,0x0080, 0x02a6,0x008f, 0x02a6,0x0095,  +    0x02aa,0x0029, 0x02aa,0x0030, 0x02b5,0x0008, 0x02b9,0x003a, 0x02bd,0x0004,  +    0x02bd,0x00fc, 0x02c2,0x00b2, 0x02c1,0x00b4, 0x02c4,0x0029, 0x02c8,0x0029,  +    0x02c8,0x0033, 0x02ca,0x003d, 0x02ce,0x0029, 0x02ce,0x0030, 0x02d2,0x0068,  +    0x02d1,0x006a, 0x02d5,0x006a, 0x02d9,0x0008, 0x02de,0x012c, 0x02e2,0x012c,  +    0x02e4,0x0009, 0x02e5,0x002a, 0x02e5,0x0056, 0x02e5,0x012c, 0x02ea,0x0029,  +    0x02ea,0x0030, 0x02e9,0x0030, 0x02ec,0x0029, 0x02ec,0x0030, 0x02ee,0x012c,  +    0x02f1,0x0068, 0x02f1,0x00b2, 0x02f1,0x0108, 0x02f1,0x012c, 0x02f6,0x0013,  +    0x02f6,0x0015, 0x02f6,0x001f, 0x02f6,0x0030, 0x02f6,0x0065, 0x02f6,0x0067,  +    0x02f6,0x009f, 0x02f6,0x00b6, 0x02f6,0x00b9, 0x02f6,0x00c0, 0x02f6,0x00cf,  +    0x02f6,0x0107, 0x02f6,0x010b, 0x02f6,0x010f, 0x02f6,0x0115, 0x02f6,0x012d,  +    0x02f6,0x0134, 0x02f6,0x0153, 0x02f6,0x0171, 0x02f6,0x0176, 0x02f8,0x0003,  +    0x02fa,0x017b, 0x02fc,0x00ba, 0x02fc,0x00d3, 0x0302,0x0013, 0x0302,0x001f,  +    0x0302,0x0030, 0x0302,0x005d, 0x0302,0x0065, 0x0302,0x0067, 0x0302,0x0099,  +    0x0302,0x009f, 0x0302,0x00ad, 0x0302,0x00b9, 0x0302,0x00c0, 0x0302,0x00cf,  +    0x0301,0x00d2, 0x0301,0x00fe, 0x0302,0x0107, 0x0302,0x010b, 0x0302,0x010f,  +    0x0302,0x0117, 0x0302,0x0134, 0x0302,0x0153, 0x0302,0x0157, 0x0302,0x0176,  +    0x0306,0x0029, 0x0308,0x00b2, 0x0309,0x00dc, 0x030d,0x00f8, 0x0312,0x00f3,  +    0x0318,0x007e, 0x031d,0x0080, 0x0321,0x0008, 0x0321,0x0094, 0x0326,0x017b,  +    0x0326,0x0181, 0x0329,0x012e, 0x032a,0x017b, 0x032a,0x0181, 0x032e,0x008f,  +    0x032e,0x0095, 0x032e,0x00f3, 0x032e,0x00f9, 0x0332,0x0009, 0x0331,0x0008,  +    0x0330,0x003d, 0x0330,0x0044, 0x0330,0x0053, 0x0332,0x008f, 0x0332,0x0095,  +    0x0330,0x00b1, 0x0332,0x00f3, 0x0332,0x00f9, 0x0330,0x0127, 0x0332,0x017b,  +    0x0332,0x0181, 0x033c,0x0013, 0x033c,0x001c, 0x033d,0x0086, 0x033d,0x00ec,  +    0x033d,0x0172, 0x033e,0x019d, 0x0345,0x0002, 0x0344,0x008f, 0x0344,0x00f3,  +    0x034d,0x0030, 0x0352,0x0033, 0x0354,0x0029, 0x0354,0x0030, 0x035a,0x0009,  +    0x035a,0x017b, 0x035a,0x019b, 0x035a,0x01a2, 0x035e,0x0181, 0x0360,0x0009,  +    0x0366,0x0009, 0x0364,0x0029, 0x0364,0x0030, 0x0364,0x0033, 0x0364,0x003a,  +    0x0364,0x003d, 0x0364,0x0044, 0x0369,0x0030, 0x0370,0x0029, 0x0370,0x0030,  +    0x0376,0x0033, 0x037a,0x0009, 0x037a,0x019b, 0x037a,0x01a2, 0x037c,0x0009,  +    0x0382,0x0181, 0x0386,0x0009, 0x0384,0x0029, 0x0384,0x0030, 0x0384,0x0033,  +    0x0384,0x003a, 0x0384,0x003d, 0x0384,0x0044, 0x038a,0x0044, 0x038a,0x009e,  +    0x038a,0x0106, 0x038a,0x0198, 0x038d,0x010e, 0x038d,0x0152, 0x038d,0x0158,  +    0x0392,0x009e, 0x0392,0x0106, 0x0392,0x0198, 0x0395,0x0086, 0x0395,0x009a,  +    0x0395,0x00ec, 0x0395,0x0172, 0x0398,0x014e, 0x0398,0x0175, 0x0398,0x018d,  +    0x039c,0x0023, 0x039c,0x0027, 0x039c,0x00ef, 0x039c,0x0139, 0x039c,0x0168,  +    0x03a0,0x0019, 0x03a0,0x001d, 0x03a0,0x0023, 0x03a0,0x0027, 0x03a1,0x004e,  +    0x03a4,0x0162, 0x03a4,0x0183, 0x03a8,0x0013, 0x03a8,0x0027, 0x03a8,0x0133,  +    0x03a8,0x0148, 0x03a8,0x0181, 0x03ac,0x0013, 0x03ac,0x0027, 0x03b0,0x017b,  +    0x03b0,0x0181, 0x03b4,0x004b, 0x03b4,0x00e0, 0x03b4,0x00fb, 0x03b8,0x000f,  +    0x03b8,0x0013, 0x03b8,0x00ab, 0x03b8,0x00bf, 0x03b8,0x00d0, 0x03bd,0x00da,  +    0x03bd,0x012c, 0x03c8,0x000f, 0x03c8,0x0013, 0x03c8,0x0019, 0x03c8,0x001d,  +    0x03cd,0x0086, 0x03cd,0x00ec, 0x03cd,0x0172, 0x03d2,0x00e0, 0x03d2,0x00ef,  +    0x03d2,0x0112, 0x03d2,0x0139, 0x03d2,0x0168, 0x03d6,0x017b, 0x03d6,0x0181,  +    0x03da,0x0133, 0x03da,0x0148, 0x03e2,0x0023, 0x03e2,0x0027, 0x03e6,0x0027,  +    0x03e6,0x0181, 0x03ee,0x017b, 0x03ee,0x0181, 0x03fe,0x003d, 0x0401,0x012a,  +    0x0401,0x019e, 0x0405,0x01a0, 0x040a,0x000d, 0x040a,0x011f, 0x040a,0x016f,  +    0x040d,0x012a, 0x0412,0x017b, 0x041a,0x0033, 0x041a,0x003d, 0x041a,0x0181,  +    0x0421,0x0086, 0x0421,0x009a, 0x0421,0x00ec, 0x0421,0x0172, 0x042e,0x0205,  +    0x043a,0x0205, 0x043e,0x017b, 0x0442,0x01f5, 0x044c,0x0007, 0x0452,0x0033,  +    0x0452,0x01ce, 0x0452,0x01d0, 0x0452,0x01f1, 0x0452,0x01fb, 0x0452,0x0225,  +    0x0454,0x0005, 0x045a,0x0033, 0x045a,0x0181, 0x045a,0x01ce, 0x045a,0x01d0,  +    0x045a,0x01f1, 0x0469,0x01de, 0x046e,0x0181, 0x047a,0x01ce, 0x047a,0x01f1,  +    0x0485,0x012c, 0x0489,0x012c, 0x0490,0x01d8, 0x0496,0x0033, 0x0496,0x003d,  +    0x0498,0x008f, 0x0498,0x00f3, 0x049e,0x0044, 0x049e,0x0221, 0x04a1,0x0006,  +    0x04a2,0x0044, 0x04a6,0x0221, 0x04a9,0x0004, 0x04ac,0x0027, 0x04b1,0x009a,  +    0x04b6,0x0097, 0x04b8,0x0027, 0x04c6,0x0219, 0x04ca,0x017b, 0x04cc,0x004b,  +    0x04d0,0x00ab, 0x04d6,0x017b, 0x04d8,0x000f, 0x04d8,0x0019, 0x04d8,0x0033,  +    0x04d8,0x003d, 0x04de,0x003d, 0x04de,0x0103, 0x04de,0x018b, 0x04de,0x0231,  +    0x04e2,0x0044, 0x04e2,0x009e, 0x04e2,0x0106, 0x04e2,0x0198, 0x04e5,0x01a4,  +    0x04e5,0x01b6, 0x04ea,0x009e, 0x04ea,0x0106, 0x04ea,0x0198, 0x04ed,0x002e,  +    0x04ed,0x0038, 0x04ed,0x00a2, 0x04f1,0x0086, 0x04f1,0x009a, 0x04f1,0x00ec,  +    0x04f1,0x0172, 0x04f9,0x004e, 0x04f8,0x0229, 0x04f8,0x022d, 0x0500,0x023e,  +    0x0504,0x0217, 0x0510,0x00f3, 0x0514,0x0043, 0x0514,0x004d, 0x0514,0x00c3,  +    0x0514,0x013d, 0x0514,0x0215, 0x0514,0x0232, 0x0515,0x0260, 0x0519,0x002a,  +    0x0518,0x0030, 0x0518,0x0067, 0x0518,0x00c9, 0x0518,0x01eb, 0x0518,0x01ef,  +    0x051c,0x0139, 0x051c,0x0168, 0x0520,0x0027, 0x0526,0x014e, 0x0526,0x0175,  +    0x0526,0x018d, 0x052d,0x0200, 0x0532,0x0021, 0x0532,0x00bf, 0x0532,0x00d0,  +    0x0532,0x0239, 0x0532,0x0266, 0x053d,0x0024, 0x053d,0x00da, 0x054a,0x000f,  +    0x054a,0x00ab, 0x054a,0x023a, 0x054e,0x0043, 0x054e,0x004d, 0x054e,0x00c3,  +    0x054e,0x013d, 0x054e,0x0215, 0x054e,0x0232, 0x054e,0x029d, 0x0552,0x014e,  +    0x0552,0x018d, 0x0556,0x00f3, 0x0556,0x01e4, 0x055a,0x0299, 0x055d,0x0086,  +    0x055d,0x009a, 0x055d,0x00ec, 0x055d,0x0172, 0x0566,0x01dc, 0x0566,0x02a5,  +    0x056d,0x020a, 0x057a,0x003d, 0x057a,0x01d4, 0x057a,0x01f3, 0x0579,0x025e,  +    0x057e,0x0139, 0x057e,0x0168, 0x0581,0x0006, 0x0586,0x017b, 0x0586,0x0181,  +    0x0586,0x028c, 0x0588,0x0007, 0x058e,0x0033, 0x058e,0x008f, 0x058e,0x01d0,  +    0x058e,0x027c, 0x0590,0x0003, 0x0596,0x0033, 0x0596,0x008f, 0x0596,0x0095,  +    0x0596,0x01d0, 0x0596,0x027c, 0x05a2,0x026f, 0x05a5,0x0284, 0x05aa,0x017b,  +    0x05ac,0x0205, 0x05b2,0x008f, 0x05b6,0x017b, 0x05b8,0x01da, 0x05c1,0x0276,  +    0x05c6,0x0248, 0x05c8,0x0247, 0x05c8,0x027e, 0x05cc,0x003d, 0x05cc,0x01d4,  +    0x05cc,0x01f3, 0x05d0,0x014e, 0x05d0,0x018d, 0x05da,0x00f9, 0x05dd,0x0006,  +    0x05de,0x0044, 0x05e5,0x002e, 0x05e6,0x02f1, 0x05ea,0x01d4, 0x05ea,0x01f3,  +    0x05ea,0x022d, 0x05ed,0x0002, 0x05f6,0x0027, 0x05fa,0x0097, 0x05fc,0x003d,  +    0x0602,0x003d, 0x0606,0x00f3, 0x060a,0x0027, 0x060e,0x003d, 0x060e,0x0103,  +    0x060e,0x018b, 0x060e,0x0231, 0x060e,0x02d1, 0x0611,0x01fc, 0x0611,0x0234,  +    0x061a,0x0287, 0x061d,0x0214, 0x0621,0x01d4, 0x062a,0x0027, 0x062a,0x022d,  +    0x062e,0x009e, 0x062e,0x0106, 0x062e,0x0198, 0x0632,0x009e, 0x0632,0x0106,  +    0x0632,0x0198, 0x0639,0x0042, 0x0639,0x00b2, 0x0639,0x0108, 0x063d,0x01f8,  +    0x0641,0x0086, 0x0641,0x009a, 0x0641,0x00ec, 0x0641,0x0172, 0x0645,0x0044,  +    0x0649,0x0042, 0x0648,0x0087, 0x0648,0x00ed, 0x0648,0x0173, 0x0649,0x01a0,  +    0x0648,0x0241, 0x0648,0x026f, 0x0648,0x02df, 0x0648,0x0307, 0x064c,0x023a,  +    0x064c,0x02b3, 0x0651,0x0062, 0x0650,0x0217, 0x0651,0x02ac, 0x0650,0x02d6,  +    0x0655,0x0042, 0x065d,0x0042, 0x0664,0x02b1, 0x0664,0x02ce, 0x0669,0x0238,  +    0x066d,0x002a, 0x066c,0x0039, 0x066d,0x01f6, 0x066c,0x0213, 0x066c,0x022e,  +    0x066d,0x02a2, 0x066c,0x02e1, 0x0671,0x002a, 0x0670,0x0030, 0x0670,0x0067,  +    0x0670,0x00c9, 0x0670,0x01eb, 0x0670,0x01ef, 0x0670,0x02c3, 0x0675,0x0020,  +    0x0678,0x0133, 0x0678,0x0148, 0x067c,0x0027, 0x0681,0x023a, 0x0684,0x0021,  +    0x0684,0x00bf, 0x0684,0x00d0, 0x0689,0x01fc, 0x068e,0x0162, 0x068e,0x0183,  +    0x0691,0x0200, 0x0696,0x0023, 0x0696,0x00e0, 0x0696,0x00fb, 0x0696,0x0268,  +    0x069a,0x0282, 0x069d,0x007e, 0x06a2,0x004b, 0x06a2,0x023e, 0x06a2,0x02dc,  +    0x06a6,0x0097, 0x06aa,0x02b1, 0x06aa,0x02ce, 0x06ae,0x0039, 0x06ae,0x0213,  +    0x06ae,0x022e, 0x06ae,0x02e1, 0x06b2,0x0162, 0x06b2,0x0183, 0x06b6,0x0023,  +    0x06b6,0x00e0, 0x06b6,0x00fb, 0x06ba,0x008f, 0x06ba,0x01e4, 0x06be,0x034b,  +    0x06c1,0x0086, 0x06c1,0x009a, 0x06c1,0x00ec, 0x06c1,0x0172, 0x06c6,0x01da,  +    0x06c6,0x0280, 0x06c6,0x0351, 0x06ce,0x008f, 0x06d2,0x01e3, 0x06d2,0x0287,  +    0x06d2,0x0353, 0x06d6,0x027a, 0x06d6,0x029b, 0x06da,0x0033, 0x06da,0x01ce,  +    0x06da,0x01f1, 0x06de,0x0133, 0x06de,0x0148, 0x06e2,0x0021, 0x06e2,0x00bf,  +    0x06e2,0x00d0, 0x06e5,0x023a, 0x06e9,0x0004, 0x06ee,0x028c, 0x06ee,0x0338,  +    0x06f2,0x0328, 0x06f2,0x0330, 0x06f4,0x0005, 0x06f9,0x01e0, 0x06fe,0x0328,  +    0x06fe,0x0330, 0x0702,0x003d, 0x0702,0x00f3, 0x0702,0x0330, 0x0704,0x0003,  +    0x070a,0x003d, 0x070a,0x00f3, 0x070a,0x01d4, 0x070a,0x01f3, 0x070a,0x0330,  +    0x0711,0x032a, 0x0711,0x032e, 0x0716,0x003d, 0x0718,0x0205, 0x0718,0x0282,  +    0x071e,0x00f3, 0x0720,0x01dc, 0x0720,0x02a5, 0x0726,0x0324, 0x072a,0x028a,  +    0x072a,0x02a7, 0x0729,0x031c, 0x0729,0x032a, 0x072e,0x003d, 0x072e,0x00f9,  +    0x072e,0x022d, 0x072e,0x0248, 0x072e,0x02e4, 0x0730,0x003d, 0x0730,0x0247,  +    0x0730,0x02e3, 0x0730,0x0324, 0x0732,0x0324, 0x0739,0x032e, 0x073e,0x003d,  +    0x0740,0x003d, 0x0744,0x027a, 0x0744,0x029b, 0x0748,0x0033, 0x0748,0x01ce,  +    0x0748,0x01f1, 0x074c,0x0162, 0x074c,0x0183, 0x0750,0x0023, 0x0750,0x00e0,  +    0x0750,0x00fb, 0x0755,0x0246, 0x075a,0x0095, 0x075a,0x0397, 0x075d,0x0004,  +    0x076a,0x03b3, 0x076d,0x0002, 0x0772,0x02fb, 0x0772,0x0301, 0x0772,0x0315,  +    0x0772,0x0397, 0x0776,0x008f, 0x077e,0x0027, 0x078a,0x00a1, 0x0792,0x009d,  +    0x0792,0x00c3, 0x0792,0x02fb, 0x0792,0x0301, 0x0792,0x0315, 0x0792,0x03bd,  +    0x0796,0x0027, 0x0796,0x024f, 0x079e,0x009d, 0x07a6,0x009d, 0x07a6,0x02fb,  +    0x07a6,0x0301, 0x07a6,0x0315, 0x07a6,0x03bd, 0x07aa,0x0027, 0x07aa,0x024f,  +    0x07ae,0x009d, 0x07b9,0x004e, 0x07b8,0x0087, 0x07b8,0x00ed, 0x07b8,0x0173,  +    0x07b8,0x0197, 0x07b9,0x021a, 0x07b9,0x02b8, 0x07b9,0x0364, 0x07be,0x0029,  +    0x07be,0x0030, 0x07c0,0x017b, 0x07c6,0x017b, 0x07c8,0x00f3, 0x07ce,0x00f3,  +    0x07d0,0x008f, 0x07d6,0x008f, 0x07d9,0x01e8, 0x07dd,0x0292, 0x07e2,0x0053,  +    0x07e6,0x008f, 0x07e6,0x00f3, 0x07e6,0x017b, 0x07e8,0x0029, 0x07e8,0x0030,  +    0x07ec,0x0021, 0x07ec,0x02ad, 0x07f2,0x0181, 0x07f2,0x0315, 0x07f4,0x0021,  +    0x07f8,0x020f, 0x07fd,0x002e, 0x0800,0x008f, 0x0805,0x0006, 0x0809,0x03c2,  +    0x080d,0x0084, 0x0812,0x0009, 0x0811,0x0008, 0x0812,0x00f3, 0x0812,0x00f9,  +    0x0812,0x017b, 0x0812,0x0181, 0x0814,0x0033, 0x0818,0x0023, 0x081c,0x0285,  +    0x0826,0x03bd, 0x082c,0x008f, 0x082c,0x017b, 0x0832,0x0043, 0x0832,0x011b,  +    0x0832,0x01b3, 0x0832,0x01c3, 0x0835,0x032a, 0x0838,0x0085, 0x0839,0x032a,  +    0x083e,0x0049, 0x083d,0x0084, 0x083e,0x02fb, 0x083e,0x0301, 0x083e,0x0315,  +    0x083e,0x0397, 0x0842,0x0009, 0x0841,0x0008, 0x0844,0x0009, 0x0846,0x008f,  +    0x084a,0x0033, 0x084e,0x0285, 0x0851,0x009a, 0x0856,0x00a1, 0x0859,0x031c,  +    0x085d,0x00b2, 0x0861,0x0012, 0x0861,0x02cc, 0x0865,0x0058, 0x0865,0x007e,  +    0x0869,0x004a, 0x0871,0x0010, 0x0876,0x003d, 0x0879,0x032c, 0x087e,0x0089,  +    0x0882,0x0229, 0x0882,0x022d, 0x0882,0x02c7, 0x0882,0x02cb, 0x0886,0x0021,  +    0x0886,0x02ad, 0x0885,0x0356, 0x088a,0x0017, 0x088a,0x020f, 0x0889,0x0354,  +    0x088d,0x009c, 0x0892,0x0089, 0x0895,0x0246, 0x089a,0x03bd, 0x089e,0x008f,  +    0x089e,0x02f9, 0x089e,0x0313, 0x08a1,0x032a, 0x08a6,0x0053, 0x08a6,0x0095,  +    0x08a6,0x0397, 0x08a8,0x017b, 0x08ad,0x031a, 0x08b2,0x017b, 0x08b4,0x00f3,  +    0x08b5,0x02a0, 0x08b8,0x0089, 0x08c1,0x0024, 0x08c4,0x00f3, 0x08c9,0x007e,  +    0x08cd,0x007c, 0x08cd,0x0222, 0x08cd,0x0294, 0x08d1,0x003a, 0x08d6,0x0009,  +    0x08d9,0x003a, 0x08dc,0x001f, 0x08e0,0x008f, 0x08e0,0x017b, 0x08e4,0x0009,  +    0x08e8,0x01ed, 0x08ed,0x031c, 0x08f2,0x003d, 0x08f6,0x008f, 0x08f6,0x017b,  +    0x08fa,0x0009, 0x08fe,0x003d, 0x0902,0x01e9, 0x0904,0x01e9, 0x0904,0x0381,  +    0x090a,0x03b1, 0x090d,0x031a, 0x0910,0x0299, 0x0914,0x034b, 0x0919,0x0008,  +    0x091c,0x0033, 0x091c,0x003d, 0x0920,0x0027, 0x0924,0x0027, 0x0924,0x01fb,  +    0x092a,0x01ce, 0x092a,0x01f1, 0x092d,0x031c, 0x0930,0x001f, 0x0936,0x00c5,  +    0x0938,0x00c5, 0x0938,0x0381, 0x093c,0x001b, 0x0942,0x017d, 0x094a,0x0027,  +    0x094e,0x0027, 0x094e,0x01fb, 0x0952,0x03b1, 0x095a,0x0029, 0x095a,0x0030,  +    0x095d,0x0030, 0x0961,0x0030, 0x0966,0x02f9, 0x0966,0x0313, 0x0968,0x02eb,  +    0x096d,0x0008, 0x0970,0x017b, 0x0974,0x0033, 0x0979,0x0150, 0x097d,0x009a,  +    0x0982,0x0293, 0x0984,0x0293, 0x0984,0x0379, 0x098a,0x02eb, 0x098e,0x0009,  +    0x0992,0x003d, 0x0996,0x003d, 0x0999,0x0062, 0x099e,0x003d, 0x09a0,0x0027,  +    0x09a5,0x0144, 0x09a8,0x02b5, 0x09ae,0x008f, 0x09ae,0x009d, 0x09b2,0x004d,  +    0x09b2,0x0053, 0x09b2,0x00c3, 0x09b2,0x013d, 0x09b2,0x01c5, 0x09b2,0x0271,  +    0x09b4,0x0025, 0x09ba,0x0033, 0x09ba,0x0079, 0x09bc,0x0015, 0x09c2,0x013f,  +    0x09c4,0x013f, 0x09c4,0x0379, 0x09ca,0x02b5, 0x09cd,0x0006, 0x09da,0x0009,  +    0x09d9,0x0008, 0x09dc,0x000b, 0x09dc,0x004f, 0x09dd,0x0086, 0x09e0,0x0009,  +    0x09e6,0x00a1, 0x09e8,0x0009, 0x09ed,0x0086, 0x09f2,0x001f, 0x09f2,0x002f,  +    0x09f2,0x0049, 0x09f2,0x006f, 0x09f2,0x0085, 0x09f2,0x0091, 0x09f2,0x00a9,  +    0x09f2,0x00d3, 0x09f2,0x00d7, 0x09f2,0x011d, 0x09f2,0x0121, 0x09f2,0x0235,  +    0x09f2,0x0393, 0x09f6,0x0324, 0x09f8,0x0049, 0x09f8,0x00a9, 0x09f8,0x011d,  +    0x09fe,0x001f, 0x09fe,0x0029, 0x09fe,0x0033, 0x09fe,0x003d, 0x09fe,0x0085,  +    0x09fe,0x008f, 0x09fe,0x00d3, 0x0a00,0x003d, 0x0a06,0x012d, 0x0a0e,0x00b3,  +    0x0a10,0x000b, 0x0a10,0x0387, 0x0a16,0x0059, 0x0a18,0x0009, 0x0a1e,0x0043,  +    0x0a24,0x0085, 0x0a2a,0x0009, 0x0a2d,0x0008, 0x0a32,0x028a, 0x0a32,0x02a7,  +    0x0a31,0x031c, 0x0a35,0x032e, 0x0a39,0x0006, 0x0a3a,0x0105, 0x0a3a,0x024f,  +    0x0a3c,0x0299, 0x0a42,0x01ed, 0x0a46,0x0299, 0x0a48,0x01ed, 0x0a4c,0x0059,  +    0x0a52,0x000b, 0x0a52,0x0387, 0x0a56,0x000b, 0x0a5e,0x0009, 0x0a60,0x003d,  +    0x0a66,0x0105, 0x0a6a,0x0195, 0x0a6c,0x000b, 0x0a76,0x0053, 0x0a78,0x0009,  +    0x0a7a,0x008f, 0x0a82,0x0299, 0x0a86,0x01ed, 0x0a8a,0x0027, 0x0a8e,0x004b,  +    0x0a92,0x003d, 0x0a95,0x0322, 0x0a99,0x0038, 0x0a99,0x0090, 0x0a9c,0x0061,  +    0x0a9c,0x00c7, 0x0a9c,0x012d, 0x0a9c,0x016f, 0x0a9c,0x017d, 0x0a9c,0x02c9,  +    0x0a9c,0x0383, 0x0aa1,0x0010, 0x0aa4,0x00b3, 0x0aa8,0x002f, 0x0aac,0x0027,  +    0x0ab0,0x004b, 0x0ab4,0x0043, 0x0ab9,0x0090, 0x0abd,0x0010, 0x0ac4,0x0019,  +    0x0acc,0x00f5, 0x0acc,0x022b, 0x0acc,0x037b, 0x0ad2,0x008f, 0x0ad2,0x01f1,  +    0x0ad6,0x0324, 0x0ad9,0x0330, 0x0ade,0x008f, 0x0ade,0x01f1, 0x0ae0,0x017b,  +    0x0ae4,0x008f, 0x0ae9,0x004e, 0x0aee,0x0027, 0x0af2,0x028a, 0x0af2,0x02a7,  +    0x0af1,0x031c, 0x0af6,0x0027, 0x0af9,0x031c, 0x0afe,0x00e9, 0x0afe,0x02bb,  +    0x0b02,0x000b, 0x0b06,0x00f5, 0x0b06,0x022b, 0x0b06,0x037b, 0x0b0a,0x003d,  +    0x0000,0x0000  +}; + + diff --git a/src/temp/vec/module.make b/src/temp/vec/module.make new file mode 100644 index 00000000..d6d908e7 --- /dev/null +++ b/src/temp/vec/module.make @@ -0,0 +1 @@ +SRC +=  diff --git a/src/temp/vec/vec.h b/src/temp/vec/vec.h new file mode 100644 index 00000000..6ab23298 --- /dev/null +++ b/src/temp/vec/vec.h @@ -0,0 +1,66 @@ +/**CFile**************************************************************** + +  FileName    [vec.h] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [Resizable arrays.] + +  Synopsis    [External declarations.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - June 20, 2005.] + +  Revision    [$Id: vec.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ +  +#ifndef __VEC_H__ +#define __VEC_H__ + +#ifdef __cplusplus +extern "C" { +#endif + +//////////////////////////////////////////////////////////////////////// +///                          INCLUDES                                /// +//////////////////////////////////////////////////////////////////////// + +#ifdef _WIN32 +#define inline __inline // compatible with MS VS 6.0 +#endif + +#include "vecInt.h" +#include "vecStr.h" +#include "vecPtr.h" +#include "vecVec.h" + +//////////////////////////////////////////////////////////////////////// +///                         PARAMETERS                               /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +///                         BASIC TYPES                              /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +///                      MACRO DEFINITIONS                           /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +///                    FUNCTION DECLARATIONS                         /// +//////////////////////////////////////////////////////////////////////// + +#ifdef __cplusplus +} +#endif + +#endif + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + diff --git a/src/temp/vec/vecInt.h b/src/temp/vec/vecInt.h new file mode 100644 index 00000000..4f193cf2 --- /dev/null +++ b/src/temp/vec/vecInt.h @@ -0,0 +1,753 @@ +/**CFile**************************************************************** + +  FileName    [vecInt.h] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [Resizable arrays.] + +  Synopsis    [Resizable arrays of integers.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - June 20, 2005.] + +  Revision    [$Id: vecInt.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ +  +#ifndef __VEC_INT_H__ +#define __VEC_INT_H__ + +//////////////////////////////////////////////////////////////////////// +///                          INCLUDES                                /// +//////////////////////////////////////////////////////////////////////// + +#include "extra.h" + +//////////////////////////////////////////////////////////////////////// +///                         PARAMETERS                               /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +///                         BASIC TYPES                              /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Vec_Int_t_       Vec_Int_t; +struct Vec_Int_t_  +{ +    int              nCap; +    int              nSize; +    int *            pArray; +}; + +//////////////////////////////////////////////////////////////////////// +///                      MACRO DEFINITIONS                           /// +//////////////////////////////////////////////////////////////////////// + +#define Vec_IntForEachEntry( vVec, Entry, i )                                               \ +    for ( i = 0; (i < Vec_IntSize(vVec)) && (((Entry) = Vec_IntEntry(vVec, i)), 1); i++ ) +#define Vec_IntForEachEntryStart( vVec, Entry, i, Start )                                   \ +    for ( i = Start; (i < Vec_IntSize(vVec)) && (((Entry) = Vec_IntEntry(vVec, i)), 1); i++ ) +#define Vec_IntForEachEntryStartStop( vVec, Entry, i, Start, Stop )                         \ +    for ( i = Start; (i < Stop) && (((Entry) = Vec_IntEntry(vVec, i)), 1); i++ ) +#define Vec_IntForEachEntryReverse( vVec, pEntry, i )                                       \ +    for ( i = Vec_IntSize(vVec) - 1; (i >= 0) && (((pEntry) = Vec_IntEntry(vVec, i)), 1); i-- ) + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [Allocates a vector with the given capacity.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline Vec_Int_t * Vec_IntAlloc( int nCap ) +{ +    Vec_Int_t * p; +    p = ALLOC( Vec_Int_t, 1 ); +    if ( nCap > 0 && nCap < 16 ) +        nCap = 16; +    p->nSize  = 0; +    p->nCap   = nCap; +    p->pArray = p->nCap? ALLOC( int, p->nCap ) : NULL; +    return p; +} + +/**Function************************************************************* + +  Synopsis    [Allocates a vector with the given size and cleans it.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline Vec_Int_t * Vec_IntStart( int nSize ) +{ +    Vec_Int_t * p; +    p = Vec_IntAlloc( nSize ); +    p->nSize = nSize; +    memset( p->pArray, 0, sizeof(int) * nSize ); +    return p; +} + +/**Function************************************************************* + +  Synopsis    [Creates the vector from an integer array of the given size.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline Vec_Int_t * Vec_IntAllocArray( int * pArray, int nSize ) +{ +    Vec_Int_t * p; +    p = ALLOC( Vec_Int_t, 1 ); +    p->nSize  = nSize; +    p->nCap   = nSize; +    p->pArray = pArray; +    return p; +} + +/**Function************************************************************* + +  Synopsis    [Creates the vector from an integer array of the given size.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline Vec_Int_t * Vec_IntAllocArrayCopy( int * pArray, int nSize ) +{ +    Vec_Int_t * p; +    p = ALLOC( Vec_Int_t, 1 ); +    p->nSize  = nSize; +    p->nCap   = nSize; +    p->pArray = ALLOC( int, nSize ); +    memcpy( p->pArray, pArray, sizeof(int) * nSize ); +    return p; +} + +/**Function************************************************************* + +  Synopsis    [Duplicates the integer array.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline Vec_Int_t * Vec_IntDup( Vec_Int_t * pVec ) +{ +    Vec_Int_t * p; +    p = ALLOC( Vec_Int_t, 1 ); +    p->nSize  = pVec->nSize; +    p->nCap   = pVec->nCap; +    p->pArray = p->nCap? ALLOC( int, p->nCap ) : NULL; +    memcpy( p->pArray, pVec->pArray, sizeof(int) * pVec->nSize ); +    return p; +} + +/**Function************************************************************* + +  Synopsis    [Transfers the array into another vector.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline Vec_Int_t * Vec_IntDupArray( Vec_Int_t * pVec ) +{ +    Vec_Int_t * p; +    p = ALLOC( Vec_Int_t, 1 ); +    p->nSize  = pVec->nSize; +    p->nCap   = pVec->nCap; +    p->pArray = pVec->pArray; +    pVec->nSize  = 0; +    pVec->nCap   = 0; +    pVec->pArray = NULL; +    return p; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Vec_IntFree( Vec_Int_t * p ) +{ +    FREE( p->pArray ); +    FREE( p ); +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int * Vec_IntReleaseArray( Vec_Int_t * p ) +{ +    int * pArray = p->pArray; +    p->nCap = 0; +    p->nSize = 0; +    p->pArray = NULL; +    return pArray; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int * Vec_IntArray( Vec_Int_t * p ) +{ +    return p->pArray; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Vec_IntSize( Vec_Int_t * p ) +{ +    return p->nSize; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Vec_IntEntry( Vec_Int_t * p, int i ) +{ +    assert( i >= 0 && i < p->nSize ); +    return p->pArray[i]; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Vec_IntWriteEntry( Vec_Int_t * p, int i, int Entry ) +{ +    assert( i >= 0 && i < p->nSize ); +    p->pArray[i] = Entry; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Vec_IntAddToEntry( Vec_Int_t * p, int i, int Addition ) +{ +    assert( i >= 0 && i < p->nSize ); +    p->pArray[i] += Addition; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Vec_IntEntryLast( Vec_Int_t * p ) +{ +    assert( p->nSize > 0 ); +    return p->pArray[p->nSize-1]; +} + +/**Function************************************************************* + +  Synopsis    [Resizes the vector to the given capacity.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Vec_IntGrow( Vec_Int_t * p, int nCapMin ) +{ +    if ( p->nCap >= nCapMin ) +        return; +    p->pArray = REALLOC( int, p->pArray, nCapMin );  +    assert( p->pArray ); +    p->nCap   = nCapMin; +} + +/**Function************************************************************* + +  Synopsis    [Fills the vector with given number of entries.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Vec_IntFill( Vec_Int_t * p, int nSize, int Entry ) +{ +    int i; +    Vec_IntGrow( p, nSize ); +    for ( i = 0; i < nSize; i++ ) +        p->pArray[i] = Entry; +    p->nSize = nSize; +} + +/**Function************************************************************* + +  Synopsis    [Fills the vector with given number of entries.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Vec_IntFillExtra( Vec_Int_t * p, int nSize, int Entry ) +{ +    int i; +    if ( p->nSize >= nSize ) +        return; +    Vec_IntGrow( p, nSize ); +    for ( i = p->nSize; i < nSize; i++ ) +        p->pArray[i] = Entry; +    p->nSize = nSize; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Vec_IntShrink( Vec_Int_t * p, int nSizeNew ) +{ +    assert( p->nSize >= nSizeNew ); +    p->nSize = nSizeNew; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Vec_IntClear( Vec_Int_t * p ) +{ +    p->nSize = 0; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Vec_IntPush( Vec_Int_t * p, int Entry ) +{ +    if ( p->nSize == p->nCap ) +    { +        if ( p->nCap < 16 ) +            Vec_IntGrow( p, 16 ); +        else +            Vec_IntGrow( p, 2 * p->nCap ); +    } +    p->pArray[p->nSize++] = Entry; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Vec_IntPushFirst( Vec_Int_t * p, int Entry ) +{ +    int i; +    if ( p->nSize == p->nCap ) +    { +        if ( p->nCap < 16 ) +            Vec_IntGrow( p, 16 ); +        else +            Vec_IntGrow( p, 2 * p->nCap ); +    } +    p->nSize++; +    for ( i = p->nSize - 1; i >= 1; i-- ) +        p->pArray[i] = p->pArray[i-1]; +    p->pArray[0] = Entry; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Vec_IntPushMem( Extra_MmStep_t * pMemMan, Vec_Int_t * p, int Entry ) +{ +    if ( p->nSize == p->nCap ) +    { +        int * pArray; +        int i; + +        if ( p->nSize == 0 ) +            p->nCap = 1; +        pArray = (int *)Extra_MmStepEntryFetch( pMemMan, p->nCap * 8 ); +//        pArray = ALLOC( int, p->nCap * 2 ); +        if ( p->pArray ) +        { +            for ( i = 0; i < p->nSize; i++ ) +                pArray[i] = p->pArray[i]; +            Extra_MmStepEntryRecycle( pMemMan, (char *)p->pArray, p->nCap * 4 ); +//            free( p->pArray ); +        } +        p->nCap *= 2; +        p->pArray = pArray; +    } +    p->pArray[p->nSize++] = Entry; +} + +/**Function************************************************************* + +  Synopsis    [Inserts the entry while preserving the increasing order.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Vec_IntPushOrder( Vec_Int_t * p, int Entry ) +{ +    int i; +    if ( p->nSize == p->nCap ) +    { +        if ( p->nCap < 16 ) +            Vec_IntGrow( p, 16 ); +        else +            Vec_IntGrow( p, 2 * p->nCap ); +    } +    p->nSize++; +    for ( i = p->nSize-2; i >= 0; i-- ) +        if ( p->pArray[i] > Entry ) +            p->pArray[i+1] = p->pArray[i]; +        else +            break; +    p->pArray[i+1] = Entry; +} + +/**Function************************************************************* + +  Synopsis    [Inserts the entry while preserving the increasing order.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Vec_IntPushUniqueOrder( Vec_Int_t * p, int Entry ) +{ +    int i; +    for ( i = 0; i < p->nSize; i++ ) +        if ( p->pArray[i] == Entry ) +            return 1; +    Vec_IntPushOrder( p, Entry ); +    return 0; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Vec_IntPushUnique( Vec_Int_t * p, int Entry ) +{ +    int i; +    for ( i = 0; i < p->nSize; i++ ) +        if ( p->pArray[i] == Entry ) +            return 1; +    Vec_IntPush( p, Entry ); +    return 0; +} + +/**Function************************************************************* + +  Synopsis    [Returns the last entry and removes it from the list.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Vec_IntPop( Vec_Int_t * p ) +{ +    assert( p->nSize > 0 ); +    return p->pArray[--p->nSize]; +} + +/**Function************************************************************* + +  Synopsis    [Find entry.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Vec_IntFind( Vec_Int_t * p, int Entry ) +{ +    int i; +    for ( i = 0; i < p->nSize; i++ ) +        if ( p->pArray[i] == Entry ) +            return i; +    return -1; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Vec_IntRemove( Vec_Int_t * p, int Entry ) +{ +    int i; +    for ( i = 0; i < p->nSize; i++ ) +        if ( p->pArray[i] == Entry ) +            break; +    if ( i == p->nSize ) +        return 0; +    assert( i < p->nSize ); +    for ( i++; i < p->nSize; i++ ) +        p->pArray[i-1] = p->pArray[i]; +    p->nSize--; +    return 1; +} + +/**Function************************************************************* + +  Synopsis    [Comparison procedure for two integers.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Vec_IntSortCompare1( int * pp1, int * pp2 ) +{ +    // for some reason commenting out lines (as shown) led to crashing of the release version +    if ( *pp1 < *pp2 ) +        return -1; +    if ( *pp1 > *pp2 ) // +        return 1; +    return 0; // +} + +/**Function************************************************************* + +  Synopsis    [Comparison procedure for two integers.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Vec_IntSortCompare2( int * pp1, int * pp2 ) +{ +    // for some reason commenting out lines (as shown) led to crashing of the release version +    if ( *pp1 > *pp2 ) +        return -1; +    if ( *pp1 < *pp2 ) // +        return 1; +    return 0; // +} + +/**Function************************************************************* + +  Synopsis    [Sorting the entries by their integer value.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Vec_IntSort( Vec_Int_t * p, int fReverse ) +{ +    if ( fReverse )  +        qsort( (void *)p->pArray, p->nSize, sizeof(int),  +                (int (*)(const void *, const void *)) Vec_IntSortCompare2 ); +    else +        qsort( (void *)p->pArray, p->nSize, sizeof(int),  +                (int (*)(const void *, const void *)) Vec_IntSortCompare1 ); +} + + +/**Function************************************************************* + +  Synopsis    [Comparison procedure for two integers.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Vec_IntSortCompareUnsigned( unsigned * pp1, unsigned * pp2 ) +{ +    if ( *pp1 < *pp2 ) +        return -1; +    if ( *pp1 > *pp2 ) +        return 1; +    return 0; +} + +/**Function************************************************************* + +  Synopsis    [Sorting the entries by their integer value.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Vec_IntSortUnsigned( Vec_Int_t * p ) +{ +    qsort( (void *)p->pArray, p->nSize, sizeof(int),  +            (int (*)(const void *, const void *)) Vec_IntSortCompareUnsigned ); +} + +#endif + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + diff --git a/src/temp/vec/vecPtr.h b/src/temp/vec/vecPtr.h new file mode 100644 index 00000000..96975ff0 --- /dev/null +++ b/src/temp/vec/vecPtr.h @@ -0,0 +1,559 @@ +/**CFile**************************************************************** + +  FileName    [vecPtr.h] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [Resizable arrays.] + +  Synopsis    [Resizable arrays of generic pointers.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - June 20, 2005.] + +  Revision    [$Id: vecPtr.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ +  +#ifndef __VEC_PTR_H__ +#define __VEC_PTR_H__ + +//////////////////////////////////////////////////////////////////////// +///                          INCLUDES                                /// +//////////////////////////////////////////////////////////////////////// + +#include <stdio.h> +#include "extra.h" + +//////////////////////////////////////////////////////////////////////// +///                         PARAMETERS                               /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +///                         BASIC TYPES                              /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Vec_Ptr_t_       Vec_Ptr_t; +struct Vec_Ptr_t_  +{ +    int              nCap; +    int              nSize; +    void **          pArray; +}; + +//////////////////////////////////////////////////////////////////////// +///                      MACRO DEFINITIONS                           /// +//////////////////////////////////////////////////////////////////////// + +// iterators through entries +#define Vec_PtrForEachEntry( vVec, pEntry, i )                                               \ +    for ( i = 0; (i < Vec_PtrSize(vVec)) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i++ ) +#define Vec_PtrForEachEntryStart( vVec, pEntry, i, Start )                                   \ +    for ( i = Start; (i < Vec_PtrSize(vVec)) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i++ ) +#define Vec_PtrForEachEntryStop( vVec, pEntry, i, Stop )                                     \ +    for ( i = 0; (i < Stop) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i++ ) +#define Vec_PtrForEachEntryStartStop( vVec, pEntry, i, Start, Stop )                         \ +    for ( i = Start; (i < Stop) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i++ ) +#define Vec_PtrForEachEntryReverse( vVec, pEntry, i )                                        \ +    for ( i = Vec_PtrSize(vVec) - 1; (i >= 0) && (((pEntry) = Vec_PtrEntry(vVec, i)), 1); i-- ) + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [Allocates a vector with the given capacity.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline Vec_Ptr_t * Vec_PtrAlloc( int nCap ) +{ +    Vec_Ptr_t * p; +    p = ALLOC( Vec_Ptr_t, 1 ); +    if ( nCap > 0 && nCap < 8 ) +        nCap = 8; +    p->nSize  = 0; +    p->nCap   = nCap; +    p->pArray = p->nCap? ALLOC( void *, p->nCap ) : NULL; +    return p; +} + +/**Function************************************************************* + +  Synopsis    [Allocates a vector with the given size and cleans it.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline Vec_Ptr_t * Vec_PtrStart( int nSize ) +{ +    Vec_Ptr_t * p; +    p = Vec_PtrAlloc( nSize ); +    p->nSize = nSize; +    memset( p->pArray, 0, sizeof(void *) * nSize ); +    return p; +} + +/**Function************************************************************* + +  Synopsis    [Creates the vector from an integer array of the given size.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline Vec_Ptr_t * Vec_PtrAllocArray( void ** pArray, int nSize ) +{ +    Vec_Ptr_t * p; +    p = ALLOC( Vec_Ptr_t, 1 ); +    p->nSize  = nSize; +    p->nCap   = nSize; +    p->pArray = pArray; +    return p; +} + +/**Function************************************************************* + +  Synopsis    [Creates the vector from an integer array of the given size.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline Vec_Ptr_t * Vec_PtrAllocArrayCopy( void ** pArray, int nSize ) +{ +    Vec_Ptr_t * p; +    p = ALLOC( Vec_Ptr_t, 1 ); +    p->nSize  = nSize; +    p->nCap   = nSize; +    p->pArray = ALLOC( void *, nSize ); +    memcpy( p->pArray, pArray, sizeof(void *) * nSize ); +    return p; +} + +/**Function************************************************************* + +  Synopsis    [Duplicates the integer array.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline Vec_Ptr_t * Vec_PtrDup( Vec_Ptr_t * pVec ) +{ +    Vec_Ptr_t * p; +    p = ALLOC( Vec_Ptr_t, 1 ); +    p->nSize  = pVec->nSize; +    p->nCap   = pVec->nCap; +    p->pArray = p->nCap? ALLOC( void *, p->nCap ) : NULL; +    memcpy( p->pArray, pVec->pArray, sizeof(void *) * pVec->nSize ); +    return p; +} + +/**Function************************************************************* + +  Synopsis    [Transfers the array into another vector.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline Vec_Ptr_t * Vec_PtrDupArray( Vec_Ptr_t * pVec ) +{ +    Vec_Ptr_t * p; +    p = ALLOC( Vec_Ptr_t, 1 ); +    p->nSize  = pVec->nSize; +    p->nCap   = pVec->nCap; +    p->pArray = pVec->pArray; +    pVec->nSize  = 0; +    pVec->nCap   = 0; +    pVec->pArray = NULL; +    return p; +} + +/**Function************************************************************* + +  Synopsis    [Frees the vector.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Vec_PtrFree( Vec_Ptr_t * p ) +{ +    FREE( p->pArray ); +    FREE( p ); +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void ** Vec_PtrReleaseArray( Vec_Ptr_t * p ) +{ +    void ** pArray = p->pArray; +    p->nCap = 0; +    p->nSize = 0; +    p->pArray = NULL; +    return pArray; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void ** Vec_PtrArray( Vec_Ptr_t * p ) +{ +    return p->pArray; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Vec_PtrSize( Vec_Ptr_t * p ) +{ +    return p->nSize; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void * Vec_PtrEntry( Vec_Ptr_t * p, int i ) +{ +    assert( i >= 0 && i < p->nSize ); +    return p->pArray[i]; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Vec_PtrWriteEntry( Vec_Ptr_t * p, int i, void * Entry ) +{ +    assert( i >= 0 && i < p->nSize ); +    p->pArray[i] = Entry; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void * Vec_PtrEntryLast( Vec_Ptr_t * p ) +{ +    assert( p->nSize > 0 ); +    return p->pArray[p->nSize-1]; +} + +/**Function************************************************************* + +  Synopsis    [Resizes the vector to the given capacity.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Vec_PtrGrow( Vec_Ptr_t * p, int nCapMin ) +{ +    if ( p->nCap >= nCapMin ) +        return; +    p->pArray = REALLOC( void *, p->pArray, nCapMin );  +    p->nCap   = nCapMin; +} + +/**Function************************************************************* + +  Synopsis    [Fills the vector with given number of entries.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Vec_PtrFill( Vec_Ptr_t * p, int nSize, void * Entry ) +{ +    int i; +    Vec_PtrGrow( p, nSize ); +    for ( i = 0; i < nSize; i++ ) +        p->pArray[i] = Entry; +    p->nSize = nSize; +} + +/**Function************************************************************* + +  Synopsis    [Fills the vector with given number of entries.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Vec_PtrFillExtra( Vec_Ptr_t * p, int nSize, void * Entry ) +{ +    int i; +    if ( p->nSize >= nSize ) +        return; +    Vec_PtrGrow( p, nSize ); +    for ( i = p->nSize; i < nSize; i++ ) +        p->pArray[i] = Entry; +    p->nSize = nSize; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Vec_PtrShrink( Vec_Ptr_t * p, int nSizeNew ) +{ +    assert( p->nSize >= nSizeNew ); +    p->nSize = nSizeNew; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Vec_PtrClear( Vec_Ptr_t * p ) +{ +    p->nSize = 0; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Vec_PtrPush( Vec_Ptr_t * p, void * Entry ) +{ +    if ( p->nSize == p->nCap ) +    { +        if ( p->nCap < 16 ) +            Vec_PtrGrow( p, 16 ); +        else +            Vec_PtrGrow( p, 2 * p->nCap ); +    } +    p->pArray[p->nSize++] = Entry; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Vec_PtrPushUnique( Vec_Ptr_t * p, void * Entry ) +{ +    int i; +    for ( i = 0; i < p->nSize; i++ ) +        if ( p->pArray[i] == Entry ) +            return 1; +    Vec_PtrPush( p, Entry ); +    return 0; +} + +/**Function************************************************************* + +  Synopsis    [Returns the last entry and removes it from the list.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void * Vec_PtrPop( Vec_Ptr_t * p ) +{ +    assert( p->nSize > 0 ); +    return p->pArray[--p->nSize]; +} + +/**Function************************************************************* + +  Synopsis    [Find entry.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Vec_PtrFind( Vec_Ptr_t * p, void * Entry ) +{ +    int i; +    for ( i = 0; i < p->nSize; i++ ) +        if ( p->pArray[i] == Entry ) +            return i; +    return -1; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Vec_PtrRemove( Vec_Ptr_t * p, void * Entry ) +{ +    int i; +    for ( i = 0; i < p->nSize; i++ ) +        if ( p->pArray[i] == Entry ) +            break; +    assert( i < p->nSize ); +    for ( i++; i < p->nSize; i++ ) +        p->pArray[i-1] = p->pArray[i]; +    p->nSize--; +} + +/**Function************************************************************* + +  Synopsis    [Moves the first nItems to the end.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Vec_PtrReorder( Vec_Ptr_t * p, int nItems ) +{ +    assert( nItems < p->nSize ); +    Vec_PtrGrow( p, nItems + p->nSize ); +    memmove( (char **)p->pArray + p->nSize, p->pArray, nItems * sizeof(void*) ); +    memmove( p->pArray, (char **)p->pArray + nItems, p->nSize * sizeof(void*) ); +} + +/**Function************************************************************* + +  Synopsis    [Sorting the entries by their integer value.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Vec_PtrSort( Vec_Ptr_t * p, int (*Vec_PtrSortCompare)() ) +{ +    qsort( (void *)p->pArray, p->nSize, sizeof(void *),  +            (int (*)(const void *, const void *)) Vec_PtrSortCompare ); +} + +#endif + + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + diff --git a/src/temp/vec/vecStr.h b/src/temp/vec/vecStr.h new file mode 100644 index 00000000..eb6aa41d --- /dev/null +++ b/src/temp/vec/vecStr.h @@ -0,0 +1,510 @@ +/**CFile**************************************************************** + +  FileName    [vecStr.h] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [Resizable arrays.] + +  Synopsis    [Resizable arrays of characters.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - June 20, 2005.] + +  Revision    [$Id: vecStr.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ +  +#ifndef __VEC_STR_H__ +#define __VEC_STR_H__ + +//////////////////////////////////////////////////////////////////////// +///                          INCLUDES                                /// +//////////////////////////////////////////////////////////////////////// + +#include <stdio.h> +#include "extra.h" + +//////////////////////////////////////////////////////////////////////// +///                         PARAMETERS                               /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +///                         BASIC TYPES                              /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Vec_Str_t_       Vec_Str_t; +struct Vec_Str_t_  +{ +    int              nCap; +    int              nSize; +    char *           pArray; +}; + +//////////////////////////////////////////////////////////////////////// +///                      MACRO DEFINITIONS                           /// +//////////////////////////////////////////////////////////////////////// + +#define Vec_StrForEachEntry( vVec, Entry, i )                                               \ +    for ( i = 0; (i < Vec_StrSize(vVec)) && (((Entry) = Vec_StrEntry(vVec, i)), 1); i++ )    + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [Allocates a vector with the given capacity.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline Vec_Str_t * Vec_StrAlloc( int nCap ) +{ +    Vec_Str_t * p; +    p = ALLOC( Vec_Str_t, 1 ); +    if ( nCap > 0 && nCap < 16 ) +        nCap = 16; +    p->nSize  = 0; +    p->nCap   = nCap; +    p->pArray = p->nCap? ALLOC( char, p->nCap ) : NULL; +    return p; +} + +/**Function************************************************************* + +  Synopsis    [Allocates a vector with the given size and cleans it.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline Vec_Str_t * Vec_StrStart( int nSize ) +{ +    Vec_Str_t * p; +    p = Vec_StrAlloc( nSize ); +    p->nSize = nSize; +    memset( p->pArray, 0, sizeof(char) * nSize ); +    return p; +} + +/**Function************************************************************* + +  Synopsis    [Creates the vector from an integer array of the given size.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline Vec_Str_t * Vec_StrAllocArray( char * pArray, int nSize ) +{ +    Vec_Str_t * p; +    p = ALLOC( Vec_Str_t, 1 ); +    p->nSize  = nSize; +    p->nCap   = nSize; +    p->pArray = pArray; +    return p; +} + +/**Function************************************************************* + +  Synopsis    [Creates the vector from an integer array of the given size.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline Vec_Str_t * Vec_StrAllocArrayCopy( char * pArray, int nSize ) +{ +    Vec_Str_t * p; +    p = ALLOC( Vec_Str_t, 1 ); +    p->nSize  = nSize; +    p->nCap   = nSize; +    p->pArray = ALLOC( char, nSize ); +    memcpy( p->pArray, pArray, sizeof(char) * nSize ); +    return p; +} + +/**Function************************************************************* + +  Synopsis    [Duplicates the integer array.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline Vec_Str_t * Vec_StrDup( Vec_Str_t * pVec ) +{ +    Vec_Str_t * p; +    p = ALLOC( Vec_Str_t, 1 ); +    p->nSize  = pVec->nSize; +    p->nCap   = pVec->nCap; +    p->pArray = p->nCap? ALLOC( char, p->nCap ) : NULL; +    memcpy( p->pArray, pVec->pArray, sizeof(char) * pVec->nSize ); +    return p; +} + +/**Function************************************************************* + +  Synopsis    [Transfers the array into another vector.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline Vec_Str_t * Vec_StrDupArray( Vec_Str_t * pVec ) +{ +    Vec_Str_t * p; +    p = ALLOC( Vec_Str_t, 1 ); +    p->nSize  = pVec->nSize; +    p->nCap   = pVec->nCap; +    p->pArray = pVec->pArray; +    pVec->nSize  = 0; +    pVec->nCap   = 0; +    pVec->pArray = NULL; +    return p; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Vec_StrFree( Vec_Str_t * p ) +{ +    FREE( p->pArray ); +    FREE( p ); +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline char * Vec_StrReleaseArray( Vec_Str_t * p ) +{ +    char * pArray = p->pArray; +    p->nCap = 0; +    p->nSize = 0; +    p->pArray = NULL; +    return pArray; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline char * Vec_StrArray( Vec_Str_t * p ) +{ +    return p->pArray; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Vec_StrSize( Vec_Str_t * p ) +{ +    return p->nSize; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline char Vec_StrEntry( Vec_Str_t * p, int i ) +{ +    assert( i >= 0 && i < p->nSize ); +    return p->pArray[i]; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Vec_StrWriteEntry( Vec_Str_t * p, int i, char Entry ) +{ +    assert( i >= 0 && i < p->nSize ); +    p->pArray[i] = Entry; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline char Vec_StrEntryLast( Vec_Str_t * p ) +{ +    assert( p->nSize > 0 ); +    return p->pArray[p->nSize-1]; +} + +/**Function************************************************************* + +  Synopsis    [Resizes the vector to the given capacity.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Vec_StrGrow( Vec_Str_t * p, int nCapMin ) +{ +    if ( p->nCap >= nCapMin ) +        return; +    p->pArray = REALLOC( char, p->pArray, 2 * nCapMin );  +    p->nCap   = 2 * nCapMin; +} + +/**Function************************************************************* + +  Synopsis    [Fills the vector with given number of entries.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Vec_StrFill( Vec_Str_t * p, int nSize, char Entry ) +{ +    int i; +    Vec_StrGrow( p, nSize ); +    p->nSize = nSize; +    for ( i = 0; i < p->nSize; i++ ) +        p->pArray[i] = Entry; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Vec_StrShrink( Vec_Str_t * p, int nSizeNew ) +{ +    assert( p->nSize >= nSizeNew ); +    p->nSize = nSizeNew; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Vec_StrClear( Vec_Str_t * p ) +{ +    p->nSize = 0; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Vec_StrPush( Vec_Str_t * p, char Entry ) +{ +    if ( p->nSize == p->nCap ) +    { +        if ( p->nCap < 16 ) +            Vec_StrGrow( p, 16 ); +        else +            Vec_StrGrow( p, 2 * p->nCap ); +    } +    p->pArray[p->nSize++] = Entry; +} + +/**Function************************************************************* + +  Synopsis    [Appends the string to the char vector.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Vec_StrAppend( Vec_Str_t * p, char * pString ) +{ +    int i, nLength = strlen(pString); +    Vec_StrGrow( p, p->nSize + nLength ); +    for ( i = 0; i < nLength; i++ ) +        p->pArray[p->nSize + i] = pString[i]; +    p->nSize += nLength; +} + +/**Function************************************************************* + +  Synopsis    [Returns the last entry and removes it from the list.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline char Vec_StrPop( Vec_Str_t * p ) +{ +    assert( p->nSize > 0 ); +    return p->pArray[--p->nSize]; +} + +/**Function************************************************************* + +  Synopsis    [Comparison procedure for two clauses.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Vec_StrSortCompare1( char * pp1, char * pp2 ) +{ +    // for some reason commenting out lines (as shown) led to crashing of the release version +    if ( *pp1 < *pp2 ) +        return -1; +    if ( *pp1 > *pp2 ) // +        return 1; +    return 0; // +} + +/**Function************************************************************* + +  Synopsis    [Comparison procedure for two clauses.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Vec_StrSortCompare2( char * pp1, char * pp2 ) +{ +    // for some reason commenting out lines (as shown) led to crashing of the release version +    if ( *pp1 > *pp2 ) +        return -1; +    if ( *pp1 < *pp2 ) // +        return 1; +    return 0; // +} + +/**Function************************************************************* + +  Synopsis    [Sorting the entries by their integer value.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Vec_StrSort( Vec_Str_t * p, int fReverse ) +{ +    if ( fReverse )  +        qsort( (void *)p->pArray, p->nSize, sizeof(char),  +                (int (*)(const void *, const void *)) Vec_StrSortCompare2 ); +    else +        qsort( (void *)p->pArray, p->nSize, sizeof(char),  +                (int (*)(const void *, const void *)) Vec_StrSortCompare1 ); +} + +#endif + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + diff --git a/src/temp/vec/vecVec.h b/src/temp/vec/vecVec.h new file mode 100644 index 00000000..5b725354 --- /dev/null +++ b/src/temp/vec/vecVec.h @@ -0,0 +1,289 @@ +/**CFile**************************************************************** + +  FileName    [vecVec.h] + +  SystemName  [ABC: Logic synthesis and verification system.] + +  PackageName [Resizable arrays.] + +  Synopsis    [Resizable vector of resizable vectors.] + +  Author      [Alan Mishchenko] +   +  Affiliation [UC Berkeley] + +  Date        [Ver. 1.0. Started - June 20, 2005.] + +  Revision    [$Id: vecVec.h,v 1.00 2005/06/20 00:00:00 alanmi Exp $] + +***********************************************************************/ +  +#ifndef __VEC_VEC_H__ +#define __VEC_VEC_H__ + +//////////////////////////////////////////////////////////////////////// +///                          INCLUDES                                /// +//////////////////////////////////////////////////////////////////////// + +#include <stdio.h> +#include "extra.h" + +//////////////////////////////////////////////////////////////////////// +///                         PARAMETERS                               /// +//////////////////////////////////////////////////////////////////////// + +//////////////////////////////////////////////////////////////////////// +///                         BASIC TYPES                              /// +//////////////////////////////////////////////////////////////////////// + +typedef struct Vec_Vec_t_       Vec_Vec_t; +struct Vec_Vec_t_  +{ +    int              nCap; +    int              nSize; +    void **          pArray; +}; + +//////////////////////////////////////////////////////////////////////// +///                      MACRO DEFINITIONS                           /// +//////////////////////////////////////////////////////////////////////// + +// iterators through levels  +#define Vec_VecForEachLevel( vGlob, vVec, i )                                                 \ +    for ( i = 0; (i < Vec_VecSize(vGlob)) && (((vVec) = (Vec_Ptr_t*)Vec_VecEntry(vGlob, i)), 1); i++ ) +#define Vec_VecForEachLevelStart( vGlob, vVec, i, LevelStart )                                \ +    for ( i = LevelStart; (i < Vec_VecSize(vGlob)) && (((vVec) = (Vec_Ptr_t*)Vec_VecEntry(vGlob, i)), 1); i++ ) +#define Vec_VecForEachLevelStartStop( vGlob, vVec, i, LevelStart, LevelStop )                 \ +    for ( i = LevelStart; (i <= LevelStop) && (((vVec) = (Vec_Ptr_t*)Vec_VecEntry(vGlob, i)), 1); i++ ) +#define Vec_VecForEachLevelReverse( vGlob, vVec, i )                                          \ +    for ( i = Vec_VecSize(vGlob) - 1; (i >= 0) && (((vVec) = (Vec_Ptr_t*)Vec_VecEntry(vGlob, i)), 1); i-- ) + +// iteratores through entries +#define Vec_VecForEachEntry( vGlob, pEntry, i, k )                                            \ +    for ( i = 0; i < Vec_VecSize(vGlob); i++ )                                                \ +        Vec_PtrForEachEntry( Vec_VecEntry(vGlob, i), pEntry, k )  +#define Vec_VecForEachEntryStart( vGlob, pEntry, i, k, LevelStart )                           \ +    for ( i = LevelStart; i < Vec_VecSize(vGlob); i++ )                                       \ +        Vec_PtrForEachEntry( Vec_VecEntry(vGlob, i), pEntry, k )  +#define Vec_VecForEachEntryStartStop( vGlob, pEntry, i, k, LevelStart, LevelStop )            \ +    for ( i = LevelStart; i <= LevelStop; i++ )                                               \ +        Vec_PtrForEachEntry( Vec_VecEntry(vGlob, i), pEntry, k )  +#define Vec_VecForEachEntryReverse( vGlob, pEntry, i, k )                                     \ +    for ( i = 0; i < Vec_VecSize(vGlob); i++ )                                                \ +        Vec_PtrForEachEntryReverse( Vec_VecEntry(vGlob, i), pEntry, k )  +#define Vec_VecForEachEntryReverseReverse( vGlob, pEntry, i, k )                              \ +    for ( i = Vec_VecSize(vGlob) - 1; i >= 0; i-- )                                           \ +        Vec_PtrForEachEntryReverse( Vec_VecEntry(vGlob, i), pEntry, k )  + +//////////////////////////////////////////////////////////////////////// +///                     FUNCTION DEFINITIONS                         /// +//////////////////////////////////////////////////////////////////////// + +/**Function************************************************************* + +  Synopsis    [Allocates a vector with the given capacity.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline Vec_Vec_t * Vec_VecAlloc( int nCap ) +{ +    Vec_Vec_t * p; +    p = ALLOC( Vec_Vec_t, 1 ); +    if ( nCap > 0 && nCap < 8 ) +        nCap = 8; +    p->nSize  = 0; +    p->nCap   = nCap; +    p->pArray = p->nCap? ALLOC( void *, p->nCap ) : NULL; +    return p; +} + +/**Function************************************************************* + +  Synopsis    [Allocates a vector with the given capacity.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline Vec_Vec_t * Vec_VecStart( int nSize ) +{ +    Vec_Vec_t * p; +    int i; +    p = Vec_VecAlloc( nSize ); +    for ( i = 0; i < nSize; i++ ) +        p->pArray[i] = Vec_PtrAlloc( 0 ); +    p->nSize = nSize; +    return p; +} + +/**Function************************************************************* + +  Synopsis    [Allocates a vector with the given capacity.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Vec_VecExpand( Vec_Vec_t * p, int Level ) +{ +    int i; +    if ( p->nSize >= Level + 1 ) +        return; +    Vec_PtrGrow( (Vec_Ptr_t *)p, Level + 1 ); +    for ( i = p->nSize; i <= Level; i++ ) +        p->pArray[i] = Vec_PtrAlloc( 0 ); +    p->nSize = Level + 1; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Vec_VecSize( Vec_Vec_t * p ) +{ +    return p->nSize; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void * Vec_VecEntry( Vec_Vec_t * p, int i ) +{ +    assert( i >= 0 && i < p->nSize ); +    return p->pArray[i]; +} + +/**Function************************************************************* + +  Synopsis    [Frees the vector.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Vec_VecFree( Vec_Vec_t * p ) +{ +    Vec_Ptr_t * vVec; +    int i; +    Vec_VecForEachLevel( p, vVec, i ) +        Vec_PtrFree( vVec ); +    Vec_PtrFree( (Vec_Ptr_t *)p ); +} + +/**Function************************************************************* + +  Synopsis    [Frees the vector of vectors.] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline int Vec_VecSizeSize( Vec_Vec_t * p ) +{ +    Vec_Ptr_t * vVec; +    int i, Counter = 0; +    Vec_VecForEachLevel( p, vVec, i ) +        Counter += vVec->nSize; +    return Counter; +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Vec_VecClear( Vec_Vec_t * p ) +{ +    Vec_Ptr_t * vVec; +    int i; +    Vec_VecForEachLevel( p, vVec, i ) +        Vec_PtrClear( vVec ); +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Vec_VecPush( Vec_Vec_t * p, int Level, void * Entry ) +{ +    if ( p->nSize < Level + 1 ) +    { +        int i; +        Vec_PtrGrow( (Vec_Ptr_t *)p, Level + 1 ); +        for ( i = p->nSize; i < Level + 1; i++ ) +            p->pArray[i] = Vec_PtrAlloc( 0 ); +        p->nSize = Level + 1; +    } +    Vec_PtrPush( (Vec_Ptr_t*)p->pArray[Level], Entry ); +} + +/**Function************************************************************* + +  Synopsis    [] + +  Description [] +                +  SideEffects [] + +  SeeAlso     [] + +***********************************************************************/ +static inline void Vec_VecPushUnique( Vec_Vec_t * p, int Level, void * Entry ) +{ +    if ( p->nSize < Level + 1 ) +        Vec_VecPush( p, Level, Entry ); +    else +        Vec_PtrPushUnique( (Vec_Ptr_t*)p->pArray[Level], Entry ); +} + +#endif + +//////////////////////////////////////////////////////////////////////// +///                       END OF FILE                                /// +//////////////////////////////////////////////////////////////////////// + diff --git a/src/temp/xyz/module.make b/src/temp/xyz/module.make index ae7dab0f..f84fa8cc 100644 --- a/src/temp/xyz/module.make +++ b/src/temp/xyz/module.make @@ -1,8 +1,8 @@ -SRC +=    src/opt/xyz/xyzBuild.c \ -    src/opt/xyz/xyzCore.c \ -    src/opt/xyz/xyzMan.c \ -    src/opt/xyz/xyzMinEsop.c \ -    src/opt/xyz/xyzMinMan.c \ -    src/opt/xyz/xyzMinSop.c \ -    src/opt/xyz/xyzMinUtil.c \ -    src/opt/xyz/xyzTest.c  +SRC +=    src/temp/xyz/xyzBuild.c \ +    src/temp/xyz/xyzCore.c \ +    src/temp/xyz/xyzMan.c \ +    src/temp/xyz/xyzMinEsop.c \ +    src/temp/xyz/xyzMinMan.c \ +    src/temp/xyz/xyzMinSop.c \ +    src/temp/xyz/xyzMinUtil.c \ +    src/temp/xyz/xyzTest.c   | 
