harec

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

commit cffdad98039c202e0c2e39bbf952dfdf6b26f0ab
parent 3520ab2c1510f12b066ab1d1dafcdba6abf2435b
Author: Drew DeVault <sir@cmpwn.com>
Date:   Thu,  5 Aug 2021 09:48:09 +0200

gen: commoditize branch consolidation

Signed-off-by: Drew DeVault <sir@cmpwn.com>

Diffstat:
Minclude/gen.h | 2++
Msrc/gen.c | 16++++------------
Msrc/genutil.c | 17+++++++++++++++++
3 files changed, 23 insertions(+), 12 deletions(-)

diff --git a/include/gen.h b/include/gen.h @@ -74,6 +74,8 @@ struct qbe_value mkqtmp(struct gen_context *ctx, struct qbe_value mkrtfunc(struct gen_context *ctx, const char *name); struct qbe_value mklabel(struct gen_context *ctx, struct qbe_statement *stmt, const char *fmt); +void branch_copyresult(struct gen_context *ctx, struct gen_value result, + struct gen_value merged, struct gen_value *out); // qinstr.c enum qbe_instr alloc_for_align(size_t align); diff --git a/src/gen.c b/src/gen.c @@ -537,10 +537,8 @@ gen_expr_if_with(struct gen_context *ctx, struct gen_value *out) { struct gen_value gvout = gv_void; - struct qbe_value qvout; if (!out && type_dealias(expr->result)->storage != STORAGE_VOID) { gvout = mktemp(ctx, expr->result, ".%d"); - qvout = mkqval(ctx, &gvout); } struct qbe_statement ltrue, lfalse, lend; @@ -553,20 +551,14 @@ gen_expr_if_with(struct gen_context *ctx, push(&ctx->current->body, &ltrue); struct gen_value vtrue = gen_expr_with(ctx, expr->_if.true_branch, out); - if (!out && type_dealias(expr->result)->storage != STORAGE_VOID) { - struct qbe_value qvtrue = mkqval(ctx, &vtrue); - pushi(ctx->current, &qvout, Q_COPY, &qvtrue, NULL); - } + branch_copyresult(ctx, vtrue, gvout, out); pushi(ctx->current, NULL, Q_JMP, &bend, NULL); push(&ctx->current->body, &lfalse); if (expr->_if.false_branch) { - struct gen_value vfalse = gen_expr_with( - ctx, expr->_if.false_branch, out); - if (!out && type_dealias(expr->result)->storage != STORAGE_VOID) { - struct qbe_value qvfalse = mkqval(ctx, &vfalse); - pushi(ctx->current, &qvout, Q_COPY, &qvfalse, NULL); - } + struct gen_value vfalse = gen_expr_with(ctx, + expr->_if.false_branch, out); + branch_copyresult(ctx, vfalse, gvout, out); } push(&ctx->current->body, &lend); diff --git a/src/genutil.c b/src/genutil.c @@ -92,3 +92,20 @@ mklabel(struct gen_context *ctx, struct qbe_statement *stmt, const char *fmt) val.name = strdup(genl(stmt, &ctx->id, fmt)); return val; } + +void +branch_copyresult(struct gen_context *ctx, + struct gen_value result, + struct gen_value merged, + struct gen_value *out) +{ + // Branching expressions written in the _with style may need to + // consolodate each branch's result into a single temporary to return to + // the caller. This function facilitates that. + if (out || type_dealias(result.type)->storage == STORAGE_VOID) { + return; + } + struct qbe_value qmerged = mkqval(ctx, &merged); + struct qbe_value qval = mkqval(ctx, &result); + pushi(ctx->current, &qmerged, Q_COPY, &qval, NULL); +}