Mesa (master): nir/algebraic: Use a cache to avoid re-emitting structs

GitLab Mirror gitlab-mirror at kemper.freedesktop.org
Tue Apr 16 16:54:03 UTC 2019


Module: Mesa
Branch: master
Commit: ba0f203ae82673ad050355e94386c849de7eaa92
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=ba0f203ae82673ad050355e94386c849de7eaa92

Author: Jason Ekstrand <jason at jlekstrand.net>
Date:   Sat Apr 13 10:35:07 2019 -0500

nir/algebraic: Use a cache to avoid re-emitting structs

This takes the stupid simplest and most reliable approach to reducing
redundancy that I could come up with:  Just use the struct declaration
as the cach key.  This cuts the size of the generated C file to about
half and takes about 50 KiB off the .data section.

size before (release build):

   text	   data	    bss	    dec	    hex	filename
5363833	 336880	  13584	5714297	 573179	_install/lib64/libvulkan_intel.so

size after (release build):

   text	   data	    bss	    dec	    hex	filename
5229017	 285264	  13584	5527865	 545939	_install/lib64/libvulkan_intel.so

Reviewed-by: Connor Abbott <cwabbott0 at gmail.com>

---

 src/compiler/nir/nir_algebraic.py | 53 ++++++++++++++++++++++++++-------------
 1 file changed, 36 insertions(+), 17 deletions(-)

diff --git a/src/compiler/nir/nir_algebraic.py b/src/compiler/nir/nir_algebraic.py
index 12d5da531d5..4779507fada 100644
--- a/src/compiler/nir/nir_algebraic.py
+++ b/src/compiler/nir/nir_algebraic.py
@@ -152,9 +152,17 @@ class Value(object):
    def c_type(self):
       return "nir_search_" + self.type_str
 
-   @property
-   def c_ptr(self):
-      return "&{0}.value".format(self.name)
+   def __c_name(self, cache):
+      if cache is not None and self.name in cache:
+         return cache[self.name]
+      else:
+         return self.name
+
+   def c_value_ptr(self, cache):
+      return "&{0}.value".format(self.__c_name(cache))
+
+   def c_ptr(self, cache):
+      return "&{0}".format(self.__c_name(cache))
 
    @property
    def c_bit_size(self):
@@ -171,8 +179,7 @@ class Value(object):
          # We represent these cases with a 0 bit-size.
          return 0
 
-   __template = mako.template.Template("""
-static const ${val.c_type} ${val.name} = {
+   __template = mako.template.Template("""{
    { ${val.type_enum}, ${val.c_bit_size} },
 % if isinstance(val, Constant):
    ${val.type()}, { ${val.hex()} /* ${val.value} */ },
@@ -185,16 +192,27 @@ static const ${val.c_type} ${val.name} = {
    ${'true' if val.inexact else 'false'},
    ${val.comm_expr_idx}, ${val.comm_exprs},
    ${val.c_opcode()},
-   { ${', '.join(src.c_ptr for src in val.sources)} },
+   { ${', '.join(src.c_value_ptr(cache) for src in val.sources)} },
    ${val.cond if val.cond else 'NULL'},
 % endif
 };""")
 
-   def render(self):
-      return self.__template.render(val=self,
-                                    Constant=Constant,
-                                    Variable=Variable,
-                                    Expression=Expression)
+   def render(self, cache):
+      struct_init = self.__template.render(val=self, cache=cache,
+                                           Constant=Constant,
+                                           Variable=Variable,
+                                           Expression=Expression)
+      if cache is not None and struct_init in cache:
+         # If it's in the cache, register a name remap in the cache and render
+         # only a comment saying it's been remapped
+         cache[self.name] = cache[struct_init]
+         return "/* {} -> {} in the cache */\n".format(self.name,
+                                                       cache[struct_init])
+      else:
+         if cache is not None:
+            cache[struct_init] = self.name
+         return "static const {} {} = {}\n".format(self.c_type, self.name,
+                                                   struct_init)
 
 _constant_re = re.compile(r"(?P<value>[^@\(]+)(?:@(?P<bits>\d+))?")
 
@@ -334,9 +352,9 @@ class Expression(Value):
       else:
          return 'nir_op_' + self.opcode
 
-   def render(self):
-      srcs = "\n".join(src.render() for src in self.sources)
-      return srcs + super(Expression, self).render()
+   def render(self, cache):
+      srcs = "\n".join(src.render(cache) for src in self.sources)
+      return srcs + super(Expression, self).render(cache)
 
 class BitSizeValidator(object):
    """A class for validating bit sizes of expressions.
@@ -691,15 +709,16 @@ struct transform {
 
 #endif
 
+<% cache = {} %>
 % for xform in xforms:
-   ${xform.search.render()}
-   ${xform.replace.render()}
+   ${xform.search.render(cache)}
+   ${xform.replace.render(cache)}
 % endfor
 
 % for (opcode, xform_list) in sorted(opcode_xforms.items()):
 static const struct transform ${pass_name}_${opcode}_xforms[] = {
 % for xform in xform_list:
-   { &${xform.search.name}, ${xform.replace.c_ptr}, ${xform.condition_index} },
+   { ${xform.search.c_ptr(cache)}, ${xform.replace.c_value_ptr(cache)}, ${xform.condition_index} },
 % endfor
 };
 % endfor




More information about the mesa-commit mailing list