Skip to content

Commit a74b6ad

Browse files
committed
LLVM: lower all structs as byref=true
Same reasoning as previous commit.
1 parent 961b05f commit a74b6ad

File tree

1 file changed

+64
-62
lines changed

1 file changed

+64
-62
lines changed

src/codegen/llvm.zig

Lines changed: 64 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -5731,12 +5731,7 @@ pub const FuncGen = struct {
57315731
// The payload and the optional are the same value.
57325732
return operand;
57335733
}
5734-
const index_type = self.context.intType(32);
5735-
const indices: [2]*const llvm.Value = .{
5736-
index_type.constNull(), // dereference the pointer
5737-
index_type.constNull(), // first field is the payload
5738-
};
5739-
return self.builder.buildInBoundsGEP(operand, &indices, indices.len, "");
5734+
return self.builder.buildStructGEP(operand, 0, "");
57405735
}
57415736

57425737
fn airOptionalPayloadPtrSet(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
@@ -5760,24 +5755,17 @@ pub const FuncGen = struct {
57605755
// Setting to non-null will be done when the payload is set.
57615756
return operand;
57625757
}
5763-
const index_type = self.context.intType(32);
5764-
{
5765-
// First set the non-null bit.
5766-
const indices: [2]*const llvm.Value = .{
5767-
index_type.constNull(), // dereference the pointer
5768-
index_type.constInt(1, .False), // second field is the non-null bit
5769-
};
5770-
const non_null_ptr = self.builder.buildInBoundsGEP(operand, &indices, indices.len, "");
5771-
_ = self.builder.buildStore(non_null_bit, non_null_ptr);
5772-
}
5758+
5759+
// First set the non-null bit.
5760+
const non_null_ptr = self.builder.buildStructGEP(operand, 1, "");
5761+
// TODO set alignment on this store
5762+
_ = self.builder.buildStore(non_null_bit, non_null_ptr);
5763+
57735764
// Then return the payload pointer (only if it's used).
57745765
if (self.liveness.isUnused(inst))
57755766
return null;
5776-
const indices: [2]*const llvm.Value = .{
5777-
index_type.constNull(), // dereference the pointer
5778-
index_type.constNull(), // first field is the payload
5779-
};
5780-
return self.builder.buildInBoundsGEP(operand, &indices, indices.len, "");
5767+
5768+
return self.builder.buildStructGEP(operand, 0, "");
57815769
}
57825770

57835771
fn airOptionalPayload(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
@@ -5873,16 +5861,11 @@ pub const FuncGen = struct {
58735861
_ = self.builder.buildStore(non_error_val, operand);
58745862
return operand;
58755863
}
5876-
const index_type = self.context.intType(32);
58775864
const target = self.dg.module.getTarget();
58785865
{
58795866
const error_offset = errUnionErrorOffset(payload_ty, target);
58805867
// First set the non-error value.
5881-
const indices: [2]*const llvm.Value = .{
5882-
index_type.constNull(), // dereference the pointer
5883-
index_type.constInt(error_offset, .False),
5884-
};
5885-
const non_null_ptr = self.builder.buildInBoundsGEP(operand, &indices, indices.len, "");
5868+
const non_null_ptr = self.builder.buildStructGEP(operand, error_offset, "");
58865869
const store_inst = self.builder.buildStore(non_error_val, non_null_ptr);
58875870
store_inst.setAlignment(Type.anyerror.abiAlignment(target));
58885871
}
@@ -5891,11 +5874,7 @@ pub const FuncGen = struct {
58915874
return null;
58925875

58935876
const payload_offset = errUnionPayloadOffset(payload_ty, target);
5894-
const indices: [2]*const llvm.Value = .{
5895-
index_type.constNull(), // dereference the pointer
5896-
index_type.constInt(payload_offset, .False),
5897-
};
5898-
return self.builder.buildInBoundsGEP(operand, &indices, indices.len, "");
5877+
return self.builder.buildStructGEP(operand, payload_offset, "");
58995878
}
59005879

59015880
fn airErrReturnTrace(self: *FuncGen, _: Air.Inst.Index) !?*const llvm.Value {
@@ -6390,8 +6369,30 @@ pub const FuncGen = struct {
63906369
const overflow_bit = self.builder.buildExtractValue(result_struct, 1, "");
63916370

63926371
var ty_buf: Type.Payload.Pointer = undefined;
6393-
const partial = self.builder.buildInsertValue(llvm_dest_ty.getUndef(), result, llvmFieldIndex(dest_ty, 0, tg, &ty_buf).?, "");
6394-
return self.builder.buildInsertValue(partial, overflow_bit, llvmFieldIndex(dest_ty, 1, tg, &ty_buf).?, "");
6372+
const result_index = llvmFieldIndex(dest_ty, 0, tg, &ty_buf).?;
6373+
const overflow_index = llvmFieldIndex(dest_ty, 1, tg, &ty_buf).?;
6374+
6375+
if (isByRef(dest_ty)) {
6376+
const target = self.dg.module.getTarget();
6377+
const alloca_inst = self.buildAlloca(llvm_dest_ty);
6378+
const result_alignment = dest_ty.abiAlignment(target);
6379+
alloca_inst.setAlignment(result_alignment);
6380+
{
6381+
const field_ptr = self.builder.buildStructGEP(alloca_inst, result_index, "");
6382+
const store_inst = self.builder.buildStore(result, field_ptr);
6383+
store_inst.setAlignment(result_alignment);
6384+
}
6385+
{
6386+
const field_ptr = self.builder.buildStructGEP(alloca_inst, overflow_index, "");
6387+
const store_inst = self.builder.buildStore(overflow_bit, field_ptr);
6388+
store_inst.setAlignment(1);
6389+
}
6390+
6391+
return alloca_inst;
6392+
}
6393+
6394+
const partial = self.builder.buildInsertValue(llvm_dest_ty.getUndef(), result, result_index, "");
6395+
return self.builder.buildInsertValue(partial, overflow_bit, overflow_index, "");
63956396
}
63966397

63976398
fn buildElementwiseCall(
@@ -6720,8 +6721,30 @@ pub const FuncGen = struct {
67206721
const overflow_bit = self.builder.buildICmp(.NE, lhs, reconstructed, "");
67216722

67226723
var ty_buf: Type.Payload.Pointer = undefined;
6723-
const partial = self.builder.buildInsertValue(llvm_dest_ty.getUndef(), result, llvmFieldIndex(dest_ty, 0, tg, &ty_buf).?, "");
6724-
return self.builder.buildInsertValue(partial, overflow_bit, llvmFieldIndex(dest_ty, 1, tg, &ty_buf).?, "");
6724+
const result_index = llvmFieldIndex(dest_ty, 0, tg, &ty_buf).?;
6725+
const overflow_index = llvmFieldIndex(dest_ty, 1, tg, &ty_buf).?;
6726+
6727+
if (isByRef(dest_ty)) {
6728+
const target = self.dg.module.getTarget();
6729+
const alloca_inst = self.buildAlloca(llvm_dest_ty);
6730+
const result_alignment = dest_ty.abiAlignment(target);
6731+
alloca_inst.setAlignment(result_alignment);
6732+
{
6733+
const field_ptr = self.builder.buildStructGEP(alloca_inst, result_index, "");
6734+
const store_inst = self.builder.buildStore(result, field_ptr);
6735+
store_inst.setAlignment(result_alignment);
6736+
}
6737+
{
6738+
const field_ptr = self.builder.buildStructGEP(alloca_inst, overflow_index, "");
6739+
const store_inst = self.builder.buildStore(overflow_bit, field_ptr);
6740+
store_inst.setAlignment(1);
6741+
}
6742+
6743+
return alloca_inst;
6744+
}
6745+
6746+
const partial = self.builder.buildInsertValue(llvm_dest_ty.getUndef(), result, result_index, "");
6747+
return self.builder.buildInsertValue(partial, overflow_bit, overflow_index, "");
67256748
}
67266749

67276750
fn airAnd(self: *FuncGen, inst: Air.Inst.Index) !?*const llvm.Value {
@@ -8332,14 +8355,7 @@ pub const FuncGen = struct {
83328355
/// Assumes the optional is not pointer-like and payload has bits.
83338356
fn optIsNonNull(self: *FuncGen, opt_handle: *const llvm.Value, is_by_ref: bool) *const llvm.Value {
83348357
if (is_by_ref) {
8335-
const index_type = self.context.intType(32);
8336-
8337-
const indices: [2]*const llvm.Value = .{
8338-
index_type.constNull(),
8339-
index_type.constInt(1, .False),
8340-
};
8341-
8342-
const field_ptr = self.builder.buildInBoundsGEP(opt_handle, &indices, indices.len, "");
8358+
const field_ptr = self.builder.buildStructGEP(opt_handle, 1, "");
83438359
return self.builder.buildLoad(field_ptr, "");
83448360
}
83458361

@@ -8357,12 +8373,7 @@ pub const FuncGen = struct {
83578373

83588374
if (isByRef(opt_ty)) {
83598375
// We have a pointer and we need to return a pointer to the first field.
8360-
const index_type = fg.context.intType(32);
8361-
const indices: [2]*const llvm.Value = .{
8362-
index_type.constNull(), // dereference the pointer
8363-
index_type.constNull(), // first field is the payload
8364-
};
8365-
const payload_ptr = fg.builder.buildInBoundsGEP(opt_handle, &indices, indices.len, "");
8376+
const payload_ptr = fg.builder.buildStructGEP(opt_handle, 0, "");
83668377

83678378
if (isByRef(payload_ty)) {
83688379
return payload_ptr;
@@ -8392,22 +8403,13 @@ pub const FuncGen = struct {
83928403
const payload_alignment = optional_ty.abiAlignment(target);
83938404
alloca_inst.setAlignment(payload_alignment);
83948405

8395-
const index_type = self.context.intType(32);
83968406
{
8397-
const indices: [2]*const llvm.Value = .{
8398-
index_type.constNull(), // dereference the pointer
8399-
index_type.constNull(), // first field is the payload
8400-
};
8401-
const field_ptr = self.builder.buildInBoundsGEP(alloca_inst, &indices, indices.len, "");
8407+
const field_ptr = self.builder.buildStructGEP(alloca_inst, 0, "");
84028408
const store_inst = self.builder.buildStore(payload, field_ptr);
84038409
store_inst.setAlignment(payload_alignment);
84048410
}
84058411
{
8406-
const indices: [2]*const llvm.Value = .{
8407-
index_type.constNull(), // dereference the pointer
8408-
index_type.constInt(1, .False), // second field is the non-null bit
8409-
};
8410-
const field_ptr = self.builder.buildInBoundsGEP(alloca_inst, &indices, indices.len, "");
8412+
const field_ptr = self.builder.buildStructGEP(alloca_inst, 1, "");
84118413
const store_inst = self.builder.buildStore(non_null_bit, field_ptr);
84128414
store_inst.setAlignment(1);
84138415
}
@@ -9328,7 +9330,7 @@ fn ccAbiPromoteInt(
93289330
fn isByRef(ty: Type) bool {
93299331
// For tuples and structs, if there are more than this many non-void
93309332
// fields, then we make it byref, otherwise byval.
9331-
const max_fields_byval = 2;
9333+
const max_fields_byval = 0;
93329334

93339335
switch (ty.zigTypeTag()) {
93349336
.Type,

0 commit comments

Comments
 (0)