1 | /**CFile*********************************************************************** |
---|
2 | |
---|
3 | FileName [calReorderDF.c] |
---|
4 | |
---|
5 | PackageName [cal] |
---|
6 | |
---|
7 | Synopsis [Routines for dynamic reordering of variables.] |
---|
8 | |
---|
9 | Description [This method is based on traditional dynamic reordering |
---|
10 | technique found in depth-first based packages. The data structure is |
---|
11 | first converted to conform to traditional one and then reordering is |
---|
12 | performed. At the end the nodes are arranged back on the pages. The |
---|
13 | computational overheads are in terms of converting the data |
---|
14 | structure back and forth and the memory overhead due to the extra |
---|
15 | space needed to arrange the nodes. This overhead can be eliminated |
---|
16 | by proper implementation. For details, please refer to the work by |
---|
17 | Rajeev K. Ranjan et al - "Dynamic variable reordering in a |
---|
18 | breadth-first manipulation based package: Challenges and Solutions"- |
---|
19 | Proceedings of ICCD'97.] |
---|
20 | |
---|
21 | SeeAlso [calReorderBF.c calReorderUtil.c] |
---|
22 | |
---|
23 | Author [Rajeev K. Ranjan (rajeev@@ic. eecs.berkeley.edu)] |
---|
24 | |
---|
25 | Copyright [Copyright (c) 1994-1996 The Regents of the Univ. of California. |
---|
26 | All rights reserved. |
---|
27 | |
---|
28 | Permission is hereby granted, without written agreement and without license |
---|
29 | or royalty fees, to use, copy, modify, and distribute this software and its |
---|
30 | documentation for any purpose, provided that the above copyright notice and |
---|
31 | the following two paragraphs appear in all copies of this software. |
---|
32 | |
---|
33 | IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY FOR |
---|
34 | DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES ARISING OUT |
---|
35 | OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF THE UNIVERSITY OF |
---|
36 | CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
---|
37 | |
---|
38 | THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, |
---|
39 | INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
---|
40 | FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS ON AN |
---|
41 | "AS IS" BASIS, AND THE UNIVERSITY OF CALIFORNIA HAS NO OBLIGATION TO PROVIDE |
---|
42 | MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.] |
---|
43 | |
---|
44 | ******************************************************************************/ |
---|
45 | |
---|
46 | #include "calInt.h" |
---|
47 | |
---|
48 | /*---------------------------------------------------------------------------*/ |
---|
49 | /* Constant declarations */ |
---|
50 | /*---------------------------------------------------------------------------*/ |
---|
51 | |
---|
52 | /*---------------------------------------------------------------------------*/ |
---|
53 | /* Type declarations */ |
---|
54 | /*---------------------------------------------------------------------------*/ |
---|
55 | |
---|
56 | /*---------------------------------------------------------------------------*/ |
---|
57 | /* Stucture declarations */ |
---|
58 | /*---------------------------------------------------------------------------*/ |
---|
59 | |
---|
60 | /*---------------------------------------------------------------------------*/ |
---|
61 | /* Variable declarations */ |
---|
62 | /*---------------------------------------------------------------------------*/ |
---|
63 | static CalNodeManager_t *nodeManager; |
---|
64 | static int freeListId; |
---|
65 | |
---|
66 | |
---|
67 | /*---------------------------------------------------------------------------*/ |
---|
68 | /* Macro declarations */ |
---|
69 | /*---------------------------------------------------------------------------*/ |
---|
70 | /* These macros are needed because we are dealing with a new data |
---|
71 | structures of the BDD nodes */ |
---|
72 | |
---|
73 | #define BddNodeIcrRefCount(f) \ |
---|
74 | { \ |
---|
75 | CalBddNode_t *_bddNode = CAL_BDD_POINTER(f); \ |
---|
76 | if (_bddNode->elseBddId < CAL_MAX_REF_COUNT){ \ |
---|
77 | _bddNode->elseBddId++; \ |
---|
78 | } \ |
---|
79 | } |
---|
80 | |
---|
81 | #define BddNodeDcrRefCount(f) \ |
---|
82 | { \ |
---|
83 | CalBddNode_t *_bddNode = CAL_BDD_POINTER(f); \ |
---|
84 | if ((_bddNode->elseBddId < CAL_MAX_REF_COUNT) && (_bddNode->elseBddId)){ \ |
---|
85 | _bddNode->elseBddId--; \ |
---|
86 | } \ |
---|
87 | else if (_bddNode->elseBddId == 0){ \ |
---|
88 | CalBddWarningMessage("Trying to decrement reference count below zero"); \ |
---|
89 | } \ |
---|
90 | } |
---|
91 | |
---|
92 | #define BddGetCofactors(bddManager, f, id, fThen, fElse) \ |
---|
93 | { \ |
---|
94 | CalBddNode_t *_bddNode = CAL_BDD_POINTER(f); \ |
---|
95 | Cal_Assert(bddManager->idToIndex[_bddNode->thenBddId] <= \ |
---|
96 | bddManager->idToIndex[id]); \ |
---|
97 | if (bddManager->idToIndex[_bddNode->thenBddId] == \ |
---|
98 | bddManager->idToIndex[id]){ \ |
---|
99 | fThen = _bddNode->thenBddNode; \ |
---|
100 | fElse = _bddNode->elseBddNode; \ |
---|
101 | } \ |
---|
102 | else{ \ |
---|
103 | fThen = fElse = f; \ |
---|
104 | } \ |
---|
105 | } |
---|
106 | |
---|
107 | #define BddNodeGetThenBddNode(bddNode) \ |
---|
108 | ((CalBddNode_t*) ((CalAddress_t) \ |
---|
109 | (CAL_BDD_POINTER(bddNode)->thenBddNode) \ |
---|
110 | ^ (CAL_TAG0(bddNode)))) |
---|
111 | |
---|
112 | #define BddNodeGetElseBddNode(bddNode) \ |
---|
113 | ((CalBddNode_t*) ((CalAddress_t) \ |
---|
114 | (CAL_BDD_POINTER(bddNode)->elseBddNode) \ |
---|
115 | ^ (CAL_TAG0(bddNode)))) |
---|
116 | |
---|
117 | |
---|
118 | |
---|
119 | /**AutomaticStart*************************************************************/ |
---|
120 | |
---|
121 | /*---------------------------------------------------------------------------*/ |
---|
122 | /* Static function prototypes */ |
---|
123 | /*---------------------------------------------------------------------------*/ |
---|
124 | |
---|
125 | static int UniqueTableForIdFindOrAdd(Cal_BddManager_t * bddManager, CalHashTable_t * hashTable, CalBddNode_t *thenBdd, CalBddNode_t *elseBdd, CalBddNode_t **bddPtr); |
---|
126 | static void HashTableAddDirect(CalHashTable_t * hashTable, CalBddNode_t *bddNode); |
---|
127 | static int HashTableFindOrAdd(Cal_BddManager_t *bddManager, CalHashTable_t *hashTable, CalBddNode_t *thenBdd, CalBddNode_t *elseBdd, CalBddNode_t **bddPtr); |
---|
128 | static void BddConvertDataStruct(Cal_BddManager_t *bddManager); |
---|
129 | static void BddConvertDataStructBack(Cal_BddManager_t *bddManager); |
---|
130 | static void BddReallocateNodes(Cal_BddManager_t *bddManager); |
---|
131 | static void BddExchangeAux(Cal_BddManager_t *bddManager, CalBddNode_t *f, int id, int nextId); |
---|
132 | static int CheckValidityOfNodes(Cal_BddManager_t *bddManager, long id); |
---|
133 | static void SweepVarTable(Cal_BddManager_t *bddManager, long id); |
---|
134 | static void BddExchange(Cal_BddManager_t *bddManager, long id); |
---|
135 | static void BddExchangeVarBlocks(Cal_BddManager_t *bddManager, Cal_Block parent, long blockIndex); |
---|
136 | static int BddReorderWindow2(Cal_BddManager_t *bddManager, Cal_Block block, long i); |
---|
137 | static int BddReorderWindow3(Cal_BddManager_t *bddManager, Cal_Block block, long i); |
---|
138 | static void BddReorderStableWindow3Aux(Cal_BddManager_t *bddManager, Cal_Block block, char *levels); |
---|
139 | static void BddReorderStableWindow3(Cal_BddManager_t *bddManager); |
---|
140 | static void BddSiftBlock(Cal_BddManager_t *bddManager, Cal_Block block, long startPosition, double maxSizeFactor); |
---|
141 | static void BddReorderSiftAux(Cal_BddManager_t *bddManager, Cal_Block block, Cal_Block *toSift, double maxSizeFactor); |
---|
142 | static void BddReorderSift(Cal_BddManager_t *bddManager, double maxSizeFactor); |
---|
143 | static int CeilLog2(int number); |
---|
144 | |
---|
145 | /**AutomaticEnd***************************************************************/ |
---|
146 | |
---|
147 | /*---------------------------------------------------------------------------*/ |
---|
148 | /* Definition of exported functions */ |
---|
149 | /*---------------------------------------------------------------------------*/ |
---|
150 | |
---|
151 | /**Function******************************************************************** |
---|
152 | |
---|
153 | Synopsis [required] |
---|
154 | |
---|
155 | Description [optional] |
---|
156 | |
---|
157 | SideEffects [required] |
---|
158 | |
---|
159 | SeeAlso [optional] |
---|
160 | |
---|
161 | ******************************************************************************/ |
---|
162 | void |
---|
163 | CalBddReorderAuxDF(Cal_BddManager_t *bddManager) |
---|
164 | { |
---|
165 | CalHashTableGC(bddManager, bddManager->uniqueTable[0]); |
---|
166 | /*Cal_BddManagerGC(bddManager);Cal_Assert(CalCheckAllValidity(bddManager));*/ |
---|
167 | /* If we want to check the validity, we need to garbage collect */ |
---|
168 | CalInitInteract(bddManager); /* Initialize the interaction matrix |
---|
169 | before changing the data structure */ |
---|
170 | nodeManager = CalNodeManagerInit(bddManager->pageManager2); |
---|
171 | freeListId = 1; |
---|
172 | #ifdef _CAL_QUANTIFY_ |
---|
173 | quantify_start_recording_data(); |
---|
174 | #endif |
---|
175 | BddConvertDataStruct(bddManager); |
---|
176 | if (bddManager->reorderTechnique == CAL_REORDER_WINDOW){ |
---|
177 | BddReorderStableWindow3(bddManager); |
---|
178 | } |
---|
179 | else { |
---|
180 | BddReorderSift(bddManager, bddManager->maxSiftingGrowth); |
---|
181 | } |
---|
182 | BddReallocateNodes(bddManager); |
---|
183 | BddConvertDataStructBack(bddManager); |
---|
184 | #ifdef _CAL_QUANTIFY_ |
---|
185 | quantify_stop_recording_data(); |
---|
186 | #endif |
---|
187 | nodeManager->numPages = 0; /* Since these pages have already been |
---|
188 | freed */ |
---|
189 | CalNodeManagerQuit(nodeManager); |
---|
190 | Cal_Assert(CalCheckAllValidity(bddManager)); |
---|
191 | Cal_MemFree(bddManager->interact); |
---|
192 | bddManager->numReorderings++; |
---|
193 | } |
---|
194 | |
---|
195 | |
---|
196 | /*---------------------------------------------------------------------------*/ |
---|
197 | /* Definition of internal functions */ |
---|
198 | /*---------------------------------------------------------------------------*/ |
---|
199 | /*---------------------------------------------------------------------------*/ |
---|
200 | /* Definition of static functions */ |
---|
201 | /*---------------------------------------------------------------------------*/ |
---|
202 | static void |
---|
203 | NodeManagerAllocNode(Cal_BddManager_t *bddManager, CalBddNode_t **nodePtr) |
---|
204 | { |
---|
205 | /* First check the free list of bddManager */ |
---|
206 | if (nodeManager->freeNodeList){ |
---|
207 | *nodePtr = nodeManager->freeNodeList; |
---|
208 | nodeManager->freeNodeList = |
---|
209 | ((CalBddNode_t *)(*nodePtr))->nextBddNode; |
---|
210 | } |
---|
211 | else{ |
---|
212 | if (freeListId < bddManager->numVars){ |
---|
213 | /* Find the next id with free list */ |
---|
214 | for (; freeListId <= bddManager->numVars; freeListId++){ |
---|
215 | CalNodeManager_t *nodeManagerForId = |
---|
216 | bddManager->nodeManagerArray[freeListId]; |
---|
217 | if (nodeManagerForId->freeNodeList){ |
---|
218 | *nodePtr = nodeManagerForId->freeNodeList; |
---|
219 | nodeManagerForId->freeNodeList = (CalBddNode_t *)0; |
---|
220 | nodeManager->freeNodeList = |
---|
221 | ((CalBddNode_t *)(*nodePtr))->nextBddNode; |
---|
222 | break; |
---|
223 | } |
---|
224 | } |
---|
225 | } |
---|
226 | } |
---|
227 | if (!(*nodePtr)){ |
---|
228 | /* Create a new page */ |
---|
229 | CalBddNode_t *_freeNodeList, *_nextNode, *_node; |
---|
230 | _freeNodeList = |
---|
231 | (CalBddNode_t *)CalPageManagerAllocPage(nodeManager->pageManager); |
---|
232 | for(_node = _freeNodeList + NUM_NODES_PER_PAGE - 1, _nextNode =0; |
---|
233 | _node != _freeNodeList; _nextNode = _node--){ |
---|
234 | _node->nextBddNode = _nextNode; |
---|
235 | } |
---|
236 | nodeManager->freeNodeList = _freeNodeList + 1; |
---|
237 | *nodePtr = _node; |
---|
238 | if (nodeManager->numPages == nodeManager->maxNumPages){ |
---|
239 | nodeManager->maxNumPages *= 2; |
---|
240 | nodeManager->pageList = |
---|
241 | Cal_MemRealloc(CalAddress_t *, nodeManager->pageList, |
---|
242 | nodeManager->maxNumPages); |
---|
243 | } |
---|
244 | nodeManager->pageList[nodeManager->numPages++] = |
---|
245 | (CalAddress_t *)_freeNodeList; |
---|
246 | } |
---|
247 | } |
---|
248 | |
---|
249 | /**Function******************************************************************** |
---|
250 | |
---|
251 | Synopsis [find or add in the unique table for id.] |
---|
252 | |
---|
253 | Description [optional] |
---|
254 | |
---|
255 | SideEffects [If a new BDD node is created (found == false), then the |
---|
256 | numNodes field of the manager needs to be incremented.] |
---|
257 | |
---|
258 | SeeAlso [optional] |
---|
259 | |
---|
260 | ******************************************************************************/ |
---|
261 | static int |
---|
262 | UniqueTableForIdFindOrAdd(Cal_BddManager_t * bddManager, |
---|
263 | CalHashTable_t * hashTable, |
---|
264 | CalBddNode_t *thenBdd, |
---|
265 | CalBddNode_t *elseBdd, |
---|
266 | CalBddNode_t **bddPtr) |
---|
267 | { |
---|
268 | int found = 0; |
---|
269 | if (thenBdd == elseBdd){ |
---|
270 | *bddPtr = thenBdd; |
---|
271 | found = 1; |
---|
272 | } |
---|
273 | else if(CalBddNodeIsOutPos(thenBdd)){ |
---|
274 | found = HashTableFindOrAdd(bddManager, hashTable, thenBdd, elseBdd, bddPtr); |
---|
275 | } |
---|
276 | else{ |
---|
277 | found = HashTableFindOrAdd(bddManager, hashTable, |
---|
278 | CalBddNodeNot(thenBdd), |
---|
279 | CalBddNodeNot(elseBdd), bddPtr); |
---|
280 | *bddPtr = CalBddNodeNot(*bddPtr); |
---|
281 | } |
---|
282 | if (!found) bddManager->numNodes++; |
---|
283 | return found; |
---|
284 | } |
---|
285 | |
---|
286 | /**Function******************************************************************** |
---|
287 | |
---|
288 | Synopsis [Directly insert a BDD node in the hash table.] |
---|
289 | |
---|
290 | Description [optional] |
---|
291 | |
---|
292 | SideEffects [required] |
---|
293 | |
---|
294 | SeeAlso [optional] |
---|
295 | |
---|
296 | ******************************************************************************/ |
---|
297 | static void |
---|
298 | HashTableAddDirect(CalHashTable_t * hashTable, CalBddNode_t *bddNode) |
---|
299 | { |
---|
300 | int hashValue; |
---|
301 | CalBddNode_t *thenBddNode, *elseBddNode; |
---|
302 | |
---|
303 | hashTable->numEntries++; |
---|
304 | if(hashTable->numEntries >= hashTable->maxCapacity){ |
---|
305 | CalHashTableRehash(hashTable, 1); |
---|
306 | } |
---|
307 | thenBddNode = bddNode->thenBddNode; |
---|
308 | Cal_Assert(CalBddNodeIsOutPos(thenBddNode)); |
---|
309 | elseBddNode = bddNode->elseBddNode; |
---|
310 | hashValue = CalDoHash2(thenBddNode, elseBddNode, hashTable); |
---|
311 | bddNode->nextBddNode = hashTable->bins[hashValue]; |
---|
312 | hashTable->bins[hashValue] = bddNode; |
---|
313 | } |
---|
314 | |
---|
315 | |
---|
316 | /**Function******************************************************************** |
---|
317 | |
---|
318 | Synopsis [required] |
---|
319 | |
---|
320 | Description [optional] |
---|
321 | |
---|
322 | SideEffects [required] |
---|
323 | |
---|
324 | SeeAlso [optional] |
---|
325 | |
---|
326 | ******************************************************************************/ |
---|
327 | static int |
---|
328 | HashTableFindOrAdd(Cal_BddManager_t *bddManager, CalHashTable_t |
---|
329 | *hashTable, CalBddNode_t *thenBdd, |
---|
330 | CalBddNode_t *elseBdd, CalBddNode_t **bddPtr) |
---|
331 | { |
---|
332 | CalBddNode_t *ptr; |
---|
333 | int hashValue; |
---|
334 | |
---|
335 | Cal_Assert(CalBddNodeIsOutPos(thenBdd)); |
---|
336 | hashValue = CalDoHash2(thenBdd, elseBdd, hashTable); |
---|
337 | for (ptr = hashTable->bins[hashValue]; ptr; ptr = ptr->nextBddNode){ |
---|
338 | if ((ptr->thenBddNode == thenBdd) && |
---|
339 | (ptr->elseBddNode == elseBdd)){ |
---|
340 | *bddPtr = ptr; |
---|
341 | return 1; |
---|
342 | } |
---|
343 | } |
---|
344 | hashTable->numEntries++; |
---|
345 | if(hashTable->numEntries > hashTable->maxCapacity){ |
---|
346 | CalHashTableRehash(hashTable,1); |
---|
347 | hashValue = CalDoHash2(thenBdd, elseBdd, hashTable); |
---|
348 | } |
---|
349 | |
---|
350 | NodeManagerAllocNode(bddManager, &ptr); |
---|
351 | |
---|
352 | ptr->thenBddNode = thenBdd; |
---|
353 | ptr->elseBddNode = elseBdd; |
---|
354 | ptr->nextBddNode = hashTable->bins[hashValue]; |
---|
355 | ptr->thenBddId = hashTable->bddId; |
---|
356 | ptr->elseBddId = 0; |
---|
357 | hashTable->bins[hashValue] = ptr; |
---|
358 | *bddPtr = ptr; |
---|
359 | return 0; |
---|
360 | } |
---|
361 | |
---|
362 | |
---|
363 | /**Function******************************************************************** |
---|
364 | |
---|
365 | Synopsis [Changes the data structure of the bdd nodes.] |
---|
366 | |
---|
367 | Description [New data structure: thenBddId -> id |
---|
368 | elseBddId -> ref count] |
---|
369 | |
---|
370 | SideEffects [required] |
---|
371 | |
---|
372 | SeeAlso [optional] |
---|
373 | |
---|
374 | ******************************************************************************/ |
---|
375 | static void |
---|
376 | BddConvertDataStruct(Cal_BddManager_t *bddManager) |
---|
377 | { |
---|
378 | CalBddNode_t *bddNode, *thenBddNode, *elseBddNode, |
---|
379 | *next = Cal_Nil(CalBddNode_t); |
---|
380 | CalBddNode_t *last; |
---|
381 | long numBins; |
---|
382 | int i, refCount, id, index; |
---|
383 | long oldNumEntries; |
---|
384 | CalHashTable_t *uniqueTableForId; |
---|
385 | |
---|
386 | if (bddManager->numPeakNodes < bddManager->numNodes){ |
---|
387 | bddManager->numPeakNodes = bddManager->numNodes; |
---|
388 | } |
---|
389 | |
---|
390 | for(index = 0; index < bddManager->numVars; index++){ |
---|
391 | id = bddManager->indexToId[index]; |
---|
392 | uniqueTableForId = bddManager->uniqueTable[id]; |
---|
393 | oldNumEntries = uniqueTableForId->numEntries; |
---|
394 | numBins = uniqueTableForId->numBins; |
---|
395 | for(i = 0; i < numBins; i++){ |
---|
396 | last = NULL; |
---|
397 | bddNode = uniqueTableForId->bins[i]; |
---|
398 | while(bddNode != Cal_Nil(CalBddNode_t)){ |
---|
399 | next = CalBddNodeGetNextBddNode(bddNode); |
---|
400 | CalBddNodeGetRefCount(bddNode, refCount); |
---|
401 | thenBddNode = CalBddNodeGetThenBddNode(bddNode); |
---|
402 | elseBddNode = CalBddNodeGetElseBddNode(bddNode); |
---|
403 | if(refCount == 0){ |
---|
404 | if (last == NULL){ |
---|
405 | uniqueTableForId->bins[i] = next; |
---|
406 | } |
---|
407 | else{ |
---|
408 | last->nextBddNode = next; |
---|
409 | } |
---|
410 | CalBddNodeDcrRefCount(CAL_BDD_POINTER(thenBddNode)); |
---|
411 | CalBddNodeDcrRefCount(CAL_BDD_POINTER(elseBddNode)); |
---|
412 | CalNodeManagerFreeNode(nodeManager, bddNode); |
---|
413 | uniqueTableForId->numEntries--; |
---|
414 | } |
---|
415 | else { |
---|
416 | bddNode->thenBddId = id; |
---|
417 | bddNode->elseBddId = refCount; |
---|
418 | bddNode->nextBddNode = next; |
---|
419 | bddNode->thenBddNode = thenBddNode; |
---|
420 | bddNode->elseBddNode = elseBddNode; |
---|
421 | last = bddNode; |
---|
422 | } |
---|
423 | bddNode = next; |
---|
424 | } |
---|
425 | } |
---|
426 | if ((uniqueTableForId->numBins > uniqueTableForId->numEntries) && |
---|
427 | (uniqueTableForId->sizeIndex > HASH_TABLE_DEFAULT_SIZE_INDEX)){ |
---|
428 | CalHashTableRehash(uniqueTableForId, 0); |
---|
429 | } |
---|
430 | bddManager->numNodes -= oldNumEntries - uniqueTableForId->numEntries; |
---|
431 | bddManager->numNodesFreed += oldNumEntries - uniqueTableForId->numEntries; |
---|
432 | } |
---|
433 | id = 0; |
---|
434 | uniqueTableForId = bddManager->uniqueTable[id]; |
---|
435 | numBins = uniqueTableForId->numBins; |
---|
436 | for(i = 0; i < numBins; i++){ |
---|
437 | bddNode = uniqueTableForId->bins[i]; |
---|
438 | while(bddNode != Cal_Nil(CalBddNode_t)){ |
---|
439 | next = CalBddNodeGetNextBddNode(bddNode); |
---|
440 | CalBddNodeGetRefCount(bddNode, refCount); |
---|
441 | Cal_Assert(refCount); |
---|
442 | thenBddNode = CalBddNodeGetThenBddNode(bddNode); |
---|
443 | elseBddNode = CalBddNodeGetElseBddNode(bddNode); |
---|
444 | bddNode->thenBddId = id; |
---|
445 | bddNode->elseBddId = refCount; |
---|
446 | bddNode->nextBddNode = next; |
---|
447 | bddNode->thenBddNode = thenBddNode; |
---|
448 | bddNode->elseBddNode = elseBddNode; |
---|
449 | bddNode = next; |
---|
450 | } |
---|
451 | } |
---|
452 | bddNode = bddManager->bddOne.bddNode; |
---|
453 | CalBddNodeGetRefCount(bddNode, refCount); |
---|
454 | Cal_Assert(refCount); |
---|
455 | thenBddNode = CalBddNodeGetThenBddNode(bddNode); |
---|
456 | elseBddNode = CalBddNodeGetElseBddNode(bddNode); |
---|
457 | bddNode->thenBddId = id; |
---|
458 | bddNode->elseBddId = refCount; |
---|
459 | bddNode->nextBddNode = next; |
---|
460 | bddNode->thenBddNode = thenBddNode; |
---|
461 | bddNode->elseBddNode = elseBddNode; |
---|
462 | } |
---|
463 | |
---|
464 | |
---|
465 | /**Function******************************************************************** |
---|
466 | |
---|
467 | Synopsis [Changes the data structure of the bdd nodes to |
---|
468 | the original one.] |
---|
469 | |
---|
470 | Description [Data structure conversion: thenBddId -> id |
---|
471 | elseBddId -> ref count] |
---|
472 | SideEffects [required] |
---|
473 | |
---|
474 | SeeAlso [optional] |
---|
475 | |
---|
476 | ******************************************************************************/ |
---|
477 | static void |
---|
478 | BddConvertDataStructBack(Cal_BddManager_t *bddManager) |
---|
479 | { |
---|
480 | Cal_Bdd_t thenBdd, elseBdd; |
---|
481 | |
---|
482 | CalBddNode_t *bddNode, *nextBddNode, **bins; |
---|
483 | long numBins; |
---|
484 | int i, id, index; |
---|
485 | CalHashTable_t *uniqueTableForId; |
---|
486 | uniqueTableForId = bddManager->uniqueTable[0]; |
---|
487 | numBins = uniqueTableForId->numBins; |
---|
488 | bins = uniqueTableForId->bins; |
---|
489 | for(i = 0; i < numBins; i++) { |
---|
490 | for(bddNode = bins[i]; |
---|
491 | bddNode != Cal_Nil(CalBddNode_t); |
---|
492 | bddNode = nextBddNode) { |
---|
493 | nextBddNode = CalBddNodeGetNextBddNode(bddNode); |
---|
494 | CalBddNodePutRefCount(bddNode, bddNode->elseBddId); |
---|
495 | bddNode->thenBddId = CAL_BDD_POINTER(bddNode->thenBddNode)->thenBddId; |
---|
496 | bddNode->elseBddId = CAL_BDD_POINTER(bddNode->elseBddNode)->thenBddId; |
---|
497 | } |
---|
498 | } |
---|
499 | for(index = 0; index < bddManager->numVars; index++){ |
---|
500 | id = bddManager->indexToId[index]; |
---|
501 | uniqueTableForId = bddManager->uniqueTable[id]; |
---|
502 | numBins = uniqueTableForId->numBins; |
---|
503 | bins = uniqueTableForId->bins; |
---|
504 | for(i = 0; i < numBins; i++) { |
---|
505 | for(bddNode = bins[i]; |
---|
506 | bddNode != Cal_Nil(CalBddNode_t); |
---|
507 | bddNode = nextBddNode) { |
---|
508 | nextBddNode = CalBddNodeGetNextBddNode(bddNode); |
---|
509 | CalBddNodePutRefCount(bddNode, bddNode->elseBddId); |
---|
510 | bddNode->thenBddId = CAL_BDD_POINTER(bddNode->thenBddNode)->thenBddId; |
---|
511 | bddNode->elseBddId = CAL_BDD_POINTER(bddNode->elseBddNode)->thenBddId; |
---|
512 | Cal_Assert(!CalBddNodeIsForwarded(bddNode)); |
---|
513 | Cal_Assert(!CalBddNodeIsRefCountZero(bddNode)); |
---|
514 | CalBddNodeGetThenBdd(bddNode, thenBdd); |
---|
515 | CalBddNodeGetElseBdd(bddNode, elseBdd); |
---|
516 | Cal_Assert(CalBddIsForwarded(thenBdd) == 0); |
---|
517 | Cal_Assert(CalBddIsForwarded(elseBdd) == 0); |
---|
518 | } |
---|
519 | } |
---|
520 | } |
---|
521 | bddNode = bddManager->bddOne.bddNode; |
---|
522 | CalBddNodePutRefCount(bddNode, bddNode->elseBddId); |
---|
523 | bddNode->thenBddId = 0; |
---|
524 | bddNode->elseBddId = 0; |
---|
525 | } |
---|
526 | |
---|
527 | #ifdef _FOO_ |
---|
528 | /**Function******************************************************************** |
---|
529 | |
---|
530 | Synopsis [required] |
---|
531 | |
---|
532 | Description [optional] |
---|
533 | |
---|
534 | SideEffects [required] |
---|
535 | |
---|
536 | SeeAlso [optional] |
---|
537 | |
---|
538 | ******************************************************************************/ |
---|
539 | static void |
---|
540 | BddReallocateNodesInPlace(Cal_BddManager_t *bddManager) |
---|
541 | { |
---|
542 | Cal_Address_t *pageSegment; |
---|
543 | CalPageManager_t *pageManager; |
---|
544 | CalHashTable_t *uniqueTable; |
---|
545 | CalNodeManager_t *nodeManager; |
---|
546 | int index, id, i, pageCounter, numUsefulSegments, segmentCounter; |
---|
547 | |
---|
548 | /* Initialize and set up few things */ |
---|
549 | pageManager = bddManager->pageManager; |
---|
550 | uniqueTable = bddManager->uniqueTable; |
---|
551 | for (id = 1; id <= bddManager->numVars; id++){ |
---|
552 | numPagesRequired = |
---|
553 | uniqueTable[id]->numEntries/NUM_NODES_PER_PAGE+1; |
---|
554 | nodeManager = uniqueTable[id]->nodeManager; |
---|
555 | /* Clear out the page list of the node manager */ |
---|
556 | for (i=0; i<nodeManager->maxNumPages; i++){ |
---|
557 | nodeManager->pageList[i] = 0; |
---|
558 | } |
---|
559 | nodeManager->freeNodeList = (CalBddNode_t *)0; |
---|
560 | nodeManager->numPages = numPagesRequired; |
---|
561 | Cal_Assert(nodeManager->maxNumPages >= numPagesRequired); |
---|
562 | for (i = 0; i<numPagesRequired; i++){ |
---|
563 | if (++pageCounter == |
---|
564 | pageManager->numPagesArray[segmentCounter]){ |
---|
565 | pageCounter = 0; |
---|
566 | segmentCounter++; |
---|
567 | pageSegment = pageManager->pageSegmentArray[segmentCounter]; |
---|
568 | } |
---|
569 | nodeManager->pageList[i] = pageSegment[pageCounter]; |
---|
570 | } |
---|
571 | } |
---|
572 | numUsefulSegments = segmentCounter+1; |
---|
573 | numUsefulPagesInLastSegment = pageCounter+1; |
---|
574 | |
---|
575 | /* Traverse all the nodes belonging in each page */ |
---|
576 | /* Put the destination addresses in the next pointer */ |
---|
577 | for (numSegment=0; numSegment < pageManager->numSegments; |
---|
578 | numSegment++){ |
---|
579 | for (numPage = 0, page = pageManager->pageSegmentArray[numSegment]; |
---|
580 | numPage < pageManager->numPagesArray[numSegment]; |
---|
581 | page += PAGE_SIZE, numPage++){ |
---|
582 | for (bddNode = (CalBddNode_t*) page, numNode = 0; |
---|
583 | numNode < NUM_NODES_PER_PAGE; numNode++, bddNode += 1){ |
---|
584 | /* If the node is not useful, continue */ |
---|
585 | if (bddNode->elseBddId == 0) continue; |
---|
586 | /* Find out the destination address */ |
---|
587 | bddId = bddNode->thenBddId; |
---|
588 | nodeCounter[bddId]++; |
---|
589 | if (nodeCounter[bddId] == NUM_NODES_PER_PAGE){ |
---|
590 | pageCounter[bddId]++; |
---|
591 | nodePointerArray[bddId] = |
---|
592 | pageListArray[bddId][pageCounter[bddId]]; |
---|
593 | nodeCounter[bddId] = 0; |
---|
594 | } |
---|
595 | bddNode->nextBddNode = nodePointerArray[bddId]; |
---|
596 | nodePointerArray[bddId] += 1; |
---|
597 | } |
---|
598 | } |
---|
599 | } |
---|
600 | /* Traverse all the nodes belonging in each page */ |
---|
601 | /* Update the contents */ |
---|
602 | for (numSegment=0; numSegment < pageManager->totalNumSegments; |
---|
603 | numSegment++){ |
---|
604 | for (numPage = 0, page = pageManager->pageSegmentArray[numSegment]; |
---|
605 | numPage < pageManager->numPagesArray[numSegment]; |
---|
606 | page += PAGE_SIZE, numPage++){ |
---|
607 | for (bddNode = (CalBddNode_t*) page, numNode = 0; |
---|
608 | numNode < NUM_NODES_PER_PAGE; numNode++, bddNode += 1){ |
---|
609 | /* If the node is not useful, continue */ |
---|
610 | if (bddNode->elseBddId == 0) continue; |
---|
611 | /* If the node has been visited, continue */ |
---|
612 | if ((CalAddress_t)bddNode->nextBddNode & 01) continue; |
---|
613 | /* If the nodes is supposed to remain at the same place, |
---|
614 | update the then and else pointers and continue */ |
---|
615 | if (((CalAddress_t) bddNode->nextBddNode &~01) == |
---|
616 | ((CalAddress_t) bddNode & ~01)){ |
---|
617 | CalBddNodeUpdatebddNode(bddNode); |
---|
618 | continue; |
---|
619 | } |
---|
620 | origNode = bddNode; /* Remember the address */ |
---|
621 | /* Update the contents */ |
---|
622 | thenBddNode = bddNode->thenBddNode; |
---|
623 | elseBddNode = bddNode->elseBddNode; |
---|
624 | thenBddId = bddNode->thenBddId; |
---|
625 | elseBddId = bddNode->elseBddId; |
---|
626 | do{ |
---|
627 | thenBddNode = UpdateThenBddNode(thenBddNode); |
---|
628 | elseBddNode = UpdateElseBddNode(elseBddNode); |
---|
629 | destinationNode = bddNode->nextBddNode; |
---|
630 | /* Mark the node visited */ |
---|
631 | bddNode->nextBddNode = (CalBddNode_t *) |
---|
632 | ((CalAddress_t)bddNode->nextBddNode | 01); |
---|
633 | thenBddNode2 = destinationNode->thenBddNode; |
---|
634 | elseBddNode2 = destinationNode->elseBddNode; |
---|
635 | thenBddId2 = destinationNode->thenBddId; |
---|
636 | elseBddId2 = destinationNode->elseBddId; |
---|
637 | destinationNode->thenBddNode = thenBddNode; |
---|
638 | destinationNode->elseBddNode = elseBddNode; |
---|
639 | destinationNode->thenBddId = thenBddId; |
---|
640 | destinationNode->elseBddId = elseBddId; |
---|
641 | bddNode = destinationNode; |
---|
642 | thenBddNode = thenBddNode2; |
---|
643 | elseBddNode = elseBddNode2; |
---|
644 | thenBddId = thenBddId2; |
---|
645 | elseBddId = elseBddId2; |
---|
646 | } while ((elseBddId != 0) && (bddNode != origNode) && |
---|
647 | !((CalAddress_t)(bddNode->nextBddNode) & 01)); |
---|
648 | } |
---|
649 | } |
---|
650 | } |
---|
651 | /* Fix the handles to the nodes being moved */ |
---|
652 | for (id = 1; id <= bddManager->numVars; id++){ |
---|
653 | /* Fix the varBdd array */ |
---|
654 | } |
---|
655 | /* Need to update the handles to the nodes being moved */ |
---|
656 | if (bddManager->pipelineState == CREATE){ |
---|
657 | /* There are some results computed in pipeline */ |
---|
658 | CalBddReorderFixProvisionalNodesAfterReallocation(bddManager); |
---|
659 | } |
---|
660 | |
---|
661 | /* Fix the user BDDs */ |
---|
662 | CalBddReorderFixUserBddPtrsAfterReallocation(bddManager); |
---|
663 | |
---|
664 | /* Fix the association */ |
---|
665 | CalReorderAssociationFixAfterReallocation(bddManager); |
---|
666 | |
---|
667 | Cal_Assert(CalCheckAssoc(bddManager)); |
---|
668 | |
---|
669 | |
---|
670 | /* Update the next pointers */ |
---|
671 | /* Since the pages for the ids are distributed in the uniform |
---|
672 | manner, we can scan the pages on id by id basis without any |
---|
673 | disadvantage */ |
---|
674 | for (id = 1; id <= bddManager->numVars; id++){ |
---|
675 | nodeManager = uniqueTable[id]->nodeManager; |
---|
676 | freeNodeList = Cal_Nil(CalBddNode_t); |
---|
677 | for (i=0; i<nodeManager->numPages; i++){ |
---|
678 | page = nodeManager->pageList[i]; |
---|
679 | for (bddNode = (CalBddNode_t*) page, numNode = 0; |
---|
680 | numNode < NUM_NODES_PER_PAGE; numNode++, bddNode += 1){ |
---|
681 | /* If the node is not useful, put it in the free list */ |
---|
682 | if ((bddNode->elseBddId == 0) || (bddNode->elseBddNode == 0)){ |
---|
683 | bddNode->nextBddNode = freeNodeList; |
---|
684 | freeNodeList = bddNode; |
---|
685 | } |
---|
686 | } |
---|
687 | } |
---|
688 | nodeManager->freeNodeList = freeNodeList; |
---|
689 | } |
---|
690 | /* We should put the unused pages in the free page list */ |
---|
691 | pageSegment = pageManager->pageSegmentArray[numUsefulSegments-1]; |
---|
692 | for (pageCounter = numUsefulPagesInLastSegment; |
---|
693 | pageCounter < pageSegment->numPages ; pageCounter++){ |
---|
694 | CalPageManagerFreePage(pageManager, pageSegment[pageCounter]); |
---|
695 | } |
---|
696 | /* We have to free up the unnecessary page segments;*/ |
---|
697 | for (i = numUsefulSegments; i < pageManager->numSegments; i++){ |
---|
698 | free(pageManager->pageSegmentArray[i]); |
---|
699 | pageManager->pageSegmentArray[i] = 0; |
---|
700 | } |
---|
701 | pageManager->numSegments = numUsefulSegments; |
---|
702 | } |
---|
703 | /**Function******************************************************************** |
---|
704 | |
---|
705 | Synopsis [required] |
---|
706 | |
---|
707 | Description [optional] |
---|
708 | |
---|
709 | SideEffects [required] |
---|
710 | |
---|
711 | SeeAlso [optional] |
---|
712 | |
---|
713 | ******************************************************************************/ |
---|
714 | void |
---|
715 | CalAlignCollisionChains(Cal_BddManager_t *bddManager) |
---|
716 | { |
---|
717 | /* First find out the pages corresponding to each variable */ |
---|
718 | Cal_Address_t ***pageListArray = Cal_MemAlloc(Cal_Address_t **, |
---|
719 | bddManager->numVars+1); |
---|
720 | for (id = 1; id <= bddManager->numVars; id++){ |
---|
721 | nodeManager = bddManager->nodeManagerArray[id]; |
---|
722 | numPages = nodeManager->numPages; |
---|
723 | pageListArray[id] = Cal_MemAlloc(Cal_Address_t *, numPages); |
---|
724 | for (i=0; i<numPages; i++){ |
---|
725 | pageListArray[id][i] = nodeManager->pageList[i]; |
---|
726 | } |
---|
727 | } |
---|
728 | |
---|
729 | /* Bottom up traversal */ |
---|
730 | for (index = bddManager->numVars-1; index >= 0; index--){ |
---|
731 | id = bddManager->indexToId[index]; |
---|
732 | uniqueTableForId = bddManager->uniqueTable[id]; |
---|
733 | nodeManager = uniqueTableForId->nodeManager; |
---|
734 | /* Calculate the collision lengths */ |
---|
735 | collisionLengthArray = CalculateCollisionLength(uniqueTableForId); |
---|
736 | /* Initialize the bins */ |
---|
737 | bins = uniqueTableForId->bins; |
---|
738 | numBins = uniqueTableForId->numBins; |
---|
739 | numNodes = 0; |
---|
740 | pageNum = 0; |
---|
741 | for (i=0; i<numBins; i++){ |
---|
742 | numNodes += collisionLengthArray[i]; |
---|
743 | if (numNodes < NUM_NODES_PER_PAGE){ |
---|
744 | nodePointer[i] += collisionLengthArray[i]; |
---|
745 | } |
---|
746 | else if (numNodes == NUM_NODES_PER_PAGE){ |
---|
747 | nodePointer[i] = pageListArray[id][++pageNum]; |
---|
748 | numNodes = 0; |
---|
749 | } |
---|
750 | else { |
---|
751 | /* put the rest of the nodes from this page in a free list */ |
---|
752 | nodePointer[i]->nextBddNode = nodeManager->freeNodeList; |
---|
753 | nodeManager->freeNodeList = nodePointer; |
---|
754 | nodePointer[i] = pageListArray[id][++pageNum]+collisionLengthArray[i]; |
---|
755 | numNodes = collisionLengthArray[i]; |
---|
756 | } |
---|
757 | } |
---|
758 | } |
---|
759 | } |
---|
760 | #endif |
---|
761 | |
---|
762 | /**Function******************************************************************** |
---|
763 | |
---|
764 | Synopsis [required] |
---|
765 | |
---|
766 | Description [optional] |
---|
767 | |
---|
768 | SideEffects [required] |
---|
769 | |
---|
770 | SeeAlso [optional] |
---|
771 | |
---|
772 | ******************************************************************************/ |
---|
773 | static void |
---|
774 | BddReallocateNodes(Cal_BddManager_t *bddManager) |
---|
775 | { |
---|
776 | int i; |
---|
777 | int index; |
---|
778 | CalNodeManager_t *nodeManager; |
---|
779 | CalPageManager_t *pageManager; |
---|
780 | int numSegments; |
---|
781 | CalAddress_t **pageSegmentArray; |
---|
782 | |
---|
783 | pageManager = bddManager->pageManager2; |
---|
784 | numSegments = pageManager->numSegments; |
---|
785 | pageSegmentArray = pageManager->pageSegmentArray; |
---|
786 | |
---|
787 | /* Reinitialize the page manager */ |
---|
788 | pageManager->totalNumPages = 0; |
---|
789 | pageManager->numSegments = 0; |
---|
790 | pageManager->maxNumSegments = MAX_NUM_SEGMENTS; |
---|
791 | pageManager->pageSegmentArray |
---|
792 | = Cal_MemAlloc(CalAddress_t *, pageManager->maxNumSegments); |
---|
793 | pageManager->freePageList = Cal_Nil(CalAddress_t); |
---|
794 | |
---|
795 | /* Do a bottom up traversal */ |
---|
796 | |
---|
797 | for (index = bddManager->numVars-1; index >= 0; index--){ |
---|
798 | int id; |
---|
799 | CalHashTable_t *uniqueTableForId; |
---|
800 | int numPagesRequired, newSizeIndex; |
---|
801 | CalBddNode_t *bddNode, *dupNode, *thenNode, *elseNode, **oldBins; |
---|
802 | long hashValue, oldNumBins; |
---|
803 | |
---|
804 | id = bddManager->indexToId[index]; |
---|
805 | uniqueTableForId = bddManager->uniqueTable[id]; |
---|
806 | nodeManager = bddManager->nodeManagerArray[id]; |
---|
807 | oldBins = uniqueTableForId->bins; |
---|
808 | oldNumBins = uniqueTableForId->numBins; |
---|
809 | nodeManager->freeNodeList = Cal_Nil(CalBddNode_t); |
---|
810 | nodeManager->numPages = 0; |
---|
811 | numPagesRequired = |
---|
812 | uniqueTableForId->numEntries/NUM_NODES_PER_PAGE; |
---|
813 | nodeManager->maxNumPages = |
---|
814 | 2*(numPagesRequired ? numPagesRequired : 1); |
---|
815 | Cal_MemFree(nodeManager->pageList); |
---|
816 | nodeManager->pageList = Cal_MemAlloc(CalAddress_t *, |
---|
817 | nodeManager->maxNumPages); |
---|
818 | /* Create the new set of bins */ |
---|
819 | newSizeIndex = |
---|
820 | CeilLog2(uniqueTableForId->numEntries/HASH_TABLE_DEFAULT_MAX_DENSITY); |
---|
821 | if (newSizeIndex < HASH_TABLE_DEFAULT_SIZE_INDEX){ |
---|
822 | newSizeIndex = HASH_TABLE_DEFAULT_SIZE_INDEX; |
---|
823 | } |
---|
824 | uniqueTableForId->sizeIndex = newSizeIndex; |
---|
825 | uniqueTableForId->numBins = TABLE_SIZE(uniqueTableForId->sizeIndex); |
---|
826 | uniqueTableForId->maxCapacity = |
---|
827 | uniqueTableForId->numBins * HASH_TABLE_DEFAULT_MAX_DENSITY; |
---|
828 | |
---|
829 | uniqueTableForId->bins = Cal_MemAlloc(CalBddNode_t *, |
---|
830 | uniqueTableForId->numBins); |
---|
831 | memset((char *)uniqueTableForId->bins, 0, |
---|
832 | uniqueTableForId->numBins*sizeof(CalBddNode_t *)); |
---|
833 | for (i=0; i<oldNumBins; i++){ |
---|
834 | for (bddNode = oldBins[i]; bddNode; bddNode = bddNode->nextBddNode){ |
---|
835 | CalNodeManagerAllocNode(nodeManager, dupNode); |
---|
836 | thenNode = bddNode->thenBddNode; |
---|
837 | CalBddNodeIsForwardedTo(thenNode); |
---|
838 | Cal_Assert(thenNode); |
---|
839 | Cal_Assert(!CalBddNodeIsForwarded(thenNode)); |
---|
840 | elseNode = bddNode->elseBddNode; |
---|
841 | CalBddNodeIsForwardedTo(elseNode); |
---|
842 | Cal_Assert(elseNode); |
---|
843 | Cal_Assert(!CalBddNodeIsForwarded(CAL_BDD_POINTER(elseNode))); |
---|
844 | Cal_Assert(bddManager->idToIndex[bddNode->thenBddId] < |
---|
845 | bddManager->idToIndex[thenNode->thenBddId]); |
---|
846 | Cal_Assert(bddManager->idToIndex[bddNode->thenBddId] < |
---|
847 | bddManager->idToIndex[CAL_BDD_POINTER(elseNode)->thenBddId]); |
---|
848 | dupNode->thenBddNode = thenNode; |
---|
849 | dupNode->elseBddNode = elseNode; |
---|
850 | dupNode->thenBddId = bddNode->thenBddId; |
---|
851 | dupNode->elseBddId = bddNode->elseBddId; |
---|
852 | hashValue = CalDoHash2(thenNode, elseNode, uniqueTableForId); |
---|
853 | dupNode->nextBddNode = uniqueTableForId->bins[hashValue]; |
---|
854 | uniqueTableForId->bins[hashValue] = dupNode; |
---|
855 | bddNode->thenBddNode = dupNode; |
---|
856 | bddNode->elseBddNode = (CalBddNode_t *)0; |
---|
857 | bddNode->thenBddId = id; |
---|
858 | Cal_Assert(bddManager->idToIndex[dupNode->thenBddId] < |
---|
859 | bddManager->idToIndex[thenNode->thenBddId]); |
---|
860 | Cal_Assert(bddManager->idToIndex[dupNode->thenBddId] < |
---|
861 | bddManager->idToIndex[CAL_BDD_POINTER(elseNode)->thenBddId]); |
---|
862 | } |
---|
863 | } |
---|
864 | Cal_MemFree(oldBins); |
---|
865 | CalBddIsForwardedTo(bddManager->varBdds[id]); |
---|
866 | } |
---|
867 | |
---|
868 | if (bddManager->pipelineState == CREATE){ |
---|
869 | /* There are some results computed in pipeline */ |
---|
870 | CalBddReorderFixProvisionalNodes(bddManager); |
---|
871 | } |
---|
872 | |
---|
873 | /* Fix the user BDDs */ |
---|
874 | CalBddReorderFixUserBddPtrs(bddManager); |
---|
875 | |
---|
876 | /* Fix the association */ |
---|
877 | CalReorderAssociationFix(bddManager); |
---|
878 | |
---|
879 | Cal_Assert(CalCheckAssoc(bddManager)); |
---|
880 | |
---|
881 | /* Free the page manager related stuff*/ |
---|
882 | for(i = 0; i < numSegments; i++){ |
---|
883 | free(pageSegmentArray[i]); |
---|
884 | } |
---|
885 | Cal_MemFree(pageSegmentArray); |
---|
886 | } |
---|
887 | |
---|
888 | |
---|
889 | /**Function******************************************************************** |
---|
890 | |
---|
891 | Synopsis [required] |
---|
892 | |
---|
893 | Description [optional] |
---|
894 | |
---|
895 | SideEffects [required] |
---|
896 | |
---|
897 | SeeAlso [optional] |
---|
898 | |
---|
899 | ******************************************************************************/ |
---|
900 | static void |
---|
901 | BddExchangeAux(Cal_BddManager_t *bddManager, CalBddNode_t *f, |
---|
902 | int id, int nextId) |
---|
903 | { |
---|
904 | CalBddNode_t *f0, *f1; |
---|
905 | CalBddNode_t *f00, *f01, *f10, *f11; |
---|
906 | CalBddNode_t *newF0, *newF1; |
---|
907 | int f0Found, f1Found; |
---|
908 | int fIndex; |
---|
909 | |
---|
910 | f0 = f->elseBddNode; |
---|
911 | f1 = f->thenBddNode; |
---|
912 | |
---|
913 | if (CAL_BDD_POINTER(f0)->thenBddId == nextId){ |
---|
914 | f00 = BddNodeGetElseBddNode(f0); |
---|
915 | f01 = BddNodeGetThenBddNode(f0); |
---|
916 | } |
---|
917 | else { |
---|
918 | f00 = f01 = f0; |
---|
919 | } |
---|
920 | if (CAL_BDD_POINTER(f1)->thenBddId == nextId){ |
---|
921 | f10 = BddNodeGetElseBddNode(f1); |
---|
922 | f11 = BddNodeGetThenBddNode(f1); |
---|
923 | } |
---|
924 | else { |
---|
925 | f10 = f11 = f1; |
---|
926 | } |
---|
927 | |
---|
928 | if (f00 == f10){ |
---|
929 | newF0 = f00; |
---|
930 | f0Found = 1; |
---|
931 | } |
---|
932 | else{ |
---|
933 | f0Found = UniqueTableForIdFindOrAdd(bddManager, |
---|
934 | bddManager->uniqueTable[id], f10, |
---|
935 | f00, &newF0); |
---|
936 | } |
---|
937 | BddNodeIcrRefCount(newF0); |
---|
938 | if (f01 == f11){ |
---|
939 | newF1 = f11; |
---|
940 | f1Found = 1; |
---|
941 | } |
---|
942 | else{ |
---|
943 | f1Found = UniqueTableForIdFindOrAdd(bddManager, |
---|
944 | bddManager->uniqueTable[id], f11, |
---|
945 | f01, &newF1); |
---|
946 | } |
---|
947 | BddNodeIcrRefCount(newF1); |
---|
948 | |
---|
949 | f->thenBddId = nextId; |
---|
950 | f->elseBddNode = newF0; |
---|
951 | f->thenBddNode = newF1; |
---|
952 | |
---|
953 | fIndex = bddManager->idToIndex[id]; |
---|
954 | Cal_Assert(fIndex < |
---|
955 | bddManager->idToIndex[CAL_BDD_POINTER(f00)->thenBddId]); |
---|
956 | Cal_Assert(fIndex < |
---|
957 | bddManager->idToIndex[CAL_BDD_POINTER(f10)->thenBddId]); |
---|
958 | Cal_Assert(fIndex < |
---|
959 | bddManager->idToIndex[CAL_BDD_POINTER(f01)->thenBddId]); |
---|
960 | Cal_Assert(fIndex < |
---|
961 | bddManager->idToIndex[CAL_BDD_POINTER(f11)->thenBddId]); |
---|
962 | Cal_Assert(CAL_BDD_POINTER(f00)->thenBddId != nextId); |
---|
963 | Cal_Assert(CAL_BDD_POINTER(f01)->thenBddId != nextId); |
---|
964 | Cal_Assert(CAL_BDD_POINTER(f10)->thenBddId != nextId); |
---|
965 | Cal_Assert(CAL_BDD_POINTER(f11)->thenBddId != nextId); |
---|
966 | |
---|
967 | if (!f0Found){ |
---|
968 | BddNodeIcrRefCount(f00); |
---|
969 | BddNodeIcrRefCount(f10); |
---|
970 | } |
---|
971 | |
---|
972 | if (!f1Found){ |
---|
973 | BddNodeIcrRefCount(f01); |
---|
974 | BddNodeIcrRefCount(f11); |
---|
975 | } |
---|
976 | |
---|
977 | BddNodeDcrRefCount(f0); |
---|
978 | BddNodeDcrRefCount(f1); |
---|
979 | } |
---|
980 | |
---|
981 | /**Function******************************************************************** |
---|
982 | |
---|
983 | Synopsis [required] |
---|
984 | |
---|
985 | Description [optional] |
---|
986 | |
---|
987 | SideEffects [required] |
---|
988 | |
---|
989 | SeeAlso [optional] |
---|
990 | |
---|
991 | ******************************************************************************/ |
---|
992 | static int |
---|
993 | CheckValidityOfNodes(Cal_BddManager_t *bddManager, long id) |
---|
994 | { |
---|
995 | #ifndef NDEBUG |
---|
996 | CalHashTable_t *table = bddManager->uniqueTable[id]; |
---|
997 | int i; |
---|
998 | CalBddNode_t *bddNode; |
---|
999 | int index = bddManager->idToIndex[id]; |
---|
1000 | for(i = 0; i < table->numBins; ++i){ |
---|
1001 | for (bddNode = table->bins[i]; bddNode; bddNode = bddNode->nextBddNode){ |
---|
1002 | int thenIndex = bddManager->idToIndex[bddNode->thenBddNode->thenBddId]; |
---|
1003 | int elseIndex = |
---|
1004 | bddManager->idToIndex[CAL_BDD_POINTER(bddNode->elseBddNode)->thenBddId]; |
---|
1005 | assert((thenIndex > index) && (elseIndex > index)); |
---|
1006 | } |
---|
1007 | } |
---|
1008 | #endif |
---|
1009 | return 1; |
---|
1010 | } |
---|
1011 | |
---|
1012 | /**Function******************************************************************** |
---|
1013 | |
---|
1014 | Synopsis [required] |
---|
1015 | |
---|
1016 | Description [optional] |
---|
1017 | |
---|
1018 | SideEffects [required] |
---|
1019 | |
---|
1020 | SeeAlso [optional] |
---|
1021 | |
---|
1022 | ******************************************************************************/ |
---|
1023 | static void |
---|
1024 | SweepVarTable(Cal_BddManager_t *bddManager, long id) |
---|
1025 | { |
---|
1026 | CalHashTable_t *table = bddManager->uniqueTable[id]; |
---|
1027 | long numNodesFreed, oldNumEntries; |
---|
1028 | CalBddNode_t **ptr, *bddNode; |
---|
1029 | int i; |
---|
1030 | |
---|
1031 | oldNumEntries = table->numEntries; |
---|
1032 | for(i = 0; i < table->numBins; ++i){ |
---|
1033 | for (ptr = &table->bins[i], bddNode = *ptr; bddNode; |
---|
1034 | bddNode = *ptr){ |
---|
1035 | if (bddNode->elseBddId == 0){ |
---|
1036 | *ptr = bddNode->nextBddNode; |
---|
1037 | CalNodeManagerFreeNode(nodeManager, bddNode); |
---|
1038 | BddNodeDcrRefCount(bddNode->thenBddNode); |
---|
1039 | BddNodeDcrRefCount(bddNode->elseBddNode); |
---|
1040 | table->numEntries--; |
---|
1041 | } |
---|
1042 | else{ |
---|
1043 | ptr = &bddNode->nextBddNode; |
---|
1044 | } |
---|
1045 | } |
---|
1046 | } |
---|
1047 | numNodesFreed = oldNumEntries - table->numEntries; |
---|
1048 | bddManager->numNodes -= numNodesFreed; |
---|
1049 | bddManager->numNodesFreed += numNodesFreed; |
---|
1050 | } |
---|
1051 | |
---|
1052 | |
---|
1053 | /**Function******************************************************************** |
---|
1054 | |
---|
1055 | Synopsis [required] |
---|
1056 | |
---|
1057 | Description [optional] |
---|
1058 | |
---|
1059 | SideEffects [required] |
---|
1060 | |
---|
1061 | SeeAlso [optional] |
---|
1062 | |
---|
1063 | ******************************************************************************/ |
---|
1064 | static void |
---|
1065 | BddExchange(Cal_BddManager_t *bddManager, long id) |
---|
1066 | { |
---|
1067 | Cal_BddId_t nextId; |
---|
1068 | CalBddNode_t **ptr, *bddNode, *nodeList; |
---|
1069 | CalHashTable_t *table, *nextTable; |
---|
1070 | Cal_BddIndex_t index, nextIndex; |
---|
1071 | int i; |
---|
1072 | CalBddNode_t *f1, *f2; |
---|
1073 | CalAssociation_t *p; |
---|
1074 | CalNodeManager_t *nodeManager; |
---|
1075 | |
---|
1076 | index = bddManager->idToIndex[id]; |
---|
1077 | nextIndex = index+1; |
---|
1078 | nextId = bddManager->indexToId[nextIndex]; |
---|
1079 | |
---|
1080 | if (CalTestInteract(bddManager, id, nextId)){ |
---|
1081 | bddManager->numSwaps++; |
---|
1082 | nodeManager = bddManager->nodeManagerArray[id]; |
---|
1083 | table = bddManager->uniqueTable[id]; |
---|
1084 | nextTable = bddManager->uniqueTable[nextId]; |
---|
1085 | nodeList = (CalBddNode_t*)0; |
---|
1086 | for(i = 0; i < table->numBins; i++){ |
---|
1087 | for (ptr = &table->bins[i], bddNode = *ptr; bddNode; |
---|
1088 | bddNode = *ptr){ |
---|
1089 | Cal_Assert(bddNode->elseBddId != 0); |
---|
1090 | f1 = bddNode->elseBddNode; |
---|
1091 | f2 = bddNode->thenBddNode; |
---|
1092 | if ((CAL_BDD_POINTER(f1)->thenBddId != nextId) && |
---|
1093 | (CAL_BDD_POINTER(f2)->thenBddId != nextId)){ |
---|
1094 | ptr = &bddNode->nextBddNode; |
---|
1095 | } |
---|
1096 | else{ |
---|
1097 | *ptr = bddNode->nextBddNode; |
---|
1098 | bddNode->nextBddNode = nodeList; |
---|
1099 | nodeList = bddNode; |
---|
1100 | } |
---|
1101 | } |
---|
1102 | } |
---|
1103 | for (bddNode = nodeList; bddNode ; bddNode = nodeList){ |
---|
1104 | BddExchangeAux(bddManager, bddNode, id, nextId); |
---|
1105 | nodeList = bddNode->nextBddNode; |
---|
1106 | HashTableAddDirect(nextTable, bddNode); |
---|
1107 | table->numEntries--; |
---|
1108 | } |
---|
1109 | SweepVarTable(bddManager, nextId); |
---|
1110 | } |
---|
1111 | else { |
---|
1112 | bddManager->numTrivialSwaps++; |
---|
1113 | } |
---|
1114 | |
---|
1115 | CalFixupAssoc(bddManager, id, nextId, bddManager->tempAssociation); |
---|
1116 | for(p = bddManager->associationList; p; p = p->next){ |
---|
1117 | CalFixupAssoc(bddManager, id, nextId, p); |
---|
1118 | } |
---|
1119 | |
---|
1120 | bddManager->idToIndex[id] = nextIndex; |
---|
1121 | bddManager->idToIndex[nextId] = index; |
---|
1122 | bddManager->indexToId[index] = nextId; |
---|
1123 | bddManager->indexToId[nextIndex] = id; |
---|
1124 | |
---|
1125 | Cal_Assert(CheckValidityOfNodes(bddManager, id)); |
---|
1126 | Cal_Assert(CheckValidityOfNodes(bddManager, nextId)); |
---|
1127 | Cal_Assert(CalCheckAssoc(bddManager)); |
---|
1128 | #ifdef _CAL_VERBOSE |
---|
1129 | /*fprintf(stdout,"Variable order after swap:\n");*/ |
---|
1130 | for (i=0; i<bddManager->numVars; i++){ |
---|
1131 | fprintf(stdout, "%3d ", bddManager->indexToId[i]); |
---|
1132 | } |
---|
1133 | fprintf(stdout, "%8d\n", bddManager->numNodes); |
---|
1134 | #endif |
---|
1135 | } |
---|
1136 | |
---|
1137 | |
---|
1138 | /**Function******************************************************************** |
---|
1139 | |
---|
1140 | Synopsis [required] |
---|
1141 | |
---|
1142 | Description [optional] |
---|
1143 | |
---|
1144 | SideEffects [required] |
---|
1145 | |
---|
1146 | SeeAlso [optional] |
---|
1147 | |
---|
1148 | ******************************************************************************/ |
---|
1149 | static void |
---|
1150 | BddExchangeVarBlocks(Cal_BddManager_t *bddManager, Cal_Block parent, |
---|
1151 | long blockIndex) |
---|
1152 | { |
---|
1153 | Cal_Block b1, b2, temp; |
---|
1154 | long i, j, k, l, firstBlockWidth, secondBlockWidth; |
---|
1155 | |
---|
1156 | b1 = parent->children[blockIndex]; |
---|
1157 | b2 = parent->children[blockIndex+1]; |
---|
1158 | /* This slides the blocks past each other in a kind of interleaving */ |
---|
1159 | /* fashion. */ |
---|
1160 | firstBlockWidth = b1->lastIndex - b1->firstIndex; |
---|
1161 | secondBlockWidth = b2->lastIndex - b2->firstIndex; |
---|
1162 | |
---|
1163 | for (i=0; i <= firstBlockWidth + secondBlockWidth; i++){ |
---|
1164 | j = i - firstBlockWidth; |
---|
1165 | if (j < 0) j=0; |
---|
1166 | k = ((i > secondBlockWidth) ? secondBlockWidth : i); |
---|
1167 | while (j <= k) { |
---|
1168 | l = b2->firstIndex + j - i + j; |
---|
1169 | BddExchange(bddManager, bddManager->indexToId[l-1]); |
---|
1170 | ++j; |
---|
1171 | } |
---|
1172 | } |
---|
1173 | CalBddBlockDelta(b1, secondBlockWidth+1); |
---|
1174 | CalBddBlockDelta(b2, -(firstBlockWidth+1)); |
---|
1175 | temp = parent->children[blockIndex]; |
---|
1176 | parent->children[blockIndex] = parent->children[blockIndex+1]; |
---|
1177 | parent->children[blockIndex+1] = temp; |
---|
1178 | } |
---|
1179 | |
---|
1180 | /**Function******************************************************************** |
---|
1181 | |
---|
1182 | Synopsis [required] |
---|
1183 | |
---|
1184 | Description [optional] |
---|
1185 | |
---|
1186 | SideEffects [required] |
---|
1187 | |
---|
1188 | SeeAlso [optional] |
---|
1189 | |
---|
1190 | ******************************************************************************/ |
---|
1191 | static int |
---|
1192 | BddReorderWindow2(Cal_BddManager_t *bddManager, Cal_Block block, long i) |
---|
1193 | { |
---|
1194 | long size, bestSize; |
---|
1195 | |
---|
1196 | /* 1 2 */ |
---|
1197 | bestSize = bddManager->numNodes; |
---|
1198 | BddExchangeVarBlocks(bddManager, block, i); |
---|
1199 | /* 2 1 */ |
---|
1200 | size = bddManager->numNodes; |
---|
1201 | if (size < bestSize) return (1); |
---|
1202 | BddExchangeVarBlocks(bddManager, block, i); |
---|
1203 | return (0); |
---|
1204 | } |
---|
1205 | |
---|
1206 | |
---|
1207 | /**Function******************************************************************** |
---|
1208 | |
---|
1209 | Synopsis [required] |
---|
1210 | |
---|
1211 | Description [optional] |
---|
1212 | |
---|
1213 | SideEffects [required] |
---|
1214 | |
---|
1215 | SeeAlso [optional] |
---|
1216 | |
---|
1217 | ******************************************************************************/ |
---|
1218 | static int |
---|
1219 | BddReorderWindow3(Cal_BddManager_t *bddManager, Cal_Block block, long i) |
---|
1220 | { |
---|
1221 | int best; |
---|
1222 | long size, bestSize; |
---|
1223 | long origSize; |
---|
1224 | |
---|
1225 | origSize = bddManager->numNodes; |
---|
1226 | best = 0; |
---|
1227 | /* 1 2 3 */ |
---|
1228 | bestSize = bddManager->numNodes; |
---|
1229 | BddExchangeVarBlocks(bddManager, block, i); |
---|
1230 | /* 2 1 3 */ |
---|
1231 | size=bddManager->numNodes; |
---|
1232 | if (size < bestSize) { |
---|
1233 | best=1; |
---|
1234 | bestSize=size; |
---|
1235 | } |
---|
1236 | BddExchangeVarBlocks(bddManager, block, i+1); |
---|
1237 | /* 2 3 1 */ |
---|
1238 | size=bddManager->numNodes; |
---|
1239 | if (size < bestSize) { |
---|
1240 | best=2; |
---|
1241 | bestSize=size; |
---|
1242 | } |
---|
1243 | BddExchangeVarBlocks(bddManager, block, i); |
---|
1244 | /* 3 2 1 */ |
---|
1245 | size=bddManager->numNodes; |
---|
1246 | if (size <= bestSize) { |
---|
1247 | best=3; |
---|
1248 | bestSize=size; |
---|
1249 | } |
---|
1250 | BddExchangeVarBlocks(bddManager, block, i+1); |
---|
1251 | /* 3 1 2 */ |
---|
1252 | size=bddManager->numNodes; |
---|
1253 | if (size <= bestSize) { |
---|
1254 | best=4; |
---|
1255 | bestSize=size; |
---|
1256 | } |
---|
1257 | BddExchangeVarBlocks(bddManager, block, i); |
---|
1258 | /* 1 3 2 */ |
---|
1259 | size=bddManager->numNodes; |
---|
1260 | if (size <= bestSize) { |
---|
1261 | best=5; |
---|
1262 | bestSize=size; |
---|
1263 | } |
---|
1264 | switch (best){ |
---|
1265 | case 0: |
---|
1266 | BddExchangeVarBlocks(bddManager, block, i+1); |
---|
1267 | break; |
---|
1268 | case 1: |
---|
1269 | BddExchangeVarBlocks(bddManager, block, i+1); |
---|
1270 | BddExchangeVarBlocks(bddManager, block, i); |
---|
1271 | break; |
---|
1272 | case 2: |
---|
1273 | BddExchangeVarBlocks(bddManager, block, i+1); |
---|
1274 | BddExchangeVarBlocks(bddManager, block, i); |
---|
1275 | BddExchangeVarBlocks(bddManager, block, i+1); |
---|
1276 | break; |
---|
1277 | case 3: |
---|
1278 | BddExchangeVarBlocks(bddManager, block, i); |
---|
1279 | BddExchangeVarBlocks(bddManager, block, i+1); |
---|
1280 | break; |
---|
1281 | case 4: |
---|
1282 | BddExchangeVarBlocks(bddManager, block, i); |
---|
1283 | break; |
---|
1284 | case 5: |
---|
1285 | break; |
---|
1286 | } |
---|
1287 | return ((best > 0) && (origSize > bestSize)); |
---|
1288 | } |
---|
1289 | |
---|
1290 | /**Function******************************************************************** |
---|
1291 | |
---|
1292 | Synopsis [required] |
---|
1293 | |
---|
1294 | Description [optional] |
---|
1295 | |
---|
1296 | SideEffects [required] |
---|
1297 | |
---|
1298 | SeeAlso [optional] |
---|
1299 | |
---|
1300 | ******************************************************************************/ |
---|
1301 | static void |
---|
1302 | BddReorderStableWindow3Aux(Cal_BddManager_t *bddManager, Cal_Block block, |
---|
1303 | char *levels) |
---|
1304 | { |
---|
1305 | long i; |
---|
1306 | int moved; |
---|
1307 | int anySwapped; |
---|
1308 | |
---|
1309 | if (block->reorderable) { |
---|
1310 | for (i=0; i < block->numChildren-1; ++i) levels[i]=1; |
---|
1311 | do { |
---|
1312 | anySwapped=0; |
---|
1313 | for (i=0; i < block->numChildren-1; i++){ |
---|
1314 | if (levels[i]){ |
---|
1315 | #ifdef _CAL_VERBOSE |
---|
1316 | fprintf(stdout,"Moving block %3d -- %3d\n", |
---|
1317 | bddManager->indexToId[block->children[i]-> firstIndex], |
---|
1318 | bddManager->indexToId[block->children[i]->lastIndex]); |
---|
1319 | fflush(stdout); |
---|
1320 | for (j=0; j<bddManager->numVars; j++){ |
---|
1321 | fprintf(stdout, "%3d ", bddManager->indexToId[j]); |
---|
1322 | } |
---|
1323 | fprintf(stdout, "%8d\n", bddManager->numNodes); |
---|
1324 | #endif |
---|
1325 | if (i < block->numChildren-2){ |
---|
1326 | moved = BddReorderWindow3(bddManager, block, i); |
---|
1327 | } |
---|
1328 | else{ |
---|
1329 | moved = BddReorderWindow2(bddManager, block, i); |
---|
1330 | } |
---|
1331 | if (moved){ |
---|
1332 | if (i > 0) { |
---|
1333 | levels[i-1]=1; |
---|
1334 | if (i > 1) |
---|
1335 | levels[i-2]=1; |
---|
1336 | } |
---|
1337 | levels[i]=1; |
---|
1338 | levels[i+1]=1; |
---|
1339 | if (i < block->numChildren-2){ |
---|
1340 | levels[i+2]=1; |
---|
1341 | if (i < block->numChildren-3) { |
---|
1342 | levels[i+3]=1; |
---|
1343 | if (i < block->numChildren-4) levels[i+4]=1; |
---|
1344 | } |
---|
1345 | } |
---|
1346 | anySwapped=1; |
---|
1347 | } |
---|
1348 | else levels[i]=0; |
---|
1349 | } |
---|
1350 | } |
---|
1351 | } while (anySwapped); |
---|
1352 | } |
---|
1353 | for (i=0; i < block->numChildren; ++i){ |
---|
1354 | BddReorderStableWindow3Aux(bddManager, block->children[i], levels); |
---|
1355 | } |
---|
1356 | } |
---|
1357 | |
---|
1358 | /**Function******************************************************************** |
---|
1359 | |
---|
1360 | Synopsis [required] |
---|
1361 | |
---|
1362 | Description [optional] |
---|
1363 | |
---|
1364 | SideEffects [required] |
---|
1365 | |
---|
1366 | SeeAlso [optional] |
---|
1367 | |
---|
1368 | ******************************************************************************/ |
---|
1369 | static void |
---|
1370 | BddReorderStableWindow3(Cal_BddManager_t *bddManager) |
---|
1371 | { |
---|
1372 | char *levels; |
---|
1373 | levels = Cal_MemAlloc(char, bddManager->numVars); |
---|
1374 | bddManager->numSwaps = 0; |
---|
1375 | BddReorderStableWindow3Aux(bddManager, bddManager->superBlock, levels); |
---|
1376 | Cal_MemFree(levels); |
---|
1377 | } |
---|
1378 | |
---|
1379 | /**Function******************************************************************** |
---|
1380 | |
---|
1381 | Synopsis [required] |
---|
1382 | |
---|
1383 | Description [optional] |
---|
1384 | |
---|
1385 | SideEffects [required] |
---|
1386 | |
---|
1387 | SeeAlso [optional] |
---|
1388 | |
---|
1389 | ******************************************************************************/ |
---|
1390 | static void |
---|
1391 | BddSiftBlock(Cal_BddManager_t *bddManager, Cal_Block block, long |
---|
1392 | startPosition, double maxSizeFactor) |
---|
1393 | { |
---|
1394 | long startSize; |
---|
1395 | long bestSize; |
---|
1396 | long bestPosition; |
---|
1397 | long currentSize; |
---|
1398 | long currentPosition; |
---|
1399 | long maxSize; |
---|
1400 | |
---|
1401 | startSize = bddManager->numNodes; |
---|
1402 | bestSize = startSize; |
---|
1403 | bestPosition = startPosition; |
---|
1404 | currentSize = startSize; |
---|
1405 | currentPosition = startPosition; |
---|
1406 | maxSize = maxSizeFactor*startSize; |
---|
1407 | if (bddManager->nodeLimit && maxSize > bddManager->nodeLimit) |
---|
1408 | maxSize = bddManager->nodeLimit; |
---|
1409 | |
---|
1410 | /* Need to do optimization here */ |
---|
1411 | if (startPosition > (block->numChildren >> 1)){ |
---|
1412 | while (currentPosition < block->numChildren-1 && currentSize <= maxSize){ |
---|
1413 | BddExchangeVarBlocks(bddManager, block, currentPosition); |
---|
1414 | ++currentPosition; |
---|
1415 | currentSize = bddManager->numNodes; |
---|
1416 | if (currentSize < bestSize){ |
---|
1417 | bestSize = currentSize; |
---|
1418 | bestPosition=currentPosition; |
---|
1419 | } |
---|
1420 | } |
---|
1421 | while (currentPosition != startPosition){ |
---|
1422 | --currentPosition; |
---|
1423 | BddExchangeVarBlocks(bddManager, block, currentPosition); |
---|
1424 | } |
---|
1425 | currentSize = startSize; |
---|
1426 | while (currentPosition && currentSize <= maxSize){ |
---|
1427 | --currentPosition; |
---|
1428 | BddExchangeVarBlocks(bddManager, block, currentPosition); |
---|
1429 | currentSize = bddManager->numNodes; |
---|
1430 | if (currentSize <= bestSize){ |
---|
1431 | bestSize = currentSize; |
---|
1432 | bestPosition = currentPosition; |
---|
1433 | } |
---|
1434 | } |
---|
1435 | while (currentPosition != bestPosition){ |
---|
1436 | BddExchangeVarBlocks(bddManager, block, currentPosition); |
---|
1437 | ++currentPosition; |
---|
1438 | } |
---|
1439 | } |
---|
1440 | else{ |
---|
1441 | while (currentPosition && currentSize <= maxSize){ |
---|
1442 | --currentPosition; |
---|
1443 | BddExchangeVarBlocks(bddManager, block, currentPosition); |
---|
1444 | currentSize = bddManager->numNodes; |
---|
1445 | if (currentSize < bestSize){ |
---|
1446 | bestSize = currentSize; |
---|
1447 | bestPosition = currentPosition; |
---|
1448 | } |
---|
1449 | } |
---|
1450 | while (currentPosition != startPosition){ |
---|
1451 | BddExchangeVarBlocks(bddManager, block, currentPosition); |
---|
1452 | ++currentPosition; |
---|
1453 | } |
---|
1454 | currentSize = startSize; |
---|
1455 | while (currentPosition < block->numChildren-1 && currentSize <= maxSize){ |
---|
1456 | BddExchangeVarBlocks(bddManager, block, currentPosition); |
---|
1457 | currentSize = bddManager->numNodes; |
---|
1458 | ++currentPosition; |
---|
1459 | if (currentSize <= bestSize){ |
---|
1460 | bestSize = currentSize; |
---|
1461 | bestPosition = currentPosition; |
---|
1462 | } |
---|
1463 | } |
---|
1464 | while (currentPosition != bestPosition){ |
---|
1465 | --currentPosition; |
---|
1466 | BddExchangeVarBlocks(bddManager, block, currentPosition); |
---|
1467 | } |
---|
1468 | } |
---|
1469 | } |
---|
1470 | |
---|
1471 | |
---|
1472 | |
---|
1473 | /**Function******************************************************************** |
---|
1474 | |
---|
1475 | Synopsis [Reorder variables using "sift" algorithm.] |
---|
1476 | |
---|
1477 | Description [Reorder variables using "sift" algorithm.] |
---|
1478 | |
---|
1479 | SideEffects [None] |
---|
1480 | |
---|
1481 | ******************************************************************************/ |
---|
1482 | static void |
---|
1483 | BddReorderSiftAux(Cal_BddManager_t *bddManager, Cal_Block block, |
---|
1484 | Cal_Block *toSift, double maxSizeFactor) |
---|
1485 | { |
---|
1486 | long i, j, k; |
---|
1487 | long width; |
---|
1488 | long maxWidth; |
---|
1489 | long widest; |
---|
1490 | long numVarsShifted = 0; |
---|
1491 | bddManager->numSwaps = 0; |
---|
1492 | if (block->reorderable) { |
---|
1493 | for (i=0; i < block->numChildren; ++i){ |
---|
1494 | toSift[i] = block->children[i]; |
---|
1495 | } |
---|
1496 | while (i && |
---|
1497 | (numVarsShifted <= |
---|
1498 | bddManager->maxNumVarsSiftedPerReordering) && |
---|
1499 | (bddManager->numSwaps <= |
---|
1500 | bddManager->maxNumSwapsPerReordering)){ |
---|
1501 | i--; |
---|
1502 | numVarsShifted++; |
---|
1503 | maxWidth = 0; |
---|
1504 | widest = 0; |
---|
1505 | for (j=0; j <= i; ++j) { |
---|
1506 | for (width=0, k=toSift[j]->firstIndex; k <= toSift[j]->lastIndex; ++k){ |
---|
1507 | width += |
---|
1508 | bddManager->uniqueTable[bddManager->indexToId[k]]->numEntries; |
---|
1509 | } |
---|
1510 | width /= toSift[j]->lastIndex - toSift[j]->firstIndex+1; |
---|
1511 | if (width > maxWidth) { |
---|
1512 | maxWidth = width; |
---|
1513 | widest = j; |
---|
1514 | } |
---|
1515 | } |
---|
1516 | if (maxWidth > 1) { |
---|
1517 | for (j=0; block->children[j] != toSift[widest]; ++j); |
---|
1518 | #ifdef _CAL_VERBOSE |
---|
1519 | fprintf(stdout,"Moving block %3d -- %3d\n", |
---|
1520 | bddManager->indexToId[block->children[j]-> firstIndex], |
---|
1521 | bddManager->indexToId[block->children[j]->lastIndex]); |
---|
1522 | fflush(stdout); |
---|
1523 | for (l=0; l<bddManager->numVars; l++){ |
---|
1524 | fprintf(stdout, "%3d ", bddManager->indexToId[l]); |
---|
1525 | } |
---|
1526 | fprintf(stdout, "%8d\n", bddManager->numNodes); |
---|
1527 | #endif |
---|
1528 | BddSiftBlock(bddManager, block, j, maxSizeFactor); |
---|
1529 | toSift[widest] = toSift[i]; |
---|
1530 | } |
---|
1531 | else { |
---|
1532 | break; |
---|
1533 | } |
---|
1534 | } |
---|
1535 | } |
---|
1536 | for (i=0; i < block->numChildren; ++i) |
---|
1537 | BddReorderSiftAux(bddManager, block->children[i], toSift, |
---|
1538 | maxSizeFactor); |
---|
1539 | } |
---|
1540 | |
---|
1541 | /**Function******************************************************************** |
---|
1542 | |
---|
1543 | Synopsis [required] |
---|
1544 | |
---|
1545 | Description [optional] |
---|
1546 | |
---|
1547 | SideEffects [required] |
---|
1548 | |
---|
1549 | SeeAlso [optional] |
---|
1550 | |
---|
1551 | ******************************************************************************/ |
---|
1552 | static void |
---|
1553 | BddReorderSift(Cal_BddManager_t *bddManager, double maxSizeFactor) |
---|
1554 | { |
---|
1555 | Cal_Block *toSift; |
---|
1556 | |
---|
1557 | toSift = Cal_MemAlloc(Cal_Block, bddManager->numVars); |
---|
1558 | BddReorderSiftAux(bddManager, bddManager->superBlock, toSift, |
---|
1559 | maxSizeFactor); |
---|
1560 | Cal_MemFree(toSift); |
---|
1561 | } |
---|
1562 | |
---|
1563 | |
---|
1564 | |
---|
1565 | |
---|
1566 | /**Function******************************************************************** |
---|
1567 | |
---|
1568 | Synopsis [Returns the smallest integer greater than or equal to log2 of a |
---|
1569 | number] |
---|
1570 | |
---|
1571 | Description [Returns the smallest integer greater than or equal to log2 of a |
---|
1572 | number (The assumption is that the number is >= 1)] |
---|
1573 | |
---|
1574 | SideEffects [None] |
---|
1575 | |
---|
1576 | ******************************************************************************/ |
---|
1577 | static int |
---|
1578 | CeilLog2(int number) |
---|
1579 | { |
---|
1580 | int num, count; |
---|
1581 | for (num=number, count=0; num > 1; num >>= 1, count++); |
---|
1582 | if ((1 << count) != number) count++; |
---|
1583 | return count; |
---|
1584 | } |
---|