Mesa (main): nir/algebraic: Move all the individual transforms to a common table.
GitLab Mirror
gitlab-mirror at kemper.freedesktop.org
Tue Dec 7 07:49:39 UTC 2021
Module: Mesa
Branch: main
Commit: de33205f88eebc43676c9a7f603b70e8bc212e95
URL: http://cgit.freedesktop.org/mesa/mesa/commit/?id=de33205f88eebc43676c9a7f603b70e8bc212e95
Author: Emma Anholt <emma at anholt.net>
Date: Wed Dec 1 15:45:54 2021 -0800
nir/algebraic: Move all the individual transforms to a common table.
Cuts 28% of the remaining relocations in libvulkan_intel.so, shrinks
binary size by 290kb.
Reviewed-by: Adam Jackson <ajax at redhat.com>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13987>
---
src/compiler/nir/nir_algebraic.py | 56 ++++++++++++++++++---------------------
src/compiler/nir/nir_search.c | 5 ++--
src/compiler/nir/nir_search.h | 6 +++--
3 files changed, 33 insertions(+), 34 deletions(-)
diff --git a/src/compiler/nir/nir_algebraic.py b/src/compiler/nir/nir_algebraic.py
index 0f1f3e0612a..bfe00d6ed85 100644
--- a/src/compiler/nir/nir_algebraic.py
+++ b/src/compiler/nir/nir_algebraic.py
@@ -935,8 +935,10 @@ class TreeAutomaton(object):
# Bijection from state to index. q in the original algorithm is
# len(self.states)
self.states = self.IndexMap()
- # List of pattern matches for each state index.
- self.state_patterns = []
+ # Lists of pattern matches separated by None
+ self.state_patterns = [None]
+ # Offset in the ->transforms table for each state index
+ self.state_pattern_offsets = []
# Map from state index to filtered state index for each opcode.
self.filter = defaultdict(list)
# Bijections from filtered state to filtered state index for each
@@ -966,15 +968,21 @@ class TreeAutomaton(object):
def process_new_states():
while self.worklist_index < len(self.states):
state = self.states[self.worklist_index]
-
# Calculate pattern matches for this state. Each pattern is
# assigned to a unique item, so we don't have to worry about
# deduplicating them here. However, we do have to sort them so
# that they're visited at runtime in the order they're specified
# in the source.
patterns = list(sorted(p for item in state for p in item.patterns))
- assert len(self.state_patterns) == self.worklist_index
- self.state_patterns.append(patterns)
+
+ if patterns:
+ # Add our patterns to the global table.
+ self.state_pattern_offsets.append(len(self.state_patterns))
+ self.state_patterns.extend(patterns)
+ self.state_patterns.append(None)
+ else:
+ # Point to the initial sentinel in the global table.
+ self.state_pattern_offsets.append(0)
# calculate filter table for this state, and update filtered
# worklists.
@@ -1072,15 +1080,16 @@ static const nir_search_variable_cond ${pass_name}_variable_cond[] = {
};
% endif
-% for state_id, state_xforms in enumerate(automaton.state_patterns):
-% if state_xforms: # avoid emitting a 0-length array for MSVC
-static const struct transform ${pass_name}_state${state_id}_xforms[] = {
-% for i in state_xforms:
- { ${xforms[i].search.array_index}, ${xforms[i].replace.array_index}, ${xforms[i].condition_index} },
-% endfor
-};
+static const struct transform ${pass_name}_transforms[] = {
+% for i in automaton.state_patterns:
+% if i is not None:
+ { ${xforms[i].search.array_index}, ${xforms[i].replace.array_index}, ${xforms[i].condition_index} },
+% else:
+ { ~0, ~0, ~0 }, /* Sentinel */
+
% endif
% endfor
+};
static const struct per_op_table ${pass_name}_pass_op_table[nir_num_search_ops] = {
% for op in automaton.opcodes:
@@ -1110,29 +1119,16 @@ static const struct per_op_table ${pass_name}_pass_op_table[nir_num_search_ops]
% endfor
};
-const struct transform *${pass_name}_transforms[] = {
-% for i in range(len(automaton.state_patterns)):
- % if automaton.state_patterns[i]:
- ${pass_name}_state${i}_xforms,
- % else:
- NULL,
- % endif
-% endfor
-};
-
-const uint16_t ${pass_name}_transform_counts[] = {
-% for i in range(len(automaton.state_patterns)):
- % if automaton.state_patterns[i]:
- (uint16_t)ARRAY_SIZE(${pass_name}_state${i}_xforms),
- % else:
- 0,
- % endif
+/* Mapping from state index to offset in transforms (0 being no transforms) */
+static const uint16_t ${pass_name}_transform_offsets[] = {
+% for offset in automaton.state_pattern_offsets:
+ ${offset},
% endfor
};
static const nir_algebraic_table ${pass_name}_table = {
.transforms = ${pass_name}_transforms,
- .transform_counts = ${pass_name}_transform_counts,
+ .transform_offsets = ${pass_name}_transform_offsets,
.pass_op_table = ${pass_name}_pass_op_table,
.values = ${pass_name}_values,
.expression_cond = ${ pass_name + "_expression_cond" if expression_cond else "NULL" },
diff --git a/src/compiler/nir/nir_search.c b/src/compiler/nir/nir_search.c
index 9e13452008d..3246d13ec8a 100644
--- a/src/compiler/nir/nir_search.c
+++ b/src/compiler/nir/nir_search.c
@@ -884,8 +884,9 @@ nir_algebraic_instr(nir_builder *build, nir_instr *instr,
int xform_idx = *util_dynarray_element(states, uint16_t,
alu->dest.dest.ssa.index);
- for (uint16_t i = 0; i < table->transform_counts[xform_idx]; i++) {
- const struct transform *xform = &table->transforms[xform_idx][i];
+ for (const struct transform *xform = &table->transforms[table->transform_offsets[xform_idx]];
+ xform->condition_offset != ~0;
+ xform++) {
if (condition_flags[xform->condition_offset] &&
!(table->values[xform->search].expression.inexact && ignore_inexact) &&
nir_replace_instr(build, alu, range_ht, states, table,
diff --git a/src/compiler/nir/nir_search.h b/src/compiler/nir/nir_search.h
index 67fe7d0a516..2a7e9a2f0fe 100644
--- a/src/compiler/nir/nir_search.h
+++ b/src/compiler/nir/nir_search.h
@@ -197,8 +197,10 @@ typedef bool (*nir_search_variable_cond)(struct hash_table *range_ht,
/* Generated data table for an algebraic optimization pass. */
typedef struct {
- const struct transform **transforms;
- const uint16_t *transform_counts;
+ /** Array of all transforms in the pass. */
+ const struct transform *transforms;
+ /** Mapping from automaton state index to location in *transforms. */
+ const uint16_t *transform_offsets;
const struct per_op_table *pass_op_table;
const nir_search_value_union *values;
More information about the mesa-commit
mailing list