static uint8_t
get_resolve_status_for_src(nir_src *src)
{
- nir_instr *src_instr;
if (src->is_ssa) {
- src_instr = src->ssa->parent_instr;
- } else {
- src_instr = src->reg.reg->parent_instr;
- }
-
- if (src_instr) {
+ nir_instr *src_instr = src->ssa->parent_instr;
uint8_t resolve_status = src_instr->pass_flags & BRW_NIR_BOOLEAN_MASK;
/* If the source instruction needs resolve, then from the perspective
static bool
src_mark_needs_resolve(nir_src *src, void *void_state)
{
- nir_instr *src_instr;
if (src->is_ssa) {
- src_instr = src->ssa->parent_instr;
- } else {
- src_instr = src->reg.reg->parent_instr;
- }
-
- if (src_instr) {
+ nir_instr *src_instr = src->ssa->parent_instr;
uint8_t resolve_status = src_instr->pass_flags & BRW_NIR_BOOLEAN_MASK;
/* If the source instruction is unresolved, then mark it as needing
}
static bool
-analyze_boolean_resolves_block(nir_block *block, void *void_state)
+analyze_boolean_resolves_block(nir_block *block)
{
- nir_foreach_instr(block, instr) {
+ nir_foreach_instr(instr, block) {
switch (instr->type) {
case nir_instr_type_alu: {
/* For ALU instructions, the resolve status is handled in a
uint8_t resolve_status;
nir_alu_instr *alu = nir_instr_as_alu(instr);
switch (alu->op) {
- case nir_op_flt:
- case nir_op_ilt:
- case nir_op_ult:
- case nir_op_fge:
- case nir_op_ige:
- case nir_op_uge:
- case nir_op_feq:
- case nir_op_ieq:
- case nir_op_fne:
- case nir_op_ine:
- case nir_op_f2b:
- case nir_op_i2b:
- /* This instruction will turn into a CMP when we actually emit
- * so the result will have to be resolved before it can be used.
- */
- resolve_status = BRW_NIR_BOOLEAN_UNRESOLVED;
-
- /* Even though the destination is allowed to be left unresolved,
- * the sources are treated as regular integers or floats so
- * they need to be resolved.
+ case nir_op_ball_fequal2:
+ case nir_op_ball_iequal2:
+ case nir_op_ball_fequal3:
+ case nir_op_ball_iequal3:
+ case nir_op_ball_fequal4:
+ case nir_op_ball_iequal4:
+ case nir_op_bany_fnequal2:
+ case nir_op_bany_inequal2:
+ case nir_op_bany_fnequal3:
+ case nir_op_bany_inequal3:
+ case nir_op_bany_fnequal4:
+ case nir_op_bany_inequal4:
+ /* These are only implemented by the vec4 backend and its
+ * implementation emits resolved booleans. At some point in the
+ * future, this may change and we'll have to remove some of the
+ * above cases.
*/
- nir_foreach_src(instr, src_mark_needs_resolve, NULL);
+ resolve_status = BRW_NIR_BOOLEAN_NO_RESOLVE;
break;
case nir_op_imov:
}
default:
- resolve_status = BRW_NIR_NON_BOOLEAN;
+ if (nir_alu_type_get_base_type(nir_op_infos[alu->op].output_type) == nir_type_bool) {
+ /* This instructions will turn into a CMP when we actually emit
+ * them so the result will have to be resolved before it can be
+ * used.
+ */
+ resolve_status = BRW_NIR_BOOLEAN_UNRESOLVED;
+
+ /* Even though the destination is allowed to be left
+ * unresolved, the sources are treated as regular integers or
+ * floats so they need to be resolved.
+ */
+ nir_foreach_src(instr, src_mark_needs_resolve, NULL);
+ } else {
+ resolve_status = BRW_NIR_NON_BOOLEAN;
+ }
}
- /* If the destination is SSA-like, go ahead allow unresolved booleans.
+ /* If the destination is SSA, go ahead allow unresolved booleans.
* If the destination register doesn't have a well-defined parent_instr
* we need to resolve immediately.
*/
- if (alu->dest.dest.reg.reg->parent_instr == NULL &&
+ if (!alu->dest.dest.is_ssa &&
resolve_status == BRW_NIR_BOOLEAN_UNRESOLVED) {
resolve_status = BRW_NIR_BOOLEAN_NEEDS_RESOLVE;
}
* have to worry about resolving them.
*/
instr->pass_flags &= ~BRW_NIR_BOOLEAN_MASK;
- if (load->value.u[0] == NIR_TRUE || load->value.u[0] == NIR_FALSE) {
+ if (load->value.u32[0] == NIR_TRUE || load->value.u32[0] == NIR_FALSE) {
instr->pass_flags |= BRW_NIR_BOOLEAN_NO_RESOLVE;
} else {
instr->pass_flags |= BRW_NIR_NON_BOOLEAN;
static void
analyze_boolean_resolves_impl(nir_function_impl *impl)
{
- nir_foreach_block(impl, analyze_boolean_resolves_block, NULL);
+ nir_foreach_block(block, impl) {
+ analyze_boolean_resolves_block(block);
+ }
}
void
brw_nir_analyze_boolean_resolves(nir_shader *shader)
{
- nir_foreach_overload(shader, overload)
- if (overload->impl)
- analyze_boolean_resolves_impl(overload->impl);
+ nir_foreach_function(function, shader) {
+ if (function->impl)
+ analyze_boolean_resolves_impl(function->impl);
+ }
}