~mcf/cproc

098957b65500aa13005c540cf33a6e28c71cb153 — Michael Forney 2 years ago 5eb638e
init: Improve parseinit performance for sequential initializers

Now, we only traverse the current initializer list to find the place to
insert a designated initializer. Regular initializers always go after
the previous one.

Fixes #37.
1 files changed, 10 insertions(+), 5 deletions(-)

M init.c
M init.c => init.c +10 -5
@@ 22,6 22,7 @@ struct initparser {
	/* TODO: keep track of type depth, and allocate maximum possible
	   number of nested objects in initializer */
	struct object obj[32], *cur, *sub;
	struct init *init, **last;
};

struct init *


@@ 39,10 40,11 @@ mkinit(uint64_t start, uint64_t end, struct expr *expr)
}

static void
initadd(struct init **init, struct init *new)
initadd(struct initparser *p, struct init *new)
{
	struct init *old;
	struct init **init, *old;

	init = p->last;
	for (; old = *init; init = &old->next) {
		if (new->start >= old->end)
			continue;


@@ 59,6 61,7 @@ initadd(struct init **init, struct init *new)
	}
	new->next = old;
	*init = new;
	p->last = &new->next;
}

static void


@@ 111,6 114,7 @@ designator(struct scope *s, struct initparser *p)
	struct type *t;
	char *name;

	p->last = &p->init;
	p->sub = p->cur;
	for (;;) {
		t = p->sub->type;


@@ 208,7 212,6 @@ struct init *
parseinit(struct scope *s, struct type *t)
{
	struct initparser p;
	struct init *init = NULL;
	struct expr *expr;
	struct type *base;



@@ 217,6 220,8 @@ parseinit(struct scope *s, struct type *t)
	p.sub->offset = 0;
	p.sub->type = t;
	p.sub->iscur = false;
	p.init = NULL;
	p.last = &p.init;
	if (t->incomplete && !(t->kind == TYPEARRAY && t->array.length == 0))
		error(&tok.loc, "initializer specified for incomplete type");
	for (;;) {


@@ 270,12 275,12 @@ parseinit(struct scope *s, struct type *t)
			if ((t->kind == TYPESTRUCT || t->kind == TYPEUNION) && isbitfield(p.sub[-1].mem))
				error(&tok.loc, "bit-field initializers are not yet supported");
		}
		initadd(&init, mkinit(p.sub->offset, p.sub->offset + p.sub->type->size, expr));
		initadd(&p, mkinit(p.sub->offset, p.sub->offset + p.sub->type->size, expr));
		for (;;) {
			if (p.sub->type->kind == TYPEARRAY && p.sub->type->incomplete)
				p.sub->type->incomplete = false;
			if (!p.cur)
				return init;
				return p.init;
			if (tok.kind == TCOMMA) {
				next();
				if (tok.kind != TRBRACE)