#include "bddint.h"
Go to the source code of this file.
Defines | |
#define | MIN_GC_LIMIT 10000 |
Functions | |
void | bdd_rehash_var_table (var_table table, int grow) |
static void | bdd_mark (cmu_bdd_manager bddm) |
void | bdd_sweep_var_table (cmu_bdd_manager bddm, long i, int maybe_rehash) |
void | bdd_sweep (cmu_bdd_manager bddm) |
void | cmu_bdd_gc (cmu_bdd_manager bddm) |
static void | bdd_set_gc_limit (cmu_bdd_manager bddm) |
void | bdd_clear_temps (cmu_bdd_manager bddm) |
void | bdd_cleanup (cmu_bdd_manager bddm, int code) |
bdd | bdd_find_aux (cmu_bdd_manager bddm, bdd_indexindex_type indexindex, INT_PTR d1, INT_PTR d2) |
static void | bdd_check (cmu_bdd_manager bddm) |
bdd | bdd_find (cmu_bdd_manager bddm, bdd_indexindex_type indexindex, bdd f, bdd g) |
bdd | bdd_find_terminal (cmu_bdd_manager bddm, INT_PTR value1, INT_PTR value2) |
void | cmu_bdd_clear_refs (cmu_bdd_manager bddm) |
var_table | bdd_new_var_table (cmu_bdd_manager bddm) |
void | cmu_bdd_init_unique (cmu_bdd_manager bddm) |
void | cmu_bdd_free_unique (cmu_bdd_manager bddm) |
#define MIN_GC_LIMIT 10000 |
Definition at line 7 of file bddunique.c.
static void bdd_check | ( | cmu_bdd_manager | bddm | ) | [static] |
Definition at line 227 of file bddunique.c.
00228 { 00229 long nodes; 00230 00231 bddm->check=100; 00232 /* When bag_it_fn set, clean up and abort immediately. */ 00233 if (bddm->bag_it_fn) 00234 longjmp(bddm->abort.context, BDD_ABORTED); 00235 if (bddm->unique_table.entries > bddm->unique_table.gc_limit) 00236 { 00237 cmu_bdd_gc(bddm); 00238 /* Table full. */ 00239 nodes=bddm->unique_table.entries; 00240 if (3*nodes > 2*bddm->unique_table.gc_limit && bddm->allow_reordering && bddm->reorder_fn) 00241 { 00242 cmu_bdd_reorder_aux(bddm); 00243 if (4*bddm->unique_table.entries > 3*nodes && 3*nodes > 4*bddm->nodes_at_start) 00244 /* If we didn't save much, but we have created a reasonable number */ 00245 /* of nodes, then don't bother reordering next time. */ 00246 bddm->allow_reordering=0; 00247 /* Go try again. */ 00248 bdd_set_gc_limit(bddm); 00249 longjmp(bddm->abort.context, BDD_REORDERED); 00250 } 00251 bdd_set_gc_limit(bddm); 00252 if (bddm->unique_table.node_limit && 00253 bddm->unique_table.entries >= bddm->unique_table.node_limit-1000) 00254 { 00255 /* Out of memory; go clean up. */ 00256 bddm->overflow=1; 00257 longjmp(bddm->abort.context, BDD_OVERFLOWED); 00258 } 00259 } 00260 /* Maybe increase cache size if it's getting full. */ 00261 if (3*bddm->op_cache.size < 2*bddm->op_cache.entries && 00262 32*bddm->op_cache.size < bddm->op_cache.cache_ratio*bddm->unique_table.entries) 00263 bdd_rehash_cache(bddm, 1); 00264 }
void bdd_cleanup | ( | cmu_bdd_manager | bddm, | |
int | code | |||
) |
Definition at line 175 of file bddunique.c.
00176 { 00177 bdd_clear_temps(bddm); 00178 switch (code) 00179 { 00180 case BDD_ABORTED: 00181 (*bddm->bag_it_fn)(bddm, bddm->bag_it_env); 00182 break; 00183 case BDD_OVERFLOWED: 00184 if (bddm->overflow_fn) 00185 (*bddm->overflow_fn)(bddm, bddm->overflow_env); 00186 break; 00187 } 00188 }
void bdd_clear_temps | ( | cmu_bdd_manager | bddm | ) |
Definition at line 153 of file bddunique.c.
00154 { 00155 long i, j; 00156 var_table table; 00157 bdd f; 00158 00159 for (i=0; i <= bddm->vars; ++i) 00160 { 00161 table=bddm->unique_table.tables[i]; 00162 for (j=0; j < table->size; ++j) 00163 for (f=table->table[j]; f; f=f->next) 00164 { 00165 BDD_SETUP(f); 00166 BDD_TEMP_REFS(f)=0; 00167 } 00168 } 00169 cmu_bdd_gc(bddm); 00170 bdd_set_gc_limit(bddm); 00171 }
bdd bdd_find | ( | cmu_bdd_manager | bddm, | |
bdd_indexindex_type | indexindex, | |||
bdd | f, | |||
bdd | g | |||
) |
Definition at line 271 of file bddunique.c.
00272 { 00273 bdd temp; 00274 00275 BDD_SETUP(f); 00276 BDD_SETUP(g); 00277 if (f == g) 00278 { 00279 BDD_TEMP_DECREFS(f); 00280 temp=f; 00281 } 00282 else 00283 { 00284 if (BDD_IS_OUTPOS(f)) 00285 temp=bdd_find_aux(bddm, indexindex, (INT_PTR)f, (INT_PTR)g); 00286 else 00287 temp=BDD_NOT(bdd_find_aux(bddm, indexindex, (INT_PTR)BDD_NOT(f), (INT_PTR)BDD_NOT(g))); 00288 { 00289 BDD_SETUP(temp); 00290 BDD_TEMP_INCREFS(temp); 00291 } 00292 BDD_TEMP_DECREFS(f); 00293 BDD_TEMP_DECREFS(g); 00294 } 00295 bddm->check--; 00296 if (!bddm->check) 00297 bdd_check(bddm); 00298 return (temp); 00299 }
bdd bdd_find_aux | ( | cmu_bdd_manager | bddm, | |
bdd_indexindex_type | indexindex, | |||
INT_PTR | d1, | |||
INT_PTR | d2 | |||
) |
Definition at line 192 of file bddunique.c.
00193 { 00194 var_table table; 00195 long hash; 00196 bdd temp; 00197 00198 table=bddm->unique_table.tables[indexindex]; 00199 hash=HASH_NODE(d1, d2); 00200 BDD_REDUCE(hash, table->size); 00201 for (temp=table->table[hash]; temp; temp=temp->next) 00202 if (temp->data[0] == d1 && temp->data[1] == d2) 00203 break; 00204 if (!temp) 00205 { 00206 /* Not found; make a new node. */ 00207 temp=(bdd)BDD_NEW_REC(bddm, sizeof(struct bdd_)); 00208 temp->indexindex=indexindex; 00209 temp->refs=0; 00210 temp->mark=0; 00211 temp->data[0]=d1; 00212 temp->data[1]=d2; 00213 temp->next=table->table[hash]; 00214 table->table[hash]=temp; 00215 table->entries++; 00216 bddm->unique_table.entries++; 00217 if (4*table->size < table->entries) 00218 bdd_rehash_var_table(table, 1); 00219 } 00220 bddm->unique_table.finds++; 00221 return (temp); 00222 }
bdd bdd_find_terminal | ( | cmu_bdd_manager | bddm, | |
INT_PTR | value1, | |||
INT_PTR | value2 | |||
) |
Definition at line 306 of file bddunique.c.
00307 { 00308 bdd temp; 00309 00310 if ((*bddm->canonical_fn)(bddm, value1, value2, bddm->transform_env)) 00311 { 00312 (*bddm->transform_fn)(bddm, value1, value2, &value1, &value2, bddm->transform_env); 00313 temp=BDD_NOT(bdd_find_aux(bddm, BDD_CONST_INDEXINDEX, value1, value2)); 00314 } 00315 else 00316 temp=bdd_find_aux(bddm, BDD_CONST_INDEXINDEX, value1, value2); 00317 { 00318 BDD_SETUP(temp); 00319 BDD_TEMP_INCREFS(temp); 00320 } 00321 bddm->check--; 00322 if (!bddm->check) 00323 bdd_check(bddm); 00324 return (temp); 00325 }
static void bdd_mark | ( | cmu_bdd_manager | bddm | ) | [static] |
Definition at line 44 of file bddunique.c.
00045 { 00046 long i, j; 00047 var_table table; 00048 bdd f, g; 00049 00050 for (i=0; i <= bddm->vars; ++i) 00051 { 00052 if (i == bddm->vars) 00053 table=bddm->unique_table.tables[BDD_CONST_INDEXINDEX]; 00054 else 00055 table=bddm->unique_table.tables[bddm->indexindexes[i]]; 00056 for (j=0; j < table->size; ++j) 00057 for (f=table->table[j]; f; f=f->next) 00058 { 00059 BDD_SETUP(f); 00060 if (BDD_REFS(f) || BDD_TEMP_REFS(f)) 00061 BDD_MARK(f)|=BDD_GC_MARK; 00062 if (BDD_IS_USED(f) && !BDD_IS_CONST(f)) 00063 { 00064 g=(bdd)BDD_DATA0(f); 00065 { 00066 BDD_SETUP(g); 00067 BDD_MARK(g)|=BDD_GC_MARK; 00068 } 00069 g=(bdd)BDD_DATA1(f); 00070 { 00071 BDD_SETUP(g); 00072 BDD_MARK(g)|=BDD_GC_MARK; 00073 } 00074 } 00075 } 00076 } 00077 }
var_table bdd_new_var_table | ( | cmu_bdd_manager | bddm | ) |
Definition at line 362 of file bddunique.c.
00363 { 00364 long i; 00365 var_table table; 00366 00367 table=(var_table)BDD_NEW_REC(bddm, sizeof(struct var_table_)); 00368 table->size_index=3; 00369 table->size=TABLE_SIZE(table->size_index); 00370 table->entries=0; 00371 table->table=(bdd *)mem_get_block((SIZE_T)(table->size*sizeof(bdd))); 00372 for (i=0; i < table->size; ++i) 00373 table->table[i]=0; 00374 return (table); 00375 }
void bdd_rehash_var_table | ( | var_table | table, | |
int | grow | |||
) |
Definition at line 11 of file bddunique.c.
00012 { 00013 long i; 00014 long hash; 00015 long oldsize; 00016 bdd *newtable; 00017 bdd p, q; 00018 00019 oldsize=table->size; 00020 if (grow) 00021 table->size_index++; 00022 else 00023 table->size_index--; 00024 table->size=TABLE_SIZE(table->size_index); 00025 newtable=(bdd *)mem_get_block((SIZE_T)(table->size*sizeof(bdd))); 00026 for (i=0; i < table->size; ++i) 00027 newtable[i]=0; 00028 for (i=0; i < oldsize; ++i) 00029 for (p=table->table[i]; p; p=q) 00030 { 00031 q=p->next; 00032 hash=HASH_NODE(p->data[0], p->data[1]); 00033 BDD_REDUCE(hash, table->size); 00034 p->next=newtable[hash]; 00035 newtable[hash]=p; 00036 } 00037 mem_free_block((pointer)table->table); 00038 table->table=newtable; 00039 }
static void bdd_set_gc_limit | ( | cmu_bdd_manager | bddm | ) | [static] |
Definition at line 141 of file bddunique.c.
00142 { 00143 bddm->unique_table.gc_limit=2*bddm->unique_table.entries; 00144 if (bddm->unique_table.gc_limit < MIN_GC_LIMIT) 00145 bddm->unique_table.gc_limit=MIN_GC_LIMIT; 00146 if (bddm->unique_table.node_limit && 00147 bddm->unique_table.gc_limit > bddm->unique_table.node_limit) 00148 bddm->unique_table.gc_limit=bddm->unique_table.node_limit; 00149 }
void bdd_sweep | ( | cmu_bdd_manager | bddm | ) |
Definition at line 118 of file bddunique.c.
00119 { 00120 long i; 00121 00122 for (i=0; i <= bddm->vars; ++i) 00123 bdd_sweep_var_table(bddm, i, 1); 00124 }
void bdd_sweep_var_table | ( | cmu_bdd_manager | bddm, | |
long | i, | |||
int | maybe_rehash | |||
) |
Definition at line 81 of file bddunique.c.
00082 { 00083 long j; 00084 var_table table; 00085 bdd f, *p; 00086 00087 table=bddm->unique_table.tables[i]; 00088 for (j=0; j < table->size; ++j) 00089 for (p= &table->table[j], f= *p; f; f= *p) 00090 { 00091 BDD_SETUP(f); 00092 if (BDD_IS_USED(f)) 00093 { 00094 BDD_SETUP(f); 00095 BDD_MARK(f)&=~BDD_GC_MARK; 00096 p= &f->next; 00097 } 00098 else 00099 { 00100 *p=f->next; 00101 if (i == BDD_CONST_INDEXINDEX && bddm->unique_table.free_terminal_fn) 00102 (*bddm->unique_table.free_terminal_fn)(bddm, 00103 BDD_DATA0(f), 00104 BDD_DATA1(f), 00105 bddm->unique_table.free_terminal_env); 00106 BDD_FREE_REC(bddm, (pointer)f, sizeof(struct bdd_)); 00107 table->entries--; 00108 bddm->unique_table.entries--; 00109 bddm->unique_table.freed++; 00110 } 00111 } 00112 if (maybe_rehash && table->size > table->entries && table->size_index > 3) 00113 bdd_rehash_var_table(table, 0); 00114 }
void cmu_bdd_clear_refs | ( | cmu_bdd_manager | bddm | ) |
Definition at line 331 of file bddunique.c.
00332 { 00333 long i, j; 00334 var_table table; 00335 bdd f; 00336 assoc_list q; 00337 00338 for (i=0; i <= bddm->vars; ++i) 00339 { 00340 table=bddm->unique_table.tables[i]; 00341 for (j=0; j < table->size; ++j) 00342 for (f=table->table[j]; f; f=f->next) 00343 { 00344 BDD_SETUP(f); 00345 BDD_REFS(f)=0; 00346 } 00347 } 00348 for (i=0; i < bddm->vars; ++i) 00349 bddm->variables[i+1]->refs=BDD_MAX_REFS; 00350 bddm->one->refs=BDD_MAX_REFS; 00351 for (q=bddm->assocs; q; q=q->next) 00352 for (i=0; i < bddm->vars; ++i) 00353 if ((f=q->va.assoc[i+1])) 00354 { 00355 BDD_SETUP(f); 00356 BDD_INCREFS(f); 00357 } 00358 }
void cmu_bdd_free_unique | ( | cmu_bdd_manager | bddm | ) |
Definition at line 395 of file bddunique.c.
00396 { 00397 long i, j; 00398 var_table table; 00399 bdd p, q; 00400 00401 for (i=0; i <= bddm->vars; ++i) 00402 { 00403 table=bddm->unique_table.tables[i]; 00404 for (j=0; j < table->size; ++j) 00405 for (p=table->table[j]; p; p=q) 00406 { 00407 q=p->next; 00408 BDD_FREE_REC(bddm, (pointer)p, sizeof(struct bdd_)); 00409 } 00410 mem_free_block((pointer)table->table); 00411 BDD_FREE_REC(bddm, (pointer)table, sizeof(struct var_table_)); 00412 } 00413 mem_free_block((pointer)bddm->unique_table.tables); 00414 }
void cmu_bdd_gc | ( | cmu_bdd_manager | bddm | ) |
Definition at line 130 of file bddunique.c.
00131 { 00132 bdd_mark(bddm); 00133 bdd_purge_cache(bddm); 00134 bdd_sweep(bddm); 00135 bddm->unique_table.gcs++; 00136 }
void cmu_bdd_init_unique | ( | cmu_bdd_manager | bddm | ) |
Definition at line 379 of file bddunique.c.
00380 { 00381 bddm->unique_table.tables=(var_table *)mem_get_block((SIZE_T)((bddm->maxvars+1)*sizeof(var_table))); 00382 bddm->unique_table.tables[BDD_CONST_INDEXINDEX]=bdd_new_var_table(bddm); 00383 bddm->unique_table.gc_limit=MIN_GC_LIMIT; 00384 bddm->unique_table.node_limit=0; 00385 bddm->unique_table.entries=0; 00386 bddm->unique_table.freed=0; 00387 bddm->unique_table.gcs=0; 00388 bddm->unique_table.finds=0; 00389 bddm->unique_table.free_terminal_fn=0; 00390 bddm->unique_table.free_terminal_env=0; 00391 }