added README_changes.txt
[wrffire.git] / wrfv2_fire / external / RSL / RSL / process_refs.c
blob79328c5db3a0250d7ba2a70beeabb05306b81538
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include "rsl.h"
5 #ifdef NEC_TUNE
6 typedef struct{
7 int max_nsec ; /* Maximum number of entris on secondary list */
8 int nsec ; /* Number of entries on secondary list */
9 void *base ; /* Base address */
10 int *offset ; /* Array of "offsets" associated with base */
11 int *n ; /* Array of "lengths" associated with offset */
12 packrec_t **data ; /* Array of "Ptr's to head data" */
13 } Pri_lst_t ;
14 static int max_npri = 128 ; /* Max. no of "base" entries on primary list */
15 static int npri = 0 ; /* Number of "base" entries on primary list */
16 static Pri_lst_t *Pri_lst = NULL ; /* Primary list */
17 #endif
18 static rsl_list_t * list_head = NULL ;
20 static int destroy_packrec( p ) packrec_t * p ; { free( p ) ; return(0) ;}
22 init_process_refs()
24 int destroy_packrec() ;
25 rsl_list_t * lp, *lpnext ;
27 for ( lp = list_head ; lp ; lp = lp->next )
29 destroy_list( &(lp->data), destroy_packrec ) ;
31 destroy_list( &list_head, NULL ) ;
32 #ifdef NEC_TUNE
34 NECNOTE:
35 If primary list is allocated and has entries assigned, free all data
36 allocated on secondary lists by reseting variable 'nsec' to zero.
38 if ( npri != 0 )
40 int ipri ;
41 for ( ipri = 0 ; ipri < npri ; ipri++ )
43 Pri_lst[ipri].nsec = 0 ; /* Free all entries on secondary list */
45 npri = 0 ; /* Free all entries on primary list */
47 #endif
50 The data structure being built by this routine:
51 (n is next pointer, d is data pointer)
52 The primary list (downwards) is a list of lists.
53 Each of the secondary lists (leftwards) is a list of all the
54 pack or unpack records with the same base. This routine
55 checks to ensure that recs that are complete duplicates
56 (which can happen) are not added.
58 list_t -d-> list_t -n-> list_t -n-> list_t -n-> ...
59 | \ \ \
60 n d d d
61 | \ \ \
62 | base,off,n base,off,n base,off,n ...
64 list_t -d-> list_t -n-> list_t -n-> list_t -n-> ...
65 | \ \ \
66 n d d d
67 | \ \ \
68 | base,off,n base,off,n base,off,n ...
70 list_t -d-> list_t -n-> list_t -n-> list_t -n-> ...
71 | \ \ \
72 n d d d
73 | \ \ \
74 | base,off,n base,off,n base,off,n ...
81 store_process_refs( base, f90_table_index , offset, n, nelems, stride )
82 void * base ;
83 int f90_table_index ;
84 int offset ;
85 int n ;
86 int nelems ;
87 int stride ;
89 rsl_list_t * lp, *lp1, *lp2, *lp3, *lp4 ;
90 rsl_list_t * x ;
91 packrec_t * newrec, *arec, *nextrec ;
92 int found, found1 ;
93 #ifdef NEC_TUNE
94 int ipri ;
95 int isec ;
96 int found_search ;
98 if ( Pri_lst == NULL ) /* Need to initialize Primary list */
100 Pri_lst = realloc(Pri_lst, max_npri*sizeof(Pri_lst_t)) ;
101 RSL_TEST_ERR(Pri_lst == NULL, "out of memory - 1") ;
103 #endif
105 #if 0
106 fprintf(stderr,"debug store_process_refs 1 base %08x ",base) ;
107 fprintf(stderr," f90_table_index %3d ",f90_table_index) ;
108 fprintf(stderr," offset %10d ",offset) ;
109 fprintf(stderr," n %5d",n) ;
110 fprintf(stderr," nelems %5d",nelems) ;
111 fprintf(stderr," stride %5d\n",stride) ;
112 #endif
114 newrec = RSL_MALLOC( packrec_t, 1 ) ;
115 newrec->endstop = 0 ;
116 if ( stride < 0 ) { newrec->endstop = 1 ; stride = -stride ; }
117 newrec->base = base ;
118 newrec->f90_table_index = f90_table_index ;
119 newrec->offset = offset ;
120 newrec->n = n ;
121 newrec->nelems = nelems ;
122 newrec->stride = stride ;
123 newrec->valid = 1 ;
125 /* traverse the primary list and see if there's a secondary
126 list already for this base address. If there is not, add
127 it with newrec as the first entry in the new secondar list.
128 If there is alread a secondary list, traverse it and make sure
129 there's not already an entry for newrec. If there isn't, add
130 an entry for newrec to the end of the secondary list. */
131 found = 0 ;
132 #ifdef NEC_TUNE
133 for ( ipri = 0 ; ipri < npri ; ipri++ )
135 if ( base == Pri_lst[ipri].base )
137 found = 1 ;
138 break ;
141 if ( found )
143 /* Quick search to see whether this is a duplicate call. */
144 found_search = 0 ;
145 #pragma vdir altcode=loopcnt
146 for ( isec = 0 ; isec < Pri_lst[ipri].nsec ; isec++ )
148 if ( Pri_lst[ipri].offset[isec] == offset )
150 found_search = 1 ; /* return silently */
151 break ;
154 if ( found_search )
156 if ( Pri_lst[ipri].n[isec] < n )
158 Pri_lst[ipri].n[isec] = n ;
159 Pri_lst[ipri].data[isec]->n = n ;
161 RSL_FREE(newrec) ;
162 return ;
165 #endif
166 for ( lp = list_head ; lp ; lp = lp->next )
168 if ( lp != NULL )
169 if ((lp1 = (rsl_list_t *)lp->data) != NULL )
170 if ((arec = (packrec_t *) lp1->data) != NULL )
171 if ( arec->base == base )
173 found = 1 ;
174 break ;
177 if ( !found )
179 x = RSL_MALLOC( rsl_list_t, 1 ) ;
180 x->next = list_head ;
181 list_head = x ;
182 x->data = RSL_MALLOC( rsl_list_t, 1 ) ;
183 ((rsl_list_t *) x->data)->data = newrec ;
184 ((rsl_list_t *) x->data)->next = NULL ;
186 else
188 /* includes an insertion sort */
189 found1 = 0 ;
190 #ifndef NEC_TUNE
191 for ( lp2 = lp1 ; lp2 != NULL ; lp2 = lp2->next )
193 lp3 = lp2 ; /* store previous lp2 */
194 arec = (packrec_t *) lp2->data ;
196 if (lp2 == lp1)
198 if ( newrec->offset < arec->offset )
199 { found1 = 0 ; break ; }
201 if (newrec->offset == arec->offset)
203 if (arec->n >= newrec->n)
204 { found1 = 1 ; break ; }
205 else
206 { arec->n = newrec->n ; found1 = 1 ; break ; }
208 else if (lp2->next != NULL)
210 nextrec = lp2->next->data ;
211 if ( newrec->offset > arec->offset &&
212 newrec->offset < nextrec->offset )
213 { found1 = 2 ; break ; }
215 else if (newrec->offset > arec->offset)
217 { found1 = 2 ; break ; }
220 #else
221 for ( lp2 = lp1 ; lp2 != NULL ; lp2 = lp2->next )
223 lp3 = lp2 ; /* store previous lp2 */
224 arec = (packrec_t *) lp2->data ;
226 if (lp2 == lp1)
228 if ( offset < arec->offset )
229 { found1 = 0 ; break ; }
231 if (offset == arec->offset)
233 if (arec->n >= n)
234 { found1 = 1 ; break ; }
235 else
236 { arec->n = n ; found1 = 3 ; break ; }
238 else if (lp2->next != NULL)
240 nextrec = lp2->next->data ;
241 if ( offset > arec->offset &&
242 offset < nextrec->offset )
243 { found1 = 2 ; break ; }
245 else if (offset > arec->offset)
247 { found1 = 2 ; break ; }
250 /* NECNOTE: Add base/offset/n to duplicate list. */
251 if ( found1 == 1 || found1 == 3 )
253 int nsec ;
254 int pri_found ;
255 RSL_FREE(newrec) ;
257 for ( ipri = 0, pri_found = 0 ; ipri < npri ; ipri++ )
259 if ( Pri_lst[ipri].base == base )
261 pri_found = 1 ;
262 break ;
266 if ( !pri_found )
268 if ( npri == max_npri )
270 max_npri *= 2 ;
271 Pri_lst = (Pri_lst_t *)realloc(Pri_lst, max_npri*sizeof(Pri_lst_t)) ;
274 Pri_lst[npri].max_nsec = 128 ;
275 Pri_lst[npri].nsec = 0 ;
276 Pri_lst[npri].base = base ;
278 NECNOTE:
279 I'd like to use RSL_MALLOC, but there is a good chance that the
280 following two pointers will be 'realloc'ed.
282 Pri_lst[npri].offset = (int *)malloc(Pri_lst[npri].max_nsec*sizeof(int)) ;
283 Pri_lst[npri].n = (int *)malloc(Pri_lst[npri].max_nsec*sizeof(int)) ;
284 Pri_lst[npri].data = (packrec_t **)malloc(Pri_lst[npri].max_nsec*sizeof(packrec_t *)) ;
285 RSL_TEST_ERR(Pri_lst[npri].offset == NULL || Pri_lst[npri].n == NULL ||
286 Pri_lst[npri].data == NULL, "out of memory - 2") ;
287 npri++ ;
290 nsec = Pri_lst[ipri].nsec ;
291 if ( nsec == Pri_lst[ipri].max_nsec )
293 Pri_lst[ipri].max_nsec *= 2 ;
294 Pri_lst[ipri].offset = (int *)realloc(Pri_lst[ipri].offset, Pri_lst[ipri].max_nsec*sizeof(int)) ;
295 Pri_lst[ipri].n = (int *)realloc(Pri_lst[ipri].n, Pri_lst[ipri].max_nsec*sizeof(int)) ;
296 Pri_lst[ipri].data = (packrec_t **)realloc(Pri_lst[ipri].data, Pri_lst[ipri].max_nsec*sizeof(packrec_t *)) ;
299 Pri_lst[ipri].offset[nsec] = offset ;
300 Pri_lst[ipri].n[nsec] = n ;
301 Pri_lst[ipri].data[nsec] = arec ;
302 Pri_lst[ipri].nsec++ ;
304 #endif
305 if ( found1 == 0 ) /* not found; add to beginning of list */
307 lp4 = RSL_MALLOC( rsl_list_t, 1 ) ;
308 lp4->next = (rsl_list_t *) lp->data ;
309 lp4->data = newrec ;
310 lp->data = lp4 ;
312 if ( found1 == 2 ) /* insert after this element */
314 lp4 = RSL_MALLOC( rsl_list_t, 1 ) ;
315 lp4->data = newrec ;
316 lp4->next = lp2->next ;
317 lp2->next = lp4 ;
322 static int compare_primary( lp1, lp2, dummy )
323 rsl_list_t *lp1, *lp2 ;
324 int dummy ;
326 rsl_list_t *a, *b ;
327 packrec_t *x, *y ;
328 if ( lp1 != NULL && lp2 != NULL )
330 if ((x=(packrec_t*)lp1->data) != NULL && (y=(packrec_t*)lp2->data) != NULL )
332 if (x->base > y->base)
334 return(1) ;
337 else
338 RSL_TEST_ERR(1,"compare_primary 2") ;
340 else
341 RSL_TEST_ERR(1, "compare_primary 1" ) ;
342 return(0) ;
345 static int compare_secondary( a, b, dummy )
346 packrec_t *a, *b ;
347 int dummy ;
349 if ( a != NULL && b != NULL )
350 if (a->offset > b->offset)
351 return(1) ;
352 return(0) ;
355 static int collapsetable( lst )
356 rsl_list_t ** lst ;
358 rsl_list_t * lp, * lp2, * prevlp ;
359 packrec_t *x, *y ;
361 if ( lst == NULL ) return(0) ;
363 lp = *lst ; x = lp->data ; if ( ! (x->valid ) ) RSL_TEST_ERR(1,"internal error: first entry invalid\n") ;
365 for ( lp = *lst ; lp != NULL ; lp = lp->next )
367 if (( x = lp->data ) != NULL ) ; if ( x->valid ) /* 2 statements */
369 for ( lp2 = lp->next ; lp2 != NULL ; lp2 = lp2->next )
371 if (( y = lp2->data ) != NULL ) ; if ( y->valid ) /* 2 statements */
373 if ((x->stride == y->stride) &&
374 (x->nelems == y->nelems) &&
375 ((x->offset + x->n ) == y->offset) && ! x->endstop )
378 y->valid = 0 ;
379 x->n += y->n ;
382 else
384 break ; /* out of inner loop */
390 /* new bit... collapse sequences of entries with the same base and stride */
392 int xn, bigstride, firsty ;
393 for ( lp = *lst ; lp != NULL ; lp = lp->next )
395 if (( x = lp->data ) != NULL ) ; if ( x->valid ) /* 2 statements */
397 if ( x->nelems != 1 ) continue ;
398 xn = x->n ;
399 firsty = 1 ;
400 for ( lp2 = lp->next ; lp2 != NULL ; lp2 = lp2->next )
402 if (( y = lp2->data ) != NULL ) ; if ( y->valid ) /* 2 statements */
404 if ( y->base != x->base ) break ;
405 if ( y->nelems != 1 ) break ;
406 if ( y->n != xn ) break ;
407 if ( firsty == 1 ) /* first y */
409 firsty = 0 ;
410 bigstride = y->offset - x->offset ;
412 if ( bigstride <= x->n ) break ;
413 if ( y->offset - x->offset == bigstride )
415 y->valid = 0 ;
416 x->nelems++ ;
417 x->stride = bigstride ;
424 /* now eliminate the invalidated entries */
425 for ( prevlp = *lst, lp = *lst ; lp != NULL ; )
427 if (( x=lp->data ) != NULL ) ; if ( ! x->valid ) /* 2 statements */
429 RSL_TEST_ERR( lp == *lst , " internal error -- shouldn't happen " ) ;
430 prevlp->next = lp->next ;
431 lp->next = NULL ;
432 destroy_list( &lp, destroy_packrec ) ; /* destroys just one rec */
433 lp2 = prevlp ;
434 lp = prevlp->next ;
436 else
438 lp2 = lp ;
439 lp = lp->next ;
441 prevlp = lp2 ;
445 process_refs( pack_table, pack_table_size, pack_table_nbytes, collapse )
446 packrec_t ** pack_table ;
447 int * pack_table_size, *pack_table_nbytes, collapse ;
449 /* First sort the primary list, then sort each of the secondary lists
450 in the data structure built by
451 store_process_refs. Finally, go through and collapse them. */
453 int compare_primary(), compare_secondary() ;
454 rsl_list_t * lp, *lp1, *lp2, *lp3 ;
455 packrec_t *x, *y ;
456 int dummy ;
457 int i, nbytes ;
459 #if 0
460 fprintf(stderr,"before sort\n") ;
461 for ( i = 0, lp = list_head ; lp ; lp = lp->next )
463 lp2 = lp->data ;
464 fprintf(stderr,"%d %08x\n", i, ((packrec_t *)(lp2->data))->base) ;
465 i++ ;
467 #endif
469 dummy = 0 ;
470 rsl_sort( &list_head, compare_primary, dummy ) ;
472 /* figure the number of entries */
473 for ( i = 0, lp = list_head ; lp ; lp = lp->next )
474 for ( lp1 = (rsl_list_t *)lp->data ; lp1 ; lp1 = lp1->next )
475 i++ ;
477 for ( lp = list_head ; lp ; lp = lp->next )
479 rsl_sort( &(lp->data), compare_secondary, 99 ) ;
480 #if 1
481 if ( collapse ) collapsetable( &(lp->data) ) ;
482 #endif
485 #if 0
486 for ( i = 0, lp = list_head ; lp ; lp = lp->next )
488 #if 0
489 lp1 = (rsl_list_t *)lp->data ; x = (packrec_t *)lp1->data ;
490 fprintf(stderr,"Entries for base %08x\n", x->base ) ;
491 #endif
492 for ( lp1 = (rsl_list_t *)lp->data ; lp1 ; lp1 = lp1->next )
494 #if 0
495 x = (packrec_t *)lp1->data ;
496 fprintf(stderr," offset %10d %d %4d\n", x->offset, x->f90_table_index,x->n ) ;
497 #endif
498 i++ ;
501 #endif
504 /* figure the number of remaining entries */
505 for ( i = 0, lp = list_head ; lp ; lp = lp->next )
506 for ( lp1 = (rsl_list_t *)lp->data ; lp1 ; lp1 = lp1->next )
507 i++ ;
509 *pack_table_size = i ;
511 #if 0
512 fprintf(stderr,"debug 2 pack_table_size = %d\n",*pack_table_size) ;
513 #endif
515 /* now allocate and populate the table */
516 *pack_table = RSL_MALLOC( packrec_t, *pack_table_size ) ;
517 for ( i = 0, nbytes = 0, lp = list_head ; lp ; lp = lp->next )
518 for ( lp1 = (rsl_list_t *)lp->data ; lp1 ; lp1 = lp1->next )
520 x = (packrec_t *)lp1->data ;
521 nbytes += x->n * x->nelems ;
522 bcopy(lp1->data,&((*pack_table)[i]),sizeof(packrec_t)) ;
523 i++ ;
526 *pack_table_nbytes = nbytes ;
528 return ;