glsl: Fix unroll of do{} while(false) like loops
[mesa.git] / src / compiler / glsl / loop_analysis.cpp
1 /*
2 * Copyright © 2010 Intel Corporation
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
14 *
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
22 */
23
24 #include "compiler/glsl_types.h"
25 #include "loop_analysis.h"
26 #include "ir_hierarchical_visitor.h"
27
28 static void try_add_loop_terminator(loop_variable_state *ls, ir_if *ir);
29
30 static bool all_expression_operands_are_loop_constant(ir_rvalue *,
31 hash_table *);
32
33 static ir_rvalue *get_basic_induction_increment(ir_assignment *, hash_table *);
34
35 /**
36 * Find an initializer of a variable outside a loop
37 *
38 * Works backwards from the loop to find the pre-loop value of the variable.
39 * This is used, for example, to find the initial value of loop induction
40 * variables.
41 *
42 * \param loop Loop where \c var is an induction variable
43 * \param var Variable whose initializer is to be found
44 *
45 * \return
46 * The \c ir_rvalue assigned to the variable outside the loop. May return
47 * \c NULL if no initializer can be found.
48 */
49 static ir_rvalue *
50 find_initial_value(ir_loop *loop, ir_variable *var)
51 {
52 for (exec_node *node = loop->prev; !node->is_head_sentinel();
53 node = node->prev) {
54 ir_instruction *ir = (ir_instruction *) node;
55
56 switch (ir->ir_type) {
57 case ir_type_call:
58 case ir_type_loop:
59 case ir_type_loop_jump:
60 case ir_type_return:
61 case ir_type_if:
62 return NULL;
63
64 case ir_type_function:
65 case ir_type_function_signature:
66 assert(!"Should not get here.");
67 return NULL;
68
69 case ir_type_assignment: {
70 ir_assignment *assign = ir->as_assignment();
71 ir_variable *assignee = assign->lhs->whole_variable_referenced();
72
73 if (assignee == var)
74 return (assign->condition != NULL) ? NULL : assign->rhs;
75
76 break;
77 }
78
79 default:
80 break;
81 }
82 }
83
84 return NULL;
85 }
86
87
88 static int
89 calculate_iterations(ir_rvalue *from, ir_rvalue *to, ir_rvalue *increment,
90 enum ir_expression_operation op, bool continue_from_then,
91 bool swap_compare_operands, bool inc_before_terminator)
92 {
93 if (from == NULL || to == NULL || increment == NULL)
94 return -1;
95
96 void *mem_ctx = ralloc_context(NULL);
97
98 ir_expression *const sub =
99 new(mem_ctx) ir_expression(ir_binop_sub, from->type, to, from);
100
101 ir_expression *const div =
102 new(mem_ctx) ir_expression(ir_binop_div, sub->type, sub, increment);
103
104 ir_constant *iter = div->constant_expression_value(mem_ctx);
105 if (iter == NULL) {
106 ralloc_free(mem_ctx);
107 return -1;
108 }
109
110 if (!iter->type->is_integer_32()) {
111 const ir_expression_operation op = iter->type->is_double()
112 ? ir_unop_d2i : ir_unop_f2i;
113 ir_rvalue *cast =
114 new(mem_ctx) ir_expression(op, glsl_type::int_type, iter, NULL);
115
116 iter = cast->constant_expression_value(mem_ctx);
117 }
118
119 int iter_value = iter->get_int_component(0);
120
121 /* Code after this block works under assumption that iterator will be
122 * incremented or decremented until it hits the limit,
123 * however the loop condition can be false on the first iteration.
124 * Handle such loops first.
125 */
126 {
127 ir_rvalue *first_value = from;
128 if (inc_before_terminator) {
129 first_value =
130 new(mem_ctx) ir_expression(ir_binop_add, from->type, from, increment);
131 }
132
133 ir_expression *cmp = swap_compare_operands
134 ? new(mem_ctx) ir_expression(op, glsl_type::bool_type, to, first_value)
135 : new(mem_ctx) ir_expression(op, glsl_type::bool_type, first_value, to);
136 if (continue_from_then)
137 cmp = new(mem_ctx) ir_expression(ir_unop_logic_not, cmp);
138
139 ir_constant *const cmp_result = cmp->constant_expression_value(mem_ctx);
140 assert(cmp_result != NULL);
141 if (cmp_result->get_bool_component(0)) {
142 ralloc_free(mem_ctx);
143 return 0;
144 }
145 }
146
147 /* Make sure that the calculated number of iterations satisfies the exit
148 * condition. This is needed to catch off-by-one errors and some types of
149 * ill-formed loops. For example, we need to detect that the following
150 * loop does not have a maximum iteration count.
151 *
152 * for (float x = 0.0; x != 0.9; x += 0.2)
153 * ;
154 */
155 const int bias[] = { -1, 0, 1 };
156 bool valid_loop = false;
157
158 for (unsigned i = 0; i < ARRAY_SIZE(bias); i++) {
159 /* Increment may be of type int, uint or float. */
160 switch (increment->type->base_type) {
161 case GLSL_TYPE_INT:
162 iter = new(mem_ctx) ir_constant(iter_value + bias[i]);
163 break;
164 case GLSL_TYPE_UINT:
165 iter = new(mem_ctx) ir_constant(unsigned(iter_value + bias[i]));
166 break;
167 case GLSL_TYPE_FLOAT:
168 iter = new(mem_ctx) ir_constant(float(iter_value + bias[i]));
169 break;
170 case GLSL_TYPE_DOUBLE:
171 iter = new(mem_ctx) ir_constant(double(iter_value + bias[i]));
172 break;
173 default:
174 unreachable("Unsupported type for loop iterator.");
175 }
176
177 ir_expression *const mul =
178 new(mem_ctx) ir_expression(ir_binop_mul, increment->type, iter,
179 increment);
180
181 ir_expression *const add =
182 new(mem_ctx) ir_expression(ir_binop_add, mul->type, mul, from);
183
184 ir_expression *cmp = swap_compare_operands
185 ? new(mem_ctx) ir_expression(op, glsl_type::bool_type, to, add)
186 : new(mem_ctx) ir_expression(op, glsl_type::bool_type, add, to);
187 if (continue_from_then)
188 cmp = new(mem_ctx) ir_expression(ir_unop_logic_not, cmp);
189
190 ir_constant *const cmp_result = cmp->constant_expression_value(mem_ctx);
191
192 assert(cmp_result != NULL);
193 if (cmp_result->get_bool_component(0)) {
194 iter_value += bias[i];
195 valid_loop = true;
196 break;
197 }
198 }
199
200 ralloc_free(mem_ctx);
201
202 if (inc_before_terminator) {
203 iter_value--;
204 }
205
206 return (valid_loop) ? iter_value : -1;
207 }
208
209 static bool
210 incremented_before_terminator(ir_loop *loop, ir_variable *var,
211 ir_if *terminator)
212 {
213 for (exec_node *node = loop->body_instructions.get_head();
214 !node->is_tail_sentinel();
215 node = node->get_next()) {
216 ir_instruction *ir = (ir_instruction *) node;
217
218 switch (ir->ir_type) {
219 case ir_type_if:
220 if (ir->as_if() == terminator)
221 return false;
222 break;
223
224 case ir_type_assignment: {
225 ir_assignment *assign = ir->as_assignment();
226 ir_variable *assignee = assign->lhs->whole_variable_referenced();
227
228 if (assignee == var) {
229 assert(assign->condition == NULL);
230 return true;
231 }
232
233 break;
234 }
235
236 default:
237 break;
238 }
239 }
240
241 unreachable("Unable to find induction variable");
242 }
243
244 /**
245 * Record the fact that the given loop variable was referenced inside the loop.
246 *
247 * \arg in_assignee is true if the reference was on the LHS of an assignment.
248 *
249 * \arg in_conditional_code_or_nested_loop is true if the reference occurred
250 * inside an if statement or a nested loop.
251 *
252 * \arg current_assignment is the ir_assignment node that the loop variable is
253 * on the LHS of, if any (ignored if \c in_assignee is false).
254 */
255 void
256 loop_variable::record_reference(bool in_assignee,
257 bool in_conditional_code_or_nested_loop,
258 ir_assignment *current_assignment)
259 {
260 if (in_assignee) {
261 assert(current_assignment != NULL);
262
263 if (in_conditional_code_or_nested_loop ||
264 current_assignment->condition != NULL) {
265 this->conditional_or_nested_assignment = true;
266 }
267
268 if (this->first_assignment == NULL) {
269 assert(this->num_assignments == 0);
270
271 this->first_assignment = current_assignment;
272 }
273
274 this->num_assignments++;
275 } else if (this->first_assignment == current_assignment) {
276 /* This catches the case where the variable is used in the RHS of an
277 * assignment where it is also in the LHS.
278 */
279 this->read_before_write = true;
280 }
281 }
282
283
284 loop_state::loop_state()
285 {
286 this->ht = _mesa_pointer_hash_table_create(NULL);
287 this->mem_ctx = ralloc_context(NULL);
288 this->loop_found = false;
289 }
290
291
292 loop_state::~loop_state()
293 {
294 _mesa_hash_table_destroy(this->ht, NULL);
295 ralloc_free(this->mem_ctx);
296 }
297
298
299 loop_variable_state *
300 loop_state::insert(ir_loop *ir)
301 {
302 loop_variable_state *ls = new(this->mem_ctx) loop_variable_state;
303
304 _mesa_hash_table_insert(this->ht, ir, ls);
305 this->loop_found = true;
306
307 return ls;
308 }
309
310
311 loop_variable_state *
312 loop_state::get(const ir_loop *ir)
313 {
314 hash_entry *entry = _mesa_hash_table_search(this->ht, ir);
315 return entry ? (loop_variable_state *) entry->data : NULL;
316 }
317
318
319 loop_variable *
320 loop_variable_state::get(const ir_variable *ir)
321 {
322 if (ir == NULL)
323 return NULL;
324
325 hash_entry *entry = _mesa_hash_table_search(this->var_hash, ir);
326 return entry ? (loop_variable *) entry->data : NULL;
327 }
328
329
330 loop_variable *
331 loop_variable_state::insert(ir_variable *var)
332 {
333 void *mem_ctx = ralloc_parent(this);
334 loop_variable *lv = rzalloc(mem_ctx, loop_variable);
335
336 lv->var = var;
337
338 _mesa_hash_table_insert(this->var_hash, lv->var, lv);
339 this->variables.push_tail(lv);
340
341 return lv;
342 }
343
344
345 loop_terminator *
346 loop_variable_state::insert(ir_if *if_stmt, bool continue_from_then)
347 {
348 void *mem_ctx = ralloc_parent(this);
349 loop_terminator *t = new(mem_ctx) loop_terminator();
350
351 t->ir = if_stmt;
352 t->continue_from_then = continue_from_then;
353
354 this->terminators.push_tail(t);
355
356 return t;
357 }
358
359
360 /**
361 * If the given variable already is recorded in the state for this loop,
362 * return the corresponding loop_variable object that records information
363 * about it.
364 *
365 * Otherwise, create a new loop_variable object to record information about
366 * the variable, and set its \c read_before_write field appropriately based on
367 * \c in_assignee.
368 *
369 * \arg in_assignee is true if this variable was encountered on the LHS of an
370 * assignment.
371 */
372 loop_variable *
373 loop_variable_state::get_or_insert(ir_variable *var, bool in_assignee)
374 {
375 loop_variable *lv = this->get(var);
376
377 if (lv == NULL) {
378 lv = this->insert(var);
379 lv->read_before_write = !in_assignee;
380 }
381
382 return lv;
383 }
384
385
386 namespace {
387
388 class loop_analysis : public ir_hierarchical_visitor {
389 public:
390 loop_analysis(loop_state *loops);
391
392 virtual ir_visitor_status visit(ir_loop_jump *);
393 virtual ir_visitor_status visit(ir_dereference_variable *);
394
395 virtual ir_visitor_status visit_enter(ir_call *);
396
397 virtual ir_visitor_status visit_enter(ir_loop *);
398 virtual ir_visitor_status visit_leave(ir_loop *);
399 virtual ir_visitor_status visit_enter(ir_assignment *);
400 virtual ir_visitor_status visit_leave(ir_assignment *);
401 virtual ir_visitor_status visit_enter(ir_if *);
402 virtual ir_visitor_status visit_leave(ir_if *);
403
404 loop_state *loops;
405
406 int if_statement_depth;
407
408 ir_assignment *current_assignment;
409
410 exec_list state;
411 };
412
413 } /* anonymous namespace */
414
415 loop_analysis::loop_analysis(loop_state *loops)
416 : loops(loops), if_statement_depth(0), current_assignment(NULL)
417 {
418 /* empty */
419 }
420
421
422 ir_visitor_status
423 loop_analysis::visit(ir_loop_jump *ir)
424 {
425 (void) ir;
426
427 assert(!this->state.is_empty());
428
429 loop_variable_state *const ls =
430 (loop_variable_state *) this->state.get_head();
431
432 ls->num_loop_jumps++;
433
434 return visit_continue;
435 }
436
437
438 ir_visitor_status
439 loop_analysis::visit_enter(ir_call *)
440 {
441 /* Mark every loop that we're currently analyzing as containing an ir_call
442 * (even those at outer nesting levels).
443 */
444 foreach_in_list(loop_variable_state, ls, &this->state) {
445 ls->contains_calls = true;
446 }
447
448 return visit_continue_with_parent;
449 }
450
451
452 ir_visitor_status
453 loop_analysis::visit(ir_dereference_variable *ir)
454 {
455 /* If we're not somewhere inside a loop, there's nothing to do.
456 */
457 if (this->state.is_empty())
458 return visit_continue;
459
460 bool nested = false;
461
462 foreach_in_list(loop_variable_state, ls, &this->state) {
463 ir_variable *var = ir->variable_referenced();
464 loop_variable *lv = ls->get_or_insert(var, this->in_assignee);
465
466 lv->record_reference(this->in_assignee,
467 nested || this->if_statement_depth > 0,
468 this->current_assignment);
469 nested = true;
470 }
471
472 return visit_continue;
473 }
474
475 ir_visitor_status
476 loop_analysis::visit_enter(ir_loop *ir)
477 {
478 loop_variable_state *ls = this->loops->insert(ir);
479 this->state.push_head(ls);
480
481 return visit_continue;
482 }
483
484 ir_visitor_status
485 loop_analysis::visit_leave(ir_loop *ir)
486 {
487 loop_variable_state *const ls =
488 (loop_variable_state *) this->state.pop_head();
489
490 /* Function calls may contain side effects. These could alter any of our
491 * variables in ways that cannot be known, and may even terminate shader
492 * execution (say, calling discard in the fragment shader). So we can't
493 * rely on any of our analysis about assignments to variables.
494 *
495 * We could perform some conservative analysis (prove there's no statically
496 * possible assignment, etc.) but it isn't worth it for now; function
497 * inlining will allow us to unroll loops anyway.
498 */
499 if (ls->contains_calls)
500 return visit_continue;
501
502 foreach_in_list(ir_instruction, node, &ir->body_instructions) {
503 /* Skip over declarations at the start of a loop.
504 */
505 if (node->as_variable())
506 continue;
507
508 ir_if *if_stmt = ((ir_instruction *) node)->as_if();
509
510 if (if_stmt != NULL)
511 try_add_loop_terminator(ls, if_stmt);
512 }
513
514
515 foreach_in_list_safe(loop_variable, lv, &ls->variables) {
516 /* Move variables that are already marked as being loop constant to
517 * a separate list. These trivially don't need to be tested.
518 */
519 if (lv->is_loop_constant()) {
520 lv->remove();
521 ls->constants.push_tail(lv);
522 }
523 }
524
525 /* Each variable assigned in the loop that isn't already marked as being loop
526 * constant might still be loop constant. The requirements at this point
527 * are:
528 *
529 * - Variable is written before it is read.
530 *
531 * - Only one assignment to the variable.
532 *
533 * - All operands on the RHS of the assignment are also loop constants.
534 *
535 * The last requirement is the reason for the progress loop. A variable
536 * marked as a loop constant on one pass may allow other variables to be
537 * marked as loop constant on following passes.
538 */
539 bool progress;
540 do {
541 progress = false;
542
543 foreach_in_list_safe(loop_variable, lv, &ls->variables) {
544 if (lv->conditional_or_nested_assignment || (lv->num_assignments > 1))
545 continue;
546
547 /* Process the RHS of the assignment. If all of the variables
548 * accessed there are loop constants, then add this
549 */
550 ir_rvalue *const rhs = lv->first_assignment->rhs;
551 if (all_expression_operands_are_loop_constant(rhs, ls->var_hash)) {
552 lv->rhs_clean = true;
553
554 if (lv->is_loop_constant()) {
555 progress = true;
556
557 lv->remove();
558 ls->constants.push_tail(lv);
559 }
560 }
561 }
562 } while (progress);
563
564 /* The remaining variables that are not loop invariant might be loop
565 * induction variables.
566 */
567 foreach_in_list_safe(loop_variable, lv, &ls->variables) {
568 /* If there is more than one assignment to a variable, it cannot be a
569 * loop induction variable. This isn't strictly true, but this is a
570 * very simple induction variable detector, and it can't handle more
571 * complex cases.
572 */
573 if (lv->num_assignments > 1)
574 continue;
575
576 /* All of the variables with zero assignments in the loop are loop
577 * invariant, and they should have already been filtered out.
578 */
579 assert(lv->num_assignments == 1);
580 assert(lv->first_assignment != NULL);
581
582 /* The assignment to the variable in the loop must be unconditional and
583 * not inside a nested loop.
584 */
585 if (lv->conditional_or_nested_assignment)
586 continue;
587
588 /* Basic loop induction variables have a single assignment in the loop
589 * that has the form 'VAR = VAR + i' or 'VAR = VAR - i' where i is a
590 * loop invariant.
591 */
592 ir_rvalue *const inc =
593 get_basic_induction_increment(lv->first_assignment, ls->var_hash);
594 if (inc != NULL) {
595 lv->increment = inc;
596
597 lv->remove();
598 ls->induction_variables.push_tail(lv);
599 }
600 }
601
602 /* Search the loop terminating conditions for those of the form 'i < c'
603 * where i is a loop induction variable, c is a constant, and < is any
604 * relative operator. From each of these we can infer an iteration count.
605 * Also figure out which terminator (if any) produces the smallest
606 * iteration count--this is the limiting terminator.
607 */
608 foreach_in_list(loop_terminator, t, &ls->terminators) {
609 ir_if *if_stmt = t->ir;
610
611 /* If-statements can be either 'if (expr)' or 'if (deref)'. We only care
612 * about the former here.
613 */
614 ir_expression *cond = if_stmt->condition->as_expression();
615 if (cond == NULL)
616 continue;
617
618 switch (cond->operation) {
619 case ir_binop_less:
620 case ir_binop_gequal: {
621 /* The expressions that we care about will either be of the form
622 * 'counter < limit' or 'limit < counter'. Figure out which is
623 * which.
624 */
625 ir_rvalue *counter = cond->operands[0]->as_dereference_variable();
626 ir_constant *limit = cond->operands[1]->as_constant();
627 enum ir_expression_operation cmp = cond->operation;
628 bool swap_compare_operands = false;
629
630 if (limit == NULL) {
631 counter = cond->operands[1]->as_dereference_variable();
632 limit = cond->operands[0]->as_constant();
633 swap_compare_operands = true;
634 }
635
636 if ((counter == NULL) || (limit == NULL))
637 break;
638
639 ir_variable *var = counter->variable_referenced();
640
641 ir_rvalue *init = find_initial_value(ir, var);
642
643 loop_variable *lv = ls->get(var);
644 if (lv != NULL && lv->is_induction_var()) {
645 bool inc_before_terminator =
646 incremented_before_terminator(ir, var, t->ir);
647
648 t->iterations = calculate_iterations(init, limit, lv->increment,
649 cmp, t->continue_from_then,
650 swap_compare_operands,
651 inc_before_terminator);
652
653 if (t->iterations >= 0 &&
654 (ls->limiting_terminator == NULL ||
655 t->iterations < ls->limiting_terminator->iterations)) {
656 ls->limiting_terminator = t;
657 }
658 }
659 break;
660 }
661
662 default:
663 break;
664 }
665 }
666
667 return visit_continue;
668 }
669
670 ir_visitor_status
671 loop_analysis::visit_enter(ir_if *ir)
672 {
673 (void) ir;
674
675 if (!this->state.is_empty())
676 this->if_statement_depth++;
677
678 return visit_continue;
679 }
680
681 ir_visitor_status
682 loop_analysis::visit_leave(ir_if *ir)
683 {
684 (void) ir;
685
686 if (!this->state.is_empty())
687 this->if_statement_depth--;
688
689 return visit_continue;
690 }
691
692 ir_visitor_status
693 loop_analysis::visit_enter(ir_assignment *ir)
694 {
695 /* If we're not somewhere inside a loop, there's nothing to do.
696 */
697 if (this->state.is_empty())
698 return visit_continue_with_parent;
699
700 this->current_assignment = ir;
701
702 return visit_continue;
703 }
704
705 ir_visitor_status
706 loop_analysis::visit_leave(ir_assignment *ir)
707 {
708 /* Since the visit_enter exits with visit_continue_with_parent for this
709 * case, the loop state stack should never be empty here.
710 */
711 assert(!this->state.is_empty());
712
713 assert(this->current_assignment == ir);
714 this->current_assignment = NULL;
715
716 return visit_continue;
717 }
718
719
720 class examine_rhs : public ir_hierarchical_visitor {
721 public:
722 examine_rhs(hash_table *loop_variables)
723 {
724 this->only_uses_loop_constants = true;
725 this->loop_variables = loop_variables;
726 }
727
728 virtual ir_visitor_status visit(ir_dereference_variable *ir)
729 {
730 hash_entry *entry = _mesa_hash_table_search(this->loop_variables,
731 ir->var);
732 loop_variable *lv = entry ? (loop_variable *) entry->data : NULL;
733
734 assert(lv != NULL);
735
736 if (lv->is_loop_constant()) {
737 return visit_continue;
738 } else {
739 this->only_uses_loop_constants = false;
740 return visit_stop;
741 }
742 }
743
744 hash_table *loop_variables;
745 bool only_uses_loop_constants;
746 };
747
748
749 bool
750 all_expression_operands_are_loop_constant(ir_rvalue *ir, hash_table *variables)
751 {
752 examine_rhs v(variables);
753
754 ir->accept(&v);
755
756 return v.only_uses_loop_constants;
757 }
758
759
760 ir_rvalue *
761 get_basic_induction_increment(ir_assignment *ir, hash_table *var_hash)
762 {
763 /* The RHS must be a binary expression.
764 */
765 ir_expression *const rhs = ir->rhs->as_expression();
766 if ((rhs == NULL)
767 || ((rhs->operation != ir_binop_add)
768 && (rhs->operation != ir_binop_sub)))
769 return NULL;
770
771 /* One of the of operands of the expression must be the variable assigned.
772 * If the operation is subtraction, the variable in question must be the
773 * "left" operand.
774 */
775 ir_variable *const var = ir->lhs->variable_referenced();
776
777 ir_variable *const op0 = rhs->operands[0]->variable_referenced();
778 ir_variable *const op1 = rhs->operands[1]->variable_referenced();
779
780 if (((op0 != var) && (op1 != var))
781 || ((op1 == var) && (rhs->operation == ir_binop_sub)))
782 return NULL;
783
784 ir_rvalue *inc = (op0 == var) ? rhs->operands[1] : rhs->operands[0];
785
786 if (inc->as_constant() == NULL) {
787 ir_variable *const inc_var = inc->variable_referenced();
788 if (inc_var != NULL) {
789 hash_entry *entry = _mesa_hash_table_search(var_hash, inc_var);
790 loop_variable *lv = entry ? (loop_variable *) entry->data : NULL;
791
792 if (lv == NULL || !lv->is_loop_constant()) {
793 assert(lv != NULL);
794 inc = NULL;
795 }
796 } else
797 inc = NULL;
798 }
799
800 if ((inc != NULL) && (rhs->operation == ir_binop_sub)) {
801 void *mem_ctx = ralloc_parent(ir);
802
803 inc = new(mem_ctx) ir_expression(ir_unop_neg,
804 inc->type,
805 inc->clone(mem_ctx, NULL),
806 NULL);
807 }
808
809 return inc;
810 }
811
812
813 /**
814 * Detect whether an if-statement is a loop terminating condition, if so
815 * add it to the list of loop terminators.
816 *
817 * Detects if-statements of the form
818 *
819 * (if (expression bool ...) (...then_instrs...break))
820 *
821 * or
822 *
823 * (if (expression bool ...) ... (...else_instrs...break))
824 */
825 void
826 try_add_loop_terminator(loop_variable_state *ls, ir_if *ir)
827 {
828 ir_instruction *inst = (ir_instruction *) ir->then_instructions.get_tail();
829 ir_instruction *else_inst =
830 (ir_instruction *) ir->else_instructions.get_tail();
831
832 if (is_break(inst) || is_break(else_inst))
833 ls->insert(ir, is_break(else_inst));
834 }
835
836
837 loop_state *
838 analyze_loop_variables(exec_list *instructions)
839 {
840 loop_state *loops = new loop_state;
841 loop_analysis v(loops);
842
843 v.run(instructions);
844 return v.loops;
845 }