nir/algebraic: Move relocations for variable conds to a table.
This helps concentrate the dirty pages from the relocations, reduces how many relocations there are, and reduces the size of each variable assuming variables mostly don't have conditions or the conditions are mostly reused). Reduces libvulkan_intel.so size by 49kb. Reviewed-by: Adam Jackson <ajax@redhat.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/13987>
This commit is contained in:
parent
8485a78977
commit
53f49b7066
|
@ -109,7 +109,7 @@ class Value(object):
|
||||||
elif isinstance(val, Expression):
|
elif isinstance(val, Expression):
|
||||||
return val
|
return val
|
||||||
elif isinstance(val, str):
|
elif isinstance(val, str):
|
||||||
return Variable(val, name_base, varset)
|
return Variable(val, name_base, varset, algebraic_pass)
|
||||||
elif isinstance(val, (bool, float, int)):
|
elif isinstance(val, (bool, float, int)):
|
||||||
return Constant(val, name_base)
|
return Constant(val, name_base)
|
||||||
|
|
||||||
|
@ -182,7 +182,7 @@ class Value(object):
|
||||||
${val.index}, /* ${val.var_name} */
|
${val.index}, /* ${val.var_name} */
|
||||||
${'true' if val.is_constant else 'false'},
|
${'true' if val.is_constant else 'false'},
|
||||||
${val.type() or 'nir_type_invalid' },
|
${val.type() or 'nir_type_invalid' },
|
||||||
${val.cond if val.cond else 'NULL'},
|
${val.cond_index},
|
||||||
${val.swizzle()},
|
${val.swizzle()},
|
||||||
% elif isinstance(val, Expression):
|
% elif isinstance(val, Expression):
|
||||||
${'true' if val.inexact else 'false'}, ${'true' if val.exact else 'false'},
|
${'true' if val.inexact else 'false'}, ${'true' if val.exact else 'false'},
|
||||||
|
@ -269,7 +269,7 @@ _var_name_re = re.compile(r"(?P<const>#)?(?P<name>\w+)"
|
||||||
r"$")
|
r"$")
|
||||||
|
|
||||||
class Variable(Value):
|
class Variable(Value):
|
||||||
def __init__(self, val, name, varset):
|
def __init__(self, val, name, varset, algebraic_pass):
|
||||||
Value.__init__(self, val, name, "variable")
|
Value.__init__(self, val, name, "variable")
|
||||||
|
|
||||||
m = _var_name_re.match(val)
|
m = _var_name_re.match(val)
|
||||||
|
@ -286,7 +286,7 @@ class Variable(Value):
|
||||||
assert self.var_name != 'False'
|
assert self.var_name != 'False'
|
||||||
|
|
||||||
self.is_constant = m.group('const') is not None
|
self.is_constant = m.group('const') is not None
|
||||||
self.cond = m.group('cond')
|
self.cond_index = get_cond_index(algebraic_pass.variable_cond, m.group('cond'))
|
||||||
self.required_type = m.group('type')
|
self.required_type = m.group('type')
|
||||||
self._bit_size = int(m.group('bits')) if m.group('bits') else None
|
self._bit_size = int(m.group('bits')) if m.group('bits') else None
|
||||||
self.swiz = m.group('swiz')
|
self.swiz = m.group('swiz')
|
||||||
|
@ -1064,6 +1064,14 @@ static const nir_search_expression_cond ${pass_name}_expression_cond[] = {
|
||||||
};
|
};
|
||||||
% endif
|
% endif
|
||||||
|
|
||||||
|
% if variable_cond:
|
||||||
|
static const nir_search_variable_cond ${pass_name}_variable_cond[] = {
|
||||||
|
% for cond in variable_cond:
|
||||||
|
${cond[0]},
|
||||||
|
% endfor
|
||||||
|
};
|
||||||
|
% endif
|
||||||
|
|
||||||
% for state_id, state_xforms in enumerate(automaton.state_patterns):
|
% for state_id, state_xforms in enumerate(automaton.state_patterns):
|
||||||
% if state_xforms: # avoid emitting a 0-length array for MSVC
|
% if state_xforms: # avoid emitting a 0-length array for MSVC
|
||||||
static const struct transform ${pass_name}_state${state_id}_xforms[] = {
|
static const struct transform ${pass_name}_state${state_id}_xforms[] = {
|
||||||
|
@ -1124,6 +1132,7 @@ static const nir_algebraic_table ${pass_name}_table = {
|
||||||
.pass_op_table = ${pass_name}_pass_op_table,
|
.pass_op_table = ${pass_name}_pass_op_table,
|
||||||
.values = ${pass_name}_values,
|
.values = ${pass_name}_values,
|
||||||
.expression_cond = ${ pass_name + "_expression_cond" if expression_cond else "NULL" },
|
.expression_cond = ${ pass_name + "_expression_cond" if expression_cond else "NULL" },
|
||||||
|
.variable_cond = ${ pass_name + "_variable_cond" if variable_cond else "NULL" },
|
||||||
};
|
};
|
||||||
|
|
||||||
bool
|
bool
|
||||||
|
@ -1159,6 +1168,7 @@ class AlgebraicPass(object):
|
||||||
self.opcode_xforms = defaultdict(lambda : [])
|
self.opcode_xforms = defaultdict(lambda : [])
|
||||||
self.pass_name = pass_name
|
self.pass_name = pass_name
|
||||||
self.expression_cond = {}
|
self.expression_cond = {}
|
||||||
|
self.variable_cond = {}
|
||||||
|
|
||||||
error = False
|
error = False
|
||||||
|
|
||||||
|
@ -1222,5 +1232,6 @@ class AlgebraicPass(object):
|
||||||
condition_list=condition_list,
|
condition_list=condition_list,
|
||||||
automaton=self.automaton,
|
automaton=self.automaton,
|
||||||
expression_cond = sorted(self.expression_cond.items(), key=lambda kv: kv[1]),
|
expression_cond = sorted(self.expression_cond.items(), key=lambda kv: kv[1]),
|
||||||
|
variable_cond = sorted(self.variable_cond.items(), key=lambda kv: kv[1]),
|
||||||
get_c_opcode=get_c_opcode,
|
get_c_opcode=get_c_opcode,
|
||||||
itertools=itertools)
|
itertools=itertools)
|
||||||
|
|
|
@ -315,8 +315,8 @@ match_value(const nir_algebraic_table *table,
|
||||||
instr->src[src].src.ssa->parent_instr->type != nir_instr_type_load_const)
|
instr->src[src].src.ssa->parent_instr->type != nir_instr_type_load_const)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (var->cond && !var->cond(state->range_ht, instr,
|
if (var->cond_index != -1 && !table->variable_cond[var->cond_index](state->range_ht, instr,
|
||||||
src, num_components, new_swizzle))
|
src, num_components, new_swizzle))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (var->type != nir_type_invalid &&
|
if (var->type != nir_type_invalid &&
|
||||||
|
|
|
@ -88,15 +88,14 @@ typedef struct {
|
||||||
*/
|
*/
|
||||||
nir_alu_type type;
|
nir_alu_type type;
|
||||||
|
|
||||||
/** Optional condition fxn ptr
|
/** Optional table->variable_cond[] fxn ptr index
|
||||||
*
|
*
|
||||||
* This is only allowed in search expressions, and allows additional
|
* This is only allowed in search expressions, and allows additional
|
||||||
* constraints to be placed on the match. Typically used for 'is_constant'
|
* constraints to be placed on the match. Typically used for 'is_constant'
|
||||||
* variables to require, for example, power-of-two in order for the search
|
* variables to require, for example, power-of-two in order for the search
|
||||||
* to match.
|
* to match.
|
||||||
*/
|
*/
|
||||||
bool (*cond)(struct hash_table *range_ht, const nir_alu_instr *instr,
|
int16_t cond_index;
|
||||||
unsigned src, unsigned num_components, const uint8_t *swizzle);
|
|
||||||
|
|
||||||
/** Swizzle (for replace only) */
|
/** Swizzle (for replace only) */
|
||||||
uint8_t swizzle[NIR_MAX_VEC_COMPONENTS];
|
uint8_t swizzle[NIR_MAX_VEC_COMPONENTS];
|
||||||
|
@ -190,6 +189,10 @@ typedef union {
|
||||||
} nir_search_value_union;
|
} nir_search_value_union;
|
||||||
|
|
||||||
typedef bool (*nir_search_expression_cond)(nir_alu_instr *instr);
|
typedef bool (*nir_search_expression_cond)(nir_alu_instr *instr);
|
||||||
|
typedef bool (*nir_search_variable_cond)(struct hash_table *range_ht,
|
||||||
|
const nir_alu_instr *instr,
|
||||||
|
unsigned src, unsigned num_components,
|
||||||
|
const uint8_t *swizzle);
|
||||||
|
|
||||||
/* Generated data table for an algebraic optimization pass. */
|
/* Generated data table for an algebraic optimization pass. */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -203,6 +206,12 @@ typedef struct {
|
||||||
* nir_search_expression->cond.
|
* nir_search_expression->cond.
|
||||||
*/
|
*/
|
||||||
const nir_search_expression_cond *expression_cond;
|
const nir_search_expression_cond *expression_cond;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Array of condition functions for variables, referenced by
|
||||||
|
* nir_search_variable->cond.
|
||||||
|
*/
|
||||||
|
const nir_search_variable_cond *variable_cond;
|
||||||
} nir_algebraic_table;
|
} nir_algebraic_table;
|
||||||
|
|
||||||
/* Note: these must match the start states created in
|
/* Note: these must match the start states created in
|
||||||
|
|
Loading…
Reference in New Issue