authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-02-22 11:54:27-05:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2018-02-22 11:54:27-05:00
logca1b77b2d51408589659f652b1b1dbe2a25e149f
treebb7f5bb301a9077ce9118c3125d344235bef8e53
parent88e7b9bf80ef261be23ab5a427f6f10604225be1

IR analysis for coro.begin

See #727

4 files changed, 84 insertions(+), 7 deletions(-)

src/all_types.hpp+8
...@@ -1490,6 +1490,7 @@ struct CodeGen {...@@ -1490,6 +1490,7 @@ struct CodeGen {
1490 TypeTableEntry *entry_u8;1490 TypeTableEntry *entry_u8;
1491 TypeTableEntry *entry_u16;1491 TypeTableEntry *entry_u16;
1492 TypeTableEntry *entry_u32;1492 TypeTableEntry *entry_u32;
1493 TypeTableEntry *entry_u29;
1493 TypeTableEntry *entry_u64;1494 TypeTableEntry *entry_u64;
1494 TypeTableEntry *entry_u128;1495 TypeTableEntry *entry_u128;
1495 TypeTableEntry *entry_i8;1496 TypeTableEntry *entry_i8;
...@@ -1966,6 +1967,7 @@ enum IrInstructionId {...@@ -1966,6 +1967,7 @@ enum IrInstructionId {
1966 IrInstructionIdCoroAlloc,1967 IrInstructionIdCoroAlloc,
1967 IrInstructionIdCoroSize,1968 IrInstructionIdCoroSize,
1968 IrInstructionIdCoroBegin,1969 IrInstructionIdCoroBegin,
1970 IrInstructionIdCoroAllocFail,
1969};1971};
19701972
1971struct IrInstruction {1973struct IrInstruction {
...@@ -2836,6 +2838,12 @@ struct IrInstructionCoroBegin {...@@ -2836,6 +2838,12 @@ struct IrInstructionCoroBegin {
2836 IrInstruction *coro_mem_ptr;2838 IrInstruction *coro_mem_ptr;
2837};2839};
28382840
2841struct IrInstructionCoroAllocFail {
2842 IrInstruction base;
2843
2844 IrInstruction *err_val;
2845};
2846
2839static const size_t slice_ptr_index = 0;2847static const size_t slice_ptr_index = 0;
2840static const size_t slice_len_index = 1;2848static const size_t slice_len_index = 1;
28412849
src/codegen.cpp+6
...@@ -3712,6 +3712,9 @@ static LLVMValueRef ir_render_coro_begin(CodeGen *g, IrExecutable *executable, I...@@ -3712,6 +3712,9 @@ static LLVMValueRef ir_render_coro_begin(CodeGen *g, IrExecutable *executable, I
3712 zig_panic("TODO ir_render_coro_begin");3712 zig_panic("TODO ir_render_coro_begin");
3713}3713}
37143714
3715static LLVMValueRef ir_render_coro_alloc_fail(CodeGen *g, IrExecutable *executable, IrInstructionCoroAllocFail *instruction) {
3716 zig_panic("TODO ir_render_coro_alloc_fail");
3717}
37153718
3716static void set_debug_location(CodeGen *g, IrInstruction *instruction) {3719static void set_debug_location(CodeGen *g, IrInstruction *instruction) {
3717 AstNode *source_node = instruction->source_node;3720 AstNode *source_node = instruction->source_node;
...@@ -3906,6 +3909,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,...@@ -3906,6 +3909,8 @@ static LLVMValueRef ir_render_instruction(CodeGen *g, IrExecutable *executable,
3906 return ir_render_coro_size(g, executable, (IrInstructionCoroSize *)instruction);3909 return ir_render_coro_size(g, executable, (IrInstructionCoroSize *)instruction);
3907 case IrInstructionIdCoroBegin:3910 case IrInstructionIdCoroBegin:
3908 return ir_render_coro_begin(g, executable, (IrInstructionCoroBegin *)instruction);3911 return ir_render_coro_begin(g, executable, (IrInstructionCoroBegin *)instruction);
3912 case IrInstructionIdCoroAllocFail:
3913 return ir_render_coro_alloc_fail(g, executable, (IrInstructionCoroAllocFail *)instruction);
3909 }3914 }
3910 zig_unreachable();3915 zig_unreachable();
3911}3916}
...@@ -5282,6 +5287,7 @@ static void define_builtin_types(CodeGen *g) {...@@ -5282,6 +5287,7 @@ static void define_builtin_types(CodeGen *g) {
52825287
5283 g->builtin_types.entry_u8 = get_int_type(g, false, 8);5288 g->builtin_types.entry_u8 = get_int_type(g, false, 8);
5284 g->builtin_types.entry_u16 = get_int_type(g, false, 16);5289 g->builtin_types.entry_u16 = get_int_type(g, false, 16);
5290 g->builtin_types.entry_u29 = get_int_type(g, false, 29);
5285 g->builtin_types.entry_u32 = get_int_type(g, false, 32);5291 g->builtin_types.entry_u32 = get_int_type(g, false, 32);
5286 g->builtin_types.entry_u64 = get_int_type(g, false, 64);5292 g->builtin_types.entry_u64 = get_int_type(g, false, 64);
5287 g->builtin_types.entry_u128 = get_int_type(g, false, 128);5293 g->builtin_types.entry_u128 = get_int_type(g, false, 128);
src/ir.cpp+61-7
...@@ -668,6 +668,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroBegin *) {...@@ -668,6 +668,10 @@ static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroBegin *) {
668 return IrInstructionIdCoroBegin;668 return IrInstructionIdCoroBegin;
669}669}
670670
671static constexpr IrInstructionId ir_instruction_id(IrInstructionCoroAllocFail *) {
672 return IrInstructionIdCoroAllocFail;
673}
674
671template<typename T>675template<typename T>
672static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {676static T *ir_create_instruction(IrBuilder *irb, Scope *scope, AstNode *source_node) {
673 T *special_instruction = allocate<T>(1);677 T *special_instruction = allocate<T>(1);
...@@ -810,6 +814,14 @@ static IrInstruction *ir_build_const_usize(IrBuilder *irb, Scope *scope, AstNode...@@ -810,6 +814,14 @@ static IrInstruction *ir_build_const_usize(IrBuilder *irb, Scope *scope, AstNode
810 return &const_instruction->base;814 return &const_instruction->base;
811}815}
812816
817static 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
813static IrInstruction *ir_create_const_type(IrBuilder *irb, Scope *scope, AstNode *source_node,825static IrInstruction *ir_create_const_type(IrBuilder *irb, Scope *scope, AstNode *source_node,
814 TypeTableEntry *type_entry)826 TypeTableEntry *type_entry)
815{827{
...@@ -2471,6 +2483,17 @@ static IrInstruction *ir_build_coro_begin(IrBuilder *irb, Scope *scope, AstNode...@@ -2471,6 +2483,17 @@ static IrInstruction *ir_build_coro_begin(IrBuilder *irb, Scope *scope, AstNode
2471 return &instruction->base;2483 return &instruction->base;
2472}2484}
24732485
2486static 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
2474static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) {2497static void ir_count_defers(IrBuilder *irb, Scope *inner_scope, Scope *outer_scope, size_t *results) {
2475 results[ReturnKindUnconditional] = 0;2498 results[ReturnKindUnconditional] = 0;
2476 results[ReturnKindError] = 0;2499 results[ReturnKindError] = 0;
...@@ -5854,23 +5877,22 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec...@@ -5854,23 +5877,22 @@ bool ir_gen(CodeGen *codegen, AstNode *node, Scope *scope, IrExecutable *ir_exec
5854 Buf *alloc_field_name = buf_create_from_str(ASYNC_ALLOC_FIELD_NAME);5877 Buf *alloc_field_name = buf_create_from_str(ASYNC_ALLOC_FIELD_NAME);
5855 IrInstruction *alloc_fn_ptr = ir_build_field_ptr(irb, scope, node, implicit_allocator_ptr, alloc_field_name);5878 IrInstruction *alloc_fn_ptr = ir_build_field_ptr(irb, scope, node, implicit_allocator_ptr, alloc_field_name);
5856 IrInstruction *alloc_fn = ir_build_load_ptr(irb, scope, node, alloc_fn_ptr);5879 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);5880 IrInstruction *alignment = ir_build_const_u29(irb, scope, node, irb->codegen->pointer_size_bytes * 2);
5858 IrInstruction *alignment = ir_build_const_usize(irb, scope, node, irb->codegen->pointer_size_bytes * 2);
5859 size_t arg_count = 3;5881 size_t arg_count = 3;
5860 IrInstruction **args = allocate<IrInstruction *>(arg_count);5882 IrInstruction **args = allocate<IrInstruction *>(arg_count);
5861 args[0] = implicit_allocator; // self5883 args[0] = implicit_allocator_ptr; // self
5862 args[1] = coro_size; // byte_count5884 args[1] = coro_size; // byte_count
5863 args[2] = alignment; // alignment5885 args[2] = alignment; // alignment
5864 IrInstruction *alloc_result = ir_build_call(irb, scope, node, nullptr, alloc_fn, arg_count, args, false, FnInlineAuto, false, nullptr);5886 IrInstruction *alloc_result = ir_build_call(irb, scope, node, nullptr, alloc_fn, arg_count, args, false, FnInlineAuto, false, nullptr);
5865 IrInstruction *alloc_result_ptr = ir_build_ref(irb, scope, node, alloc_result, true, false);5887 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);
5867 IrBasicBlock *alloc_err_block = ir_create_basic_block(irb, scope, "AllocError");5889 IrBasicBlock *alloc_err_block = ir_create_basic_block(irb, scope, "AllocError");
5868 IrBasicBlock *alloc_ok_block = ir_create_basic_block(irb, scope, "AllocOk");5890 IrBasicBlock *alloc_ok_block = ir_create_basic_block(irb, scope, "AllocOk");
5869 ir_build_cond_br(irb, scope, node, alloc_result_is_err, alloc_err_block, alloc_ok_block, is_comptime_false);5891 ir_build_cond_br(irb, scope, node, alloc_result_is_err, alloc_err_block, alloc_ok_block, is_comptime_false);
58705892
5871 ir_set_cursor_at_end_and_append_block(irb, alloc_err_block);5893 ir_set_cursor_at_end_and_append_block(irb, alloc_err_block);
5872 IrInstruction *err_val = ir_build_unwrap_err_code(irb, scope, node, alloc_result_ptr);5894 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
5875 ir_set_cursor_at_end_and_append_block(irb, alloc_ok_block);5897 ir_set_cursor_at_end_and_append_block(irb, alloc_ok_block);
5876 IrInstruction *unwrapped_mem_ptr = ir_build_unwrap_err_payload(irb, scope, node, alloc_result_ptr, false);5898 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...@@ -16826,18 +16848,47 @@ static TypeTableEntry *ir_analyze_instruction_coro_alloc(IrAnalyze *ira, IrInstr
16826}16848}
1682716849
16828static TypeTableEntry *ir_analyze_instruction_coro_size(IrAnalyze *ira, IrInstructionCoroSize *instruction) {16850static 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;
16830}16855}
1683116856
16832static TypeTableEntry *ir_analyze_instruction_coro_begin(IrAnalyze *ira, IrInstructionCoroBegin *instruction) {16857static 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;
16834}16873}
1683516874
16836static TypeTableEntry *ir_analyze_instruction_get_implicit_allocator(IrAnalyze *ira, IrInstructionGetImplicitAllocator *instruction) {16875static TypeTableEntry *ir_analyze_instruction_get_implicit_allocator(IrAnalyze *ira, IrInstructionGetImplicitAllocator *instruction) {
16837 IrInstruction *result = ir_get_implicit_allocator(ira, &instruction->base);16876 IrInstruction *result = ir_get_implicit_allocator(ira, &instruction->base);
16877 ir_link_new_instruction(result, &instruction->base);
16838 return result->value.type;16878 return result->value.type;
16839}16879}
1684016880
16881static 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
16841static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) {16892static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstruction *instruction) {
16842 switch (instruction->id) {16893 switch (instruction->id) {
16843 case IrInstructionIdInvalid:16894 case IrInstructionIdInvalid:
...@@ -17052,6 +17103,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi...@@ -17052,6 +17103,8 @@ static TypeTableEntry *ir_analyze_instruction_nocast(IrAnalyze *ira, IrInstructi
17052 return ir_analyze_instruction_coro_begin(ira, (IrInstructionCoroBegin *)instruction);17103 return ir_analyze_instruction_coro_begin(ira, (IrInstructionCoroBegin *)instruction);
17053 case IrInstructionIdGetImplicitAllocator:17104 case IrInstructionIdGetImplicitAllocator:
17054 return ir_analyze_instruction_get_implicit_allocator(ira, (IrInstructionGetImplicitAllocator *)instruction);17105 return ir_analyze_instruction_get_implicit_allocator(ira, (IrInstructionGetImplicitAllocator *)instruction);
17106 case IrInstructionIdCoroAllocFail:
17107 return ir_analyze_instruction_coro_alloc_fail(ira, (IrInstructionCoroAllocFail *)instruction);
17055 }17108 }
17056 zig_unreachable();17109 zig_unreachable();
17057}17110}
...@@ -17168,6 +17221,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {...@@ -17168,6 +17221,7 @@ bool ir_has_side_effects(IrInstruction *instruction) {
17168 case IrInstructionIdCancel:17221 case IrInstructionIdCancel:
17169 case IrInstructionIdCoroId:17222 case IrInstructionIdCoroId:
17170 case IrInstructionIdCoroBegin:17223 case IrInstructionIdCoroBegin:
17224 case IrInstructionIdCoroAllocFail:
17171 return true;17225 return true;
1717217226
17173 case IrInstructionIdPhi:17227 case IrInstructionIdPhi:
src/ir_print.cpp+9
...@@ -1052,6 +1052,12 @@ static void ir_print_coro_begin(IrPrint *irp, IrInstructionCoroBegin *instructio...@@ -1052,6 +1052,12 @@ static void ir_print_coro_begin(IrPrint *irp, IrInstructionCoroBegin *instructio
1052 fprintf(irp->f, ")");1052 fprintf(irp->f, ")");
1053}1053}
10541054
1055static 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
1055static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {1061static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1056 ir_print_prefix(irp, instruction);1062 ir_print_prefix(irp, instruction);
1057 switch (instruction->id) {1063 switch (instruction->id) {
...@@ -1390,6 +1396,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {...@@ -1390,6 +1396,9 @@ static void ir_print_instruction(IrPrint *irp, IrInstruction *instruction) {
1390 case IrInstructionIdCoroBegin:1396 case IrInstructionIdCoroBegin:
1391 ir_print_coro_begin(irp, (IrInstructionCoroBegin *)instruction);1397 ir_print_coro_begin(irp, (IrInstructionCoroBegin *)instruction);
1392 break;1398 break;
1399 case IrInstructionIdCoroAllocFail:
1400 ir_print_coro_alloc_fail(irp, (IrInstructionCoroAllocFail *)instruction);
1401 break;
1393 }1402 }
1394 fprintf(irp->f, "\n");1403 fprintf(irp->f, "\n");
1395}1404}