}
static nir_ssa_def *
-lower_int64_alu_instr(nir_builder *b, nir_alu_instr *alu)
+lower_int64_alu_instr(nir_builder *b, nir_instr *instr, void *_state)
{
+ nir_alu_instr *alu = nir_instr_as_alu(instr);
+
nir_ssa_def *src[4];
for (unsigned i = 0; i < nir_op_infos[alu->op].num_inputs; i++)
src[i] = nir_ssa_for_alu_src(b, alu, i);
}
static bool
-lower_int64_impl(nir_function_impl *impl, nir_lower_int64_options options)
-{
- nir_builder b;
- nir_builder_init(&b, impl);
-
- bool progress = false;
- nir_foreach_block(block, impl) {
- nir_foreach_instr_safe(instr, block) {
- if (instr->type != nir_instr_type_alu)
- continue;
-
- nir_alu_instr *alu = nir_instr_as_alu(instr);
- switch (alu->op) {
- case nir_op_i2b1:
- case nir_op_i2i32:
- case nir_op_u2u32:
- assert(alu->src[0].src.is_ssa);
- if (alu->src[0].src.ssa->bit_size != 64)
- continue;
- break;
- case nir_op_bcsel:
- assert(alu->src[1].src.is_ssa);
- assert(alu->src[2].src.is_ssa);
- assert(alu->src[1].src.ssa->bit_size ==
- alu->src[2].src.ssa->bit_size);
- if (alu->src[1].src.ssa->bit_size != 64)
- continue;
- break;
- case nir_op_ieq:
- case nir_op_ine:
- case nir_op_ult:
- case nir_op_ilt:
- case nir_op_uge:
- case nir_op_ige:
- assert(alu->src[0].src.is_ssa);
- assert(alu->src[1].src.is_ssa);
- assert(alu->src[0].src.ssa->bit_size ==
- alu->src[1].src.ssa->bit_size);
- if (alu->src[0].src.ssa->bit_size != 64)
- continue;
- break;
- default:
- assert(alu->dest.dest.is_ssa);
- if (alu->dest.dest.ssa.bit_size != 64)
- continue;
- break;
- }
+should_lower_int64_alu_instr(const nir_instr *instr, const void *_options)
+{
+ const nir_lower_int64_options options =
+ *(const nir_lower_int64_options *)_options;
- if (!(options & nir_lower_int64_op_to_options_mask(alu->op)))
- continue;
+ if (instr->type != nir_instr_type_alu)
+ return false;
- b.cursor = nir_before_instr(instr);
+ const nir_alu_instr *alu = nir_instr_as_alu(instr);
- nir_ssa_def *lowered = lower_int64_alu_instr(&b, alu);
- nir_ssa_def_rewrite_uses(&alu->dest.dest.ssa,
- nir_src_for_ssa(lowered));
- nir_instr_remove(&alu->instr);
- progress = true;
- }
- }
-
- if (progress) {
- nir_metadata_preserve(impl, nir_metadata_none);
- } else {
-#ifndef NDEBUG
- impl->valid_metadata &= ~nir_metadata_not_properly_reset;
-#endif
+ switch (alu->op) {
+ case nir_op_i2b1:
+ case nir_op_i2i32:
+ case nir_op_u2u32:
+ assert(alu->src[0].src.is_ssa);
+ if (alu->src[0].src.ssa->bit_size != 64)
+ return false;
+ break;
+ case nir_op_bcsel:
+ assert(alu->src[1].src.is_ssa);
+ assert(alu->src[2].src.is_ssa);
+ assert(alu->src[1].src.ssa->bit_size ==
+ alu->src[2].src.ssa->bit_size);
+ if (alu->src[1].src.ssa->bit_size != 64)
+ return false;
+ break;
+ case nir_op_ieq:
+ case nir_op_ine:
+ case nir_op_ult:
+ case nir_op_ilt:
+ case nir_op_uge:
+ case nir_op_ige:
+ assert(alu->src[0].src.is_ssa);
+ assert(alu->src[1].src.is_ssa);
+ assert(alu->src[0].src.ssa->bit_size ==
+ alu->src[1].src.ssa->bit_size);
+ if (alu->src[0].src.ssa->bit_size != 64)
+ return false;
+ break;
+ default:
+ assert(alu->dest.dest.is_ssa);
+ if (alu->dest.dest.ssa.bit_size != 64)
+ return false;
+ break;
}
- return progress;
+ return (options & nir_lower_int64_op_to_options_mask(alu->op)) != 0;
}
bool
nir_lower_int64(nir_shader *shader, nir_lower_int64_options options)
{
- bool progress = false;
-
- nir_foreach_function(function, shader) {
- if (function->impl)
- progress |= lower_int64_impl(function->impl, options);
- }
-
- return progress;
+ return nir_shader_lower_instructions(shader,
+ should_lower_int64_alu_instr,
+ lower_int64_alu_instr,
+ &options);
}