authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-06-20 18:03:55-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-06-20 18:03:55-04:00
log057b105fadb1b60d0927cb878e795c9e7ac9bdb1
tree2c59db03a6222d653a5b4a558da473a86fef40ca
parent3c541d7be38d625645276f8a0dee57774fe94134
signaturelock-open Commit is signed but in an unrecognized format.

one more test passing


3 files changed, 60 insertions(+), 37 deletions(-)

src/all_types.hpp+1
...@@ -2157,6 +2157,7 @@ struct IrBasicBlock {...@@ -2157,6 +2157,7 @@ struct IrBasicBlock {
2157 IrInstruction *suspend_instruction_ref;2157 IrInstruction *suspend_instruction_ref;
2158 bool already_appended;2158 bool already_appended;
2159 bool suspended;2159 bool suspended;
2160 bool in_resume_stack;
2160};2161};
21612162
2162// These instructions are in transition to having "pass 1" instructions2163// These instructions are in transition to having "pass 1" instructions
src/ir.cpp+58-36
...@@ -6958,6 +6958,8 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *...@@ -6958,6 +6958,8 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
6958 peer_parent->peers = allocate<ResultLocPeer>(prong_count);6958 peer_parent->peers = allocate<ResultLocPeer>(prong_count);
6959 peer_parent->peer_count = 0;6959 peer_parent->peer_count = 0;
69606960
6961 ir_build_reset_result(irb, scope, node, &peer_parent->base);
6962
6961 // First do the else and the ranges6963 // First do the else and the ranges
6962 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);6964 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);
6963 Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope);6965 Scope *comptime_scope = create_comptime_scope(irb->codegen, node, scope);
...@@ -7117,8 +7119,6 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *...@@ -7117,8 +7119,6 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
7117 IrInstruction *switch_prongs_void = ir_build_check_switch_prongs(irb, scope, node, target_value,7119 IrInstruction *switch_prongs_void = ir_build_check_switch_prongs(irb, scope, node, target_value,
7118 check_ranges.items, check_ranges.length, else_prong != nullptr);7120 check_ranges.items, check_ranges.length, else_prong != nullptr);
71197121
7120 ir_build_reset_result(irb, scope, node, &peer_parent->base);
7121
7122 IrInstruction *br_instruction;7122 IrInstruction *br_instruction;
7123 if (cases.length == 0) {7123 if (cases.length == 0) {
7124 br_instruction = ir_build_br(irb, scope, node, else_block, is_comptime);7124 br_instruction = ir_build_br(irb, scope, node, else_block, is_comptime);
...@@ -10880,6 +10880,7 @@ static IrBasicBlock *ir_get_new_bb_runtime(IrAnalyze *ira, IrBasicBlock *old_bb,...@@ -10880,6 +10880,7 @@ static IrBasicBlock *ir_get_new_bb_runtime(IrAnalyze *ira, IrBasicBlock *old_bb,
10880}10880}
1088110881
10882static void ir_start_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrBasicBlock *const_predecessor_bb) {10882static void ir_start_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrBasicBlock *const_predecessor_bb) {
10883 assert(!old_bb->suspended);
10883 ira->instruction_index = 0;10884 ira->instruction_index = 0;
10884 ira->old_irb.current_basic_block = old_bb;10885 ira->old_irb.current_basic_block = old_bb;
10885 ira->const_predecessor_bb = const_predecessor_bb;10886 ira->const_predecessor_bb = const_predecessor_bb;
...@@ -10889,20 +10890,14 @@ static void ir_start_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrBasicBlock *cons...@@ -10889,20 +10890,14 @@ static void ir_start_bb(IrAnalyze *ira, IrBasicBlock *old_bb, IrBasicBlock *cons
10889static IrInstruction *ira_suspend(IrAnalyze *ira, IrInstruction *old_instruction, IrBasicBlock *next_bb,10890static IrInstruction *ira_suspend(IrAnalyze *ira, IrInstruction *old_instruction, IrBasicBlock *next_bb,
10890 IrSuspendPosition *suspend_pos)10891 IrSuspendPosition *suspend_pos)
10891{10892{
10892 // reserve block position10893 if (ira->codegen->verbose_ir) {
10893 if (!ira->new_irb.current_basic_block->already_appended) {10894 fprintf(stderr, "suspend %s_%zu %s_%zu #%zu (%zu,%zu)\n", ira->old_irb.current_basic_block->name_hint,
10894 ira->new_irb.current_basic_block->already_appended = true;10895 ira->old_irb.current_basic_block->debug_id,
10895 ira->new_irb.exec->basic_block_list.append(ira->new_irb.current_basic_block);10896 ira->old_irb.exec->basic_block_list.at(ira->old_bb_index)->name_hint,
10897 ira->old_irb.exec->basic_block_list.at(ira->old_bb_index)->debug_id,
10898 ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index)->debug_id,
10899 ira->old_bb_index, ira->instruction_index);
10896 }10900 }
10897
10898 //if (ira->codegen->verbose_ir) {
10899 // fprintf(stderr, "suspend %s_%zu %s_%zu #%zu (%zu,%zu)\n", ira->old_irb.current_basic_block->name_hint,
10900 // ira->old_irb.current_basic_block->debug_id,
10901 // ira->old_irb.exec->basic_block_list.at(ira->old_bb_index)->name_hint,
10902 // ira->old_irb.exec->basic_block_list.at(ira->old_bb_index)->debug_id,
10903 // ira->old_irb.current_basic_block->instruction_list.at(ira->instruction_index)->debug_id,
10904 // ira->old_bb_index, ira->instruction_index);
10905 //}
10906 suspend_pos->basic_block_index = ira->old_bb_index;10901 suspend_pos->basic_block_index = ira->old_bb_index;
10907 suspend_pos->instruction_index = ira->instruction_index;10902 suspend_pos->instruction_index = ira->instruction_index;
1090810903
...@@ -10923,19 +10918,21 @@ static IrInstruction *ira_suspend(IrAnalyze *ira, IrInstruction *old_instruction...@@ -10923,19 +10918,21 @@ static IrInstruction *ira_suspend(IrAnalyze *ira, IrInstruction *old_instruction
1092310918
10924static IrInstruction *ira_resume(IrAnalyze *ira) {10919static IrInstruction *ira_resume(IrAnalyze *ira) {
10925 IrSuspendPosition pos = ira->resume_stack.pop();10920 IrSuspendPosition pos = ira->resume_stack.pop();
10926 //if (ira->codegen->verbose_ir) {10921 if (ira->codegen->verbose_ir) {
10927 // fprintf(stderr, "resume (%zu,%zu) ", pos.basic_block_index, pos.instruction_index);10922 fprintf(stderr, "resume (%zu,%zu) ", pos.basic_block_index, pos.instruction_index);
10928 //}10923 }
10929 ira->old_bb_index = pos.basic_block_index;10924 ira->old_bb_index = pos.basic_block_index;
10930 ira->old_irb.current_basic_block = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index);10925 ira->old_irb.current_basic_block = ira->old_irb.exec->basic_block_list.at(ira->old_bb_index);
10926 assert(ira->old_irb.current_basic_block->in_resume_stack);
10927 ira->old_irb.current_basic_block->in_resume_stack = false;
10931 ira->old_irb.current_basic_block->suspended = false;10928 ira->old_irb.current_basic_block->suspended = false;
10932 ira->instruction_index = pos.instruction_index;10929 ira->instruction_index = pos.instruction_index;
10933 assert(pos.instruction_index < ira->old_irb.current_basic_block->instruction_list.length);10930 assert(pos.instruction_index < ira->old_irb.current_basic_block->instruction_list.length);
10934 //if (ira->codegen->verbose_ir) {10931 if (ira->codegen->verbose_ir) {
10935 // fprintf(stderr, "%s_%zu #%zu\n", ira->old_irb.current_basic_block->name_hint,10932 fprintf(stderr, "%s_%zu #%zu\n", ira->old_irb.current_basic_block->name_hint,
10936 // ira->old_irb.current_basic_block->debug_id,10933 ira->old_irb.current_basic_block->debug_id,
10937 // ira->old_irb.current_basic_block->instruction_list.at(pos.instruction_index)->debug_id);10934 ira->old_irb.current_basic_block->instruction_list.at(pos.instruction_index)->debug_id);
10938 //}10935 }
10939 ira->const_predecessor_bb = nullptr;10936 ira->const_predecessor_bb = nullptr;
10940 ira->new_irb.current_basic_block = ira->old_irb.current_basic_block->other;10937 ira->new_irb.current_basic_block = ira->old_irb.current_basic_block->other;
10941 assert(ira->new_irb.current_basic_block != nullptr);10938 assert(ira->new_irb.current_basic_block != nullptr);
...@@ -10945,6 +10942,10 @@ static IrInstruction *ira_resume(IrAnalyze *ira) {...@@ -10945,6 +10942,10 @@ static IrInstruction *ira_resume(IrAnalyze *ira) {
10945static void ir_finish_bb(IrAnalyze *ira) {10942static void ir_finish_bb(IrAnalyze *ira) {
10946 if (!ira->new_irb.current_basic_block->already_appended) {10943 if (!ira->new_irb.current_basic_block->already_appended) {
10947 ira->new_irb.current_basic_block->already_appended = true;10944 ira->new_irb.current_basic_block->already_appended = true;
10945 if (ira->codegen->verbose_ir) {
10946 fprintf(stderr, "append new bb %s_%zu\n", ira->new_irb.current_basic_block->name_hint,
10947 ira->new_irb.current_basic_block->debug_id);
10948 }
10948 ira->new_irb.exec->basic_block_list.append(ira->new_irb.current_basic_block);10949 ira->new_irb.exec->basic_block_list.append(ira->new_irb.current_basic_block);
10949 }10950 }
10950 ira->instruction_index += 1;10951 ira->instruction_index += 1;
...@@ -10957,7 +10958,6 @@ static void ir_finish_bb(IrAnalyze *ira) {...@@ -10957,7 +10958,6 @@ static void ir_finish_bb(IrAnalyze *ira) {
10957 ira->instruction_index += 1;10958 ira->instruction_index += 1;
10958 }10959 }
1095910960
10960 size_t my_old_bb_index = ira->old_bb_index;
10961 ira->old_bb_index += 1;10961 ira->old_bb_index += 1;
1096210962
10963 bool need_repeat = true;10963 bool need_repeat = true;
...@@ -10968,17 +10968,17 @@ static void ir_finish_bb(IrAnalyze *ira) {...@@ -10968,17 +10968,17 @@ static void ir_finish_bb(IrAnalyze *ira) {
10968 ira->old_bb_index += 1;10968 ira->old_bb_index += 1;
10969 continue;10969 continue;
10970 }10970 }
10971 // If it's the block we just finished, or10971 // if it's already started, or
10972 // if it's already a finished block, or
10973 // if it's a suspended block,10972 // if it's a suspended block,
10974 // then skip it10973 // then skip it
10975 if (ira->old_bb_index == my_old_bb_index ||10974 if (old_bb->suspended ||
10976 old_bb->suspended ||10975 (old_bb->other != nullptr && old_bb->other->instruction_list.length != 0) ||
10977 (old_bb->other != nullptr && old_bb->other->instruction_list.length != 0))10976 (old_bb->other != nullptr && old_bb->other->already_appended))
10978 {10977 {
10979 ira->old_bb_index += 1;10978 ira->old_bb_index += 1;
10980 continue;10979 continue;
10981 }10980 }
10981
10982 // if there is a resume_stack, pop one from there rather than moving on.10982 // if there is a resume_stack, pop one from there rather than moving on.
10983 // the last item of the resume stack will be a basic block that will10983 // the last item of the resume stack will be a basic block that will
10984 // move on to the next one below10984 // move on to the next one below
...@@ -15520,7 +15520,9 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source...@@ -15520,7 +15520,9 @@ static IrInstruction *ir_analyze_store_ptr(IrAnalyze *ira, IrInstruction *source
15520 // ConstPtrMutComptimeVar, thus defeating the logic below.15520 // ConstPtrMutComptimeVar, thus defeating the logic below.
15521 bool same_global_refs = ptr->value.data.x_ptr.mut != ConstPtrMutComptimeVar;15521 bool same_global_refs = ptr->value.data.x_ptr.mut != ConstPtrMutComptimeVar;
15522 copy_const_val(dest_val, &value->value, same_global_refs);15522 copy_const_val(dest_val, &value->value, same_global_refs);
15523 if (!ira->new_irb.current_basic_block->must_be_comptime_source_instr) {15523 if (ptr->value.data.x_ptr.mut == ConstPtrMutComptimeVar &&
15524 !ira->new_irb.current_basic_block->must_be_comptime_source_instr)
15525 {
15524 ira->new_irb.current_basic_block->must_be_comptime_source_instr = source_instr;15526 ira->new_irb.current_basic_block->must_be_comptime_source_instr = source_instr;
15525 }15527 }
15526 return ir_const_void(ira, source_instr);15528 return ir_const_void(ira, source_instr);
...@@ -16484,6 +16486,19 @@ static IrInstruction *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstruction...@@ -16484,6 +16486,19 @@ static IrInstruction *ir_analyze_instruction_un_op(IrAnalyze *ira, IrInstruction
16484 zig_unreachable();16486 zig_unreachable();
16485}16487}
1648616488
16489static void ir_push_resume(IrAnalyze *ira, IrSuspendPosition pos) {
16490 IrBasicBlock *old_bb = ira->old_irb.exec->basic_block_list.at(pos.basic_block_index);
16491 if (old_bb->in_resume_stack) return;
16492 ira->resume_stack.append(pos);
16493 old_bb->in_resume_stack = true;
16494}
16495
16496static void ir_push_resume_block(IrAnalyze *ira, IrBasicBlock *old_bb) {
16497 if (ira->resume_stack.length != 0) {
16498 ir_push_resume(ira, {old_bb->index, 0});
16499 }
16500}
16501
16487static IrInstruction *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr *br_instruction) {16502static IrInstruction *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr *br_instruction) {
16488 IrBasicBlock *old_dest_block = br_instruction->dest_block;16503 IrBasicBlock *old_dest_block = br_instruction->dest_block;
1648916504
...@@ -16498,6 +16513,8 @@ static IrInstruction *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr...@@ -16498,6 +16513,8 @@ static IrInstruction *ir_analyze_instruction_br(IrAnalyze *ira, IrInstructionBr
16498 if (new_bb == nullptr)16513 if (new_bb == nullptr)
16499 return ir_unreach_error(ira);16514 return ir_unreach_error(ira);
1650016515
16516 ir_push_resume_block(ira, old_dest_block);
16517
16501 IrInstruction *result = ir_build_br(&ira->new_irb,16518 IrInstruction *result = ir_build_br(&ira->new_irb,
16502 br_instruction->base.scope, br_instruction->base.source_node, new_bb, nullptr);16519 br_instruction->base.scope, br_instruction->base.source_node, new_bb, nullptr);
16503 result->value.type = ira->codegen->builtin_types.entry_unreachable;16520 result->value.type = ira->codegen->builtin_types.entry_unreachable;
...@@ -16526,13 +16543,15 @@ static IrInstruction *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstructi...@@ -16526,13 +16543,15 @@ static IrInstruction *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstructi
16526 IrBasicBlock *old_dest_block = cond_is_true ?16543 IrBasicBlock *old_dest_block = cond_is_true ?
16527 cond_br_instruction->then_block : cond_br_instruction->else_block;16544 cond_br_instruction->then_block : cond_br_instruction->else_block;
1652816545
16529 if (is_comptime || old_dest_block->ref_count == 1)16546 if (is_comptime || (old_dest_block->ref_count == 1 && old_dest_block->suspend_instruction_ref == nullptr))
16530 return ir_inline_bb(ira, &cond_br_instruction->base, old_dest_block);16547 return ir_inline_bb(ira, &cond_br_instruction->base, old_dest_block);
1653116548
16532 IrBasicBlock *new_dest_block = ir_get_new_bb_runtime(ira, old_dest_block, &cond_br_instruction->base);16549 IrBasicBlock *new_dest_block = ir_get_new_bb_runtime(ira, old_dest_block, &cond_br_instruction->base);
16533 if (new_dest_block == nullptr)16550 if (new_dest_block == nullptr)
16534 return ir_unreach_error(ira);16551 return ir_unreach_error(ira);
1653516552
16553 ir_push_resume_block(ira, old_dest_block);
16554
16536 IrInstruction *result = ir_build_br(&ira->new_irb,16555 IrInstruction *result = ir_build_br(&ira->new_irb,
16537 cond_br_instruction->base.scope, cond_br_instruction->base.source_node, new_dest_block, nullptr);16556 cond_br_instruction->base.scope, cond_br_instruction->base.source_node, new_dest_block, nullptr);
16538 result->value.type = ira->codegen->builtin_types.entry_unreachable;16557 result->value.type = ira->codegen->builtin_types.entry_unreachable;
...@@ -16548,6 +16567,9 @@ static IrInstruction *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstructi...@@ -16548,6 +16567,9 @@ static IrInstruction *ir_analyze_instruction_cond_br(IrAnalyze *ira, IrInstructi
16548 if (new_else_block == nullptr)16567 if (new_else_block == nullptr)
16549 return ir_unreach_error(ira);16568 return ir_unreach_error(ira);
1655016569
16570 ir_push_resume_block(ira, cond_br_instruction->else_block);
16571 ir_push_resume_block(ira, cond_br_instruction->then_block);
16572
16551 IrInstruction *result = ir_build_cond_br(&ira->new_irb,16573 IrInstruction *result = ir_build_cond_br(&ira->new_irb,
16552 cond_br_instruction->base.scope, cond_br_instruction->base.source_node,16574 cond_br_instruction->base.scope, cond_br_instruction->base.source_node,
16553 casted_condition, new_then_block, new_else_block, nullptr);16575 casted_condition, new_then_block, new_else_block, nullptr);
...@@ -16643,14 +16665,14 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh...@@ -16643,14 +16665,14 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh
1664316665
16644 IrSuspendPosition suspend_pos;16666 IrSuspendPosition suspend_pos;
16645 ira_suspend(ira, &phi_instruction->base, nullptr, &suspend_pos);16667 ira_suspend(ira, &phi_instruction->base, nullptr, &suspend_pos);
16646 ira->resume_stack.append(suspend_pos);16668 ir_push_resume(ira, suspend_pos);
1664716669
16648 for (size_t i = 0; i < peer_parent->peer_count; i += 1) {16670 for (size_t i = 0; i < peer_parent->peer_count; i += 1) {
16649 ResultLocPeer *opposite_peer = &peer_parent->peers[peer_parent->peer_count - i - 1];16671 ResultLocPeer *opposite_peer = &peer_parent->peers[peer_parent->peer_count - i - 1];
16650 if (opposite_peer->base.implicit_elem_type != nullptr &&16672 if (opposite_peer->base.implicit_elem_type != nullptr &&
16651 opposite_peer->base.implicit_elem_type->id != ZigTypeIdUnreachable)16673 opposite_peer->base.implicit_elem_type->id != ZigTypeIdUnreachable)
16652 {16674 {
16653 ira->resume_stack.append(opposite_peer->suspend_pos);16675 ir_push_resume(ira, opposite_peer->suspend_pos);
16654 }16676 }
16655 }16677 }
1665616678
...@@ -25017,9 +25039,9 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_...@@ -25017,9 +25039,9 @@ ZigType *ir_analyze(CodeGen *codegen, IrExecutable *old_exec, IrExecutable *new_
25017 continue;25039 continue;
25018 }25040 }
2501925041
25020 //if (ira->codegen->verbose_ir) {25042 if (ira->codegen->verbose_ir) {
25021 // fprintf(stderr, "analyze #%zu\n", old_instruction->debug_id);25043 fprintf(stderr, "analyze #%zu\n", old_instruction->debug_id);
25022 //}25044 }
25023 IrInstruction *new_instruction = ir_analyze_instruction_base(ira, old_instruction);25045 IrInstruction *new_instruction = ir_analyze_instruction_base(ira, old_instruction);
25024 if (new_instruction != nullptr) {25046 if (new_instruction != nullptr) {
25025 ir_assert(new_instruction->value.type != nullptr || new_instruction->value.type != nullptr, old_instruction);25047 ir_assert(new_instruction->value.type != nullptr || new_instruction->value.type != nullptr, old_instruction);
test/stage1/behavior.zig+1-1
...@@ -80,7 +80,7 @@ comptime {...@@ -80,7 +80,7 @@ comptime {
80 _ = @import("behavior/struct_contains_null_ptr_itself.zig");80 _ = @import("behavior/struct_contains_null_ptr_itself.zig");
81 _ = @import("behavior/struct_contains_slice_of_itself.zig");81 _ = @import("behavior/struct_contains_slice_of_itself.zig");
82 _ = @import("behavior/switch.zig");82 _ = @import("behavior/switch.zig");
83 //_ = @import("behavior/switch_prong_err_enum.zig");83 _ = @import("behavior/switch_prong_err_enum.zig");
84 _ = @import("behavior/switch_prong_implicit_cast.zig");84 _ = @import("behavior/switch_prong_implicit_cast.zig");
85 _ = @import("behavior/syntax.zig");85 _ = @import("behavior/syntax.zig");
86 _ = @import("behavior/this.zig");86 _ = @import("behavior/this.zig");