# New Ticket Created by  Leopold Toetsch 
# Please include the string:  [perl #37760]
# in the subject line of all future correspondence about this issue. 
# <URL: https://rt.perl.org/rt3/Ticket/Display.html?id=37760 >


imcc has a lot of structure items, which are quite similar. All these 
consist of an item count and a list of items. E.g.

   imcc/unit.h

   struct _IMC_Unit {
      ...
      int n_basic_blocks;
      Basic_block **bb_list;

or

   imcc/symreg.h

   struct pcc_sub_t {
      ...
      int nargs;
      SymReg **args;
      int *arg_flags;   // these 2 should be just one item

There are about 10 such lists around, which could be unified easily. The 
current code is suboptimal anyway, because resizing is done by 1 mostly.
Some of the lists allocate ptr space and items, which can also be 
simplified and reduces indirection by one.

Therefore the job would be to replace *gradually* all these lists by a 
common interface.

Attached is an *example*, how this could look like. Basically just some 
macros that replace the current code.

Takers wanted & thanks,
leo
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>

typedef struct {
    int a;
    int b;
} foo_t;

#define ITEM_LIST(ITEM, LIST) struct { \
    int n; \
    ITEM *items; \
} LIST

#define MAKE_ITEM_LIST(ITEM, LIST) \
    LIST.n = 0; \
    LIST.items = malloc(8 * sizeof(ITEM))

#define ITEM_PTR_ADD(ITEM, LIST, PTR) \
    if ((LIST.n & 7) == 7) { \
	int n = LIST.n + 1; \
	n = ((n >> 3) + 1) << 3; \
	LIST.items = realloc(LIST.items, n * sizeof(ITEM)); \
    } \
    PTR = ITEM_PTR(ITEM, LIST, LIST.n++)

#define ITEMS(LIST) LIST.n

#define FREE_ITEM_LIST(LIST) free(LIST.items); LIST.items = NULL

#define ITEM_PTR(ITEM, LIST, N) \
    &LIST.items[N]


struct bar_t {
    int x;
    ITEM_LIST(foo_t, foo_list);
};

int main(int argc, char *argv[])
{
    ITEM_LIST(foo_t, foo_list);
    int i;
    foo_t *fp;
    struct bar_t * bp;

    MAKE_ITEM_LIST(foo_t, foo_list);
    for (i = 0; i < 20; ++i) {
	ITEM_PTR_ADD(foo_t, foo_list, fp);
	fp->a = i;
    }
    for (i = 0; i < ITEMS(foo_list); ++i) {
	fp = ITEM_PTR(foo_t, foo_list, i);
	printf("item at %d = %d\n", i, fp->a);
    }

    bp = malloc(sizeof(struct bar_t));
    MAKE_ITEM_LIST(foo_t, bp->foo_list);
    for (i = 0; i < 20; ++i) {
	ITEM_PTR_ADD(foo_t, bp->foo_list, fp);
	fp->a = i * 2;
    }
    for (i = 0; i < ITEMS(bp->foo_list); ++i) {
	fp = ITEM_PTR(foo_t, bp->foo_list, i);
	printf("item at %d = %d\n", i, fp->a);
    }
    FREE_ITEM_LIST(foo_list);
    FREE_ITEM_LIST(bp->foo_list);
    free(bp);
    return 0;
}

Reply via email to