xref: /dflybsd-src/contrib/gcc-8.0/gcc/hw-doloop.h (revision 38fd149817dfbff97799f62fcb70be98c4e32523)
1*38fd1498Szrj /* Code to analyze doloop loops in order for targets to perform late
2*38fd1498Szrj    optimizations converting doloops to other forms of hardware loops.
3*38fd1498Szrj    Copyright (C) 2011-2018 Free Software Foundation, Inc.
4*38fd1498Szrj 
5*38fd1498Szrj This file is part of GCC.
6*38fd1498Szrj 
7*38fd1498Szrj GCC is free software; you can redistribute it and/or modify it under
8*38fd1498Szrj the terms of the GNU General Public License as published by the Free
9*38fd1498Szrj Software Foundation; either version 3, or (at your option) any later
10*38fd1498Szrj version.
11*38fd1498Szrj 
12*38fd1498Szrj GCC is distributed in the hope that it will be useful, but WITHOUT ANY
13*38fd1498Szrj WARRANTY; without even the implied warranty of MERCHANTABILITY or
14*38fd1498Szrj FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
15*38fd1498Szrj for more details.
16*38fd1498Szrj 
17*38fd1498Szrj You should have received a copy of the GNU General Public License
18*38fd1498Szrj along with GCC; see the file COPYING3.  If not see
19*38fd1498Szrj <http://www.gnu.org/licenses/>.  */
20*38fd1498Szrj 
21*38fd1498Szrj #ifndef GCC_HW_DOLOOP_H
22*38fd1498Szrj #define GCC_HW_DOLOOP_H
23*38fd1498Szrj 
24*38fd1498Szrj /* We need to keep a vector of loops */
25*38fd1498Szrj typedef struct hwloop_info_d *hwloop_info;
26*38fd1498Szrj 
27*38fd1498Szrj /* Information about a loop we have found (or are in the process of
28*38fd1498Szrj    finding).  */
29*38fd1498Szrj struct GTY (()) hwloop_info_d
30*38fd1498Szrj {
31*38fd1498Szrj   /* loop number, for dumps */
32*38fd1498Szrj   int loop_no;
33*38fd1498Szrj 
34*38fd1498Szrj   /* Next loop in the graph. */
35*38fd1498Szrj   hwloop_info next;
36*38fd1498Szrj 
37*38fd1498Szrj   /* Vector of blocks only within the loop, including those within
38*38fd1498Szrj      inner loops.  */
39*38fd1498Szrj   vec<basic_block> blocks;
40*38fd1498Szrj 
41*38fd1498Szrj   /* Same information in a bitmap.  */
42*38fd1498Szrj   bitmap block_bitmap;
43*38fd1498Szrj 
44*38fd1498Szrj   /* Vector of inner loops within this loop.  Includes loops of every
45*38fd1498Szrj      nesting level.  */
46*38fd1498Szrj   vec<hwloop_info> loops;
47*38fd1498Szrj 
48*38fd1498Szrj   /* All edges that jump into the loop.  */
49*38fd1498Szrj   vec<edge, va_gc> *incoming;
50*38fd1498Szrj 
51*38fd1498Szrj   /* The ports currently using this infrastructure can typically
52*38fd1498Szrj      handle two cases: all incoming edges have the same destination
53*38fd1498Szrj      block, or all incoming edges have the same source block.  These
54*38fd1498Szrj      two members are set to the common source or destination we found,
55*38fd1498Szrj      or NULL if different blocks were found.  If both are NULL the
56*38fd1498Szrj      loop can't be optimized.  */
57*38fd1498Szrj   basic_block incoming_src;
58*38fd1498Szrj   basic_block incoming_dest;
59*38fd1498Szrj 
60*38fd1498Szrj   /* First block in the loop.  This is the one branched to by the loop_end
61*38fd1498Szrj      insn.  */
62*38fd1498Szrj   basic_block head;
63*38fd1498Szrj 
64*38fd1498Szrj   /* Last block in the loop (the one with the loop_end insn).  */
65*38fd1498Szrj   basic_block tail;
66*38fd1498Szrj 
67*38fd1498Szrj   /* The successor block of the loop.  This is the one the loop_end insn
68*38fd1498Szrj      falls into.  */
69*38fd1498Szrj   basic_block successor;
70*38fd1498Szrj 
71*38fd1498Szrj   /* The last instruction in the tail.  */
72*38fd1498Szrj   rtx_insn *last_insn;
73*38fd1498Szrj 
74*38fd1498Szrj   /* The loop_end insn.  */
75*38fd1498Szrj   rtx_insn *loop_end;
76*38fd1498Szrj 
77*38fd1498Szrj   /* The iteration register.  */
78*38fd1498Szrj   rtx iter_reg;
79*38fd1498Szrj 
80*38fd1498Szrj   /* The new label placed at the beginning of the loop. */
81*38fd1498Szrj   rtx_insn *start_label;
82*38fd1498Szrj 
83*38fd1498Szrj   /* The new label placed at the end of the loop. */
84*38fd1498Szrj   rtx end_label;
85*38fd1498Szrj 
86*38fd1498Szrj   /* The length of the loop.  */
87*38fd1498Szrj   int length;
88*38fd1498Szrj 
89*38fd1498Szrj   /* The nesting depth of the loop.  Innermost loops are given a depth
90*38fd1498Szrj      of 1.  Only successfully optimized doloops are counted; if an inner
91*38fd1498Szrj      loop was marked as bad, it does not increase the depth of its parent
92*38fd1498Szrj      loop.
93*38fd1498Szrj      This value is valid when the target's optimize function is called.  */
94*38fd1498Szrj   int depth;
95*38fd1498Szrj 
96*38fd1498Szrj   /* True if we can't optimize this loop.  */
97*38fd1498Szrj   bool bad;
98*38fd1498Szrj 
99*38fd1498Szrj   /* True if we have visited this loop during the optimization phase.  */
100*38fd1498Szrj   bool visited;
101*38fd1498Szrj 
102*38fd1498Szrj   /* The following values are collected before calling the target's optimize
103*38fd1498Szrj      function and are not valid earlier.  */
104*38fd1498Szrj 
105*38fd1498Szrj   /* Record information about control flow: whether the loop has calls
106*38fd1498Szrj      or asm statements, whether it has edges that jump out of the loop,
107*38fd1498Szrj      or edges that jump within the loop.  */
108*38fd1498Szrj   bool has_call;
109*38fd1498Szrj   bool has_asm;
110*38fd1498Szrj   bool jumps_within;
111*38fd1498Szrj   bool jumps_outof;
112*38fd1498Szrj 
113*38fd1498Szrj   /* True if there is an instruction other than the doloop_end which uses the
114*38fd1498Szrj      iteration register.  */
115*38fd1498Szrj   bool iter_reg_used;
116*38fd1498Szrj   /* True if the iteration register lives past the doloop instruction.  */
117*38fd1498Szrj   bool iter_reg_used_outside;
118*38fd1498Szrj 
119*38fd1498Szrj   /* Hard registers set at any point in the loop, except for the loop counter
120*38fd1498Szrj      register's set in the doloop_end instruction.  */
121*38fd1498Szrj   HARD_REG_SET regs_set_in_loop;
122*38fd1498Szrj };
123*38fd1498Szrj 
124*38fd1498Szrj /* A set of hooks to be defined by a target that wants to use the reorg_loops
125*38fd1498Szrj    functionality.
126*38fd1498Szrj 
127*38fd1498Szrj    reorg_loops is intended to handle cases where special hardware loop
128*38fd1498Szrj    setup instructions are required before the loop, for example to set
129*38fd1498Szrj    up loop counter registers that are not exposed to the register
130*38fd1498Szrj    allocator, or to inform the hardware about loop bounds.
131*38fd1498Szrj 
132*38fd1498Szrj    reorg_loops performs analysis to discover loop_end patterns created
133*38fd1498Szrj    by the earlier loop-doloop pass, and sets up a hwloop_info
134*38fd1498Szrj    structure for each such insn it finds.  It then tries to discover
135*38fd1498Szrj    the basic blocks containing the loop by tracking the lifetime of
136*38fd1498Szrj    the iteration register.
137*38fd1498Szrj 
138*38fd1498Szrj    If a valid loop can't be found, the FAIL function is called;
139*38fd1498Szrj    otherwise the OPT function is called for each loop, visiting
140*38fd1498Szrj    innermost loops first and ascending.  */
141*38fd1498Szrj struct hw_doloop_hooks
142*38fd1498Szrj {
143*38fd1498Szrj   /* Examine INSN.  If it is a suitable doloop_end pattern, return the
144*38fd1498Szrj      iteration register, which should be a single hard register.
145*38fd1498Szrj      Otherwise, return NULL_RTX.  */
146*38fd1498Szrj   rtx (*end_pattern_reg) (rtx_insn *insn);
147*38fd1498Szrj   /* Optimize LOOP.  The target should perform any additional analysis
148*38fd1498Szrj      (e.g. checking that the loop isn't too long), and then perform
149*38fd1498Szrj      its transformations.  Return true if successful, false if the
150*38fd1498Szrj      loop should be marked bad.  If it returns false, the FAIL
151*38fd1498Szrj      function is called.  */
152*38fd1498Szrj   bool (*opt) (hwloop_info loop);
153*38fd1498Szrj   /* Handle a loop that was marked bad for any reason.  This could be
154*38fd1498Szrj      used to split the doloop_end pattern.  */
155*38fd1498Szrj   void (*fail) (hwloop_info loop);
156*38fd1498Szrj };
157*38fd1498Szrj 
158*38fd1498Szrj extern void reorg_loops (bool, struct hw_doloop_hooks *);
159*38fd1498Szrj 
160*38fd1498Szrj #endif /* GCC_HW_DOLOOP_H */
161