harec

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

commit 34c063ebdda44768262a2ecae2cb3b4f320f8c8b
parent 70cd7548e3cea3bf2b326c1328879912de348d99
Author: Drew DeVault <sir@cmpwn.com>
Date:   Thu,  8 Jul 2021 17:02:21 -0400

gen: emit memcpy for initializing large arrays

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

Diffstat:
Msrc/gen.c | 40++++++++++++++++++++++++++++------------
Mtests/01-arrays.ha | 9+++++++++
2 files changed, 37 insertions(+), 12 deletions(-)

diff --git a/src/gen.c b/src/gen.c @@ -1599,19 +1599,35 @@ gen_array(struct gen_context *ctx, } pushc(ctx->current, "expanding array to length %zd", type->array.length); - struct qbe_value last = {0}; - if (type_is_aggregate(type->array.members)) { - alloc_temp(ctx, &last, type->array.members, "expand.%d"); - qval_deref(&last); + if (type->array.length < 16) { + struct qbe_value last = {0}; + if (type_is_aggregate(type->array.members)) { + alloc_temp(ctx, &last, type->array.members, "expand.%d"); + qval_deref(&last); + } else { + gen_temp(ctx, &last, + qtype_for_type(ctx, type->array.members, false), + "expand.%d"); + } + gen_load(ctx, &last, &val, type_is_signed(type->array.members)); + for (; n < type->array.length; ++n) { + pushi(ctx->current, &ptr, Q_ADD, &ptr, &size, NULL); + gen_store(ctx, &val, &last); + } } else { - gen_temp(ctx, &last, - qtype_for_type(ctx, type->array.members, false), - "expand.%d"); - } - gen_load(ctx, &last, &val, type_is_signed(type->array.members)); - for (; n < type->array.length; ++n) { - pushi(ctx->current, &ptr, Q_ADD, &ptr, &size, NULL); - gen_store(ctx, &val, &last); + struct qbe_value totalsize = {0}; + constl(&totalsize, (type->array.length - n) * type->array.members->size); + struct qbe_value offset = {0}; + gen_temp(ctx, &offset, &qbe_long, "ptr.%d"); + pushi(ctx->current, &offset, Q_ADD, &val, &size, NULL); + val.type = &qbe_long; + + struct qbe_value rtmemcpy = {0}; + rtmemcpy.kind = QV_GLOBAL; + rtmemcpy.name = strdup("rt.memcpy"); + rtmemcpy.type = &qbe_long; + pushi(ctx->current, NULL, Q_CALL, &rtmemcpy, + &offset, &val, &totalsize, NULL); } } diff --git a/tests/01-arrays.ha b/tests/01-arrays.ha @@ -82,6 +82,15 @@ fn expanded() void = { for (let i = 0z; i < len(c); i += 1) { assert(c[i] == expected[i]); }; + + let q: [65535]int = [1, 2, 3...]; + let expected = [1, 2, 3]; + for (let i = 0z; i < len(expected); i += 1) { + assert(q[i] == expected[i]); + }; + for (let i = 3z; i < len(q); i += 1) { + assert(q[i] == 3); + }; }; fn extype() void = {