mesa/program: Change the program parser's namespace.
[mesa.git] / src / glsl / loop_controls.cpp
index f2e1ecb904daf2cb3cff29f1ccc040cc018a78fe..79c820436fd6951a0643d9fa1189b83b59136b90 100644 (file)
@@ -21,7 +21,7 @@
  * DEALINGS IN THE SOFTWARE.
  */
 
-#include <climits>
+#include <limits.h>
 #include "main/compiler.h"
 #include "glsl_types.h"
 #include "loop_analysis.h"
@@ -85,7 +85,10 @@ int
 calculate_iterations(ir_rvalue *from, ir_rvalue *to, ir_rvalue *increment,
                     enum ir_expression_operation op)
 {
-   void *mem_ctx = talloc_init(__func__);
+   if (from == NULL || to == NULL || increment == NULL)
+      return -1;
+
+   void *mem_ctx = ralloc_context(NULL);
 
    ir_expression *const sub =
       new(mem_ctx) ir_expression(ir_binop_sub, from->type, to, from);
@@ -144,7 +147,7 @@ calculate_iterations(ir_rvalue *from, ir_rvalue *to, ir_rvalue *increment,
       }
    }
 
-   talloc_free(mem_ctx);
+   ralloc_free(mem_ctx);
    return (valid_loop) ? iter_value : -1;
 }
 
@@ -182,7 +185,14 @@ loop_control_visitor::visit_leave(ir_loop *ir)
     * i is a loop induction variable, c is a constant, and < is any relative
     * operator.
     */
-   int max_iterations = INT_MAX;
+   int max_iterations = ls->max_iterations;
+
+   if(ir->from && ir->to && ir->increment)
+      max_iterations = calculate_iterations(ir->from, ir->to, ir->increment, (ir_expression_operation)ir->cmp);
+
+   if(max_iterations < 0)
+      max_iterations = INT_MAX;
+
    foreach_list(node, &ls->terminators) {
       loop_terminator *t = (loop_terminator *) node;
       ir_if *if_stmt = t->ir;
@@ -204,18 +214,18 @@ loop_control_visitor::visit_leave(ir_loop *ir)
          * which.
          */
         ir_rvalue *counter = cond->operands[0]->as_dereference_variable();
-        ir_constant *limit = cond->operands[1]->constant_expression_value();
+        ir_constant *limit = cond->operands[1]->as_constant();
         enum ir_expression_operation cmp = cond->operation;
 
         if (limit == NULL) {
            counter = cond->operands[1]->as_dereference_variable();
-           limit = cond->operands[0]->constant_expression_value();
+           limit = cond->operands[0]->as_constant();
 
            switch (cmp) {
-           case ir_binop_less:    cmp = ir_binop_gequal;  break;
-           case ir_binop_greater: cmp = ir_binop_lequal;  break;
-           case ir_binop_lequal:  cmp = ir_binop_greater; break;
-           case ir_binop_gequal:  cmp = ir_binop_less;    break;
+           case ir_binop_less:    cmp = ir_binop_greater; break;
+           case ir_binop_greater: cmp = ir_binop_less;    break;
+           case ir_binop_lequal:  cmp = ir_binop_gequal;  break;
+           case ir_binop_gequal:  cmp = ir_binop_lequal;  break;
            default: assert(!"Should not get here.");
            }
         }
@@ -276,6 +286,8 @@ loop_control_visitor::visit_leave(ir_loop *ir)
     */
    if (max_iterations == 0)
       ir->remove();
+   else
+      ls->max_iterations = max_iterations;
 
    return visit_continue;
 }