authorgravatar for topolarity@tapscott.meCody Tapscott <topolarity@tapscott.me> 2022-11-10 12:03:17-07:00
committergravatar for topolarity@tapscott.meCody Tapscott <topolarity@tapscott.me> 2022-11-10 12:22:40-07:00
loga2f4de1663f815ae8c202ba6a8c68b0658b7d23f
treee900f62b506072b35e8d4d106c7948ee6977879c
parent8f3880074fb76871d9a4f35d1f72d0304ac5b404

stage2 llvm: Elide more loads

Adds optimizations for by-ref types to: - .struct_field_val - .slice_elem_val - .ptr_elem_val I would have expected LLVM to be able to optimize away these temporaries since we don't leak pointers to them and they are fed straight from def to use, but empirically it does not. Resolves https://github.com/ziglang/zig/issues/12713 Resolves https://github.com/ziglang/zig/issues/12638

1 files changed, 24 insertions(+), 1 deletions(-)

src/codegen/llvm.zig+24-1
......@@ -5644,6 +5644,14 @@ pub const FuncGen = struct {
56445644 const base_ptr = self.builder.buildExtractValue(slice, 0, "");
56455645 const indices: [1]*llvm.Value = .{index};
56465646 const ptr = self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");
5647 if (isByRef(elem_ty)) {
5648 if (self.canElideLoad(body_tail))
5649 return ptr;
5650
5651 const target = self.dg.module.getTarget();
5652 return self.loadByRef(ptr, elem_ty, elem_ty.abiAlignment(target), false);
5653 }
5654
56475655 return self.load(ptr, slice_ty);
56485656 }
56495657
......@@ -5709,6 +5717,14 @@ pub const FuncGen = struct {
57095717 const indices: [1]*llvm.Value = .{rhs};
57105718 break :ptr self.builder.buildInBoundsGEP(llvm_elem_ty, base_ptr, &indices, indices.len, "");
57115719 };
5720 if (isByRef(elem_ty)) {
5721 if (self.canElideLoad(body_tail))
5722 return ptr;
5723
5724 const target = self.dg.module.getTarget();
5725 return self.loadByRef(ptr, elem_ty, elem_ty.abiAlignment(target), false);
5726 }
5727
57125728 return self.load(ptr, ptr_ty);
57135729 }
57145730
......@@ -5832,7 +5848,14 @@ pub const FuncGen = struct {
58325848 const struct_llvm_ty = try self.dg.lowerType(struct_ty);
58335849 const field_ptr = self.builder.buildStructGEP(struct_llvm_ty, struct_llvm_val, llvm_field_index, "");
58345850 const field_ptr_ty = Type.initPayload(&ptr_ty_buf.base);
5835 return self.load(field_ptr, field_ptr_ty);
5851 if (isByRef(field_ty)) {
5852 if (canElideLoad(self, body_tail))
5853 return field_ptr;
5854
5855 return self.loadByRef(field_ptr, field_ty, ptr_ty_buf.data.alignment(target), false);
5856 } else {
5857 return self.load(field_ptr, field_ptr_ty);
5858 }
58365859 },
58375860 .Union => {
58385861 const union_llvm_ty = try self.dg.lowerType(struct_ty);