nir: Add some generic helpers for writing lowering passes

Reviewed-by: Eric Anholt <eric@anholt.net>
This commit is contained in:
Jason Ekstrand
2019-07-11 13:00:42 -05:00
parent c74b98486a
commit 758fdce9fe
2 changed files with 192 additions and 0 deletions

View File

@@ -3277,6 +3277,51 @@ static inline bool should_print_nir(void) { return false; }
#define NIR_SKIP(name) should_skip_nir(#name)
/** An instruction filtering callback
*
* Returns true if the instruction should be processed and false otherwise.
*/
typedef bool (*nir_instr_filter_cb)(const nir_instr *, const void *);
/** A simple instruction lowering callback
*
* Many instruction lowering passes can be written as a simple function which
* takes an instruction as its input and returns a sequence of instructions
* that implement the consumed instruction. This function type represents
* such a lowering function. When called, a function with this prototype
* should either return NULL indicating that no lowering needs to be done or
* emit a sequence of instructions using the provided builder (whose cursor
* will already be placed after the instruction to be lowered) and return the
* resulting nir_ssa_def.
*/
typedef nir_ssa_def *(*nir_lower_instr_cb)(struct nir_builder *,
nir_instr *, void *);
/** Iterate over all the instructions in a nir_function_impl and lower them
* using the provided callbacks
*
* This function implements the guts of a standard lowering pass for you. It
* iterates over all of the instructions in a nir_function_impl and calls the
* filter callback on each one. If the filter callback returns true, it then
* calls the lowering call back on the instruction. (Splitting it this way
* allows us to avoid some save/restore work for instructions we know won't be
* lowered.) If the instruction is dead after the lowering is complete, it
* will be removed. If new instructions are added, the lowering callback will
* also be called on them in case multiple lowerings are required.
*
* The metadata for the nir_function_impl will also be updated. If any blocks
* are added (they cannot be removed), dominance and block indices will be
* invalidated.
*/
bool nir_function_impl_lower_instructions(nir_function_impl *impl,
nir_instr_filter_cb filter,
nir_lower_instr_cb lower,
void *cb_data);
bool nir_shader_lower_instructions(nir_shader *shader,
nir_instr_filter_cb filter,
nir_lower_instr_cb lower,
void *cb_data);
void nir_calc_dominance_impl(nir_function_impl *impl);
void nir_calc_dominance(nir_shader *shader);