mirror of
https://gitlab.freedesktop.org/mesa/mesa.git
synced 2026-03-16 10:30:46 +01:00
nir: let nir_analyze_fp_range take a nir_def
This is midly worse for vector constants, but so much simpler. Reviewed-by: Rhys Perry <pendingchaos02@gmail.com> Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/39756>
This commit is contained in:
parent
474af815ff
commit
bca5aab2be
4 changed files with 53 additions and 94 deletions
|
|
@ -458,19 +458,8 @@ nir_gather_tcs_info(const nir_shader *nir, nir_tcs_info *info,
|
|||
continue;
|
||||
}
|
||||
|
||||
/* nir_analyze_fp_range only accepts an ALU src, so we have to
|
||||
* create a dummy ALU instruction. It's not inserted into
|
||||
* the shader.
|
||||
*/
|
||||
nir_alu_instr *dummy_alu =
|
||||
nir_alu_instr_create((nir_shader*)nir, nir_op_mov);
|
||||
dummy_alu->def.num_components = 1;
|
||||
dummy_alu->def.bit_size = scalar.def->bit_size;
|
||||
dummy_alu->src[0].src.ssa = scalar.def;
|
||||
dummy_alu->src[0].swizzle[0] = scalar.comp;
|
||||
|
||||
const struct fp_result_range r =
|
||||
nir_analyze_fp_range(range_ht, dummy_alu, 0);
|
||||
nir_analyze_fp_range(range_ht, scalar.def);
|
||||
|
||||
switch (r.range) {
|
||||
case unknown:
|
||||
|
|
@ -493,8 +482,6 @@ nir_gather_tcs_info(const nir_shader *nir, nir_tcs_info *info,
|
|||
tess_level_writes_gt_two |= BITFIELD_BIT(shift);
|
||||
break;
|
||||
}
|
||||
|
||||
nir_instr_free(&dummy_alu->instr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -151,24 +151,8 @@ nir_alu_src_type(const nir_alu_instr *instr, unsigned src)
|
|||
}
|
||||
|
||||
static struct fp_result_range
|
||||
analyze_constant(const struct nir_alu_instr *instr, unsigned src)
|
||||
analyze_fp_constant(const nir_load_const_instr *const load)
|
||||
{
|
||||
uint8_t swizzle[NIR_MAX_VEC_COMPONENTS] = { 0, 1, 2, 3,
|
||||
4, 5, 6, 7,
|
||||
8, 9, 10, 11,
|
||||
12, 13, 14, 15 };
|
||||
|
||||
/* If the source is an explicitly sized source, then we need to reset
|
||||
* both the number of components and the swizzle.
|
||||
*/
|
||||
const unsigned num_components = nir_ssa_alu_instr_src_components(instr, src);
|
||||
|
||||
for (unsigned i = 0; i < num_components; ++i)
|
||||
swizzle[i] = instr->src[src].swizzle[i];
|
||||
|
||||
const nir_load_const_instr *const load =
|
||||
nir_def_as_load_const(instr->src[src].src.ssa);
|
||||
|
||||
struct fp_result_range r = { unknown, false, false, false };
|
||||
|
||||
double min_value = NAN;
|
||||
|
|
@ -180,8 +164,8 @@ analyze_constant(const struct nir_alu_instr *instr, unsigned src)
|
|||
r.is_a_number = true;
|
||||
r.is_finite = true;
|
||||
|
||||
for (unsigned i = 0; i < num_components; ++i) {
|
||||
const double v = nir_const_value_as_float(load->value[swizzle[i]],
|
||||
for (unsigned i = 0; i < load->def.num_components; ++i) {
|
||||
const double v = nir_const_value_as_float(load->value[i],
|
||||
load->def.bit_size);
|
||||
|
||||
if (floor(v) != v)
|
||||
|
|
@ -402,28 +386,25 @@ union_ranges(enum fp_ranges a, enum fp_ranges b)
|
|||
|
||||
struct fp_query {
|
||||
struct analysis_query head;
|
||||
const nir_alu_instr *instr;
|
||||
unsigned src;
|
||||
const nir_def *def;
|
||||
};
|
||||
|
||||
static void
|
||||
push_fp_query(struct analysis_state *state, const nir_alu_instr *alu, unsigned src)
|
||||
push_fp_query(struct analysis_state *state, const nir_def *def)
|
||||
{
|
||||
struct fp_query *pushed_q = push_analysis_query(state, sizeof(struct fp_query));
|
||||
pushed_q->instr = alu;
|
||||
pushed_q->src = src;
|
||||
pushed_q->def = def;
|
||||
}
|
||||
|
||||
static uintptr_t
|
||||
get_fp_key(struct analysis_query *q)
|
||||
{
|
||||
struct fp_query *fp_q = (struct fp_query *)q;
|
||||
const nir_src *src = &fp_q->instr->src[fp_q->src].src;
|
||||
|
||||
if (!nir_def_is_alu(src->ssa))
|
||||
if (!nir_def_is_alu(fp_q->def))
|
||||
return 0;
|
||||
|
||||
return (uintptr_t)nir_def_as_alu(src->ssa);
|
||||
return (uintptr_t)fp_q->def;
|
||||
}
|
||||
|
||||
static inline bool
|
||||
|
|
@ -480,35 +461,27 @@ process_fp_query(struct analysis_state *state, struct analysis_query *aq, uint32
|
|||
STATIC_ASSERT(last_range + 1 == 7);
|
||||
|
||||
struct fp_query q = *(struct fp_query *)aq;
|
||||
const nir_alu_instr *instr = q.instr;
|
||||
unsigned src = q.src;
|
||||
const nir_def *def = q.def;
|
||||
|
||||
if (nir_src_is_const(instr->src[src].src)) {
|
||||
*result = pack_data(analyze_constant(instr, src));
|
||||
if (nir_def_is_const(def)) {
|
||||
*result = pack_data(analyze_fp_constant(nir_def_as_load_const(def)));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!nir_src_is_alu(instr->src[src].src)) {
|
||||
if (!nir_def_is_alu(def)) {
|
||||
*result = pack_data((struct fp_result_range){ unknown, false, false, false });
|
||||
return;
|
||||
}
|
||||
|
||||
const struct nir_alu_instr *const alu =
|
||||
nir_def_as_alu(instr->src[src].src.ssa);
|
||||
const nir_alu_instr *const alu = nir_def_as_alu(def);
|
||||
|
||||
if (!aq->pushed_queries) {
|
||||
switch (alu->op) {
|
||||
case nir_op_bcsel:
|
||||
push_fp_query(state, alu, 1);
|
||||
push_fp_query(state, alu, 2);
|
||||
push_fp_query(state, alu->src[1].src.ssa);
|
||||
push_fp_query(state, alu->src[2].src.ssa);
|
||||
return;
|
||||
case nir_op_mov:
|
||||
push_fp_query(state, alu, 0);
|
||||
return;
|
||||
case nir_op_vec2:
|
||||
push_fp_query(state, alu, 0);
|
||||
push_fp_query(state, alu, 1);
|
||||
return;
|
||||
case nir_op_fabs:
|
||||
case nir_op_fexp2:
|
||||
case nir_op_frcp:
|
||||
|
|
@ -536,7 +509,7 @@ process_fp_query(struct analysis_state *state, struct analysis_query *aq, uint32
|
|||
case nir_op_fdot4_replicated:
|
||||
case nir_op_fdot8_replicated:
|
||||
case nir_op_fdot16_replicated:
|
||||
push_fp_query(state, alu, 0);
|
||||
push_fp_query(state, alu->src[0].src.ssa);
|
||||
return;
|
||||
case nir_op_fadd:
|
||||
case nir_op_fmax:
|
||||
|
|
@ -544,15 +517,16 @@ process_fp_query(struct analysis_state *state, struct analysis_query *aq, uint32
|
|||
case nir_op_fmul:
|
||||
case nir_op_fmulz:
|
||||
case nir_op_fpow:
|
||||
push_fp_query(state, alu, 0);
|
||||
push_fp_query(state, alu, 1);
|
||||
case nir_op_vec2:
|
||||
push_fp_query(state, alu->src[0].src.ssa);
|
||||
push_fp_query(state, alu->src[1].src.ssa);
|
||||
return;
|
||||
case nir_op_ffma:
|
||||
case nir_op_ffmaz:
|
||||
case nir_op_flrp:
|
||||
push_fp_query(state, alu, 0);
|
||||
push_fp_query(state, alu, 1);
|
||||
push_fp_query(state, alu, 2);
|
||||
push_fp_query(state, alu->src[0].src.ssa);
|
||||
push_fp_query(state, alu->src[1].src.ssa);
|
||||
push_fp_query(state, alu->src[2].src.ssa);
|
||||
return;
|
||||
default:
|
||||
break;
|
||||
|
|
@ -1347,8 +1321,7 @@ process_fp_query(struct analysis_state *state, struct analysis_query *aq, uint32
|
|||
#undef _______
|
||||
|
||||
struct fp_result_range
|
||||
nir_analyze_fp_range(struct hash_table *range_ht,
|
||||
const nir_alu_instr *alu, unsigned src)
|
||||
nir_analyze_fp_range(struct hash_table *range_ht, const nir_def *def)
|
||||
{
|
||||
struct fp_query query_alloc[64];
|
||||
uint32_t result_alloc[64];
|
||||
|
|
@ -1361,7 +1334,7 @@ nir_analyze_fp_range(struct hash_table *range_ht,
|
|||
state.get_key = &get_fp_key;
|
||||
state.process_query = &process_fp_query;
|
||||
|
||||
push_fp_query(&state, alu, src);
|
||||
push_fp_query(&state, def);
|
||||
|
||||
return unpack_data(perform_analysis(&state));
|
||||
}
|
||||
|
|
|
|||
|
|
@ -55,8 +55,7 @@ extern "C" {
|
|||
#endif
|
||||
|
||||
struct fp_result_range
|
||||
nir_analyze_fp_range(struct hash_table *range_ht,
|
||||
const nir_alu_instr *instr, unsigned src);
|
||||
nir_analyze_fp_range(struct hash_table *range_ht, const nir_def *def);
|
||||
|
||||
uint64_t nir_def_bits_used(const nir_def *def);
|
||||
|
||||
|
|
|
|||
|
|
@ -895,7 +895,7 @@ static inline bool
|
|||
is_integral(const nir_search_state *state, const nir_alu_instr *instr, unsigned src,
|
||||
UNUSED unsigned num_components, UNUSED const uint8_t *swizzle)
|
||||
{
|
||||
const struct fp_result_range r = nir_analyze_fp_range(state->range_ht, instr, src);
|
||||
const struct fp_result_range r = nir_analyze_fp_range(state->range_ht, instr->src[src].src.ssa);
|
||||
|
||||
return r.is_integral;
|
||||
}
|
||||
|
|
@ -908,7 +908,7 @@ is_finite(UNUSED const nir_search_state *state, const nir_alu_instr *instr,
|
|||
unsigned src, UNUSED unsigned num_components,
|
||||
UNUSED const uint8_t *swizzle)
|
||||
{
|
||||
const struct fp_result_range v = nir_analyze_fp_range(state->range_ht, instr, src);
|
||||
const struct fp_result_range v = nir_analyze_fp_range(state->range_ht, instr->src[src].src.ssa);
|
||||
|
||||
return v.is_finite;
|
||||
}
|
||||
|
|
@ -918,29 +918,29 @@ is_finite_not_zero(UNUSED const nir_search_state *state, const nir_alu_instr *in
|
|||
unsigned src, UNUSED unsigned num_components,
|
||||
UNUSED const uint8_t *swizzle)
|
||||
{
|
||||
const struct fp_result_range v = nir_analyze_fp_range(state->range_ht, instr, src);
|
||||
const struct fp_result_range v = nir_analyze_fp_range(state->range_ht, instr->src[src].src.ssa);
|
||||
|
||||
return v.is_finite &&
|
||||
(v.range == lt_zero || v.range == gt_zero || v.range == ne_zero);
|
||||
}
|
||||
|
||||
#define RELATION(r) \
|
||||
static inline bool \
|
||||
is_##r(const nir_search_state *state, const nir_alu_instr *instr, \
|
||||
unsigned src, UNUSED unsigned num_components, \
|
||||
UNUSED const uint8_t *swizzle) \
|
||||
{ \
|
||||
const struct fp_result_range v = nir_analyze_fp_range(state->range_ht, instr, src); \
|
||||
return v.range == r; \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
is_a_number_##r(const nir_search_state *state, const nir_alu_instr *instr, \
|
||||
unsigned src, UNUSED unsigned num_components, \
|
||||
UNUSED const uint8_t *swizzle) \
|
||||
{ \
|
||||
const struct fp_result_range v = nir_analyze_fp_range(state->range_ht, instr, src); \
|
||||
return v.is_a_number && v.range == r; \
|
||||
#define RELATION(r) \
|
||||
static inline bool \
|
||||
is_##r(const nir_search_state *state, const nir_alu_instr *instr, \
|
||||
unsigned src, UNUSED unsigned num_components, \
|
||||
UNUSED const uint8_t *swizzle) \
|
||||
{ \
|
||||
const struct fp_result_range v = nir_analyze_fp_range(state->range_ht, instr->src[src].src.ssa); \
|
||||
return v.range == r; \
|
||||
} \
|
||||
\
|
||||
static inline bool \
|
||||
is_a_number_##r(const nir_search_state *state, const nir_alu_instr *instr, \
|
||||
unsigned src, UNUSED unsigned num_components, \
|
||||
UNUSED const uint8_t *swizzle) \
|
||||
{ \
|
||||
const struct fp_result_range v = nir_analyze_fp_range(state->range_ht, instr->src[src].src.ssa); \
|
||||
return v.is_a_number && v.range == r; \
|
||||
}
|
||||
|
||||
RELATION(lt_zero)
|
||||
|
|
@ -953,7 +953,7 @@ static inline bool
|
|||
is_not_negative(const nir_search_state *state, const nir_alu_instr *instr, unsigned src,
|
||||
UNUSED unsigned num_components, UNUSED const uint8_t *swizzle)
|
||||
{
|
||||
const struct fp_result_range v = nir_analyze_fp_range(state->range_ht, instr, src);
|
||||
const struct fp_result_range v = nir_analyze_fp_range(state->range_ht, instr->src[src].src.ssa);
|
||||
return v.range == ge_zero || v.range == gt_zero || v.range == eq_zero;
|
||||
}
|
||||
|
||||
|
|
@ -962,7 +962,7 @@ is_a_number_not_negative(const nir_search_state *state, const nir_alu_instr *ins
|
|||
unsigned src, UNUSED unsigned num_components,
|
||||
UNUSED const uint8_t *swizzle)
|
||||
{
|
||||
const struct fp_result_range v = nir_analyze_fp_range(state->range_ht, instr, src);
|
||||
const struct fp_result_range v = nir_analyze_fp_range(state->range_ht, instr->src[src].src.ssa);
|
||||
return v.is_a_number &&
|
||||
(v.range == ge_zero || v.range == gt_zero || v.range == eq_zero);
|
||||
}
|
||||
|
|
@ -971,7 +971,7 @@ static inline bool
|
|||
is_not_positive(const nir_search_state *state, const nir_alu_instr *instr, unsigned src,
|
||||
UNUSED unsigned num_components, UNUSED const uint8_t *swizzle)
|
||||
{
|
||||
const struct fp_result_range v = nir_analyze_fp_range(state->range_ht, instr, src);
|
||||
const struct fp_result_range v = nir_analyze_fp_range(state->range_ht, instr->src[src].src.ssa);
|
||||
return v.range == le_zero || v.range == lt_zero || v.range == eq_zero;
|
||||
}
|
||||
|
||||
|
|
@ -980,7 +980,7 @@ is_a_number_not_positive(const nir_search_state *state, const nir_alu_instr *ins
|
|||
unsigned src, UNUSED unsigned num_components,
|
||||
UNUSED const uint8_t *swizzle)
|
||||
{
|
||||
const struct fp_result_range v = nir_analyze_fp_range(state->range_ht, instr, src);
|
||||
const struct fp_result_range v = nir_analyze_fp_range(state->range_ht, instr->src[src].src.ssa);
|
||||
return v.is_a_number &&
|
||||
(v.range == le_zero || v.range == lt_zero || v.range == eq_zero);
|
||||
}
|
||||
|
|
@ -989,7 +989,7 @@ static inline bool
|
|||
is_not_zero(const nir_search_state *state, const nir_alu_instr *instr, unsigned src,
|
||||
UNUSED unsigned num_components, UNUSED const uint8_t *swizzle)
|
||||
{
|
||||
const struct fp_result_range v = nir_analyze_fp_range(state->range_ht, instr, src);
|
||||
const struct fp_result_range v = nir_analyze_fp_range(state->range_ht, instr->src[src].src.ssa);
|
||||
return v.range == lt_zero || v.range == gt_zero || v.range == ne_zero;
|
||||
}
|
||||
|
||||
|
|
@ -998,7 +998,7 @@ is_a_number_not_zero(const nir_search_state *state, const nir_alu_instr *instr,
|
|||
unsigned src, UNUSED unsigned num_components,
|
||||
UNUSED const uint8_t *swizzle)
|
||||
{
|
||||
const struct fp_result_range v = nir_analyze_fp_range(state->range_ht, instr, src);
|
||||
const struct fp_result_range v = nir_analyze_fp_range(state->range_ht, instr->src[src].src.ssa);
|
||||
return v.is_a_number &&
|
||||
(v.range == lt_zero || v.range == gt_zero || v.range == ne_zero);
|
||||
}
|
||||
|
|
@ -1007,7 +1007,7 @@ static inline bool
|
|||
is_a_number(const nir_search_state *state, const nir_alu_instr *instr, unsigned src,
|
||||
UNUSED unsigned num_components, UNUSED const uint8_t *swizzle)
|
||||
{
|
||||
const struct fp_result_range v = nir_analyze_fp_range(state->range_ht, instr, src);
|
||||
const struct fp_result_range v = nir_analyze_fp_range(state->range_ht, instr->src[src].src.ssa);
|
||||
return v.is_a_number;
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue