diff options
| -rw-r--r-- | src/ir.cpp | 140 |
1 files changed, 73 insertions, 67 deletions
diff --git a/src/ir.cpp b/src/ir.cpp index 41da32d551..34d3c2fb5b 100644 --- a/src/ir.cpp +++ b/src/ir.cpp @@ -3795,7 +3795,29 @@ static IrInstruction *ir_gen_bool_and(IrBuilder *irb, Scope *scope, AstNode *nod return ir_build_phi(irb, scope, node, 2, incoming_blocks, incoming_values); } -static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode *node) { +static ResultLocPeerParent *create_binary_result_peers(IrInstruction *cond_br_inst, + IrBasicBlock *else_block, IrBasicBlock *endif_block, ResultLoc *parent) +{ + ResultLocPeerParent *peer_parent = allocate<ResultLocPeerParent>(1); + peer_parent->base.id = ResultLocIdPeerParent; + peer_parent->base.source_instruction = cond_br_inst; + peer_parent->parent = parent; + peer_parent->peer_count = 2; + peer_parent->peers = allocate<ResultLocPeer>(2); + peer_parent->peers[0].base.id = ResultLocIdPeer; + peer_parent->peers[0].base.source_instruction = cond_br_inst; + peer_parent->peers[0].parent = peer_parent; + peer_parent->peers[0].next_bb = else_block; + peer_parent->peers[1].base.id = ResultLocIdPeer; + peer_parent->peers[1].base.source_instruction = cond_br_inst; + peer_parent->peers[1].parent = peer_parent; + peer_parent->peers[1].next_bb = endif_block; + return peer_parent; +} + +static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode *node, LVal lval, + ResultLoc *result_loc) +{ assert(node->type == NodeTypeBinOpExpr); AstNode *op1_node = node->data.bin_op_expr.op1; @@ -3818,10 +3840,12 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode IrBasicBlock *ok_block = ir_create_basic_block(irb, parent_scope, "OptionalNonNull"); IrBasicBlock *null_block = ir_create_basic_block(irb, parent_scope, "OptionalNull"); IrBasicBlock *end_block = ir_create_basic_block(irb, parent_scope, "OptionalEnd"); - ir_build_cond_br(irb, parent_scope, node, is_non_null, ok_block, null_block, is_comptime); + IrInstruction *cond_br_inst = ir_build_cond_br(irb, parent_scope, node, is_non_null, ok_block, null_block, is_comptime); + + ResultLocPeerParent *peer_parent = create_binary_result_peers(cond_br_inst, ok_block, end_block, result_loc); ir_set_cursor_at_end_and_append_block(irb, null_block); - IrInstruction *null_result = ir_gen_node(irb, op2_node, parent_scope); + IrInstruction *null_result = ir_gen_node_extra(irb, op2_node, parent_scope, lval, &peer_parent->peers[0].base); if (null_result == irb->codegen->invalid_instruction) return irb->codegen->invalid_instruction; IrBasicBlock *after_null_block = irb->current_basic_block; @@ -3831,6 +3855,7 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode ir_set_cursor_at_end_and_append_block(irb, ok_block); IrInstruction *unwrapped_ptr = ir_build_optional_unwrap_ptr(irb, parent_scope, node, maybe_ptr, false); IrInstruction *unwrapped_payload = ir_build_load_ptr(irb, parent_scope, node, unwrapped_ptr); + ir_build_end_expr(irb, parent_scope, node, unwrapped_payload, &peer_parent->peers[1].base); IrBasicBlock *after_ok_block = irb->current_basic_block; ir_build_br(irb, parent_scope, node, end_block, is_comptime); @@ -3841,7 +3866,8 @@ static IrInstruction *ir_gen_orelse(IrBuilder *irb, Scope *parent_scope, AstNode IrBasicBlock **incoming_blocks = allocate<IrBasicBlock *>(2); incoming_blocks[0] = after_null_block; incoming_blocks[1] = after_ok_block; - return ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values); + IrInstruction *phi = ir_build_phi(irb, parent_scope, node, 2, incoming_blocks, incoming_values); + return ir_lval_wrap(irb, parent_scope, phi, lval, result_loc); } static IrInstruction *ir_gen_error_union(IrBuilder *irb, Scope *parent_scope, AstNode *node) { @@ -3861,7 +3887,7 @@ static IrInstruction *ir_gen_error_union(IrBuilder *irb, Scope *parent_scope, As return ir_build_error_union(irb, parent_scope, node, err_set, payload); } -static IrInstruction *ir_gen_bin_op(IrBuilder *irb, Scope *scope, AstNode *node) { +static IrInstruction *ir_gen_bin_op(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { assert(node->type == NodeTypeBinOpExpr); BinOpType bin_op_type = node->data.bin_op_expr.bin_op; @@ -3869,87 +3895,87 @@ static IrInstruction *ir_gen_bin_op(IrBuilder *irb, Scope *scope, AstNode *node) case BinOpTypeInvalid: zig_unreachable(); case BinOpTypeAssign: - return ir_gen_assign(irb, scope, node); + return ir_lval_wrap(irb, scope, ir_gen_assign(irb, scope, node), lval, result_loc); case BinOpTypeAssignTimes: - return ir_gen_assign_op(irb, scope, node, IrBinOpMult); + return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpMult), lval, result_loc); case BinOpTypeAssignTimesWrap: - return ir_gen_assign_op(irb, scope, node, IrBinOpMultWrap); + return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpMultWrap), lval, result_loc); case BinOpTypeAssignDiv: - return ir_gen_assign_op(irb, scope, node, IrBinOpDivUnspecified); + return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpDivUnspecified), lval, result_loc); case BinOpTypeAssignMod: - return ir_gen_assign_op(irb, scope, node, IrBinOpRemUnspecified); + return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpRemUnspecified), lval, result_loc); case BinOpTypeAssignPlus: - return ir_gen_assign_op(irb, scope, node, IrBinOpAdd); + return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpAdd), lval, result_loc); case BinOpTypeAssignPlusWrap: - return ir_gen_assign_op(irb, scope, node, IrBinOpAddWrap); + return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpAddWrap), lval, result_loc); case BinOpTypeAssignMinus: - return ir_gen_assign_op(irb, scope, node, IrBinOpSub); + return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpSub), lval, result_loc); case BinOpTypeAssignMinusWrap: - return ir_gen_assign_op(irb, scope, node, IrBinOpSubWrap); + return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpSubWrap), lval, result_loc); case BinOpTypeAssignBitShiftLeft: - return ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftLeftLossy); + return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftLeftLossy), lval, result_loc); case BinOpTypeAssignBitShiftRight: - return ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftRightLossy); + return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBitShiftRightLossy), lval, result_loc); case BinOpTypeAssignBitAnd: - return ir_gen_assign_op(irb, scope, node, IrBinOpBinAnd); + return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBinAnd), lval, result_loc); case BinOpTypeAssignBitXor: - return ir_gen_assign_op(irb, scope, node, IrBinOpBinXor); + return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBinXor), lval, result_loc); case BinOpTypeAssignBitOr: - return ir_gen_assign_op(irb, scope, node, IrBinOpBinOr); + return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpBinOr), lval, result_loc); case BinOpTypeAssignMergeErrorSets: - return ir_gen_assign_op(irb, scope, node, IrBinOpMergeErrorSets); + return ir_lval_wrap(irb, scope, ir_gen_assign_op(irb, scope, node, IrBinOpMergeErrorSets), lval, result_loc); case BinOpTypeBoolOr: - return ir_gen_bool_or(irb, scope, node); + return ir_lval_wrap(irb, scope, ir_gen_bool_or(irb, scope, node), lval, result_loc); case BinOpTypeBoolAnd: - return ir_gen_bool_and(irb, scope, node); + return ir_lval_wrap(irb, scope, ir_gen_bool_and(irb, scope, node), lval, result_loc); case BinOpTypeCmpEq: - return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpEq); + return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpEq), lval, result_loc); case BinOpTypeCmpNotEq: - return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpNotEq); + return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpNotEq), lval, result_loc); case BinOpTypeCmpLessThan: - return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessThan); + return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessThan), lval, result_loc); case BinOpTypeCmpGreaterThan: - return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterThan); + return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterThan), lval, result_loc); case BinOpTypeCmpLessOrEq: - return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessOrEq); + return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpLessOrEq), lval, result_loc); case BinOpTypeCmpGreaterOrEq: - return ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterOrEq); + return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpCmpGreaterOrEq), lval, result_loc); case BinOpTypeBinOr: - return ir_gen_bin_op_id(irb, scope, node, IrBinOpBinOr); + return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBinOr), lval, result_loc); case BinOpTypeBinXor: - return ir_gen_bin_op_id(irb, scope, node, IrBinOpBinXor); + return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBinXor), lval, result_loc); case BinOpTypeBinAnd: - return ir_gen_bin_op_id(irb, scope, node, IrBinOpBinAnd); + return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBinAnd), lval, result_loc); case BinOpTypeBitShiftLeft: - return ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftLeftLossy); + return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftLeftLossy), lval, result_loc); case BinOpTypeBitShiftRight: - return ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftRightLossy); + return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpBitShiftRightLossy), lval, result_loc); case BinOpTypeAdd: - return ir_gen_bin_op_id(irb, scope, node, IrBinOpAdd); + return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpAdd), lval, result_loc); case BinOpTypeAddWrap: - return ir_gen_bin_op_id(irb, scope, node, IrBinOpAddWrap); + return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpAddWrap), lval, result_loc); case BinOpTypeSub: - return ir_gen_bin_op_id(irb, scope, node, IrBinOpSub); + return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpSub), lval, result_loc); case BinOpTypeSubWrap: - return ir_gen_bin_op_id(irb, scope, node, IrBinOpSubWrap); + return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpSubWrap), lval, result_loc); case BinOpTypeMult: - return ir_gen_bin_op_id(irb, scope, node, IrBinOpMult); + return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpMult), lval, result_loc); case BinOpTypeMultWrap: - return ir_gen_bin_op_id(irb, scope, node, IrBinOpMultWrap); + return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpMultWrap), lval, result_loc); case BinOpTypeDiv: - return ir_gen_bin_op_id(irb, scope, node, IrBinOpDivUnspecified); + return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpDivUnspecified), lval, result_loc); case BinOpTypeMod: - return ir_gen_bin_op_id(irb, scope, node, IrBinOpRemUnspecified); + return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpRemUnspecified), lval, result_loc); case BinOpTypeArrayCat: - return ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayCat); + return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayCat), lval, result_loc); case BinOpTypeArrayMult: - return ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayMult); + return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpArrayMult), lval, result_loc); case BinOpTypeMergeErrorSets: - return ir_gen_bin_op_id(irb, scope, node, IrBinOpMergeErrorSets); + return ir_lval_wrap(irb, scope, ir_gen_bin_op_id(irb, scope, node, IrBinOpMergeErrorSets), lval, result_loc); case BinOpTypeUnwrapOptional: - return ir_gen_orelse(irb, scope, node); + return ir_gen_orelse(irb, scope, node, lval, result_loc); case BinOpTypeErrorUnion: - return ir_gen_error_union(irb, scope, node); + return ir_lval_wrap(irb, scope, ir_gen_error_union(irb, scope, node), lval, result_loc); } zig_unreachable(); } @@ -5290,26 +5316,6 @@ static IrInstruction *ir_gen_fn_call(IrBuilder *irb, Scope *scope, AstNode *node return ir_lval_wrap(irb, scope, fn_call, lval, result_loc); } -static ResultLocPeerParent *create_binary_result_peers(IrInstruction *cond_br_inst, - IrBasicBlock *else_block, IrBasicBlock *endif_block, ResultLoc *parent) -{ - ResultLocPeerParent *peer_parent = allocate<ResultLocPeerParent>(1); - peer_parent->base.id = ResultLocIdPeerParent; - peer_parent->base.source_instruction = cond_br_inst; - peer_parent->parent = parent; - peer_parent->peer_count = 2; - peer_parent->peers = allocate<ResultLocPeer>(2); - peer_parent->peers[0].base.id = ResultLocIdPeer; - peer_parent->peers[0].base.source_instruction = cond_br_inst; - peer_parent->peers[0].parent = peer_parent; - peer_parent->peers[0].next_bb = else_block; - peer_parent->peers[1].base.id = ResultLocIdPeer; - peer_parent->peers[1].base.source_instruction = cond_br_inst; - peer_parent->peers[1].parent = peer_parent; - peer_parent->peers[1].next_bb = endif_block; - return peer_parent; -} - static IrInstruction *ir_gen_if_bool_expr(IrBuilder *irb, Scope *scope, AstNode *node, LVal lval, ResultLoc *result_loc) { @@ -7863,7 +7869,7 @@ static IrInstruction *ir_gen_node_raw(IrBuilder *irb, AstNode *node, Scope *scop case NodeTypeGroupedExpr: return ir_gen_node_raw(irb, node->data.grouped_expr, scope, lval, result_loc); case NodeTypeBinOpExpr: - return ir_lval_wrap(irb, scope, ir_gen_bin_op(irb, scope, node), lval, result_loc); + return ir_gen_bin_op(irb, scope, node, lval, result_loc); case NodeTypeIntLiteral: return ir_lval_wrap(irb, scope, ir_gen_int_lit(irb, scope, node), lval, result_loc); case NodeTypeFloatLiteral: |
