diff --git a/src/intel/compiler/jay/jay_ir.h b/src/intel/compiler/jay/jay_ir.h index 1f54ffbce58..f52e9db7138 100644 --- a/src/intel/compiler/jay/jay_ir.h +++ b/src/intel/compiler/jay/jay_ir.h @@ -1379,6 +1379,13 @@ jay_block_add_successor(jay_block *block, jay_block *succ, enum jay_file file) } } +static inline bool +jay_cfg_has_edge(jay_block *pred, jay_block *succ, enum jay_file file) +{ + return jay_successors(pred, file)[0] == succ || + jay_successors(pred, file)[1] == succ; +} + static inline unsigned jay_source_last_use_bit(const jay_def *srcs, unsigned src_idx) { diff --git a/src/intel/compiler/jay/jay_liveness.c b/src/intel/compiler/jay/jay_liveness.c index 68b5f097e1f..ffffa573c4f 100644 --- a/src/intel/compiler/jay/jay_liveness.c +++ b/src/intel/compiler/jay/jay_liveness.c @@ -100,21 +100,27 @@ jay_compute_liveness(jay_function *f) /* Propagate block->live_in[] to the live_out[] of predecessors. Since * phis are split, they are handled naturally without special cases. + * + * The physical control flow graph is a subset of the logical control flow + * graph. So, edges that are in both can use the fast merge, and other + * edges are physical-only and need to merge only UGPRs. */ - for (enum jay_file file = GPR; file <= UGPR; ++file) { - jay_foreach_predecessor(block, p, file) { - bool progress = false; + jay_foreach_predecessor(block, p, UGPR) { + bool progress = false; + if (jay_cfg_has_edge(*p, block, GPR)) { + progress = u_sparse_bitset_merge(&(*p)->live_out, &block->live_in); + } else { U_SPARSE_BITSET_FOREACH_SET(&block->live_in, i) { - if ((file == UGPR) == BITSET_TEST(uniform, i)) { + if (BITSET_TEST(uniform, i)) { progress |= !u_sparse_bitset_test(&(*p)->live_out, i); u_sparse_bitset_set(&(*p)->live_out, i); } } + } - if (progress) { - jay_worklist_push_tail(&worklist, *p); - } + if (progress) { + jay_worklist_push_tail(&worklist, *p); } } }