authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-07-18 21:27:40-07:00
committergravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2022-07-19 11:26:19-07:00
log74fb65fb424a0fbb2eb00109fe4cee17aa2646c2
tree0ea0f6373ac13f9a6596503099a070c2f083809e
parentbab570a22540c2acb15c19e1d080a80d355407e3

LLVM: lower all error unions as byref=true

Same reasoning as previous commit.

1 files changed, 35 insertions(+), 2 deletions(-)

src/codegen/llvm.zig+35-2
...@@ -4740,12 +4740,14 @@ pub const FuncGen = struct {...@@ -4740,12 +4740,14 @@ pub const FuncGen = struct {
4740 const err_set_ty = try fg.dg.lowerType(Type.anyerror);4740 const err_set_ty = try fg.dg.lowerType(Type.anyerror);
4741 const zero = err_set_ty.constNull();4741 const zero = err_set_ty.constNull();
4742 if (!payload_has_bits) {4742 if (!payload_has_bits) {
4743 // TODO add alignment to this load
4743 const loaded = if (operand_is_ptr) fg.builder.buildLoad(err_union, "") else err_union;4744 const loaded = if (operand_is_ptr) fg.builder.buildLoad(err_union, "") else err_union;
4744 break :err fg.builder.buildICmp(.NE, loaded, zero, "");4745 break :err fg.builder.buildICmp(.NE, loaded, zero, "");
4745 }4746 }
4746 const err_field_index = errUnionErrorOffset(payload_ty, target);4747 const err_field_index = errUnionErrorOffset(payload_ty, target);
4747 if (operand_is_ptr or isByRef(err_union_ty)) {4748 if (operand_is_ptr or isByRef(err_union_ty)) {
4748 const err_field_ptr = fg.builder.buildStructGEP(err_union, err_field_index, "");4749 const err_field_ptr = fg.builder.buildStructGEP(err_union, err_field_index, "");
4750 // TODO add alignment to this load
4749 const loaded = fg.builder.buildLoad(err_field_ptr, "");4751 const loaded = fg.builder.buildLoad(err_field_ptr, "");
4750 break :err fg.builder.buildICmp(.NE, loaded, zero, "");4752 break :err fg.builder.buildICmp(.NE, loaded, zero, "");
4751 }4753 }
...@@ -4765,13 +4767,22 @@ pub const FuncGen = struct {...@@ -4765,13 +4767,22 @@ pub const FuncGen = struct {
4765 if (!payload_has_bits) {4767 if (!payload_has_bits) {
4766 if (!operand_is_ptr) return null;4768 if (!operand_is_ptr) return null;
47674769
4768 // TODO once we update to LLVM 14 this bitcast won't be necessary.4770 // TODO once we update to an LLVM version with opaque pointers
4771 // this bitcast won't be necessary.
4769 const res_ptr_ty = try fg.dg.lowerType(result_ty);4772 const res_ptr_ty = try fg.dg.lowerType(result_ty);
4770 return fg.builder.buildBitCast(err_union, res_ptr_ty, "");4773 return fg.builder.buildBitCast(err_union, res_ptr_ty, "");
4771 }4774 }
4772 const offset = errUnionPayloadOffset(payload_ty, target);4775 const offset = errUnionPayloadOffset(payload_ty, target);
4773 if (operand_is_ptr or isByRef(payload_ty)) {4776 if (operand_is_ptr or isByRef(payload_ty)) {
4774 return fg.builder.buildStructGEP(err_union, offset, "");4777 return fg.builder.buildStructGEP(err_union, offset, "");
4778 } else if (isByRef(err_union_ty)) {
4779 const payload_ptr = fg.builder.buildStructGEP(err_union, offset, "");
4780 if (isByRef(payload_ty)) {
4781 return payload_ptr;
4782 }
4783 const load_inst = fg.builder.buildLoad(payload_ptr, "");
4784 load_inst.setAlignment(payload_ty.abiAlignment(target));
4785 return load_inst;
4775 }4786 }
4776 return fg.builder.buildExtractValue(err_union, offset, "");4787 return fg.builder.buildExtractValue(err_union, offset, "");
4777 }4788 }
...@@ -5795,6 +5806,8 @@ pub const FuncGen = struct {...@@ -5795,6 +5806,8 @@ pub const FuncGen = struct {
57955806
5796 const ty_op = self.air.instructions.items(.data)[inst].ty_op;5807 const ty_op = self.air.instructions.items(.data)[inst].ty_op;
5797 const operand = try self.resolveInst(ty_op.operand);5808 const operand = try self.resolveInst(ty_op.operand);
5809 const operand_ty = self.air.typeOf(ty_op.operand);
5810 const err_union_ty = if (operand_is_ptr) operand_ty.childType() else operand_ty;
5798 const result_ty = self.air.typeOfIndex(inst);5811 const result_ty = self.air.typeOfIndex(inst);
5799 const payload_ty = if (operand_is_ptr) result_ty.childType() else result_ty;5812 const payload_ty = if (operand_is_ptr) result_ty.childType() else result_ty;
5800 const target = self.dg.module.getTarget();5813 const target = self.dg.module.getTarget();
...@@ -5809,6 +5822,14 @@ pub const FuncGen = struct {...@@ -5809,6 +5822,14 @@ pub const FuncGen = struct {
5809 const offset = errUnionPayloadOffset(payload_ty, target);5822 const offset = errUnionPayloadOffset(payload_ty, target);
5810 if (operand_is_ptr or isByRef(payload_ty)) {5823 if (operand_is_ptr or isByRef(payload_ty)) {
5811 return self.builder.buildStructGEP(operand, offset, "");5824 return self.builder.buildStructGEP(operand, offset, "");
5825 } else if (isByRef(err_union_ty)) {
5826 const payload_ptr = self.builder.buildStructGEP(operand, offset, "");
5827 if (isByRef(payload_ty)) {
5828 return payload_ptr;
5829 }
5830 const load_inst = self.builder.buildLoad(payload_ptr, "");
5831 load_inst.setAlignment(payload_ty.abiAlignment(target));
5832 return load_inst;
5812 }5833 }
5813 return self.builder.buildExtractValue(operand, offset, "");5834 return self.builder.buildExtractValue(operand, offset, "");
5814 }5835 }
...@@ -9338,6 +9359,8 @@ fn ccAbiPromoteInt(...@@ -9338,6 +9359,8 @@ fn ccAbiPromoteInt(
9338fn isByRef(ty: Type) bool {9359fn isByRef(ty: Type) bool {
9339 // For tuples and structs, if there are more than this many non-void9360 // For tuples and structs, if there are more than this many non-void
9340 // fields, then we make it byref, otherwise byval.9361 // fields, then we make it byref, otherwise byval.
9362 // TODO we actually want to set this to 2, however it is tripping an LLVM 14 regression:
9363 // https://github.com/llvm/llvm-project/issues/56585
9341 const max_fields_byval = 0;9364 const max_fields_byval = 0;
93429365
9343 switch (ty.zigTypeTag()) {9366 switch (ty.zigTypeTag()) {
...@@ -9392,7 +9415,17 @@ fn isByRef(ty: Type) bool {...@@ -9392,7 +9415,17 @@ fn isByRef(ty: Type) bool {
9392 return false;9415 return false;
9393 },9416 },
9394 .Union => return ty.hasRuntimeBits(),9417 .Union => return ty.hasRuntimeBits(),
9395 .ErrorUnion => return isByRef(ty.errorUnionPayload()),9418 .ErrorUnion => {
9419 const payload_ty = ty.errorUnionPayload();
9420 if (!payload_ty.hasRuntimeBitsIgnoreComptime()) {
9421 return false;
9422 }
9423 return true;
9424 // TODO we actually want this logic:
9425 // however it is tripping an LLVM 14 regression:
9426 // https://github.com/llvm/llvm-project/issues/56585
9427 //return isByRef(payload_ty);
9428 },
9396 .Optional => {9429 .Optional => {
9397 var buf: Type.Payload.ElemType = undefined;9430 var buf: Type.Payload.ElemType = undefined;
9398 const payload_ty = ty.optionalChild(&buf);9431 const payload_ty = ty.optionalChild(&buf);