| ... | @@ -421,6 +421,20 @@ fn resolveValue(cg: *CodeGen, val: Value) InnerError!WValue { | ... | @@ -421,6 +421,20 @@ fn resolveValue(cg: *CodeGen, val: Value) InnerError!WValue { |
| 421 | /// NOTE: if result == .stack, it will be stored in .local | 421 | /// NOTE: if result == .stack, it will be stored in .local |
| 422 | fn finishAir(cg: *CodeGen, inst: Air.Inst.Index, result: WValue, operands: []const Air.Inst.Ref) InnerError!void { | 422 | fn finishAir(cg: *CodeGen, inst: Air.Inst.Index, result: WValue, operands: []const Air.Inst.Ref) InnerError!void { |
| 423 | assert(operands.len <= Air.Liveness.bpi - 1); | 423 | assert(operands.len <= Air.Liveness.bpi - 1); |
| | 424 | |
| | 425 | var final_result = result; |
| | 426 | const aliased_operand: ?*WValue = if (result == .local) aliased: { |
| | 427 | for (operands) |operand| { |
| | 428 | if (operand.toIndex() == null) continue; |
| | 429 | const resolved_operand = cg.getResolvedInst(operand); |
| | 430 | if (resolved_operand.* != .local or resolved_operand.local.value != result.local.value) continue; |
| | 431 | |
| | 432 | resolved_operand.local.references += 1; |
| | 433 | break :aliased resolved_operand; |
| | 434 | } |
| | 435 | break :aliased null; |
| | 436 | } else null; |
| | 437 | |
| 424 | var tomb_bits = cg.liveness.getTombBits(inst); | 438 | var tomb_bits = cg.liveness.getTombBits(inst); |
| 425 | for (operands) |operand| { | 439 | for (operands) |operand| { |
| 426 | const dies = @as(u1, @truncate(tomb_bits)) != 0; | 440 | const dies = @as(u1, @truncate(tomb_bits)) != 0; |
| ... | @@ -428,7 +442,8 @@ fn finishAir(cg: *CodeGen, inst: Air.Inst.Index, result: WValue, operands: []con | ... | @@ -428,7 +442,8 @@ fn finishAir(cg: *CodeGen, inst: Air.Inst.Index, result: WValue, operands: []con |
| 428 | if (!dies) continue; | 442 | if (!dies) continue; |
| 429 | processDeath(cg, operand); | 443 | processDeath(cg, operand); |
| 430 | } | 444 | } |
| 431 | try cg.finishAirResult(inst, result); | 445 | if (aliased_operand) |operand| final_result.local.references = operand.local.references; |
| | 446 | try cg.finishAirResult(inst, final_result); |
| 432 | } | 447 | } |
| 433 | | 448 | |
| 434 | fn finishAirResult(cg: *CodeGen, inst: Air.Inst.Index, result: WValue) InnerError!void { | 449 | fn finishAirResult(cg: *CodeGen, inst: Air.Inst.Index, result: WValue) InnerError!void { |
| ... | @@ -478,7 +493,7 @@ fn processDeath(cg: *CodeGen, ref: Air.Inst.Ref) void { | ... | @@ -478,7 +493,7 @@ fn processDeath(cg: *CodeGen, ref: Air.Inst.Ref) void { |
| 478 | return; // function arguments can never be re-used | 493 | return; // function arguments can never be re-used |
| 479 | } | 494 | } |
| 480 | log.debug("Decreasing reference for ref: %{d}, using local '{d}'", .{ @backingInt(ref.toIndex().?), value.local.value }); | 495 | log.debug("Decreasing reference for ref: %{d}, using local '{d}'", .{ @backingInt(ref.toIndex().?), value.local.value }); |
| 481 | value.local.references -= 1; // if this panics, a call to `reuseOperand` was forgotten by the developer | 496 | value.local.references -= 1; |
| 482 | if (value.local.references == 0) { | 497 | if (value.local.references == 0) { |
| 483 | value.free(cg); | 498 | value.free(cg); |
| 484 | } | 499 | } |
| ... | @@ -631,7 +646,7 @@ fn genBlockType(ty: Type, zcu: *const Zcu, target: *const std.Target) std.wasm.B | ... | @@ -631,7 +646,7 @@ fn genBlockType(ty: Type, zcu: *const Zcu, target: *const std.Target) std.wasm.B |
| 631 | /// Writes the bytecode depending on the given `WValue` in `val` | 646 | /// Writes the bytecode depending on the given `WValue` in `val` |
| 632 | fn emitWValue(cg: *CodeGen, value: WValue) InnerError!void { | 647 | fn emitWValue(cg: *CodeGen, value: WValue) InnerError!void { |
| 633 | switch (value) { | 648 | switch (value) { |
| 634 | .dead => unreachable, // reference to free'd `WValue` (missing reuseOperand?) | 649 | .dead => unreachable, // reference to free'd `WValue` |
| 635 | .none, .stack => {}, // no-op | 650 | .none, .stack => {}, // no-op |
| 636 | .local => |idx| try cg.addLocal(.local_get, idx.value), | 651 | .local => |idx| try cg.addLocal(.local_get, idx.value), |
| 637 | .imm32 => |val| try cg.addImm32(val), | 652 | .imm32 => |val| try cg.addImm32(val), |
| ... | @@ -699,23 +714,6 @@ fn emitWValue(cg: *CodeGen, value: WValue) InnerError!void { | ... | @@ -699,23 +714,6 @@ fn emitWValue(cg: *CodeGen, value: WValue) InnerError!void { |
| 699 | } | 714 | } |
| 700 | } | 715 | } |
| 701 | | 716 | |
| 702 | /// If given a local or stack-offset, increases the reference count by 1. | | |
| 703 | /// The old `WValue` found at instruction `ref` is then replaced by the | | |
| 704 | /// modified `WValue` and returned. When given a non-local or non-stack-offset, | | |
| 705 | /// returns the given `operand` itfunc instead. | | |
| 706 | fn reuseOperand(cg: *CodeGen, ref: Air.Inst.Ref, operand: WValue) WValue { | | |
| 707 | if (operand != .local and operand != .stack_offset) return operand; | | |
| 708 | var new_value = operand; | | |
| 709 | switch (new_value) { | | |
| 710 | .local => |*local| local.references += 1, | | |
| 711 | .stack_offset => |*stack_offset| stack_offset.references += 1, | | |
| 712 | else => unreachable, | | |
| 713 | } | | |
| 714 | const old_value = cg.getResolvedInst(ref); | | |
| 715 | old_value.* = new_value; | | |
| 716 | return new_value; | | |
| 717 | } | | |
| 718 | | | |
| 719 | /// From a reference, returns its resolved `WValue`. | 717 | /// From a reference, returns its resolved `WValue`. |
| 720 | /// It's illegal to provide a `Air.Inst.Ref` that hasn't been resolved yet. | 718 | /// It's illegal to provide a `Air.Inst.Ref` that hasn't been resolved yet. |
| 721 | fn getResolvedInst(cg: *CodeGen, ref: Air.Inst.Ref) *WValue { | 719 | fn getResolvedInst(cg: *CodeGen, ref: Air.Inst.Ref) *WValue { |
| ... | @@ -1598,17 +1596,7 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -1598,17 +1596,7 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 1598 | const src_int_ty: IntType = .fromType(cg, src_ty); | 1596 | const src_int_ty: IntType = .fromType(cg, src_ty); |
| 1599 | const dest_int_ty: IntType = .fromType(cg, dest_ty); | 1597 | const dest_int_ty: IntType = .fromType(cg, dest_ty); |
| 1600 | | 1598 | |
| 1601 | const src_bits = src_int_ty.bits; | 1599 | const result = try cg.intCast(dest_int_ty, src_int_ty, operand); |
| 1602 | const dest_bits = dest_int_ty.bits; | | |
| 1603 | | | |
| 1604 | const same_class: bool = (src_bits <= 32 and dest_bits <= 32) or | | |
| 1605 | (src_bits >= 33 and src_bits <= 64 and dest_bits >= 33 and dest_bits <= 64) or | | |
| 1606 | (src_bits >= 65 and src_bits <= 128 and dest_bits >= 65 and dest_bits <= 128); | | |
| 1607 | | | |
| 1608 | const result = if (same_class) | | |
| 1609 | cg.reuseOperand(ty_op.operand, operand) | | |
| 1610 | else | | |
| 1611 | try cg.intCast(dest_int_ty, src_int_ty, operand); | | |
| 1612 | | 1600 | |
| 1613 | try cg.finishAir(inst, result, &.{ty_op.operand}); | 1601 | try cg.finishAir(inst, result, &.{ty_op.operand}); |
| 1614 | }, | 1602 | }, |
| ... | @@ -1625,12 +1613,7 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -1625,12 +1613,7 @@ fn genInst(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 1625 | | 1613 | |
| 1626 | const src_int_ty: IntType = .fromType(cg, src_ty); | 1614 | const src_int_ty: IntType = .fromType(cg, src_ty); |
| 1627 | const dest_int_ty: IntType = .fromType(cg, dest_ty); | 1615 | const dest_int_ty: IntType = .fromType(cg, dest_ty); |
| 1628 | | 1616 | const result = try cg.intTrunc(dest_int_ty, src_int_ty, operand); |
| 1629 | const result = if (src_int_ty.bits == dest_int_ty.bits) | | |
| 1630 | cg.reuseOperand(ty_op.operand, operand) | | |
| 1631 | else blk: { | | |
| 1632 | break :blk try cg.intTrunc(dest_int_ty, src_int_ty, operand); | | |
| 1633 | }; | | |
| 1634 | | 1617 | |
| 1635 | try cg.finishAir(inst, result, &.{ty_op.operand}); | 1618 | try cg.finishAir(inst, result, &.{ty_op.operand}); |
| 1636 | }, | 1619 | }, |
| ... | @@ -4259,6 +4242,7 @@ fn intCast(cg: *CodeGen, dest_ty: IntType, src_ty: IntType, operand: WValue) Inn | ... | @@ -4259,6 +4242,7 @@ fn intCast(cg: *CodeGen, dest_ty: IntType, src_ty: IntType, operand: WValue) Inn |
| 4259 | } | 4242 | } |
| 4260 | | 4243 | |
| 4261 | fn intTrunc(cg: *CodeGen, dest_ty: IntType, src_ty: IntType, operand: WValue) InnerError!WValue { | 4244 | fn intTrunc(cg: *CodeGen, dest_ty: IntType, src_ty: IntType, operand: WValue) InnerError!WValue { |
| | 4245 | assert(src_ty.bits > dest_ty.bits); |
| 4262 | var result = try cg.intCast(dest_ty, src_ty, operand); | 4246 | var result = try cg.intCast(dest_ty, src_ty, operand); |
| 4263 | | 4247 | |
| 4264 | const dest_wasm_bits = cg.intBackingBits(dest_ty.bits); | 4248 | const dest_wasm_bits = cg.intBackingBits(dest_ty.bits); |
| ... | @@ -5584,8 +5568,7 @@ fn airNopCast(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -5584,8 +5568,7 @@ fn airNopCast(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5584 | assert(operand_ty.abiAlignment(zcu) == dest_ty.abiAlignment(zcu)); | 5568 | assert(operand_ty.abiAlignment(zcu) == dest_ty.abiAlignment(zcu)); |
| 5585 | | 5569 | |
| 5586 | const operand = try cg.resolveInst(ty_op.operand); | 5570 | const operand = try cg.resolveInst(ty_op.operand); |
| 5587 | const result = cg.reuseOperand(ty_op.operand, operand); | 5571 | return cg.finishAir(inst, operand, &.{ty_op.operand}); |
| 5588 | return cg.finishAir(inst, result, &.{ty_op.operand}); | | |
| 5589 | } | 5572 | } |
| 5590 | | 5573 | |
| 5591 | fn airIntFromPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 5574 | fn airIntFromPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| ... | @@ -5601,7 +5584,7 @@ fn airIntFromPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -5601,7 +5584,7 @@ fn airIntFromPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5601 | const operand = try cg.resolveInst(ty_op.operand); | 5584 | const operand = try cg.resolveInst(ty_op.operand); |
| 5602 | const result = switch (operand) { | 5585 | const result = switch (operand) { |
| 5603 | .stack_offset => try cg.buildPointerOffset(operand, 0, .new), | 5586 | .stack_offset => try cg.buildPointerOffset(operand, 0, .new), |
| 5604 | else => cg.reuseOperand(ty_op.operand, operand), | 5587 | else => operand, |
| 5605 | }; | 5588 | }; |
| 5606 | return cg.finishAir(inst, result, &.{ty_op.operand}); | 5589 | return cg.finishAir(inst, result, &.{ty_op.operand}); |
| 5607 | } | 5590 | } |
| ... | @@ -5627,7 +5610,7 @@ fn airBitcast(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -5627,7 +5610,7 @@ fn airBitcast(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5627 | const dest_ty = cg.typeOfIndex(inst); | 5610 | const dest_ty = cg.typeOfIndex(inst); |
| 5628 | const src_ty = cg.typeOf(ty_op.operand); | 5611 | const src_ty = cg.typeOf(ty_op.operand); |
| 5629 | | 5612 | |
| 5630 | const result = (try cg.bitcast(dest_ty, src_ty, operand)) orelse cg.reuseOperand(ty_op.operand, operand); | 5613 | const result = try cg.bitcast(dest_ty, src_ty, operand); |
| 5631 | | 5614 | |
| 5632 | return cg.finishAir(inst, result, &.{ty_op.operand}); | 5615 | return cg.finishAir(inst, result, &.{ty_op.operand}); |
| 5633 | } | 5616 | } |
| ... | @@ -5654,8 +5637,8 @@ fn bitcastClass(cg: *CodeGen, ty: Type) BitcastClass { | ... | @@ -5654,8 +5637,8 @@ fn bitcastClass(cg: *CodeGen, ty: Type) BitcastClass { |
| 5654 | }; | 5637 | }; |
| 5655 | } | 5638 | } |
| 5656 | | 5639 | |
| 5657 | fn bitcast(cg: *CodeGen, dest_ty: Type, src_ty: Type, operand: WValue) InnerError!?WValue { | 5640 | fn bitcast(cg: *CodeGen, dest_ty: Type, src_ty: Type, operand: WValue) InnerError!WValue { |
| 5658 | if (dest_ty.eql(src_ty)) return null; | 5641 | if (dest_ty.eql(src_ty)) return operand; |
| 5659 | | 5642 | |
| 5660 | const zcu = cg.pt.zcu; | 5643 | const zcu = cg.pt.zcu; |
| 5661 | const src_class = cg.bitcastClass(src_ty); | 5644 | const src_class = cg.bitcastClass(src_ty); |
| ... | @@ -5674,7 +5657,7 @@ fn bitcast(cg: *CodeGen, dest_ty: Type, src_ty: Type, operand: WValue) InnerErro | ... | @@ -5674,7 +5657,7 @@ fn bitcast(cg: *CodeGen, dest_ty: Type, src_ty: Type, operand: WValue) InnerErro |
| 5674 | | 5657 | |
| 5675 | if (src_by_ref and dest_by_ref) { | 5658 | if (src_by_ref and dest_by_ref) { |
| 5676 | if (needs_wrapping) return try cg.intWrap(dest_class.int, operand); | 5659 | if (needs_wrapping) return try cg.intWrap(dest_class.int, operand); |
| 5677 | return null; | 5660 | return operand; |
| 5678 | } | 5661 | } |
| 5679 | | 5662 | |
| 5680 | if (dest_by_ref) { | 5663 | if (dest_by_ref) { |
| ... | @@ -5708,7 +5691,7 @@ fn bitcast(cg: *CodeGen, dest_ty: Type, src_ty: Type, operand: WValue) InnerErro | ... | @@ -5708,7 +5691,7 @@ fn bitcast(cg: *CodeGen, dest_ty: Type, src_ty: Type, operand: WValue) InnerErro |
| 5708 | | 5691 | |
| 5709 | switch (dest_class) { | 5692 | switch (dest_class) { |
| 5710 | .float => |float_ty| switch (float_ty) { | 5693 | .float => |float_ty| switch (float_ty) { |
| 5711 | .f16 => return null, | 5694 | .f16 => return operand, |
| 5712 | .f32 => { | 5695 | .f32 => { |
| 5713 | try cg.emitWValue(operand); | 5696 | try cg.emitWValue(operand); |
| 5714 | try cg.addTag(.f32_reinterpret_i32); | 5697 | try cg.addTag(.f32_reinterpret_i32); |
| ... | @@ -5729,7 +5712,7 @@ fn bitcast(cg: *CodeGen, dest_ty: Type, src_ty: Type, operand: WValue) InnerErro | ... | @@ -5729,7 +5712,7 @@ fn bitcast(cg: *CodeGen, dest_ty: Type, src_ty: Type, operand: WValue) InnerErro |
| 5729 | return try cg.intWrap(dest_class.int, operand); | 5712 | return try cg.intWrap(dest_class.int, operand); |
| 5730 | } | 5713 | } |
| 5731 | | 5714 | |
| 5732 | return null; | 5715 | return operand; |
| 5733 | } | 5716 | } |
| 5734 | | 5717 | |
| 5735 | fn airStructFieldPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { | 5718 | fn airStructFieldPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| ... | @@ -5740,7 +5723,7 @@ fn airStructFieldPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -5740,7 +5723,7 @@ fn airStructFieldPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 5740 | const struct_ptr = try cg.resolveInst(extra.data.struct_operand); | 5723 | const struct_ptr = try cg.resolveInst(extra.data.struct_operand); |
| 5741 | const struct_ptr_ty = cg.typeOf(extra.data.struct_operand); | 5724 | const struct_ptr_ty = cg.typeOf(extra.data.struct_operand); |
| 5742 | const struct_ty = struct_ptr_ty.childType(zcu); | 5725 | const struct_ty = struct_ptr_ty.childType(zcu); |
| 5743 | const result = try cg.structFieldPtr(inst, extra.data.struct_operand, struct_ptr, struct_ptr_ty, struct_ty, extra.data.field_index); | 5726 | const result = try cg.structFieldPtr(inst, struct_ptr, struct_ptr_ty, struct_ty, extra.data.field_index); |
| 5744 | return cg.finishAir(inst, result, &.{extra.data.struct_operand}); | 5727 | return cg.finishAir(inst, result, &.{extra.data.struct_operand}); |
| 5745 | } | 5728 | } |
| 5746 | | 5729 | |
| ... | @@ -5751,14 +5734,13 @@ fn airStructFieldPtrIndex(cg: *CodeGen, inst: Air.Inst.Index, index: u32) InnerE | ... | @@ -5751,14 +5734,13 @@ fn airStructFieldPtrIndex(cg: *CodeGen, inst: Air.Inst.Index, index: u32) InnerE |
| 5751 | const struct_ptr_ty = cg.typeOf(ty_op.operand); | 5734 | const struct_ptr_ty = cg.typeOf(ty_op.operand); |
| 5752 | const struct_ty = struct_ptr_ty.childType(zcu); | 5735 | const struct_ty = struct_ptr_ty.childType(zcu); |
| 5753 | | 5736 | |
| 5754 | const result = try cg.structFieldPtr(inst, ty_op.operand, struct_ptr, struct_ptr_ty, struct_ty, index); | 5737 | const result = try cg.structFieldPtr(inst, struct_ptr, struct_ptr_ty, struct_ty, index); |
| 5755 | return cg.finishAir(inst, result, &.{ty_op.operand}); | 5738 | return cg.finishAir(inst, result, &.{ty_op.operand}); |
| 5756 | } | 5739 | } |
| 5757 | | 5740 | |
| 5758 | fn structFieldPtr( | 5741 | fn structFieldPtr( |
| 5759 | cg: *CodeGen, | 5742 | cg: *CodeGen, |
| 5760 | inst: Air.Inst.Index, | 5743 | inst: Air.Inst.Index, |
| 5761 | ref: Air.Inst.Ref, | | |
| 5762 | struct_ptr: WValue, | 5744 | struct_ptr: WValue, |
| 5763 | struct_ptr_ty: Type, | 5745 | struct_ptr_ty: Type, |
| 5764 | struct_ty: Type, | 5746 | struct_ty: Type, |
| ... | @@ -5785,7 +5767,7 @@ fn structFieldPtr( | ... | @@ -5785,7 +5767,7 @@ fn structFieldPtr( |
| 5785 | }; | 5767 | }; |
| 5786 | // save a load and store when we can simply reuse the operand | 5768 | // save a load and store when we can simply reuse the operand |
| 5787 | if (offset == 0) { | 5769 | if (offset == 0) { |
| 5788 | return cg.reuseOperand(ref, struct_ptr); | 5770 | return struct_ptr; |
| 5789 | } | 5771 | } |
| 5790 | switch (struct_ptr) { | 5772 | switch (struct_ptr) { |
| 5791 | .stack_offset => |stack_offset| { | 5773 | .stack_offset => |stack_offset| { |
| ... | @@ -6092,7 +6074,7 @@ fn airUnwrapErrUnionPayload(cg: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) | ... | @@ -6092,7 +6074,7 @@ fn airUnwrapErrUnionPayload(cg: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) |
| 6092 | const result: WValue = result: { | 6074 | const result: WValue = result: { |
| 6093 | if (!payload_ty.hasRuntimeBits(zcu)) { | 6075 | if (!payload_ty.hasRuntimeBits(zcu)) { |
| 6094 | if (op_is_ptr) { | 6076 | if (op_is_ptr) { |
| 6095 | break :result cg.reuseOperand(ty_op.operand, operand); | 6077 | break :result operand; |
| 6096 | } else { | 6078 | } else { |
| 6097 | break :result .none; | 6079 | break :result .none; |
| 6098 | } | 6080 | } |
| ... | @@ -6131,7 +6113,7 @@ fn airUnwrapErrUnionError(cg: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) I | ... | @@ -6131,7 +6113,7 @@ fn airUnwrapErrUnionError(cg: *CodeGen, inst: Air.Inst.Index, op_is_ptr: bool) I |
| 6131 | break :result try cg.load(operand, Type.anyerror, err_offset); | 6113 | break :result try cg.load(operand, Type.anyerror, err_offset); |
| 6132 | } else { | 6114 | } else { |
| 6133 | assert(!payload_ty.hasRuntimeBits(zcu)); | 6115 | assert(!payload_ty.hasRuntimeBits(zcu)); |
| 6134 | break :result cg.reuseOperand(ty_op.operand, operand); | 6116 | break :result operand; |
| 6135 | } | 6117 | } |
| 6136 | }; | 6118 | }; |
| 6137 | return cg.finishAir(inst, result, &.{ty_op.operand}); | 6119 | return cg.finishAir(inst, result, &.{ty_op.operand}); |
| ... | @@ -6147,7 +6129,7 @@ fn airWrapErrUnionPayload(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -6147,7 +6129,7 @@ fn airWrapErrUnionPayload(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6147 | const pl_ty = cg.typeOf(ty_op.operand); | 6129 | const pl_ty = cg.typeOf(ty_op.operand); |
| 6148 | const result = result: { | 6130 | const result = result: { |
| 6149 | if (!pl_ty.hasRuntimeBits(zcu)) { | 6131 | if (!pl_ty.hasRuntimeBits(zcu)) { |
| 6150 | break :result cg.reuseOperand(ty_op.operand, operand); | 6132 | break :result operand; |
| 6151 | } | 6133 | } |
| 6152 | | 6134 | |
| 6153 | const err_union = try cg.allocStack(err_ty); | 6135 | const err_union = try cg.allocStack(err_ty); |
| ... | @@ -6177,7 +6159,7 @@ fn airWrapErrUnionErr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -6177,7 +6159,7 @@ fn airWrapErrUnionErr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6177 | | 6159 | |
| 6178 | const result = result: { | 6160 | const result = result: { |
| 6179 | if (!pl_ty.hasRuntimeBits(zcu)) { | 6161 | if (!pl_ty.hasRuntimeBits(zcu)) { |
| 6180 | break :result cg.reuseOperand(ty_op.operand, operand); | 6162 | break :result operand; |
| 6181 | } | 6163 | } |
| 6182 | | 6164 | |
| 6183 | const err_union = try cg.allocStack(err_ty); | 6165 | const err_union = try cg.allocStack(err_ty); |
| ... | @@ -6257,7 +6239,7 @@ fn airOptionalPayload(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -6257,7 +6239,7 @@ fn airOptionalPayload(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6257 | | 6239 | |
| 6258 | const result = result: { | 6240 | const result = result: { |
| 6259 | const operand = try cg.resolveInst(ty_op.operand); | 6241 | const operand = try cg.resolveInst(ty_op.operand); |
| 6260 | if (opt_ty.optionalReprIsPayload(zcu)) break :result cg.reuseOperand(ty_op.operand, operand); | 6242 | if (opt_ty.optionalReprIsPayload(zcu)) break :result operand; |
| 6261 | | 6243 | |
| 6262 | if (isByRef(payload_ty, zcu, cg.target)) { | 6244 | if (isByRef(payload_ty, zcu, cg.target)) { |
| 6263 | break :result try cg.buildPointerOffset(operand, 0, .new); | 6245 | break :result try cg.buildPointerOffset(operand, 0, .new); |
| ... | @@ -6277,7 +6259,7 @@ fn airOptionalPayloadPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -6277,7 +6259,7 @@ fn airOptionalPayloadPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6277 | const result = result: { | 6259 | const result = result: { |
| 6278 | const payload_ty = opt_ty.optionalChild(zcu); | 6260 | const payload_ty = opt_ty.optionalChild(zcu); |
| 6279 | if (!payload_ty.hasRuntimeBits(zcu) or opt_ty.optionalReprIsPayload(zcu)) { | 6261 | if (!payload_ty.hasRuntimeBits(zcu) or opt_ty.optionalReprIsPayload(zcu)) { |
| 6280 | break :result cg.reuseOperand(ty_op.operand, operand); | 6262 | break :result operand; |
| 6281 | } | 6263 | } |
| 6282 | | 6264 | |
| 6283 | break :result try cg.buildPointerOffset(operand, 0, .new); | 6265 | break :result try cg.buildPointerOffset(operand, 0, .new); |
| ... | @@ -6327,7 +6309,7 @@ fn airWrapOptional(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -6327,7 +6309,7 @@ fn airWrapOptional(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 6327 | const operand = try cg.resolveInst(ty_op.operand); | 6309 | const operand = try cg.resolveInst(ty_op.operand); |
| 6328 | const op_ty = cg.typeOfIndex(inst); | 6310 | const op_ty = cg.typeOfIndex(inst); |
| 6329 | if (op_ty.optionalReprIsPayload(zcu)) { | 6311 | if (op_ty.optionalReprIsPayload(zcu)) { |
| 6330 | break :result cg.reuseOperand(ty_op.operand, operand); | 6312 | break :result operand; |
| 6331 | } | 6313 | } |
| 6332 | const offset = std.math.cast(u32, payload_ty.abiSize(zcu)) orelse { | 6314 | const offset = std.math.cast(u32, payload_ty.abiSize(zcu)) orelse { |
| 6333 | return cg.fail("Optional type {f} too big to fit into stack frame", .{op_ty.fmt(pt)}); | 6315 | return cg.fail("Optional type {f} too big to fit into stack frame", .{op_ty.fmt(pt)}); |
| ... | @@ -7146,7 +7128,7 @@ fn airErrUnionPayloadPtrSet(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void | ... | @@ -7146,7 +7128,7 @@ fn airErrUnionPayloadPtrSet(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void |
| 7146 | | 7128 | |
| 7147 | const result = result: { | 7129 | const result = result: { |
| 7148 | if (!payload_ty.hasRuntimeBits(zcu)) { | 7130 | if (!payload_ty.hasRuntimeBits(zcu)) { |
| 7149 | break :result cg.reuseOperand(ty_op.operand, operand); | 7131 | break :result operand; |
| 7150 | } | 7132 | } |
| 7151 | | 7133 | |
| 7152 | break :result try cg.buildPointerOffset(operand, @as(u32, @intCast(errUnionPayloadOffset(payload_ty, zcu))), .new); | 7134 | break :result try cg.buildPointerOffset(operand, @as(u32, @intCast(errUnionPayloadOffset(payload_ty, zcu))), .new); |
| ... | @@ -7182,7 +7164,7 @@ fn airFieldParentPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { | ... | @@ -7182,7 +7164,7 @@ fn airFieldParentPtr(cg: *CodeGen, inst: Air.Inst.Index) InnerError!void { |
| 7182 | try cg.addTag(.i32_sub); | 7164 | try cg.addTag(.i32_sub); |
| 7183 | try cg.addLocal(.local_set, base.local.value); | 7165 | try cg.addLocal(.local_set, base.local.value); |
| 7184 | break :result base; | 7166 | break :result base; |
| 7185 | } else cg.reuseOperand(extra.field_ptr, field_ptr); | 7167 | } else field_ptr; |
| 7186 | | 7168 | |
| 7187 | return cg.finishAir(inst, result, &.{extra.field_ptr}); | 7169 | return cg.finishAir(inst, result, &.{extra.field_ptr}); |
| 7188 | } | 7170 | } |