loop_analysis.cpp revision 01e04c3f
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 28static void try_add_loop_terminator(loop_variable_state *ls, ir_if *ir); 29 30static bool all_expression_operands_are_loop_constant(ir_rvalue *, 31 hash_table *); 32 33static 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 */ 49static ir_rvalue * 50find_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 88static int 89calculate_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) 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()) { 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 /* Make sure that the calculated number of iterations satisfies the exit 122 * condition. This is needed to catch off-by-one errors and some types of 123 * ill-formed loops. For example, we need to detect that the following 124 * loop does not have a maximum iteration count. 125 * 126 * for (float x = 0.0; x != 0.9; x += 0.2) 127 * ; 128 */ 129 const int bias[] = { -1, 0, 1 }; 130 bool valid_loop = false; 131 132 for (unsigned i = 0; i < ARRAY_SIZE(bias); i++) { 133 /* Increment may be of type int, uint or float. */ 134 switch (increment->type->base_type) { 135 case GLSL_TYPE_INT: 136 iter = new(mem_ctx) ir_constant(iter_value + bias[i]); 137 break; 138 case GLSL_TYPE_UINT: 139 iter = new(mem_ctx) ir_constant(unsigned(iter_value + bias[i])); 140 break; 141 case GLSL_TYPE_FLOAT: 142 iter = new(mem_ctx) ir_constant(float(iter_value + bias[i])); 143 break; 144 case GLSL_TYPE_DOUBLE: 145 iter = new(mem_ctx) ir_constant(double(iter_value + bias[i])); 146 break; 147 default: 148 unreachable("Unsupported type for loop iterator."); 149 } 150 151 ir_expression *const mul = 152 new(mem_ctx) ir_expression(ir_binop_mul, increment->type, iter, 153 increment); 154 155 ir_expression *const add = 156 new(mem_ctx) ir_expression(ir_binop_add, mul->type, mul, from); 157 158 ir_expression *cmp = swap_compare_operands 159 ? new(mem_ctx) ir_expression(op, glsl_type::bool_type, to, add) 160 : new(mem_ctx) ir_expression(op, glsl_type::bool_type, add, to); 161 if (continue_from_then) 162 cmp = new(mem_ctx) ir_expression(ir_unop_logic_not, cmp); 163 164 ir_constant *const cmp_result = cmp->constant_expression_value(mem_ctx); 165 166 assert(cmp_result != NULL); 167 if (cmp_result->get_bool_component(0)) { 168 iter_value += bias[i]; 169 valid_loop = true; 170 break; 171 } 172 } 173 174 ralloc_free(mem_ctx); 175 return (valid_loop) ? iter_value : -1; 176} 177 178static bool 179incremented_before_terminator(ir_loop *loop, ir_variable *var, 180 ir_if *terminator) 181{ 182 for (exec_node *node = loop->body_instructions.get_head(); 183 !node->is_tail_sentinel(); 184 node = node->get_next()) { 185 ir_instruction *ir = (ir_instruction *) node; 186 187 switch (ir->ir_type) { 188 case ir_type_if: 189 if (ir->as_if() == terminator) 190 return false; 191 break; 192 193 case ir_type_assignment: { 194 ir_assignment *assign = ir->as_assignment(); 195 ir_variable *assignee = assign->lhs->whole_variable_referenced(); 196 197 if (assignee == var) { 198 assert(assign->condition == NULL); 199 return true; 200 } 201 202 break; 203 } 204 205 default: 206 break; 207 } 208 } 209 210 unreachable("Unable to find induction variable"); 211} 212 213/** 214 * Record the fact that the given loop variable was referenced inside the loop. 215 * 216 * \arg in_assignee is true if the reference was on the LHS of an assignment. 217 * 218 * \arg in_conditional_code_or_nested_loop is true if the reference occurred 219 * inside an if statement or a nested loop. 220 * 221 * \arg current_assignment is the ir_assignment node that the loop variable is 222 * on the LHS of, if any (ignored if \c in_assignee is false). 223 */ 224void 225loop_variable::record_reference(bool in_assignee, 226 bool in_conditional_code_or_nested_loop, 227 ir_assignment *current_assignment) 228{ 229 if (in_assignee) { 230 assert(current_assignment != NULL); 231 232 if (in_conditional_code_or_nested_loop || 233 current_assignment->condition != NULL) { 234 this->conditional_or_nested_assignment = true; 235 } 236 237 if (this->first_assignment == NULL) { 238 assert(this->num_assignments == 0); 239 240 this->first_assignment = current_assignment; 241 } 242 243 this->num_assignments++; 244 } else if (this->first_assignment == current_assignment) { 245 /* This catches the case where the variable is used in the RHS of an 246 * assignment where it is also in the LHS. 247 */ 248 this->read_before_write = true; 249 } 250} 251 252 253loop_state::loop_state() 254{ 255 this->ht = _mesa_hash_table_create(NULL, _mesa_hash_pointer, 256 _mesa_key_pointer_equal); 257 this->mem_ctx = ralloc_context(NULL); 258 this->loop_found = false; 259} 260 261 262loop_state::~loop_state() 263{ 264 _mesa_hash_table_destroy(this->ht, NULL); 265 ralloc_free(this->mem_ctx); 266} 267 268 269loop_variable_state * 270loop_state::insert(ir_loop *ir) 271{ 272 loop_variable_state *ls = new(this->mem_ctx) loop_variable_state; 273 274 _mesa_hash_table_insert(this->ht, ir, ls); 275 this->loop_found = true; 276 277 return ls; 278} 279 280 281loop_variable_state * 282loop_state::get(const ir_loop *ir) 283{ 284 hash_entry *entry = _mesa_hash_table_search(this->ht, ir); 285 return entry ? (loop_variable_state *) entry->data : NULL; 286} 287 288 289loop_variable * 290loop_variable_state::get(const ir_variable *ir) 291{ 292 hash_entry *entry = _mesa_hash_table_search(this->var_hash, ir); 293 return entry ? (loop_variable *) entry->data : NULL; 294} 295 296 297loop_variable * 298loop_variable_state::insert(ir_variable *var) 299{ 300 void *mem_ctx = ralloc_parent(this); 301 loop_variable *lv = rzalloc(mem_ctx, loop_variable); 302 303 lv->var = var; 304 305 _mesa_hash_table_insert(this->var_hash, lv->var, lv); 306 this->variables.push_tail(lv); 307 308 return lv; 309} 310 311 312loop_terminator * 313loop_variable_state::insert(ir_if *if_stmt, bool continue_from_then) 314{ 315 void *mem_ctx = ralloc_parent(this); 316 loop_terminator *t = new(mem_ctx) loop_terminator(); 317 318 t->ir = if_stmt; 319 t->continue_from_then = continue_from_then; 320 321 this->terminators.push_tail(t); 322 323 return t; 324} 325 326 327/** 328 * If the given variable already is recorded in the state for this loop, 329 * return the corresponding loop_variable object that records information 330 * about it. 331 * 332 * Otherwise, create a new loop_variable object to record information about 333 * the variable, and set its \c read_before_write field appropriately based on 334 * \c in_assignee. 335 * 336 * \arg in_assignee is true if this variable was encountered on the LHS of an 337 * assignment. 338 */ 339loop_variable * 340loop_variable_state::get_or_insert(ir_variable *var, bool in_assignee) 341{ 342 loop_variable *lv = this->get(var); 343 344 if (lv == NULL) { 345 lv = this->insert(var); 346 lv->read_before_write = !in_assignee; 347 } 348 349 return lv; 350} 351 352 353namespace { 354 355class loop_analysis : public ir_hierarchical_visitor { 356public: 357 loop_analysis(loop_state *loops); 358 359 virtual ir_visitor_status visit(ir_loop_jump *); 360 virtual ir_visitor_status visit(ir_dereference_variable *); 361 362 virtual ir_visitor_status visit_enter(ir_call *); 363 364 virtual ir_visitor_status visit_enter(ir_loop *); 365 virtual ir_visitor_status visit_leave(ir_loop *); 366 virtual ir_visitor_status visit_enter(ir_assignment *); 367 virtual ir_visitor_status visit_leave(ir_assignment *); 368 virtual ir_visitor_status visit_enter(ir_if *); 369 virtual ir_visitor_status visit_leave(ir_if *); 370 371 loop_state *loops; 372 373 int if_statement_depth; 374 375 ir_assignment *current_assignment; 376 377 exec_list state; 378}; 379 380} /* anonymous namespace */ 381 382loop_analysis::loop_analysis(loop_state *loops) 383 : loops(loops), if_statement_depth(0), current_assignment(NULL) 384{ 385 /* empty */ 386} 387 388 389ir_visitor_status 390loop_analysis::visit(ir_loop_jump *ir) 391{ 392 (void) ir; 393 394 assert(!this->state.is_empty()); 395 396 loop_variable_state *const ls = 397 (loop_variable_state *) this->state.get_head(); 398 399 ls->num_loop_jumps++; 400 401 return visit_continue; 402} 403 404 405ir_visitor_status 406loop_analysis::visit_enter(ir_call *) 407{ 408 /* Mark every loop that we're currently analyzing as containing an ir_call 409 * (even those at outer nesting levels). 410 */ 411 foreach_in_list(loop_variable_state, ls, &this->state) { 412 ls->contains_calls = true; 413 } 414 415 return visit_continue_with_parent; 416} 417 418 419ir_visitor_status 420loop_analysis::visit(ir_dereference_variable *ir) 421{ 422 /* If we're not somewhere inside a loop, there's nothing to do. 423 */ 424 if (this->state.is_empty()) 425 return visit_continue; 426 427 bool nested = false; 428 429 foreach_in_list(loop_variable_state, ls, &this->state) { 430 ir_variable *var = ir->variable_referenced(); 431 loop_variable *lv = ls->get_or_insert(var, this->in_assignee); 432 433 lv->record_reference(this->in_assignee, 434 nested || this->if_statement_depth > 0, 435 this->current_assignment); 436 nested = true; 437 } 438 439 return visit_continue; 440} 441 442ir_visitor_status 443loop_analysis::visit_enter(ir_loop *ir) 444{ 445 loop_variable_state *ls = this->loops->insert(ir); 446 this->state.push_head(ls); 447 448 return visit_continue; 449} 450 451ir_visitor_status 452loop_analysis::visit_leave(ir_loop *ir) 453{ 454 loop_variable_state *const ls = 455 (loop_variable_state *) this->state.pop_head(); 456 457 /* Function calls may contain side effects. These could alter any of our 458 * variables in ways that cannot be known, and may even terminate shader 459 * execution (say, calling discard in the fragment shader). So we can't 460 * rely on any of our analysis about assignments to variables. 461 * 462 * We could perform some conservative analysis (prove there's no statically 463 * possible assignment, etc.) but it isn't worth it for now; function 464 * inlining will allow us to unroll loops anyway. 465 */ 466 if (ls->contains_calls) 467 return visit_continue; 468 469 foreach_in_list(ir_instruction, node, &ir->body_instructions) { 470 /* Skip over declarations at the start of a loop. 471 */ 472 if (node->as_variable()) 473 continue; 474 475 ir_if *if_stmt = ((ir_instruction *) node)->as_if(); 476 477 if (if_stmt != NULL) 478 try_add_loop_terminator(ls, if_stmt); 479 } 480 481 482 foreach_in_list_safe(loop_variable, lv, &ls->variables) { 483 /* Move variables that are already marked as being loop constant to 484 * a separate list. These trivially don't need to be tested. 485 */ 486 if (lv->is_loop_constant()) { 487 lv->remove(); 488 ls->constants.push_tail(lv); 489 } 490 } 491 492 /* Each variable assigned in the loop that isn't already marked as being loop 493 * constant might still be loop constant. The requirements at this point 494 * are: 495 * 496 * - Variable is written before it is read. 497 * 498 * - Only one assignment to the variable. 499 * 500 * - All operands on the RHS of the assignment are also loop constants. 501 * 502 * The last requirement is the reason for the progress loop. A variable 503 * marked as a loop constant on one pass may allow other variables to be 504 * marked as loop constant on following passes. 505 */ 506 bool progress; 507 do { 508 progress = false; 509 510 foreach_in_list_safe(loop_variable, lv, &ls->variables) { 511 if (lv->conditional_or_nested_assignment || (lv->num_assignments > 1)) 512 continue; 513 514 /* Process the RHS of the assignment. If all of the variables 515 * accessed there are loop constants, then add this 516 */ 517 ir_rvalue *const rhs = lv->first_assignment->rhs; 518 if (all_expression_operands_are_loop_constant(rhs, ls->var_hash)) { 519 lv->rhs_clean = true; 520 521 if (lv->is_loop_constant()) { 522 progress = true; 523 524 lv->remove(); 525 ls->constants.push_tail(lv); 526 } 527 } 528 } 529 } while (progress); 530 531 /* The remaining variables that are not loop invariant might be loop 532 * induction variables. 533 */ 534 foreach_in_list_safe(loop_variable, lv, &ls->variables) { 535 /* If there is more than one assignment to a variable, it cannot be a 536 * loop induction variable. This isn't strictly true, but this is a 537 * very simple induction variable detector, and it can't handle more 538 * complex cases. 539 */ 540 if (lv->num_assignments > 1) 541 continue; 542 543 /* All of the variables with zero assignments in the loop are loop 544 * invariant, and they should have already been filtered out. 545 */ 546 assert(lv->num_assignments == 1); 547 assert(lv->first_assignment != NULL); 548 549 /* The assignment to the variable in the loop must be unconditional and 550 * not inside a nested loop. 551 */ 552 if (lv->conditional_or_nested_assignment) 553 continue; 554 555 /* Basic loop induction variables have a single assignment in the loop 556 * that has the form 'VAR = VAR + i' or 'VAR = VAR - i' where i is a 557 * loop invariant. 558 */ 559 ir_rvalue *const inc = 560 get_basic_induction_increment(lv->first_assignment, ls->var_hash); 561 if (inc != NULL) { 562 lv->increment = inc; 563 564 lv->remove(); 565 ls->induction_variables.push_tail(lv); 566 } 567 } 568 569 /* Search the loop terminating conditions for those of the form 'i < c' 570 * where i is a loop induction variable, c is a constant, and < is any 571 * relative operator. From each of these we can infer an iteration count. 572 * Also figure out which terminator (if any) produces the smallest 573 * iteration count--this is the limiting terminator. 574 */ 575 foreach_in_list(loop_terminator, t, &ls->terminators) { 576 ir_if *if_stmt = t->ir; 577 578 /* If-statements can be either 'if (expr)' or 'if (deref)'. We only care 579 * about the former here. 580 */ 581 ir_expression *cond = if_stmt->condition->as_expression(); 582 if (cond == NULL) 583 continue; 584 585 switch (cond->operation) { 586 case ir_binop_less: 587 case ir_binop_gequal: { 588 /* The expressions that we care about will either be of the form 589 * 'counter < limit' or 'limit < counter'. Figure out which is 590 * which. 591 */ 592 ir_rvalue *counter = cond->operands[0]->as_dereference_variable(); 593 ir_constant *limit = cond->operands[1]->as_constant(); 594 enum ir_expression_operation cmp = cond->operation; 595 bool swap_compare_operands = false; 596 597 if (limit == NULL) { 598 counter = cond->operands[1]->as_dereference_variable(); 599 limit = cond->operands[0]->as_constant(); 600 swap_compare_operands = true; 601 } 602 603 if ((counter == NULL) || (limit == NULL)) 604 break; 605 606 ir_variable *var = counter->variable_referenced(); 607 608 ir_rvalue *init = find_initial_value(ir, var); 609 610 loop_variable *lv = ls->get(var); 611 if (lv != NULL && lv->is_induction_var()) { 612 t->iterations = calculate_iterations(init, limit, lv->increment, 613 cmp, t->continue_from_then, 614 swap_compare_operands); 615 616 if (incremented_before_terminator(ir, var, t->ir)) { 617 t->iterations--; 618 } 619 620 if (t->iterations >= 0 && 621 (ls->limiting_terminator == NULL || 622 t->iterations < ls->limiting_terminator->iterations)) { 623 ls->limiting_terminator = t; 624 } 625 } 626 break; 627 } 628 629 default: 630 break; 631 } 632 } 633 634 return visit_continue; 635} 636 637ir_visitor_status 638loop_analysis::visit_enter(ir_if *ir) 639{ 640 (void) ir; 641 642 if (!this->state.is_empty()) 643 this->if_statement_depth++; 644 645 return visit_continue; 646} 647 648ir_visitor_status 649loop_analysis::visit_leave(ir_if *ir) 650{ 651 (void) ir; 652 653 if (!this->state.is_empty()) 654 this->if_statement_depth--; 655 656 return visit_continue; 657} 658 659ir_visitor_status 660loop_analysis::visit_enter(ir_assignment *ir) 661{ 662 /* If we're not somewhere inside a loop, there's nothing to do. 663 */ 664 if (this->state.is_empty()) 665 return visit_continue_with_parent; 666 667 this->current_assignment = ir; 668 669 return visit_continue; 670} 671 672ir_visitor_status 673loop_analysis::visit_leave(ir_assignment *ir) 674{ 675 /* Since the visit_enter exits with visit_continue_with_parent for this 676 * case, the loop state stack should never be empty here. 677 */ 678 assert(!this->state.is_empty()); 679 680 assert(this->current_assignment == ir); 681 this->current_assignment = NULL; 682 683 return visit_continue; 684} 685 686 687class examine_rhs : public ir_hierarchical_visitor { 688public: 689 examine_rhs(hash_table *loop_variables) 690 { 691 this->only_uses_loop_constants = true; 692 this->loop_variables = loop_variables; 693 } 694 695 virtual ir_visitor_status visit(ir_dereference_variable *ir) 696 { 697 hash_entry *entry = _mesa_hash_table_search(this->loop_variables, 698 ir->var); 699 loop_variable *lv = entry ? (loop_variable *) entry->data : NULL; 700 701 assert(lv != NULL); 702 703 if (lv->is_loop_constant()) { 704 return visit_continue; 705 } else { 706 this->only_uses_loop_constants = false; 707 return visit_stop; 708 } 709 } 710 711 hash_table *loop_variables; 712 bool only_uses_loop_constants; 713}; 714 715 716bool 717all_expression_operands_are_loop_constant(ir_rvalue *ir, hash_table *variables) 718{ 719 examine_rhs v(variables); 720 721 ir->accept(&v); 722 723 return v.only_uses_loop_constants; 724} 725 726 727ir_rvalue * 728get_basic_induction_increment(ir_assignment *ir, hash_table *var_hash) 729{ 730 /* The RHS must be a binary expression. 731 */ 732 ir_expression *const rhs = ir->rhs->as_expression(); 733 if ((rhs == NULL) 734 || ((rhs->operation != ir_binop_add) 735 && (rhs->operation != ir_binop_sub))) 736 return NULL; 737 738 /* One of the of operands of the expression must be the variable assigned. 739 * If the operation is subtraction, the variable in question must be the 740 * "left" operand. 741 */ 742 ir_variable *const var = ir->lhs->variable_referenced(); 743 744 ir_variable *const op0 = rhs->operands[0]->variable_referenced(); 745 ir_variable *const op1 = rhs->operands[1]->variable_referenced(); 746 747 if (((op0 != var) && (op1 != var)) 748 || ((op1 == var) && (rhs->operation == ir_binop_sub))) 749 return NULL; 750 751 ir_rvalue *inc = (op0 == var) ? rhs->operands[1] : rhs->operands[0]; 752 753 if (inc->as_constant() == NULL) { 754 ir_variable *const inc_var = inc->variable_referenced(); 755 if (inc_var != NULL) { 756 hash_entry *entry = _mesa_hash_table_search(var_hash, inc_var); 757 loop_variable *lv = entry ? (loop_variable *) entry->data : NULL; 758 759 if (lv == NULL || !lv->is_loop_constant()) { 760 assert(lv != NULL); 761 inc = NULL; 762 } 763 } else 764 inc = NULL; 765 } 766 767 if ((inc != NULL) && (rhs->operation == ir_binop_sub)) { 768 void *mem_ctx = ralloc_parent(ir); 769 770 inc = new(mem_ctx) ir_expression(ir_unop_neg, 771 inc->type, 772 inc->clone(mem_ctx, NULL), 773 NULL); 774 } 775 776 return inc; 777} 778 779 780/** 781 * Detect whether an if-statement is a loop terminating condition, if so 782 * add it to the list of loop terminators. 783 * 784 * Detects if-statements of the form 785 * 786 * (if (expression bool ...) (...then_instrs...break)) 787 * 788 * or 789 * 790 * (if (expression bool ...) ... (...else_instrs...break)) 791 */ 792void 793try_add_loop_terminator(loop_variable_state *ls, ir_if *ir) 794{ 795 ir_instruction *inst = (ir_instruction *) ir->then_instructions.get_tail(); 796 ir_instruction *else_inst = 797 (ir_instruction *) ir->else_instructions.get_tail(); 798 799 if (is_break(inst) || is_break(else_inst)) 800 ls->insert(ir, is_break(else_inst)); 801} 802 803 804loop_state * 805analyze_loop_variables(exec_list *instructions) 806{ 807 loop_state *loops = new loop_state; 808 loop_analysis v(loops); 809 810 v.run(instructions); 811 return v.loops; 812} 813