GCC Middle and Back End API Reference
loop-doloop.cc File Reference
#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "target.h"
#include "rtl.h"
#include "tree.h"
#include "cfghooks.h"
#include "memmodel.h"
#include "emit-rtl.h"
#include "dojump.h"
#include "expr.h"
#include "cfgloop.h"
#include "cfgrtl.h"
#include "dumpfile.h"
#include "loop-unroll.h"
#include "regs.h"
#include "df.h"
Include dependency graph for loop-doloop.cc:


rtx doloop_condition_get (rtx_insn *doloop_pat)
static bool doloop_valid_p (class loop *loop, class niter_desc *desc)
static bool add_test (rtx cond, edge *e, basic_block dest)
static rtx doloop_simplify_count (class loop *loop, scalar_int_mode mode, rtx count)
static void doloop_modify (class loop *loop, class niter_desc *desc, rtx_insn *doloop_seq, rtx condition, rtx count)
static void record_reg_sets (rtx x, const_rtx pat, void *data)
static bool doloop_optimize (class loop *loop)
void doloop_optimize_loops (void)

Function Documentation

◆ add_test()

static bool add_test ( rtx cond,
edge * e,
basic_block dest )
Adds test of COND jumping to DEST on edge *E and set *E to the new fallthru
edge.  If the condition is always false, do not do anything.  If it is always
true, redirect E to DEST and return false.  In all other cases, true is

References any_uncondjump_p(), block_label(), delete_insn(), do_compare_rtx_and_jump(), end_sequence(), basic_block_def::flags, force_operand(), gcc_assert, GET_CODE, get_insns(), get_last_insn(), GET_MODE, ggc_alloc(), profile_probability::guessed_never(), profile_probability::invert(), JUMP_LABEL, JUMP_P, LABEL_NUSES, make_edge(), NULL, NULL_RTX, onlyjump_p(), redirect_edge_and_branch_force(), single_succ_edge(), split_edge_and_insert(), start_sequence(), unshare_all_rtl_in_chain(), update_br_prob_note(), and XEXP.

Referenced by doloop_modify().

◆ doloop_condition_get()

rtx doloop_condition_get ( rtx_insn * doloop_pat)
Perform doloop optimizations
   Copyright (C) 2004-2024 Free Software Foundation, Inc.
   Based on code by Michael P. Hayes (m.hayes@elec.canterbury.ac.nz)

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
This module is used to modify loops with a determinable number of
iterations to use special low-overhead looping instructions.

It first validates whether the loop is well behaved and has a
determinable number of iterations (either at compile or run-time).
It then modifies the loop to use a low-overhead looping pattern as

1. A pseudo register is allocated as the loop iteration counter.

2. The number of loop iterations is calculated and is stored
   in the loop counter.

3. At the end of the loop, the jump insn is replaced by the
   doloop_end pattern.  The compare must remain because it might be
   used elsewhere.  If the loop-variable or condition register are
   used elsewhere, they will be eliminated by flow.

4. An optional doloop_begin pattern is inserted at the top of the

TODO The optimization should only performed when either the biv used for exit
condition is unused at all except for the exit test, or if we do not have to
change its value, since otherwise we have to add a new induction variable,
which usually will not pay up (unless the cost of the doloop pattern is
somehow extremely lower than the cost of compare & jump, or unless the bct
register cannot be used for anything else but doloop -- ??? detect these
Return the loop termination condition for PATTERN or zero
if it is not a decrement and branch jump insn.   

References const0_rtx, const1_rtx, constm1_rtx, GEN_INT, GET_CODE, ggc_alloc(), INSN_P, NULL_RTX, PATTERN(), pc_rtx, prev_nondebug_insn(), REG_P, SET, SET_DEST, SET_SRC, XEXP, and XVECEXP.

Referenced by doloop_optimize().

◆ doloop_modify()

◆ doloop_optimize()

◆ doloop_optimize_loops()

void doloop_optimize_loops ( void )
This is the main entry point.  Process all loops using doloop_optimize.   

References cfun, checking_verify_loop_structure(), df_live, df_live_add_problem(), df_live_set_all_dirty(), df_remove_problem(), doloop_optimize(), ggc_alloc(), and iv_analysis_done().

◆ doloop_simplify_count()

static rtx doloop_simplify_count ( class loop * loop,
scalar_int_mode mode,
rtx count )
Fold (add -1; zero_ext; add +1) operations to zero_ext if not wrapping. i.e:

73: r145:SI=r123:DI#0-0x1
74: r144:DI=zero_extend (r145:SI)
75: r143:DI=r144:DI+0x1
31: r135:CC=cmp (r123:DI,0)
72: {pc={(r143:DI!=0x1)?L70:pc};r143:DI=r143:DI-0x1;...}

r123:DI#0-0x1 is param count derived from loop->niter_expr equal to number of
loop iterations, if loop iterations expression doesn't overflow, then
(zero_extend (r123:DI#0-1))+1 can be simplified to zero_extend.   

References const1_rtx, constm1_rtx, count, GET_CODE, get_max_loop_iterations(), GET_MODE, GET_MODE_MASK, ggc_alloc(), wi::ltu_p(), simplify_gen_binary(), simplify_gen_unary(), and XEXP.

Referenced by doloop_modify().

◆ doloop_valid_p()

static bool doloop_valid_p ( class loop * loop,
class niter_desc * desc )
Return nonzero if the loop specified by LOOP is suitable for
the use of special low-overhead looping instructions.  DESC
describes the number of iterations of the loop.   

References niter_desc::assumptions, BB_END, BB_HEAD, dump_file, free(), get_loop_body(), ggc_alloc(), i, niter_desc::infinite, NEXT_INSN(), loop::num_nodes, niter_desc::simple_p, and targetm.

Referenced by doloop_optimize().

◆ record_reg_sets()

static void record_reg_sets ( rtx x,
const_rtx pat,
void * data )
Called through note_stores.   

References bitmap_set_bit, end_hard_regno(), GET_MODE, HARD_REGISTER_P, REG_P, and REGNO.

Referenced by doloop_optimize().