[Mesa-dev] [RFC 2/5] nir/gcm: Loop over blocks in pin_instructions
Jason Ekstrand
jason at jlekstrand.net
Sat Jan 14 22:37:38 UTC 2017
Now that we have the new block iterators, we can simplify things a bit.
---
src/compiler/nir/nir_opt_gcm.c | 138 ++++++++++++++++++++---------------------
1 file changed, 68 insertions(+), 70 deletions(-)
diff --git a/src/compiler/nir/nir_opt_gcm.c b/src/compiler/nir/nir_opt_gcm.c
index 72ddc54..a07f2f1 100644
--- a/src/compiler/nir/nir_opt_gcm.c
+++ b/src/compiler/nir/nir_opt_gcm.c
@@ -112,89 +112,89 @@ gcm_build_block_info(struct exec_list *cf_list, struct gcm_state *state,
* After this is completed, all instructions' pass_flags fields will be set
* to either GCM_INSTR_PINNED or 0.
*/
-static bool
-gcm_pin_instructions_block(nir_block *block, struct gcm_state *state)
+static void
+gcm_pin_instructions(nir_function_impl *impl, struct gcm_state *state)
{
- nir_foreach_instr_safe(instr, block) {
- switch (instr->type) {
- case nir_instr_type_alu:
- switch (nir_instr_as_alu(instr)->op) {
- case nir_op_fddx:
- case nir_op_fddy:
- case nir_op_fddx_fine:
- case nir_op_fddy_fine:
- case nir_op_fddx_coarse:
- case nir_op_fddy_coarse:
- /* These can only go in uniform control flow; pin them for now */
- instr->pass_flags = GCM_INSTR_PINNED;
+ nir_foreach_block(block, impl) {
+ nir_foreach_instr_safe(instr, block) {
+ switch (instr->type) {
+ case nir_instr_type_alu:
+ switch (nir_instr_as_alu(instr)->op) {
+ case nir_op_fddx:
+ case nir_op_fddy:
+ case nir_op_fddx_fine:
+ case nir_op_fddy_fine:
+ case nir_op_fddx_coarse:
+ case nir_op_fddy_coarse:
+ /* These can only go in uniform control flow; pin them for now */
+ instr->pass_flags = GCM_INSTR_PINNED;
+ break;
+
+ default:
+ instr->pass_flags = 0;
+ break;
+ }
break;
- default:
+ case nir_instr_type_tex:
+ switch (nir_instr_as_tex(instr)->op) {
+ case nir_texop_tex:
+ case nir_texop_txb:
+ case nir_texop_lod:
+ /* These two take implicit derivatives so they need to be pinned */
+ instr->pass_flags = GCM_INSTR_PINNED;
+ break;
+
+ default:
+ instr->pass_flags = 0;
+ break;
+ }
+ break;
+
+ case nir_instr_type_load_const:
instr->pass_flags = 0;
break;
+
+ case nir_instr_type_intrinsic: {
+ const nir_intrinsic_info *info =
+ &nir_intrinsic_infos[nir_instr_as_intrinsic(instr)->intrinsic];
+
+ if ((info->flags & NIR_INTRINSIC_CAN_ELIMINATE) &&
+ (info->flags & NIR_INTRINSIC_CAN_REORDER)) {
+ instr->pass_flags = 0;
+ } else {
+ instr->pass_flags = GCM_INSTR_PINNED;
+ }
+ break;
}
- break;
- case nir_instr_type_tex:
- switch (nir_instr_as_tex(instr)->op) {
- case nir_texop_tex:
- case nir_texop_txb:
- case nir_texop_lod:
- /* These two take implicit derivatives so they need to be pinned */
+ case nir_instr_type_jump:
+ case nir_instr_type_ssa_undef:
+ case nir_instr_type_phi:
instr->pass_flags = GCM_INSTR_PINNED;
break;
default:
- instr->pass_flags = 0;
- break;
+ unreachable("Invalid instruction type in GCM");
}
- break;
-
- case nir_instr_type_load_const:
- instr->pass_flags = 0;
- break;
- case nir_instr_type_intrinsic: {
- const nir_intrinsic_info *info =
- &nir_intrinsic_infos[nir_instr_as_intrinsic(instr)->intrinsic];
-
- if ((info->flags & NIR_INTRINSIC_CAN_ELIMINATE) &&
- (info->flags & NIR_INTRINSIC_CAN_REORDER)) {
- instr->pass_flags = 0;
- } else {
- instr->pass_flags = GCM_INSTR_PINNED;
+ if (!(instr->pass_flags & GCM_INSTR_PINNED)) {
+ /* If this is an unpinned instruction, go ahead and pull it out of
+ * the program and put it on the instrs list. This has a couple
+ * of benifits. First, it makes the scheduling algorithm more
+ * efficient because we can avoid walking over basic blocks and
+ * pinned instructions. Second, it keeps us from causing linked
+ * list confusion when we're trying to put everything in its
+ * proper place at the end of the pass.
+ *
+ * Note that we don't use nir_instr_remove here because that also
+ * cleans up uses and defs and we want to keep that information.
+ */
+ exec_node_remove(&instr->node);
+ exec_list_push_tail(&state->instrs, &instr->node);
}
- break;
- }
-
- case nir_instr_type_jump:
- case nir_instr_type_ssa_undef:
- case nir_instr_type_phi:
- instr->pass_flags = GCM_INSTR_PINNED;
- break;
-
- default:
- unreachable("Invalid instruction type in GCM");
- }
-
- if (!(instr->pass_flags & GCM_INSTR_PINNED)) {
- /* If this is an unpinned instruction, go ahead and pull it out of
- * the program and put it on the instrs list. This has a couple
- * of benifits. First, it makes the scheduling algorithm more
- * efficient because we can avoid walking over basic blocks and
- * pinned instructions. Second, it keeps us from causing linked
- * list confusion when we're trying to put everything in its
- * proper place at the end of the pass.
- *
- * Note that we don't use nir_instr_remove here because that also
- * cleans up uses and defs and we want to keep that information.
- */
- exec_node_remove(&instr->node);
- exec_list_push_tail(&state->instrs, &instr->node);
}
}
-
- return true;
}
static void
@@ -475,9 +475,7 @@ opt_gcm_impl(nir_function_impl *impl, bool value_number)
gcm_build_block_info(&impl->body, &state, 0, 0);
- nir_foreach_block(block, impl) {
- gcm_pin_instructions_block(block, &state);
- }
+ gcm_pin_instructions(impl, &state);
bool progress = false;
if (value_number) {
--
2.5.0.400.gff86faf
More information about the mesa-dev
mailing list