From ba0f203ae82673ad050355e94386c849de7eaa92 Mon Sep 17 00:00:00 2001 From: Jason Ekstrand Date: Sat, 13 Apr 2019 10:35:07 -0500 Subject: [PATCH] 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 --- 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 12d5da5..4779507 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[^@\(]+)(?:@(?P\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 -- 2.7.4