X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fglsl%2Floop_controls.cpp;h=79c820436fd6951a0643d9fa1189b83b59136b90;hb=f25d94084ce3225e803c07672c359a4e553b0e08;hp=2eddb91364883745f34ae40b5ae9703edb54270d;hpb=bfe3fbb38e0a3ae7c1efb74282628c2cc5abc3e0;p=mesa.git diff --git a/src/glsl/loop_controls.cpp b/src/glsl/loop_controls.cpp index 2eddb913648..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."); } } @@ -234,7 +244,7 @@ loop_control_visitor::visit_leave(ir_loop *ir) const int iterations = calculate_iterations(init, limit, lv->increment, cmp); - if (iterations > 0) { + if (iterations >= 0) { /* If the new iteration count is lower than the previously * believed iteration count, update the loop control values. */ @@ -253,6 +263,10 @@ loop_control_visitor::visit_leave(ir_loop *ir) * satisfied. */ if_stmt->remove(); + + assert(ls->num_loop_jumps > 0); + ls->num_loop_jumps--; + this->progress = true; } @@ -267,6 +281,14 @@ loop_control_visitor::visit_leave(ir_loop *ir) } } + /* If we have proven the one of the loop exit conditions is satisifed before + * running the loop once, remove the loop. + */ + if (max_iterations == 0) + ir->remove(); + else + ls->max_iterations = max_iterations; + return visit_continue; }