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