Skip to content

Commit ca1b77b

Browse files
committed
IR analysis for coro.begin
See #727
1 parent 88e7b9b commit ca1b77b

File tree

4 files changed

+84
-7
lines changed

4 files changed

+84
-7
lines changed

src/all_types.hpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1490,6 +1490,7 @@ struct CodeGen {
14901490
TypeTableEntry *entry_u8;
14911491
TypeTableEntry *entry_u16;
14921492
TypeTableEntry *entry_u32;
1493+
TypeTableEntry *entry_u29;
14931494
TypeTableEntry *entry_u64;
14941495
TypeTableEntry *entry_u128;
14951496
TypeTableEntry *entry_i8;
@@ -1966,6 +1967,7 @@ enum IrInstructionId {
19661967
IrInstructionIdCoroAlloc,
19671968
IrInstructionIdCoroSize,
19681969
IrInstructionIdCoroBegin,
1970+
IrInstructionIdCoroAllocFail,
19691971
};
19701972

19711973
struct IrInstruction {
@@ -2836,6 +2838,12 @@ struct IrInstructionCoroBegin {
28362838
IrInstruction *coro_mem_ptr;
28372839
};
28382840

2841+
struct IrInstructionCoroAllocFail {
2842+
IrInstruction base;
2843+
2844+
IrInstruction *err_val;
2845+
};
2846+
28392847
static const size_t slice_ptr_index = 0;
28402848
static const size_t slice_len_index = 1;
28412849

src/codegen.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3712,6 +3712,9 @@ static LLVMValueRef ir_render_coro_begin(CodeGen *g, IrExecutable *executable, I
37123712
zig_panic("TODO ir_render_coro_begin");
37133713
}
37143714

3715+
static LLVMValueRef ir_render_coro_alloc_fail(CodeGen *g, IrExecutable *executable, IrInstructionCoroAllocFail *instruction) {
3716+
zig_panic("TODO ir_render_coro_alloc_fail");
3717+
}
37153718

37163719
static void set_debug_location(CodeGen *g, IrInstruction *instruction) {
37173720
AstNode *source_node = instruction->source_node;
@@ -3906,6 +3909,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
39063909
return ir_render_coro_size(g, executable, (IrInstructionCoroSize *)instruction);
39073910
case IrInstructionIdCoroBegin:
39083911
return ir_render_coro_begin(g, executable, (IrInstructionCoroBegin *)instruction);
3912+
case IrInstructionIdCoroAllocFail:
3913+
return ir_render_coro_alloc_fail(g, executable, (IrInstructionCoroAllocFail *)instruction);
39093914
}
39103915
zig_unreachable();
39113916
}
@@ -5282,6 +5287,7 @@ static void define_builtin_types(CodeGen *g) {
52825287

52835288
g->builtin_types.entry_u8 = get_int_type(g, false, 8);
52845289
g->builtin_types.entry_u16 = get_int_type(g, false, 16);
5290+
g->builtin_types.entry_u29 = get_int_type(g, false, 29);
52855291
g->builtin_types.entry_u32 = get_int_type(g, false, 32);
52865292
g->builtin_types.entry_u64 = get_int_type(g, false, 64);
52875293
g->builtin_types.entry_u128 = get_int_type(g, false, 128);

src/ir.cpp

Lines changed: 61 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -668,6 +668,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroBegin *) {
668668
return IrInstructionIdCoroBegin;
669669
}
670670

671+
static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroAllocFail *) {
672+
return IrInstructionIdCoroAllocFail;
673+
}
674+
671675
template<typename T>
672676
static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {
673677
T *special_instruction = allocate<T>(1);
@@ -810,6 +814,14 @@ static IrInstruction *ir_build_const_usize(IrBuilder *irb, Scope *scope, AstNode
810814
return &const_instruction->base;
811815
}
812816

817+
static IrInstruction *ir_build_const_u29(IrBuilder *irb, Scope *scope, AstNode *source_node, uint32_t value) {
818+
IrInstructionConst *const_instruction = ir_build_instruction<IrInstructionConst>(irb, scope, source_node);
819+
const_instruction->base.value.type = irb->codegen->builtin_types.entry_u29;
820+
const_instruction->base.value.special = ConstValSpecialStatic;
821+
bigint_init_unsigned(&const_instruction->base.value.data.x_bigint, value);
822+
return &const_instruction->base;
823+
}
824+
813825
static IrInstruction *ir_create_const_type(IrBuilder *irb, Scope *scope, AstNode *source_node,
814826
TypeTableEntry *type_entry)
815827
{
@@ -2471,6 +2483,17 @@ static IrInstruction *ir_build_coro_begin(IrBuilder *irb, Scope *scope, AstNode
24712483
return &instruction->base;
24722484
}
24732485

2486+
static IrInstruction *ir_build_coro_alloc_fail(IrBuilder *irb, Scope *scope, AstNode *source_node, IrInstruction *err_val) {
2487+
IrInstructionCoroAllocFail *instruction = ir_build_instruction<IrInstructionCoroAllocFail>(irb, scope, source_node);
2488+
instruction->base.value.type = irb->codegen->builtin_types.entry_unreachable;
2489+
instruction->base.value.special = ConstValSpecialStatic;
2490+
instruction->err_val = err_val;
2491+
2492+
ir_ref_instruction(err_val, irb->current_basic_block);
2493+
2494+
return &instruction->base;
2495+
}
2496+
24742497
static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) {
24752498
results[ReturnKindUnconditional] = 0;
24762499
results[ReturnKindError] = 0;
@@ -5854,23 +5877,22 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
58545877
Buf *alloc_field_name = buf_create_from_str(ASYNC_ALLOC_FIELD_NAME);
58555878
IrInstruction *alloc_fn_ptr = ir_build_field_ptr(irb, scope, node, implicit_allocator_ptr, alloc_field_name);
58565879
IrInstruction *alloc_fn = ir_build_load_ptr(irb, scope, node, alloc_fn_ptr);
5857-
IrInstruction *implicit_allocator = ir_build_load_ptr(irb, scope, node, implicit_allocator_ptr);
5858-
IrInstruction *alignment = ir_build_const_usize(irb, scope, node, irb->codegen->pointer_size_bytes * 2);
5880+
IrInstruction *alignment = ir_build_const_u29(irb, scope, node, irb->codegen->pointer_size_bytes * 2);
58595881
size_t arg_count = 3;
58605882
IrInstruction **args = allocate<IrInstruction *>(arg_count);
5861-
args[0] = implicit_allocator; // self
5883+
args[0] = implicit_allocator_ptr; // self
58625884
args[1] = coro_size; // byte_count
58635885
args[2] = alignment; // alignment
58645886
IrInstruction *alloc_result = ir_build_call(irb, scope, node, nullptr, alloc_fn, arg_count, args, false, FnInlineAuto, false, nullptr);
58655887
IrInstruction *alloc_result_ptr = ir_build_ref(irb, scope, node, alloc_result, true, false);
5866-
IrInstruction *alloc_result_is_err = ir_build_test_err(irb, scope, node, alloc_result_ptr);
5888+
IrInstruction *alloc_result_is_err = ir_build_test_err(irb, scope, node, alloc_result);
58675889
IrBasicBlock *alloc_err_block = ir_create_basic_block(irb, scope, "AllocError");
58685890
IrBasicBlock *alloc_ok_block = ir_create_basic_block(irb, scope, "AllocOk");
58695891
ir_build_cond_br(irb, scope, node, alloc_result_is_err, alloc_err_block, alloc_ok_block, is_comptime_false);
58705892

58715893
ir_set_cursor_at_end_and_append_block(irb, alloc_err_block);
58725894
IrInstruction *err_val = ir_build_unwrap_err_code(irb, scope, node, alloc_result_ptr);
5873-
ir_build_return(irb, scope, node, err_val);
5895+
ir_build_coro_alloc_fail(irb, scope, node, err_val);
58745896

58755897
ir_set_cursor_at_end_and_append_block(irb, alloc_ok_block);
58765898
IrInstruction *unwrapped_mem_ptr = ir_build_unwrap_err_payload(irb, scope, node, alloc_result_ptr, false);
@@ -16826,18 +16848,47 @@ static TypeTableEntry *ir_analyze_instruction_coro_alloc(IrAnalyze *ira, IrInstr
1682616848
}
1682716849

1682816850
static TypeTableEntry *ir_analyze_instruction_coro_size(IrAnalyze *ira, IrInstructionCoroSize *instruction) {
16829-
zig_panic("TODO ir_analyze_instruction_coro_size");
16851+
IrInstruction *result = ir_build_coro_size(&ira->new_irb, instruction->base.scope, instruction->base.source_node);
16852+
ir_link_new_instruction(result, &instruction->base);
16853+
result->value.type = ira->codegen->builtin_types.entry_usize;
16854+
return result->value.type;
1683016855
}
1683116856

1683216857
static TypeTableEntry *ir_analyze_instruction_coro_begin(IrAnalyze *ira, IrInstructionCoroBegin *instruction) {
16833-
zig_panic("TODO ir_analyze_instruction_coro_begin");
16858+
IrInstruction *coro_id = instruction->coro_id->other;
16859+
if (type_is_invalid(coro_id->value.type))
16860+
return ira->codegen->builtin_types.entry_invalid;
16861+
16862+
IrInstruction *coro_mem_ptr = instruction->coro_mem_ptr->other;
16863+
if (type_is_invalid(coro_mem_ptr->value.type))
16864+
return ira->codegen->builtin_types.entry_invalid;
16865+
16866+
FnTableEntry *fn_entry = exec_fn_entry(ira->new_irb.exec);
16867+
assert(fn_entry != nullptr);
16868+
IrInstruction *result = ir_build_coro_begin(&ira->new_irb, instruction->base.scope, instruction->base.source_node,
16869+
coro_id, coro_mem_ptr);
16870+
ir_link_new_instruction(result, &instruction->base);
16871+
result->value.type = get_promise_type(ira->codegen, fn_entry->type_entry->data.fn.fn_type_id.return_type);
16872+
return result->value.type;
1683416873
}
1683516874

1683616875
static TypeTableEntry *ir_analyze_instruction_get_implicit_allocator(IrAnalyze *ira, IrInstructionGetImplicitAllocator *instruction) {
1683716876
IrInstruction *result = ir_get_implicit_allocator(ira, &instruction->base);
16877+
ir_link_new_instruction(result, &instruction->base);
1683816878
return result->value.type;
1683916879
}
1684016880

16881+
static TypeTableEntry *ir_analyze_instruction_coro_alloc_fail(IrAnalyze *ira, IrInstructionCoroAllocFail *instruction) {
16882+
IrInstruction *err_val = instruction->err_val->other;
16883+
if (type_is_invalid(err_val->value.type))
16884+
return ir_unreach_error(ira);
16885+
16886+
IrInstruction *result = ir_build_coro_alloc_fail(&ira->new_irb, instruction->base.scope, instruction->base.source_node, err_val);
16887+
ir_link_new_instruction(result, &instruction->base);
16888+
result->value.type = ira->codegen->builtin_types.entry_unreachable;
16889+
return ir_finish_anal(ira, result->value.type);
16890+
}
16891+
1684116892
static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) {
1684216893
switch (instruction->id) {
1684316894
case IrInstructionIdInvalid:
@@ -17052,6 +17103,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
1705217103
return ir_analyze_instruction_coro_begin(ira, (IrInstructionCoroBegin *)instruction);
1705317104
case IrInstructionIdGetImplicitAllocator:
1705417105
return ir_analyze_instruction_get_implicit_allocator(ira, (IrInstructionGetImplicitAllocator *)instruction);
17106+
case IrInstructionIdCoroAllocFail:
17107+
return ir_analyze_instruction_coro_alloc_fail(ira, (IrInstructionCoroAllocFail *)instruction);
1705517108
}
1705617109
zig_unreachable();
1705717110
}
@@ -17168,6 +17221,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
1716817221
case IrInstructionIdCancel:
1716917222
case IrInstructionIdCoroId:
1717017223
case IrInstructionIdCoroBegin:
17224+
case IrInstructionIdCoroAllocFail:
1717117225
return true;
1717217226

1717317227
case IrInstructionIdPhi:

src/ir_print.cpp

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1052,6 +1052,12 @@ static void ir_print_coro_begin(IrPrint *irp, IrInstructionCoroBegin *instructio
10521052
fprintf(irp->f, ")");
10531053
}
10541054

1055+
static void ir_print_coro_alloc_fail(IrPrint *irp, IrInstructionCoroAllocFail *instruction) {
1056+
fprintf(irp->f, "@coroAllocFail(");
1057+
ir_print_other_instruction(irp, instruction->err_val);
1058+
fprintf(irp->f, ")");
1059+
}
1060+
10551061
static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
10561062
ir_print_prefix(irp, instruction);
10571063
switch (instruction->id) {
@@ -1390,6 +1396,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
13901396
case IrInstructionIdCoroBegin:
13911397
ir_print_coro_begin(irp, (IrInstructionCoroBegin *)instruction);
13921398
break;
1399+
case IrInstructionIdCoroAllocFail:
1400+
ir_print_coro_alloc_fail(irp, (IrInstructionCoroAllocFail *)instruction);
1401+
break;
13931402
}
13941403
fprintf(irp->f, "\n");
13951404
}

0 commit comments

Comments
 (0)