X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fglsl%2Floop_controls.cpp;h=79c820436fd6951a0643d9fa1189b83b59136b90;hb=de917b4c4c4dfc949d5f8e3d9eb2dd48b63a3de5;hp=17a0d2db816e09e835c2eabbe5d965b3f67de36a;hpb=f061524f0737bf59dad6ab9bb2e0015df804e4b5;p=mesa.git diff --git a/src/glsl/loop_controls.cpp b/src/glsl/loop_controls.cpp index 17a0d2db816..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 = (ls->max_iterations < 0) ? INT_MAX : ls->max_iterations; + 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; @@ -212,10 +222,10 @@ loop_control_visitor::visit_leave(ir_loop *ir) 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."); } }