SVF
cuddLCache.c
Go to the documentation of this file.
1 
78 #include "CUDD/util.h"
79 #include "CUDD/cuddInt.h"
80 
81 /*---------------------------------------------------------------------------*/
82 /* Constant declarations */
83 /*---------------------------------------------------------------------------*/
84 
85 #define DD_MAX_HASHTABLE_DENSITY 2 /* tells when to resize a table */
86 
87 /*---------------------------------------------------------------------------*/
88 /* Stucture declarations */
89 /*---------------------------------------------------------------------------*/
90 
91 
92 /*---------------------------------------------------------------------------*/
93 /* Type declarations */
94 /*---------------------------------------------------------------------------*/
95 
96 
97 /*---------------------------------------------------------------------------*/
98 /* Variable declarations */
99 /*---------------------------------------------------------------------------*/
100 
101 #ifndef lint
102 static char rcsid[] DD_UNUSED = "$Id: cuddLCache.c,v 1.27 2012/02/05 01:07:19 fabio Exp $";
103 #endif
104 
105 /*---------------------------------------------------------------------------*/
106 /* Macro declarations */
107 /*---------------------------------------------------------------------------*/
108 
120 #if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4
121 #define ddLCHash1(f,shift) \
122 (((unsigned)(ptruint)(f) * DD_P1) >> (shift))
123 #else
124 #define ddLCHash1(f,shift) \
125 (((unsigned)(f) * DD_P1) >> (shift))
126 #endif
127 
128 
140 #if SIZEOF_VOID_P == 8 && SIZEOF_INT == 4
141 #define ddLCHash2(f,g,shift) \
142 ((((unsigned)(ptruint)(f) * DD_P1 + \
143  (unsigned)(ptruint)(g)) * DD_P2) >> (shift))
144 #else
145 #define ddLCHash2(f,g,shift) \
146 ((((unsigned)(f) * DD_P1 + (unsigned)(g)) * DD_P2) >> (shift))
147 #endif
148 
149 
161 #define ddLCHash3(f,g,h,shift) ddCHash2(f,g,h,shift)
162 
163 
166 /*---------------------------------------------------------------------------*/
167 /* Static function prototypes */
168 /*---------------------------------------------------------------------------*/
169 
170 static void cuddLocalCacheResize (DdLocalCache *cache);
171 DD_INLINE static unsigned int ddLCHash (DdNodePtr *key, unsigned int keysize, int shift);
172 static void cuddLocalCacheAddToList (DdLocalCache *cache);
173 static void cuddLocalCacheRemoveFromList (DdLocalCache *cache);
174 static int cuddHashTableResize (DdHashTable *hash);
176 
180 /*---------------------------------------------------------------------------*/
181 /* Definition of exported functions */
182 /*---------------------------------------------------------------------------*/
183 
184 /*---------------------------------------------------------------------------*/
185 /* Definition of internal functions */
186 /*---------------------------------------------------------------------------*/
187 
188 
201 DdLocalCache *
203  DdManager * manager /* manager */,
204  unsigned int keySize /* size of the key (number of operands) */,
205  unsigned int cacheSize /* Initial size of the cache */,
206  unsigned int maxCacheSize /* Size of the cache beyond which no resizing occurs */)
207 {
208  DdLocalCache *cache;
209  int logSize;
210 
211  cache = ALLOC(DdLocalCache,1);
212  if (cache == NULL) {
213  manager->errorCode = CUDD_MEMORY_OUT;
214  return(NULL);
215  }
216  cache->manager = manager;
217  cache->keysize = keySize;
218  cache->itemsize = (keySize + 1) * sizeof(DdNode *);
219 #ifdef DD_CACHE_PROFILE
220  cache->itemsize += sizeof(ptrint);
221 #endif
222  logSize = cuddComputeFloorLog2(ddMax(cacheSize,manager->slots/2));
223  cacheSize = 1 << logSize;
224  cache->item = (DdLocalCacheItem *)
225  ALLOC(char, cacheSize * cache->itemsize);
226  if (cache->item == NULL) {
227  manager->errorCode = CUDD_MEMORY_OUT;
228  FREE(cache);
229  return(NULL);
230  }
231  cache->slots = cacheSize;
232  cache->shift = sizeof(int) * 8 - logSize;
233  cache->maxslots = ddMin(maxCacheSize,manager->slots);
234  cache->minHit = manager->minHit;
235  /* Initialize to avoid division by 0 and immediate resizing. */
236  cache->lookUps = (double) (int) (cacheSize * cache->minHit + 1);
237  cache->hits = 0;
238  manager->memused += cacheSize * cache->itemsize + sizeof(DdLocalCache);
239 
240  /* Initialize the cache. */
241  memset(cache->item, 0, cacheSize * cache->itemsize);
242 
243  /* Add to manager's list of local caches for GC. */
245 
246  return(cache);
247 
248 } /* end of cuddLocalCacheInit */
249 
250 
264 void
266  DdLocalCache * cache /* cache to be shut down */)
267 {
268  cache->manager->memused -=
269  cache->slots * cache->itemsize + sizeof(DdLocalCache);
271  FREE(cache->item);
272  FREE(cache);
273 
274  return;
275 
276 } /* end of cuddLocalCacheQuit */
277 
278 
290 void
292  DdLocalCache * cache,
293  DdNodePtr * key,
294  DdNode * value)
295 {
296  unsigned int posn;
298 
299  posn = ddLCHash(key,cache->keysize,cache->shift);
300  entry = (DdLocalCacheItem *) ((char *) cache->item +
301  posn * cache->itemsize);
302  memcpy(entry->key,key,cache->keysize * sizeof(DdNode *));
303  entry->value = value;
304 #ifdef DD_CACHE_PROFILE
305  entry->count++;
306 #endif
307 
308 } /* end of cuddLocalCacheInsert */
309 
310 
323 DdNode *
325  DdLocalCache * cache,
326  DdNodePtr * key)
327 {
328  unsigned int posn;
330  DdNode *value;
331 
332  cache->lookUps++;
333  posn = ddLCHash(key,cache->keysize,cache->shift);
334  entry = (DdLocalCacheItem *) ((char *) cache->item +
335  posn * cache->itemsize);
336  if (entry->value != NULL &&
337  memcmp(key,entry->key,cache->keysize*sizeof(DdNode *)) == 0) {
338  cache->hits++;
339  value = Cudd_Regular(entry->value);
340  if (value->ref == 0) {
341  cuddReclaim(cache->manager,value);
342  }
343  return(entry->value);
344  }
345 
346  /* Cache miss: decide whether to resize */
347 
348  if (cache->slots < cache->maxslots &&
349  cache->hits > cache->lookUps * cache->minHit) {
350  cuddLocalCacheResize(cache);
351  }
352 
353  return(NULL);
354 
355 } /* end of cuddLocalCacheLookup */
356 
357 
370 void
372  DdManager * manager)
373 {
374  DdLocalCache *cache = manager->localCaches;
375  unsigned int keysize;
376  unsigned int itemsize;
377  unsigned int slots;
378  DdLocalCacheItem *item;
379  DdNodePtr *key;
380  unsigned int i, j;
381 
382  while (cache != NULL) {
383  keysize = cache->keysize;
384  itemsize = cache->itemsize;
385  slots = cache->slots;
386  item = cache->item;
387  for (i = 0; i < slots; i++) {
388  if (item->value != NULL) {
389  if (Cudd_Regular(item->value)->ref == 0) {
390  item->value = NULL;
391  } else {
392  key = item->key;
393  for (j = 0; j < keysize; j++) {
394  if (Cudd_Regular(key[j])->ref == 0) {
395  item->value = NULL;
396  break;
397  }
398  }
399  }
400  }
401  item = (DdLocalCacheItem *) ((char *) item + itemsize);
402  }
403  cache = cache->next;
404  }
405  return;
406 
407 } /* end of cuddLocalCacheClearDead */
408 
409 
422 void
424  DdManager * manager)
425 {
426  DdLocalCache *cache = manager->localCaches;
427 
428  while (cache != NULL) {
429  memset(cache->item, 0, cache->slots * cache->itemsize);
430  cache = cache->next;
431  }
432  return;
433 
434 } /* end of cuddLocalCacheClearAll */
435 
436 
437 #ifdef DD_CACHE_PROFILE
438 
439 #define DD_HYSTO_BINS 8
440 
453 int
454 cuddLocalCacheProfile(
455  DdLocalCache * cache)
456 {
457  double count, mean, meansq, stddev, expected;
458  long max, min;
459  int imax, imin;
460  int i, retval, slots;
461  long *hystogram;
462  int nbins = DD_HYSTO_BINS;
463  int bin;
464  long thiscount;
465  double totalcount;
466  int nzeroes;
468  FILE *fp = cache->manager->out;
469 
470  slots = cache->slots;
471 
472  meansq = mean = expected = 0.0;
473  max = min = (long) cache->item[0].count;
474  imax = imin = nzeroes = 0;
475  totalcount = 0.0;
476 
477  hystogram = ALLOC(long, nbins);
478  if (hystogram == NULL) {
479  return(0);
480  }
481  for (i = 0; i < nbins; i++) {
482  hystogram[i] = 0;
483  }
484 
485  for (i = 0; i < slots; i++) {
486  entry = (DdLocalCacheItem *) ((char *) cache->item +
487  i * cache->itemsize);
488  thiscount = (long) entry->count;
489  if (thiscount > max) {
490  max = thiscount;
491  imax = i;
492  }
493  if (thiscount < min) {
494  min = thiscount;
495  imin = i;
496  }
497  if (thiscount == 0) {
498  nzeroes++;
499  }
500  count = (double) thiscount;
501  mean += count;
502  meansq += count * count;
503  totalcount += count;
504  expected += count * (double) i;
505  bin = (i * nbins) / slots;
506  hystogram[bin] += thiscount;
507  }
508  mean /= (double) slots;
509  meansq /= (double) slots;
510  stddev = sqrt(meansq - mean*mean);
511 
512  retval = fprintf(fp,"Cache stats: slots = %d average = %g ", slots, mean);
513  if (retval == EOF) return(0);
514  retval = fprintf(fp,"standard deviation = %g\n", stddev);
515  if (retval == EOF) return(0);
516  retval = fprintf(fp,"Cache max accesses = %ld for slot %d\n", max, imax);
517  if (retval == EOF) return(0);
518  retval = fprintf(fp,"Cache min accesses = %ld for slot %d\n", min, imin);
519  if (retval == EOF) return(0);
520  retval = fprintf(fp,"Cache unused slots = %d\n", nzeroes);
521  if (retval == EOF) return(0);
522 
523  if (totalcount) {
524  expected /= totalcount;
525  retval = fprintf(fp,"Cache access hystogram for %d bins", nbins);
526  if (retval == EOF) return(0);
527  retval = fprintf(fp," (expected bin value = %g)\n# ", expected);
528  if (retval == EOF) return(0);
529  for (i = nbins - 1; i>=0; i--) {
530  retval = fprintf(fp,"%ld ", hystogram[i]);
531  if (retval == EOF) return(0);
532  }
533  retval = fprintf(fp,"\n");
534  if (retval == EOF) return(0);
535  }
536 
537  FREE(hystogram);
538  return(1);
539 
540 } /* end of cuddLocalCacheProfile */
541 #endif
542 
543 
556 DdHashTable *
558  DdManager * manager,
559  unsigned int keySize,
560  unsigned int initSize)
561 {
562  DdHashTable *hash;
563  int logSize;
564 
565  hash = ALLOC(DdHashTable, 1);
566  if (hash == NULL) {
567  manager->errorCode = CUDD_MEMORY_OUT;
568  return(NULL);
569  }
570  hash->keysize = keySize;
571  hash->manager = manager;
572  hash->memoryList = NULL;
573  hash->nextFree = NULL;
574  hash->itemsize = (keySize + 1) * sizeof(DdNode *) +
575  sizeof(ptrint) + sizeof(DdHashItem *);
576  /* We have to guarantee that the shift be < 32. */
577  if (initSize < 2) initSize = 2;
578  logSize = cuddComputeFloorLog2(initSize);
579  hash->numBuckets = 1 << logSize;
580  hash->shift = sizeof(int) * 8 - logSize;
581  hash->bucket = ALLOC(DdHashItem *, hash->numBuckets);
582  if (hash->bucket == NULL) {
583  manager->errorCode = CUDD_MEMORY_OUT;
584  FREE(hash);
585  return(NULL);
586  }
587  memset(hash->bucket, 0, hash->numBuckets * sizeof(DdHashItem *));
588  hash->size = 0;
590  return(hash);
591 
592 } /* end of cuddHashTableInit */
593 
594 
606 void
608  DdHashTable * hash)
609 {
610  unsigned int i;
611  DdManager *dd = hash->manager;
612  DdHashItem *bucket;
613  DdHashItem **memlist, **nextmem;
614  unsigned int numBuckets = hash->numBuckets;
615 
616  for (i = 0; i < numBuckets; i++) {
617  bucket = hash->bucket[i];
618  while (bucket != NULL) {
619  Cudd_RecursiveDeref(dd, bucket->value);
620  bucket = bucket->next;
621  }
622  }
623 
624  memlist = hash->memoryList;
625  while (memlist != NULL) {
626  nextmem = (DdHashItem **) memlist[0];
627  FREE(memlist);
628  memlist = nextmem;
629  }
630 
631  FREE(hash->bucket);
632  FREE(hash);
633 
634  return;
635 
636 } /* end of cuddHashTableQuit */
637 
638 
651 void
653  DdHashTable * hash)
654 {
655 #ifdef __osf__
656 #pragma pointer_size save
657 #pragma pointer_size short
658 #endif
659  DdHashItem **memlist, **nextmem;
660 
661  memlist = hash->memoryList;
662  while (memlist != NULL) {
663  nextmem = (DdHashItem **) memlist[0];
664  FREE(memlist);
665  memlist = nextmem;
666  }
667 
668  FREE(hash->bucket);
669  FREE(hash);
670 #ifdef __osf__
671 #pragma pointer_size restore
672 #endif
673 
674  return;
675 
676 } /* end of cuddHashTableGenericQuit */
677 
678 
692 int
694  DdHashTable * hash,
695  DdNodePtr * key,
696  DdNode * value,
697  ptrint count)
698 {
699  int result;
700  unsigned int posn;
701  DdHashItem *item;
702  unsigned int i;
703 
704 #ifdef DD_DEBUG
705  assert(hash->keysize > 3);
706 #endif
707 
708  if (hash->size > hash->maxsize) {
709  result = cuddHashTableResize(hash);
710  if (result == 0) return(0);
711  }
712  item = cuddHashTableAlloc(hash);
713  if (item == NULL) return(0);
714  hash->size++;
715  item->value = value;
716  cuddRef(value);
717  item->count = count;
718  for (i = 0; i < hash->keysize; i++) {
719  item->key[i] = key[i];
720  }
721  posn = ddLCHash(key,hash->keysize,hash->shift);
722  item->next = hash->bucket[posn];
723  hash->bucket[posn] = item;
724 
725  return(1);
726 
727 } /* end of cuddHashTableInsert */
728 
729 
747 DdNode *
749  DdHashTable * hash,
750  DdNodePtr * key)
751 {
752  unsigned int posn;
753  DdHashItem *item, *prev;
754  unsigned int i, keysize;
755 
756 #ifdef DD_DEBUG
757  assert(hash->keysize > 3);
758 #endif
759 
760  posn = ddLCHash(key,hash->keysize,hash->shift);
761  item = hash->bucket[posn];
762  prev = NULL;
763 
764  keysize = hash->keysize;
765  while (item != NULL) {
766  DdNodePtr *key2 = item->key;
767  int equal = 1;
768  for (i = 0; i < keysize; i++) {
769  if (key[i] != key2[i]) {
770  equal = 0;
771  break;
772  }
773  }
774  if (equal) {
775  DdNode *value = item->value;
776  cuddSatDec(item->count);
777  if (item->count == 0) {
778  cuddDeref(value);
779  if (prev == NULL) {
780  hash->bucket[posn] = item->next;
781  } else {
782  prev->next = item->next;
783  }
784  item->next = hash->nextFree;
785  hash->nextFree = item;
786  hash->size--;
787  }
788  return(value);
789  }
790  prev = item;
791  item = item->next;
792  }
793  return(NULL);
794 
795 } /* end of cuddHashTableLookup */
796 
797 
811 int
813  DdHashTable * hash,
814  DdNode * f,
815  DdNode * value,
816  ptrint count)
817 {
818  int result;
819  unsigned int posn;
820  DdHashItem *item;
821 
822 #ifdef DD_DEBUG
823  assert(hash->keysize == 1);
824 #endif
825 
826  if (hash->size > hash->maxsize) {
827  result = cuddHashTableResize(hash);
828  if (result == 0) return(0);
829  }
830  item = cuddHashTableAlloc(hash);
831  if (item == NULL) return(0);
832  hash->size++;
833  item->value = value;
834  cuddRef(value);
835  item->count = count;
836  item->key[0] = f;
837  posn = ddLCHash1(f,hash->shift);
838  item->next = hash->bucket[posn];
839  hash->bucket[posn] = item;
840 
841  return(1);
842 
843 } /* end of cuddHashTableInsert1 */
844 
845 
863 DdNode *
865  DdHashTable * hash,
866  DdNode * f)
867 {
868  unsigned int posn;
869  DdHashItem *item, *prev;
870 
871 #ifdef DD_DEBUG
872  assert(hash->keysize == 1);
873 #endif
874 
875  posn = ddLCHash1(f,hash->shift);
876  item = hash->bucket[posn];
877  prev = NULL;
878 
879  while (item != NULL) {
880  DdNodePtr *key = item->key;
881  if (f == key[0]) {
882  DdNode *value = item->value;
883  cuddSatDec(item->count);
884  if (item->count == 0) {
885  cuddDeref(value);
886  if (prev == NULL) {
887  hash->bucket[posn] = item->next;
888  } else {
889  prev->next = item->next;
890  }
891  item->next = hash->nextFree;
892  hash->nextFree = item;
893  hash->size--;
894  }
895  return(value);
896  }
897  prev = item;
898  item = item->next;
899  }
900  return(NULL);
901 
902 } /* end of cuddHashTableLookup1 */
903 
904 
918 int
920  DdHashTable * hash,
921  DdNode * f,
922  void * value)
923 {
924  int result;
925  unsigned int posn;
926  DdHashItem *item;
927 
928 #ifdef DD_DEBUG
929  assert(hash->keysize == 1);
930 #endif
931 
932  if (hash->size > hash->maxsize) {
933  result = cuddHashTableResize(hash);
934  if (result == 0) return(0);
935  }
936  item = cuddHashTableAlloc(hash);
937  if (item == NULL) return(0);
938  hash->size++;
939  item->value = (DdNode *) value;
940  item->count = 0;
941  item->key[0] = f;
942  posn = ddLCHash1(f,hash->shift);
943  item->next = hash->bucket[posn];
944  hash->bucket[posn] = item;
945 
946  return(1);
947 
948 } /* end of cuddHashTableGenericInsert */
949 
950 
965 void *
967  DdHashTable * hash,
968  DdNode * f)
969 {
970  unsigned int posn;
971  DdHashItem *item;
972 
973 #ifdef DD_DEBUG
974  assert(hash->keysize == 1);
975 #endif
976 
977  posn = ddLCHash1(f,hash->shift);
978  item = hash->bucket[posn];
979 
980  while (item != NULL) {
981  if (f == item->key[0]) {
982  return ((void *) item->value);
983  }
984  item = item->next;
985  }
986  return(NULL);
987 
988 } /* end of cuddHashTableGenericLookup */
989 
990 
1004 int
1006  DdHashTable * hash,
1007  DdNode * f,
1008  DdNode * g,
1009  DdNode * value,
1010  ptrint count)
1011 {
1012  int result;
1013  unsigned int posn;
1014  DdHashItem *item;
1015 
1016 #ifdef DD_DEBUG
1017  assert(hash->keysize == 2);
1018 #endif
1019 
1020  if (hash->size > hash->maxsize) {
1021  result = cuddHashTableResize(hash);
1022  if (result == 0) return(0);
1023  }
1024  item = cuddHashTableAlloc(hash);
1025  if (item == NULL) return(0);
1026  hash->size++;
1027  item->value = value;
1028  cuddRef(value);
1029  item->count = count;
1030  item->key[0] = f;
1031  item->key[1] = g;
1032  posn = ddLCHash2(f,g,hash->shift);
1033  item->next = hash->bucket[posn];
1034  hash->bucket[posn] = item;
1035 
1036  return(1);
1037 
1038 } /* end of cuddHashTableInsert2 */
1039 
1040 
1058 DdNode *
1060  DdHashTable * hash,
1061  DdNode * f,
1062  DdNode * g)
1063 {
1064  unsigned int posn;
1065  DdHashItem *item, *prev;
1066 
1067 #ifdef DD_DEBUG
1068  assert(hash->keysize == 2);
1069 #endif
1070 
1071  posn = ddLCHash2(f,g,hash->shift);
1072  item = hash->bucket[posn];
1073  prev = NULL;
1074 
1075  while (item != NULL) {
1076  DdNodePtr *key = item->key;
1077  if ((f == key[0]) && (g == key[1])) {
1078  DdNode *value = item->value;
1079  cuddSatDec(item->count);
1080  if (item->count == 0) {
1081  cuddDeref(value);
1082  if (prev == NULL) {
1083  hash->bucket[posn] = item->next;
1084  } else {
1085  prev->next = item->next;
1086  }
1087  item->next = hash->nextFree;
1088  hash->nextFree = item;
1089  hash->size--;
1090  }
1091  return(value);
1092  }
1093  prev = item;
1094  item = item->next;
1095  }
1096  return(NULL);
1097 
1098 } /* end of cuddHashTableLookup2 */
1099 
1100 
1114 int
1116  DdHashTable * hash,
1117  DdNode * f,
1118  DdNode * g,
1119  DdNode * h,
1120  DdNode * value,
1121  ptrint count)
1122 {
1123  int result;
1124  unsigned int posn;
1125  DdHashItem *item;
1126 
1127 #ifdef DD_DEBUG
1128  assert(hash->keysize == 3);
1129 #endif
1130 
1131  if (hash->size > hash->maxsize) {
1132  result = cuddHashTableResize(hash);
1133  if (result == 0) return(0);
1134  }
1135  item = cuddHashTableAlloc(hash);
1136  if (item == NULL) return(0);
1137  hash->size++;
1138  item->value = value;
1139  cuddRef(value);
1140  item->count = count;
1141  item->key[0] = f;
1142  item->key[1] = g;
1143  item->key[2] = h;
1144  posn = ddLCHash3(f,g,h,hash->shift);
1145  item->next = hash->bucket[posn];
1146  hash->bucket[posn] = item;
1147 
1148  return(1);
1149 
1150 } /* end of cuddHashTableInsert3 */
1151 
1152 
1170 DdNode *
1172  DdHashTable * hash,
1173  DdNode * f,
1174  DdNode * g,
1175  DdNode * h)
1176 {
1177  unsigned int posn;
1178  DdHashItem *item, *prev;
1179 
1180 #ifdef DD_DEBUG
1181  assert(hash->keysize == 3);
1182 #endif
1183 
1184  posn = ddLCHash3(f,g,h,hash->shift);
1185  item = hash->bucket[posn];
1186  prev = NULL;
1187 
1188  while (item != NULL) {
1189  DdNodePtr *key = item->key;
1190  if ((f == key[0]) && (g == key[1]) && (h == key[2])) {
1191  DdNode *value = item->value;
1192  cuddSatDec(item->count);
1193  if (item->count == 0) {
1194  cuddDeref(value);
1195  if (prev == NULL) {
1196  hash->bucket[posn] = item->next;
1197  } else {
1198  prev->next = item->next;
1199  }
1200  item->next = hash->nextFree;
1201  hash->nextFree = item;
1202  hash->size--;
1203  }
1204  return(value);
1205  }
1206  prev = item;
1207  item = item->next;
1208  }
1209  return(NULL);
1210 
1211 } /* end of cuddHashTableLookup3 */
1212 
1213 
1214 /*---------------------------------------------------------------------------*/
1215 /* Definition of static functions */
1216 /*---------------------------------------------------------------------------*/
1217 
1218 
1230 static void
1232  DdLocalCache * cache)
1233 {
1234  DdLocalCacheItem *item, *olditem, *entry, *old;
1235  int i, shift;
1236  unsigned int posn;
1237  unsigned int slots, oldslots;
1238  extern DD_OOMFP MMoutOfMemory;
1239  DD_OOMFP saveHandler;
1240 
1241  olditem = cache->item;
1242  oldslots = cache->slots;
1243  slots = cache->slots = oldslots << 1;
1244 
1245 #ifdef DD_VERBOSE
1246  (void) fprintf(cache->manager->err,
1247  "Resizing local cache from %d to %d entries\n",
1248  oldslots, slots);
1249  (void) fprintf(cache->manager->err,
1250  "\thits = %.0f\tlookups = %.0f\thit ratio = %5.3f\n",
1251  cache->hits, cache->lookUps, cache->hits / cache->lookUps);
1252 #endif
1253 
1254  saveHandler = MMoutOfMemory;
1255  MMoutOfMemory = Cudd_OutOfMem;
1256  cache->item = item =
1257  (DdLocalCacheItem *) ALLOC(char, slots * cache->itemsize);
1258  MMoutOfMemory = saveHandler;
1259  /* If we fail to allocate the new table we just give up. */
1260  if (item == NULL) {
1261 #ifdef DD_VERBOSE
1262  (void) fprintf(cache->manager->err,"Resizing failed. Giving up.\n");
1263 #endif
1264  cache->slots = oldslots;
1265  cache->item = olditem;
1266  /* Do not try to resize again. */
1267  cache->maxslots = oldslots - 1;
1268  return;
1269  }
1270  shift = --(cache->shift);
1271  cache->manager->memused += (slots - oldslots) * cache->itemsize;
1272 
1273  /* Clear new cache. */
1274  memset(item, 0, slots * cache->itemsize);
1275 
1276  /* Copy from old cache to new one. */
1277  for (i = 0; (unsigned) i < oldslots; i++) {
1278  old = (DdLocalCacheItem *) ((char *) olditem + i * cache->itemsize);
1279  if (old->value != NULL) {
1280  posn = ddLCHash(old->key,cache->keysize,shift);
1281  entry = (DdLocalCacheItem *) ((char *) item +
1282  posn * cache->itemsize);
1283  memcpy(entry->key,old->key,cache->keysize*sizeof(DdNode *));
1284  entry->value = old->value;
1285  }
1286  }
1287 
1288  FREE(olditem);
1289 
1290  /* Reinitialize measurements so as to avoid division by 0 and
1291  ** immediate resizing.
1292  */
1293  cache->lookUps = (double) (int) (slots * cache->minHit + 1);
1294  cache->hits = 0;
1295 
1296 } /* end of cuddLocalCacheResize */
1297 
1298 
1311 DD_INLINE
1312 static unsigned int
1314  DdNodePtr * key,
1315  unsigned int keysize,
1316  int shift)
1317 {
1318  unsigned int val = (unsigned int) (ptrint) key[0] * DD_P2;
1319  unsigned int i;
1320 
1321  for (i = 1; i < keysize; i++) {
1322  val = val * DD_P1 + (int) (ptrint) key[i];
1323  }
1324 
1325  return(val >> shift);
1326 
1327 } /* end of ddLCHash */
1328 
1329 
1341 static void
1343  DdLocalCache * cache)
1344 {
1345  DdManager *manager = cache->manager;
1346 
1347  cache->next = manager->localCaches;
1348  manager->localCaches = cache;
1349  return;
1350 
1351 } /* end of cuddLocalCacheAddToList */
1352 
1353 
1365 static void
1367  DdLocalCache * cache)
1368 {
1369  DdManager *manager = cache->manager;
1370  DdLocalCache **prevCache, *nextCache;
1371 
1372  prevCache = &(manager->localCaches);
1373  nextCache = manager->localCaches;
1374 
1375  while (nextCache != NULL) {
1376  if (nextCache == cache) {
1377  *prevCache = nextCache->next;
1378  return;
1379  }
1380  prevCache = &(nextCache->next);
1381  nextCache = nextCache->next;
1382  }
1383  return; /* should never get here */
1384 
1385 } /* end of cuddLocalCacheRemoveFromList */
1386 
1387 
1400 static int
1402  DdHashTable * hash)
1403 {
1404  int j;
1405  unsigned int posn;
1406  DdHashItem *item;
1407  DdHashItem *next;
1408  DdNode **key;
1409  int numBuckets;
1410  DdHashItem **buckets;
1411  DdHashItem **oldBuckets = hash->bucket;
1412  int shift;
1413  int oldNumBuckets = hash->numBuckets;
1414  extern DD_OOMFP MMoutOfMemory;
1415  DD_OOMFP saveHandler;
1416 
1417  /* Compute the new size of the table. */
1418  numBuckets = oldNumBuckets << 1;
1419  saveHandler = MMoutOfMemory;
1420  MMoutOfMemory = Cudd_OutOfMem;
1421  buckets = ALLOC(DdHashItem *, numBuckets);
1422  MMoutOfMemory = saveHandler;
1423  if (buckets == NULL) {
1424  hash->maxsize <<= 1;
1425  return(1);
1426  }
1427 
1428  hash->bucket = buckets;
1429  hash->numBuckets = numBuckets;
1430  shift = --(hash->shift);
1431  hash->maxsize <<= 1;
1432  memset(buckets, 0, numBuckets * sizeof(DdHashItem *));
1433  if (hash->keysize == 1) {
1434  for (j = 0; j < oldNumBuckets; j++) {
1435  item = oldBuckets[j];
1436  while (item != NULL) {
1437  next = item->next;
1438  key = item->key;
1439  posn = ddLCHash2(key[0], key[0], shift);
1440  item->next = buckets[posn];
1441  buckets[posn] = item;
1442  item = next;
1443  }
1444  }
1445  } else if (hash->keysize == 2) {
1446  for (j = 0; j < oldNumBuckets; j++) {
1447  item = oldBuckets[j];
1448  while (item != NULL) {
1449  next = item->next;
1450  key = item->key;
1451  posn = ddLCHash2(key[0], key[1], shift);
1452  item->next = buckets[posn];
1453  buckets[posn] = item;
1454  item = next;
1455  }
1456  }
1457  } else if (hash->keysize == 3) {
1458  for (j = 0; j < oldNumBuckets; j++) {
1459  item = oldBuckets[j];
1460  while (item != NULL) {
1461  next = item->next;
1462  key = item->key;
1463  posn = ddLCHash3(key[0], key[1], key[2], shift);
1464  item->next = buckets[posn];
1465  buckets[posn] = item;
1466  item = next;
1467  }
1468  }
1469  } else {
1470  for (j = 0; j < oldNumBuckets; j++) {
1471  item = oldBuckets[j];
1472  while (item != NULL) {
1473  next = item->next;
1474  posn = ddLCHash(item->key, hash->keysize, shift);
1475  item->next = buckets[posn];
1476  buckets[posn] = item;
1477  item = next;
1478  }
1479  }
1480  }
1481  FREE(oldBuckets);
1482  return(1);
1483 
1484 } /* end of cuddHashTableResize */
1485 
1486 
1501 DD_INLINE
1502 static DdHashItem *
1504  DdHashTable * hash)
1505 {
1506  int i;
1507  unsigned int itemsize = hash->itemsize;
1508  extern DD_OOMFP MMoutOfMemory;
1509  DD_OOMFP saveHandler;
1510  DdHashItem **mem, *thisOne, *next, *item;
1511 
1512  if (hash->nextFree == NULL) {
1513  saveHandler = MMoutOfMemory;
1514  MMoutOfMemory = Cudd_OutOfMem;
1515  mem = (DdHashItem **) ALLOC(char,(DD_MEM_CHUNK+1) * itemsize);
1516  MMoutOfMemory = saveHandler;
1517  if (mem == NULL) {
1518  if (hash->manager->stash != NULL) {
1519  FREE(hash->manager->stash);
1520  hash->manager->stash = NULL;
1521  /* Inhibit resizing of tables. */
1522  hash->manager->maxCacheHard = hash->manager->cacheSlots - 1;
1523  hash->manager->cacheSlack = - (int) (hash->manager->cacheSlots + 1);
1524  for (i = 0; i < hash->manager->size; i++) {
1525  hash->manager->subtables[i].maxKeys <<= 2;
1526  }
1527  hash->manager->gcFrac = 0.2;
1528  hash->manager->minDead =
1529  (unsigned) (0.2 * (double) hash->manager->slots);
1530  mem = (DdHashItem **) ALLOC(char,(DD_MEM_CHUNK+1) * itemsize);
1531  }
1532  if (mem == NULL) {
1533  (*MMoutOfMemory)((long)((DD_MEM_CHUNK + 1) * itemsize));
1535  return(NULL);
1536  }
1537  }
1538 
1539  mem[0] = (DdHashItem *) hash->memoryList;
1540  hash->memoryList = mem;
1541 
1542  thisOne = (DdHashItem *) ((char *) mem + itemsize);
1543  hash->nextFree = thisOne;
1544  for (i = 1; i < DD_MEM_CHUNK; i++) {
1545  next = (DdHashItem *) ((char *) thisOne + itemsize);
1546  thisOne->next = next;
1547  thisOne = next;
1548  }
1549 
1550  thisOne->next = NULL;
1551 
1552  }
1553  item = hash->nextFree;
1554  hash->nextFree = item->next;
1555  return(item);
1556 
1557 } /* end of cuddHashTableAlloc */
unsigned int keysize
Definition: cuddInt.h:289
DdHalfWord ref
Definition: cudd.h:272
#define cuddRef(n)
Definition: cuddInt.h:557
DdHashItem ** bucket
Definition: cuddInt.h:291
int ptrint
Definition: cuddInt.h:249
DdNode * value
Definition: cuddInt.h:283
unsigned int size
Definition: cuddInt.h:296
static void cuddLocalCacheRemoveFromList(DdLocalCache *cache)
Definition: cuddLCache.c:1366
#define cuddDeref(n)
Definition: cuddInt.h:577
void Cudd_OutOfMem(long size)
Definition: cuddUtil.c:2845
void Cudd_RecursiveDeref(DdManager *table, DdNode *n)
Definition: cuddRef.c:150
Definition: cudd.h:270
#define FREE(obj)
Definition: util.h:80
void cuddLocalCacheInsert(DdLocalCache *cache, DdNodePtr *key, DdNode *value)
Definition: cuddLCache.c:291
#define assert(ex)
Definition: util.h:141
DdManager * manager
Definition: cuddInt.h:298
int size
Definition: cuddInt.h:345
double gcFrac
Definition: cuddInt.h:359
static DD_INLINE DdHashItem * cuddHashTableAlloc(DdHashTable *hash)
Definition: cuddLCache.c:1503
char * memcpy()
unsigned int maxCacheHard
Definition: cuddInt.h:343
unsigned int slots
Definition: cuddInt.h:352
#define Cudd_Regular(node)
Definition: cudd.h:384
void cuddReclaim(DdManager *table, DdNode *n)
Definition: cuddRef.c:580
ptrint count
Definition: cuddInt.h:282
DdNode * cuddHashTableLookup3(DdHashTable *hash, DdNode *f, DdNode *g, DdNode *h)
Definition: cuddLCache.c:1171
FILE * err
Definition: cuddInt.h:424
int cuddHashTableGenericInsert(DdHashTable *hash, DdNode *f, void *value)
Definition: cuddLCache.c:919
struct DdHashItem * next
Definition: cuddInt.h:281
DdHashTable * cuddHashTableInit(DdManager *manager, unsigned int keySize, unsigned int initSize)
Definition: cuddLCache.c:557
void * cuddHashTableGenericLookup(DdHashTable *hash, DdNode *f)
Definition: cuddLCache.c:966
void cuddLocalCacheQuit(DdLocalCache *cache)
Definition: cuddLCache.c:265
DdSubtable * subtables
Definition: cuddInt.h:349
DdNode * value
Definition: cuddInt.h:257
double minHit
Definition: cuddInt.h:272
unsigned int keysize
Definition: cuddInt.h:268
#define ddLCHash1(f, shift)
Definition: cuddLCache.c:124
DdLocalCacheItem * item
Definition: cuddInt.h:266
void(* DD_OOMFP)(long)
Definition: cudd.h:311
static char rcsid [] DD_UNUSED
Definition: cuddLCache.c:102
struct DdLocalCache * next
Definition: cuddInt.h:276
static int * entry
Definition: cuddGroup.c:119
DdNode * cuddHashTableLookup2(DdHashTable *hash, DdNode *f, DdNode *g)
Definition: cuddLCache.c:1059
unsigned int maxslots
Definition: cuddInt.h:274
#define DD_INLINE
Definition: cuddInt.h:91
int cuddHashTableInsert1(DdHashTable *hash, DdNode *f, DdNode *value, ptrint count)
Definition: cuddLCache.c:812
int cuddHashTableInsert3(DdHashTable *hash, DdNode *f, DdNode *g, DdNode *h, DdNode *value, ptrint count)
Definition: cuddLCache.c:1115
static DD_INLINE unsigned int ddLCHash(DdNodePtr *key, unsigned int keysize, int shift)
Definition: cuddLCache.c:1313
unsigned int cacheSlots
Definition: cuddInt.h:337
char * stash
Definition: cuddInt.h:382
char * memset()
unsigned int itemsize
Definition: cuddInt.h:267
#define ALLOC(type, num)
Definition: util.h:76
FILE * out
Definition: cuddInt.h:423
double hits
Definition: cuddInt.h:273
double lookUps
Definition: cuddInt.h:271
unsigned int numBuckets
Definition: cuddInt.h:294
unsigned int slots
Definition: cuddInt.h:269
DdLocalCache * cuddLocalCacheInit(DdManager *manager, unsigned int keySize, unsigned int cacheSize, unsigned int maxCacheSize)
Definition: cuddLCache.c:202
unsigned int maxKeys
Definition: cuddInt.h:315
#define DD_P2
Definition: cuddInt.h:157
#define ddMax(x, y)
Definition: cuddInt.h:785
static void cuddLocalCacheResize(DdLocalCache *cache)
Definition: cuddLCache.c:1231
void cuddLocalCacheClearDead(DdManager *manager)
Definition: cuddLCache.c:371
unsigned int maxsize
Definition: cuddInt.h:297
#define ddMin(x, y)
Definition: cuddInt.h:771
DdLocalCache * localCaches
Definition: cuddInt.h:417
int cacheSlack
Definition: cuddInt.h:342
int memcmp()
DdNode * cuddHashTableLookup1(DdHashTable *hash, DdNode *f)
Definition: cuddLCache.c:864
DdNode * cuddLocalCacheLookup(DdLocalCache *cache, DdNodePtr *key)
Definition: cuddLCache.c:324
void(* MMoutOfMemory)(long)
Definition: safe_mem.c:32
void cuddHashTableQuit(DdHashTable *hash)
Definition: cuddLCache.c:607
unsigned int itemsize
Definition: cuddInt.h:290
unsigned long memused
Definition: cuddInt.h:429
#define DD_P1
Definition: cuddInt.h:156
DdNode * key[1]
Definition: cuddInt.h:261
DdHashItem * nextFree
Definition: cuddInt.h:292
int cuddHashTableInsert2(DdHashTable *hash, DdNode *f, DdNode *g, DdNode *value, ptrint count)
Definition: cuddLCache.c:1005
double minHit
Definition: cuddInt.h:341
#define cuddSatDec(x)
Definition: cuddInt.h:849
struct DdLocalCache DdLocalCache
DdNode * key[1]
Definition: cuddInt.h:284
#define ddLCHash2(f, g, shift)
Definition: cuddLCache.c:145
DdNode * cuddHashTableLookup(DdHashTable *hash, DdNodePtr *key)
Definition: cuddLCache.c:748
int shift
Definition: cuddInt.h:295
static int result
Definition: cuddGenetic.c:121
int cuddComputeFloorLog2(unsigned int value)
Definition: cuddCache.c:1036
#define DD_MEM_CHUNK
Definition: cuddInt.h:105
DdHashItem ** memoryList
Definition: cuddInt.h:293
DdManager * manager
Definition: cuddInt.h:275
void cuddHashTableGenericQuit(DdHashTable *hash)
Definition: cuddLCache.c:652
static void cuddLocalCacheAddToList(DdLocalCache *cache)
Definition: cuddLCache.c:1342
Cudd_ErrorType errorCode
Definition: cuddInt.h:425
int cuddHashTableInsert(DdHashTable *hash, DdNodePtr *key, DdNode *value, ptrint count)
Definition: cuddLCache.c:693
unsigned int minDead
Definition: cuddInt.h:358
#define ddLCHash3(f, g, h, shift)
Definition: cuddLCache.c:161
#define DD_MAX_HASHTABLE_DENSITY
Definition: cuddLCache.c:85
static int cuddHashTableResize(DdHashTable *hash)
Definition: cuddLCache.c:1401
void cuddLocalCacheClearAll(DdManager *manager)
Definition: cuddLCache.c:423
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