diff options
author | Eduardo Lima Mitev <[email protected]> | 2019-05-13 00:23:58 +0200 |
---|---|---|
committer | Eduardo Lima Mitev <[email protected]> | 2019-06-07 08:45:05 +0200 |
commit | 340277ad719526cd4c02583a08151473cc0a6904 (patch) | |
tree | 57f80b5b01f5ba8103e6124a5fccd509f1b2f137 | |
parent | 3addd7c8d9da9fd050e91738110b6e0a22b9023c (diff) |
ir3/nir: Add new NIR AlgebraicPass for lowering imul
Currently, ir3 backend compiler is lowering integer multiplication from:
dst = a * b
to:
dst = (al * bl) + (ah * bl << 16) + (al * bh << 16)
by emitting this code:
mull.u tmp0, a, b ; mul low, i.e. al * bl
madsh.m16 tmp1, a, b, tmp0 ; mul-add shift high mix, i.e. ah * bl << 16
madsh.m16 dst, b, a, tmp1 ; i.e. al * bh << 16
which at that point has very low chances of being optimized.
This patch adds a new nir_algebraic.AlgebraicPass to performs this
lowering during NIR algebraic optimization passes, giving it a better
chance for optimizing the resulting code.
Reviewed-by: Eric Anholt <[email protected]>
-rw-r--r-- | src/freedreno/ir3/ir3_nir.h | 1 | ||||
-rw-r--r-- | src/freedreno/ir3/ir3_nir_imul.py | 50 | ||||
-rw-r--r-- | src/freedreno/ir3/meson.build | 14 |
3 files changed, 64 insertions, 1 deletions
diff --git a/src/freedreno/ir3/ir3_nir.h b/src/freedreno/ir3/ir3_nir.h index 84c09b073f0..6314c097956 100644 --- a/src/freedreno/ir3/ir3_nir.h +++ b/src/freedreno/ir3/ir3_nir.h @@ -34,6 +34,7 @@ #include "ir3_shader.h" bool ir3_nir_apply_trig_workarounds(nir_shader *shader); +bool ir3_nir_lower_imul(nir_shader *shader); bool ir3_nir_lower_tg4_to_tex(nir_shader *shader); bool ir3_nir_lower_io_offsets(nir_shader *shader); bool ir3_nir_lower_load_barycentric_at_sample(nir_shader *shader); diff --git a/src/freedreno/ir3/ir3_nir_imul.py b/src/freedreno/ir3/ir3_nir_imul.py new file mode 100644 index 00000000000..f648cd11071 --- /dev/null +++ b/src/freedreno/ir3/ir3_nir_imul.py @@ -0,0 +1,50 @@ +# +# Copyright (C) 2019 Igalia S.L. +# +# Permission is hereby granted, free of charge, to any person obtaining a +# copy of this software and associated documentation files (the "Software"), +# to deal in the Software without restriction, including without limitation +# the rights to use, copy, modify, merge, publish, distribute, sublicense, +# and/or sell copies of the Software, and to permit persons to whom the +# Software is furnished to do so, subject to the following conditions: +# +# The above copyright notice and this permission notice (including the next +# paragraph) shall be included in all copies or substantial portions of the +# Software. +# +# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL +# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING +# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS +# IN THE SOFTWARE. + +from __future__ import print_function + +import argparse +import sys + +imul_lowering = [ + (('imul', 'a@32', 'b@32'), ('imadsh_mix16', 'b', 'a', ('imadsh_mix16', 'a', 'b', ('umul_low', 'a', 'b')))), +] + + +def main(): + parser = argparse.ArgumentParser() + parser.add_argument('-p', '--import-path', required=True) + args = parser.parse_args() + sys.path.insert(0, args.import_path) + run() + + +def run(): + import nir_algebraic # pylint: disable=import-error + + print('#include "ir3_nir.h"') + print(nir_algebraic.AlgebraicPass("ir3_nir_lower_imul", + imul_lowering).render()) + + +if __name__ == '__main__': + main() diff --git a/src/freedreno/ir3/meson.build b/src/freedreno/ir3/meson.build index bf4d41b5444..be03ffb88c3 100644 --- a/src/freedreno/ir3/meson.build +++ b/src/freedreno/ir3/meson.build @@ -30,6 +30,18 @@ ir3_nir_trig_c = custom_target( depend_files : nir_algebraic_py, ) +ir3_nir_imul_c = custom_target( + 'ir3_nir_imul.c', + input : 'ir3_nir_imul.py', + output : 'ir3_nir_imul.c', + command : [ + prog_python, '@INPUT@', + '-p', join_paths(meson.source_root(), 'src/compiler/nir/'), + ], + capture : true, + depend_files : nir_algebraic_py, +) + libfreedreno_ir3_files = files( 'disasm-a3xx.c', 'instr-a3xx.h', @@ -66,7 +78,7 @@ libfreedreno_ir3_files = files( libfreedreno_ir3 = static_library( 'freedreno_ir3', - [libfreedreno_ir3_files, ir3_nir_trig_c], + [libfreedreno_ir3_files, ir3_nir_trig_c, ir3_nir_imul_c], include_directories : [inc_freedreno, inc_common], c_args : [c_vis_args, no_override_init_args], cpp_args : [cpp_vis_args], |