authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-06-07 11:34:47-04:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2019-06-07 11:34:47-04:00
log76a3938d69e23a22ee2d5db971737c532ee8a6b0
tree175f87fd222edfefd2ec2136619ff1e3a2b165c8
parentb19b1c1298f755238e7b6a54e5482616d923f9a8
signaturelock-open Commit is signed but in an unrecognized format.

no-copy semantics for peer result function calls

```zig export fn entry() void { var c = true; var x = if (c) foo() else bar(); } ``` ```llvm define void @entry() #2 !dbg !35 { Entry: %c = alloca i1, align 1 %x = alloca %Foo, align 4 store i1 true, i1* %c, align 1, !dbg !47 call void @llvm.dbg.declare(metadata i1* %c, metadata !39, metadata !DIExpression()), !dbg !48 %0 = load i1, i1* %c, align 1, !dbg !49 br i1 %0, label %Then, label %Else, !dbg !49 Then: ; preds = %Entry call fastcc void @foo(%Foo* sret %x), !dbg !50 br label %EndIf, !dbg !51 Else: ; preds = %Entry call fastcc void @bar(%Foo* sret %x), !dbg !52 br label %EndIf, !dbg !51 EndIf: ; preds = %Else, %Then call void @llvm.dbg.declare(metadata %Foo* %x, metadata !42, metadata !DIExpression()), !dbg !53 ret void, !dbg !54 } ```

4 files changed, 137 insertions(+), 74 deletions(-)

BRANCH_TODO+8
......@@ -31,3 +31,11 @@ inferred comptime
3131
3232handle if with no else
3333
34
35
36static IrInstruction *ir_const_unreachable(IrAnalyze *ira, IrInstruction *source_instruction) {
37 IrInstruction *result = ir_const(ira, source_instruction, ira->codegen->builtin_types.entry_unreachable);
38 result->value.special = ConstValSpecialStatic;
39 return result;
40}
41
src/all_types.hpp+3-1
......@@ -3590,8 +3590,10 @@ enum ResultLocId {
35903590
35913591struct ResultLoc {
35923592 ResultLocId id;
3593 bool written;
3594 IrInstruction *resolved_loc; // result ptr
35933595 IrInstruction *source_instruction;
3594 IrInstruction *gen_instruction;
3596 IrInstruction *gen_instruction; // value to store to the result loc
35953597 ZigType *implicit_elem_type;
35963598};
35973599
src/ir.cpp+119-71
......@@ -185,7 +185,8 @@ static IrInstruction *ir_analyze_int_to_ptr(IrAnalyze *ira, IrInstruction *sourc
185185 ZigType *ptr_type);
186186static IrInstruction *ir_analyze_bit_cast(IrAnalyze *ira, IrInstruction *source_instr, IrInstruction *value,
187187 ZigType *dest_type);
188static IrInstruction *ir_resolve_result(IrAnalyze *ira, ResultLoc *result_loc, ZigType *value_type, IrInstruction *value);
188static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_source_instr,
189 ResultLoc *result_loc, ZigType *value_type, IrInstruction *value);
189190
190191static ConstExprValue *const_ptr_pointee_unchecked(CodeGen *g, ConstExprValue *const_val) {
191192 assert(get_src_ptr_type(const_val->type) != nullptr);
......@@ -1376,11 +1377,8 @@ static IrInstruction *ir_build_call_src(IrBuilder *irb, Scope *scope, AstNode *s
13761377static IrInstruction *ir_build_call_gen(IrAnalyze *ira, IrInstruction *source_instruction,
13771378 ZigFn *fn_entry, IrInstruction *fn_ref, size_t arg_count, IrInstruction **args,
13781379 FnInline fn_inline, bool is_async, IrInstruction *async_allocator, IrInstruction *new_stack,
1379 ResultLoc *result_loc, ZigType *return_type)
1380 IrInstruction *result_loc, ZigType *return_type)
13801381{
1381 // must be resolved before building the call instruction
1382 IrInstruction *resolved_result_loc = ir_resolve_result(ira, result_loc, return_type, nullptr);
1383
13841382 IrInstructionCallGen *call_instruction = ir_build_instruction<IrInstructionCallGen>(&ira->new_irb,
13851383 source_instruction->scope, source_instruction->source_node);
13861384 call_instruction->base.value.type = return_type;
......@@ -1392,14 +1390,14 @@ static IrInstruction *ir_build_call_gen(IrAnalyze *ira, IrInstruction *source_in
13921390 call_instruction->is_async = is_async;
13931391 call_instruction->async_allocator = async_allocator;
13941392 call_instruction->new_stack = new_stack;
1395 call_instruction->result_loc = resolved_result_loc;
1393 call_instruction->result_loc = result_loc;
13961394
13971395 if (fn_ref != nullptr) ir_ref_instruction(fn_ref, ira->new_irb.current_basic_block);
13981396 for (size_t i = 0; i < arg_count; i += 1)
13991397 ir_ref_instruction(args[i], ira->new_irb.current_basic_block);
14001398 if (async_allocator != nullptr) ir_ref_instruction(async_allocator, ira->new_irb.current_basic_block);
14011399 if (new_stack != nullptr) ir_ref_instruction(new_stack, ira->new_irb.current_basic_block);
1402 if (call_instruction->result_loc != nullptr) ir_ref_instruction(call_instruction->result_loc, ira->new_irb.current_basic_block);
1400 if (result_loc != nullptr) ir_ref_instruction(result_loc, ira->new_irb.current_basic_block);
14031401
14041402 return &call_instruction->base;
14051403}
......@@ -5366,7 +5364,7 @@ static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode
53665364 incoming_blocks[1] = after_else_block;
53675365
53685366 IrInstruction *phi = ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values);
5369 return ir_lval_wrap(irb, scope, phi, lval, result_loc);
5367 return ir_expr_wrap(irb, scope, phi, result_loc);
53705368}
53715369
53725370static IrInstruction *ir_gen_prefix_op_id_lval(IrBuilder *irb, Scope *scope, AstNode *node, IrUnOp op_id, LVal lval) {
......@@ -6558,10 +6556,11 @@ static bool ir_gen_switch_prong_expr(IrBuilder *irb, Scope *scope, AstNode *swit
65586556 return true;
65596557}
65606558
6561static void next_peer_block(ZigList<ResultLocPeer> *list, IrBasicBlock *next_bb) {
6562 if (list->length >= 2) {
6563 list->at(list->length - 2).next_bb = next_bb;
6559static void next_peer_block(ResultLocPeerParent *peer_parent, IrBasicBlock *next_bb) {
6560 if (peer_parent->peer_count > 0) {
6561 peer_parent->peers[peer_parent->peer_count - 1].next_bb = next_bb;
65646562 }
6563 peer_parent->peer_count += 1;
65656564}
65666565
65676566static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval,
......@@ -6600,8 +6599,8 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
66006599 ResultLocPeerParent *peer_parent = allocate<ResultLocPeerParent>(1);
66016600 peer_parent->base.id = ResultLocIdPeerParent;
66026601 peer_parent->parent = result_loc;
6603
6604 ZigList<ResultLocPeer> peer_result_locs = {};
6602 peer_parent->peers = allocate<ResultLocPeer>(prong_count);
6603 peer_parent->peer_count = 0;
66056604
66066605 // First do the else and the ranges
66076606 Scope *subexpr_scope = create_runtime_scope(irb->codegen, node, scope, is_comptime);
......@@ -6611,7 +6610,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
66116610 AstNode *prong_node = node->data.switch_expr.prongs.at(prong_i);
66126611 size_t prong_item_count = prong_node->data.switch_prong.items.length;
66136612 if (prong_item_count == 0) {
6614 ResultLocPeer *this_peer_result_loc = peer_result_locs.add_one();
6613 ResultLocPeer *this_peer_result_loc = &peer_parent->peers[peer_parent->peer_count];
66156614 this_peer_result_loc->base.id = ResultLocIdPeer;
66166615 this_peer_result_loc->parent = peer_parent;
66176616 if (else_prong) {
......@@ -6624,7 +6623,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
66246623 else_prong = prong_node;
66256624
66266625 IrBasicBlock *prev_block = irb->current_basic_block;
6627 next_peer_block(&peer_result_locs, else_block);
6626 next_peer_block(peer_parent, else_block);
66286627 ir_set_cursor_at_end_and_append_block(irb, else_block);
66296628 if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block,
66306629 is_comptime, var_is_comptime, target_value_ptr, nullptr, 0, &incoming_blocks, &incoming_values,
......@@ -6634,7 +6633,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
66346633 }
66356634 ir_set_cursor_at_end(irb, prev_block);
66366635 } else if (prong_node->data.switch_prong.any_items_are_range) {
6637 ResultLocPeer *this_peer_result_loc = peer_result_locs.add_one();
6636 ResultLocPeer *this_peer_result_loc = &peer_parent->peers[peer_parent->peer_count];
66386637 this_peer_result_loc->base.id = ResultLocIdPeer;
66396638 this_peer_result_loc->parent = peer_parent;
66406639
......@@ -6697,7 +6696,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
66976696 ir_mark_gen(ir_build_cond_br(irb, scope, last_item_node, ok_bit, range_block_yes,
66986697 range_block_no, is_comptime));
66996698
6700 next_peer_block(&peer_result_locs, range_block_yes);
6699 next_peer_block(peer_parent, range_block_yes);
67016700 ir_set_cursor_at_end_and_append_block(irb, range_block_yes);
67026701 if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block,
67036702 is_comptime, var_is_comptime, target_value_ptr, nullptr, 0,
......@@ -6719,7 +6718,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
67196718 if (prong_node->data.switch_prong.any_items_are_range)
67206719 continue;
67216720
6722 ResultLocPeer *this_peer_result_loc = peer_result_locs.add_one();
6721 ResultLocPeer *this_peer_result_loc = &peer_parent->peers[peer_parent->peer_count];
67236722 this_peer_result_loc->base.id = ResultLocIdPeer;
67246723 this_peer_result_loc->parent = peer_parent;
67256724
......@@ -6746,7 +6745,7 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
67466745 }
67476746
67486747 IrBasicBlock *prev_block = irb->current_basic_block;
6749 next_peer_block(&peer_result_locs, prong_block);
6748 next_peer_block(peer_parent, prong_block);
67506749 ir_set_cursor_at_end_and_append_block(irb, prong_block);
67516750 if (!ir_gen_switch_prong_expr(irb, subexpr_scope, node, prong_node, end_block,
67526751 is_comptime, var_is_comptime, target_value_ptr, items, prong_item_count,
......@@ -6773,22 +6772,20 @@ static IrInstruction *ir_gen_switch_expr(IrBuilder *irb, Scope *scope, AstNode *
67736772 }
67746773 br_instruction = &switch_br->base;
67756774 }
6776 for (size_t i = 0; i < peer_result_locs.length; i += 1) {
6777 peer_result_locs.at(i).base.source_instruction = br_instruction;
6775 for (size_t i = 0; i < peer_parent->peer_count; i += 1) {
6776 peer_parent->peers[i].base.source_instruction = br_instruction;
67786777 }
67796778 peer_parent->base.source_instruction = br_instruction;
6780 peer_parent->peer_count = peer_result_locs.length;
6781 peer_parent->peers = peer_result_locs.items;
67826779
67836780 if (!else_prong) {
6784 if (peer_result_locs.length != 0) {
6785 peer_result_locs.last().next_bb = else_block;
6781 if (peer_parent->peer_count != 0) {
6782 peer_parent->peers[peer_parent->peer_count - 1].next_bb = else_block;
67866783 }
67876784 ir_set_cursor_at_end_and_append_block(irb, else_block);
67886785 ir_build_unreachable(irb, scope, node);
67896786 } else {
6790 if (peer_result_locs.length != 0) {
6791 peer_result_locs.last().next_bb = end_block;
6787 if (peer_parent->peer_count != 0) {
6788 peer_parent->peers[peer_parent->peer_count - 1].next_bb = end_block;
67926789 }
67936790 }
67946791
......@@ -14400,12 +14397,12 @@ static ZigType *ir_result_loc_expected_type(IrAnalyze *ira, ResultLoc *result_lo
1440014397
1440114398// give nullptr for value to resolve it at runtime
1440214399// returns a result location, or nullptr if the result location was already taken care of
14403static IrInstruction *ir_resolve_result(IrAnalyze *ira, ResultLoc *result_loc, ZigType *value_type,
14404 IrInstruction *value)
14400// when calling this function, at the callsite must check for result type noreturn and propagate it up
14401static IrInstruction *ir_resolve_result(IrAnalyze *ira, IrInstruction *suspend_source_instr,
14402 ResultLoc *result_loc, ZigType *value_type, IrInstruction *value)
1440514403{
14406 if (result_loc->implicit_elem_type != nullptr) {
14407 // already resolved
14408 return nullptr;
14404 if (result_loc->resolved_loc != nullptr) {
14405 return result_loc->resolved_loc;
1440914406 }
1441014407 result_loc->gen_instruction = value;
1441114408 result_loc->implicit_elem_type = value_type;
......@@ -14420,12 +14417,12 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, ResultLoc *result_loc, Z
1442014417 assert(result_loc->source_instruction->id == IrInstructionIdAllocaSrc);
1442114418 IrInstructionAllocaSrc *alloca_src =
1442214419 reinterpret_cast<IrInstructionAllocaSrc *>(result_loc->source_instruction);
14420 bool force_comptime;
14421 if (!ir_resolve_comptime(ira, alloca_src->is_comptime->child, &force_comptime))
14422 return ira->codegen->invalid_instruction;
14423 bool is_comptime = force_comptime || (value != nullptr &&
14424 value->value.special != ConstValSpecialRuntime && result_loc_var->var->gen_is_const);
1442314425 if (alloca_src->base.child == nullptr) {
14424 bool force_comptime;
14425 if (!ir_resolve_comptime(ira, alloca_src->is_comptime->child, &force_comptime))
14426 return ira->codegen->invalid_instruction;
14427 bool is_comptime = force_comptime || (value != nullptr &&
14428 value->value.special != ConstValSpecialRuntime && result_loc_var->var->gen_is_const);
1442914426 uint32_t align = 0;
1443014427 if (alloca_src->align != nullptr && !ir_resolve_align(ira, alloca_src->align->child, &align)) {
1443114428 return ira->codegen->invalid_instruction;
......@@ -14441,18 +14438,67 @@ static IrInstruction *ir_resolve_result(IrAnalyze *ira, ResultLoc *result_loc, Z
1444114438 alloca_src->name_hint, force_comptime);
1444214439 }
1444314440 alloca_src->base.child = alloca_gen;
14444 return is_comptime ? nullptr : alloca_src->base.child;
1444514441 }
14446 return nullptr;
14442 result_loc->written = true;
14443 result_loc->resolved_loc = is_comptime ? nullptr : alloca_src->base.child;
14444 return result_loc->resolved_loc;
1444714445 }
1444814446 case ResultLocIdReturn: {
1444914447 bool is_comptime = value != nullptr && value->value.special != ConstValSpecialRuntime;
1445014448 if (is_comptime) return nullptr;
1445114449 ZigType *ptr_return_type = get_pointer_to_type(ira->codegen, ira->explicit_return_type, false);
14452 return ir_build_return_ptr(ira, result_loc->source_instruction, ptr_return_type);
14450 result_loc->written = true;
14451 result_loc->resolved_loc = ir_build_return_ptr(ira, result_loc->source_instruction, ptr_return_type);
14452 return result_loc->resolved_loc;
14453 }
14454 case ResultLocIdPeer: {
14455 ResultLocPeer *result_peer = reinterpret_cast<ResultLocPeer *>(result_loc);
14456 ResultLocPeerParent *peer_parent = result_peer->parent;
14457
14458 if (ira->const_predecessor_bb)
14459 return nullptr;
14460
14461 if (peer_parent->resolved_type == nullptr) {
14462 IrInstruction *suspended_inst = ira_suspend(ira, suspend_source_instr,
14463 result_peer->next_bb, &result_peer->suspend_pos);
14464 bool last_one = (result_peer == &peer_parent->peers[peer_parent->peer_count - 1]);
14465 if (!last_one) {
14466 return suspended_inst;
14467 }
14468 IrInstruction **instructions = allocate<IrInstruction *>(peer_parent->peer_count);
14469 for (size_t i = 0; i < peer_parent->peer_count; i += 1) {
14470 ResultLocPeer *this_peer = &peer_parent->peers[i];
14471 ResultLocPeer *opposite_peer = &peer_parent->peers[peer_parent->peer_count - i - 1];
14472
14473 IrInstruction *gen_instruction = this_peer->base.gen_instruction;
14474 if (gen_instruction == nullptr) {
14475 instructions[i] = ir_const(ira, this_peer->base.source_instruction,
14476 this_peer->base.implicit_elem_type);
14477 instructions[i]->value.special = ConstValSpecialRuntime;
14478 } else {
14479 instructions[i] = gen_instruction;
14480 }
14481 if (opposite_peer->base.implicit_elem_type->id != ZigTypeIdUnreachable) {
14482 ira->resume_stack.append(opposite_peer->suspend_pos);
14483 }
14484 }
14485 ZigType *expected_type = ir_result_loc_expected_type(ira, peer_parent->parent);
14486 peer_parent->resolved_type = ir_resolve_peer_types(ira,
14487 peer_parent->base.source_instruction->source_node, expected_type, instructions,
14488 peer_parent->peer_count);
14489 return ira_resume(ira);
14490 }
14491
14492 IrInstruction *parent_result_loc = ir_resolve_result(ira, suspend_source_instr, peer_parent->parent,
14493 peer_parent->resolved_type, nullptr);
14494 if (parent_result_loc == nullptr || type_is_invalid(parent_result_loc->value.type) ||
14495 parent_result_loc->value.type->id == ZigTypeIdUnreachable)
14496 {
14497 return parent_result_loc;
14498 }
14499 result_loc->resolved_loc = parent_result_loc;
14500 return result_loc->resolved_loc;
1445314501 }
14454 case ResultLocIdPeer:
14455 return nullptr;
1445614502 }
1445714503 zig_unreachable();
1445814504}
......@@ -14504,7 +14550,7 @@ static IrInstruction *ir_analyze_async_call(IrAnalyze *ira, IrInstructionCallSrc
1450414550 ZigType *async_return_type = get_error_union_type(ira->codegen, alloc_fn_error_set_type, promise_type);
1450514551
1450614552 return ir_build_call_gen(ira, &call_instruction->base, fn_entry, fn_ref, arg_count,
14507 casted_args, FnInlineAuto, true, async_allocator_inst, nullptr, call_instruction->result_loc,
14553 casted_args, FnInlineAuto, true, async_allocator_inst, nullptr, nullptr,
1450814554 async_return_type);
1450914555}
1451014556
......@@ -15246,6 +15292,14 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
1524615292 }
1524715293
1524815294 FnTypeId *impl_fn_type_id = &impl_fn->type_entry->data.fn.fn_type_id;
15295 IrInstruction *result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc,
15296 impl_fn_type_id->return_type, nullptr);
15297 if (result_loc != nullptr &&
15298 (type_is_invalid(result_loc->value.type) || result_loc->value.type->id == ZigTypeIdUnreachable))
15299 {
15300 return result_loc;
15301 }
15302
1524915303 if (fn_type_can_fail(impl_fn_type_id)) {
1525015304 parent_fn_entry->calls_or_awaits_errorable_fn = true;
1525115305 }
......@@ -15257,10 +15311,11 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
1525715311 return ir_finish_anal(ira, result);
1525815312 }
1525915313
15314 call_instruction->result_loc->written = true;
1526015315 assert(async_allocator_inst == nullptr);
1526115316 IrInstruction *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base,
1526215317 impl_fn, nullptr, impl_param_count, casted_args, fn_inline,
15263 call_instruction->is_async, nullptr, casted_new_stack, call_instruction->result_loc,
15318 call_instruction->is_async, nullptr, casted_new_stack, result_loc,
1526415319 impl_fn_type_id->return_type);
1526515320
1526615321 return ir_finish_anal(ira, new_call_instruction);
......@@ -15355,9 +15410,18 @@ static IrInstruction *ir_analyze_fn_call(IrAnalyze *ira, IrInstructionCallSrc *c
1535515410 return ira->codegen->invalid_instruction;
1535615411 }
1535715412
15413 IrInstruction *result_loc = ir_resolve_result(ira, &call_instruction->base, call_instruction->result_loc,
15414 return_type, nullptr);
15415 if (result_loc != nullptr &&
15416 (type_is_invalid(result_loc->value.type) || result_loc->value.type->id == ZigTypeIdUnreachable))
15417 {
15418 return result_loc;
15419 }
15420
15421 call_instruction->result_loc->written = true;
1535815422 IrInstruction *new_call_instruction = ir_build_call_gen(ira, &call_instruction->base, fn_entry, fn_ref,
1535915423 call_param_count, casted_args, fn_inline, false, nullptr, casted_new_stack,
15360 call_instruction->result_loc, return_type);
15424 result_loc, return_type);
1536115425 return ir_finish_anal(ira, new_call_instruction);
1536215426}
1536315427
......@@ -23619,35 +23683,19 @@ static IrInstruction *ir_analyze_instruction_end_expr(IrAnalyze *ira, IrInstruct
2361923683 if (type_is_invalid(value->value.type))
2362023684 return ira->codegen->invalid_instruction;
2362123685
23622 if (instruction->result_loc->id == ResultLocIdPeer) {
23623 ResultLocPeer *result_peer = reinterpret_cast<ResultLocPeer *>(instruction->result_loc);
23624 ResultLocPeerParent *peer_parent = result_peer->parent;
23686 if (!instruction->result_loc->written) {
23687 IrInstruction *result_loc = ir_resolve_result(ira, &instruction->base, instruction->result_loc,
23688 value->value.type, value);
23689 if (result_loc != nullptr) {
23690 if (type_is_invalid(result_loc->value.type))
23691 return ira->codegen->invalid_instruction;
23692 if (result_loc->value.type->id == ZigTypeIdUnreachable)
23693 return result_loc;
2362523694
23626 if (peer_parent->resolved_type == nullptr && !ira->const_predecessor_bb) {
23627 instruction->result_loc->implicit_elem_type = value->value.type;
23628 instruction->result_loc->gen_instruction = value;
23629 IrInstruction *suspended_inst = ira_suspend(ira, &instruction->base, result_peer->next_bb,
23630 &result_peer->suspend_pos);
23631 bool last_one = (result_peer == &peer_parent->peers[peer_parent->peer_count - 1]);
23632 if (!last_one) {
23633 return suspended_inst;
23634 }
23635 IrInstruction **instructions = allocate<IrInstruction *>(peer_parent->peer_count);
23636 for (size_t i = 0; i < peer_parent->peer_count; i += 1) {
23637 instructions[i] = peer_parent->peers[i].base.gen_instruction;
23638 ira->resume_stack.append(peer_parent->peers[peer_parent->peer_count - i - 1].suspend_pos);
23639 }
23640 ZigType *expected_type = ir_result_loc_expected_type(ira, peer_parent->parent);
23641 peer_parent->resolved_type = ir_resolve_peer_types(ira,
23642 peer_parent->base.source_instruction->source_node, expected_type, instructions,
23643 peer_parent->peer_count);
23644 return ira_resume(ira);
23695 instruction->result_loc->written = true;
23696 ir_analyze_store_ptr(ira, &instruction->base, result_loc, value);
2364523697 }
2364623698 }
23647 IrInstruction *result_loc = ir_resolve_result(ira, instruction->result_loc, value->value.type, value);
23648 if (result_loc != nullptr && !type_is_invalid(result_loc->value.type)) {
23649 ir_analyze_store_ptr(ira, &instruction->base, result_loc, value);
23650 }
2365123699
2365223700 return ir_const_void(ira, &instruction->base);
2365323701}
src/ir_print.cpp+7-2
......@@ -207,6 +207,12 @@ static void ir_print_result_loc_var(IrPrint *irp, ResultLocVar *result_loc_var)
207207 fprintf(irp->f, ")");
208208}
209209
210static void ir_print_result_loc_peer(IrPrint *irp, ResultLocPeer *result_loc_peer) {
211 fprintf(irp->f, "peer(next=");
212 ir_print_other_block(irp, result_loc_peer->next_bb);
213 fprintf(irp->f, ")");
214}
215
210216static void ir_print_result_loc(IrPrint *irp, ResultLoc *result_loc) {
211217 switch (result_loc->id) {
212218 case ResultLocIdInvalid:
......@@ -220,8 +226,7 @@ static void ir_print_result_loc(IrPrint *irp, ResultLoc *result_loc) {
220226 case ResultLocIdVar:
221227 return ir_print_result_loc_var(irp, (ResultLocVar *)result_loc);
222228 case ResultLocIdPeer:
223 fprintf(irp->f, "peer");
224 return;
229 return ir_print_result_loc_peer(irp, (ResultLocPeer *)result_loc);
225230 case ResultLocIdPeerParent:
226231 fprintf(irp->f, "peer_parent");
227232 return;