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++; } } }
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++; } } }
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); } }
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; }
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); } }