Mesa (main): nir/nir_lower_io: Optimize 32-bit inbounds access
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Thu Jun 9 17:07:31 UTC 2022
Module: Mesa
Branch: main
Commit: 08577bbb703abdb91e1ae71ff2119beea59cd568
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=08577bbb703abdb91e1ae71ff2119beea59cd568
Author: Konstantin Seurer <konstantin.seurer at gmail.com>
Date: Thu May 26 21:15:11 2022 +0200
nir/nir_lower_io: Optimize 32-bit inbounds access
Perform address calculation in 32 bits when
dealing with inbounds array derefs.
Closes: #6562
Signed-off-by: Konstantin Seurer <konstantin.seurer at gmail.com>
Reviewed-by: Jason Ekstrand <jason.ekstrand at collabora.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/16729>
---
src/compiler/nir/nir_lower_io.c | 28 ++++++++++++++++++----------
1 file changed, 18 insertions(+), 10 deletions(-)
diff --git a/src/compiler/nir/nir_lower_io.c b/src/compiler/nir/nir_lower_io.c
index 4acd8f84ac9..9cb400b5a6e 100644
--- a/src/compiler/nir/nir_lower_io.c
+++ b/src/compiler/nir/nir_lower_io.c
@@ -1820,22 +1820,30 @@ nir_explicit_io_address_from_deref(nir_builder *b, nir_deref_instr *deref,
case nir_deref_type_var:
return build_addr_for_var(b, deref->var, addr_format);
+ case nir_deref_type_ptr_as_array:
case nir_deref_type_array: {
unsigned stride = nir_deref_instr_array_stride(deref);
assert(stride > 0);
+ unsigned offset_bit_size = addr_get_offset_bit_size(base_addr, addr_format);
nir_ssa_def *index = nir_ssa_for_src(b, deref->arr.index, 1);
- index = nir_i2i(b, index, addr_get_offset_bit_size(base_addr, addr_format));
- return build_addr_iadd(b, base_addr, addr_format, deref->modes,
- nir_amul_imm(b, index, stride));
- }
+ nir_ssa_def *offset;
- case nir_deref_type_ptr_as_array: {
- nir_ssa_def *index = nir_ssa_for_src(b, deref->arr.index, 1);
- index = nir_i2i(b, index, addr_get_offset_bit_size(base_addr, addr_format));
- unsigned stride = nir_deref_instr_array_stride(deref);
- return build_addr_iadd(b, base_addr, addr_format, deref->modes,
- nir_amul_imm(b, index, stride));
+ /* If the access chain has been declared in-bounds, then we know it doesn't
+ * overflow the type. For nir_deref_type_array, this implies it cannot be
+ * negative. Also, since types in NIR have a maximum 32-bit size, we know the
+ * final result will fit in a 32-bit value so we can convert the index to
+ * 32-bit before multiplying and save ourselves from a 64-bit multiply.
+ */
+ if (deref->arr.in_bounds && deref->deref_type == nir_deref_type_array) {
+ index = nir_u2u32(b, index);
+ offset = nir_u2u(b, nir_amul_imm(b, index, stride), offset_bit_size);
+ } else {
+ index = nir_i2i(b, index, offset_bit_size);
+ offset = nir_amul_imm(b, index, stride);
+ }
+
+ return build_addr_iadd(b, base_addr, addr_format, deref->modes, offset);
}
case nir_deref_type_array_wildcard:
More information about the mesa-commit
mailing list