SVF
cuddRef.c
Go to the documentation of this file.
1 
68 #include "CUDD/util.h"
69 #include "CUDD/cuddInt.h"
70 
71 /*---------------------------------------------------------------------------*/
72 /* Constant declarations */
73 /*---------------------------------------------------------------------------*/
74 
75 
76 /*---------------------------------------------------------------------------*/
77 /* Stucture declarations */
78 /*---------------------------------------------------------------------------*/
79 
80 
81 /*---------------------------------------------------------------------------*/
82 /* Type declarations */
83 /*---------------------------------------------------------------------------*/
84 
85 
86 /*---------------------------------------------------------------------------*/
87 /* Variable declarations */
88 /*---------------------------------------------------------------------------*/
89 
90 #ifndef lint
91 static char rcsid[] DD_UNUSED = "$Id: cuddRef.c,v 1.29 2012/02/05 01:07:19 fabio Exp $";
92 #endif
93 
94 /*---------------------------------------------------------------------------*/
95 /* Macro declarations */
96 /*---------------------------------------------------------------------------*/
97 
98 
101 /*---------------------------------------------------------------------------*/
102 /* Static function prototypes */
103 /*---------------------------------------------------------------------------*/
104 
108 /*---------------------------------------------------------------------------*/
109 /* Definition of exported functions */
110 /*---------------------------------------------------------------------------*/
111 
124 void
126  DdNode * n)
127 {
128 
129  n = Cudd_Regular(n);
130 
131  cuddSatInc(n->ref);
132 
133 } /* end of Cudd_Ref */
134 
135 
149 void
151  DdManager * table,
152  DdNode * n)
153 {
154  DdNode *N;
155  int ord;
156  DdNodePtr *stack = table->stack;
157  int SP = 1;
158 
159  unsigned int live = table->keys - table->dead;
160  if (live > table->peakLiveNodes) {
161  table->peakLiveNodes = live;
162  }
163 
164  N = Cudd_Regular(n);
165 
166  do {
167 #ifdef DD_DEBUG
168  assert(N->ref != 0);
169 #endif
170 
171  if (N->ref == 1) {
172  N->ref = 0;
173  table->dead++;
174 #ifdef DD_STATS
175  table->nodesDropped++;
176 #endif
177  if (cuddIsConstant(N)) {
178  table->constants.dead++;
179  N = stack[--SP];
180  } else {
181  ord = table->perm[N->index];
182  stack[SP++] = Cudd_Regular(cuddE(N));
183  table->subtables[ord].dead++;
184  N = cuddT(N);
185  }
186  } else {
187  cuddSatDec(N->ref);
188  N = stack[--SP];
189  }
190  } while (SP != 0);
191 
192 } /* end of Cudd_RecursiveDeref */
193 
194 
212 void
214  DdManager * table,
215  DdNode * n)
216 {
217  DdNode *N;
218  int ord;
219  DdNodePtr *stack = table->stack;
220  int SP = 1;
221 
222  unsigned int live = table->keys - table->dead;
223  if (live > table->peakLiveNodes) {
224  table->peakLiveNodes = live;
225  }
226 
227  N = Cudd_Regular(n);
228 
229  do {
230 #ifdef DD_DEBUG
231  assert(N->ref != 0);
232 #endif
233 
234  if (N->ref == 1) {
235  N->ref = 0;
236  table->dead++;
237 #ifdef DD_STATS
238  table->nodesDropped++;
239 #endif
240  ord = table->perm[N->index];
241  stack[SP++] = Cudd_Regular(cuddE(N));
242  table->subtables[ord].dead++;
243  N = cuddT(N);
244  } else {
245  cuddSatDec(N->ref);
246  N = stack[--SP];
247  }
248  } while (SP != 0);
249 
250 } /* end of Cudd_IterDerefBdd */
251 
252 
269 void
271  DdManager * table,
272  DdNode * n)
273 {
274  DdNode *N;
275  int ord;
276  DdNodePtr *stack;
277  int SP;
278 
279  unsigned int live = table->keys - table->dead;
280  if (live > table->peakLiveNodes) {
281  table->peakLiveNodes = live;
282  }
283 
284  n = Cudd_Regular(n);
285 #ifdef DD_DEBUG
286  assert(n->ref != 0);
287 #endif
288 
289 #ifdef DD_NO_DEATH_ROW
290  N = n;
291 #else
292  if (cuddIsConstant(n) || n->ref > 1) {
293 #ifdef DD_DEBUG
294  assert(n->ref != 1 && (!cuddIsConstant(n) || n == DD_ONE(table)));
295 #endif
296  cuddSatDec(n->ref);
297  return;
298  }
299 
300  N = table->deathRow[table->nextDead];
301 
302  if (N != NULL) {
303 #endif
304 #ifdef DD_DEBUG
306 #endif
307  stack = table->stack;
308  SP = 1;
309  do {
310 #ifdef DD_DEBUG
311  assert(N->ref != 0);
312 #endif
313  if (N->ref == 1) {
314  N->ref = 0;
315  table->dead++;
316 #ifdef DD_STATS
317  table->nodesDropped++;
318 #endif
319  ord = table->perm[N->index];
320  stack[SP++] = Cudd_Regular(cuddE(N));
321  table->subtables[ord].dead++;
322  N = cuddT(N);
323  } else {
324  cuddSatDec(N->ref);
325  N = stack[--SP];
326  }
327  } while (SP != 0);
328 #ifndef DD_NO_DEATH_ROW
329  }
330  table->deathRow[table->nextDead] = n;
331 
332  /* Udate insertion point. */
333  table->nextDead++;
334  table->nextDead &= table->deadMask;
335 #if 0
336  if (table->nextDead == table->deathRowDepth) {
337  if (table->deathRowDepth < table->looseUpTo / 2) {
338  extern void (*MMoutOfMemory)(long);
339  void (*saveHandler)(long) = MMoutOfMemory;
340  DdNodePtr *newRow;
342  newRow = REALLOC(DdNodePtr,table->deathRow,2*table->deathRowDepth);
343  MMoutOfMemory = saveHandler;
344  if (newRow == NULL) {
345  table->nextDead = 0;
346  } else {
347  int i;
348  table->memused += table->deathRowDepth;
349  i = table->deathRowDepth;
350  table->deathRowDepth <<= 1;
351  for (; i < table->deathRowDepth; i++) {
352  newRow[i] = NULL;
353  }
354  table->deadMask = table->deathRowDepth - 1;
355  table->deathRow = newRow;
356  }
357  } else {
358  table->nextDead = 0;
359  }
360  }
361 #endif
362 #endif
363 
364 } /* end of Cudd_DelayedDerefBdd */
365 
366 
380 void
382  DdManager * table,
383  DdNode * n)
384 {
385  DdNode *N;
386  int ord;
387  DdNodePtr *stack = table->stack;
388  int SP = 1;
389 
390  N = n;
391 
392  do {
393 #ifdef DD_DEBUG
394  assert(N->ref != 0);
395 #endif
396 
397  cuddSatDec(N->ref);
398 
399  if (N->ref == 0) {
400  table->deadZ++;
401 #ifdef DD_STATS
402  table->nodesDropped++;
403 #endif
404 #ifdef DD_DEBUG
405  assert(!cuddIsConstant(N));
406 #endif
407  ord = table->permZ[N->index];
408  stack[SP++] = cuddE(N);
409  table->subtableZ[ord].dead++;
410  N = cuddT(N);
411  } else {
412  N = stack[--SP];
413  }
414  } while (SP != 0);
415 
416 } /* end of Cudd_RecursiveDerefZdd */
417 
418 
433 void
435  DdNode * node)
436 {
437  node = Cudd_Regular(node);
438  cuddSatDec(node->ref);
439 
440 } /* end of Cudd_Deref */
441 
442 
461 int
463  DdManager * manager)
464 {
465  int size;
466  int i, j;
467  int remain; /* the expected number of remaining references to one */
468  DdNodePtr *nodelist;
469  DdNode *node;
470  DdNode *sentinel = &(manager->sentinel);
471  DdSubtable *subtable;
472  int count = 0;
473  int index;
474 
475 #ifndef DD_NO_DEATH_ROW
476  cuddClearDeathRow(manager);
477 #endif
478 
479  /* First look at the BDD/ADD subtables. */
480  remain = 1; /* reference from the manager */
481  size = manager->size;
482  remain += 2 * size; /* reference from the BDD projection functions */
483 
484  for (i = 0; i < size; i++) {
485  subtable = &(manager->subtables[i]);
486  nodelist = subtable->nodelist;
487  for (j = 0; (unsigned) j < subtable->slots; j++) {
488  node = nodelist[j];
489  while (node != sentinel) {
490  if (node->ref != 0 && node->ref != DD_MAXREF) {
491  index = (int) node->index;
492  if (node != manager->vars[index]) {
493  count++;
494  } else {
495  if (node->ref != 1) {
496  count++;
497  }
498  }
499  }
500  node = node->next;
501  }
502  }
503  }
504 
505  /* Then look at the ZDD subtables. */
506  size = manager->sizeZ;
507  if (size) /* references from ZDD universe */
508  remain += 2;
509 
510  for (i = 0; i < size; i++) {
511  subtable = &(manager->subtableZ[i]);
512  nodelist = subtable->nodelist;
513  for (j = 0; (unsigned) j < subtable->slots; j++) {
514  node = nodelist[j];
515  while (node != NULL) {
516  if (node->ref != 0 && node->ref != DD_MAXREF) {
517  index = (int) node->index;
518  if (node == manager->univ[manager->permZ[index]]) {
519  if (node->ref > 2) {
520  count++;
521  }
522  } else {
523  count++;
524  }
525  }
526  node = node->next;
527  }
528  }
529  }
530 
531  /* Now examine the constant table. Plusinfinity, minusinfinity, and
532  ** zero are referenced by the manager. One is referenced by the
533  ** manager, by the ZDD universe, and by all projection functions.
534  ** All other nodes should have no references.
535  */
536  nodelist = manager->constants.nodelist;
537  for (j = 0; (unsigned) j < manager->constants.slots; j++) {
538  node = nodelist[j];
539  while (node != NULL) {
540  if (node->ref != 0 && node->ref != DD_MAXREF) {
541  if (node == manager->one) {
542  if ((int) node->ref != remain) {
543  count++;
544  }
545  } else if (node == manager->zero ||
546  node == manager->plusinfinity ||
547  node == manager->minusinfinity) {
548  if (node->ref != 1) {
549  count++;
550  }
551  } else {
552  count++;
553  }
554  }
555  node = node->next;
556  }
557  }
558  return(count);
559 
560 } /* end of Cudd_CheckZeroRef */
561 
562 
563 /*---------------------------------------------------------------------------*/
564 /* Definition of internal functions */
565 /*---------------------------------------------------------------------------*/
566 
567 
579 void
581  DdManager * table,
582  DdNode * n)
583 {
584  DdNode *N;
585  int ord;
586  DdNodePtr *stack = table->stack;
587  int SP = 1;
588  double initialDead = table->dead;
589 
590  N = Cudd_Regular(n);
591 
592 #ifdef DD_DEBUG
593  assert(N->ref == 0);
594 #endif
595 
596  do {
597  if (N->ref == 0) {
598  N->ref = 1;
599  table->dead--;
600  if (cuddIsConstant(N)) {
601  table->constants.dead--;
602  N = stack[--SP];
603  } else {
604  ord = table->perm[N->index];
605  stack[SP++] = Cudd_Regular(cuddE(N));
606  table->subtables[ord].dead--;
607  N = cuddT(N);
608  }
609  } else {
610  cuddSatInc(N->ref);
611  N = stack[--SP];
612  }
613  } while (SP != 0);
614 
615  N = Cudd_Regular(n);
616  cuddSatDec(N->ref);
617  table->reclaimed += initialDead - table->dead;
618 
619 } /* end of cuddReclaim */
620 
621 
633 void
635  DdManager * table,
636  DdNode * n)
637 {
638  DdNode *N;
639  int ord;
640  DdNodePtr *stack = table->stack;
641  int SP = 1;
642 
643  N = n;
644 
645 #ifdef DD_DEBUG
646  assert(N->ref == 0);
647 #endif
648 
649  do {
650  cuddSatInc(N->ref);
651 
652  if (N->ref == 1) {
653  table->deadZ--;
654  table->reclaimed++;
655 #ifdef DD_DEBUG
656  assert(!cuddIsConstant(N));
657 #endif
658  ord = table->permZ[N->index];
659  stack[SP++] = cuddE(N);
660  table->subtableZ[ord].dead--;
661  N = cuddT(N);
662  } else {
663  N = stack[--SP];
664  }
665  } while (SP != 0);
666 
667  cuddSatDec(n->ref);
668 
669 } /* end of cuddReclaimZdd */
670 
671 
683 void
685  DdManager *table)
686 {
687 #ifndef DD_NO_DEATH_ROW
688  int i;
689 
690  if (table->deathRowDepth > 3) {
691  for (i = table->deathRowDepth/4; i < table->deathRowDepth; i++) {
692  if (table->deathRow[i] == NULL) break;
693  Cudd_IterDerefBdd(table,table->deathRow[i]);
694  table->deathRow[i] = NULL;
695  }
696  table->deathRowDepth /= 4;
697  table->deadMask = table->deathRowDepth - 1;
698  if ((unsigned) table->nextDead > table->deadMask) {
699  table->nextDead = 0;
700  }
701  table->deathRow = REALLOC(DdNodePtr, table->deathRow,
702  table->deathRowDepth);
703  }
704 #endif
705 
706 } /* end of cuddShrinkDeathRow */
707 
708 
721 void
723  DdManager *table)
724 {
725 #ifndef DD_NO_DEATH_ROW
726  int i;
727 
728  for (i = 0; i < table->deathRowDepth; i++) {
729  if (table->deathRow[i] == NULL) break;
730  Cudd_IterDerefBdd(table,table->deathRow[i]);
731  table->deathRow[i] = NULL;
732  }
733 #ifdef DD_DEBUG
734  for (; i < table->deathRowDepth; i++) {
735  assert(table->deathRow[i] == NULL);
736  }
737 #endif
738  table->nextDead = 0;
739 #endif
740 
741 } /* end of cuddClearDeathRow */
742 
743 
757 int
759  DdManager *dd,
760  DdNode *f)
761 {
762 #ifndef DD_NO_DEATH_ROW
763  int i;
764 
765  for (i = 0; i < dd->deathRowDepth; i++) {
766  if (f == dd->deathRow[i]) {
767  return(i);
768  }
769  }
770 #endif
771 
772  return(-1);
773 
774 } /* end of cuddIsInDeathRow */
775 
776 
788 int
790  DdManager *dd,
791  DdNode *f)
792 {
793  int count = 0;
794 #ifndef DD_NO_DEATH_ROW
795  int i;
796 
797  for (i = 0; i < dd->deathRowDepth; i++) {
798  count += f == dd->deathRow[i];
799  }
800 #endif
801 
802  return(count);
803 
804 } /* end of cuddTimesInDeathRow */
805 
806 /*---------------------------------------------------------------------------*/
807 /* Definition of static functions */
808 /*---------------------------------------------------------------------------*/
DdHalfWord ref
Definition: cudd.h:272
#define DD_MAXREF
Definition: cuddInt.h:101
void cuddReclaim(DdManager *table, DdNode *n)
Definition: cuddRef.c:580
void Cudd_OutOfMem(long size)
Definition: cuddUtil.c:2845
static char rcsid [] DD_UNUSED
Definition: cuddRef.c:91
unsigned int peakLiveNodes
Definition: cuddInt.h:445
Definition: cudd.h:270
unsigned int deadZ
Definition: cuddInt.h:356
unsigned deadMask
Definition: cuddInt.h:387
#define assert(ex)
Definition: util.h:141
int size
Definition: cuddInt.h:345
DdNode * zero
Definition: cuddInt.h:330
#define Cudd_Regular(node)
Definition: cudd.h:384
int Cudd_CheckZeroRef(DdManager *manager)
Definition: cuddRef.c:462
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:150
DdSubtable * subtables
Definition: cuddInt.h:349
int * permZ
Definition: cuddInt.h:370
void Cudd_RecursiveDerefZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:381
DdNode ** deathRow
Definition: cuddInt.h:384
DdNode ** stack
Definition: cuddInt.h:364
void Cudd_Ref(DdNode *n)
Definition: cuddRef.c:125
unsigned int dead
Definition: cuddInt.h:355
#define Cudd_IsComplement(node)
Definition: cudd.h:412
DdNode sentinel
Definition: cuddInt.h:328
int cuddIsInDeathRow(DdManager *dd, DdNode *f)
Definition: cuddRef.c:758
unsigned int keys
Definition: cuddInt.h:353
unsigned int dead
Definition: cuddInt.h:316
DdNode * next
Definition: cudd.h:273
#define cuddIsConstant(node)
Definition: cuddInt.h:593
DdNode ** nodelist
Definition: cuddInt.h:311
void Cudd_IterDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:213
void cuddReclaimZdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:634
#define cuddT(node)
Definition: cuddInt.h:609
int nextDead
Definition: cuddInt.h:386
void(* MMoutOfMemory)(long)
Definition: safe_mem.c:32
void cuddShrinkDeathRow(DdManager *table)
Definition: cuddRef.c:684
unsigned long memused
Definition: cuddInt.h:429
int deathRowDepth
Definition: cuddInt.h:385
#define REALLOC(type, obj, num)
Definition: util.h:78
int sizeZ
Definition: cuddInt.h:346
DdHalfWord index
Definition: cudd.h:271
unsigned int looseUpTo
Definition: cuddInt.h:361
DdNode ** vars
Definition: cuddInt.h:373
DdNode * one
Definition: cuddInt.h:329
void Cudd_DelayedDerefBdd(DdManager *table, DdNode *n)
Definition: cuddRef.c:270
#define cuddE(node)
Definition: cuddInt.h:625
int cuddTimesInDeathRow(DdManager *dd, DdNode *f)
Definition: cuddRef.c:789
DdNode * plusinfinity
Definition: cuddInt.h:331
#define cuddSatDec(x)
Definition: cuddInt.h:849
DdSubtable constants
Definition: cuddInt.h:351
DdNode * minusinfinity
Definition: cuddInt.h:332
void cuddClearDeathRow(DdManager *table)
Definition: cuddRef.c:722
#define DD_ONE(dd)
Definition: cuddInt.h:864
void Cudd_Deref(DdNode *node)
Definition: cuddRef.c:434
int * perm
Definition: cuddInt.h:369
#define cuddSatInc(x)
Definition: cuddInt.h:831
double reclaimed
Definition: cuddInt.h:367
DdSubtable * subtableZ
Definition: cuddInt.h:350
DdNode ** univ
Definition: cuddInt.h:375
if(DEFINED IN_SOURCE_BUILD) set(LLVM_LINK_COMPONENTS BitWriter Core IPO IrReader InstCombine Instrumentation Target Linker Analysis ScalarOpts Support Svf Cudd) add_llvm_tool(dvf dda.cpp) else() add_executable(dvf dda.cpp) target_link_libraries(dvf Svf Cudd $
Definition: CMakeLists.txt:2