aboutsummaryrefslogtreecommitdiff
path: root/src/analyze.cpp
diff options
context:
space:
mode:
authorAndrew Kelley <andrew@ziglang.org>2019-09-10 22:59:00 -0400
committerAndrew Kelley <andrew@ziglang.org>2019-09-10 22:59:00 -0400
commitc9b2210fcf58d9e99851ad2a6a1219c997cf0d82 (patch)
treeb4976b37d6a29279abf003ffff47fe58707db169 /src/analyze.cpp
parent7101e583d6a752fa1145c13c6e1a58f36bd35f2d (diff)
downloadzig-c9b2210fcf58d9e99851ad2a6a1219c997cf0d82.tar.gz
zig-c9b2210fcf58d9e99851ad2a6a1219c997cf0d82.zip
async function calls re-use frame buffers
See #3069
Diffstat (limited to 'src/analyze.cpp')
-rw-r--r--src/analyze.cpp23
1 files changed, 21 insertions, 2 deletions
diff --git a/src/analyze.cpp b/src/analyze.cpp
index 4347f06699..946bbd17ae 100644
--- a/src/analyze.cpp
+++ b/src/analyze.cpp
@@ -2538,6 +2538,8 @@ static Error resolve_enum_zero_bits(CodeGen *g, ZigType *enum_type) {
enum_type->data.enumeration.resolve_loop_flag = false;
enum_type->data.enumeration.resolve_status = ResolveStatusSizeKnown;
+ occupied_tag_values.deinit();
+
return ErrorNone;
}
@@ -5878,6 +5880,11 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
fn->err_code_spill = &alloca_gen->base;
}
+ ZigType *largest_call_frame_type = nullptr;
+ // Later we'll change this to be largest_call_frame_type instead of void.
+ IrInstruction *all_calls_alloca = ir_create_alloca(g, &fn->fndef_scope->base, fn->body_node,
+ fn, g->builtin_types.entry_void, "@async_call_frame");
+
for (size_t i = 0; i < fn->call_list.length; i += 1) {
IrInstructionCallGen *call = fn->call_list.at(i);
if (call->new_stack != nullptr) {
@@ -5921,9 +5928,21 @@ static Error resolve_async_frame(CodeGen *g, ZigType *frame_type) {
mark_suspension_point(call->base.scope);
- call->frame_result_loc = ir_create_alloca(g, call->base.scope, call->base.source_node, fn,
- callee_frame_type, "");
+ if ((err = type_resolve(g, callee_frame_type, ResolveStatusSizeKnown))) {
+ return err;
+ }
+ if (largest_call_frame_type == nullptr ||
+ callee_frame_type->abi_size > largest_call_frame_type->abi_size)
+ {
+ largest_call_frame_type = callee_frame_type;
+ }
+
+ call->frame_result_loc = all_calls_alloca;
}
+ if (largest_call_frame_type != nullptr) {
+ all_calls_alloca->value.type = get_pointer_to_type(g, largest_call_frame_type, false);
+ }
+
// Since this frame is async, an await might represent a suspend point, and
// therefore need to spill. It also needs to mark expr scopes as having to spill.
// For example: foo() + await z