| ... | @@ -22,6 +22,8 @@ struct LoopStackItem { | ... | @@ -22,6 +22,8 @@ struct LoopStackItem { |
| 22 | IrBasicBlock *break_block; | 22 | IrBasicBlock *break_block; |
| 23 | IrBasicBlock *continue_block; | 23 | IrBasicBlock *continue_block; |
| 24 | IrInstruction *is_comptime; | 24 | IrInstruction *is_comptime; |
| | 25 | ZigList<IrInstruction *> *incoming_values; |
| | 26 | ZigList<IrBasicBlock *> *incoming_blocks; |
| 25 | }; | 27 | }; |
| 26 | | 28 | |
| 27 | struct IrBuilder { | 29 | struct IrBuilder { |
| ... | @@ -56,6 +58,18 @@ static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *sc | ... | @@ -56,6 +58,18 @@ static IrInstruction *ir_gen_node_extra(IrBuilder *irb, AstNode *node, Scope *sc |
| 56 | static TypeTableEntry *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *instruction); | 58 | static TypeTableEntry *ir_analyze_instruction(IrAnalyze *ira, IrInstruction *instruction); |
| 57 | static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, TypeTableEntry *expected_type); | 59 | static IrInstruction *ir_implicit_cast(IrAnalyze *ira, IrInstruction *value, TypeTableEntry *expected_type); |
| 58 | | 60 | |
| | 61 | static LoopStackItem *add_loop_stack_item(IrBuilder *irb, IrBasicBlock *break_block, IrBasicBlock *continue_block, |
| | 62 | IrInstruction *is_comptime, ZigList<IrBasicBlock *> *incoming_blocks, ZigList<IrInstruction *> *incoming_values) |
| | 63 | { |
| | 64 | LoopStackItem *loop_stack_item = irb->loop_stack.add_one(); |
| | 65 | loop_stack_item->break_block = break_block; |
| | 66 | loop_stack_item->continue_block = continue_block; |
| | 67 | loop_stack_item->is_comptime = is_comptime; |
| | 68 | loop_stack_item->incoming_blocks = incoming_blocks; |
| | 69 | loop_stack_item->incoming_values = incoming_values; |
| | 70 | return loop_stack_item; |
| | 71 | } |
| | 72 | |
| 59 | ConstExprValue *const_ptr_pointee(CodeGen *g, ConstExprValue *const_val) { | 73 | ConstExprValue *const_ptr_pointee(CodeGen *g, ConstExprValue *const_val) { |
| 60 | assert(const_val->type->id == TypeTableEntryIdPointer); | 74 | assert(const_val->type->id == TypeTableEntryIdPointer); |
| 61 | assert(const_val->special == ConstValSpecialStatic); | 75 | assert(const_val->special == ConstValSpecialStatic); |
| ... | @@ -4693,6 +4707,8 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -4693,6 +4707,8 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 4693 | return err_val_ptr; | 4707 | return err_val_ptr; |
| 4694 | IrInstruction *err_val = ir_build_load_ptr(irb, scope, node->data.while_expr.condition, err_val_ptr); | 4708 | IrInstruction *err_val = ir_build_load_ptr(irb, scope, node->data.while_expr.condition, err_val_ptr); |
| 4695 | IrInstruction *is_err = ir_build_test_err(irb, scope, node->data.while_expr.condition, err_val); | 4709 | IrInstruction *is_err = ir_build_test_err(irb, scope, node->data.while_expr.condition, err_val); |
| | 4710 | IrBasicBlock *after_cond_block = irb->current_basic_block; |
| | 4711 | IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); |
| 4696 | if (!instr_is_unreachable(is_err)) { | 4712 | if (!instr_is_unreachable(is_err)) { |
| 4697 | ir_mark_gen(ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_err, | 4713 | ir_mark_gen(ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_err, |
| 4698 | else_block, body_block, is_comptime)); | 4714 | else_block, body_block, is_comptime)); |
| ... | @@ -4706,10 +4722,9 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -4706,10 +4722,9 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 4706 | var_ptr_value : ir_build_load_ptr(irb, payload_scope, symbol_node, var_ptr_value); | 4722 | var_ptr_value : ir_build_load_ptr(irb, payload_scope, symbol_node, var_ptr_value); |
| 4707 | ir_build_var_decl(irb, payload_scope, symbol_node, payload_var, nullptr, var_value); | 4723 | ir_build_var_decl(irb, payload_scope, symbol_node, payload_var, nullptr, var_value); |
| 4708 | } | 4724 | } |
| 4709 | LoopStackItem *loop_stack_item = irb->loop_stack.add_one(); | 4725 | ZigList<IrInstruction *> incoming_values = {0}; |
| 4710 | loop_stack_item->break_block = end_block; | 4726 | ZigList<IrBasicBlock *> incoming_blocks = {0}; |
| 4711 | loop_stack_item->continue_block = continue_block; | 4727 | add_loop_stack_item(irb, end_block, continue_block, is_comptime, &incoming_blocks, &incoming_values); |
| 4712 | loop_stack_item->is_comptime = is_comptime; | | |
| 4713 | IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, payload_scope); | 4728 | IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, payload_scope); |
| 4714 | if (body_result == irb->codegen->invalid_instruction) | 4729 | if (body_result == irb->codegen->invalid_instruction) |
| 4715 | return body_result; | 4730 | return body_result; |
| ... | @@ -4727,6 +4742,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -4727,6 +4742,7 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 4727 | ir_mark_gen(ir_build_br(irb, payload_scope, node, cond_block, is_comptime)); | 4742 | ir_mark_gen(ir_build_br(irb, payload_scope, node, cond_block, is_comptime)); |
| 4728 | } | 4743 | } |
| 4729 | | 4744 | |
| | 4745 | IrInstruction *else_result = nullptr; |
| 4730 | if (else_node) { | 4746 | if (else_node) { |
| 4731 | ir_set_cursor_at_end(irb, else_block); | 4747 | ir_set_cursor_at_end(irb, else_block); |
| 4732 | | 4748 | |
| ... | @@ -4738,15 +4754,23 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -4738,15 +4754,23 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 4738 | IrInstruction *err_var_value = ir_build_unwrap_err_code(irb, err_scope, err_symbol_node, err_val_ptr); | 4754 | IrInstruction *err_var_value = ir_build_unwrap_err_code(irb, err_scope, err_symbol_node, err_val_ptr); |
| 4739 | ir_build_var_decl(irb, err_scope, symbol_node, err_var, nullptr, err_var_value); | 4755 | ir_build_var_decl(irb, err_scope, symbol_node, err_var, nullptr, err_var_value); |
| 4740 | | 4756 | |
| 4741 | IrInstruction *else_result = ir_gen_node(irb, else_node, err_scope); | 4757 | else_result = ir_gen_node(irb, else_node, err_scope); |
| 4742 | if (else_result == irb->codegen->invalid_instruction) | 4758 | if (else_result == irb->codegen->invalid_instruction) |
| 4743 | return else_result; | 4759 | return else_result; |
| 4744 | if (!instr_is_unreachable(else_result)) | 4760 | if (!instr_is_unreachable(else_result)) |
| 4745 | ir_mark_gen(ir_build_br(irb, scope, node, end_block, is_comptime)); | 4761 | ir_mark_gen(ir_build_br(irb, scope, node, end_block, is_comptime)); |
| 4746 | } | 4762 | } |
| 4747 | | 4763 | IrBasicBlock *after_else_block = irb->current_basic_block; |
| 4748 | ir_set_cursor_at_end(irb, end_block); | 4764 | ir_set_cursor_at_end(irb, end_block); |
| 4749 | return ir_build_const_void(irb, scope, node); | 4765 | if (else_result) { |
| | 4766 | incoming_blocks.append(after_else_block); |
| | 4767 | incoming_values.append(else_result); |
| | 4768 | } else { |
| | 4769 | incoming_blocks.append(after_cond_block); |
| | 4770 | incoming_values.append(void_else_result); |
| | 4771 | } |
| | 4772 | |
| | 4773 | return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); |
| 4750 | } else if (var_symbol != nullptr) { | 4774 | } else if (var_symbol != nullptr) { |
| 4751 | ir_set_cursor_at_end(irb, cond_block); | 4775 | ir_set_cursor_at_end(irb, cond_block); |
| 4752 | // TODO make it an error to write to payload variable | 4776 | // TODO make it an error to write to payload variable |
| ... | @@ -4759,6 +4783,8 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -4759,6 +4783,8 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 4759 | return maybe_val_ptr; | 4783 | return maybe_val_ptr; |
| 4760 | IrInstruction *maybe_val = ir_build_load_ptr(irb, scope, node->data.while_expr.condition, maybe_val_ptr); | 4784 | IrInstruction *maybe_val = ir_build_load_ptr(irb, scope, node->data.while_expr.condition, maybe_val_ptr); |
| 4761 | IrInstruction *is_non_null = ir_build_test_nonnull(irb, scope, node->data.while_expr.condition, maybe_val); | 4785 | IrInstruction *is_non_null = ir_build_test_nonnull(irb, scope, node->data.while_expr.condition, maybe_val); |
| | 4786 | IrBasicBlock *after_cond_block = irb->current_basic_block; |
| | 4787 | IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); |
| 4762 | if (!instr_is_unreachable(is_non_null)) { | 4788 | if (!instr_is_unreachable(is_non_null)) { |
| 4763 | ir_mark_gen(ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_non_null, | 4789 | ir_mark_gen(ir_build_cond_br(irb, scope, node->data.while_expr.condition, is_non_null, |
| 4764 | body_block, else_block, is_comptime)); | 4790 | body_block, else_block, is_comptime)); |
| ... | @@ -4769,10 +4795,9 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -4769,10 +4795,9 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 4769 | IrInstruction *var_value = node->data.while_expr.var_is_ptr ? | 4795 | IrInstruction *var_value = node->data.while_expr.var_is_ptr ? |
| 4770 | var_ptr_value : ir_build_load_ptr(irb, child_scope, symbol_node, var_ptr_value); | 4796 | var_ptr_value : ir_build_load_ptr(irb, child_scope, symbol_node, var_ptr_value); |
| 4771 | ir_build_var_decl(irb, child_scope, symbol_node, payload_var, nullptr, var_value); | 4797 | ir_build_var_decl(irb, child_scope, symbol_node, payload_var, nullptr, var_value); |
| 4772 | LoopStackItem *loop_stack_item = irb->loop_stack.add_one(); | 4798 | ZigList<IrInstruction *> incoming_values = {0}; |
| 4773 | loop_stack_item->break_block = end_block; | 4799 | ZigList<IrBasicBlock *> incoming_blocks = {0}; |
| 4774 | loop_stack_item->continue_block = continue_block; | 4800 | add_loop_stack_item(irb, end_block, continue_block, is_comptime, &incoming_blocks, &incoming_values); |
| 4775 | loop_stack_item->is_comptime = is_comptime; | | |
| 4776 | IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, child_scope); | 4801 | IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, child_scope); |
| 4777 | if (body_result == irb->codegen->invalid_instruction) | 4802 | if (body_result == irb->codegen->invalid_instruction) |
| 4778 | return body_result; | 4803 | return body_result; |
| ... | @@ -4790,18 +4815,27 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -4790,18 +4815,27 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 4790 | ir_mark_gen(ir_build_br(irb, child_scope, node, cond_block, is_comptime)); | 4815 | ir_mark_gen(ir_build_br(irb, child_scope, node, cond_block, is_comptime)); |
| 4791 | } | 4816 | } |
| 4792 | | 4817 | |
| | 4818 | IrInstruction *else_result = nullptr; |
| 4793 | if (else_node) { | 4819 | if (else_node) { |
| 4794 | ir_set_cursor_at_end(irb, else_block); | 4820 | ir_set_cursor_at_end(irb, else_block); |
| 4795 | | 4821 | |
| 4796 | IrInstruction *else_result = ir_gen_node(irb, else_node, scope); | 4822 | else_result = ir_gen_node(irb, else_node, scope); |
| 4797 | if (else_result == irb->codegen->invalid_instruction) | 4823 | if (else_result == irb->codegen->invalid_instruction) |
| 4798 | return else_result; | 4824 | return else_result; |
| 4799 | if (!instr_is_unreachable(else_result)) | 4825 | if (!instr_is_unreachable(else_result)) |
| 4800 | ir_mark_gen(ir_build_br(irb, scope, node, end_block, is_comptime)); | 4826 | ir_mark_gen(ir_build_br(irb, scope, node, end_block, is_comptime)); |
| 4801 | } | 4827 | } |
| 4802 | | 4828 | IrBasicBlock *after_else_block = irb->current_basic_block; |
| 4803 | ir_set_cursor_at_end(irb, end_block); | 4829 | ir_set_cursor_at_end(irb, end_block); |
| 4804 | return ir_build_const_void(irb, scope, node); | 4830 | if (else_result) { |
| | 4831 | incoming_blocks.append(after_else_block); |
| | 4832 | incoming_values.append(else_result); |
| | 4833 | } else { |
| | 4834 | incoming_blocks.append(after_cond_block); |
| | 4835 | incoming_values.append(void_else_result); |
| | 4836 | } |
| | 4837 | |
| | 4838 | return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); |
| 4805 | } else { | 4839 | } else { |
| 4806 | if (continue_expr_node) { | 4840 | if (continue_expr_node) { |
| 4807 | ir_set_cursor_at_end(irb, continue_block); | 4841 | ir_set_cursor_at_end(irb, continue_block); |
| ... | @@ -4816,6 +4850,8 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -4816,6 +4850,8 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 4816 | IrInstruction *cond_val = ir_gen_node(irb, node->data.while_expr.condition, scope); | 4850 | IrInstruction *cond_val = ir_gen_node(irb, node->data.while_expr.condition, scope); |
| 4817 | if (cond_val == irb->codegen->invalid_instruction) | 4851 | if (cond_val == irb->codegen->invalid_instruction) |
| 4818 | return cond_val; | 4852 | return cond_val; |
| | 4853 | IrBasicBlock *after_cond_block = irb->current_basic_block; |
| | 4854 | IrInstruction *void_else_result = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, scope, node)); |
| 4819 | if (!instr_is_unreachable(cond_val)) { | 4855 | if (!instr_is_unreachable(cond_val)) { |
| 4820 | ir_mark_gen(ir_build_cond_br(irb, scope, node->data.while_expr.condition, cond_val, | 4856 | ir_mark_gen(ir_build_cond_br(irb, scope, node->data.while_expr.condition, cond_val, |
| 4821 | body_block, else_block, is_comptime)); | 4857 | body_block, else_block, is_comptime)); |
| ... | @@ -4823,10 +4859,9 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -4823,10 +4859,9 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 4823 | | 4859 | |
| 4824 | ir_set_cursor_at_end(irb, body_block); | 4860 | ir_set_cursor_at_end(irb, body_block); |
| 4825 | | 4861 | |
| 4826 | LoopStackItem *loop_stack_item = irb->loop_stack.add_one(); | 4862 | ZigList<IrInstruction *> incoming_values = {0}; |
| 4827 | loop_stack_item->break_block = end_block; | 4863 | ZigList<IrBasicBlock *> incoming_blocks = {0}; |
| 4828 | loop_stack_item->continue_block = continue_block; | 4864 | add_loop_stack_item(irb, end_block, continue_block, is_comptime, &incoming_blocks, &incoming_values); |
| 4829 | loop_stack_item->is_comptime = is_comptime; | | |
| 4830 | IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, scope); | 4865 | IrInstruction *body_result = ir_gen_node(irb, node->data.while_expr.body, scope); |
| 4831 | if (body_result == irb->codegen->invalid_instruction) | 4866 | if (body_result == irb->codegen->invalid_instruction) |
| 4832 | return body_result; | 4867 | return body_result; |
| ... | @@ -4835,19 +4870,27 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n | ... | @@ -4835,19 +4870,27 @@ static IrInstruction *ir_gen_while_expr(IrBuilder *irb, Scope *scope, AstNode *n |
| 4835 | if (!instr_is_unreachable(body_result)) | 4870 | if (!instr_is_unreachable(body_result)) |
| 4836 | ir_mark_gen(ir_build_br(irb, scope, node, continue_block, is_comptime)); | 4871 | ir_mark_gen(ir_build_br(irb, scope, node, continue_block, is_comptime)); |
| 4837 | | 4872 | |
| | 4873 | IrInstruction *else_result = nullptr; |
| 4838 | if (else_node) { | 4874 | if (else_node) { |
| 4839 | ir_set_cursor_at_end(irb, else_block); | 4875 | ir_set_cursor_at_end(irb, else_block); |
| 4840 | | 4876 | |
| 4841 | IrInstruction *else_result = ir_gen_node(irb, else_node, scope); | 4877 | else_result = ir_gen_node(irb, else_node, scope); |
| 4842 | if (else_result == irb->codegen->invalid_instruction) | 4878 | if (else_result == irb->codegen->invalid_instruction) |
| 4843 | return else_result; | 4879 | return else_result; |
| 4844 | if (!instr_is_unreachable(else_result)) | 4880 | if (!instr_is_unreachable(else_result)) |
| 4845 | ir_mark_gen(ir_build_br(irb, scope, node, end_block, is_comptime)); | 4881 | ir_mark_gen(ir_build_br(irb, scope, node, end_block, is_comptime)); |
| 4846 | } | 4882 | } |
| 4847 | | 4883 | IrBasicBlock *after_else_block = irb->current_basic_block; |
| 4848 | ir_set_cursor_at_end(irb, end_block); | 4884 | ir_set_cursor_at_end(irb, end_block); |
| | 4885 | if (else_result) { |
| | 4886 | incoming_blocks.append(after_else_block); |
| | 4887 | incoming_values.append(else_result); |
| | 4888 | } else { |
| | 4889 | incoming_blocks.append(after_cond_block); |
| | 4890 | incoming_values.append(void_else_result); |
| | 4891 | } |
| 4849 | | 4892 | |
| 4850 | return ir_build_const_void(irb, scope, node); | 4893 | return ir_build_phi(irb, scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); |
| 4851 | } | 4894 | } |
| 4852 | } | 4895 | } |
| 4853 | | 4896 | |
| ... | @@ -4858,6 +4901,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo | ... | @@ -4858,6 +4901,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo |
| 4858 | AstNode *elem_node = node->data.for_expr.elem_node; | 4901 | AstNode *elem_node = node->data.for_expr.elem_node; |
| 4859 | AstNode *index_node = node->data.for_expr.index_node; | 4902 | AstNode *index_node = node->data.for_expr.index_node; |
| 4860 | AstNode *body_node = node->data.for_expr.body; | 4903 | AstNode *body_node = node->data.for_expr.body; |
| | 4904 | AstNode *else_node = node->data.for_expr.else_node; |
| 4861 | | 4905 | |
| 4862 | if (!elem_node) { | 4906 | if (!elem_node) { |
| 4863 | add_node_error(irb->codegen, node, buf_sprintf("for loop expression missing element parameter")); | 4907 | add_node_error(irb->codegen, node, buf_sprintf("for loop expression missing element parameter")); |
| ... | @@ -4915,6 +4959,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo | ... | @@ -4915,6 +4959,7 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo |
| 4915 | IrBasicBlock *cond_block = ir_build_basic_block(irb, child_scope, "ForCond"); | 4959 | IrBasicBlock *cond_block = ir_build_basic_block(irb, child_scope, "ForCond"); |
| 4916 | IrBasicBlock *body_block = ir_build_basic_block(irb, child_scope, "ForBody"); | 4960 | IrBasicBlock *body_block = ir_build_basic_block(irb, child_scope, "ForBody"); |
| 4917 | IrBasicBlock *end_block = ir_build_basic_block(irb, child_scope, "ForEnd"); | 4961 | IrBasicBlock *end_block = ir_build_basic_block(irb, child_scope, "ForEnd"); |
| | 4962 | IrBasicBlock *else_block = else_node ? ir_build_basic_block(irb, child_scope, "ForElse") : end_block; |
| 4918 | IrBasicBlock *continue_block = ir_build_basic_block(irb, child_scope, "ForContinue"); | 4963 | IrBasicBlock *continue_block = ir_build_basic_block(irb, child_scope, "ForContinue"); |
| 4919 | | 4964 | |
| 4920 | IrInstruction *len_val = ir_build_array_len(irb, child_scope, node, array_val); | 4965 | IrInstruction *len_val = ir_build_array_len(irb, child_scope, node, array_val); |
| ... | @@ -4923,7 +4968,9 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo | ... | @@ -4923,7 +4968,9 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo |
| 4923 | ir_set_cursor_at_end(irb, cond_block); | 4968 | ir_set_cursor_at_end(irb, cond_block); |
| 4924 | IrInstruction *index_val = ir_build_load_ptr(irb, child_scope, node, index_ptr); | 4969 | IrInstruction *index_val = ir_build_load_ptr(irb, child_scope, node, index_ptr); |
| 4925 | IrInstruction *cond = ir_build_bin_op(irb, child_scope, node, IrBinOpCmpLessThan, index_val, len_val, false); | 4970 | IrInstruction *cond = ir_build_bin_op(irb, child_scope, node, IrBinOpCmpLessThan, index_val, len_val, false); |
| 4926 | ir_mark_gen(ir_build_cond_br(irb, child_scope, node, cond, body_block, end_block, is_comptime)); | 4971 | IrBasicBlock *after_cond_block = irb->current_basic_block; |
| | 4972 | IrInstruction *void_else_value = else_node ? nullptr : ir_mark_gen(ir_build_const_void(irb, parent_scope, node)); |
| | 4973 | ir_mark_gen(ir_build_cond_br(irb, child_scope, node, cond, body_block, else_block, is_comptime)); |
| 4927 | | 4974 | |
| 4928 | ir_set_cursor_at_end(irb, body_block); | 4975 | ir_set_cursor_at_end(irb, body_block); |
| 4929 | IrInstruction *elem_ptr = ir_build_elem_ptr(irb, child_scope, node, array_val_ptr, index_val, false); | 4976 | IrInstruction *elem_ptr = ir_build_elem_ptr(irb, child_scope, node, array_val_ptr, index_val, false); |
| ... | @@ -4935,10 +4982,9 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo | ... | @@ -4935,10 +4982,9 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo |
| 4935 | } | 4982 | } |
| 4936 | ir_mark_gen(ir_build_store_ptr(irb, child_scope, node, elem_var_ptr, elem_val)); | 4983 | ir_mark_gen(ir_build_store_ptr(irb, child_scope, node, elem_var_ptr, elem_val)); |
| 4937 | | 4984 | |
| 4938 | LoopStackItem *loop_stack_item = irb->loop_stack.add_one(); | 4985 | ZigList<IrInstruction *> incoming_values = {0}; |
| 4939 | loop_stack_item->break_block = end_block; | 4986 | ZigList<IrBasicBlock *> incoming_blocks = {0}; |
| 4940 | loop_stack_item->continue_block = continue_block; | 4987 | add_loop_stack_item(irb, end_block, continue_block, is_comptime, &incoming_blocks, &incoming_values); |
| 4941 | loop_stack_item->is_comptime = is_comptime; | | |
| 4942 | IrInstruction *body_result = ir_gen_node(irb, body_node, child_scope); | 4988 | IrInstruction *body_result = ir_gen_node(irb, body_node, child_scope); |
| 4943 | irb->loop_stack.pop(); | 4989 | irb->loop_stack.pop(); |
| 4944 | | 4990 | |
| ... | @@ -4950,9 +4996,28 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo | ... | @@ -4950,9 +4996,28 @@ static IrInstruction *ir_gen_for_expr(IrBuilder *irb, Scope *parent_scope, AstNo |
| 4950 | ir_mark_gen(ir_build_store_ptr(irb, child_scope, node, index_ptr, new_index_val)); | 4996 | ir_mark_gen(ir_build_store_ptr(irb, child_scope, node, index_ptr, new_index_val)); |
| 4951 | ir_build_br(irb, child_scope, node, cond_block, is_comptime); | 4997 | ir_build_br(irb, child_scope, node, cond_block, is_comptime); |
| 4952 | | 4998 | |
| | 4999 | IrInstruction *else_result = nullptr; |
| | 5000 | if (else_node) { |
| | 5001 | ir_set_cursor_at_end(irb, else_block); |
| | 5002 | |
| | 5003 | else_result = ir_gen_node(irb, else_node, parent_scope); |
| | 5004 | if (else_result == irb->codegen->invalid_instruction) |
| | 5005 | return else_result; |
| | 5006 | if (!instr_is_unreachable(else_result)) |
| | 5007 | ir_mark_gen(ir_build_br(irb, parent_scope, node, end_block, is_comptime)); |
| | 5008 | } |
| | 5009 | IrBasicBlock *after_else_block = irb->current_basic_block; |
| 4953 | ir_set_cursor_at_end(irb, end_block); | 5010 | ir_set_cursor_at_end(irb, end_block); |
| 4954 | return ir_build_const_void(irb, child_scope, node); | | |
| 4955 | | 5011 | |
| | 5012 | if (else_result) { |
| | 5013 | incoming_blocks.append(after_else_block); |
| | 5014 | incoming_values.append(else_result); |
| | 5015 | } else { |
| | 5016 | incoming_blocks.append(after_cond_block); |
| | 5017 | incoming_values.append(void_else_value); |
| | 5018 | } |
| | 5019 | |
| | 5020 | return ir_build_phi(irb, parent_scope, node, incoming_blocks.length, incoming_blocks.items, incoming_values.items); |
| 4956 | } | 5021 | } |
| 4957 | | 5022 | |
| 4958 | static IrInstruction *ir_gen_this_literal(IrBuilder *irb, Scope *scope, AstNode *node) { | 5023 | static IrInstruction *ir_gen_this_literal(IrBuilder *irb, Scope *scope, AstNode *node) { |
| ... | @@ -5512,8 +5577,20 @@ static IrInstruction *ir_gen_break(IrBuilder *irb, Scope *scope, AstNode *node) | ... | @@ -5512,8 +5577,20 @@ static IrInstruction *ir_gen_break(IrBuilder *irb, Scope *scope, AstNode *node) |
| 5512 | is_comptime = loop_stack_item->is_comptime; | 5577 | is_comptime = loop_stack_item->is_comptime; |
| 5513 | } | 5578 | } |
| 5514 | | 5579 | |
| | 5580 | IrInstruction *result_value; |
| | 5581 | if (node->data.break_expr.expr) { |
| | 5582 | result_value = ir_gen_node(irb, node->data.break_expr.expr, scope); |
| | 5583 | if (result_value == irb->codegen->invalid_instruction) |
| | 5584 | return irb->codegen->invalid_instruction; |
| | 5585 | } else { |
| | 5586 | result_value = ir_build_const_void(irb, scope, node); |
| | 5587 | } |
| | 5588 | |
| 5515 | IrBasicBlock *dest_block = loop_stack_item->break_block; | 5589 | IrBasicBlock *dest_block = loop_stack_item->break_block; |
| 5516 | ir_gen_defers_for_block(irb, scope, dest_block->scope, false); | 5590 | ir_gen_defers_for_block(irb, scope, dest_block->scope, false); |
| | 5591 | |
| | 5592 | loop_stack_item->incoming_blocks->append(irb->current_basic_block); |
| | 5593 | loop_stack_item->incoming_values->append(result_value); |
| 5517 | return ir_build_br(irb, scope, node, dest_block, is_comptime); | 5594 | return ir_build_br(irb, scope, node, dest_block, is_comptime); |
| 5518 | } | 5595 | } |
| 5519 | | 5596 | |