X-Git-Url: http://nsz.repo.hu/git/?a=blobdiff_plain;ds=sidebyside;f=ir%2Fadt%2Fpdeq.c;h=cc168460e4558ebc179b7f1ab32a5d7860f0ac4f;hb=26b9008643da89a023fd6839ded5b9abf21ef328;hp=642fd355803725759bcbe13c582e52fe6def5e90;hpb=473262b60c2d2ca67fb760998aa1357ba44b5c44;p=libfirm diff --git a/ir/adt/pdeq.c b/ir/adt/pdeq.c index 642fd3558..cc168460e 100644 --- a/ir/adt/pdeq.c +++ b/ir/adt/pdeq.c @@ -22,7 +22,6 @@ * @brief double ended queue of generic pointers. * @author Christian von Roques * @date 1999 by getting from fiasco - * @version $Id$ */ #include "config.h" @@ -34,19 +33,21 @@ #include "fourcc.h" #include "pdeq.h" #include "xmalloc.h" -#include "align.h" /* Pointer Double Ended Queue */ -#define PDEQ_MAGIC1 FOURCC('P','D','E','1') -#define PDEQ_MAGIC2 FOURCC('P','D','E','2') +#define PDEQ_MAGIC1 FOURCC('P','D','E','1') +#define PDEQ_MAGIC2 FOURCC('P','D','E','2') /** Size of pdeq block cache. */ #define TUNE_NSAVED_PDEQS 16 +/** A size handled efficiently by malloc(), at least 1K. */ +#define PREF_MALLOC_SIZE 2048 + /** * Maximal number of data items in a pdeq chunk. */ -#define NDATA ((int)((PREF_MALLOC_SIZE - offsetof (pdeq, data)) / sizeof (void *))) +#define NDATA ((PREF_MALLOC_SIZE - offsetof(pdeq, data)) / sizeof(void *)) #ifdef NDEBUG # define VRFY(dq) ((void)0) @@ -60,21 +61,20 @@ */ struct pdeq { #ifndef NDEBUG - unsigned magic; /**< debug magic */ + unsigned magic; /**< debug magic */ #endif - pdeq *l_end, *r_end; /**< left and right ends of the queue */ - pdeq *l, *r; /**< left and right neighbor */ - int n; /**< number of elements in the current chunk */ - int p; /**< the read/write pointer */ - const void *data[1]; /**< storage for elements */ + pdeq *l_end, *r_end; /**< left and right ends of the queue */ + pdeq *l, *r; /**< left and right neighbor */ + size_t n; /**< number of elements in the current chunk */ + size_t p; /**< the read/write pointer */ + const void *data[1]; /**< storage for elements */ }; /** * cache of unused, pdeq blocks to speed up new_pdeq and del_pdeq. - * +1 for compilers that can't grok empty arrays */ -static pdeq *pdeq_block_cache[TUNE_NSAVED_PDEQS+1]; +static pdeq *pdeq_block_cache[TUNE_NSAVED_PDEQS]; /** * Number of pdeqs in pdeq_store. @@ -89,13 +89,13 @@ static unsigned pdeqs_cached; static inline void free_pdeq_block (pdeq *p) { #ifndef NDEBUG - p->magic = 0xbadf00d1; + p->magic = 0xbadf00d1; #endif - if (pdeqs_cached < TUNE_NSAVED_PDEQS) { - pdeq_block_cache[pdeqs_cached++] = p; - } else { - xfree (p); - } + if (pdeqs_cached < TUNE_NSAVED_PDEQS) { + pdeq_block_cache[pdeqs_cached++] = p; + } else { + xfree (p); + } } /** @@ -105,254 +105,227 @@ static inline void free_pdeq_block (pdeq *p) */ static inline pdeq *alloc_pdeq_block (void) { - pdeq *p; - if (TUNE_NSAVED_PDEQS && pdeqs_cached) { - p = pdeq_block_cache[--pdeqs_cached]; - } else { - p = xmalloc(PREF_MALLOC_SIZE); - } - return p; + pdeq *p; + if (pdeqs_cached > 0) { + p = pdeq_block_cache[--pdeqs_cached]; + } else { + p = (pdeq*) xmalloc(PREF_MALLOC_SIZE); + } + return p; } - -#ifndef NDEBUG -/** - * Verify a double ended list, assert if failure. - * - * @param dq The list to verify. - */ -void _pdeq_vrfy(pdeq *dq) -{ - pdeq *q; - - assert ( dq - && (dq->magic == PDEQ_MAGIC1) - && (dq->l_end && dq->r_end)); - q = dq->l_end; - while (q) { - assert ( ((q == dq) || (q->magic == PDEQ_MAGIC2)) - && ((q == dq->l_end) ^ (q->l != NULL)) - && ((q == dq->r_end) ^ (q->r != NULL)) - && (!q->l || (q == q->l->r)) - && ((q->n >= 0) && (q->n <= NDATA)) - && ((q == dq->l_end) || (q == dq->r_end) || (q->n == NDATA)) - && ((q->p >= 0) && (q->p < NDATA))); - q = q->r; - } -} -#endif - /* Creates a new double ended pointer list. */ pdeq *new_pdeq(void) { - pdeq *dq; + pdeq *dq; - dq = alloc_pdeq_block(); + dq = alloc_pdeq_block(); #ifndef NDEBUG - dq->magic = PDEQ_MAGIC1; + dq->magic = PDEQ_MAGIC1; #endif - dq->l_end = dq->r_end = dq; - dq->l = dq->r = NULL; - dq->n = dq->p = 0; + dq->l_end = dq->r_end = dq; + dq->l = dq->r = NULL; + dq->n = dq->p = 0; - VRFY(dq); - return dq; + VRFY(dq); + return dq; } /* Creates a new double ended pointer list and puts an initial pointer element in. */ pdeq *new_pdeq1(const void *x) { - return pdeq_putr(new_pdeq(), x); + return pdeq_putr(new_pdeq(), x); } /* Delete a double ended pointer list. */ void del_pdeq(pdeq *dq) { - pdeq *q, *qq; - - VRFY(dq); + pdeq *q, *qq; - q = dq->l_end; /* left end of chain */ - /* pdeq trunk empty, but !pdeq_empty() ==> trunk not in chain */ - if (dq->n == 0 && dq->l_end != dq ) { - free_pdeq_block(dq); - } + VRFY(dq); - /* Free all blocks in the pdeq chain */ - do { - qq = q->r; - free_pdeq_block(q); - } while ((q = qq)); + q = dq->l_end; /* left end of chain */ + /* pdeq trunk empty, but !pdeq_empty() ==> trunk not in chain */ + if (dq->n == 0 && dq->l_end != dq ) { + free_pdeq_block(dq); + } + /* Free all blocks in the pdeq chain */ + do { + qq = q->r; + free_pdeq_block(q); + } while ((q = qq)); } /* Checks if a list is empty. */ int pdeq_empty(pdeq *dq) { - VRFY(dq); - return dq->l_end->n == 0; + VRFY(dq); + return dq->l_end->n == 0; } /* Returns the length of a double ended pointer list. */ -int pdeq_len(pdeq *dq) +size_t pdeq_len(pdeq *dq) { - int n; - pdeq *q; + size_t n; + pdeq *q; - VRFY(dq); + VRFY(dq); - n = 0; - q = dq->l_end; - do { - n += q->n; - q = q->r; - } while (q); + n = 0; + q = dq->l_end; + do { + n += q->n; + q = q->r; + } while (q); - return n; + return n; } /* Add a pointer to the right site of a double ended pointer list. */ pdeq *pdeq_putr(pdeq *dq, const void *x) { - pdeq *rdq; - int n; + pdeq *rdq; + size_t n; - VRFY(dq); + VRFY(dq); - rdq = dq->r_end; - if (rdq->n >= NDATA) { /* tailblock full */ - pdeq *ndq; + rdq = dq->r_end; + if (rdq->n >= NDATA) { /* tailblock full */ + pdeq *ndq; - ndq = dq; /* try to reuse trunk, but ... */ - if (dq->n) { /* ... if trunk used */ - /* allocate and init new block */ - ndq = alloc_pdeq_block(); + ndq = dq; /* try to reuse trunk, but ... */ + if (dq->n) { /* ... if trunk used */ + /* allocate and init new block */ + ndq = alloc_pdeq_block(); #ifndef NDEBUG - ndq->magic = PDEQ_MAGIC2; + ndq->magic = PDEQ_MAGIC2; #endif - ndq->l_end = ndq->r_end = NULL; - } + ndq->l_end = ndq->r_end = NULL; + } - ndq->r = NULL; - ndq->l = rdq; rdq->r = ndq; - ndq->n = 0; ndq->p = 0; - dq->r_end = ndq; - rdq = ndq; - } + ndq->r = NULL; + ndq->l = rdq; rdq->r = ndq; + ndq->n = 0; ndq->p = 0; + dq->r_end = ndq; + rdq = ndq; + } - n = rdq->n++ + rdq->p; - if (n >= NDATA) n -= NDATA; + n = rdq->n++ + rdq->p; + if (n >= NDATA) n -= NDATA; - rdq->data[n] = x; + rdq->data[n] = x; - VRFY(dq); - return dq; + VRFY(dq); + return dq; } /* Add a pointer to the left site of a double ended pointer list. */ pdeq *pdeq_putl(pdeq *dq, const void *x) { - pdeq *ldq; - int p; + pdeq *ldq; + size_t p; - VRFY(dq); + VRFY(dq); - ldq = dq->l_end; - if (ldq->n >= NDATA) { /* headblock full */ - pdeq *ndq; + ldq = dq->l_end; + if (ldq->n >= NDATA) { /* headblock full */ + pdeq *ndq; - ndq = dq; /* try to reuse trunk, but ... */ - if (dq->n) { /* ... if trunk used */ - /* allocate and init new block */ - ndq = alloc_pdeq_block(); + ndq = dq; /* try to reuse trunk, but ... */ + if (dq->n) { /* ... if trunk used */ + /* allocate and init new block */ + ndq = alloc_pdeq_block(); #ifndef NDEBUG - ndq->magic = PDEQ_MAGIC2; + ndq->magic = PDEQ_MAGIC2; #endif - ndq->l_end = ndq->r_end = NULL; - } - - ndq->l = NULL; - ndq->r = ldq; ldq->l = ndq; - ndq->n = 0; ndq->p = 0; - dq->l_end = ndq; - ldq = ndq; - } - - ldq->n++; - p = ldq->p - 1; - if (p < 0) p += NDATA; - ldq->p = p; - - ldq->data[p] = x; - - VRFY(dq); - return dq; + ndq->l_end = ndq->r_end = NULL; + } + + ndq->l = NULL; + ndq->r = ldq; ldq->l = ndq; + ndq->n = 0; ndq->p = 0; + dq->l_end = ndq; + ldq = ndq; + } + + ldq->n++; + if (ldq->p == 0) + p = NDATA; + else + p = ldq->p - 1; + ldq->p = p; + + ldq->data[p] = x; + + VRFY(dq); + return dq; } /* Retrieve a pointer from the right site of a double ended pointer list. */ void *pdeq_getr(pdeq *dq) { - pdeq *rdq; - const void *x; - int n; - - VRFY(dq); - assert(dq->l_end->n); - - rdq = dq->r_end; - n = rdq->p + --rdq->n; - if (n >= NDATA) n -= NDATA; - x = rdq->data[n]; - - if (rdq->n == 0) { - if (rdq->l) { - dq->r_end = rdq->l; - rdq->l->r = NULL; - rdq->l = NULL; - } else { - dq->r_end = dq->l_end = dq; - } - if (dq != rdq) { - free_pdeq_block(rdq); - } - } - - VRFY(dq); - return (void *)x; + pdeq *rdq; + const void *x; + size_t n; + + VRFY(dq); + assert(dq->l_end->n); + + rdq = dq->r_end; + n = rdq->p + --rdq->n; + if (n >= NDATA) n -= NDATA; + x = rdq->data[n]; + + if (rdq->n == 0) { + if (rdq->l) { + dq->r_end = rdq->l; + rdq->l->r = NULL; + rdq->l = NULL; + } else { + dq->r_end = dq->l_end = dq; + } + if (dq != rdq) { + free_pdeq_block(rdq); + } + } + + VRFY(dq); + return (void *)x; } /* Retrieve a pointer from the left site of a double ended pointer list. */ void *pdeq_getl(pdeq *dq) { - pdeq *ldq; - const void *x; - int p; - - VRFY(dq); - assert(dq->l_end->n); - - ldq = dq->l_end; - p = ldq->p; - x = ldq->data[p]; - if (++p >= NDATA) p = 0; - ldq->p = p; - - if (--ldq->n == 0) { - if (ldq->r) { - dq->l_end = ldq->r; - ldq->r->l = NULL; - ldq->r = NULL; - } else { - dq->l_end = dq->r_end = dq; - } - if (dq != ldq) { - free_pdeq_block(ldq); - } - } - - VRFY(dq); - return (void *)x; + pdeq *ldq; + const void *x; + size_t p; + + VRFY(dq); + assert(dq->l_end->n); + + ldq = dq->l_end; + p = ldq->p; + x = ldq->data[p]; + if (++p >= NDATA) p = 0; + ldq->p = p; + + if (--ldq->n == 0) { + if (ldq->r) { + dq->l_end = ldq->r; + ldq->r->l = NULL; + ldq->r = NULL; + } else { + dq->l_end = dq->r_end = dq; + } + if (dq != ldq) { + free_pdeq_block(ldq); + } + } + + VRFY(dq); + return (void *)x; } /* @@ -361,32 +334,32 @@ void *pdeq_getl(pdeq *dq) */ int pdeq_contains(pdeq *dq, const void *x) { - pdeq *q; + pdeq *q; - VRFY(dq); + VRFY(dq); - q = dq->l_end; - do { - int p, ep; + q = dq->l_end; + do { + size_t p, ep; - p = q->p; ep = p + q->n; + p = q->p; ep = p + q->n; - if (ep > NDATA) { - do { - if (q->data[p] == x) return 1; - } while (++p < NDATA); - p = 0; - ep -= NDATA; - } + if (ep > NDATA) { + do { + if (q->data[p] == x) return 1; + } while (++p < NDATA); + p = 0; + ep -= NDATA; + } - while (p < ep) { - if (q->data[p++] == x) return 1; - } + while (p < ep) { + if (q->data[p++] == x) return 1; + } - q = q->r; - } while (q); + q = q->r; + } while (q); - return 0; + return 0; } /* @@ -397,33 +370,33 @@ int pdeq_contains(pdeq *dq, const void *x) */ void *pdeq_search(pdeq *dq, cmp_fun cmp, const void *key) { - pdeq *q; - int p; + pdeq *q; + size_t p; - VRFY(dq); + VRFY(dq); - q = dq->l_end; - do { - int ep; + q = dq->l_end; + do { + size_t ep; - p = q->p; ep = p + q->n; + p = q->p; ep = p + q->n; - if (ep > NDATA) { - do { - if (!cmp (q->data[p], key)) return (void *)q->data[p-1]; - } while (++p < NDATA); - p = 0; - ep -= NDATA; - } + if (ep > NDATA) { + do { + if (!cmp(q->data[p], key)) return (void *)q->data[p-1]; + } while (++p < NDATA); + p = 0; + ep -= NDATA; + } - while (p < ep) { - if (!cmp (q->data[p++], key)) return (void *)q->data[p-1]; - } + while (p < ep) { + if (!cmp(q->data[p++], key)) return (void *)q->data[p-1]; + } - q = q->r; - } while (q); + q = q->r; + } while (q); - return NULL; + return NULL; } /* @@ -432,29 +405,30 @@ void *pdeq_search(pdeq *dq, cmp_fun cmp, const void *key) */ void **pdeq_copyl(pdeq *dq, const void **dst) { - pdeq *q; - const void **d = dst; + pdeq *q; + const void **d = dst; - VRFY(dq); + VRFY(dq); - q = dq->l_end; - while (q) { - int p, n; + q = dq->l_end; + while (q) { + size_t p, n; - p = q->p; n = q->n; + p = q->p; n = q->n; - if (n + p > NDATA) { - int nn = NDATA - p; - memcpy((void *) d, &q->data[p], nn * sizeof(void *)); d += nn; - p = 0; n -= nn; - } + if (n + p > NDATA) { + /* p is always < NDATA */ + size_t nn = NDATA - p; + memcpy((void *) d, &q->data[p], nn * sizeof(void *)); d += nn; + p = 0; n -= nn; + } - memcpy((void *) d, &q->data[p], n * sizeof(void *)); d += n; + memcpy((void *) d, &q->data[p], n * sizeof(void *)); d += n; - q = q->r; - } + q = q->r; + } - return (void **)dst; + return (void **)dst; } /* @@ -463,26 +437,34 @@ void **pdeq_copyl(pdeq *dq, const void **dst) */ void **pdeq_copyr(pdeq *dq, const void **dst) { - pdeq *q; - const void **d = dst; - - VRFY(dq); - - q = dq->r_end; - while (q) { - int p, i; - - p = q->p; i = q->n + p - 1; - if (i >= NDATA) { - i -= NDATA; - do *d++ = q->data[i]; while (--i >= 0); - i = NDATA - 1; - } - - do *d++ = q->data[i]; while (--i >= p); - - q = q->l; - } - - return (void **)dst; + pdeq *q; + const void **d = dst; + + VRFY(dq); + + q = dq->r_end; + while (q) { + size_t p, i; + + p = q->p; i = q->n + p - 1; + if (i >= NDATA) { + i -= NDATA; + for (;; --i) { + *d++ = q->data[i]; + if (i == 0) + break; + } + i = NDATA - 1; + } + + for (;; --i) { + *d++ = q->data[i]; + if (i <= p) + break; + } + + q = q->l; + } + + return (void **)dst; }