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" */
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 */
18 static rsl_list_t
* list_head
= NULL
;
20 static int destroy_packrec( p
) packrec_t
* p
; { free( p
) ; return(0) ;}
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
) ;
35 If primary list is allocated and has entries assigned, free all data
36 allocated on secondary lists by reseting variable 'nsec' to zero.
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 */
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-> ...
62 | base,off,n base,off,n base,off,n ...
64 list_t -d-> list_t -n-> list_t -n-> list_t -n-> ...
68 | base,off,n base,off,n base,off,n ...
70 list_t -d-> list_t -n-> list_t -n-> list_t -n-> ...
74 | base,off,n base,off,n base,off,n ...
81 store_process_refs( base
, f90_table_index
, offset
, n
, nelems
, stride
)
89 rsl_list_t
* lp
, *lp1
, *lp2
, *lp3
, *lp4
;
91 packrec_t
* newrec
, *arec
, *nextrec
;
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") ;
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
) ;
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
;
121 newrec
->nelems
= nelems
;
122 newrec
->stride
= stride
;
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. */
133 for ( ipri
= 0 ; ipri
< npri
; ipri
++ )
135 if ( base
== Pri_lst
[ipri
].base
)
143 /* Quick search to see whether this is a duplicate call. */
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 */
156 if ( Pri_lst
[ipri
].n
[isec
] < n
)
158 Pri_lst
[ipri
].n
[isec
] = n
;
159 Pri_lst
[ipri
].data
[isec
]->n
= n
;
166 for ( lp
= list_head
; lp
; lp
= lp
->next
)
169 if ((lp1
= (rsl_list_t
*)lp
->data
) != NULL
)
170 if ((arec
= (packrec_t
*) lp1
->data
) != NULL
)
171 if ( arec
->base
== base
)
179 x
= RSL_MALLOC( rsl_list_t
, 1 ) ;
180 x
->next
= list_head
;
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
;
188 /* includes an insertion sort */
191 for ( lp2
= lp1
; lp2
!= NULL
; lp2
= lp2
->next
)
193 lp3
= lp2
; /* store previous lp2 */
194 arec
= (packrec_t
*) lp2
->data
;
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 ; }
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 ; }
221 for ( lp2
= lp1
; lp2
!= NULL
; lp2
= lp2
->next
)
223 lp3
= lp2
; /* store previous lp2 */
224 arec
= (packrec_t
*) lp2
->data
;
228 if ( offset
< arec
->offset
)
229 { found1
= 0 ; break ; }
231 if (offset
== arec
->offset
)
234 { found1
= 1 ; break ; }
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 )
257 for ( ipri
= 0, pri_found
= 0 ; ipri
< npri
; ipri
++ )
259 if ( Pri_lst
[ipri
].base
== base
)
268 if ( npri
== max_npri
)
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
;
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") ;
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
++ ;
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
;
312 if ( found1
== 2 ) /* insert after this element */
314 lp4
= RSL_MALLOC( rsl_list_t
, 1 ) ;
316 lp4
->next
= lp2
->next
;
322 static int compare_primary( lp1
, lp2
, dummy
)
323 rsl_list_t
*lp1
, *lp2
;
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
)
338 RSL_TEST_ERR(1,"compare_primary 2") ;
341 RSL_TEST_ERR(1, "compare_primary 1" ) ;
345 static int compare_secondary( a
, b
, dummy
)
349 if ( a
!= NULL
&& b
!= NULL
)
350 if (a
->offset
> b
->offset
)
355 static int collapsetable( lst
)
358 rsl_list_t
* lp
, * lp2
, * prevlp
;
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
)
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 ;
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 */
410 bigstride
= y
->offset
- x
->offset
;
412 if ( bigstride
<= x
->n
) break ;
413 if ( y
->offset
- x
->offset
== bigstride
)
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
;
432 destroy_list( &lp
, destroy_packrec
) ; /* destroys just one rec */
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
;
460 fprintf(stderr
,"before sort\n") ;
461 for ( i
= 0, lp
= list_head
; lp
; lp
= lp
->next
)
464 fprintf(stderr
,"%d %08x\n", i
, ((packrec_t
*)(lp2
->data
))->base
) ;
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
)
477 for ( lp
= list_head
; lp
; lp
= lp
->next
)
479 rsl_sort( &(lp
->data
), compare_secondary
, 99 ) ;
481 if ( collapse
) collapsetable( &(lp
->data
) ) ;
486 for ( i
= 0, lp
= list_head
; lp
; lp
= lp
->next
)
489 lp1
= (rsl_list_t
*)lp
->data
; x
= (packrec_t
*)lp1
->data
;
490 fprintf(stderr
,"Entries for base %08x\n", x
->base
) ;
492 for ( lp1
= (rsl_list_t
*)lp
->data
; lp1
; lp1
= lp1
->next
)
495 x
= (packrec_t
*)lp1
->data
;
496 fprintf(stderr
," offset %10d %d %4d\n", x
->offset
, x
->f90_table_index
,x
->n
) ;
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
)
509 *pack_table_size
= i
;
512 fprintf(stderr
,"debug 2 pack_table_size = %d\n",*pack_table_size
) ;
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
)) ;
526 *pack_table_nbytes
= nbytes
;