Beispiel #1
0
static void insert_level(int levToInsert) {
	int n;
    for (n = 2; n < bddnodesize; n++) {
        int lev, lo, hi, newLev, hash, r, r2, NEXT_r;
        if (LOW(n) == INVALID_BDD) continue;
        lev = LEVEL(n);
        if (lev <= levToInsert || lev == bddvarnum-1) {
            continue;
        }
        lo = LOW(n);
        hi = HIGH(n);
        newLev = lev+1;
        hash = NODEHASH(lev, lo, hi);
        r = HASH(hash);
        r2 = 0;
        while (r != n && r != 0) {
            r2 = r;
            r = NEXT(r);
        }
        NEXT_r = NEXT(r);
        if (r2 == 0) {
            SETHASH(hash, NEXT_r);
        } else {
            SETNEXT(r2, NEXT_r);
        }
        SETLEVEL(n, newLev);
        lo = LOW(n); hi = HIGH(n);
        hash = NODEHASH(newLev, lo, hi);
        r = HASH(hash);
        SETHASH(hash, n);
        SETNEXT(n, r);
    }
}
static void bdd_gbc_rehash(void)
{
   int n;

   bddfreepos = 0;
   bddfreenum = 0;

   for (n=bddnodesize-1 ; n>=2 ; n--)
   {
      register BddNode *node = &bddnodes[n];

      if (LOWp(node) != -1)
      {
	 register unsigned int hash;

	 hash = NODEHASH(LEVELp(node), LOWp(node), HIGHp(node));
	 node->next = bddnodes[hash].hash;
	 bddnodes[hash].hash = n;
      }
      else
      {
	 node->next = bddfreepos;
	 bddfreepos = n;
	 bddfreenum++;
      }
   }
}
Beispiel #3
0
static void bdd_gbc_rehash(void)
{
   int n;

   bddfreepos = 0;
   bddfreenum = 0;

   for (n=bddnodesize-1 ; n>=2 ; n--)
   {
      register BddNode *node = &bddnodes[n];

      if (LOWp(node) != INVALID_BDD)
      {
	 register unsigned int hash;

	 hash = NODEHASH(LEVELp(node), LOWp(node), HIGHp(node));
	 SETNEXTp(node, HASH(hash));
	 SETHASH(hash, n);
      }
      else
      {
	 SETNEXTpz(node, bddfreepos);
	 bddfreepos = n;
	 bddfreenum++;
      }
   }
}
Beispiel #4
0
static void dup_level(int levToInsert, int val) {
	int n;
    for (n = 2; n < bddnodesize; n++) {
    	int lev, lo, hi, newLev;
        int n_low, n_high;
        int hash, r, r2, NEXT_r;
        if (LOW(n) == INVALID_BDD) continue;
        lev = LEVEL(n);
        if (lev != levToInsert || lev == bddvarnum-1) {
            continue;
        }
        lo = LOW(n);
        hi = HIGH(n);
        bdd_addref(n);
        n_low = bdd_makenode(levToInsert+1, val<=0 ? lo : 0, val<=0 ? 0 : lo);
        n_high = bdd_makenode(levToInsert+1, val==0 ? hi : 0, val==0 ? 0 : hi);
        bdd_delref(n);
        newLev = lev;
        SETLOW(n, n_low);
        SETHIGH(n, n_high);
        hash = NODEHASH(lev, lo, hi);
        r = HASH(hash);
        r2 = 0;
        while (r != n && r != 0) {
            r2 = r;
            r = NEXT(r);
        }
        NEXT_r = NEXT(r);
        if (r2 == 0) {
            SETHASH(hash, NEXT_r);
        } else {
            SETNEXT(r2, NEXT_r);
        }
        SETLEVEL(n, newLev);
        lo = LOW(n); hi = HIGH(n);
        hash = NODEHASH(newLev, lo, hi);
        r = HASH(hash);
        SETHASH(hash, n);
        SETNEXT(n, r);
    }
}
int bdd_makenode(unsigned int level, int low, int high)
{
   register BddNode *node;
   register unsigned int hash;
   register int res;

#ifdef CACHESTATS
   bddcachestats.uniqueAccess++;
#endif
   
      /* check whether childs are equal */
   if (low == high)
      return low;

      /* Try to find an existing node of this kind */
   hash = NODEHASH(level, low, high);
   res = bddnodes[hash].hash;

   while(res != 0)
   {
      if (LEVEL(res) == level  &&  LOW(res) == low  &&  HIGH(res) == high)
      {
#ifdef CACHESTATS
	 bddcachestats.uniqueHit++;
#endif
	 return res;
      }

      res = bddnodes[res].next;
#ifdef CACHESTATS
      bddcachestats.uniqueChain++;
#endif
   }
   
      /* No existing node -> build one */
#ifdef CACHESTATS
   bddcachestats.uniqueMiss++;
#endif

      /* Any free nodes to use ? */
   if (bddfreepos == 0)
   {
      if (bdderrorcond)
	 return 0;
      
         /* Try to allocate more nodes */
      bdd_gbc();

      if ((bddnodesize-bddfreenum) >= usednodes_nextreorder  &&
	   bdd_reorder_ready())
      {
	 longjmp(bddexception,1);
      }

      if ((bddfreenum*100) / bddnodesize <= minfreenodes)
      {
	 bdd_noderesize(1);
	 hash = NODEHASH(level, low, high);
      }

         /* Panic if that is not possible */
      if (bddfreepos == 0)
      {
	 bdd_error(BDD_NODENUM);
	 bdderrorcond = abs(BDD_NODENUM);
	 return 0;
      }
   }

      /* Build new node */
   res = bddfreepos;
   bddfreepos = bddnodes[bddfreepos].next;
   bddfreenum--;
   bddproduced++;
   
   node = &bddnodes[res];
   LEVELp(node) = level;
   LOWp(node) = low;
   HIGHp(node) = high;
   
      /* Insert node */
   node->next = bddnodes[hash].hash;
   bddnodes[hash].hash = res;

   return res;
}
void bdd_gbc(void)
{
   int *r;
   int n;
   long int c2, c1 = clock();

   if (gbc_handler != NULL)
   {
      bddGbcStat s;
      s.nodes = bddnodesize;
      s.freenodes = bddfreenum;
      s.time = 0;
      s.sumtime = gbcclock;
      s.num = gbcollectnum;
      gbc_handler(1, &s);
   }
   
   for (r=bddrefstack ; r<bddrefstacktop ; r++)
      bdd_mark(*r);

   for (n=0 ; n<bddnodesize ; n++)
   {
      if (bddnodes[n].refcou > 0)
	 bdd_mark(n);
      bddnodes[n].hash = 0;
   }
   
   bddfreepos = 0;
   bddfreenum = 0;

   for (n=bddnodesize-1 ; n>=2 ; n--)
   {
      register BddNode *node = &bddnodes[n];

      if ((LEVELp(node) & MARKON)  &&  LOWp(node) != -1)
      {
	 register unsigned int hash;

	 LEVELp(node) &= MARKOFF;
	 hash = NODEHASH(LEVELp(node), LOWp(node), HIGHp(node));
	 node->next = bddnodes[hash].hash;
	 bddnodes[hash].hash = n;
      }
      else
      {
	 LOWp(node) = -1;
	 node->next = bddfreepos;
	 bddfreepos = n;
	 bddfreenum++;
      }
   }

   bdd_operator_reset();

   c2 = clock();
   gbcclock += c2-c1;
   gbcollectnum++;

   if (gbc_handler != NULL)
   {
      bddGbcStat s;
      s.nodes = bddnodesize;
      s.freenodes = bddfreenum;
      s.time = c2-c1;
      s.sumtime = gbcclock;
      s.num = gbcollectnum;
      gbc_handler(0, &s);
   }
}
Beispiel #7
0
int bdd_makenode(unsigned int level, int low, int high)
{
   register unsigned int hash;
   register int res;

#ifdef CACHESTATS
   bddcachestats.uniqueAccess++;
#endif
   
      /* check whether childs are equal */
   if (low == high)
      return low;

      /* Try to find an existing node of this kind */
   hash = NODEHASH(level, low, high);
   res = HASH(hash);

#if defined(SMALL_NODES)
   if (res != 0) {
       int m1 = (level << LEV_LPOS) | low;
       int m2 = ((level << (LEV_HPOS-LEV_LBITS)) & LEV_HMASK) | high;
       do {
           if (bddnodes[res].low_llev == m1 && bddnodes[res].high_hlev == m2) {
#ifdef CACHESTATS
               bddcachestats.uniqueHit++;
#endif
               return res;
           }
           res = NEXT(res);
#ifdef CACHESTATS
           bddcachestats.uniqueChain++;
#endif
       } while (res != 0);
   }
#else // SMALL_NODES
   while(res != 0)
   {
      if (LEVEL(res) == level  &&  LOW(res) == low  &&  HIGH(res) == high)
      {
#ifdef CACHESTATS
	 bddcachestats.uniqueHit++;
#endif
	 return res;
      }

      res = NEXT(res);
#ifdef CACHESTATS
      bddcachestats.uniqueChain++;
#endif
   }
#endif // SMALL_NODES
   
      /* No existing node -> build one */
#ifdef CACHESTATS
   bddcachestats.uniqueMiss++;
#endif

      /* Any free nodes to use ? */
   if (bddfreepos == 0)
   {
      if (bdderrorcond)
	 return 0;
      
         /* Try to allocate more nodes */
      bdd_gbc();

      if ((bddnodesize-bddfreenum) >= usednodes_nextreorder  &&
	   bdd_reorder_ready())
      {
	 longjmp(bddexception,1);
      }

      if ((bddfreenum*100) / bddnodesize <= minfreenodes)
      {
	 bdd_noderesize(1);
	 hash = NODEHASH(level, low, high);
      }

         /* Panic if that is not possible */
      if (bddfreepos == 0)
      {
	 bdd_error(BDD_NODENUM);
	 bdderrorcond = abs(BDD_NODENUM);
	 return 0;
      }
   }

      /* Build new node */
   res = bddfreepos;
   bddfreepos = NEXT(bddfreepos);
   bddfreenum--;
   bddproduced++;
   
   {
       int next = HASH(hash);
       CREATE_NODE(res, level, low, high, next);
       /* Insert node */
       SETHASH(hash, res);
   }

   return res;
}
Beispiel #8
0
void bdd_gbc(void)
{
   int *r;
   int n;
   long int c2, c1 = clock();

   if (gbc_handler != NULL)
   {
      bddGbcStat s;
      s.nodes = bddnodesize;
      s.freenodes = bddfreenum;
      s.time = 0;
      s.sumtime = gbcclock;
      s.num = gbcollectnum;
      gbc_handler(1, &s);
   }
   
   for (r=bddrefstack ; r<bddrefstacktop ; r++)
      bdd_mark(*r);

   for (n=0 ; n<bddnodesize ; n++)
   {
      if (HASREF(n)) bdd_mark(n);
      SETHASH(n, 0);
   }
   
   bddfreepos = 0;
   bddfreenum = 0;

   for (n=bddnodesize-1 ; n>=2 ; n--)
   {
      register BddNode *node = &bddnodes[n];

      if (MARKEDp(node)  &&  LOWp(node) != INVALID_BDD)
      {
	 register unsigned int hash;

         UNMARKp(node);
	 hash = NODEHASH(LEVELp(node), LOWp(node), HIGHp(node));
	 SETNEXTp(node, HASH(hash));
	 SETHASH(hash, n);
      }
      else
      {
	 SETLOWpz(node, INVALID_BDD); // obliterates refcount
	 SETNEXTpz(node, bddfreepos); // obliterates lev, mark
	 bddfreepos = n;
	 bddfreenum++;
      }
   }

   bdd_operator_reset();

   c2 = clock();
   gbcclock += c2-c1;
   gbcollectnum++;

   if (gbc_handler != NULL)
   {
      bddGbcStat s;
      s.nodes = bddnodesize;
      s.freenodes = bddfreenum;
      s.time = c2-c1;
      s.sumtime = gbcclock;
      s.num = gbcollectnum;
      gbc_handler(0, &s);
   }
}