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