| ... | @@ -4980,8 +4980,8 @@ pub const FuncGen = struct { | ... | @@ -4980,8 +4980,8 @@ pub const FuncGen = struct { |
| 4980 | .breakpoint => try self.airBreakpoint(inst), | 4980 | .breakpoint => try self.airBreakpoint(inst), |
| 4981 | .ret_addr => try self.airRetAddr(inst), | 4981 | .ret_addr => try self.airRetAddr(inst), |
| 4982 | .frame_addr => try self.airFrameAddress(inst), | 4982 | .frame_addr => try self.airFrameAddress(inst), |
| 4983 | .@"try" => try self.airTry(body[i..], false), | 4983 | .@"try" => try self.airTry(inst, false), |
| 4984 | .try_cold => try self.airTry(body[i..], true), | 4984 | .try_cold => try self.airTry(inst, true), |
| 4985 | .try_ptr => try self.airTryPtr(inst, false), | 4985 | .try_ptr => try self.airTryPtr(inst, false), |
| 4986 | .try_ptr_cold => try self.airTryPtr(inst, true), | 4986 | .try_ptr_cold => try self.airTryPtr(inst, true), |
| 4987 | .intcast => try self.airIntCast(inst, false), | 4987 | .intcast => try self.airIntCast(inst, false), |
| ... | @@ -4989,7 +4989,7 @@ pub const FuncGen = struct { | ... | @@ -4989,7 +4989,7 @@ pub const FuncGen = struct { |
| 4989 | .trunc => try self.airTrunc(inst), | 4989 | .trunc => try self.airTrunc(inst), |
| 4990 | .fptrunc => try self.airFptrunc(inst), | 4990 | .fptrunc => try self.airFptrunc(inst), |
| 4991 | .fpext => try self.airFpext(inst), | 4991 | .fpext => try self.airFpext(inst), |
| 4992 | .load => try self.airLoad(body[i..]), | 4992 | .load => try self.airLoad(inst), |
| 4993 | .not => try self.airNot(inst), | 4993 | .not => try self.airNot(inst), |
| 4994 | .store => try self.airStore(inst, false), | 4994 | .store => try self.airStore(inst, false), |
| 4995 | .store_safe => try self.airStore(inst, true), | 4995 | .store_safe => try self.airStore(inst, true), |
| ... | @@ -5045,7 +5045,7 @@ pub const FuncGen = struct { | ... | @@ -5045,7 +5045,7 @@ pub const FuncGen = struct { |
| 5045 | .atomic_store_seq_cst => try self.airAtomicStore(inst, .seq_cst), | 5045 | .atomic_store_seq_cst => try self.airAtomicStore(inst, .seq_cst), |
| 5046 | | 5046 | |
| 5047 | .struct_field_ptr => try self.airStructFieldPtr(inst), | 5047 | .struct_field_ptr => try self.airStructFieldPtr(inst), |
| 5048 | .struct_field_val => try self.airStructFieldVal(body[i..]), | 5048 | .struct_field_val => try self.airStructFieldVal(inst), |
| 5049 | | 5049 | |
| 5050 | .struct_field_ptr_index_0 => try self.airStructFieldPtrIndex(inst, 0), | 5050 | .struct_field_ptr_index_0 => try self.airStructFieldPtrIndex(inst, 0), |
| 5051 | .struct_field_ptr_index_1 => try self.airStructFieldPtrIndex(inst, 1), | 5051 | .struct_field_ptr_index_1 => try self.airStructFieldPtrIndex(inst, 1), |
| ... | @@ -5054,18 +5054,18 @@ pub const FuncGen = struct { | ... | @@ -5054,18 +5054,18 @@ pub const FuncGen = struct { |
| 5054 | | 5054 | |
| 5055 | .field_parent_ptr => try self.airFieldParentPtr(inst), | 5055 | .field_parent_ptr => try self.airFieldParentPtr(inst), |
| 5056 | | 5056 | |
| 5057 | .array_elem_val => try self.airArrayElemVal(body[i..]), | 5057 | .array_elem_val => try self.airArrayElemVal(inst), |
| 5058 | .slice_elem_val => try self.airSliceElemVal(body[i..]), | 5058 | .slice_elem_val => try self.airSliceElemVal(inst), |
| 5059 | .slice_elem_ptr => try self.airSliceElemPtr(inst), | 5059 | .slice_elem_ptr => try self.airSliceElemPtr(inst), |
| 5060 | .ptr_elem_val => try self.airPtrElemVal(body[i..]), | 5060 | .ptr_elem_val => try self.airPtrElemVal(inst), |
| 5061 | .ptr_elem_ptr => try self.airPtrElemPtr(inst), | 5061 | .ptr_elem_ptr => try self.airPtrElemPtr(inst), |
| 5062 | | 5062 | |
| 5063 | .optional_payload => try self.airOptionalPayload(body[i..]), | 5063 | .optional_payload => try self.airOptionalPayload(inst), |
| 5064 | .optional_payload_ptr => try self.airOptionalPayloadPtr(inst), | 5064 | .optional_payload_ptr => try self.airOptionalPayloadPtr(inst), |
| 5065 | .optional_payload_ptr_set => try self.airOptionalPayloadPtrSet(inst), | 5065 | .optional_payload_ptr_set => try self.airOptionalPayloadPtrSet(inst), |
| 5066 | | 5066 | |
| 5067 | .unwrap_errunion_payload => try self.airErrUnionPayload(body[i..], false), | 5067 | .unwrap_errunion_payload => try self.airErrUnionPayload(inst, false), |
| 5068 | .unwrap_errunion_payload_ptr => try self.airErrUnionPayload(body[i..], true), | 5068 | .unwrap_errunion_payload_ptr => try self.airErrUnionPayload(inst, true), |
| 5069 | .unwrap_errunion_err => try self.airErrUnionErr(inst, false), | 5069 | .unwrap_errunion_err => try self.airErrUnionErr(inst, false), |
| 5070 | .unwrap_errunion_err_ptr => try self.airErrUnionErr(inst, true), | 5070 | .unwrap_errunion_err_ptr => try self.airErrUnionErr(inst, true), |
| 5071 | .errunion_payload_ptr_set => try self.airErrUnionPayloadPtrSet(inst), | 5071 | .errunion_payload_ptr_set => try self.airErrUnionPayloadPtrSet(inst), |
| ... | @@ -6266,19 +6266,14 @@ pub const FuncGen = struct { | ... | @@ -6266,19 +6266,14 @@ pub const FuncGen = struct { |
| 6266 | // No need to reset the insert cursor since this instruction is noreturn. | 6266 | // No need to reset the insert cursor since this instruction is noreturn. |
| 6267 | } | 6267 | } |
| 6268 | | 6268 | |
| 6269 | fn airTry(self: *FuncGen, body_tail: []const Air.Inst.Index, err_cold: bool) !Builder.Value { | 6269 | fn airTry(self: *FuncGen, inst: Air.Inst.Index, err_cold: bool) !Builder.Value { |
| 6270 | const pt = self.ng.pt; | | |
| 6271 | const zcu = pt.zcu; | | |
| 6272 | const inst = body_tail[0]; | | |
| 6273 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; | 6270 | const pl_op = self.air.instructions.items(.data)[@intFromEnum(inst)].pl_op; |
| 6274 | const err_union = try self.resolveInst(pl_op.operand); | 6271 | const err_union = try self.resolveInst(pl_op.operand); |
| 6275 | const extra = self.air.extraData(Air.Try, pl_op.payload); | 6272 | const extra = self.air.extraData(Air.Try, pl_op.payload); |
| 6276 | const body: []const Air.Inst.Index = @ptrCast(self.air.extra.items[extra.end..][0..extra.data.body_len]); | 6273 | const body: []const Air.Inst.Index = @ptrCast(self.air.extra.items[extra.end..][0..extra.data.body_len]); |
| 6277 | const err_union_ty = self.typeOf(pl_op.operand); | 6274 | const err_union_ty = self.typeOf(pl_op.operand); |
| 6278 | const payload_ty = self.typeOfIndex(inst); | | |
| 6279 | const can_elide_load = if (isByRef(payload_ty, zcu)) self.canElideLoad(body_tail) else false; | | |
| 6280 | const is_unused = self.liveness.isUnused(inst); | 6275 | const is_unused = self.liveness.isUnused(inst); |
| 6281 | return lowerTry(self, err_union, body, err_union_ty, false, can_elide_load, is_unused, err_cold); | 6276 | return lowerTry(self, err_union, body, err_union_ty, false, false, is_unused, err_cold); |
| 6282 | } | 6277 | } |
| 6283 | | 6278 | |
| 6284 | fn airTryPtr(self: *FuncGen, inst: Air.Inst.Index, err_cold: bool) !Builder.Value { | 6279 | fn airTryPtr(self: *FuncGen, inst: Air.Inst.Index, err_cold: bool) !Builder.Value { |
| ... | @@ -6824,11 +6819,10 @@ pub const FuncGen = struct { | ... | @@ -6824,11 +6819,10 @@ pub const FuncGen = struct { |
| 6824 | return self.wip.gepStruct(slice_llvm_ty, slice_ptr, index, ""); | 6819 | return self.wip.gepStruct(slice_llvm_ty, slice_ptr, index, ""); |
| 6825 | } | 6820 | } |
| 6826 | | 6821 | |
| 6827 | fn airSliceElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value { | 6822 | fn airSliceElemVal(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 6828 | const o = self.ng.object; | 6823 | const o = self.ng.object; |
| 6829 | const pt = self.ng.pt; | 6824 | const pt = self.ng.pt; |
| 6830 | const zcu = pt.zcu; | 6825 | const zcu = pt.zcu; |
| 6831 | const inst = body_tail[0]; | | |
| 6832 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 6826 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 6833 | const slice_ty = self.typeOf(bin_op.lhs); | 6827 | const slice_ty = self.typeOf(bin_op.lhs); |
| 6834 | const slice = try self.resolveInst(bin_op.lhs); | 6828 | const slice = try self.resolveInst(bin_op.lhs); |
| ... | @@ -6838,9 +6832,6 @@ pub const FuncGen = struct { | ... | @@ -6838,9 +6832,6 @@ pub const FuncGen = struct { |
| 6838 | const base_ptr = try self.wip.extractValue(slice, &.{0}, ""); | 6832 | const base_ptr = try self.wip.extractValue(slice, &.{0}, ""); |
| 6839 | const ptr = try self.wip.gep(.inbounds, llvm_elem_ty, base_ptr, &.{index}, ""); | 6833 | const ptr = try self.wip.gep(.inbounds, llvm_elem_ty, base_ptr, &.{index}, ""); |
| 6840 | if (isByRef(elem_ty, zcu)) { | 6834 | if (isByRef(elem_ty, zcu)) { |
| 6841 | if (self.canElideLoad(body_tail)) | | |
| 6842 | return ptr; | | |
| 6843 | | | |
| 6844 | self.maybeMarkAllowZeroAccess(slice_ty.ptrInfo(zcu)); | 6835 | self.maybeMarkAllowZeroAccess(slice_ty.ptrInfo(zcu)); |
| 6845 | | 6836 | |
| 6846 | const slice_align = (slice_ty.ptrAlignment(zcu).min(elem_ty.abiAlignment(zcu))).toLlvm(); | 6837 | const slice_align = (slice_ty.ptrAlignment(zcu).min(elem_ty.abiAlignment(zcu))).toLlvm(); |
| ... | @@ -6867,11 +6858,10 @@ pub const FuncGen = struct { | ... | @@ -6867,11 +6858,10 @@ pub const FuncGen = struct { |
| 6867 | return self.wip.gep(.inbounds, llvm_elem_ty, base_ptr, &.{index}, ""); | 6858 | return self.wip.gep(.inbounds, llvm_elem_ty, base_ptr, &.{index}, ""); |
| 6868 | } | 6859 | } |
| 6869 | | 6860 | |
| 6870 | fn airArrayElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value { | 6861 | fn airArrayElemVal(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 6871 | const o = self.ng.object; | 6862 | const o = self.ng.object; |
| 6872 | const pt = self.ng.pt; | 6863 | const pt = self.ng.pt; |
| 6873 | const zcu = pt.zcu; | 6864 | const zcu = pt.zcu; |
| 6874 | const inst = body_tail[0]; | | |
| 6875 | | 6865 | |
| 6876 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 6866 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 6877 | const array_ty = self.typeOf(bin_op.lhs); | 6867 | const array_ty = self.typeOf(bin_op.lhs); |
| ... | @@ -6884,9 +6874,7 @@ pub const FuncGen = struct { | ... | @@ -6884,9 +6874,7 @@ pub const FuncGen = struct { |
| 6884 | try o.builder.intValue(try o.lowerType(pt, Type.usize), 0), rhs, | 6874 | try o.builder.intValue(try o.lowerType(pt, Type.usize), 0), rhs, |
| 6885 | }; | 6875 | }; |
| 6886 | if (isByRef(elem_ty, zcu)) { | 6876 | if (isByRef(elem_ty, zcu)) { |
| 6887 | const elem_ptr = | 6877 | const elem_ptr = try self.wip.gep(.inbounds, array_llvm_ty, array_llvm_val, &indices, ""); |
| 6888 | try self.wip.gep(.inbounds, array_llvm_ty, array_llvm_val, &indices, ""); | | |
| 6889 | if (canElideLoad(self, body_tail)) return elem_ptr; | | |
| 6890 | const elem_alignment = elem_ty.abiAlignment(zcu).toLlvm(); | 6878 | const elem_alignment = elem_ty.abiAlignment(zcu).toLlvm(); |
| 6891 | return self.loadByRef(elem_ptr, elem_ty, elem_alignment, .normal); | 6879 | return self.loadByRef(elem_ptr, elem_ty, elem_alignment, .normal); |
| 6892 | } else { | 6880 | } else { |
| ... | @@ -6900,11 +6888,10 @@ pub const FuncGen = struct { | ... | @@ -6900,11 +6888,10 @@ pub const FuncGen = struct { |
| 6900 | return self.wip.extractElement(array_llvm_val, rhs, ""); | 6888 | return self.wip.extractElement(array_llvm_val, rhs, ""); |
| 6901 | } | 6889 | } |
| 6902 | | 6890 | |
| 6903 | fn airPtrElemVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value { | 6891 | fn airPtrElemVal(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 6904 | const o = self.ng.object; | 6892 | const o = self.ng.object; |
| 6905 | const pt = self.ng.pt; | 6893 | const pt = self.ng.pt; |
| 6906 | const zcu = pt.zcu; | 6894 | const zcu = pt.zcu; |
| 6907 | const inst = body_tail[0]; | | |
| 6908 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; | 6895 | const bin_op = self.air.instructions.items(.data)[@intFromEnum(inst)].bin_op; |
| 6909 | const ptr_ty = self.typeOf(bin_op.lhs); | 6896 | const ptr_ty = self.typeOf(bin_op.lhs); |
| 6910 | const elem_ty = ptr_ty.childType(zcu); | 6897 | const elem_ty = ptr_ty.childType(zcu); |
| ... | @@ -6918,10 +6905,7 @@ pub const FuncGen = struct { | ... | @@ -6918,10 +6905,7 @@ pub const FuncGen = struct { |
| 6918 | else | 6905 | else |
| 6919 | &.{rhs}, ""); | 6906 | &.{rhs}, ""); |
| 6920 | if (isByRef(elem_ty, zcu)) { | 6907 | if (isByRef(elem_ty, zcu)) { |
| 6921 | if (self.canElideLoad(body_tail)) return ptr; | | |
| 6922 | | | |
| 6923 | self.maybeMarkAllowZeroAccess(ptr_ty.ptrInfo(zcu)); | 6908 | self.maybeMarkAllowZeroAccess(ptr_ty.ptrInfo(zcu)); |
| 6924 | | | |
| 6925 | const ptr_align = (ptr_ty.ptrAlignment(zcu).min(elem_ty.abiAlignment(zcu))).toLlvm(); | 6909 | const ptr_align = (ptr_ty.ptrAlignment(zcu).min(elem_ty.abiAlignment(zcu))).toLlvm(); |
| 6926 | return self.loadByRef(ptr, elem_ty, ptr_align, if (ptr_ty.isVolatilePtr(zcu)) .@"volatile" else .normal); | 6910 | return self.loadByRef(ptr, elem_ty, ptr_align, if (ptr_ty.isVolatilePtr(zcu)) .@"volatile" else .normal); |
| 6927 | } | 6911 | } |
| ... | @@ -6974,11 +6958,10 @@ pub const FuncGen = struct { | ... | @@ -6974,11 +6958,10 @@ pub const FuncGen = struct { |
| 6974 | return self.fieldPtr(inst, struct_ptr, struct_ptr_ty, field_index); | 6958 | return self.fieldPtr(inst, struct_ptr, struct_ptr_ty, field_index); |
| 6975 | } | 6959 | } |
| 6976 | | 6960 | |
| 6977 | fn airStructFieldVal(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value { | 6961 | fn airStructFieldVal(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 6978 | const o = self.ng.object; | 6962 | const o = self.ng.object; |
| 6979 | const pt = self.ng.pt; | 6963 | const pt = self.ng.pt; |
| 6980 | const zcu = pt.zcu; | 6964 | const zcu = pt.zcu; |
| 6981 | const inst = body_tail[0]; | | |
| 6982 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; | 6965 | const ty_pl = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_pl; |
| 6983 | const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data; | 6966 | const struct_field = self.air.extraData(Air.StructField, ty_pl.payload).data; |
| 6984 | const struct_ty = self.typeOf(struct_field.struct_operand); | 6967 | const struct_ty = self.typeOf(struct_field.struct_operand); |
| ... | @@ -7052,9 +7035,6 @@ pub const FuncGen = struct { | ... | @@ -7052,9 +7035,6 @@ pub const FuncGen = struct { |
| 7052 | .flags = .{ .alignment = alignment }, | 7035 | .flags = .{ .alignment = alignment }, |
| 7053 | }); | 7036 | }); |
| 7054 | if (isByRef(field_ty, zcu)) { | 7037 | if (isByRef(field_ty, zcu)) { |
| 7055 | if (canElideLoad(self, body_tail)) | | |
| 7056 | return field_ptr; | | |
| 7057 | | | |
| 7058 | assert(alignment != .none); | 7038 | assert(alignment != .none); |
| 7059 | const field_alignment = alignment.toLlvm(); | 7039 | const field_alignment = alignment.toLlvm(); |
| 7060 | return self.loadByRef(field_ptr, field_ty, field_alignment, .normal); | 7040 | return self.loadByRef(field_ptr, field_ty, field_alignment, .normal); |
| ... | @@ -7070,7 +7050,6 @@ pub const FuncGen = struct { | ... | @@ -7070,7 +7050,6 @@ pub const FuncGen = struct { |
| 7070 | try self.wip.gepStruct(union_llvm_ty, struct_llvm_val, payload_index, ""); | 7050 | try self.wip.gepStruct(union_llvm_ty, struct_llvm_val, payload_index, ""); |
| 7071 | const payload_alignment = layout.payload_align.toLlvm(); | 7051 | const payload_alignment = layout.payload_align.toLlvm(); |
| 7072 | if (isByRef(field_ty, zcu)) { | 7052 | if (isByRef(field_ty, zcu)) { |
| 7073 | if (canElideLoad(self, body_tail)) return field_ptr; | | |
| 7074 | return self.loadByRef(field_ptr, field_ty, payload_alignment, .normal); | 7053 | return self.loadByRef(field_ptr, field_ty, payload_alignment, .normal); |
| 7075 | } else { | 7054 | } else { |
| 7076 | return self.loadTruncate(.normal, field_ty, field_ptr, payload_alignment); | 7055 | return self.loadTruncate(.normal, field_ty, field_ptr, payload_alignment); |
| ... | @@ -7829,11 +7808,10 @@ pub const FuncGen = struct { | ... | @@ -7829,11 +7808,10 @@ pub const FuncGen = struct { |
| 7829 | return self.wip.gepStruct(optional_llvm_ty, operand, 0, ""); | 7808 | return self.wip.gepStruct(optional_llvm_ty, operand, 0, ""); |
| 7830 | } | 7809 | } |
| 7831 | | 7810 | |
| 7832 | fn airOptionalPayload(self: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value { | 7811 | fn airOptionalPayload(self: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 7833 | const o = self.ng.object; | 7812 | const o = self.ng.object; |
| 7834 | const pt = self.ng.pt; | 7813 | const pt = self.ng.pt; |
| 7835 | const zcu = pt.zcu; | 7814 | const zcu = pt.zcu; |
| 7836 | const inst = body_tail[0]; | | |
| 7837 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 7815 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 7838 | const operand = try self.resolveInst(ty_op.operand); | 7816 | const operand = try self.resolveInst(ty_op.operand); |
| 7839 | const optional_ty = self.typeOf(ty_op.operand); | 7817 | const optional_ty = self.typeOf(ty_op.operand); |
| ... | @@ -7846,19 +7824,13 @@ pub const FuncGen = struct { | ... | @@ -7846,19 +7824,13 @@ pub const FuncGen = struct { |
| 7846 | } | 7824 | } |
| 7847 | | 7825 | |
| 7848 | const opt_llvm_ty = try o.lowerType(pt, optional_ty); | 7826 | const opt_llvm_ty = try o.lowerType(pt, optional_ty); |
| 7849 | const can_elide_load = if (isByRef(payload_ty, zcu)) self.canElideLoad(body_tail) else false; | 7827 | return self.optPayloadHandle(opt_llvm_ty, operand, optional_ty, false); |
| 7850 | return self.optPayloadHandle(opt_llvm_ty, operand, optional_ty, can_elide_load); | | |
| 7851 | } | 7828 | } |
| 7852 | | 7829 | |
| 7853 | fn airErrUnionPayload( | 7830 | fn airErrUnionPayload(self: *FuncGen, inst: Air.Inst.Index, operand_is_ptr: bool) !Builder.Value { |
| 7854 | self: *FuncGen, | | |
| 7855 | body_tail: []const Air.Inst.Index, | | |
| 7856 | operand_is_ptr: bool, | | |
| 7857 | ) !Builder.Value { | | |
| 7858 | const o = self.ng.object; | 7831 | const o = self.ng.object; |
| 7859 | const pt = self.ng.pt; | 7832 | const pt = self.ng.pt; |
| 7860 | const zcu = pt.zcu; | 7833 | const zcu = pt.zcu; |
| 7861 | const inst = body_tail[0]; | | |
| 7862 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 7834 | const ty_op = self.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 7863 | const operand = try self.resolveInst(ty_op.operand); | 7835 | const operand = try self.resolveInst(ty_op.operand); |
| 7864 | const operand_ty = self.typeOf(ty_op.operand); | 7836 | const operand_ty = self.typeOf(ty_op.operand); |
| ... | @@ -7877,7 +7849,6 @@ pub const FuncGen = struct { | ... | @@ -7877,7 +7849,6 @@ pub const FuncGen = struct { |
| 7877 | const payload_alignment = payload_ty.abiAlignment(zcu).toLlvm(); | 7849 | const payload_alignment = payload_ty.abiAlignment(zcu).toLlvm(); |
| 7878 | const payload_ptr = try self.wip.gepStruct(err_union_llvm_ty, operand, offset, ""); | 7850 | const payload_ptr = try self.wip.gepStruct(err_union_llvm_ty, operand, offset, ""); |
| 7879 | if (isByRef(payload_ty, zcu)) { | 7851 | if (isByRef(payload_ty, zcu)) { |
| 7880 | if (self.canElideLoad(body_tail)) return payload_ptr; | | |
| 7881 | return self.loadByRef(payload_ptr, payload_ty, payload_alignment, .normal); | 7852 | return self.loadByRef(payload_ptr, payload_ty, payload_alignment, .normal); |
| 7882 | } | 7853 | } |
| 7883 | const payload_llvm_ty = err_union_llvm_ty.structFields(&o.builder)[offset]; | 7854 | const payload_llvm_ty = err_union_llvm_ty.structFields(&o.builder)[offset]; |
| ... | @@ -9740,45 +9711,14 @@ pub const FuncGen = struct { | ... | @@ -9740,45 +9711,14 @@ pub const FuncGen = struct { |
| 9740 | return .none; | 9711 | return .none; |
| 9741 | } | 9712 | } |
| 9742 | | 9713 | |
| 9743 | /// As an optimization, we want to avoid unnecessary copies of isByRef=true | 9714 | fn airLoad(fg: *FuncGen, inst: Air.Inst.Index) !Builder.Value { |
| 9744 | /// types. Here, we scan forward in the current block, looking to see if | | |
| 9745 | /// this load dies before any side effects occur. In such case, we can | | |
| 9746 | /// safely return the operand without making a copy. | | |
| 9747 | /// | | |
| 9748 | /// The first instruction of `body_tail` is the one whose copy we want to elide. | | |
| 9749 | fn canElideLoad(fg: *FuncGen, body_tail: []const Air.Inst.Index) bool { | | |
| 9750 | const zcu = fg.ng.pt.zcu; | | |
| 9751 | const ip = &zcu.intern_pool; | | |
| 9752 | for (body_tail[1..]) |body_inst| { | | |
| 9753 | switch (fg.liveness.categorizeOperand(fg.air, zcu, body_inst, body_tail[0], ip)) { | | |
| 9754 | .none => continue, | | |
| 9755 | .write, .noret, .complex => return false, | | |
| 9756 | .tomb => return true, | | |
| 9757 | } | | |
| 9758 | } | | |
| 9759 | // The only way to get here is to hit the end of a loop instruction | | |
| 9760 | // (implicit repeat). | | |
| 9761 | return false; | | |
| 9762 | } | | |
| 9763 | | | |
| 9764 | fn airLoad(fg: *FuncGen, body_tail: []const Air.Inst.Index) !Builder.Value { | | |
| 9765 | const pt = fg.ng.pt; | 9715 | const pt = fg.ng.pt; |
| 9766 | const zcu = pt.zcu; | 9716 | const zcu = pt.zcu; |
| 9767 | const inst = body_tail[0]; | | |
| 9768 | const ty_op = fg.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; | 9717 | const ty_op = fg.air.instructions.items(.data)[@intFromEnum(inst)].ty_op; |
| 9769 | const ptr_ty = fg.typeOf(ty_op.operand); | 9718 | const ptr_ty = fg.typeOf(ty_op.operand); |
| 9770 | const ptr_info = ptr_ty.ptrInfo(zcu); | 9719 | const ptr_info = ptr_ty.ptrInfo(zcu); |
| 9771 | const ptr = try fg.resolveInst(ty_op.operand); | 9720 | const ptr = try fg.resolveInst(ty_op.operand); |
| 9772 | | | |
| 9773 | elide: { | | |
| 9774 | if (ptr_info.flags.alignment != .none) break :elide; | | |
| 9775 | if (!isByRef(Type.fromInterned(ptr_info.child), zcu)) break :elide; | | |
| 9776 | if (!canElideLoad(fg, body_tail)) break :elide; | | |
| 9777 | return ptr; | | |
| 9778 | } | | |
| 9779 | | | |
| 9780 | fg.maybeMarkAllowZeroAccess(ptr_info); | 9721 | fg.maybeMarkAllowZeroAccess(ptr_info); |
| 9781 | | | |
| 9782 | return fg.load(ptr, ptr_ty); | 9722 | return fg.load(ptr, ptr_ty); |
| 9783 | } | 9723 | } |
| 9784 | | 9724 | |