Implement "step" builtin.
[mesa.git] / ir_function_inlining.cpp
index 5b1b3cb8b0b7fa13797636299fd82b12cbf71d78..09604c04df9e71f5ba0d42ccc3a9e909896d2421 100644 (file)
 #include "ir_expression_flattening.h"
 #include "glsl_types.h"
 
+class ir_function_inlining_visitor : public ir_visitor {
+public:
+   ir_function_inlining_visitor()
+   {
+      /* empty */
+   }
+
+   virtual ~ir_function_inlining_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_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 *);
+   /*@}*/
+};
+
 class variable_remap : public exec_node {
 public:
    variable_remap(const ir_variable *old_var, ir_variable *new_var)
@@ -205,8 +241,7 @@ ir_function_cloning_visitor::visit(ir_dereference *ir)
       this->result = new ir_dereference(var, index);
    } else {
       assert(ir->mode == ir_dereference::ir_reference_record);
-      /* FINISHME: inlining of structure references */
-      assert(0);
+      this->result = new ir_dereference(var, strdup(ir->selector.field));
    }
 }
 
@@ -265,8 +300,7 @@ ir_function_cloning_visitor::visit(ir_return *ir)
    rval = this->result->as_rvalue();
    assert(rval);
 
-   result = new ir_assignment(new ir_dereference(this->retval),
-                             ir->get_value(), NULL);
+   result = new ir_assignment(new ir_dereference(this->retval), rval, NULL);
 }
 
 
@@ -390,15 +424,15 @@ ir_call::generate_inline(ir_instruction *next_ir)
       next_ir->insert_before(v.result);
    }
 
-   /* Generate the declarations for the parameters to our inlined code,
-    * and set up the mapping of real function body variables to ours.
+   /* Copy back the value of any 'out' parameters from the function body
+    * variables to our own.
     */
    i = 0;
    param_iter = this->actual_parameters.iterator();
    for (i = 0; i < num_parameters; i++) {
       ir_instruction *const param = (ir_instruction *) param_iter.get();
 
-      /* Move the actual param into our param variable if it's an 'in' type. */
+      /* Move our param variable into the actual param if it's an 'out' type. */
       if (parameters[i]->mode == ir_var_out ||
          parameters[i]->mode == ir_var_inout) {
         ir_assignment *assign;