ir_hierarchical_visitor: Add generic callback functionality
[mesa.git] / ir_constant_folding.cpp
index eabdc240ad34a3b4dbae7c75a67e3b1e55f7d53b..342d027bbe8a970ed26cd68315856d1cdf5c2985 100644 (file)
  * Replace constant-valued expressions with references to constant values.
  */
 
-#define NULL 0
 #include "ir.h"
 #include "ir_visitor.h"
-#include "ir_constant_folding.h"
+#include "ir_optimization.h"
 #include "glsl_types.h"
 
 /**
  * Visitor class for replacing expressions with ir_constant values.
  */
 
-void
-ir_constant_folding_visitor::visit(ir_variable *ir)
-{
-   (void) ir;
-}
+class ir_constant_folding_visitor : public ir_visitor {
+public:
+   ir_constant_folding_visitor()
+   {
+      /* empty */
+   }
 
+   virtual ~ir_constant_folding_visitor()
+   {
+      /* empty */
+   }
+
+   /**
+    * \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_function_signature *);
+   virtual void visit(ir_function *);
+   virtual void visit(ir_expression *);
+   virtual void visit(ir_texture *);
+   virtual void visit(ir_swizzle *);
+   virtual void visit(ir_dereference_variable *);
+   virtual void visit(ir_dereference_array *);
+   virtual void visit(ir_dereference_record *);
+   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 *);
+   virtual void visit(ir_loop *);
+   virtual void visit(ir_loop_jump *);
+   /*@}*/
+};
 
 void
-ir_constant_folding_visitor::visit(ir_label *ir)
+ir_constant_folding_visitor::visit(ir_variable *ir)
 {
    (void) ir;
 }
@@ -53,14 +84,17 @@ ir_constant_folding_visitor::visit(ir_label *ir)
 void
 ir_constant_folding_visitor::visit(ir_function_signature *ir)
 {
-   (void) ir;
+   visit_exec_list(&ir->body, this);
 }
 
 
 void
 ir_constant_folding_visitor::visit(ir_function *ir)
 {
-   (void) ir;
+   foreach_iter(exec_list_iterator, iter, *ir) {
+      ir_function_signature *const sig = (ir_function_signature *) iter.get();
+      sig->accept(this);
+   }
 }
 
 void
@@ -80,6 +114,14 @@ ir_constant_folding_visitor::visit(ir_expression *ir)
 }
 
 
+void
+ir_constant_folding_visitor::visit(ir_texture *ir)
+{
+   // FINISHME: Do stuff with texture lookups
+   (void) ir;
+}
+
+
 void
 ir_constant_folding_visitor::visit(ir_swizzle *ir)
 {
@@ -88,16 +130,31 @@ ir_constant_folding_visitor::visit(ir_swizzle *ir)
 
 
 void
-ir_constant_folding_visitor::visit(ir_dereference *ir)
+ir_constant_folding_visitor::visit(ir_dereference_variable *ir)
 {
-   if (ir->mode == ir_dereference::ir_reference_array) {
-      ir_constant *const_val = ir->selector.array_index->constant_expression_value();
-      if (const_val)
-        ir->selector.array_index = const_val;
-      else
-        ir->selector.array_index->accept(this);
-   }
-   ir->var->accept(this);
+   (void) ir;
+}
+
+
+void
+ir_constant_folding_visitor::visit(ir_dereference_array *ir)
+{
+   ir_constant *const_val =
+      ir->array_index->constant_expression_value();
+
+   if (const_val)
+      ir->array_index = const_val;
+   else
+      ir->array_index->accept(this);
+
+   ir->array->accept(this);
+}
+
+
+void
+ir_constant_folding_visitor::visit(ir_dereference_record *ir)
+{
+   ir->record->accept(this);
 }
 
 
@@ -141,4 +198,32 @@ ir_constant_folding_visitor::visit(ir_if *ir)
       ir->condition = const_val;
    else
       ir->condition->accept(this);
+
+   visit_exec_list(&ir->then_instructions, this);
+   visit_exec_list(&ir->else_instructions, this);
+}
+
+
+void
+ir_constant_folding_visitor::visit(ir_loop *ir)
+{
+   (void) ir;
+}
+
+
+void
+ir_constant_folding_visitor::visit(ir_loop_jump *ir)
+{
+   (void) ir;
+}
+
+bool
+do_constant_folding(exec_list *instructions)
+{
+   ir_constant_folding_visitor constant_folding;
+
+   visit_exec_list(instructions, &constant_folding);
+
+   /* FINISHME: Return real progress. */
+   return false;
 }