# 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;
}