Mesa (glsl2): glsl2: Refactor a bit of ir_if_return for the next changes.

Eric Anholt anholt at kemper.freedesktop.org
Thu Jul 29 23:18:11 UTC 2010


Module: Mesa
Branch: glsl2
Commit: 92a3768cef122c699b0121ab168def6eaa0faa7a
URL:    http://cgit.freedesktop.org/mesa/mesa/commit/?id=92a3768cef122c699b0121ab168def6eaa0faa7a

Author: Eric Anholt <eric at anholt.net>
Date:   Thu Jul 29 12:15:04 2010 -0700

glsl2: Refactor a bit of ir_if_return for the next changes.

---

 src/glsl/ir_if_return.cpp |   56 +++++++++++++++++++++++++++-----------------
 1 files changed, 34 insertions(+), 22 deletions(-)

diff --git a/src/glsl/ir_if_return.cpp b/src/glsl/ir_if_return.cpp
index bfb52e7..8b8ff85 100644
--- a/src/glsl/ir_if_return.cpp
+++ b/src/glsl/ir_if_return.cpp
@@ -54,11 +54,39 @@ do_if_return(exec_list *instructions)
 {
    ir_if_return_visitor v;
 
-   visit_list_elements(&v, instructions);
+   do {
+      v.progress = false;
+      visit_list_elements(&v, instructions);
+   } while (v.progress);
 
    return v.progress;
 }
 
+/**
+ * Removes any instructions after a (unconditional) return, since they will
+ * never be executed.
+ */
+static void
+truncate_after_instruction(ir_instruction *ir)
+{
+   while (!ir->get_next()->is_tail_sentinel())
+      ((ir_instruction *)ir->get_next())->remove();
+}
+
+/**
+ * Returns an ir_instruction of the first ir_return in the exec_list, or NULL.
+ */
+static ir_return *
+find_return_in_block(exec_list *instructions)
+{
+   foreach_iter(exec_list_iterator, iter, *instructions) {
+      ir_instruction *ir = (ir_instruction *)iter.get();
+      if (ir->ir_type == ir_type_return)
+	 return (ir_return *)ir;
+   }
+
+   return NULL;
+}
 
 ir_visitor_status
 ir_if_return_visitor::visit_enter(ir_if *ir)
@@ -66,32 +94,16 @@ ir_if_return_visitor::visit_enter(ir_if *ir)
    ir_return *then_return = NULL;
    ir_return *else_return = NULL;
 
-   /* Try to find a return statement on both sides. */
-   foreach_iter(exec_list_iterator, then_iter, ir->then_instructions) {
-      ir_instruction *then_ir = (ir_instruction *)then_iter.get();
-      then_return = then_ir->as_return();
-      if (then_return)
-	 break;
-   }
-   if (!then_return)
-      return visit_continue;
-
-   foreach_iter(exec_list_iterator, else_iter, ir->else_instructions) {
-      ir_instruction *else_ir = (ir_instruction *)else_iter.get();
-      else_return = else_ir->as_return();
-      if (else_return)
-	 break;
-   }
-   if (!else_return)
+   then_return = find_return_in_block(&ir->then_instructions);
+   else_return = find_return_in_block(&ir->else_instructions);
+   if (!then_return || !else_return)
       return visit_continue;
 
    /* Trim off any trailing instructions after the return statements
     * on both sides.
     */
-   while (then_return->get_next()->get_next())
-      ((ir_instruction *)then_return->get_next())->remove();
-   while (else_return->get_next()->get_next())
-      ((ir_instruction *)else_return->get_next())->remove();
+   truncate_after_instruction(then_return);
+   truncate_after_instruction(else_return);
 
    this->progress = true;
 




More information about the mesa-commit mailing list