Reimplement ir_if_simplicifation_visitor using ir_hierarchical_vistor
authorIan Romanick <ian.d.romanick@intel.com>
Fri, 14 May 2010 20:35:27 +0000 (13:35 -0700)
committerIan Romanick <ian.d.romanick@intel.com>
Mon, 17 May 2010 19:03:13 +0000 (12:03 -0700)
The output of all test cases was verified to be the same using diff.

ir_if_simplification.cpp

index 1e6fd8d..042d0b6 100644 (file)
 
 #define NULL 0
 #include "ir.h"
-#include "ir_visitor.h"
-#include "ir_function_inlining.h"
-#include "glsl_types.h"
 
-class ir_if_simplification_visitor : public ir_visitor {
+class ir_if_simplification_visitor : public ir_hierarchical_visitor {
 public:
    ir_if_simplification_visitor()
    {
-      /* empty */
+      this->made_progress = false;
    }
 
-   virtual ~ir_if_simplification_visitor()
-   {
-      /* empty */
-   }
+   ir_visitor_status visit_leave(ir_if *);
 
-   /**
-    * \name Visit methods
-    *
-    * As typical for the visitor pattern, there must be one \c visit method for
-    * each concrete subclass of \c ir_instruction.  Virtual base classes within
-    * the hierarchy should not have \c visit methods.
-    */
-   /*@{*/
-   virtual void visit(ir_variable *);
-   virtual void visit(ir_loop *);
-   virtual void visit(ir_loop_jump *);
-   virtual void visit(ir_function_signature *);
-   virtual void visit(ir_function *);
-   virtual void visit(ir_expression *);
-   virtual void visit(ir_swizzle *);
-   virtual void visit(ir_dereference *);
-   virtual void visit(ir_assignment *);
-   virtual void visit(ir_constant *);
-   virtual void visit(ir_call *);
-   virtual void visit(ir_return *);
-   virtual void visit(ir_if *);
-   /*@}*/
+   bool made_progress;
 };
 
 bool
 do_if_simplification(exec_list *instructions)
 {
-   bool progress = false;
+   ir_if_simplification_visitor v;
 
-   foreach_iter(exec_list_iterator, iter, *instructions) {
-      ir_instruction *ir = (ir_instruction *)iter.get();
-      ir_if *conditional = ir->as_if();
+   v.run(instructions);
+   return v.made_progress;
+}
 
-      if (conditional) {
-        ir_constant *condition_constant;
 
-        condition_constant =
-           conditional->condition->constant_expression_value();
-        if (condition_constant) {
-           /* Move the contents of the one branch of the conditional
-            * that matters out.
-            */
-           if (condition_constant->value.b[0]) {
-              foreach_iter(exec_list_iterator, then_iter,
-                           conditional->then_instructions) {
-                 ir_instruction *then_ir = (ir_instruction *)then_iter.get();
-                 ir->insert_before(then_ir);
-              }
-           } else {
-              foreach_iter(exec_list_iterator, else_iter,
-                           conditional->else_instructions) {
-                 ir_instruction *else_ir = (ir_instruction *)else_iter.get();
-                 ir->insert_before(else_ir);
-              }
-           }
-           ir->remove();
-           progress = true;
-           /* It would be nice to move the iterator back up to the point
-            * that we just spliced in contents.
-            */
-        } else {
-           ir_if_simplification_visitor v;
-           ir->accept(&v);
+ir_visitor_status
+ir_if_simplification_visitor::visit_leave(ir_if *ir)
+{
+   /* FINISHME: Ideally there would be a way to note that the condition results
+    * FINISHME: in a constant before processing both of the other subtrees.
+    * FINISHME: This can probably be done with some flags, but it would take
+    * FINISHME: some work to get right.
+    */
+   ir_constant *condition_constant = ir->condition->constant_expression_value();
+   if (condition_constant) {
+      /* Move the contents of the one branch of the conditional
+       * that matters out.
+       */
+      if (condition_constant->value.b[0]) {
+        foreach_iter(exec_list_iterator, then_iter, ir->then_instructions) {
+           ir_instruction *then_ir = (ir_instruction *)then_iter.get();
+           ir->insert_before(then_ir);
         }
       } else {
-        ir_if_simplification_visitor v;
-        ir->accept(&v);
+        foreach_iter(exec_list_iterator, else_iter, ir->else_instructions) {
+           ir_instruction *else_ir = (ir_instruction *)else_iter.get();
+           ir->insert_before(else_ir);
+        }
       }
+      ir->remove();
+      this->made_progress = true;
    }
 
-   return progress;
-}
-
-class variable_remap : public exec_node {
-public:
-   variable_remap(const ir_variable *old_var, ir_variable *new_var)
-      : old_var(old_var), new_var(new_var)
-   {
-      /* empty */
-   }
-   const ir_variable *old_var;
-   ir_variable *new_var;
-};
-
-void
-ir_if_simplification_visitor::visit(ir_variable *ir)
-{
-   (void) ir;
-}
-
-
-void
-ir_if_simplification_visitor::visit(ir_loop *ir)
-{
-   do_if_simplification(&ir->body_instructions);
-}
-
-void
-ir_if_simplification_visitor::visit(ir_loop_jump *ir)
-{
-   (void) ir;
-}
-
-
-void
-ir_if_simplification_visitor::visit(ir_function_signature *ir)
-{
-   do_if_simplification(&ir->body);
-}
-
-
-void
-ir_if_simplification_visitor::visit(ir_function *ir)
-{
-   foreach_iter(exec_list_iterator, iter, *ir) {
-      ir_function_signature *const sig = (ir_function_signature *) iter.get();
-      sig->accept(this);
-   }
-}
-
-void
-ir_if_simplification_visitor::visit(ir_expression *ir)
-{
-   unsigned int operand;
-
-   for (operand = 0; operand < ir->get_num_operands(); operand++) {
-      ir->operands[operand]->accept(this);
-   }
-}
-
-
-void
-ir_if_simplification_visitor::visit(ir_swizzle *ir)
-{
-   ir->val->accept(this);
-}
-
-
-void
-ir_if_simplification_visitor::visit(ir_dereference *ir)
-{
-   if (ir->mode == ir_dereference::ir_reference_array) {
-      ir->selector.array_index->accept(this);
-   }
-   ir->var->accept(this);
-}
-
-void
-ir_if_simplification_visitor::visit(ir_assignment *ir)
-{
-   ir->rhs->accept(this);
-}
-
-
-void
-ir_if_simplification_visitor::visit(ir_constant *ir)
-{
-   (void) ir;
-}
-
-
-void
-ir_if_simplification_visitor::visit(ir_call *ir)
-{
-   (void) ir;
-}
-
-
-void
-ir_if_simplification_visitor::visit(ir_return *ir)
-{
-   (void) ir;
-}
-
-
-void
-ir_if_simplification_visitor::visit(ir_if *ir)
-{
-   ir->condition->accept(this);
-
-   do_if_simplification(&ir->then_instructions);
-   do_if_simplification(&ir->else_instructions);
+   return visit_continue;
 }