| ... | @@ -2597,19 +2597,36 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, is_ptr: bool, field_name: [ | ... | @@ -2597,19 +2597,36 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, is_ptr: bool, field_name: [ |
| 2597 | } | 2597 | } |
| 2598 | | 2598 | |
| 2599 | fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue { | 2599 | fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| | 2600 | const inst_ty = f.air.typeOfIndex(inst); |
| 2600 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; | 2601 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; |
| 2601 | const ptr_ty = f.air.typeOf(bin_op.lhs); | 2602 | const ptr_ty = f.air.typeOf(bin_op.lhs); |
| 2602 | if (!ptr_ty.isVolatilePtr() and f.liveness.isUnused(inst)) return CValue.none; | 2603 | if ((!ptr_ty.isVolatilePtr() and f.liveness.isUnused(inst)) or |
| | 2604 | !inst_ty.hasRuntimeBitsIgnoreComptime()) return CValue.none; |
| 2603 | | 2605 | |
| 2604 | const ptr = try f.resolveInst(bin_op.lhs); | 2606 | const ptr = try f.resolveInst(bin_op.lhs); |
| 2605 | const index = try f.resolveInst(bin_op.rhs); | 2607 | const index = try f.resolveInst(bin_op.rhs); |
| | 2608 | |
| | 2609 | const target = f.object.dg.module.getTarget(); |
| | 2610 | const is_array = lowersToArray(inst_ty, target); |
| | 2611 | |
| | 2612 | const local = try f.allocLocal(inst_ty, if (is_array) .Mut else .Const); |
| 2606 | const writer = f.object.writer(); | 2613 | const writer = f.object.writer(); |
| 2607 | const local = try f.allocLocal(f.air.typeOfIndex(inst), .Const); | 2614 | if (is_array) { |
| 2608 | try writer.writeAll(" = "); | 2615 | try writer.writeAll(";\n"); |
| | 2616 | try writer.writeAll("memcpy("); |
| | 2617 | try f.writeCValue(writer, local, .FunctionArgument); |
| | 2618 | try writer.writeAll(", "); |
| | 2619 | } else try writer.writeAll(" = "); |
| 2609 | try f.writeCValue(writer, ptr, .Other); | 2620 | try f.writeCValue(writer, ptr, .Other); |
| 2610 | try writer.writeByte('['); | 2621 | try writer.writeByte('['); |
| 2611 | try f.writeCValue(writer, index, .Other); | 2622 | try f.writeCValue(writer, index, .Other); |
| 2612 | try writer.writeAll("];\n"); | 2623 | try writer.writeByte(']'); |
| | 2624 | if (is_array) { |
| | 2625 | try writer.writeAll(", sizeof("); |
| | 2626 | try f.renderTypecast(writer, inst_ty); |
| | 2627 | try writer.writeAll("))"); |
| | 2628 | } |
| | 2629 | try writer.writeAll(";\n"); |
| 2613 | return local; | 2630 | return local; |
| 2614 | } | 2631 | } |
| 2615 | | 2632 | |
| ... | @@ -2639,19 +2656,36 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -2639,19 +2656,36 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2639 | } | 2656 | } |
| 2640 | | 2657 | |
| 2641 | fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue { | 2658 | fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| | 2659 | const inst_ty = f.air.typeOfIndex(inst); |
| 2642 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; | 2660 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; |
| 2643 | const slice_ty = f.air.typeOf(bin_op.lhs); | 2661 | const slice_ty = f.air.typeOf(bin_op.lhs); |
| 2644 | if (!slice_ty.isVolatilePtr() and f.liveness.isUnused(inst)) return CValue.none; | 2662 | if ((!slice_ty.isVolatilePtr() and f.liveness.isUnused(inst)) or |
| | 2663 | !inst_ty.hasRuntimeBitsIgnoreComptime()) return CValue.none; |
| 2645 | | 2664 | |
| 2646 | const slice = try f.resolveInst(bin_op.lhs); | 2665 | const slice = try f.resolveInst(bin_op.lhs); |
| 2647 | const index = try f.resolveInst(bin_op.rhs); | 2666 | const index = try f.resolveInst(bin_op.rhs); |
| | 2667 | |
| | 2668 | const target = f.object.dg.module.getTarget(); |
| | 2669 | const is_array = lowersToArray(inst_ty, target); |
| | 2670 | |
| | 2671 | const local = try f.allocLocal(inst_ty, if (is_array) .Mut else .Const); |
| 2648 | const writer = f.object.writer(); | 2672 | const writer = f.object.writer(); |
| 2649 | const local = try f.allocLocal(f.air.typeOfIndex(inst), .Const); | 2673 | if (is_array) { |
| 2650 | try writer.writeAll(" = "); | 2674 | try writer.writeAll(";\n"); |
| | 2675 | try writer.writeAll("memcpy("); |
| | 2676 | try f.writeCValue(writer, local, .FunctionArgument); |
| | 2677 | try writer.writeAll(", "); |
| | 2678 | } else try writer.writeAll(" = "); |
| 2651 | try f.writeCValue(writer, slice, .Other); | 2679 | try f.writeCValue(writer, slice, .Other); |
| 2652 | try writer.writeAll(".ptr["); | 2680 | try writer.writeAll(".ptr["); |
| 2653 | try f.writeCValue(writer, index, .Other); | 2681 | try f.writeCValue(writer, index, .Other); |
| 2654 | try writer.writeAll("];\n"); | 2682 | try writer.writeByte(']'); |
| | 2683 | if (is_array) { |
| | 2684 | try writer.writeAll(", sizeof("); |
| | 2685 | try f.renderTypecast(writer, inst_ty); |
| | 2686 | try writer.writeAll("))"); |
| | 2687 | } |
| | 2688 | try writer.writeAll(";\n"); |
| 2655 | return local; | 2689 | return local; |
| 2656 | } | 2690 | } |
| 2657 | | 2691 | |
| ... | @@ -2674,18 +2708,34 @@ fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -2674,18 +2708,34 @@ fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2674 | } | 2708 | } |
| 2675 | | 2709 | |
| 2676 | fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue { | 2710 | fn airArrayElemVal(f: *Function, inst: Air.Inst.Index) !CValue { |
| 2677 | if (f.liveness.isUnused(inst)) return CValue.none; | 2711 | const inst_ty = f.air.typeOfIndex(inst); |
| | 2712 | if (f.liveness.isUnused(inst) or !inst_ty.hasRuntimeBitsIgnoreComptime()) return CValue.none; |
| 2678 | | 2713 | |
| 2679 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; | 2714 | const bin_op = f.air.instructions.items(.data)[inst].bin_op; |
| 2680 | const array = try f.resolveInst(bin_op.lhs); | 2715 | const array = try f.resolveInst(bin_op.lhs); |
| 2681 | const index = try f.resolveInst(bin_op.rhs); | 2716 | const index = try f.resolveInst(bin_op.rhs); |
| | 2717 | |
| | 2718 | const target = f.object.dg.module.getTarget(); |
| | 2719 | const is_array = lowersToArray(inst_ty, target); |
| | 2720 | |
| | 2721 | const local = try f.allocLocal(inst_ty, if (is_array) .Mut else .Const); |
| 2682 | const writer = f.object.writer(); | 2722 | const writer = f.object.writer(); |
| 2683 | const local = try f.allocLocal(f.air.typeOfIndex(inst), .Const); | 2723 | if (is_array) { |
| 2684 | try writer.writeAll(" = "); | 2724 | try writer.writeAll(";\n"); |
| | 2725 | try writer.writeAll("memcpy("); |
| | 2726 | try f.writeCValue(writer, local, .FunctionArgument); |
| | 2727 | try writer.writeAll(", "); |
| | 2728 | } else try writer.writeAll(" = "); |
| 2685 | try f.writeCValue(writer, array, .Other); | 2729 | try f.writeCValue(writer, array, .Other); |
| 2686 | try writer.writeByte('['); | 2730 | try writer.writeByte('['); |
| 2687 | try f.writeCValue(writer, index, .Other); | 2731 | try f.writeCValue(writer, index, .Other); |
| 2688 | try writer.writeAll("];\n"); | 2732 | try writer.writeByte(']'); |
| | 2733 | if (is_array) { |
| | 2734 | try writer.writeAll(", sizeof("); |
| | 2735 | try f.renderTypecast(writer, inst_ty); |
| | 2736 | try writer.writeAll("))"); |
| | 2737 | } |
| | 2738 | try writer.writeAll(";\n"); |
| 2689 | return local; | 2739 | return local; |
| 2690 | } | 2740 | } |
| 2691 | | 2741 | |
| ... | @@ -3592,13 +3642,26 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -3592,13 +3642,26 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !CValue { |
| 3592 | // If result is .none then the value of the block is unused. | 3642 | // If result is .none then the value of the block is unused. |
| 3593 | if (result != .none) { | 3643 | if (result != .none) { |
| 3594 | const operand = try f.resolveInst(branch.operand); | 3644 | const operand = try f.resolveInst(branch.operand); |
| 3595 | try f.writeCValue(writer, result, .Other); | 3645 | |
| 3596 | try writer.writeAll(" = "); | 3646 | const operand_ty = f.air.typeOf(branch.operand); |
| 3597 | try f.writeCValue(writer, operand, .Other); | 3647 | const target = f.object.dg.module.getTarget(); |
| | 3648 | if (lowersToArray(operand_ty, target)) { |
| | 3649 | try writer.writeAll("memcpy("); |
| | 3650 | try f.writeCValue(writer, result, .FunctionArgument); |
| | 3651 | try writer.writeAll(", "); |
| | 3652 | try f.writeCValue(writer, operand, .FunctionArgument); |
| | 3653 | try writer.writeAll(", sizeof("); |
| | 3654 | try f.renderTypecast(writer, operand_ty); |
| | 3655 | try writer.writeAll("))"); |
| | 3656 | } else { |
| | 3657 | try f.writeCValue(writer, result, .Other); |
| | 3658 | try writer.writeAll(" = "); |
| | 3659 | try f.writeCValue(writer, operand, .Other); |
| | 3660 | } |
| 3598 | try writer.writeAll(";\n"); | 3661 | try writer.writeAll(";\n"); |
| 3599 | } | 3662 | } |
| 3600 | | 3663 | |
| 3601 | try f.object.writer().print("goto zig_block_{d};\n", .{block.block_id}); | 3664 | try writer.print("goto zig_block_{d};\n", .{block.block_id}); |
| 3602 | return CValue.none; | 3665 | return CValue.none; |
| 3603 | } | 3666 | } |
| 3604 | | 3667 | |
| ... | @@ -4009,26 +4072,34 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4009,26 +4072,34 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4009 | if (f.liveness.isUnused(inst)) return CValue.none; | 4072 | if (f.liveness.isUnused(inst)) return CValue.none; |
| 4010 | | 4073 | |
| 4011 | const ty_op = f.air.instructions.items(.data)[inst].ty_op; | 4074 | const ty_op = f.air.instructions.items(.data)[inst].ty_op; |
| 4012 | const writer = f.object.writer(); | | |
| 4013 | const operand = try f.resolveInst(ty_op.operand); | 4075 | const operand = try f.resolveInst(ty_op.operand); |
| 4014 | const opt_ty = f.air.typeOf(ty_op.operand); | 4076 | const opt_ty = f.air.typeOf(ty_op.operand); |
| 4015 | | 4077 | |
| 4016 | var buf: Type.Payload.ElemType = undefined; | 4078 | var buf: Type.Payload.ElemType = undefined; |
| 4017 | const payload_ty = opt_ty.optionalChild(&buf); | 4079 | const payload_ty = opt_ty.optionalChild(&buf); |
| 4018 | | 4080 | |
| 4019 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) { | 4081 | if (!payload_ty.hasRuntimeBitsIgnoreComptime()) return CValue.none; |
| 4020 | return CValue.none; | 4082 | if (opt_ty.optionalReprIsPayload()) return operand; |
| 4021 | } | | |
| 4022 | | | |
| 4023 | if (opt_ty.optionalReprIsPayload()) { | | |
| 4024 | return operand; | | |
| 4025 | } | | |
| 4026 | | 4083 | |
| 4027 | const inst_ty = f.air.typeOfIndex(inst); | 4084 | const inst_ty = f.air.typeOfIndex(inst); |
| 4028 | const local = try f.allocLocal(inst_ty, .Const); | 4085 | const target = f.object.dg.module.getTarget(); |
| 4029 | try writer.writeAll(" = ("); | 4086 | const is_array = lowersToArray(inst_ty, target); |
| 4030 | try f.writeCValue(writer, operand, .Other); | 4087 | |
| 4031 | try writer.writeAll(").payload;\n"); | 4088 | const local = try f.allocLocal(inst_ty, if (is_array) .Mut else .Const); |
| | 4089 | const writer = f.object.writer(); |
| | 4090 | if (is_array) { |
| | 4091 | try writer.writeAll(";\n"); |
| | 4092 | try writer.writeAll("memcpy("); |
| | 4093 | try f.writeCValue(writer, local, .FunctionArgument); |
| | 4094 | try writer.writeAll(", "); |
| | 4095 | } else try writer.writeAll(" = "); |
| | 4096 | try f.writeCValueMember(writer, operand, .{ .identifier = "payload" }); |
| | 4097 | if (is_array) { |
| | 4098 | try writer.writeAll(", sizeof("); |
| | 4099 | try f.renderTypecast(writer, inst_ty); |
| | 4100 | try writer.writeAll("))"); |
| | 4101 | } |
| | 4102 | try writer.writeAll(";\n"); |
| 4032 | return local; | 4103 | return local; |
| 4033 | } | 4104 | } |
| 4034 | | 4105 | |
| ... | @@ -4387,25 +4458,33 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValu | ... | @@ -4387,25 +4458,33 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValu |
| 4387 | } | 4458 | } |
| 4388 | | 4459 | |
| 4389 | fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue { | 4460 | fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4390 | if (f.liveness.isUnused(inst)) | 4461 | if (f.liveness.isUnused(inst)) return CValue.none; |
| 4391 | return CValue.none; | | |
| 4392 | | 4462 | |
| | 4463 | const inst_ty = f.air.typeOfIndex(inst); |
| 4393 | const ty_op = f.air.instructions.items(.data)[inst].ty_op; | 4464 | const ty_op = f.air.instructions.items(.data)[inst].ty_op; |
| 4394 | const writer = f.object.writer(); | 4465 | const payload = try f.resolveInst(ty_op.operand); |
| 4395 | const operand = try f.resolveInst(ty_op.operand); | 4466 | if (inst_ty.optionalReprIsPayload()) return payload; |
| 4396 | | 4467 | |
| 4397 | const inst_ty = f.air.typeOfIndex(inst); | 4468 | const payload_ty = f.air.typeOf(ty_op.operand); |
| 4398 | if (inst_ty.optionalReprIsPayload()) { | 4469 | const target = f.object.dg.module.getTarget(); |
| 4399 | return operand; | 4470 | const is_array = lowersToArray(payload_ty, target); |
| 4400 | } | | |
| 4401 | | 4471 | |
| 4402 | // .wrap_optional is used to convert non-optionals into optionals so it can never be null. | 4472 | const local = try f.allocLocal(inst_ty, if (is_array) .Mut else .Const); |
| 4403 | const local = try f.allocLocal(inst_ty, .Const); | 4473 | const writer = f.object.writer(); |
| 4404 | try writer.writeAll(" = { .payload = "); | 4474 | try writer.writeAll(" = { .payload = "); |
| 4405 | try f.writeCValue(writer, operand, .Initializer); | 4475 | try f.writeCValue(writer, if (is_array) CValue{ .undef = payload_ty } else payload, .Initializer); |
| 4406 | try writer.writeAll(", .is_null = "); | 4476 | try writer.writeAll(", .is_null = "); |
| 4407 | try f.object.dg.renderValue(writer, Type.bool, Value.@"false", .Initializer); | 4477 | try f.object.dg.renderValue(writer, Type.bool, Value.@"false", .Initializer); |
| 4408 | try writer.writeAll(" };\n"); | 4478 | try writer.writeAll(" };\n"); |
| | 4479 | if (is_array) { |
| | 4480 | try writer.writeAll("memcpy("); |
| | 4481 | try f.writeCValueMember(writer, local, .{ .identifier = "payload" }); |
| | 4482 | try writer.writeAll(", "); |
| | 4483 | try f.writeCValue(writer, payload, .FunctionArgument); |
| | 4484 | try writer.writeAll(", sizeof("); |
| | 4485 | try f.renderTypecast(writer, payload_ty); |
| | 4486 | try writer.writeAll("));\n"); |
| | 4487 | } |
| 4409 | return local; | 4488 | return local; |
| 4410 | } | 4489 | } |
| 4411 | | 4490 | |
| ... | @@ -4477,35 +4556,33 @@ fn airSaveErrReturnTraceIndex(f: *Function, inst: Air.Inst.Index) !CValue { | ... | @@ -4477,35 +4556,33 @@ fn airSaveErrReturnTraceIndex(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4477 | } | 4556 | } |
| 4478 | | 4557 | |
| 4479 | fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue { | 4558 | fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue { |
| 4480 | if (f.liveness.isUnused(inst)) | 4559 | if (f.liveness.isUnused(inst)) return CValue.none; |
| 4481 | return CValue.none; | | |
| 4482 | | | |
| 4483 | const ty_op = f.air.instructions.items(.data)[inst].ty_op; | | |
| 4484 | const writer = f.object.writer(); | | |
| 4485 | const operand = try f.resolveInst(ty_op.operand); | | |
| 4486 | | 4560 | |
| 4487 | const inst_ty = f.air.typeOfIndex(inst); | 4561 | const inst_ty = f.air.typeOfIndex(inst); |
| 4488 | const payload_ty = inst_ty.errorUnionPayload(); | | |
| 4489 | const error_ty = inst_ty.errorUnionSet(); | 4562 | const error_ty = inst_ty.errorUnionSet(); |
| | 4563 | const ty_op = f.air.instructions.items(.data)[inst].ty_op; |
| | 4564 | const payload_ty = inst_ty.errorUnionPayload(); |
| | 4565 | const payload = try f.resolveInst(ty_op.operand); |
| | 4566 | |
| 4490 | const target = f.object.dg.module.getTarget(); | 4567 | const target = f.object.dg.module.getTarget(); |
| 4491 | const is_array = lowersToArray(payload_ty, target); | 4568 | const is_array = lowersToArray(payload_ty, target); |
| | 4569 | |
| 4492 | const local = try f.allocLocal(inst_ty, if (is_array) .Mut else .Const); | 4570 | const local = try f.allocLocal(inst_ty, if (is_array) .Mut else .Const); |
| | 4571 | const writer = f.object.writer(); |
| 4493 | try writer.writeAll(" = { .payload = "); | 4572 | try writer.writeAll(" = { .payload = "); |
| 4494 | try f.writeCValue(writer, if (is_array) CValue{ .undef = payload_ty } else operand, .Initializer); | 4573 | try f.writeCValue(writer, if (is_array) CValue{ .undef = payload_ty } else payload, .Initializer); |
| 4495 | try writer.writeAll(", .error = "); | 4574 | try writer.writeAll(", .error = "); |
| 4496 | try f.object.dg.renderValue(writer, error_ty, Value.zero, .Initializer); | 4575 | try f.object.dg.renderValue(writer, error_ty, Value.zero, .Initializer); |
| 4497 | try writer.writeAll(" };\n"); | 4576 | try writer.writeAll(" };\n"); |
| 4498 | | | |
| 4499 | if (is_array) { | 4577 | if (is_array) { |
| 4500 | try writer.writeAll("memcpy("); | 4578 | try writer.writeAll("memcpy("); |
| 4501 | try f.writeCValue(writer, local, .Other); | 4579 | try f.writeCValueMember(writer, local, .{ .identifier = "payload" }); |
| 4502 | try writer.writeAll(".payload, "); | 4580 | try writer.writeAll(", "); |
| 4503 | try f.writeCValue(writer, operand, .FunctionArgument); | 4581 | try f.writeCValue(writer, payload, .FunctionArgument); |
| 4504 | try writer.writeAll(", sizeof("); | 4582 | try writer.writeAll(", sizeof("); |
| 4505 | try f.renderTypecast(writer, payload_ty); | 4583 | try f.renderTypecast(writer, payload_ty); |
| 4506 | try writer.writeAll("));\n"); | 4584 | try writer.writeAll("));\n"); |
| 4507 | } | 4585 | } |
| 4508 | | | |
| 4509 | return local; | 4586 | return local; |
| 4510 | } | 4587 | } |
| 4511 | | 4588 | |