150826Smdodd/* Perform doloop optimizations 250826Smdodd Copyright (C) 2004, 2005 Free Software Foundation, Inc. 350826Smdodd Based on code by Michael P. Hayes (m.hayes@elec.canterbury.ac.nz) 450826Smdodd 550826SmdoddThis file is part of GCC. 650826Smdodd 750826SmdoddGCC is free software; you can redistribute it and/or modify it under 850826Smdoddthe terms of the GNU General Public License as published by the Free 950826SmdoddSoftware Foundation; either version 2, or (at your option) any later 1050826Smdoddversion. 1150826Smdodd 1250826SmdoddGCC is distributed in the hope that it will be useful, but WITHOUT ANY 1350826SmdoddWARRANTY; without even the implied warranty of MERCHANTABILITY or 1450826SmdoddFITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 1550826Smdoddfor more details. 1650826Smdodd 1750826SmdoddYou should have received a copy of the GNU General Public License 1850826Smdoddalong with GCC; see the file COPYING. If not, write to the Free 1950826SmdoddSoftware Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 2050826Smdodd02110-1301, USA. */ 2150826Smdodd 2250826Smdodd#include "config.h" 2350826Smdodd#include "system.h" 2450826Smdodd#include "coretypes.h" 2550826Smdodd#include "tm.h" 2650826Smdodd#include "rtl.h" 2750826Smdodd#include "flags.h" 2850826Smdodd#include "expr.h" 2950826Smdodd#include "hard-reg-set.h" 3050826Smdodd#include "basic-block.h" 3150826Smdodd#include "toplev.h" 3250826Smdodd#include "tm_p.h" 3350826Smdodd#include "cfgloop.h" 3450826Smdodd#include "output.h" 3550826Smdodd#include "params.h" 3650826Smdodd#include "target.h" 3750826Smdodd 3850826Smdodd/* This module is used to modify loops with a determinable number of 3950826Smdodd iterations to use special low-overhead looping instructions. 4050826Smdodd 4150826Smdodd It first validates whether the loop is well behaved and has a 4250826Smdodd determinable number of iterations (either at compile or run-time). 4350826Smdodd It then modifies the loop to use a low-overhead looping pattern as 4450826Smdodd follows: 4550826Smdodd 4650826Smdodd 1. A pseudo register is allocated as the loop iteration counter. 4750826Smdodd 4850826Smdodd 2. The number of loop iterations is calculated and is stored 4950826Smdodd in the loop counter. 5050826Smdodd 5150826Smdodd 3. At the end of the loop, the jump insn is replaced by the 5250826Smdodd doloop_end pattern. The compare must remain because it might be 5350826Smdodd used elsewhere. If the loop-variable or condition register are 5450826Smdodd used elsewhere, they will be eliminated by flow. 5550826Smdodd 5650826Smdodd 4. An optional doloop_begin pattern is inserted at the top of the 5750826Smdodd loop. 5850826Smdodd 5950826Smdodd TODO The optimization should only performed when either the biv used for exit 6050826Smdodd condition is unused at all except for the exit test, or if we do not have to 6150826Smdodd change its value, since otherwise we have to add a new induction variable, 6250826Smdodd which usually will not pay up (unless the cost of the doloop pattern is 6350826Smdodd somehow extremely lower than the cost of compare & jump, or unless the bct 6450826Smdodd register cannot be used for anything else but doloop -- ??? detect these 6550826Smdodd cases). */ 6650826Smdodd 6750826Smdodd#ifdef HAVE_doloop_end 6850826Smdodd 6950826Smdodd/* Return the loop termination condition for PATTERN or zero 7050826Smdodd if it is not a decrement and branch jump insn. */ 7150826Smdodd 7250826Smdoddrtx 7350826Smdodddoloop_condition_get (rtx pattern) 7450826Smdodd{ 7550826Smdodd rtx cmp; 7650826Smdodd rtx inc; 7750826Smdodd rtx reg; 7850826Smdodd rtx inc_src; 7950826Smdodd rtx condition; 8050826Smdodd 8150826Smdodd /* The canonical doloop pattern we expect is: 8250826Smdodd 8350826Smdodd (parallel [(set (pc) (if_then_else (condition) 8450826Smdodd (label_ref (label)) 8550826Smdodd (pc))) 8650826Smdodd (set (reg) (plus (reg) (const_int -1))) 8750826Smdodd (additional clobbers and uses)]) 8850826Smdodd 8950826Smdodd Some targets (IA-64) wrap the set of the loop counter in 9050826Smdodd an if_then_else too. 9150826Smdodd 9250826Smdodd In summary, the branch must be the first entry of the 9350826Smdodd parallel (also required by jump.c), and the second 9450826Smdodd entry of the parallel must be a set of the loop counter 9550826Smdodd register. */ 9650826Smdodd 9750826Smdodd if (GET_CODE (pattern) != PARALLEL) 9850826Smdodd return 0; 9950826Smdodd 10050826Smdodd cmp = XVECEXP (pattern, 0, 0); 10150826Smdodd inc = XVECEXP (pattern, 0, 1); 10250826Smdodd 10350826Smdodd /* Check for (set (reg) (something)). */ 10450826Smdodd if (GET_CODE (inc) != SET) 10550826Smdodd return 0; 10650826Smdodd reg = SET_DEST (inc); 10750826Smdodd if (! REG_P (reg)) 10850826Smdodd return 0; 10952050Smdodd 11052050Smdodd /* Check if something = (plus (reg) (const_int -1)). 11152050Smdodd On IA-64, this decrement is wrapped in an if_then_else. */ 11250826Smdodd inc_src = SET_SRC (inc); 11352050Smdodd if (GET_CODE (inc_src) == IF_THEN_ELSE) 11450826Smdodd inc_src = XEXP (inc_src, 1); 11550826Smdodd if (GET_CODE (inc_src) != PLUS 11650826Smdodd || XEXP (inc_src, 0) != reg 11750826Smdodd || XEXP (inc_src, 1) != constm1_rtx) 11850826Smdodd return 0; 11950826Smdodd 12050826Smdodd /* Check for (set (pc) (if_then_else (condition) 12150826Smdodd (label_ref (label)) 12250826Smdodd (pc))). */ 12352050Smdodd if (GET_CODE (cmp) != SET 12452050Smdodd || SET_DEST (cmp) != pc_rtx 12550826Smdodd || GET_CODE (SET_SRC (cmp)) != IF_THEN_ELSE 12652050Smdodd || GET_CODE (XEXP (SET_SRC (cmp), 1)) != LABEL_REF 12750826Smdodd || XEXP (SET_SRC (cmp), 2) != pc_rtx) 12852050Smdodd return 0; 12950826Smdodd 13052050Smdodd /* Extract loop termination condition. */ 13152050Smdodd condition = XEXP (SET_SRC (cmp), 0); 13250826Smdodd 13352050Smdodd /* We expect a GE or NE comparison with 0 or 1. */ 13452050Smdodd if ((GET_CODE (condition) != GE 13552050Smdodd && GET_CODE (condition) != NE) 13652050Smdodd || (XEXP (condition, 1) != const0_rtx 13752050Smdodd && XEXP (condition, 1) != const1_rtx)) 13852050Smdodd return 0; 13952050Smdodd 14052050Smdodd if ((XEXP (condition, 0) == reg) 14152050Smdodd || (GET_CODE (XEXP (condition, 0)) == PLUS 14252050Smdodd && XEXP (XEXP (condition, 0), 0) == reg)) 14352050Smdodd return condition; 14452050Smdodd 14552050Smdodd /* ??? If a machine uses a funny comparison, we could return a 14652050Smdodd canonicalized form here. */ 14750826Smdodd 14850826Smdodd return 0; 14950826Smdodd} 15050826Smdodd 15150826Smdodd/* Return nonzero if the loop specified by LOOP is suitable for 15250826Smdodd the use of special low-overhead looping instructions. DESC 15350826Smdodd describes the number of iterations of the loop. */ 15450826Smdodd 15550826Smdoddstatic bool 15650826Smdodddoloop_valid_p (struct loop *loop, struct niter_desc *desc) 15750826Smdodd{ 15850826Smdodd basic_block *body = get_loop_body (loop), bb; 15950826Smdodd rtx insn; 16050826Smdodd unsigned i; 16150826Smdodd bool result = true; 16250826Smdodd 16350826Smdodd /* Check for loops that may not terminate under special conditions. */ 16450826Smdodd if (!desc->simple_p 16550826Smdodd || desc->assumptions 16650826Smdodd || desc->infinite) 16750826Smdodd { 16850826Smdodd /* There are some cases that would require a special attention. 16950826Smdodd For example if the comparison is LEU and the comparison value 17050826Smdodd is UINT_MAX then the loop will not terminate. Similarly, if the 17150826Smdodd comparison code is GEU and the comparison value is 0, the 17250826Smdodd loop will not terminate. 17350826Smdodd 17450826Smdodd If the absolute increment is not 1, the loop can be infinite 17550826Smdodd even with LTU/GTU, e.g. for (i = 3; i > 0; i -= 2) 17650826Smdodd 17750826Smdodd ??? We could compute these conditions at run-time and have a 17850826Smdodd additional jump around the loop to ensure an infinite loop. 17950826Smdodd However, it is very unlikely that this is the intended 18050826Smdodd behavior of the loop and checking for these rare boundary 18150826Smdodd conditions would pessimize all other code. 18250826Smdodd 18350826Smdodd If the loop is executed only a few times an extra check to 18450826Smdodd restart the loop could use up most of the benefits of using a 18550826Smdodd count register loop. Note however, that normally, this 18651675Smdodd restart branch would never execute, so it could be predicted 18750826Smdodd well by the CPU. We should generate the pessimistic code by 18850826Smdodd default, and have an option, e.g. -funsafe-loops that would 18952050Smdodd enable count-register loops in this case. */ 19050826Smdodd if (dump_file) 19150826Smdodd fprintf (dump_file, "Doloop: Possible infinite iteration case.\n"); 19250826Smdodd result = false; 19350826Smdodd goto cleanup; 19450826Smdodd } 19550826Smdodd 19650826Smdodd for (i = 0; i < loop->num_nodes; i++) 19750826Smdodd { 19850826Smdodd bb = body[i]; 19950826Smdodd 20050826Smdodd for (insn = BB_HEAD (bb); 20150826Smdodd insn != NEXT_INSN (BB_END (bb)); 20250826Smdodd insn = NEXT_INSN (insn)) 20350826Smdodd { 20450826Smdodd /* Different targets have different necessities for low-overhead 20550826Smdodd looping. Call the back end for each instruction within the loop 20650826Smdodd to let it decide whether the insn prohibits a low-overhead loop. 20750826Smdodd It will then return the cause for it to emit to the dump file. */ 20850826Smdodd const char * invalid = targetm.invalid_within_doloop (insn); 20950826Smdodd if (invalid) 21050826Smdodd { 21150826Smdodd if (dump_file) 21252050Smdodd fprintf (dump_file, "Doloop: %s\n", invalid); 21350826Smdodd result = false; 21450826Smdodd goto cleanup; 21550826Smdodd } 21650826Smdodd } 21750826Smdodd } 21850826Smdodd result = true; 21950826Smdodd 22050826Smdoddcleanup: 22150826Smdodd free (body); 22250826Smdodd 22350826Smdodd return result; 22450826Smdodd} 22550826Smdodd 22650826Smdodd/* Adds test of COND jumping to DEST on edge *E and set *E to the new fallthru 22750826Smdodd edge. If the condition is always false, do not do anything. If it is always 22850826Smdodd true, redirect E to DEST and return false. In all other cases, true is 22950826Smdodd returned. */ 23050826Smdodd 23150826Smdoddstatic bool 23250826Smdoddadd_test (rtx cond, edge *e, basic_block dest) 23350826Smdodd{ 23450826Smdodd rtx seq, jump, label; 23550826Smdodd enum machine_mode mode; 23650826Smdodd rtx op0 = XEXP (cond, 0), op1 = XEXP (cond, 1); 23750826Smdodd enum rtx_code code = GET_CODE (cond); 23850826Smdodd basic_block bb; 23950826Smdodd 24050826Smdodd mode = GET_MODE (XEXP (cond, 0)); 24150826Smdodd if (mode == VOIDmode) 24250826Smdodd mode = GET_MODE (XEXP (cond, 1)); 24350826Smdodd 24450826Smdodd start_sequence (); 24550826Smdodd op0 = force_operand (op0, NULL_RTX); 24650826Smdodd op1 = force_operand (op1, NULL_RTX); 24750826Smdodd label = block_label (dest); 24850826Smdodd do_compare_rtx_and_jump (op0, op1, code, 0, mode, NULL_RTX, NULL_RTX, label); 24950826Smdodd 25050826Smdodd jump = get_last_insn (); 25150826Smdodd if (!JUMP_P (jump)) 25250826Smdodd { 25350826Smdodd /* The condition is always false and the jump was optimized out. */ 25450826Smdodd end_sequence (); 25550826Smdodd return true; 25650826Smdodd } 25750826Smdodd 25850826Smdodd seq = get_insns (); 25950826Smdodd end_sequence (); 26050826Smdodd bb = loop_split_edge_with (*e, seq); 26150826Smdodd *e = single_succ_edge (bb); 26250826Smdodd 26350826Smdodd if (any_uncondjump_p (jump)) 26450826Smdodd { 26550826Smdodd /* The condition is always true. */ 26650826Smdodd delete_insn (jump); 26750826Smdodd redirect_edge_and_branch_force (*e, dest); 26850826Smdodd return false; 26950826Smdodd } 27050826Smdodd 27150826Smdodd JUMP_LABEL (jump) = label; 27250826Smdodd 27350826Smdodd /* The jump is supposed to handle an unlikely special case. */ 27450826Smdodd REG_NOTES (jump) 27550826Smdodd = gen_rtx_EXPR_LIST (REG_BR_PROB, 27650826Smdodd const0_rtx, REG_NOTES (jump)); 27750826Smdodd LABEL_NUSES (label)++; 27850826Smdodd 27950826Smdodd make_edge (bb, dest, (*e)->flags & ~EDGE_FALLTHRU); 28050826Smdodd return true; 28150826Smdodd} 28250826Smdodd 28350826Smdodd/* Modify the loop to use the low-overhead looping insn where LOOP 28450826Smdodd describes the loop, DESC describes the number of iterations of the 28550826Smdodd loop, and DOLOOP_INSN is the low-overhead looping insn to emit at the 28650826Smdodd end of the loop. CONDITION is the condition separated from the 28750826Smdodd DOLOOP_SEQ. COUNT is the number of iterations of the LOOP. */ 28850826Smdodd 28950826Smdoddstatic void 29050826Smdodddoloop_modify (struct loop *loop, struct niter_desc *desc, 29150826Smdodd rtx doloop_seq, rtx condition, rtx count) 29250826Smdodd{ 29350826Smdodd rtx counter_reg; 29450826Smdodd rtx tmp, noloop = NULL_RTX; 29550826Smdodd rtx sequence; 29650826Smdodd rtx jump_insn; 29750826Smdodd rtx jump_label; 29850826Smdodd int nonneg = 0; 29950826Smdodd bool increment_count; 30050826Smdodd basic_block loop_end = desc->out_edge->src; 30150826Smdodd enum machine_mode mode; 30250826Smdodd 30350826Smdodd jump_insn = BB_END (loop_end); 30450826Smdodd 30550826Smdodd if (dump_file) 30650826Smdodd { 30750826Smdodd fprintf (dump_file, "Doloop: Inserting doloop pattern ("); 30850826Smdodd if (desc->const_iter) 30950826Smdodd fprintf (dump_file, HOST_WIDEST_INT_PRINT_DEC, desc->niter); 31050826Smdodd else 31150826Smdodd fputs ("runtime", dump_file); 31250826Smdodd fputs (" iterations).\n", dump_file); 31350826Smdodd } 31450826Smdodd 31550826Smdodd /* Discard original jump to continue loop. The original compare 31650826Smdodd result may still be live, so it cannot be discarded explicitly. */ 31750826Smdodd delete_insn (jump_insn); 31850826Smdodd 31950826Smdodd counter_reg = XEXP (condition, 0); 32050826Smdodd if (GET_CODE (counter_reg) == PLUS) 32150826Smdodd counter_reg = XEXP (counter_reg, 0); 32250826Smdodd mode = GET_MODE (counter_reg); 32350826Smdodd 32450826Smdodd increment_count = false; 32550826Smdodd switch (GET_CODE (condition)) 32650826Smdodd { 32750826Smdodd case NE: 32850826Smdodd /* Currently only NE tests against zero and one are supported. */ 329 noloop = XEXP (condition, 1); 330 if (noloop != const0_rtx) 331 { 332 gcc_assert (noloop == const1_rtx); 333 increment_count = true; 334 } 335 break; 336 337 case GE: 338 /* Currently only GE tests against zero are supported. */ 339 gcc_assert (XEXP (condition, 1) == const0_rtx); 340 341 noloop = constm1_rtx; 342 343 /* The iteration count does not need incrementing for a GE test. */ 344 increment_count = false; 345 346 /* Determine if the iteration counter will be non-negative. 347 Note that the maximum value loaded is iterations_max - 1. */ 348 if (desc->niter_max 349 <= ((unsigned HOST_WIDEST_INT) 1 350 << (GET_MODE_BITSIZE (mode) - 1))) 351 nonneg = 1; 352 break; 353 354 /* Abort if an invalid doloop pattern has been generated. */ 355 default: 356 gcc_unreachable (); 357 } 358 359 if (increment_count) 360 count = simplify_gen_binary (PLUS, mode, count, const1_rtx); 361 362 /* Insert initialization of the count register into the loop header. */ 363 start_sequence (); 364 tmp = force_operand (count, counter_reg); 365 convert_move (counter_reg, tmp, 1); 366 sequence = get_insns (); 367 end_sequence (); 368 emit_insn_after (sequence, BB_END (loop_preheader_edge (loop)->src)); 369 370 if (desc->noloop_assumptions) 371 { 372 rtx ass = copy_rtx (desc->noloop_assumptions); 373 basic_block preheader = loop_preheader_edge (loop)->src; 374 basic_block set_zero 375 = loop_split_edge_with (loop_preheader_edge (loop), NULL_RTX); 376 basic_block new_preheader 377 = loop_split_edge_with (loop_preheader_edge (loop), NULL_RTX); 378 edge te; 379 380 /* Expand the condition testing the assumptions and if it does not pass, 381 reset the count register to 0. */ 382 redirect_edge_and_branch_force (single_succ_edge (preheader), new_preheader); 383 set_immediate_dominator (CDI_DOMINATORS, new_preheader, preheader); 384 385 set_zero->count = 0; 386 set_zero->frequency = 0; 387 388 te = single_succ_edge (preheader); 389 for (; ass; ass = XEXP (ass, 1)) 390 if (!add_test (XEXP (ass, 0), &te, set_zero)) 391 break; 392 393 if (ass) 394 { 395 /* We reached a condition that is always true. This is very hard to 396 reproduce (such a loop does not roll, and thus it would most 397 likely get optimized out by some of the preceding optimizations). 398 In fact, I do not have any testcase for it. However, it would 399 also be very hard to show that it is impossible, so we must 400 handle this case. */ 401 set_zero->count = preheader->count; 402 set_zero->frequency = preheader->frequency; 403 } 404 405 if (EDGE_COUNT (set_zero->preds) == 0) 406 { 407 /* All the conditions were simplified to false, remove the 408 unreachable set_zero block. */ 409 remove_bb_from_loops (set_zero); 410 delete_basic_block (set_zero); 411 } 412 else 413 { 414 /* Reset the counter to zero in the set_zero block. */ 415 start_sequence (); 416 convert_move (counter_reg, noloop, 0); 417 sequence = get_insns (); 418 end_sequence (); 419 emit_insn_after (sequence, BB_END (set_zero)); 420 421 set_immediate_dominator (CDI_DOMINATORS, set_zero, 422 recount_dominator (CDI_DOMINATORS, 423 set_zero)); 424 } 425 426 set_immediate_dominator (CDI_DOMINATORS, new_preheader, 427 recount_dominator (CDI_DOMINATORS, 428 new_preheader)); 429 } 430 431 /* Some targets (eg, C4x) need to initialize special looping 432 registers. */ 433#ifdef HAVE_doloop_begin 434 { 435 rtx init; 436 unsigned level = get_loop_level (loop) + 1; 437 init = gen_doloop_begin (counter_reg, 438 desc->const_iter ? desc->niter_expr : const0_rtx, 439 GEN_INT (desc->niter_max), 440 GEN_INT (level)); 441 if (init) 442 { 443 start_sequence (); 444 emit_insn (init); 445 sequence = get_insns (); 446 end_sequence (); 447 emit_insn_after (sequence, BB_END (loop_preheader_edge (loop)->src)); 448 } 449 } 450#endif 451 452 /* Insert the new low-overhead looping insn. */ 453 emit_jump_insn_after (doloop_seq, BB_END (loop_end)); 454 jump_insn = BB_END (loop_end); 455 jump_label = block_label (desc->in_edge->dest); 456 JUMP_LABEL (jump_insn) = jump_label; 457 LABEL_NUSES (jump_label)++; 458 459 /* Ensure the right fallthru edge is marked, for case we have reversed 460 the condition. */ 461 desc->in_edge->flags &= ~EDGE_FALLTHRU; 462 desc->out_edge->flags |= EDGE_FALLTHRU; 463 464 /* Add a REG_NONNEG note if the actual or estimated maximum number 465 of iterations is non-negative. */ 466 if (nonneg) 467 { 468 REG_NOTES (jump_insn) 469 = gen_rtx_EXPR_LIST (REG_NONNEG, NULL_RTX, REG_NOTES (jump_insn)); 470 } 471} 472 473/* Process loop described by LOOP validating that the loop is suitable for 474 conversion to use a low overhead looping instruction, replacing the jump 475 insn where suitable. Returns true if the loop was successfully 476 modified. */ 477 478static bool 479doloop_optimize (struct loop *loop) 480{ 481 enum machine_mode mode; 482 rtx doloop_seq, doloop_pat, doloop_reg; 483 rtx iterations, count; 484 rtx iterations_max; 485 rtx start_label; 486 rtx condition; 487 unsigned level, est_niter; 488 struct niter_desc *desc; 489 unsigned word_mode_size; 490 unsigned HOST_WIDE_INT word_mode_max; 491 492 if (dump_file) 493 fprintf (dump_file, "Doloop: Processing loop %d.\n", loop->num); 494 495 iv_analysis_loop_init (loop); 496 497 /* Find the simple exit of a LOOP. */ 498 desc = get_simple_loop_desc (loop); 499 500 /* Check that loop is a candidate for a low-overhead looping insn. */ 501 if (!doloop_valid_p (loop, desc)) 502 { 503 if (dump_file) 504 fprintf (dump_file, 505 "Doloop: The loop is not suitable.\n"); 506 return false; 507 } 508 mode = desc->mode; 509 510 est_niter = 3; 511 if (desc->const_iter) 512 est_niter = desc->niter; 513 /* If the estimate on number of iterations is reliable (comes from profile 514 feedback), use it. Do not use it normally, since the expected number 515 of iterations of an unrolled loop is 2. */ 516 if (loop->header->count) 517 est_niter = expected_loop_iterations (loop); 518 519 if (est_niter < 3) 520 { 521 if (dump_file) 522 fprintf (dump_file, 523 "Doloop: Too few iterations (%u) to be profitable.\n", 524 est_niter); 525 return false; 526 } 527 528 count = copy_rtx (desc->niter_expr); 529 iterations = desc->const_iter ? desc->niter_expr : const0_rtx; 530 iterations_max = GEN_INT (desc->niter_max); 531 level = get_loop_level (loop) + 1; 532 533 /* Generate looping insn. If the pattern FAILs then give up trying 534 to modify the loop since there is some aspect the back-end does 535 not like. */ 536 start_label = block_label (desc->in_edge->dest); 537 doloop_reg = gen_reg_rtx (mode); 538 doloop_seq = gen_doloop_end (doloop_reg, iterations, iterations_max, 539 GEN_INT (level), start_label); 540 541 word_mode_size = GET_MODE_BITSIZE (word_mode); 542 word_mode_max 543 = ((unsigned HOST_WIDE_INT) 1 << (word_mode_size - 1) << 1) - 1; 544 if (! doloop_seq 545 && mode != word_mode 546 /* Before trying mode different from the one in that # of iterations is 547 computed, we must be sure that the number of iterations fits into 548 the new mode. */ 549 && (word_mode_size >= GET_MODE_BITSIZE (mode) 550 || desc->niter_max <= word_mode_max)) 551 { 552 if (word_mode_size > GET_MODE_BITSIZE (mode)) 553 { 554 count = simplify_gen_unary (ZERO_EXTEND, word_mode, 555 count, mode); 556 iterations = simplify_gen_unary (ZERO_EXTEND, word_mode, 557 iterations, mode); 558 iterations_max = simplify_gen_unary (ZERO_EXTEND, word_mode, 559 iterations_max, mode); 560 } 561 else 562 { 563 count = lowpart_subreg (word_mode, count, mode); 564 iterations = lowpart_subreg (word_mode, iterations, mode); 565 iterations_max = lowpart_subreg (word_mode, iterations_max, mode); 566 } 567 PUT_MODE (doloop_reg, word_mode); 568 doloop_seq = gen_doloop_end (doloop_reg, iterations, iterations_max, 569 GEN_INT (level), start_label); 570 } 571 if (! doloop_seq) 572 { 573 if (dump_file) 574 fprintf (dump_file, 575 "Doloop: Target unwilling to use doloop pattern!\n"); 576 return false; 577 } 578 579 /* If multiple instructions were created, the last must be the 580 jump instruction. Also, a raw define_insn may yield a plain 581 pattern. */ 582 doloop_pat = doloop_seq; 583 if (INSN_P (doloop_pat)) 584 { 585 while (NEXT_INSN (doloop_pat) != NULL_RTX) 586 doloop_pat = NEXT_INSN (doloop_pat); 587 if (JUMP_P (doloop_pat)) 588 doloop_pat = PATTERN (doloop_pat); 589 else 590 doloop_pat = NULL_RTX; 591 } 592 593 if (! doloop_pat 594 || ! (condition = doloop_condition_get (doloop_pat))) 595 { 596 if (dump_file) 597 fprintf (dump_file, "Doloop: Unrecognizable doloop pattern!\n"); 598 return false; 599 } 600 601 doloop_modify (loop, desc, doloop_seq, condition, count); 602 return true; 603} 604 605/* This is the main entry point. Process all LOOPS using doloop_optimize. */ 606 607void 608doloop_optimize_loops (struct loops *loops) 609{ 610 unsigned i; 611 struct loop *loop; 612 613 for (i = 1; i < loops->num; i++) 614 { 615 loop = loops->parray[i]; 616 if (!loop) 617 continue; 618 619 doloop_optimize (loop); 620 } 621 622 iv_analysis_done (); 623 624#ifdef ENABLE_CHECKING 625 verify_dominators (CDI_DOMINATORS); 626 verify_loop_structure (loops); 627#endif 628} 629#endif /* HAVE_doloop_end */ 630 631