X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fglsl%2Floop_controls.cpp;h=79c820436fd6951a0643d9fa1189b83b59136b90;hb=f25d94084ce3225e803c07672c359a4e553b0e08;hp=f2e1ecb904daf2cb3cff29f1ccc040cc018a78fe;hpb=3bcfafcf0320ee5407716ff67062e80d162760d4;p=mesa.git diff --git a/src/glsl/loop_controls.cpp b/src/glsl/loop_controls.cpp index f2e1ecb904d..79c820436fd 100644 --- a/src/glsl/loop_controls.cpp +++ b/src/glsl/loop_controls.cpp @@ -21,7 +21,7 @@ * DEALINGS IN THE SOFTWARE. */ -#include +#include #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; }