On 22/07/18 19:50, Jason Ekstrand wrote:
On Tue, Jul 10, 2018 at 11:49 PM Timothy Arceri <tarc...@itsqueeze.com
<mailto:tarc...@itsqueeze.com>> wrote:
This adds support for unrolling the classic
do {
// ...
} while (false)
that is used to wrap multi-line macros. GLSL IR also wraps switch
statements in a loop like this.
shader-db results IVB:
total loops in shared programs: 2515 -> 2512 (-0.12%)
loops in affected programs: 33 -> 30 (-9.09%)
helped: 3
HURT: 0
---
src/compiler/nir/nir_opt_loop_unroll.c | 63 ++++++++++++++++++++++++++
1 file changed, 63 insertions(+)
diff --git a/src/compiler/nir/nir_opt_loop_unroll.c
b/src/compiler/nir/nir_opt_loop_unroll.c
index 38901470f96..f715fc8ebda 100644
--- a/src/compiler/nir/nir_opt_loop_unroll.c
+++ b/src/compiler/nir/nir_opt_loop_unroll.c
@@ -516,6 +516,69 @@ process_loops(nir_shader *sh, nir_cf_node
*cf_node, bool *has_nested_loop)
*/
if (!progress) {
+ /* Check for the the classic
+ *
+ * do {
+ * // ...
+ * } while (false)
+ *
+ * that is used to wrap multi-line macros. GLSL IR also wraps
switch
+ * statements in a loop like this.
+ */
+ if (loop->info->limiting_terminator == NULL &&
+ list_empty(&loop->info->loop_terminator_list) &&
+ !loop->info->complex_loop) {
+
Mind putting all the code below in a "wrapper_unroll" or
"trivial_unroll" helper?
+ nir_block *blk_after_loop =
+
nir_cursor_current_block(nir_after_cf_node(&loop->cf_node));
+
+ /* There may still be some single src phis following the
loop that
+ * have not yet been cleaned up by another pass. Tidy
those up before
+ * unrolling the loop.
+ */
+ nir_foreach_instr_safe(instr, blk_after_loop) {
+ if (instr->type != nir_instr_type_phi)
+ break;
+
+ nir_phi_instr *phi = nir_instr_as_phi(instr);
+ assert(exec_list_length(&phi->srcs) == 1);
+
+ nir_phi_src *phi_src =
+ exec_node_data(nir_phi_src,
+ exec_list_get_head(&phi->srcs),
+ node);
+
+ nir_ssa_def_rewrite_uses(&phi->dest.ssa, phi_src->src);
+ nir_instr_remove(instr);
+
+ progress = true;
+ }
+
+ nir_block *last_loop_blk = nir_loop_last_block(loop);
+ if (nir_block_ends_in_break(last_loop_blk)) {
This confuses me. Above, you assert that all phis have exactly one
source and here you have an if (nir_block_ends_in_break(last_block));
which one is it? Either our loop terminator check above guarantees that
we're in the "do { } while (true)" case where we can assume a single
exit at the end of the loop or it doesn't. Which one is it?
Actually ignore my previous reply this was added because there may still
be dead instructions following the break that are yet to be removed.
_______________________________________________
mesa-dev mailing list
mesa-dev@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/mesa-dev