| ... | @@ -3866,8 +3866,8 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com | ... | @@ -3866,8 +3866,8 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 3866 | const dummy_ptr = try trash_block.addTy(.alloc, mut_final_ptr_ty); | 3866 | const dummy_ptr = try trash_block.addTy(.alloc, mut_final_ptr_ty); |
| 3867 | const empty_trash_count = trash_block.instructions.items.len; | 3867 | const empty_trash_count = trash_block.instructions.items.len; |
| 3868 | | 3868 | |
| 3869 | for (placeholders, 0..) |bitcast_inst, i| { | 3869 | for (peer_inst_list, placeholders) |peer_inst, placeholder_inst| { |
| 3870 | const sub_ptr_ty = sema.typeOf(Air.indexToRef(bitcast_inst)); | 3870 | const sub_ptr_ty = sema.typeOf(Air.indexToRef(placeholder_inst)); |
| 3871 | | 3871 | |
| 3872 | if (mut_final_ptr_ty.eql(sub_ptr_ty, sema.mod)) { | 3872 | if (mut_final_ptr_ty.eql(sub_ptr_ty, sema.mod)) { |
| 3873 | // New result location type is the same as the old one; nothing | 3873 | // New result location type is the same as the old one; nothing |
| ... | @@ -3875,39 +3875,54 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com | ... | @@ -3875,39 +3875,54 @@ fn zirResolveInferredAlloc(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Com |
| 3875 | continue; | 3875 | continue; |
| 3876 | } | 3876 | } |
| 3877 | | 3877 | |
| 3878 | var bitcast_block = block.makeSubBlock(); | 3878 | var replacement_block = block.makeSubBlock(); |
| 3879 | defer bitcast_block.instructions.deinit(gpa); | 3879 | defer replacement_block.instructions.deinit(gpa); |
| 3880 | | 3880 | |
| 3881 | trash_block.instructions.shrinkRetainingCapacity(empty_trash_count); | 3881 | const result = switch (sema.air_instructions.items(.tag)[placeholder_inst]) { |
| 3882 | const sub_ptr = try sema.coerceResultPtr(&bitcast_block, src, ptr, dummy_ptr, peer_inst_list[i], &trash_block); | 3882 | .bitcast => result: { |
| | 3883 | trash_block.instructions.shrinkRetainingCapacity(empty_trash_count); |
| | 3884 | const sub_ptr = try sema.coerceResultPtr(&replacement_block, src, ptr, dummy_ptr, peer_inst, &trash_block); |
| | 3885 | |
| | 3886 | assert(replacement_block.instructions.items.len > 0); |
| | 3887 | break :result sub_ptr; |
| | 3888 | }, |
| | 3889 | .store => result: { |
| | 3890 | const bin_op = sema.air_instructions.items(.data)[placeholder_inst].bin_op; |
| | 3891 | try sema.storePtr2(&replacement_block, src, bin_op.lhs, src, bin_op.rhs, src, .bitcast); |
| | 3892 | break :result .void_value; |
| | 3893 | }, |
| | 3894 | else => unreachable, |
| | 3895 | }; |
| 3883 | | 3896 | |
| 3884 | assert(bitcast_block.instructions.items.len > 0); | | |
| 3885 | // If only one instruction is produced then we can replace the bitcast | 3897 | // If only one instruction is produced then we can replace the bitcast |
| 3886 | // placeholder instruction with this instruction; no need for an entire block. | 3898 | // placeholder instruction with this instruction; no need for an entire block. |
| 3887 | if (bitcast_block.instructions.items.len == 1) { | 3899 | if (replacement_block.instructions.items.len == 1) { |
| 3888 | const only_inst = bitcast_block.instructions.items[0]; | 3900 | const only_inst = replacement_block.instructions.items[0]; |
| 3889 | sema.air_instructions.set(bitcast_inst, sema.air_instructions.get(only_inst)); | 3901 | sema.air_instructions.set(placeholder_inst, sema.air_instructions.get(only_inst)); |
| 3890 | continue; | 3902 | continue; |
| 3891 | } | 3903 | } |
| 3892 | | 3904 | |
| 3893 | // Here we replace the placeholder bitcast instruction with a block | 3905 | // Here we replace the placeholder bitcast instruction with a block |
| 3894 | // that does the coerce_result_ptr logic. | 3906 | // that does the coerce_result_ptr logic. |
| 3895 | _ = try bitcast_block.addBr(bitcast_inst, sub_ptr); | 3907 | _ = try replacement_block.addBr(placeholder_inst, result); |
| 3896 | const ty_inst = sema.air_instructions.items(.data)[bitcast_inst].ty_op.ty; | 3908 | const ty_inst = if (result == .void_value) |
| | 3909 | .void_type |
| | 3910 | else |
| | 3911 | sema.air_instructions.items(.data)[placeholder_inst].ty_op.ty; |
| 3897 | try sema.air_extra.ensureUnusedCapacity( | 3912 | try sema.air_extra.ensureUnusedCapacity( |
| 3898 | gpa, | 3913 | gpa, |
| 3899 | @typeInfo(Air.Block).Struct.fields.len + bitcast_block.instructions.items.len, | 3914 | @typeInfo(Air.Block).Struct.fields.len + replacement_block.instructions.items.len, |
| 3900 | ); | 3915 | ); |
| 3901 | sema.air_instructions.set(bitcast_inst, .{ | 3916 | sema.air_instructions.set(placeholder_inst, .{ |
| 3902 | .tag = .block, | 3917 | .tag = .block, |
| 3903 | .data = .{ .ty_pl = .{ | 3918 | .data = .{ .ty_pl = .{ |
| 3904 | .ty = ty_inst, | 3919 | .ty = ty_inst, |
| 3905 | .payload = sema.addExtraAssumeCapacity(Air.Block{ | 3920 | .payload = sema.addExtraAssumeCapacity(Air.Block{ |
| 3906 | .body_len = @intCast(u32, bitcast_block.instructions.items.len), | 3921 | .body_len = @intCast(u32, replacement_block.instructions.items.len), |
| 3907 | }), | 3922 | }), |
| 3908 | } }, | 3923 | } }, |
| 3909 | }); | 3924 | }); |
| 3910 | sema.air_extra.appendSliceAssumeCapacity(bitcast_block.instructions.items); | 3925 | sema.air_extra.appendSliceAssumeCapacity(replacement_block.instructions.items); |
| 3911 | } | 3926 | } |
| 3912 | }, | 3927 | }, |
| 3913 | else => unreachable, | 3928 | else => unreachable, |
| ... | @@ -4916,7 +4931,7 @@ fn zirStoreToBlockPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE | ... | @@ -4916,7 +4931,7 @@ fn zirStoreToBlockPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) CompileE |
| 4916 | }, | 4931 | }, |
| 4917 | .inferred_alloc => { | 4932 | .inferred_alloc => { |
| 4918 | const inferred_alloc = ptr_val.castTag(.inferred_alloc).?; | 4933 | const inferred_alloc = ptr_val.castTag(.inferred_alloc).?; |
| 4919 | return sema.storeToInferredAlloc(block, src, ptr, operand, inferred_alloc); | 4934 | return sema.storeToInferredAlloc(block, ptr, operand, inferred_alloc); |
| 4920 | }, | 4935 | }, |
| 4921 | else => break :blk, | 4936 | else => break :blk, |
| 4922 | } | 4937 | } |
| ... | @@ -4945,7 +4960,7 @@ fn zirStoreToInferredPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compi | ... | @@ -4945,7 +4960,7 @@ fn zirStoreToInferredPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compi |
| 4945 | }, | 4960 | }, |
| 4946 | .inferred_alloc => { | 4961 | .inferred_alloc => { |
| 4947 | const inferred_alloc = ptr_val.castTag(.inferred_alloc).?; | 4962 | const inferred_alloc = ptr_val.castTag(.inferred_alloc).?; |
| 4948 | return sema.storeToInferredAlloc(block, src, ptr, operand, inferred_alloc); | 4963 | return sema.storeToInferredAlloc(block, ptr, operand, inferred_alloc); |
| 4949 | }, | 4964 | }, |
| 4950 | else => unreachable, | 4965 | else => unreachable, |
| 4951 | } | 4966 | } |
| ... | @@ -4954,27 +4969,19 @@ fn zirStoreToInferredPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compi | ... | @@ -4954,27 +4969,19 @@ fn zirStoreToInferredPtr(sema: *Sema, block: *Block, inst: Zir.Inst.Index) Compi |
| 4954 | fn storeToInferredAlloc( | 4969 | fn storeToInferredAlloc( |
| 4955 | sema: *Sema, | 4970 | sema: *Sema, |
| 4956 | block: *Block, | 4971 | block: *Block, |
| 4957 | src: LazySrcLoc, | | |
| 4958 | ptr: Air.Inst.Ref, | 4972 | ptr: Air.Inst.Ref, |
| 4959 | operand: Air.Inst.Ref, | 4973 | operand: Air.Inst.Ref, |
| 4960 | inferred_alloc: *Value.Payload.InferredAlloc, | 4974 | inferred_alloc: *Value.Payload.InferredAlloc, |
| 4961 | ) CompileError!void { | 4975 | ) CompileError!void { |
| 4962 | const operand_ty = sema.typeOf(operand); | 4976 | // Create a store instruction as a placeholder. This will be replaced by a |
| 4963 | // Create a runtime bitcast instruction with exactly the type the pointer wants. | 4977 | // proper store sequence once we know the stored type. |
| 4964 | const target = sema.mod.getTarget(); | 4978 | const dummy_store = try block.addBinOp(.store, ptr, operand); |
| 4965 | const ptr_ty = try Type.ptr(sema.arena, sema.mod, .{ | | |
| 4966 | .pointee_type = operand_ty, | | |
| 4967 | .@"align" = inferred_alloc.data.alignment, | | |
| 4968 | .@"addrspace" = target_util.defaultAddressSpace(target, .local), | | |
| 4969 | }); | | |
| 4970 | const bitcasted_ptr = try block.addBitCast(ptr_ty, ptr); | | |
| 4971 | // Add the stored instruction to the set we will use to resolve peer types | 4979 | // Add the stored instruction to the set we will use to resolve peer types |
| 4972 | // for the inferred allocation. | 4980 | // for the inferred allocation. |
| 4973 | try inferred_alloc.data.prongs.append(sema.arena, .{ | 4981 | try inferred_alloc.data.prongs.append(sema.arena, .{ |
| 4974 | .stored_inst = operand, | 4982 | .stored_inst = operand, |
| 4975 | .placeholder = Air.refToIndex(bitcasted_ptr).?, | 4983 | .placeholder = Air.refToIndex(dummy_store).?, |
| 4976 | }); | 4984 | }); |
| 4977 | return sema.storePtr2(block, src, bitcasted_ptr, src, operand, src, .bitcast); | | |
| 4978 | } | 4985 | } |
| 4979 | | 4986 | |
| 4980 | fn storeToInferredAllocComptime( | 4987 | fn storeToInferredAllocComptime( |