authorgravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2022-11-01 04:47:09-04:00
committergravatar for jacobly@ziglang.orgJacob Young <jacobly@ziglang.org> 2022-11-01 20:39:06-04:00
log09763435a85a6108cc4624b51ac1b016746078b6
tree0e922817d4ceba843f68d031b272b87ec5640375
parent071404ff6500d26c3f8c5b08645bd90ebb3a901b

cbe: support arrays in more places


3 files changed, 129 insertions(+), 54 deletions(-)

src/codegen/c.zig+129-52
......@@ -2597,19 +2597,36 @@ fn airSliceField(f: *Function, inst: Air.Inst.Index, is_ptr: bool, field_name: [
25972597}
25982598
25992599fn airPtrElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
2600 const inst_ty = f.air.typeOfIndex(inst);
26002601 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
26012602 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;
26032605
26042606 const ptr = try f.resolveInst(bin_op.lhs);
26052607 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);
26062613 const writer = f.object.writer();
2607 const local = try f.allocLocal(f.air.typeOfIndex(inst), .Const);
2608 try writer.writeAll(" = ");
2614 if (is_array) {
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(" = ");
26092620 try f.writeCValue(writer, ptr, .Other);
26102621 try writer.writeByte('[');
26112622 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");
26132630 return local;
26142631}
26152632
......@@ -2639,19 +2656,36 @@ fn airPtrElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
26392656}
26402657
26412658fn airSliceElemVal(f: *Function, inst: Air.Inst.Index) !CValue {
2659 const inst_ty = f.air.typeOfIndex(inst);
26422660 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
26432661 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;
26452664
26462665 const slice = try f.resolveInst(bin_op.lhs);
26472666 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);
26482672 const writer = f.object.writer();
2649 const local = try f.allocLocal(f.air.typeOfIndex(inst), .Const);
2650 try writer.writeAll(" = ");
2673 if (is_array) {
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(" = ");
26512679 try f.writeCValue(writer, slice, .Other);
26522680 try writer.writeAll(".ptr[");
26532681 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");
26552689 return local;
26562690}
26572691
......@@ -2674,18 +2708,34 @@ fn airSliceElemPtr(f: *Function, inst: Air.Inst.Index) !CValue {
26742708}
26752709
26762710fn 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;
26782713
26792714 const bin_op = f.air.instructions.items(.data)[inst].bin_op;
26802715 const array = try f.resolveInst(bin_op.lhs);
26812716 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);
26822722 const writer = f.object.writer();
2683 const local = try f.allocLocal(f.air.typeOfIndex(inst), .Const);
2684 try writer.writeAll(" = ");
2723 if (is_array) {
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(" = ");
26852729 try f.writeCValue(writer, array, .Other);
26862730 try writer.writeByte('[');
26872731 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");
26892739 return local;
26902740}
26912741
......@@ -3592,13 +3642,26 @@ fn airBr(f: *Function, inst: Air.Inst.Index) !CValue {
35923642 // If result is .none then the value of the block is unused.
35933643 if (result != .none) {
35943644 const operand = try f.resolveInst(branch.operand);
3595 try f.writeCValue(writer, result, .Other);
3596 try writer.writeAll(" = ");
3597 try f.writeCValue(writer, operand, .Other);
3645
3646 const operand_ty = f.air.typeOf(branch.operand);
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 }
35983661 try writer.writeAll(";\n");
35993662 }
36003663
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});
36023665 return CValue.none;
36033666}
36043667
......@@ -4009,26 +4072,34 @@ fn airOptionalPayload(f: *Function, inst: Air.Inst.Index) !CValue {
40094072 if (f.liveness.isUnused(inst)) return CValue.none;
40104073
40114074 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
4012 const writer = f.object.writer();
40134075 const operand = try f.resolveInst(ty_op.operand);
40144076 const opt_ty = f.air.typeOf(ty_op.operand);
40154077
40164078 var buf: Type.Payload.ElemType = undefined;
40174079 const payload_ty = opt_ty.optionalChild(&buf);
40184080
4019 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
4020 return CValue.none;
4021 }
4022
4023 if (opt_ty.optionalReprIsPayload()) {
4024 return operand;
4025 }
4081 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) return CValue.none;
4082 if (opt_ty.optionalReprIsPayload()) return operand;
40264083
40274084 const inst_ty = f.air.typeOfIndex(inst);
4028 const local = try f.allocLocal(inst_ty, .Const);
4029 try writer.writeAll(" = (");
4030 try f.writeCValue(writer, operand, .Other);
4031 try writer.writeAll(").payload;\n");
4085 const target = f.object.dg.module.getTarget();
4086 const is_array = lowersToArray(inst_ty, target);
4087
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");
40324103 return local;
40334104}
40344105
......@@ -4387,25 +4458,33 @@ fn airUnwrapErrUnionPay(f: *Function, inst: Air.Inst.Index, is_ptr: bool) !CValu
43874458}
43884459
43894460fn airWrapOptional(f: *Function, inst: Air.Inst.Index) !CValue {
4390 if (f.liveness.isUnused(inst))
4391 return CValue.none;
4461 if (f.liveness.isUnused(inst)) return CValue.none;
43924462
4463 const inst_ty = f.air.typeOfIndex(inst);
43934464 const ty_op = f.air.instructions.items(.data)[inst].ty_op;
4394 const writer = f.object.writer();
4395 const operand = try f.resolveInst(ty_op.operand);
4465 const payload = try f.resolveInst(ty_op.operand);
4466 if (inst_ty.optionalReprIsPayload()) return payload;
43964467
4397 const inst_ty = f.air.typeOfIndex(inst);
4398 if (inst_ty.optionalReprIsPayload()) {
4399 return operand;
4400 }
4468 const payload_ty = f.air.typeOf(ty_op.operand);
4469 const target = f.object.dg.module.getTarget();
4470 const is_array = lowersToArray(payload_ty, target);
44014471
4402 // .wrap_optional is used to convert non-optionals into optionals so it can never be null.
4403 const local = try f.allocLocal(inst_ty, .Const);
4472 const local = try f.allocLocal(inst_ty, if (is_array) .Mut else .Const);
4473 const writer = f.object.writer();
44044474 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);
44064476 try writer.writeAll(", .is_null = ");
44074477 try f.object.dg.renderValue(writer, Type.bool, Value.@"false", .Initializer);
44084478 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 }
44094488 return local;
44104489}
44114490
......@@ -4477,35 +4556,33 @@ fn airSaveErrReturnTraceIndex(f: *Function, inst: Air.Inst.Index) !CValue {
44774556}
44784557
44794558fn airWrapErrUnionPay(f: *Function, inst: Air.Inst.Index) !CValue {
4480 if (f.liveness.isUnused(inst))
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);
4559 if (f.liveness.isUnused(inst)) return CValue.none;
44864560
44874561 const inst_ty = f.air.typeOfIndex(inst);
4488 const payload_ty = inst_ty.errorUnionPayload();
44894562 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
44904567 const target = f.object.dg.module.getTarget();
44914568 const is_array = lowersToArray(payload_ty, target);
4569
44924570 const local = try f.allocLocal(inst_ty, if (is_array) .Mut else .Const);
4571 const writer = f.object.writer();
44934572 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);
44954574 try writer.writeAll(", .error = ");
44964575 try f.object.dg.renderValue(writer, error_ty, Value.zero, .Initializer);
44974576 try writer.writeAll(" };\n");
4498
44994577 if (is_array) {
45004578 try writer.writeAll("memcpy(");
4501 try f.writeCValue(writer, local, .Other);
4502 try writer.writeAll(".payload, ");
4503 try f.writeCValue(writer, operand, .FunctionArgument);
4579 try f.writeCValueMember(writer, local, .{ .identifier = "payload" });
4580 try writer.writeAll(", ");
4581 try f.writeCValue(writer, payload, .FunctionArgument);
45044582 try writer.writeAll(", sizeof(");
45054583 try f.renderTypecast(writer, payload_ty);
45064584 try writer.writeAll("));\n");
45074585 }
4508
45094586 return local;
45104587}
45114588
test/behavior/bugs/11139.zig-1
......@@ -3,7 +3,6 @@ const builtin = @import("builtin");
33const expect = std.testing.expect;
44
55test "store array of array of structs at comptime" {
6 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
76 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO
87 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
98
test/behavior/fn.zig-1
......@@ -355,7 +355,6 @@ test "function call with anon list literal" {
355355}
356356
357357test "function call with anon list literal - 2D" {
358 if (builtin.zig_backend == .stage2_c) return error.SkipZigTest; // TODO
359358 if (builtin.zig_backend == .stage2_x86_64) return error.SkipZigTest; // TODO
360359 if (builtin.zig_backend == .stage2_arm) return error.SkipZigTest; // TODO
361360 if (builtin.zig_backend == .stage2_aarch64) return error.SkipZigTest; // TODO