annotate gcc/loop-init.c @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1 /* Loop optimizer initialization routines and RTL loop optimization passes.
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2 Copyright (C) 2002-2020 Free Software Foundation, Inc.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
4 This file is part of GCC.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
5
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
6 GCC is free software; you can redistribute it and/or modify it under
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
7 the terms of the GNU General Public License as published by the Free
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
8 Software Foundation; either version 3, or (at your option) any later
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 version.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
10
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
14 for more details.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
15
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
16 You should have received a copy of the GNU General Public License
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
17 along with GCC; see the file COPYING3. If not see
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
18 <http://www.gnu.org/licenses/>. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
19
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
20 #include "config.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
21 #include "system.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
22 #include "coretypes.h"
111
kono
parents: 67
diff changeset
23 #include "backend.h"
kono
parents: 67
diff changeset
24 #include "target.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
25 #include "rtl.h"
111
kono
parents: 67
diff changeset
26 #include "tree.h"
kono
parents: 67
diff changeset
27 #include "cfghooks.h"
kono
parents: 67
diff changeset
28 #include "df.h"
kono
parents: 67
diff changeset
29 #include "regs.h"
kono
parents: 67
diff changeset
30 #include "cfgcleanup.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
31 #include "cfgloop.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
32 #include "tree-pass.h"
111
kono
parents: 67
diff changeset
33 #include "tree-ssa-loop-niter.h"
kono
parents: 67
diff changeset
34 #include "loop-unroll.h"
kono
parents: 67
diff changeset
35 #include "tree-scalar-evolution.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
36
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
37
111
kono
parents: 67
diff changeset
38 /* Apply FLAGS to the loop state. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
39
111
kono
parents: 67
diff changeset
40 static void
kono
parents: 67
diff changeset
41 apply_loop_flags (unsigned flags)
kono
parents: 67
diff changeset
42 {
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
43 if (flags & LOOPS_MAY_HAVE_MULTIPLE_LATCHES)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
44 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
45 /* If the loops may have multiple latches, we cannot canonicalize
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
46 them further (and most of the loop manipulation functions will
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
47 not work). However, we avoid modifying cfg, which some
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
48 passes may want. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
49 gcc_assert ((flags & ~(LOOPS_MAY_HAVE_MULTIPLE_LATCHES
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
50 | LOOPS_HAVE_RECORDED_EXITS)) == 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
51 loops_state_set (LOOPS_MAY_HAVE_MULTIPLE_LATCHES);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
52 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
53 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
54 disambiguate_loops_with_multiple_latches ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
55
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
56 /* Create pre-headers. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
57 if (flags & LOOPS_HAVE_PREHEADERS)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
58 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
59 int cp_flags = CP_SIMPLE_PREHEADERS;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
60
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
61 if (flags & LOOPS_HAVE_FALLTHRU_PREHEADERS)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
62 cp_flags |= CP_FALLTHRU_PREHEADERS;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
63
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
64 create_preheaders (cp_flags);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
65 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
66
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
67 /* Force all latches to have only single successor. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
68 if (flags & LOOPS_HAVE_SIMPLE_LATCHES)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
69 force_single_succ_latches ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
70
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
71 /* Mark irreducible loops. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
72 if (flags & LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
73 mark_irreducible_loops ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
74
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
75 if (flags & LOOPS_HAVE_RECORDED_EXITS)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
76 record_loop_exits ();
111
kono
parents: 67
diff changeset
77 }
kono
parents: 67
diff changeset
78
kono
parents: 67
diff changeset
79 /* Initialize loop structures. This is used by the tree and RTL loop
kono
parents: 67
diff changeset
80 optimizers. FLAGS specify what properties to compute and/or ensure for
kono
parents: 67
diff changeset
81 loops. */
kono
parents: 67
diff changeset
82
kono
parents: 67
diff changeset
83 void
kono
parents: 67
diff changeset
84 loop_optimizer_init (unsigned flags)
kono
parents: 67
diff changeset
85 {
kono
parents: 67
diff changeset
86 timevar_push (TV_LOOP_INIT);
kono
parents: 67
diff changeset
87
kono
parents: 67
diff changeset
88 if (!current_loops)
kono
parents: 67
diff changeset
89 {
kono
parents: 67
diff changeset
90 gcc_assert (!(cfun->curr_properties & PROP_loops));
kono
parents: 67
diff changeset
91
kono
parents: 67
diff changeset
92 /* Find the loops. */
kono
parents: 67
diff changeset
93 current_loops = flow_loops_find (NULL);
kono
parents: 67
diff changeset
94 }
kono
parents: 67
diff changeset
95 else
kono
parents: 67
diff changeset
96 {
kono
parents: 67
diff changeset
97 bool recorded_exits = loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS);
kono
parents: 67
diff changeset
98 bool needs_fixup = loops_state_satisfies_p (LOOPS_NEED_FIXUP);
kono
parents: 67
diff changeset
99
kono
parents: 67
diff changeset
100 gcc_assert (cfun->curr_properties & PROP_loops);
kono
parents: 67
diff changeset
101
kono
parents: 67
diff changeset
102 /* Ensure that the dominators are computed, like flow_loops_find does. */
kono
parents: 67
diff changeset
103 calculate_dominance_info (CDI_DOMINATORS);
kono
parents: 67
diff changeset
104
kono
parents: 67
diff changeset
105 if (!needs_fixup)
kono
parents: 67
diff changeset
106 checking_verify_loop_structure ();
kono
parents: 67
diff changeset
107
kono
parents: 67
diff changeset
108 /* Clear all flags. */
kono
parents: 67
diff changeset
109 if (recorded_exits)
kono
parents: 67
diff changeset
110 release_recorded_exits (cfun);
kono
parents: 67
diff changeset
111 loops_state_clear (~0U);
kono
parents: 67
diff changeset
112
kono
parents: 67
diff changeset
113 if (needs_fixup)
kono
parents: 67
diff changeset
114 {
kono
parents: 67
diff changeset
115 /* Apply LOOPS_MAY_HAVE_MULTIPLE_LATCHES early as fix_loop_structure
kono
parents: 67
diff changeset
116 re-applies flags. */
kono
parents: 67
diff changeset
117 loops_state_set (flags & LOOPS_MAY_HAVE_MULTIPLE_LATCHES);
kono
parents: 67
diff changeset
118 fix_loop_structure (NULL);
kono
parents: 67
diff changeset
119 }
kono
parents: 67
diff changeset
120 }
kono
parents: 67
diff changeset
121
kono
parents: 67
diff changeset
122 /* Apply flags to loops. */
kono
parents: 67
diff changeset
123 apply_loop_flags (flags);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
124
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
125 /* Dump loops. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
126 flow_loops_dump (dump_file, NULL, 1);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
127
111
kono
parents: 67
diff changeset
128 checking_verify_loop_structure ();
kono
parents: 67
diff changeset
129
kono
parents: 67
diff changeset
130 timevar_pop (TV_LOOP_INIT);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
131 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
132
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
133 /* Finalize loop structures. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
134
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
135 void
111
kono
parents: 67
diff changeset
136 loop_optimizer_finalize (struct function *fn)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
137 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
138 class loop *loop;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
139 basic_block bb;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
140
111
kono
parents: 67
diff changeset
141 timevar_push (TV_LOOP_FINI);
kono
parents: 67
diff changeset
142
kono
parents: 67
diff changeset
143 if (loops_state_satisfies_p (fn, LOOPS_HAVE_RECORDED_EXITS))
kono
parents: 67
diff changeset
144 release_recorded_exits (fn);
kono
parents: 67
diff changeset
145
kono
parents: 67
diff changeset
146 free_numbers_of_iterations_estimates (fn);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
147
111
kono
parents: 67
diff changeset
148 /* If we should preserve loop structure, do not free it but clear
kono
parents: 67
diff changeset
149 flags that advanced properties are there as we are not preserving
kono
parents: 67
diff changeset
150 that in full. */
kono
parents: 67
diff changeset
151 if (fn->curr_properties & PROP_loops)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
152 {
111
kono
parents: 67
diff changeset
153 loops_state_clear (fn, LOOP_CLOSED_SSA
kono
parents: 67
diff changeset
154 | LOOPS_HAVE_MARKED_IRREDUCIBLE_REGIONS
kono
parents: 67
diff changeset
155 | LOOPS_HAVE_PREHEADERS
kono
parents: 67
diff changeset
156 | LOOPS_HAVE_SIMPLE_LATCHES
kono
parents: 67
diff changeset
157 | LOOPS_HAVE_FALLTHRU_PREHEADERS);
kono
parents: 67
diff changeset
158 loops_state_set (fn, LOOPS_MAY_HAVE_MULTIPLE_LATCHES);
kono
parents: 67
diff changeset
159 goto loop_fini_done;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
160 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
161
111
kono
parents: 67
diff changeset
162 FOR_EACH_LOOP_FN (fn, loop, 0)
kono
parents: 67
diff changeset
163 free_simple_loop_desc (loop);
kono
parents: 67
diff changeset
164
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
165 /* Clean up. */
111
kono
parents: 67
diff changeset
166 flow_loops_free (loops_for_fn (fn));
kono
parents: 67
diff changeset
167 ggc_free (loops_for_fn (fn));
kono
parents: 67
diff changeset
168 set_loops_for_fn (fn, NULL);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
169
111
kono
parents: 67
diff changeset
170 FOR_ALL_BB_FN (bb, fn)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
171 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
172 bb->loop_father = NULL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
173 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
174
111
kono
parents: 67
diff changeset
175 loop_fini_done:
kono
parents: 67
diff changeset
176 timevar_pop (TV_LOOP_FINI);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
177 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
178
111
kono
parents: 67
diff changeset
179 /* The structure of loops might have changed. Some loops might get removed
kono
parents: 67
diff changeset
180 (and their headers and latches were set to NULL), loop exists might get
kono
parents: 67
diff changeset
181 removed (thus the loop nesting may be wrong), and some blocks and edges
kono
parents: 67
diff changeset
182 were changed (so the information about bb --> loop mapping does not have
kono
parents: 67
diff changeset
183 to be correct). But still for the remaining loops the header dominates
kono
parents: 67
diff changeset
184 the latch, and loops did not get new subloops (new loops might possibly
kono
parents: 67
diff changeset
185 get created, but we are not interested in them). Fix up the mess.
kono
parents: 67
diff changeset
186
kono
parents: 67
diff changeset
187 If CHANGED_BBS is not NULL, basic blocks whose loop depth has changed are
kono
parents: 67
diff changeset
188 marked in it.
kono
parents: 67
diff changeset
189
kono
parents: 67
diff changeset
190 Returns the number of new discovered loops. */
kono
parents: 67
diff changeset
191
kono
parents: 67
diff changeset
192 unsigned
kono
parents: 67
diff changeset
193 fix_loop_structure (bitmap changed_bbs)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
194 {
111
kono
parents: 67
diff changeset
195 basic_block bb;
kono
parents: 67
diff changeset
196 int record_exits = 0;
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
197 class loop *loop;
111
kono
parents: 67
diff changeset
198 unsigned old_nloops, i;
kono
parents: 67
diff changeset
199
kono
parents: 67
diff changeset
200 timevar_push (TV_LOOP_INIT);
kono
parents: 67
diff changeset
201
kono
parents: 67
diff changeset
202 if (dump_file && (dump_flags & TDF_DETAILS))
kono
parents: 67
diff changeset
203 fprintf (dump_file, "fix_loop_structure: fixing up loops for function\n");
kono
parents: 67
diff changeset
204
kono
parents: 67
diff changeset
205 /* We need exact and fast dominance info to be available. */
kono
parents: 67
diff changeset
206 gcc_assert (dom_info_state (CDI_DOMINATORS) == DOM_OK);
kono
parents: 67
diff changeset
207
kono
parents: 67
diff changeset
208 if (loops_state_satisfies_p (LOOPS_HAVE_RECORDED_EXITS))
kono
parents: 67
diff changeset
209 {
kono
parents: 67
diff changeset
210 release_recorded_exits (cfun);
kono
parents: 67
diff changeset
211 record_exits = LOOPS_HAVE_RECORDED_EXITS;
kono
parents: 67
diff changeset
212 }
kono
parents: 67
diff changeset
213
kono
parents: 67
diff changeset
214 /* Remember the depth of the blocks in the loop hierarchy, so that we can
kono
parents: 67
diff changeset
215 recognize blocks whose loop nesting relationship has changed. */
kono
parents: 67
diff changeset
216 if (changed_bbs)
kono
parents: 67
diff changeset
217 FOR_EACH_BB_FN (bb, cfun)
kono
parents: 67
diff changeset
218 bb->aux = (void *) (size_t) loop_depth (bb->loop_father);
kono
parents: 67
diff changeset
219
kono
parents: 67
diff changeset
220 /* Remove the dead loops from structures. We start from the innermost
kono
parents: 67
diff changeset
221 loops, so that when we remove the loops, we know that the loops inside
kono
parents: 67
diff changeset
222 are preserved, and do not waste time relinking loops that will be
kono
parents: 67
diff changeset
223 removed later. */
kono
parents: 67
diff changeset
224 FOR_EACH_LOOP (loop, LI_FROM_INNERMOST)
kono
parents: 67
diff changeset
225 {
kono
parents: 67
diff changeset
226 /* Detect the case that the loop is no longer present even though
kono
parents: 67
diff changeset
227 it wasn't marked for removal.
kono
parents: 67
diff changeset
228 ??? If we do that we can get away with not marking loops for
kono
parents: 67
diff changeset
229 removal at all. And possibly avoid some spurious removals. */
kono
parents: 67
diff changeset
230 if (loop->header
kono
parents: 67
diff changeset
231 && bb_loop_header_p (loop->header))
kono
parents: 67
diff changeset
232 continue;
kono
parents: 67
diff changeset
233
kono
parents: 67
diff changeset
234 if (dump_file && (dump_flags & TDF_DETAILS))
kono
parents: 67
diff changeset
235 fprintf (dump_file, "fix_loop_structure: removing loop %d\n",
kono
parents: 67
diff changeset
236 loop->num);
kono
parents: 67
diff changeset
237
kono
parents: 67
diff changeset
238 while (loop->inner)
kono
parents: 67
diff changeset
239 {
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
240 class loop *ploop = loop->inner;
111
kono
parents: 67
diff changeset
241 flow_loop_tree_node_remove (ploop);
kono
parents: 67
diff changeset
242 flow_loop_tree_node_add (loop_outer (loop), ploop);
kono
parents: 67
diff changeset
243 }
kono
parents: 67
diff changeset
244
kono
parents: 67
diff changeset
245 /* Remove the loop. */
kono
parents: 67
diff changeset
246 if (loop->header)
kono
parents: 67
diff changeset
247 loop->former_header = loop->header;
kono
parents: 67
diff changeset
248 else
kono
parents: 67
diff changeset
249 gcc_assert (loop->former_header != NULL);
kono
parents: 67
diff changeset
250 loop->header = NULL;
kono
parents: 67
diff changeset
251 flow_loop_tree_node_remove (loop);
kono
parents: 67
diff changeset
252 }
kono
parents: 67
diff changeset
253
kono
parents: 67
diff changeset
254 /* Remember the number of loops so we can return how many new loops
kono
parents: 67
diff changeset
255 flow_loops_find discovered. */
kono
parents: 67
diff changeset
256 old_nloops = number_of_loops (cfun);
kono
parents: 67
diff changeset
257
kono
parents: 67
diff changeset
258 /* Re-compute loop structure in-place. */
kono
parents: 67
diff changeset
259 flow_loops_find (current_loops);
kono
parents: 67
diff changeset
260
kono
parents: 67
diff changeset
261 /* Mark the blocks whose loop has changed. */
kono
parents: 67
diff changeset
262 if (changed_bbs)
kono
parents: 67
diff changeset
263 {
kono
parents: 67
diff changeset
264 FOR_EACH_BB_FN (bb, cfun)
kono
parents: 67
diff changeset
265 {
kono
parents: 67
diff changeset
266 if ((void *) (size_t) loop_depth (bb->loop_father) != bb->aux)
kono
parents: 67
diff changeset
267 bitmap_set_bit (changed_bbs, bb->index);
kono
parents: 67
diff changeset
268
kono
parents: 67
diff changeset
269 bb->aux = NULL;
kono
parents: 67
diff changeset
270 }
kono
parents: 67
diff changeset
271 }
kono
parents: 67
diff changeset
272
kono
parents: 67
diff changeset
273 /* Finally free deleted loops. */
kono
parents: 67
diff changeset
274 bool any_deleted = false;
kono
parents: 67
diff changeset
275 FOR_EACH_VEC_ELT (*get_loops (cfun), i, loop)
kono
parents: 67
diff changeset
276 if (loop && loop->header == NULL)
kono
parents: 67
diff changeset
277 {
kono
parents: 67
diff changeset
278 if (dump_file
kono
parents: 67
diff changeset
279 && ((unsigned) loop->former_header->index
kono
parents: 67
diff changeset
280 < basic_block_info_for_fn (cfun)->length ()))
kono
parents: 67
diff changeset
281 {
kono
parents: 67
diff changeset
282 basic_block former_header
kono
parents: 67
diff changeset
283 = BASIC_BLOCK_FOR_FN (cfun, loop->former_header->index);
kono
parents: 67
diff changeset
284 /* If the old header still exists we want to check if the
kono
parents: 67
diff changeset
285 original loop is re-discovered or the old header is now
kono
parents: 67
diff changeset
286 part of a newly discovered loop.
kono
parents: 67
diff changeset
287 In both cases we should have avoided removing the loop. */
kono
parents: 67
diff changeset
288 if (former_header == loop->former_header)
kono
parents: 67
diff changeset
289 {
kono
parents: 67
diff changeset
290 if (former_header->loop_father->header == former_header)
kono
parents: 67
diff changeset
291 fprintf (dump_file, "fix_loop_structure: rediscovered "
kono
parents: 67
diff changeset
292 "removed loop %d as loop %d with old header %d\n",
kono
parents: 67
diff changeset
293 loop->num, former_header->loop_father->num,
kono
parents: 67
diff changeset
294 former_header->index);
kono
parents: 67
diff changeset
295 else if ((unsigned) former_header->loop_father->num
kono
parents: 67
diff changeset
296 >= old_nloops)
kono
parents: 67
diff changeset
297 fprintf (dump_file, "fix_loop_structure: header %d of "
kono
parents: 67
diff changeset
298 "removed loop %d is part of the newly "
kono
parents: 67
diff changeset
299 "discovered loop %d with header %d\n",
kono
parents: 67
diff changeset
300 former_header->index, loop->num,
kono
parents: 67
diff changeset
301 former_header->loop_father->num,
kono
parents: 67
diff changeset
302 former_header->loop_father->header->index);
kono
parents: 67
diff changeset
303 }
kono
parents: 67
diff changeset
304 }
kono
parents: 67
diff changeset
305 (*get_loops (cfun))[i] = NULL;
kono
parents: 67
diff changeset
306 flow_loop_free (loop);
kono
parents: 67
diff changeset
307 any_deleted = true;
kono
parents: 67
diff changeset
308 }
kono
parents: 67
diff changeset
309
kono
parents: 67
diff changeset
310 /* If we deleted loops then the cached scalar evolutions refering to
kono
parents: 67
diff changeset
311 those loops become invalid. */
kono
parents: 67
diff changeset
312 if (any_deleted && scev_initialized_p ())
kono
parents: 67
diff changeset
313 scev_reset_htab ();
kono
parents: 67
diff changeset
314
kono
parents: 67
diff changeset
315 loops_state_clear (LOOPS_NEED_FIXUP);
kono
parents: 67
diff changeset
316
kono
parents: 67
diff changeset
317 /* Apply flags to loops. */
kono
parents: 67
diff changeset
318 apply_loop_flags (current_loops->state | record_exits);
kono
parents: 67
diff changeset
319
kono
parents: 67
diff changeset
320 checking_verify_loop_structure ();
kono
parents: 67
diff changeset
321
kono
parents: 67
diff changeset
322 timevar_pop (TV_LOOP_INIT);
kono
parents: 67
diff changeset
323
kono
parents: 67
diff changeset
324 return number_of_loops (cfun) - old_nloops;
kono
parents: 67
diff changeset
325 }
kono
parents: 67
diff changeset
326
kono
parents: 67
diff changeset
327 /* The RTL loop superpass. The actual passes are subpasses. See passes.c for
kono
parents: 67
diff changeset
328 more on that. */
kono
parents: 67
diff changeset
329
kono
parents: 67
diff changeset
330 namespace {
kono
parents: 67
diff changeset
331
kono
parents: 67
diff changeset
332 const pass_data pass_data_loop2 =
kono
parents: 67
diff changeset
333 {
kono
parents: 67
diff changeset
334 RTL_PASS, /* type */
kono
parents: 67
diff changeset
335 "loop2", /* name */
kono
parents: 67
diff changeset
336 OPTGROUP_LOOP, /* optinfo_flags */
kono
parents: 67
diff changeset
337 TV_LOOP, /* tv_id */
kono
parents: 67
diff changeset
338 0, /* properties_required */
kono
parents: 67
diff changeset
339 0, /* properties_provided */
kono
parents: 67
diff changeset
340 0, /* properties_destroyed */
kono
parents: 67
diff changeset
341 0, /* todo_flags_start */
kono
parents: 67
diff changeset
342 0, /* todo_flags_finish */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
343 };
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
344
111
kono
parents: 67
diff changeset
345 class pass_loop2 : public rtl_opt_pass
kono
parents: 67
diff changeset
346 {
kono
parents: 67
diff changeset
347 public:
kono
parents: 67
diff changeset
348 pass_loop2 (gcc::context *ctxt)
kono
parents: 67
diff changeset
349 : rtl_opt_pass (pass_data_loop2, ctxt)
kono
parents: 67
diff changeset
350 {}
kono
parents: 67
diff changeset
351
kono
parents: 67
diff changeset
352 /* opt_pass methods: */
kono
parents: 67
diff changeset
353 virtual bool gate (function *);
kono
parents: 67
diff changeset
354
kono
parents: 67
diff changeset
355 }; // class pass_loop2
kono
parents: 67
diff changeset
356
kono
parents: 67
diff changeset
357 bool
kono
parents: 67
diff changeset
358 pass_loop2::gate (function *fun)
kono
parents: 67
diff changeset
359 {
kono
parents: 67
diff changeset
360 if (optimize > 0
kono
parents: 67
diff changeset
361 && (flag_move_loop_invariants
kono
parents: 67
diff changeset
362 || flag_unswitch_loops
kono
parents: 67
diff changeset
363 || flag_unroll_loops
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
364 || (flag_branch_on_count_reg && targetm.have_doloop_end ())
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
365 || cfun->has_unroll))
111
kono
parents: 67
diff changeset
366 return true;
kono
parents: 67
diff changeset
367 else
kono
parents: 67
diff changeset
368 {
kono
parents: 67
diff changeset
369 /* No longer preserve loops, remove them now. */
kono
parents: 67
diff changeset
370 fun->curr_properties &= ~PROP_loops;
kono
parents: 67
diff changeset
371 if (current_loops)
kono
parents: 67
diff changeset
372 loop_optimizer_finalize ();
kono
parents: 67
diff changeset
373 return false;
kono
parents: 67
diff changeset
374 }
kono
parents: 67
diff changeset
375 }
kono
parents: 67
diff changeset
376
kono
parents: 67
diff changeset
377 } // anon namespace
kono
parents: 67
diff changeset
378
kono
parents: 67
diff changeset
379 rtl_opt_pass *
kono
parents: 67
diff changeset
380 make_pass_loop2 (gcc::context *ctxt)
kono
parents: 67
diff changeset
381 {
kono
parents: 67
diff changeset
382 return new pass_loop2 (ctxt);
kono
parents: 67
diff changeset
383 }
kono
parents: 67
diff changeset
384
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
385
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
386 /* Initialization of the RTL loop passes. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
387 static unsigned int
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
388 rtl_loop_init (void)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
389 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
390 gcc_assert (current_ir_type () == IR_RTL_CFGLAYOUT);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
391
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
392 if (dump_file)
111
kono
parents: 67
diff changeset
393 {
kono
parents: 67
diff changeset
394 dump_reg_info (dump_file);
kono
parents: 67
diff changeset
395 dump_flow_info (dump_file, dump_flags);
kono
parents: 67
diff changeset
396 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
397
111
kono
parents: 67
diff changeset
398 loop_optimizer_init (LOOPS_NORMAL | LOOPS_HAVE_RECORDED_EXITS);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
399 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
400 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
401
111
kono
parents: 67
diff changeset
402 namespace {
kono
parents: 67
diff changeset
403
kono
parents: 67
diff changeset
404 const pass_data pass_data_rtl_loop_init =
kono
parents: 67
diff changeset
405 {
kono
parents: 67
diff changeset
406 RTL_PASS, /* type */
kono
parents: 67
diff changeset
407 "loop2_init", /* name */
kono
parents: 67
diff changeset
408 OPTGROUP_LOOP, /* optinfo_flags */
kono
parents: 67
diff changeset
409 TV_LOOP, /* tv_id */
kono
parents: 67
diff changeset
410 0, /* properties_required */
kono
parents: 67
diff changeset
411 0, /* properties_provided */
kono
parents: 67
diff changeset
412 0, /* properties_destroyed */
kono
parents: 67
diff changeset
413 0, /* todo_flags_start */
kono
parents: 67
diff changeset
414 0, /* todo_flags_finish */
kono
parents: 67
diff changeset
415 };
kono
parents: 67
diff changeset
416
kono
parents: 67
diff changeset
417 class pass_rtl_loop_init : public rtl_opt_pass
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
418 {
111
kono
parents: 67
diff changeset
419 public:
kono
parents: 67
diff changeset
420 pass_rtl_loop_init (gcc::context *ctxt)
kono
parents: 67
diff changeset
421 : rtl_opt_pass (pass_data_rtl_loop_init, ctxt)
kono
parents: 67
diff changeset
422 {}
kono
parents: 67
diff changeset
423
kono
parents: 67
diff changeset
424 /* opt_pass methods: */
kono
parents: 67
diff changeset
425 virtual unsigned int execute (function *) { return rtl_loop_init (); }
kono
parents: 67
diff changeset
426
kono
parents: 67
diff changeset
427 }; // class pass_rtl_loop_init
kono
parents: 67
diff changeset
428
kono
parents: 67
diff changeset
429 } // anon namespace
kono
parents: 67
diff changeset
430
kono
parents: 67
diff changeset
431 rtl_opt_pass *
kono
parents: 67
diff changeset
432 make_pass_rtl_loop_init (gcc::context *ctxt)
kono
parents: 67
diff changeset
433 {
kono
parents: 67
diff changeset
434 return new pass_rtl_loop_init (ctxt);
kono
parents: 67
diff changeset
435 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
436
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
437
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
438 /* Finalization of the RTL loop passes. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
439
111
kono
parents: 67
diff changeset
440 namespace {
kono
parents: 67
diff changeset
441
kono
parents: 67
diff changeset
442 const pass_data pass_data_rtl_loop_done =
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
443 {
111
kono
parents: 67
diff changeset
444 RTL_PASS, /* type */
kono
parents: 67
diff changeset
445 "loop2_done", /* name */
kono
parents: 67
diff changeset
446 OPTGROUP_LOOP, /* optinfo_flags */
kono
parents: 67
diff changeset
447 TV_LOOP, /* tv_id */
kono
parents: 67
diff changeset
448 0, /* properties_required */
kono
parents: 67
diff changeset
449 0, /* properties_provided */
kono
parents: 67
diff changeset
450 PROP_loops, /* properties_destroyed */
kono
parents: 67
diff changeset
451 0, /* todo_flags_start */
kono
parents: 67
diff changeset
452 0, /* todo_flags_finish */
kono
parents: 67
diff changeset
453 };
kono
parents: 67
diff changeset
454
kono
parents: 67
diff changeset
455 class pass_rtl_loop_done : public rtl_opt_pass
kono
parents: 67
diff changeset
456 {
kono
parents: 67
diff changeset
457 public:
kono
parents: 67
diff changeset
458 pass_rtl_loop_done (gcc::context *ctxt)
kono
parents: 67
diff changeset
459 : rtl_opt_pass (pass_data_rtl_loop_done, ctxt)
kono
parents: 67
diff changeset
460 {}
kono
parents: 67
diff changeset
461
kono
parents: 67
diff changeset
462 /* opt_pass methods: */
kono
parents: 67
diff changeset
463 virtual unsigned int execute (function *);
kono
parents: 67
diff changeset
464
kono
parents: 67
diff changeset
465 }; // class pass_rtl_loop_done
kono
parents: 67
diff changeset
466
kono
parents: 67
diff changeset
467 unsigned int
kono
parents: 67
diff changeset
468 pass_rtl_loop_done::execute (function *fun)
kono
parents: 67
diff changeset
469 {
kono
parents: 67
diff changeset
470 /* No longer preserve loops, remove them now. */
kono
parents: 67
diff changeset
471 fun->curr_properties &= ~PROP_loops;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
472 loop_optimizer_finalize ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
473 free_dominance_info (CDI_DOMINATORS);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
474
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
475 cleanup_cfg (0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
476 if (dump_file)
111
kono
parents: 67
diff changeset
477 {
kono
parents: 67
diff changeset
478 dump_reg_info (dump_file);
kono
parents: 67
diff changeset
479 dump_flow_info (dump_file, dump_flags);
kono
parents: 67
diff changeset
480 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
481
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
482 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
483 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
484
111
kono
parents: 67
diff changeset
485 } // anon namespace
kono
parents: 67
diff changeset
486
kono
parents: 67
diff changeset
487 rtl_opt_pass *
kono
parents: 67
diff changeset
488 make_pass_rtl_loop_done (gcc::context *ctxt)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
489 {
111
kono
parents: 67
diff changeset
490 return new pass_rtl_loop_done (ctxt);
kono
parents: 67
diff changeset
491 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
492
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
493
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
494 /* Loop invariant code motion. */
111
kono
parents: 67
diff changeset
495
kono
parents: 67
diff changeset
496 namespace {
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
497
111
kono
parents: 67
diff changeset
498 const pass_data pass_data_rtl_move_loop_invariants =
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
499 {
111
kono
parents: 67
diff changeset
500 RTL_PASS, /* type */
kono
parents: 67
diff changeset
501 "loop2_invariant", /* name */
kono
parents: 67
diff changeset
502 OPTGROUP_LOOP, /* optinfo_flags */
kono
parents: 67
diff changeset
503 TV_LOOP_MOVE_INVARIANTS, /* tv_id */
kono
parents: 67
diff changeset
504 0, /* properties_required */
kono
parents: 67
diff changeset
505 0, /* properties_provided */
kono
parents: 67
diff changeset
506 0, /* properties_destroyed */
kono
parents: 67
diff changeset
507 0, /* todo_flags_start */
kono
parents: 67
diff changeset
508 ( TODO_df_verify | TODO_df_finish ), /* todo_flags_finish */
kono
parents: 67
diff changeset
509 };
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
510
111
kono
parents: 67
diff changeset
511 class pass_rtl_move_loop_invariants : public rtl_opt_pass
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
512 {
111
kono
parents: 67
diff changeset
513 public:
kono
parents: 67
diff changeset
514 pass_rtl_move_loop_invariants (gcc::context *ctxt)
kono
parents: 67
diff changeset
515 : rtl_opt_pass (pass_data_rtl_move_loop_invariants, ctxt)
kono
parents: 67
diff changeset
516 {}
kono
parents: 67
diff changeset
517
kono
parents: 67
diff changeset
518 /* opt_pass methods: */
kono
parents: 67
diff changeset
519 virtual bool gate (function *) { return flag_move_loop_invariants; }
kono
parents: 67
diff changeset
520 virtual unsigned int execute (function *fun)
kono
parents: 67
diff changeset
521 {
kono
parents: 67
diff changeset
522 if (number_of_loops (fun) > 1)
kono
parents: 67
diff changeset
523 move_loop_invariants ();
kono
parents: 67
diff changeset
524 return 0;
kono
parents: 67
diff changeset
525 }
kono
parents: 67
diff changeset
526
kono
parents: 67
diff changeset
527 }; // class pass_rtl_move_loop_invariants
kono
parents: 67
diff changeset
528
kono
parents: 67
diff changeset
529 } // anon namespace
kono
parents: 67
diff changeset
530
kono
parents: 67
diff changeset
531 rtl_opt_pass *
kono
parents: 67
diff changeset
532 make_pass_rtl_move_loop_invariants (gcc::context *ctxt)
kono
parents: 67
diff changeset
533 {
kono
parents: 67
diff changeset
534 return new pass_rtl_move_loop_invariants (ctxt);
kono
parents: 67
diff changeset
535 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
536
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
537
111
kono
parents: 67
diff changeset
538 namespace {
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
539
111
kono
parents: 67
diff changeset
540 const pass_data pass_data_rtl_unroll_loops =
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
541 {
111
kono
parents: 67
diff changeset
542 RTL_PASS, /* type */
kono
parents: 67
diff changeset
543 "loop2_unroll", /* name */
kono
parents: 67
diff changeset
544 OPTGROUP_LOOP, /* optinfo_flags */
kono
parents: 67
diff changeset
545 TV_LOOP_UNROLL, /* tv_id */
kono
parents: 67
diff changeset
546 0, /* properties_required */
kono
parents: 67
diff changeset
547 0, /* properties_provided */
kono
parents: 67
diff changeset
548 0, /* properties_destroyed */
kono
parents: 67
diff changeset
549 0, /* todo_flags_start */
kono
parents: 67
diff changeset
550 0, /* todo_flags_finish */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
551 };
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
552
111
kono
parents: 67
diff changeset
553 class pass_rtl_unroll_loops : public rtl_opt_pass
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
554 {
111
kono
parents: 67
diff changeset
555 public:
kono
parents: 67
diff changeset
556 pass_rtl_unroll_loops (gcc::context *ctxt)
kono
parents: 67
diff changeset
557 : rtl_opt_pass (pass_data_rtl_unroll_loops, ctxt)
kono
parents: 67
diff changeset
558 {}
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
559
111
kono
parents: 67
diff changeset
560 /* opt_pass methods: */
kono
parents: 67
diff changeset
561 virtual bool gate (function *)
kono
parents: 67
diff changeset
562 {
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
563 return (flag_unroll_loops || flag_unroll_all_loops || cfun->has_unroll);
111
kono
parents: 67
diff changeset
564 }
kono
parents: 67
diff changeset
565
kono
parents: 67
diff changeset
566 virtual unsigned int execute (function *);
kono
parents: 67
diff changeset
567
kono
parents: 67
diff changeset
568 }; // class pass_rtl_unroll_loops
kono
parents: 67
diff changeset
569
kono
parents: 67
diff changeset
570 unsigned int
kono
parents: 67
diff changeset
571 pass_rtl_unroll_loops::execute (function *fun)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
572 {
111
kono
parents: 67
diff changeset
573 if (number_of_loops (fun) > 1)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
574 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
575 int flags = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
576 if (dump_file)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
577 df_dump (dump_file);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
578
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
579 if (flag_unroll_loops)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
580 flags |= UAP_UNROLL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
581 if (flag_unroll_all_loops)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
582 flags |= UAP_UNROLL_ALL;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
583
111
kono
parents: 67
diff changeset
584 unroll_loops (flags);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
585 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
586 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
587 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
588
111
kono
parents: 67
diff changeset
589 } // anon namespace
kono
parents: 67
diff changeset
590
kono
parents: 67
diff changeset
591 rtl_opt_pass *
kono
parents: 67
diff changeset
592 make_pass_rtl_unroll_loops (gcc::context *ctxt)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
593 {
111
kono
parents: 67
diff changeset
594 return new pass_rtl_unroll_loops (ctxt);
kono
parents: 67
diff changeset
595 }
kono
parents: 67
diff changeset
596
kono
parents: 67
diff changeset
597
kono
parents: 67
diff changeset
598 namespace {
kono
parents: 67
diff changeset
599
kono
parents: 67
diff changeset
600 const pass_data pass_data_rtl_doloop =
kono
parents: 67
diff changeset
601 {
kono
parents: 67
diff changeset
602 RTL_PASS, /* type */
kono
parents: 67
diff changeset
603 "loop2_doloop", /* name */
kono
parents: 67
diff changeset
604 OPTGROUP_LOOP, /* optinfo_flags */
kono
parents: 67
diff changeset
605 TV_LOOP_DOLOOP, /* tv_id */
kono
parents: 67
diff changeset
606 0, /* properties_required */
kono
parents: 67
diff changeset
607 0, /* properties_provided */
kono
parents: 67
diff changeset
608 0, /* properties_destroyed */
kono
parents: 67
diff changeset
609 0, /* todo_flags_start */
kono
parents: 67
diff changeset
610 0, /* todo_flags_finish */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
611 };
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
612
111
kono
parents: 67
diff changeset
613 class pass_rtl_doloop : public rtl_opt_pass
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
614 {
111
kono
parents: 67
diff changeset
615 public:
kono
parents: 67
diff changeset
616 pass_rtl_doloop (gcc::context *ctxt)
kono
parents: 67
diff changeset
617 : rtl_opt_pass (pass_data_rtl_doloop, ctxt)
kono
parents: 67
diff changeset
618 {}
kono
parents: 67
diff changeset
619
kono
parents: 67
diff changeset
620 /* opt_pass methods: */
kono
parents: 67
diff changeset
621 virtual bool gate (function *);
kono
parents: 67
diff changeset
622 virtual unsigned int execute (function *);
kono
parents: 67
diff changeset
623
kono
parents: 67
diff changeset
624 }; // class pass_rtl_doloop
kono
parents: 67
diff changeset
625
kono
parents: 67
diff changeset
626 bool
kono
parents: 67
diff changeset
627 pass_rtl_doloop::gate (function *)
kono
parents: 67
diff changeset
628 {
kono
parents: 67
diff changeset
629 return (flag_branch_on_count_reg && targetm.have_doloop_end ());
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
630 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
631
111
kono
parents: 67
diff changeset
632 unsigned int
kono
parents: 67
diff changeset
633 pass_rtl_doloop::execute (function *fun)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
634 {
111
kono
parents: 67
diff changeset
635 if (number_of_loops (fun) > 1)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
636 doloop_optimize_loops ();
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
637 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
638 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
639
111
kono
parents: 67
diff changeset
640 } // anon namespace
kono
parents: 67
diff changeset
641
kono
parents: 67
diff changeset
642 rtl_opt_pass *
kono
parents: 67
diff changeset
643 make_pass_rtl_doloop (gcc::context *ctxt)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
644 {
111
kono
parents: 67
diff changeset
645 return new pass_rtl_doloop (ctxt);
kono
parents: 67
diff changeset
646 }