| ... | ... | @@ -16395,45 +16395,56 @@ static IrInstruction *ir_analyze_instruction_phi(IrAnalyze *ira, IrInstructionPh |
| 16395 | 16395 | } |
| 16396 | 16396 | |
| 16397 | 16397 | ResultLocPeerParent *peer_parent = phi_instruction->peer_parent; |
| 16398 | | if (peer_parent != nullptr && peer_parent->resolved_type == nullptr && !peer_parent->skipped) { |
| 16399 | | // Suspend the phi first so that it gets resumed last |
| 16400 | | ira->resume_stack.add_one(); |
| 16401 | | for (size_t i = ira->resume_stack.length;;) { |
| 16402 | | if (i <= 1) break; |
| 16403 | | i -= 1; |
| 16404 | | ira->resume_stack.items[i] = ira->resume_stack.items[i-1]; |
| 16398 | if (peer_parent != nullptr && !peer_parent->skipped && !peer_parent->done_resuming) { |
| 16399 | if (peer_parent->resolved_type == nullptr) { |
| 16400 | IrInstruction **instructions = allocate<IrInstruction *>(peer_parent->peer_count); |
| 16401 | for (size_t i = 0; i < peer_parent->peer_count; i += 1) { |
| 16402 | ResultLocPeer *this_peer = &peer_parent->peers[i]; |
| 16403 | |
| 16404 | IrInstruction *gen_instruction = this_peer->base.gen_instruction; |
| 16405 | if (gen_instruction == nullptr) { |
| 16406 | // unreachable instructions will cause implicit_elem_type to be null |
| 16407 | if (this_peer->base.implicit_elem_type == nullptr) { |
| 16408 | instructions[i] = ir_const_unreachable(ira, this_peer->base.source_instruction); |
| 16409 | } else { |
| 16410 | instructions[i] = ir_const(ira, this_peer->base.source_instruction, |
| 16411 | this_peer->base.implicit_elem_type); |
| 16412 | instructions[i]->value.special = ConstValSpecialRuntime; |
| 16413 | } |
| 16414 | } else { |
| 16415 | instructions[i] = gen_instruction; |
| 16416 | } |
| 16417 | |
| 16418 | } |
| 16419 | ZigType *expected_type = ir_result_loc_expected_type(ira, &phi_instruction->base, peer_parent->parent); |
| 16420 | peer_parent->resolved_type = ir_resolve_peer_types(ira, |
| 16421 | peer_parent->base.source_instruction->source_node, expected_type, instructions, |
| 16422 | peer_parent->peer_count); |
| 16423 | |
| 16424 | // In case resolving the parent activates a suspend, do it now |
| 16425 | IrInstruction *parent_result_loc = ir_resolve_result(ira, &phi_instruction->base, peer_parent->parent, |
| 16426 | peer_parent->resolved_type, nullptr); |
| 16427 | if (parent_result_loc != nullptr && |
| 16428 | (type_is_invalid(parent_result_loc->value.type) || instr_is_unreachable(parent_result_loc))) |
| 16429 | { |
| 16430 | return parent_result_loc; |
| 16431 | } |
| 16405 | 16432 | } |
| 16406 | | ira_suspend(ira, &phi_instruction->base, nullptr, &ira->resume_stack.items[0]); |
| 16407 | 16433 | |
| 16408 | | IrInstruction **instructions = allocate<IrInstruction *>(peer_parent->peer_count); |
| 16434 | IrSuspendPosition suspend_pos; |
| 16435 | ira_suspend(ira, &phi_instruction->base, nullptr, &suspend_pos); |
| 16436 | ira->resume_stack.append(suspend_pos); |
| 16437 | |
| 16409 | 16438 | for (size_t i = 0; i < peer_parent->peer_count; i += 1) { |
| 16410 | | ResultLocPeer *this_peer = &peer_parent->peers[i]; |
| 16411 | 16439 | ResultLocPeer *opposite_peer = &peer_parent->peers[peer_parent->peer_count - i - 1]; |
| 16412 | | |
| 16413 | | IrInstruction *gen_instruction = this_peer->base.gen_instruction; |
| 16414 | | if (gen_instruction == nullptr) { |
| 16415 | | // unreachable instructions will cause implicit_elem_type to be null |
| 16416 | | if (this_peer->base.implicit_elem_type == nullptr) { |
| 16417 | | instructions[i] = ir_const_unreachable(ira, this_peer->base.source_instruction); |
| 16418 | | } else { |
| 16419 | | instructions[i] = ir_const(ira, this_peer->base.source_instruction, |
| 16420 | | this_peer->base.implicit_elem_type); |
| 16421 | | instructions[i]->value.special = ConstValSpecialRuntime; |
| 16422 | | } |
| 16423 | | } else { |
| 16424 | | instructions[i] = gen_instruction; |
| 16425 | | } |
| 16426 | 16440 | if (opposite_peer->base.implicit_elem_type != nullptr && |
| 16427 | 16441 | opposite_peer->base.implicit_elem_type->id != ZigTypeIdUnreachable) |
| 16428 | 16442 | { |
| 16429 | 16443 | ira->resume_stack.append(opposite_peer->suspend_pos); |
| 16430 | 16444 | } |
| 16431 | 16445 | } |
| 16432 | | ZigType *expected_type = ir_result_loc_expected_type(ira, &phi_instruction->base, peer_parent->parent); |
| 16433 | | peer_parent->resolved_type = ir_resolve_peer_types(ira, |
| 16434 | | peer_parent->base.source_instruction->source_node, expected_type, instructions, |
| 16435 | | peer_parent->peer_count); |
| 16436 | 16446 | |
| 16447 | peer_parent->done_resuming = true; |
| 16437 | 16448 | return ira_resume(ira); |
| 16438 | 16449 | } |
| 16439 | 16450 | |