harec

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs | README | LICENSE

commit 031a921a7b929d8517d720cadf04c9c4e7da3148
parent 2773bd15433e9134c064bae8fc98c009c6a19d05
Author: Drew DeVault <sir@cmpwn.com>
Date:   Fri, 25 Dec 2020 16:18:54 -0500

gen: introduce function prelude, rehome allocations

This isn't super important now, but it'll matter later when we introduce
loops & branches and such what.

Diffstat:
Minclude/qbe.h | 11++++++++---
Msrc/emit.c | 9+++++++--
Msrc/gen.c | 10++++++----
Msrc/qbe.c | 36++++++++++++++++++++++++------------
4 files changed, 45 insertions(+), 21 deletions(-)

diff --git a/include/qbe.h b/include/qbe.h @@ -175,11 +175,15 @@ struct qbe_func_param { struct qbe_func_param *next; }; +struct qbe_statements { + size_t ln, sz; + struct qbe_statement *stmts; +}; + struct qbe_func { const struct qbe_type *returns; struct qbe_func_param *params; - size_t blen, bsiz; - struct qbe_statement *body; + struct qbe_statements prelude, body; }; enum qbe_deftype { @@ -207,9 +211,10 @@ void qbe_append_def(struct qbe_program *prog, struct qbe_def *def); void geni(struct qbe_statement *stmt, const struct qbe_value *out, enum qbe_instr instr, ...); const char *genl(struct qbe_statement *stmt, uint64_t *id, const char *fmt); void pushi(struct qbe_func *func, const struct qbe_value *out, enum qbe_instr instr, ...); +void pushprei(struct qbe_func *func, const struct qbe_value *out, enum qbe_instr instr, ...); const char *pushl(struct qbe_func *func, uint64_t *id, const char *fmt); void pushc(struct qbe_func *func, const char *fmt, ...); -void push(struct qbe_func *func, struct qbe_statement *stmt); +void push(struct qbe_statements *stmts, struct qbe_statement *stmt); struct qbe_value *qval_dup(const struct qbe_value *val); diff --git a/src/emit.c b/src/emit.c @@ -147,8 +147,13 @@ emit_func(struct qbe_def *def, FILE *out) } fprintf(out, ") {\n"); - for (size_t i = 0; i < def->func.blen; ++i) { - struct qbe_statement *stmt = &def->func.body[i]; + for (size_t i = 0; i < def->func.prelude.ln; ++i) { + struct qbe_statement *stmt = &def->func.prelude.stmts[i]; + emit_stmt(stmt, out); + } + + for (size_t i = 0; i < def->func.body.ln; ++i) { + struct qbe_statement *stmt = &def->func.body.stmts[i]; emit_stmt(stmt, out); } diff --git a/src/gen.c b/src/gen.c @@ -56,7 +56,7 @@ alloc_temp(struct gen_context *ctx, struct qbe_value *val, struct qbe_value size; constl(&size, type->size); - pushi(ctx->current, val, alloc_for_align(type->align), &size, NULL); + pushprei(ctx->current, val, alloc_for_align(type->align), &size, NULL); } static struct gen_binding * @@ -315,7 +315,7 @@ gen_call(struct gen_context *ctx, next = &arg->next; } - push(ctx->current, &call); + push(&ctx->current->body, &call); } static void @@ -555,7 +555,9 @@ gen_function_decl(struct gen_context *ctx, const struct declaration *decl) qdef->func.returns = qtype_for_type(ctx, fntype->func.result, false); ctx->current = &qdef->func; - pushl(&qdef->func, &ctx->id, "start.%d"); + struct qbe_statement start_label = {0}; + genl(&start_label, &ctx->id, "start.%d"); + push(&qdef->func.prelude, &start_label); struct qbe_func_param *param, **next = &qdef->func.params; struct scope_object *obj = decl->func.scope->objects; @@ -600,7 +602,7 @@ gen_function_decl(struct gen_context *ctx, const struct declaration *decl) pushl(&qdef->func, &ctx->id, "body.%d"); gen_expression(ctx, func->body, ctx->return_value); - push(&qdef->func, &end_label); + push(&qdef->func.body, &end_label); if (fntype->func.result->storage != TYPE_STORAGE_VOID) { struct qbe_value load = {0}; diff --git a/src/qbe.c b/src/qbe.c @@ -209,18 +209,18 @@ genl(struct qbe_statement *stmt, uint64_t *id, const char *fmt) } void -push(struct qbe_func *func, struct qbe_statement *stmt) +push(struct qbe_statements *stmts, struct qbe_statement *stmt) { - if (!func->body) { - func->bsiz = 256; - func->blen = 0; - func->body = xcalloc(1, sizeof(struct qbe_statement) * func->bsiz); + if (!stmts->stmts) { + stmts->sz = 256; + stmts->ln = 0; + stmts->stmts = xcalloc(1, sizeof(struct qbe_statement) * stmts->sz); } - if (func->blen + 1 < func->bsiz) { - func->bsiz *= 2; - func->body = xrealloc(func->body, func->bsiz); + if (stmts->ln + 1 < stmts->sz) { + stmts->sz *= 2; + stmts->stmts = xrealloc(stmts->stmts, stmts->sz); } - func->body[func->blen++] = *stmt; + stmts->stmts[stmts->ln++] = *stmt; } void @@ -232,7 +232,19 @@ pushi(struct qbe_func *func, const struct qbe_value *out, va_start(ap, instr); va_geni(&stmt, instr, out, ap); va_end(ap); - push(func, &stmt); + push(&func->body, &stmt); +} + +void +pushprei(struct qbe_func *func, const struct qbe_value *out, + enum qbe_instr instr, ...) +{ + struct qbe_statement stmt = {0}; + va_list ap; + va_start(ap, instr); + va_geni(&stmt, instr, out, ap); + va_end(ap); + push(&func->prelude, &stmt); } const char * @@ -240,7 +252,7 @@ pushl(struct qbe_func *func, uint64_t *id, const char *fmt) { struct qbe_statement stmt = {0}; const char *l = genl(&stmt, id, fmt); - push(func, &stmt); + push(&func->body, &stmt); return l; } @@ -260,7 +272,7 @@ pushc(struct qbe_func *func, const char *fmt, ...) va_end(ap); stmt.comment = str; - push(func, &stmt); + push(&func->body, &stmt); } void