Skip to content

Commit a628e7f

Browse files
committed
LLVM: lower all structs as byref=true
Same reasoning as previous commit.
1 parent 0890725 commit a628e7f

File tree

1 file changed

+64
-63
lines changed

1 file changed

+64
-63
lines changed

src/codegen/llvm.zig

Lines changed: 64 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -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(
93379338
fn 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,

0 commit comments

Comments
 (0)