authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-07-18 20:59:39-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-07-19 11:26:18-07:00
logbab570a22540c2acb15c19e1d080a80d355407e3
treedb04874ddccbd5a341151ebea585d72675e60251
parent65bc4d915daf33255f16a1586e69040fd9148e87

LLVM: lower all structs as byref=true

Same reasoning as previous commit.

1 files changed, 64 insertions(+), 63 deletions(-)

src/codegen/llvm.zig+64-63
......@@ -5730,12 +5730,7 @@ pub const FuncGen = struct {
57305730 // The payload and the optional are the same value.
57315731 return operand;
57325732 }
5733 const index_type = self.context.intType(32);
5734 const indices: [2]*const llvm.Value = .{
5735 index_type.constNull(), // dereference the pointer
5736 index_type.constNull(), // first field is the payload
5737 };
5738 return self.builder.buildInBoundsGEP(operand, &indices, indices.len, "");
5733 return self.builder.buildStructGEP(operand, 0, "");
57395734 }
57405735
57415736 fn airOptionalPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
......@@ -5761,24 +5756,17 @@ pub const FuncGen = struct {
57615756 // Setting to non-null will be done when the payload is set.
57625757 return operand;
57635758 }
5764 const index_type = self.context.intType(32);
5765 {
5766 // First set the non-null bit.
5767 const indices: [2]*const llvm.Value = .{
5768 index_type.constNull(), // dereference the pointer
5769 index_type.constInt(1, .False), // second field is the non-null bit
5770 };
5771 const non_null_ptr = self.builder.buildInBoundsGEP(operand, &indices, indices.len, "");
5772 _ = self.builder.buildStore(non_null_bit, non_null_ptr);
5773 }
5759
5760 // First set the non-null bit.
5761 const non_null_ptr = self.builder.buildStructGEP(operand, 1, "");
5762 // TODO set alignment on this store
5763 _ = self.builder.buildStore(non_null_bit, non_null_ptr);
5764
57745765 // Then return the payload pointer (only if it's used).
57755766 if (self.liveness.isUnused(inst))
57765767 return null;
5777 const indices: [2]*const llvm.Value = .{
5778 index_type.constNull(), // dereference the pointer
5779 index_type.constNull(), // first field is the payload
5780 };
5781 return self.builder.buildInBoundsGEP(operand, &indices, indices.len, "");
5768
5769 return self.builder.buildStructGEP(operand, 0, "");
57825770 }
57835771
57845772 fn airOptionalPayload(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
......@@ -5874,16 +5862,11 @@ pub const FuncGen = struct {
58745862 _ = self.builder.buildStore(non_error_val, operand);
58755863 return operand;
58765864 }
5877 const index_type = self.context.intType(32);
58785865 const target = self.dg.module.getTarget();
58795866 {
58805867 const error_offset = errUnionErrorOffset(payload_ty, target);
58815868 // First set the non-error value.
5882 const indices: [2]*const llvm.Value = .{
5883 index_type.constNull(), // dereference the pointer
5884 index_type.constInt(error_offset, .False),
5885 };
5886 const non_null_ptr = self.builder.buildInBoundsGEP(operand, &indices, indices.len, "");
5869 const non_null_ptr = self.builder.buildStructGEP(operand, error_offset, "");
58875870 const store_inst = self.builder.buildStore(non_error_val, non_null_ptr);
58885871 store_inst.setAlignment(Type.anyerror.abiAlignment(target));
58895872 }
......@@ -5892,11 +5875,7 @@ pub const FuncGen = struct {
58925875 return null;
58935876
58945877 const payload_offset = errUnionPayloadOffset(payload_ty, target);
5895 const indices: [2]*const llvm.Value = .{
5896 index_type.constNull(), // dereference the pointer
5897 index_type.constInt(payload_offset, .False),
5898 };
5899 return self.builder.buildInBoundsGEP(operand, &indices, indices.len, "");
5878 return self.builder.buildStructGEP(operand, payload_offset, "");
59005879 }
59015880
59025881 fn airErrReturnTrace(self: *FuncGen, _: Air.Inst.Index) !?*const llvm.Value {
......@@ -6391,8 +6370,30 @@ pub const FuncGen = struct {
63916370 const overflow_bit = self.builder.buildExtractValue(result_struct, 1, "");
63926371
63936372 var ty_buf: Type.Payload.Pointer = undefined;
6394 const partial = self.builder.buildInsertValue(llvm_dest_ty.getUndef(), result, llvmFieldIndex(dest_ty, 0, tg, &ty_buf).?, "");
6395 return self.builder.buildInsertValue(partial, overflow_bit, llvmFieldIndex(dest_ty, 1, tg, &ty_buf).?, "");
6373 const result_index = llvmFieldIndex(dest_ty, 0, tg, &ty_buf).?;
6374 const overflow_index = llvmFieldIndex(dest_ty, 1, tg, &ty_buf).?;
6375
6376 if (isByRef(dest_ty)) {
6377 const target = self.dg.module.getTarget();
6378 const alloca_inst = self.buildAlloca(llvm_dest_ty);
6379 const result_alignment = dest_ty.abiAlignment(target);
6380 alloca_inst.setAlignment(result_alignment);
6381 {
6382 const field_ptr = self.builder.buildStructGEP(alloca_inst, result_index, "");
6383 const store_inst = self.builder.buildStore(result, field_ptr);
6384 store_inst.setAlignment(result_alignment);
6385 }
6386 {
6387 const field_ptr = self.builder.buildStructGEP(alloca_inst, overflow_index, "");
6388 const store_inst = self.builder.buildStore(overflow_bit, field_ptr);
6389 store_inst.setAlignment(1);
6390 }
6391
6392 return alloca_inst;
6393 }
6394
6395 const partial = self.builder.buildInsertValue(llvm_dest_ty.getUndef(), result, result_index, "");
6396 return self.builder.buildInsertValue(partial, overflow_bit, overflow_index, "");
63966397 }
63976398
63986399 fn buildElementwiseCall(
......@@ -6721,8 +6722,30 @@ pub const FuncGen = struct {
67216722 const overflow_bit = self.builder.buildICmp(.NE, lhs, reconstructed, "");
67226723
67236724 var ty_buf: Type.Payload.Pointer = undefined;
6724 const partial = self.builder.buildInsertValue(llvm_dest_ty.getUndef(), result, llvmFieldIndex(dest_ty, 0, tg, &ty_buf).?, "");
6725 return self.builder.buildInsertValue(partial, overflow_bit, llvmFieldIndex(dest_ty, 1, tg, &ty_buf).?, "");
6725 const result_index = llvmFieldIndex(dest_ty, 0, tg, &ty_buf).?;
6726 const overflow_index = llvmFieldIndex(dest_ty, 1, tg, &ty_buf).?;
6727
6728 if (isByRef(dest_ty)) {
6729 const target = self.dg.module.getTarget();
6730 const alloca_inst = self.buildAlloca(llvm_dest_ty);
6731 const result_alignment = dest_ty.abiAlignment(target);
6732 alloca_inst.setAlignment(result_alignment);
6733 {
6734 const field_ptr = self.builder.buildStructGEP(alloca_inst, result_index, "");
6735 const store_inst = self.builder.buildStore(result, field_ptr);
6736 store_inst.setAlignment(result_alignment);
6737 }
6738 {
6739 const field_ptr = self.builder.buildStructGEP(alloca_inst, overflow_index, "");
6740 const store_inst = self.builder.buildStore(overflow_bit, field_ptr);
6741 store_inst.setAlignment(1);
6742 }
6743
6744 return alloca_inst;
6745 }
6746
6747 const partial = self.builder.buildInsertValue(llvm_dest_ty.getUndef(), result, result_index, "");
6748 return self.builder.buildInsertValue(partial, overflow_bit, overflow_index, "");
67266749 }
67276750
67286751 fn airAnd(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
......@@ -8336,17 +8359,9 @@ pub const FuncGen = struct {
83368359 fn optIsNonNull(self: *FuncGen, opt_handle: *const llvm.Value, is_by_ref: bool) *const llvm.Value {
83378360 const field = b: {
83388361 if (is_by_ref) {
8339 const index_type = self.context.intType(32);
8340
8341 const indices: [2]*const llvm.Value = .{
8342 index_type.constNull(),
8343 index_type.constInt(1, .False),
8344 };
8345
8346 const field_ptr = self.builder.buildInBoundsGEP(opt_handle, &indices, indices.len, "");
8362 const field_ptr = self.builder.buildStructGEP(opt_handle, 1, "");
83478363 break :b self.builder.buildLoad(field_ptr, "");
83488364 }
8349
83508365 break :b self.builder.buildExtractValue(opt_handle, 1, "");
83518366 };
83528367 comptime assert(optional_layout_version == 3);
......@@ -8365,12 +8380,7 @@ pub const FuncGen = struct {
83658380
83668381 if (isByRef(opt_ty)) {
83678382 // We have a pointer and we need to return a pointer to the first field.
8368 const index_type = fg.context.intType(32);
8369 const indices: [2]*const llvm.Value = .{
8370 index_type.constNull(), // dereference the pointer
8371 index_type.constNull(), // first field is the payload
8372 };
8373 const payload_ptr = fg.builder.buildInBoundsGEP(opt_handle, &indices, indices.len, "");
8383 const payload_ptr = fg.builder.buildStructGEP(opt_handle, 0, "");
83748384
83758385 if (isByRef(payload_ty)) {
83768386 return payload_ptr;
......@@ -8401,22 +8411,13 @@ pub const FuncGen = struct {
84018411 const payload_alignment = optional_ty.abiAlignment(target);
84028412 alloca_inst.setAlignment(payload_alignment);
84038413
8404 const index_type = self.context.intType(32);
84058414 {
8406 const indices: [2]*const llvm.Value = .{
8407 index_type.constNull(), // dereference the pointer
8408 index_type.constNull(), // first field is the payload
8409 };
8410 const field_ptr = self.builder.buildInBoundsGEP(alloca_inst, &indices, indices.len, "");
8415 const field_ptr = self.builder.buildStructGEP(alloca_inst, 0, "");
84118416 const store_inst = self.builder.buildStore(payload, field_ptr);
84128417 store_inst.setAlignment(payload_alignment);
84138418 }
84148419 {
8415 const indices: [2]*const llvm.Value = .{
8416 index_type.constNull(), // dereference the pointer
8417 index_type.constInt(1, .False), // second field is the non-null bit
8418 };
8419 const field_ptr = self.builder.buildInBoundsGEP(alloca_inst, &indices, indices.len, "");
8420 const field_ptr = self.builder.buildStructGEP(alloca_inst, 1, "");
84208421 const store_inst = self.builder.buildStore(non_null_field, field_ptr);
84218422 store_inst.setAlignment(1);
84228423 }
......@@ -9337,7 +9338,7 @@ fn ccAbiPromoteInt(
93379338fn isByRef(ty: Type) bool {
93389339 // For tuples and structs, if there are more than this many non-void
93399340 // fields, then we make it byref, otherwise byval.
9340 const max_fields_byval = 2;
9341 const max_fields_byval = 0;
93419342
93429343 switch (ty.zigTypeTag()) {
93439344 .Type,