[Mesa-dev] [PATCH 3/4] nir: take cross-thread operations into account into a few places
Connor Abbott
cwabbott0 at gmail.com
Mon Jun 5 19:22:56 UTC 2017
These optimizations happened to work with derivatives, but they won't
with upcoming shader_ballot and group_vote instructions.
Signed-off-by: Connor Abbott <cwabbott0 at gmail.com>
---
src/compiler/nir/nir_instr_set.c | 12 ++++++++++++
src/compiler/nir/nir_opt_peephole_select.c | 11 +++++++++++
2 files changed, 23 insertions(+)
diff --git a/src/compiler/nir/nir_instr_set.c b/src/compiler/nir/nir_instr_set.c
index 9cb9ed4..74309d6 100644
--- a/src/compiler/nir/nir_instr_set.c
+++ b/src/compiler/nir/nir_instr_set.c
@@ -178,6 +178,18 @@ hash_instr(const void *data)
const nir_instr *instr = data;
uint32_t hash = _mesa_fnv32_1a_offset_bias;
+ /*
+ * If an instruction is cross-thread but not convergent, hash its block. If
+ * an instruction is convergent, then we can always replace one invocation
+ * with another since every invocation is guaranteed convergent. But not so
+ * for non-convergent instructions, since different invocations may be
+ * called with different execution maskes and therefore have different
+ * results.
+ */
+ if (nir_instr_is_cross_thread(instr) && !nir_instr_is_convergent(instr)) {
+ HASH(hash, instr->block);
+ }
+
switch (instr->type) {
case nir_instr_type_alu:
hash = hash_alu(hash, nir_instr_as_alu(instr));
diff --git a/src/compiler/nir/nir_opt_peephole_select.c b/src/compiler/nir/nir_opt_peephole_select.c
index 4ca4f80..ce41781 100644
--- a/src/compiler/nir/nir_opt_peephole_select.c
+++ b/src/compiler/nir/nir_opt_peephole_select.c
@@ -61,6 +61,17 @@ static bool
block_check_for_allowed_instrs(nir_block *block, unsigned *count, bool alu_ok)
{
nir_foreach_instr(instr, block) {
+ if (nir_instr_is_cross_thread(instr) && !nir_instr_is_convergent(instr)) {
+ /* If the instruction is cross-thread, then we can't execute it
+ * conditionally when we would've executed it unconditionally before,
+ * except when the condition is uniform. If the instruction is
+ * convergent, though, we're already guaranteed that the entire
+ * region is convergent (including the condition) so we can go ahead.
+ *
+ * TODO: allow when the if-condition is uniform
+ */
+ return false;
+ }
switch (instr->type) {
case nir_instr_type_intrinsic: {
nir_intrinsic_instr *intrin = nir_instr_as_intrinsic(instr);
--
2.9.3
More information about the mesa-dev
mailing list