]> gcc.gnu.org Git - gcc.git/blame - gcc/lcm.c
Makefile.in, [...]: replace "GNU CC" with "GCC".
[gcc.git] / gcc / lcm.c
CommitLineData
f4e72d6e 1/* Generic partial redundancy elimination with lazy code motion support.
6cd87539 2 Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
d2ecda27 3
1322177d 4This file is part of GCC.
d2ecda27 5
1322177d
LB
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
8Software Foundation; either version 2, or (at your option) any later
9version.
d2ecda27 10
1322177d
LB
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
d2ecda27
JL
15
16You should have received a copy of the GNU General Public License
1322177d
LB
17along with GCC; see the file COPYING. If not, write to the Free
18Software Foundation, 59 Temple Place - Suite 330, Boston, MA
1902111-1307, USA. */
d2ecda27
JL
20
21/* These routines are meant to be used by various optimization
b3bb6456 22 passes which can be modeled as lazy code motion problems.
d2ecda27
JL
23 Including, but not limited to:
24
25 * Traditional partial redundancy elimination.
26
27 * Placement of caller/caller register save/restores.
28
29 * Load/store motion.
30
31 * Copy motion.
32
33 * Conversion of flat register files to a stacked register
34 model.
35
36 * Dead load/store elimination.
37
38 These routines accept as input:
39
40 * Basic block information (number of blocks, lists of
41 predecessors and successors). Note the granularity
42 does not need to be basic block, they could be statements
43 or functions.
44
45 * Bitmaps of local properties (computed, transparent and
46 anticipatable expressions).
47
48 The output of these routines is bitmap of redundant computations
49 and a bitmap of optimal placement points. */
50
51
52#include "config.h"
53#include "system.h"
d2ecda27
JL
54#include "rtl.h"
55#include "regs.h"
56#include "hard-reg-set.h"
57#include "flags.h"
58#include "real.h"
59#include "insn-config.h"
60#include "recog.h"
61#include "basic-block.h"
9f09b1f2 62#include "tm_p.h"
f4e72d6e 63
9f09b1f2
R
64/* We want target macros for the mode switching code to be able to refer
65 to instruction attribute values. */
66#include "insn-attr.h"
d2ecda27 67
a42cd965 68/* Edge based LCM routines. */
f4e72d6e
RK
69static void compute_antinout_edge PARAMS ((sbitmap *, sbitmap *,
70 sbitmap *, sbitmap *));
71static void compute_earliest PARAMS ((struct edge_list *, int,
72 sbitmap *, sbitmap *,
73 sbitmap *, sbitmap *,
74 sbitmap *));
75static void compute_laterin PARAMS ((struct edge_list *, sbitmap *,
76 sbitmap *, sbitmap *,
77 sbitmap *));
78static void compute_insert_delete PARAMS ((struct edge_list *edge_list,
79 sbitmap *, sbitmap *,
80 sbitmap *, sbitmap *,
81 sbitmap *));
a42cd965
AM
82
83/* Edge based LCM routines on a reverse flowgraph. */
f4e72d6e
RK
84static void compute_farthest PARAMS ((struct edge_list *, int,
85 sbitmap *, sbitmap *,
86 sbitmap*, sbitmap *,
87 sbitmap *));
88static void compute_nearerout PARAMS ((struct edge_list *, sbitmap *,
89 sbitmap *, sbitmap *,
90 sbitmap *));
91static void compute_rev_insert_delete PARAMS ((struct edge_list *edge_list,
92 sbitmap *, sbitmap *,
93 sbitmap *, sbitmap *,
94 sbitmap *));
a42cd965
AM
95\f
96/* Edge based lcm routines. */
97
b3bb6456
AJ
98/* Compute expression anticipatability at entrance and exit of each block.
99 This is done based on the flow graph, and not on the pred-succ lists.
a42cd965 100 Other than that, its pretty much identical to compute_antinout. */
d2ecda27
JL
101
102static void
a42cd965 103compute_antinout_edge (antloc, transp, antin, antout)
d2ecda27
JL
104 sbitmap *antloc;
105 sbitmap *transp;
106 sbitmap *antin;
107 sbitmap *antout;
108{
bd0eaec2 109 int bb;
a42cd965 110 edge e;
274969ea
MM
111 basic_block *worklist, *qin, *qout, *qend;
112 unsigned int qlen;
d2ecda27 113
bd0eaec2
JL
114 /* Allocate a worklist array/queue. Entries are only added to the
115 list if they were not already on the list. So the size is
116 bounded by the number of basic blocks. */
274969ea 117 qin = qout = worklist
f4e72d6e 118 = (basic_block *) xmalloc (sizeof (basic_block) * n_basic_blocks);
d2ecda27 119
bd0eaec2
JL
120 /* We want a maximal solution, so make an optimistic initialization of
121 ANTIN. */
122 sbitmap_vector_ones (antin, n_basic_blocks);
d2ecda27 123
ce724250
JL
124 /* Put every block on the worklist; this is necessary because of the
125 optimistic initialization of ANTIN above. */
274969ea 126 for (bb = n_basic_blocks - 1; bb >= 0; bb--)
d2ecda27 127 {
274969ea 128 *qin++ = BASIC_BLOCK (bb);
ce724250 129 BASIC_BLOCK (bb)->aux = BASIC_BLOCK (bb);
bd0eaec2 130 }
b3bb6456 131
274969ea
MM
132 qin = worklist;
133 qend = &worklist[n_basic_blocks];
134 qlen = n_basic_blocks;
d2ecda27 135
ce724250
JL
136 /* Mark blocks which are predecessors of the exit block so that we
137 can easily identify them below. */
138 for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next)
139 e->src->aux = EXIT_BLOCK_PTR;
140
bd0eaec2 141 /* Iterate until the worklist is empty. */
274969ea 142 while (qlen)
bd0eaec2
JL
143 {
144 /* Take the first entry off the worklist. */
274969ea 145 basic_block b = *qout++;
bd0eaec2 146 bb = b->index;
274969ea
MM
147 qlen--;
148
149 if (qout >= qend)
150 qout = worklist;
d2ecda27 151
bd0eaec2 152 if (b->aux == EXIT_BLOCK_PTR)
f4e72d6e
RK
153 /* Do not clear the aux field for blocks which are predecessors of
154 the EXIT block. That way we never add then to the worklist
155 again. */
156 sbitmap_zero (antout[bb]);
bd0eaec2
JL
157 else
158 {
159 /* Clear the aux field of this block so that it can be added to
160 the worklist again if necessary. */
161 b->aux = NULL;
162 sbitmap_intersection_of_succs (antout[bb], antin, bb);
163 }
a42cd965 164
bd0eaec2 165 if (sbitmap_a_or_b_and_c (antin[bb], antloc[bb], transp[bb], antout[bb]))
f4e72d6e
RK
166 /* If the in state of this block changed, then we need
167 to add the predecessors of this block to the worklist
168 if they are not already on the worklist. */
169 for (e = b->pred; e; e = e->pred_next)
170 if (!e->src->aux && e->src != ENTRY_BLOCK_PTR)
d2ecda27 171 {
274969ea 172 *qin++ = e->src;
f4e72d6e 173 e->src->aux = e;
274969ea
MM
174 qlen++;
175 if (qin >= qend)
176 qin = worklist;
d2ecda27 177 }
d2ecda27 178 }
f4e72d6e 179
274969ea 180 free (worklist);
d2ecda27
JL
181}
182
a42cd965 183/* Compute the earliest vector for edge based lcm. */
f4e72d6e 184
d2ecda27 185static void
a42cd965
AM
186compute_earliest (edge_list, n_exprs, antin, antout, avout, kill, earliest)
187 struct edge_list *edge_list;
d2ecda27 188 int n_exprs;
a42cd965 189 sbitmap *antin, *antout, *avout, *kill, *earliest;
d2ecda27 190{
a42cd965 191 sbitmap difference, temp_bitmap;
b3bb6456 192 int x, num_edges;
a42cd965 193 basic_block pred, succ;
d2ecda27 194
a42cd965 195 num_edges = NUM_EDGES (edge_list);
d2ecda27 196
a42cd965
AM
197 difference = sbitmap_alloc (n_exprs);
198 temp_bitmap = sbitmap_alloc (n_exprs);
d2ecda27 199
a42cd965 200 for (x = 0; x < num_edges; x++)
d2ecda27 201 {
a42cd965
AM
202 pred = INDEX_EDGE_PRED_BB (edge_list, x);
203 succ = INDEX_EDGE_SUCC_BB (edge_list, x);
204 if (pred == ENTRY_BLOCK_PTR)
205 sbitmap_copy (earliest[x], antin[succ->index]);
206 else
207 {
e8eacc3f
AO
208 /* We refer to the EXIT_BLOCK index, instead of testing for
209 EXIT_BLOCK_PTR, so that EXIT_BLOCK_PTR's index can be
210 changed so as to pretend it's a regular block, so that
211 its antin can be taken into account. */
212 if (succ->index == EXIT_BLOCK)
f4e72d6e 213 sbitmap_zero (earliest[x]);
a42cd965 214 else
d2ecda27 215 {
b3bb6456
AJ
216 sbitmap_difference (difference, antin[succ->index],
217 avout[pred->index]);
a42cd965 218 sbitmap_not (temp_bitmap, antout[pred->index]);
f4e72d6e
RK
219 sbitmap_a_and_b_or_c (earliest[x], difference,
220 kill[pred->index], temp_bitmap);
d2ecda27
JL
221 }
222 }
d2ecda27 223 }
f4e72d6e 224
d2ecda27 225 free (temp_bitmap);
a42cd965 226 free (difference);
d2ecda27
JL
227}
228
bd0eaec2
JL
229/* later(p,s) is dependent on the calculation of laterin(p).
230 laterin(p) is dependent on the calculation of later(p2,p).
231
232 laterin(ENTRY) is defined as all 0's
233 later(ENTRY, succs(ENTRY)) are defined using laterin(ENTRY)
234 laterin(succs(ENTRY)) is defined by later(ENTRY, succs(ENTRY)).
235
236 If we progress in this manner, starting with all basic blocks
237 in the work list, anytime we change later(bb), we need to add
238 succs(bb) to the worklist if they are not already on the worklist.
239
240 Boundary conditions:
241
242 We prime the worklist all the normal basic blocks. The ENTRY block can
243 never be added to the worklist since it is never the successor of any
244 block. We explicitly prevent the EXIT block from being added to the
245 worklist.
246
247 We optimistically initialize LATER. That is the only time this routine
248 will compute LATER for an edge out of the entry block since the entry
249 block is never on the worklist. Thus, LATERIN is neither used nor
250 computed for the ENTRY block.
251
252 Since the EXIT block is never added to the worklist, we will neither
253 use nor compute LATERIN for the exit block. Edges which reach the
254 EXIT block are handled in the normal fashion inside the loop. However,
255 the insertion/deletion computation needs LATERIN(EXIT), so we have
256 to compute it. */
b3bb6456 257
d2ecda27 258static void
bd0eaec2 259compute_laterin (edge_list, earliest, antloc, later, laterin)
a42cd965 260 struct edge_list *edge_list;
a42cd965 261 sbitmap *earliest, *antloc, *later, *laterin;
d2ecda27 262{
bd0eaec2
JL
263 int bb, num_edges, i;
264 edge e;
274969ea
MM
265 basic_block *worklist, *qin, *qout, *qend;
266 unsigned int qlen;
d2ecda27 267
a42cd965 268 num_edges = NUM_EDGES (edge_list);
d2ecda27 269
bd0eaec2
JL
270 /* Allocate a worklist array/queue. Entries are only added to the
271 list if they were not already on the list. So the size is
272 bounded by the number of basic blocks. */
274969ea 273 qin = qout = worklist
f4e72d6e 274 = (basic_block *) xmalloc (sizeof (basic_block) * (n_basic_blocks + 1));
bd0eaec2
JL
275
276 /* Initialize a mapping from each edge to its index. */
277 for (i = 0; i < num_edges; i++)
63408827 278 INDEX_EDGE (edge_list, i)->aux = (void *) (size_t) i;
bd0eaec2
JL
279
280 /* We want a maximal solution, so initially consider LATER true for
281 all edges. This allows propagation through a loop since the incoming
282 loop edge will have LATER set, so if all the other incoming edges
283 to the loop are set, then LATERIN will be set for the head of the
284 loop.
285
286 If the optimistic setting of LATER on that edge was incorrect (for
287 example the expression is ANTLOC in a block within the loop) then
288 this algorithm will detect it when we process the block at the head
289 of the optimistic edge. That will requeue the affected blocks. */
290 sbitmap_vector_ones (later, num_edges);
291
89e606c9
JL
292 /* Note that even though we want an optimistic setting of LATER, we
293 do not want to be overly optimistic. Consider an outgoing edge from
294 the entry block. That edge should always have a LATER value the
295 same as EARLIEST for that edge. */
296 for (e = ENTRY_BLOCK_PTR->succ; e; e = e->succ_next)
f4e72d6e 297 sbitmap_copy (later[(size_t) e->aux], earliest[(size_t) e->aux]);
89e606c9 298
bd0eaec2
JL
299 /* Add all the blocks to the worklist. This prevents an early exit from
300 the loop given our optimistic initialization of LATER above. */
274969ea 301 for (bb = 0; bb < n_basic_blocks; bb++)
d2ecda27 302 {
bd0eaec2 303 basic_block b = BASIC_BLOCK (bb);
274969ea 304 *qin++ = b;
bd0eaec2 305 b->aux = b;
a42cd965 306 }
274969ea
MM
307 qin = worklist;
308 /* Note that we do not use the last allocated element for our queue,
309 as EXIT_BLOCK is never inserted into it. In fact the above allocation
dc297297 310 of n_basic_blocks + 1 elements is not encessary. */
274969ea
MM
311 qend = &worklist[n_basic_blocks];
312 qlen = n_basic_blocks;
a42cd965 313
bd0eaec2 314 /* Iterate until the worklist is empty. */
274969ea 315 while (qlen)
a42cd965 316 {
bd0eaec2 317 /* Take the first entry off the worklist. */
274969ea 318 basic_block b = *qout++;
bd0eaec2 319 b->aux = NULL;
274969ea
MM
320 qlen--;
321 if (qout >= qend)
322 qout = worklist;
bd0eaec2
JL
323
324 /* Compute the intersection of LATERIN for each incoming edge to B. */
325 bb = b->index;
326 sbitmap_ones (laterin[bb]);
327 for (e = b->pred; e != NULL; e = e->pred_next)
63408827 328 sbitmap_a_and_b (laterin[bb], laterin[bb], later[(size_t)e->aux]);
bd0eaec2
JL
329
330 /* Calculate LATER for all outgoing edges. */
331 for (e = b->succ; e != NULL; e = e->succ_next)
f4e72d6e
RK
332 if (sbitmap_union_of_diff (later[(size_t) e->aux],
333 earliest[(size_t) e->aux],
334 laterin[e->src->index],
335 antloc[e->src->index])
336 /* If LATER for an outgoing edge was changed, then we need
337 to add the target of the outgoing edge to the worklist. */
338 && e->dest != EXIT_BLOCK_PTR && e->dest->aux == 0)
339 {
274969ea 340 *qin++ = e->dest;
f4e72d6e 341 e->dest->aux = e;
274969ea
MM
342 qlen++;
343 if (qin >= qend)
344 qin = worklist;
f4e72d6e 345 }
d2ecda27
JL
346 }
347
bd0eaec2
JL
348 /* Computation of insertion and deletion points requires computing LATERIN
349 for the EXIT block. We allocated an extra entry in the LATERIN array
350 for just this purpose. */
351 sbitmap_ones (laterin[n_basic_blocks]);
352 for (e = EXIT_BLOCK_PTR->pred; e != NULL; e = e->pred_next)
353 sbitmap_a_and_b (laterin[n_basic_blocks],
354 laterin[n_basic_blocks],
63408827 355 later[(size_t) e->aux]);
bd0eaec2 356
274969ea 357 free (worklist);
d2ecda27
JL
358}
359
a42cd965 360/* Compute the insertion and deletion points for edge based LCM. */
f4e72d6e 361
a42cd965
AM
362static void
363compute_insert_delete (edge_list, antloc, later, laterin,
364 insert, delete)
365 struct edge_list *edge_list;
366 sbitmap *antloc, *later, *laterin, *insert, *delete;
367{
368 int x;
d2ecda27 369
a42cd965
AM
370 for (x = 0; x < n_basic_blocks; x++)
371 sbitmap_difference (delete[x], antloc[x], laterin[x]);
b3bb6456 372
a42cd965
AM
373 for (x = 0; x < NUM_EDGES (edge_list); x++)
374 {
375 basic_block b = INDEX_EDGE_SUCC_BB (edge_list, x);
f4e72d6e 376
a42cd965
AM
377 if (b == EXIT_BLOCK_PTR)
378 sbitmap_difference (insert[x], later[x], laterin[n_basic_blocks]);
379 else
380 sbitmap_difference (insert[x], later[x], laterin[b->index]);
381 }
382}
d2ecda27 383
f4e72d6e
RK
384/* Given local properties TRANSP, ANTLOC, AVOUT, KILL return the insert and
385 delete vectors for edge based LCM. Returns an edgelist which is used to
386 map the insert vector to what edge an expression should be inserted on. */
d2ecda27 387
a42cd965
AM
388struct edge_list *
389pre_edge_lcm (file, n_exprs, transp, avloc, antloc, kill, insert, delete)
4b66e1c0 390 FILE *file ATTRIBUTE_UNUSED;
d2ecda27 391 int n_exprs;
a42cd965
AM
392 sbitmap *transp;
393 sbitmap *avloc;
d2ecda27 394 sbitmap *antloc;
a42cd965
AM
395 sbitmap *kill;
396 sbitmap **insert;
397 sbitmap **delete;
d2ecda27 398{
a42cd965
AM
399 sbitmap *antin, *antout, *earliest;
400 sbitmap *avin, *avout;
401 sbitmap *later, *laterin;
402 struct edge_list *edge_list;
403 int num_edges;
d2ecda27 404
a42cd965
AM
405 edge_list = create_edge_list ();
406 num_edges = NUM_EDGES (edge_list);
d2ecda27 407
a42cd965
AM
408#ifdef LCM_DEBUG_INFO
409 if (file)
d2ecda27 410 {
a42cd965
AM
411 fprintf (file, "Edge List:\n");
412 verify_edge_list (file, edge_list);
413 print_edge_list (file, edge_list);
414 dump_sbitmap_vector (file, "transp", "", transp, n_basic_blocks);
415 dump_sbitmap_vector (file, "antloc", "", antloc, n_basic_blocks);
416 dump_sbitmap_vector (file, "avloc", "", avloc, n_basic_blocks);
417 dump_sbitmap_vector (file, "kill", "", kill, n_basic_blocks);
d2ecda27 418 }
a42cd965 419#endif
d2ecda27 420
a42cd965
AM
421 /* Compute global availability. */
422 avin = sbitmap_vector_alloc (n_basic_blocks, n_exprs);
423 avout = sbitmap_vector_alloc (n_basic_blocks, n_exprs);
424 compute_available (avloc, kill, avout, avin);
5a660bff 425 sbitmap_vector_free (avin);
d2ecda27 426
a42cd965
AM
427 /* Compute global anticipatability. */
428 antin = sbitmap_vector_alloc (n_basic_blocks, n_exprs);
429 antout = sbitmap_vector_alloc (n_basic_blocks, n_exprs);
430 compute_antinout_edge (antloc, transp, antin, antout);
d2ecda27 431
a42cd965
AM
432#ifdef LCM_DEBUG_INFO
433 if (file)
d2ecda27 434 {
a42cd965
AM
435 dump_sbitmap_vector (file, "antin", "", antin, n_basic_blocks);
436 dump_sbitmap_vector (file, "antout", "", antout, n_basic_blocks);
d2ecda27 437 }
a42cd965 438#endif
d2ecda27 439
a42cd965
AM
440 /* Compute earliestness. */
441 earliest = sbitmap_vector_alloc (num_edges, n_exprs);
442 compute_earliest (edge_list, n_exprs, antin, antout, avout, kill, earliest);
d2ecda27 443
a42cd965
AM
444#ifdef LCM_DEBUG_INFO
445 if (file)
446 dump_sbitmap_vector (file, "earliest", "", earliest, num_edges);
447#endif
d2ecda27 448
5a660bff
DB
449 sbitmap_vector_free (antout);
450 sbitmap_vector_free (antin);
451 sbitmap_vector_free (avout);
d2ecda27 452
a42cd965 453 later = sbitmap_vector_alloc (num_edges, n_exprs);
f4e72d6e 454
a42cd965
AM
455 /* Allocate an extra element for the exit block in the laterin vector. */
456 laterin = sbitmap_vector_alloc (n_basic_blocks + 1, n_exprs);
bd0eaec2
JL
457 compute_laterin (edge_list, earliest, antloc, later, laterin);
458
a42cd965
AM
459#ifdef LCM_DEBUG_INFO
460 if (file)
461 {
462 dump_sbitmap_vector (file, "laterin", "", laterin, n_basic_blocks + 1);
463 dump_sbitmap_vector (file, "later", "", later, num_edges);
464 }
465#endif
d2ecda27 466
5a660bff 467 sbitmap_vector_free (earliest);
a42cd965
AM
468
469 *insert = sbitmap_vector_alloc (num_edges, n_exprs);
470 *delete = sbitmap_vector_alloc (n_basic_blocks, n_exprs);
471 compute_insert_delete (edge_list, antloc, later, laterin, *insert, *delete);
d2ecda27 472
5a660bff
DB
473 sbitmap_vector_free (laterin);
474 sbitmap_vector_free (later);
a42cd965
AM
475
476#ifdef LCM_DEBUG_INFO
477 if (file)
d2ecda27 478 {
a42cd965 479 dump_sbitmap_vector (file, "pre_insert_map", "", *insert, num_edges);
f4e72d6e
RK
480 dump_sbitmap_vector (file, "pre_delete_map", "", *delete,
481 n_basic_blocks);
d2ecda27 482 }
a42cd965 483#endif
d2ecda27 484
a42cd965
AM
485 return edge_list;
486}
d2ecda27 487
a42cd965
AM
488/* Compute the AVIN and AVOUT vectors from the AVLOC and KILL vectors.
489 Return the number of passes we performed to iterate to a solution. */
f4e72d6e 490
bd0eaec2 491void
a42cd965 492compute_available (avloc, kill, avout, avin)
b3bb6456 493 sbitmap *avloc, *kill, *avout, *avin;
d2ecda27 494{
bd0eaec2
JL
495 int bb;
496 edge e;
274969ea
MM
497 basic_block *worklist, *qin, *qout, *qend;
498 unsigned int qlen;
d2ecda27 499
bd0eaec2
JL
500 /* Allocate a worklist array/queue. Entries are only added to the
501 list if they were not already on the list. So the size is
502 bounded by the number of basic blocks. */
274969ea 503 qin = qout = worklist
f4e72d6e 504 = (basic_block *) xmalloc (sizeof (basic_block) * n_basic_blocks);
d2ecda27 505
bd0eaec2
JL
506 /* We want a maximal solution. */
507 sbitmap_vector_ones (avout, n_basic_blocks);
508
ce724250
JL
509 /* Put every block on the worklist; this is necessary because of the
510 optimistic initialization of AVOUT above. */
274969ea 511 for (bb = 0; bb < n_basic_blocks; bb++)
d2ecda27 512 {
274969ea 513 *qin++ = BASIC_BLOCK (bb);
ce724250 514 BASIC_BLOCK (bb)->aux = BASIC_BLOCK (bb);
d2ecda27 515 }
b3bb6456 516
274969ea
MM
517 qin = worklist;
518 qend = &worklist[n_basic_blocks];
519 qlen = n_basic_blocks;
bd0eaec2 520
ce724250
JL
521 /* Mark blocks which are successors of the entry block so that we
522 can easily identify them below. */
523 for (e = ENTRY_BLOCK_PTR->succ; e; e = e->succ_next)
524 e->dest->aux = ENTRY_BLOCK_PTR;
525
bd0eaec2 526 /* Iterate until the worklist is empty. */
274969ea 527 while (qlen)
bd0eaec2
JL
528 {
529 /* Take the first entry off the worklist. */
274969ea 530 basic_block b = *qout++;
bd0eaec2 531 bb = b->index;
274969ea
MM
532 qlen--;
533
534 if (qout >= qend)
535 qout = worklist;
bd0eaec2
JL
536
537 /* If one of the predecessor blocks is the ENTRY block, then the
538 intersection of avouts is the null set. We can identify such blocks
539 by the special value in the AUX field in the block structure. */
540 if (b->aux == ENTRY_BLOCK_PTR)
f4e72d6e
RK
541 /* Do not clear the aux field for blocks which are successors of the
542 ENTRY block. That way we never add then to the worklist again. */
543 sbitmap_zero (avin[bb]);
bd0eaec2
JL
544 else
545 {
546 /* Clear the aux field of this block so that it can be added to
547 the worklist again if necessary. */
548 b->aux = NULL;
549 sbitmap_intersection_of_preds (avin[bb], avout, bb);
550 }
551
552 if (sbitmap_union_of_diff (avout[bb], avloc[bb], avin[bb], kill[bb]))
f4e72d6e
RK
553 /* If the out state of this block changed, then we need
554 to add the successors of this block to the worklist
555 if they are not already on the worklist. */
556 for (e = b->succ; e; e = e->succ_next)
557 if (!e->dest->aux && e->dest != EXIT_BLOCK_PTR)
bd0eaec2 558 {
274969ea 559 *qin++ = e->dest;
f4e72d6e 560 e->dest->aux = e;
274969ea
MM
561 qlen++;
562
563 if (qin >= qend)
564 qin = worklist;
bd0eaec2 565 }
bd0eaec2 566 }
f4e72d6e 567
274969ea 568 free (worklist);
d2ecda27
JL
569}
570
a42cd965 571/* Compute the farthest vector for edge based lcm. */
f4e72d6e 572
d2ecda27 573static void
b3bb6456 574compute_farthest (edge_list, n_exprs, st_avout, st_avin, st_antin,
a42cd965
AM
575 kill, farthest)
576 struct edge_list *edge_list;
d2ecda27 577 int n_exprs;
a42cd965 578 sbitmap *st_avout, *st_avin, *st_antin, *kill, *farthest;
d2ecda27 579{
a42cd965 580 sbitmap difference, temp_bitmap;
b3bb6456 581 int x, num_edges;
a42cd965 582 basic_block pred, succ;
d2ecda27 583
a42cd965 584 num_edges = NUM_EDGES (edge_list);
d2ecda27 585
a42cd965
AM
586 difference = sbitmap_alloc (n_exprs);
587 temp_bitmap = sbitmap_alloc (n_exprs);
d2ecda27 588
a42cd965 589 for (x = 0; x < num_edges; x++)
d2ecda27 590 {
a42cd965
AM
591 pred = INDEX_EDGE_PRED_BB (edge_list, x);
592 succ = INDEX_EDGE_SUCC_BB (edge_list, x);
593 if (succ == EXIT_BLOCK_PTR)
594 sbitmap_copy (farthest[x], st_avout[pred->index]);
595 else
d2ecda27 596 {
a42cd965 597 if (pred == ENTRY_BLOCK_PTR)
f4e72d6e 598 sbitmap_zero (farthest[x]);
a42cd965
AM
599 else
600 {
b3bb6456 601 sbitmap_difference (difference, st_avout[pred->index],
a42cd965
AM
602 st_antin[succ->index]);
603 sbitmap_not (temp_bitmap, st_avin[succ->index]);
b3bb6456 604 sbitmap_a_and_b_or_c (farthest[x], difference,
a42cd965
AM
605 kill[succ->index], temp_bitmap);
606 }
d2ecda27 607 }
d2ecda27 608 }
f4e72d6e 609
d2ecda27 610 free (temp_bitmap);
a42cd965 611 free (difference);
d2ecda27
JL
612}
613
bd0eaec2
JL
614/* Compute nearer and nearerout vectors for edge based lcm.
615
616 This is the mirror of compute_laterin, additional comments on the
617 implementation can be found before compute_laterin. */
618
d2ecda27 619static void
bd0eaec2 620compute_nearerout (edge_list, farthest, st_avloc, nearer, nearerout)
a42cd965 621 struct edge_list *edge_list;
a42cd965 622 sbitmap *farthest, *st_avloc, *nearer, *nearerout;
d2ecda27 623{
bd0eaec2
JL
624 int bb, num_edges, i;
625 edge e;
626 basic_block *worklist, *tos;
d2ecda27 627
a42cd965 628 num_edges = NUM_EDGES (edge_list);
d2ecda27 629
bd0eaec2
JL
630 /* Allocate a worklist array/queue. Entries are only added to the
631 list if they were not already on the list. So the size is
632 bounded by the number of basic blocks. */
f4e72d6e
RK
633 tos = worklist
634 = (basic_block *) xmalloc (sizeof (basic_block) * (n_basic_blocks + 1));
d2ecda27 635
bd0eaec2
JL
636 /* Initialize NEARER for each edge and build a mapping from an edge to
637 its index. */
638 for (i = 0; i < num_edges; i++)
63408827 639 INDEX_EDGE (edge_list, i)->aux = (void *) (size_t) i;
a42cd965 640
bd0eaec2
JL
641 /* We want a maximal solution. */
642 sbitmap_vector_ones (nearer, num_edges);
643
89e606c9
JL
644 /* Note that even though we want an optimistic setting of NEARER, we
645 do not want to be overly optimistic. Consider an incoming edge to
646 the exit block. That edge should always have a NEARER value the
647 same as FARTHEST for that edge. */
648 for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next)
e5b7ca32 649 sbitmap_copy (nearer[(size_t)e->aux], farthest[(size_t)e->aux]);
89e606c9 650
bd0eaec2
JL
651 /* Add all the blocks to the worklist. This prevents an early exit
652 from the loop given our optimistic initialization of NEARER. */
653 for (bb = 0; bb < n_basic_blocks; bb++)
d2ecda27 654 {
bd0eaec2
JL
655 basic_block b = BASIC_BLOCK (bb);
656 *tos++ = b;
657 b->aux = b;
a42cd965 658 }
b3bb6456 659
bd0eaec2
JL
660 /* Iterate until the worklist is empty. */
661 while (tos != worklist)
a42cd965 662 {
bd0eaec2
JL
663 /* Take the first entry off the worklist. */
664 basic_block b = *--tos;
665 b->aux = NULL;
666
667 /* Compute the intersection of NEARER for each outgoing edge from B. */
668 bb = b->index;
669 sbitmap_ones (nearerout[bb]);
670 for (e = b->succ; e != NULL; e = e->succ_next)
63408827
RH
671 sbitmap_a_and_b (nearerout[bb], nearerout[bb],
672 nearer[(size_t) e->aux]);
bd0eaec2
JL
673
674 /* Calculate NEARER for all incoming edges. */
675 for (e = b->pred; e != NULL; e = e->pred_next)
f4e72d6e
RK
676 if (sbitmap_union_of_diff (nearer[(size_t) e->aux],
677 farthest[(size_t) e->aux],
678 nearerout[e->dest->index],
679 st_avloc[e->dest->index])
680 /* If NEARER for an incoming edge was changed, then we need
681 to add the source of the incoming edge to the worklist. */
682 && e->src != ENTRY_BLOCK_PTR && e->src->aux == 0)
683 {
684 *tos++ = e->src;
685 e->src->aux = e;
686 }
a42cd965 687 }
d2ecda27 688
bd0eaec2
JL
689 /* Computation of insertion and deletion points requires computing NEAREROUT
690 for the ENTRY block. We allocated an extra entry in the NEAREROUT array
691 for just this purpose. */
692 sbitmap_ones (nearerout[n_basic_blocks]);
693 for (e = ENTRY_BLOCK_PTR->succ; e != NULL; e = e->succ_next)
694 sbitmap_a_and_b (nearerout[n_basic_blocks],
695 nearerout[n_basic_blocks],
63408827 696 nearer[(size_t) e->aux]);
bd0eaec2
JL
697
698 free (tos);
a42cd965 699}
d2ecda27 700
a42cd965 701/* Compute the insertion and deletion points for edge based LCM. */
f4e72d6e 702
d2ecda27 703static void
a42cd965
AM
704compute_rev_insert_delete (edge_list, st_avloc, nearer, nearerout,
705 insert, delete)
706 struct edge_list *edge_list;
707 sbitmap *st_avloc, *nearer, *nearerout, *insert, *delete;
d2ecda27 708{
a42cd965 709 int x;
d2ecda27 710
a42cd965
AM
711 for (x = 0; x < n_basic_blocks; x++)
712 sbitmap_difference (delete[x], st_avloc[x], nearerout[x]);
b3bb6456 713
a42cd965 714 for (x = 0; x < NUM_EDGES (edge_list); x++)
d2ecda27 715 {
a42cd965
AM
716 basic_block b = INDEX_EDGE_PRED_BB (edge_list, x);
717 if (b == ENTRY_BLOCK_PTR)
718 sbitmap_difference (insert[x], nearer[x], nearerout[n_basic_blocks]);
d2ecda27 719 else
a42cd965 720 sbitmap_difference (insert[x], nearer[x], nearerout[b->index]);
d2ecda27 721 }
d2ecda27
JL
722}
723
b3bb6456 724/* Given local properties TRANSP, ST_AVLOC, ST_ANTLOC, KILL return the
a42cd965
AM
725 insert and delete vectors for edge based reverse LCM. Returns an
726 edgelist which is used to map the insert vector to what edge
727 an expression should be inserted on. */
d2ecda27 728
a42cd965 729struct edge_list *
b3bb6456 730pre_edge_rev_lcm (file, n_exprs, transp, st_avloc, st_antloc, kill,
a42cd965 731 insert, delete)
4b66e1c0 732 FILE *file ATTRIBUTE_UNUSED;
a42cd965
AM
733 int n_exprs;
734 sbitmap *transp;
735 sbitmap *st_avloc;
736 sbitmap *st_antloc;
737 sbitmap *kill;
738 sbitmap **insert;
739 sbitmap **delete;
d2ecda27 740{
a42cd965
AM
741 sbitmap *st_antin, *st_antout;
742 sbitmap *st_avout, *st_avin, *farthest;
743 sbitmap *nearer, *nearerout;
744 struct edge_list *edge_list;
4b66e1c0 745 int num_edges;
a42cd965
AM
746
747 edge_list = create_edge_list ();
748 num_edges = NUM_EDGES (edge_list);
749
750 st_antin = (sbitmap *) sbitmap_vector_alloc (n_basic_blocks, n_exprs);
751 st_antout = (sbitmap *) sbitmap_vector_alloc (n_basic_blocks, n_exprs);
752 sbitmap_vector_zero (st_antin, n_basic_blocks);
753 sbitmap_vector_zero (st_antout, n_basic_blocks);
754 compute_antinout_edge (st_antloc, transp, st_antin, st_antout);
755
756 /* Compute global anticipatability. */
757 st_avout = sbitmap_vector_alloc (n_basic_blocks, n_exprs);
758 st_avin = sbitmap_vector_alloc (n_basic_blocks, n_exprs);
759 compute_available (st_avloc, kill, st_avout, st_avin);
760
761#ifdef LCM_DEBUG_INFO
762 if (file)
763 {
764 fprintf (file, "Edge List:\n");
765 verify_edge_list (file, edge_list);
766 print_edge_list (file, edge_list);
767 dump_sbitmap_vector (file, "transp", "", transp, n_basic_blocks);
768 dump_sbitmap_vector (file, "st_avloc", "", st_avloc, n_basic_blocks);
769 dump_sbitmap_vector (file, "st_antloc", "", st_antloc, n_basic_blocks);
770 dump_sbitmap_vector (file, "st_antin", "", st_antin, n_basic_blocks);
771 dump_sbitmap_vector (file, "st_antout", "", st_antout, n_basic_blocks);
772 dump_sbitmap_vector (file, "st_kill", "", kill, n_basic_blocks);
773 }
774#endif
d2ecda27 775
a42cd965
AM
776#ifdef LCM_DEBUG_INFO
777 if (file)
778 {
779 dump_sbitmap_vector (file, "st_avout", "", st_avout, n_basic_blocks);
780 dump_sbitmap_vector (file, "st_avin", "", st_avin, n_basic_blocks);
781 }
782#endif
d2ecda27 783
a42cd965
AM
784 /* Compute farthestness. */
785 farthest = sbitmap_vector_alloc (num_edges, n_exprs);
b3bb6456 786 compute_farthest (edge_list, n_exprs, st_avout, st_avin, st_antin,
a42cd965
AM
787 kill, farthest);
788
789#ifdef LCM_DEBUG_INFO
790 if (file)
791 dump_sbitmap_vector (file, "farthest", "", farthest, num_edges);
792#endif
793
5a660bff
DB
794 sbitmap_vector_free (st_antin);
795 sbitmap_vector_free (st_antout);
796
797 sbitmap_vector_free (st_avin);
798 sbitmap_vector_free (st_avout);
a42cd965
AM
799
800 nearer = sbitmap_vector_alloc (num_edges, n_exprs);
f4e72d6e 801
a42cd965
AM
802 /* Allocate an extra element for the entry block. */
803 nearerout = sbitmap_vector_alloc (n_basic_blocks + 1, n_exprs);
bd0eaec2 804 compute_nearerout (edge_list, farthest, st_avloc, nearer, nearerout);
a42cd965
AM
805
806#ifdef LCM_DEBUG_INFO
807 if (file)
d2ecda27 808 {
b3bb6456 809 dump_sbitmap_vector (file, "nearerout", "", nearerout,
a42cd965
AM
810 n_basic_blocks + 1);
811 dump_sbitmap_vector (file, "nearer", "", nearer, num_edges);
d2ecda27 812 }
a42cd965
AM
813#endif
814
5a660bff 815 sbitmap_vector_free (farthest);
a42cd965
AM
816
817 *insert = sbitmap_vector_alloc (num_edges, n_exprs);
818 *delete = sbitmap_vector_alloc (n_basic_blocks, n_exprs);
f4e72d6e
RK
819 compute_rev_insert_delete (edge_list, st_avloc, nearer, nearerout,
820 *insert, *delete);
a42cd965 821
5a660bff
DB
822 sbitmap_vector_free (nearerout);
823 sbitmap_vector_free (nearer);
a42cd965
AM
824
825#ifdef LCM_DEBUG_INFO
826 if (file)
827 {
828 dump_sbitmap_vector (file, "pre_insert_map", "", *insert, num_edges);
f4e72d6e
RK
829 dump_sbitmap_vector (file, "pre_delete_map", "", *delete,
830 n_basic_blocks);
a42cd965
AM
831 }
832#endif
a42cd965 833 return edge_list;
d2ecda27 834}
9f09b1f2 835
f4e72d6e
RK
836/* Mode switching:
837
838 The algorithm for setting the modes consists of scanning the insn list
9f09b1f2
R
839 and finding all the insns which require a specific mode. Each insn gets
840 a unique struct seginfo element. These structures are inserted into a list
841 for each basic block. For each entity, there is an array of bb_info over
842 the flow graph basic blocks (local var 'bb_info'), and contains a list
843 of all insns within that basic block, in the order they are encountered.
844
845 For each entity, any basic block WITHOUT any insns requiring a specific
846 mode are given a single entry, without a mode. (Each basic block
847 in the flow graph must have at least one entry in the segment table.)
848
849 The LCM algorithm is then run over the flow graph to determine where to
850 place the sets to the highest-priority value in respect of first the first
851 insn in any one block. Any adjustments required to the transparancy
852 vectors are made, then the next iteration starts for the next-lower
853 priority mode, till for each entity all modes are exhasted.
854
855 More details are located in the code for optimize_mode_switching(). */
856
857/* This structure contains the information for each insn which requires
b3bb6456 858 either single or double mode to be set.
9f09b1f2 859 MODE is the mode this insn must be executed in.
1cca43ea
AO
860 INSN_PTR is the insn to be executed (may be the note that marks the
861 beginning of a basic block).
9f09b1f2
R
862 BBNUM is the flow graph basic block this insn occurs in.
863 NEXT is the next insn in the same basic block. */
b3bb6456 864struct seginfo
9f09b1f2
R
865{
866 int mode;
867 rtx insn_ptr;
868 int bbnum;
869 struct seginfo *next;
870 HARD_REG_SET regs_live;
871};
872
873struct bb_info
874{
875 struct seginfo *seginfo;
876 int computing;
877};
878
879/* These bitmaps are used for the LCM algorithm. */
880
c8d8ed65 881#ifdef OPTIMIZE_MODE_SWITCHING
9f09b1f2
R
882static sbitmap *antic;
883static sbitmap *transp;
884static sbitmap *comp;
885static sbitmap *delete;
886static sbitmap *insert;
887
1270c255 888static struct seginfo * new_seginfo PARAMS ((int, rtx, int, HARD_REG_SET));
9f09b1f2 889static void add_seginfo PARAMS ((struct bb_info *, struct seginfo *));
9f09b1f2
R
890static void reg_dies PARAMS ((rtx, HARD_REG_SET));
891static void reg_becomes_live PARAMS ((rtx, rtx, void *));
c8d8ed65
RK
892static void make_preds_opaque PARAMS ((basic_block, int));
893#endif
894\f
895#ifdef OPTIMIZE_MODE_SWITCHING
9f09b1f2
R
896
897/* This function will allocate a new BBINFO structure, initialized
1270c255 898 with the MODE, INSN, and basic block BB parameters. */
c8d8ed65 899
9f09b1f2
R
900static struct seginfo *
901new_seginfo (mode, insn, bb, regs_live)
902 int mode;
903 rtx insn;
904 int bb;
905 HARD_REG_SET regs_live;
906{
907 struct seginfo *ptr;
908 ptr = xmalloc (sizeof (struct seginfo));
909 ptr->mode = mode;
910 ptr->insn_ptr = insn;
911 ptr->bbnum = bb;
912 ptr->next = NULL;
913 COPY_HARD_REG_SET (ptr->regs_live, regs_live);
914 return ptr;
915}
916
b3bb6456 917/* Add a seginfo element to the end of a list.
9f09b1f2
R
918 HEAD is a pointer to the list beginning.
919 INFO is the structure to be linked in. */
c8d8ed65 920
9f09b1f2
R
921static void
922add_seginfo (head, info)
923 struct bb_info *head;
924 struct seginfo *info;
925{
926 struct seginfo *ptr;
927
928 if (head->seginfo == NULL)
929 head->seginfo = info;
930 else
931 {
932 ptr = head->seginfo;
933 while (ptr->next != NULL)
934 ptr = ptr->next;
935 ptr->next = info;
936 }
937}
938
939/* Make all predecessors of basic block B opaque, recursively, till we hit
940 some that are already non-transparent, or an edge where aux is set; that
941 denotes that a mode set is to be done on that edge.
942 J is the bit number in the bitmaps that corresponds to the entity that
943 we are currently handling mode-switching for. */
c8d8ed65 944
9f09b1f2
R
945static void
946make_preds_opaque (b, j)
947 basic_block b;
948 int j;
949{
950 edge e;
951
952 for (e = b->pred; e; e = e->pred_next)
953 {
954 basic_block pb = e->src;
f4e72d6e 955
9f09b1f2
R
956 if (e->aux || ! TEST_BIT (transp[pb->index], j))
957 continue;
f4e72d6e 958
9f09b1f2
R
959 RESET_BIT (transp[pb->index], j);
960 make_preds_opaque (pb, j);
961 }
962}
963
964/* Record in LIVE that register REG died. */
c8d8ed65 965
9f09b1f2
R
966static void
967reg_dies (reg, live)
968 rtx reg;
969 HARD_REG_SET live;
970{
f4e72d6e 971 int regno, nregs;
9f09b1f2
R
972
973 if (GET_CODE (reg) != REG)
974 return;
f4e72d6e 975
9f09b1f2
R
976 regno = REGNO (reg);
977 if (regno < FIRST_PSEUDO_REGISTER)
f4e72d6e
RK
978 for (nregs = HARD_REGNO_NREGS (regno, GET_MODE (reg)) - 1; nregs >= 0;
979 nregs--)
980 CLEAR_HARD_REG_BIT (live, regno + nregs);
9f09b1f2
R
981}
982
983/* Record in LIVE that register REG became live.
984 This is called via note_stores. */
c8d8ed65 985
9f09b1f2
R
986static void
987reg_becomes_live (reg, setter, live)
988 rtx reg;
989 rtx setter ATTRIBUTE_UNUSED;
990 void *live;
991{
f4e72d6e 992 int regno, nregs;
9f09b1f2
R
993
994 if (GET_CODE (reg) == SUBREG)
995 reg = SUBREG_REG (reg);
996
997 if (GET_CODE (reg) != REG)
998 return;
999
1000 regno = REGNO (reg);
1001 if (regno < FIRST_PSEUDO_REGISTER)
f4e72d6e
RK
1002 for (nregs = HARD_REGNO_NREGS (regno, GET_MODE (reg)) - 1; nregs >= 0;
1003 nregs--)
1004 SET_HARD_REG_BIT (* (HARD_REG_SET *) live, regno + nregs);
9f09b1f2
R
1005}
1006
97d36f45
RH
1007/* Find all insns that need a particular mode setting, and insert the
1008 necessary mode switches. Return true if we did work. */
f4e72d6e 1009
97d36f45 1010int
9f09b1f2 1011optimize_mode_switching (file)
97d36f45 1012 FILE *file;
9f09b1f2 1013{
9f09b1f2
R
1014 rtx insn;
1015 int bb, e;
9f09b1f2
R
1016 int need_commit = 0;
1017 sbitmap *kill;
1018 struct edge_list *edge_list;
1019 static int num_modes[] = NUM_MODES_FOR_MODE_SWITCHING;
1020#define N_ENTITIES (sizeof num_modes / sizeof (int))
1021 int entity_map[N_ENTITIES];
1022 struct bb_info *bb_info[N_ENTITIES];
1023 int i, j;
1024 int n_entities;
1025 int max_num_modes = 0;
1026
e8eacc3f
AO
1027#ifdef NORMAL_MODE
1028 /* Increment n_basic_blocks before allocating bb_info. */
1029 n_basic_blocks++;
1030#endif
1031
9f09b1f2 1032 for (e = N_ENTITIES - 1, n_entities = 0; e >= 0; e--)
f4e72d6e
RK
1033 if (OPTIMIZE_MODE_SWITCHING (e))
1034 {
1035 /* Create the list of segments within each basic block. */
1036 bb_info[n_entities]
1037 = (struct bb_info *) xcalloc (n_basic_blocks, sizeof **bb_info);
1038 entity_map[n_entities++] = e;
1039 if (num_modes[e] > max_num_modes)
1040 max_num_modes = num_modes[e];
1041 }
1042
e8eacc3f
AO
1043#ifdef NORMAL_MODE
1044 /* Decrement it back in case we return below. */
1045 n_basic_blocks--;
1046#endif
1047
9f09b1f2 1048 if (! n_entities)
97d36f45 1049 return 0;
9f09b1f2 1050
e8eacc3f
AO
1051#ifdef NORMAL_MODE
1052 /* We're going to pretend the EXIT_BLOCK is a regular basic block,
1053 so that switching back to normal mode when entering the
1054 EXIT_BLOCK isn't optimized away. We do this by incrementing the
1055 basic block count, growing the VARRAY of basic_block_info and
1056 appending the EXIT_BLOCK_PTR to it. */
1057 n_basic_blocks++;
1058 if (VARRAY_SIZE (basic_block_info) < n_basic_blocks)
1059 VARRAY_GROW (basic_block_info, n_basic_blocks);
1060 BASIC_BLOCK (n_basic_blocks - 1) = EXIT_BLOCK_PTR;
1061 EXIT_BLOCK_PTR->index = n_basic_blocks - 1;
1062#endif
1063
9f09b1f2
R
1064 /* Create the bitmap vectors. */
1065
1066 antic = sbitmap_vector_alloc (n_basic_blocks, n_entities);
1067 transp = sbitmap_vector_alloc (n_basic_blocks, n_entities);
1068 comp = sbitmap_vector_alloc (n_basic_blocks, n_entities);
1069
1070 sbitmap_vector_ones (transp, n_basic_blocks);
1071
1072 for (j = n_entities - 1; j >= 0; j--)
1073 {
1074 int e = entity_map[j];
1075 int no_mode = num_modes[e];
1076 struct bb_info *info = bb_info[j];
1077
1078 /* Determine what the first use (if any) need for a mode of entity E is.
97d36f45 1079 This will be the mode that is anticipatable for this block.
9f09b1f2
R
1080 Also compute the initial transparency settings. */
1081 for (bb = 0 ; bb < n_basic_blocks; bb++)
1082 {
1083 struct seginfo *ptr;
1084 int last_mode = no_mode;
1085 HARD_REG_SET live_now;
1086
1087 REG_SET_TO_HARD_REG_SET (live_now,
1088 BASIC_BLOCK (bb)->global_live_at_start);
b3bb6456 1089 for (insn = BLOCK_HEAD (bb);
9f09b1f2
R
1090 insn != NULL && insn != NEXT_INSN (BLOCK_END (bb));
1091 insn = NEXT_INSN (insn))
1092 {
2c3c49de 1093 if (INSN_P (insn))
9f09b1f2
R
1094 {
1095 int mode = MODE_NEEDED (e, insn);
1096 rtx link;
1097
1098 if (mode != no_mode && mode != last_mode)
1099 {
1100 last_mode = mode;
1101 ptr = new_seginfo (mode, insn, bb, live_now);
1102 add_seginfo (info + bb, ptr);
1103 RESET_BIT (transp[bb], j);
1104 }
1105
1106 /* Update LIVE_NOW. */
1107 for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
1108 if (REG_NOTE_KIND (link) == REG_DEAD)
1109 reg_dies (XEXP (link, 0), live_now);
f4e72d6e 1110
9f09b1f2
R
1111 note_stores (PATTERN (insn), reg_becomes_live, &live_now);
1112 for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
1113 if (REG_NOTE_KIND (link) == REG_UNUSED)
1114 reg_dies (XEXP (link, 0), live_now);
1115 }
1116 }
f4e72d6e 1117
9f09b1f2
R
1118 info[bb].computing = last_mode;
1119 /* Check for blocks without ANY mode requirements. */
1120 if (last_mode == no_mode)
1121 {
1122 ptr = new_seginfo (no_mode, insn, bb, live_now);
1123 add_seginfo (info + bb, ptr);
1124 }
1125 }
1270c255 1126#ifdef NORMAL_MODE
9f09b1f2 1127 {
1270c255 1128 int mode = NORMAL_MODE (e);
f4e72d6e 1129
9f09b1f2
R
1130 if (mode != no_mode)
1131 {
b3bb6456
AJ
1132 edge eg;
1133
9f09b1f2
R
1134 for (eg = ENTRY_BLOCK_PTR->succ; eg; eg = eg->succ_next)
1135 {
1136 bb = eg->dest->index;
1137
1138 /* By always making this nontransparent, we save
1139 an extra check in make_preds_opaque. We also
1140 need this to avoid confusing pre_edge_lcm when
1141 antic is cleared but transp and comp are set. */
1142 RESET_BIT (transp[bb], j);
1143
1144 /* If the block already has MODE, pretend it
1145 has none (because we don't need to set it),
1146 but retain whatever mode it computes. */
1147 if (info[bb].seginfo->mode == mode)
f4e72d6e
RK
1148 info[bb].seginfo->mode = no_mode;
1149
1150 /* Insert a fake computing definition of MODE into entry
1151 blocks which compute no mode. This represents the mode on
1152 entry. */
9f09b1f2
R
1153 else if (info[bb].computing == no_mode)
1154 {
1155 info[bb].computing = mode;
1156 info[bb].seginfo->mode = no_mode;
1157 }
1158 }
e8eacc3f
AO
1159
1160 bb = n_basic_blocks - 1;
1161 info[bb].seginfo->mode = mode;
9f09b1f2
R
1162 }
1163 }
1270c255 1164#endif /* NORMAL_MODE */
9f09b1f2
R
1165 }
1166
1167 kill = sbitmap_vector_alloc (n_basic_blocks, n_entities);
1168 for (i = 0; i < max_num_modes; i++)
1169 {
1170 int current_mode[N_ENTITIES];
1171
1172 /* Set the anticipatable and computing arrays. */
1173 sbitmap_vector_zero (antic, n_basic_blocks);
1174 sbitmap_vector_zero (comp, n_basic_blocks);
1175 for (j = n_entities - 1; j >= 0; j--)
1176 {
1177 int m = current_mode[j] = MODE_PRIORITY_TO_MODE (entity_map[j], i);
1178 struct bb_info *info = bb_info[j];
b3bb6456 1179
9f09b1f2
R
1180 for (bb = 0 ; bb < n_basic_blocks; bb++)
1181 {
9f09b1f2
R
1182 if (info[bb].seginfo->mode == m)
1183 SET_BIT (antic[bb], j);
1184
1185 if (info[bb].computing == m)
1186 SET_BIT (comp[bb], j);
1187 }
1188 }
1189
1190 /* Calculate the optimal locations for the
1191 placement mode switches to modes with priority I. */
1192
1193 for (bb = n_basic_blocks - 1; bb >= 0; bb--)
1194 sbitmap_not (kill[bb], transp[bb]);
1195 edge_list = pre_edge_lcm (file, 1, transp, comp, antic,
1196 kill, &insert, &delete);
1197
f4e72d6e 1198 for (j = n_entities - 1; j >= 0; j--)
9f09b1f2
R
1199 {
1200 /* Insert all mode sets that have been inserted by lcm. */
1201 int no_mode = num_modes[entity_map[j]];
f4e72d6e 1202
9f09b1f2
R
1203 /* Wherever we have moved a mode setting upwards in the flow graph,
1204 the blocks between the new setting site and the now redundant
1205 computation ceases to be transparent for any lower-priority
1206 mode of the same entity. First set the aux field of each
1207 insertion site edge non-transparent, then propagate the new
1208 non-transparency from the redundant computation upwards till
1209 we hit an insertion site or an already non-transparent block. */
1210 for (e = NUM_EDGES (edge_list) - 1; e >= 0; e--)
1211 {
1212 edge eg = INDEX_EDGE (edge_list, e);
1213 int mode;
1214 basic_block src_bb;
1215 HARD_REG_SET live_at_edge;
1216 rtx mode_set;
1217
1218 eg->aux = 0;
1219
1220 if (! TEST_BIT (insert[e], j))
1221 continue;
1222
1223 eg->aux = (void *)1;
1224
1225 mode = current_mode[j];
1226 src_bb = eg->src;
1227
f4e72d6e
RK
1228 REG_SET_TO_HARD_REG_SET (live_at_edge,
1229 src_bb->global_live_at_end);
1230
9f09b1f2
R
1231 start_sequence ();
1232 EMIT_MODE_SET (entity_map[j], mode, live_at_edge);
1233 mode_set = gen_sequence ();
1234 end_sequence ();
1235
e8eacc3f
AO
1236 /* If this is an abnormal edge, we'll insert at the end
1237 of the previous block. */
9f09b1f2
R
1238 if (eg->flags & EDGE_ABNORMAL)
1239 {
09d84e04
AO
1240 if (GET_CODE (src_bb->end) == JUMP_INSN)
1241 emit_insn_before (mode_set, src_bb->end);
e8eacc3f
AO
1242 /* It doesn't make sense to switch to normal mode
1243 after a CALL_INSN, so we're going to abort if we
1244 find one. The cases in which a CALL_INSN may
1245 have an abnormal edge are sibcalls and EH edges.
1246 In the case of sibcalls, the dest basic-block is
1247 the EXIT_BLOCK, that runs in normal mode; it is
1248 assumed that a sibcall insn requires normal mode
1249 itself, so no mode switch would be required after
1250 the call (it wouldn't make sense, anyway). In
1251 the case of EH edges, EH entry points also start
1252 in normal mode, so a similar reasoning applies. */
1253 else if (GET_CODE (src_bb->end) == INSN)
09d84e04 1254 src_bb->end = emit_insn_after (mode_set, src_bb->end);
e8eacc3f
AO
1255 else
1256 abort ();
9f09b1f2
R
1257 bb_info[j][src_bb->index].computing = mode;
1258 RESET_BIT (transp[src_bb->index], j);
1259 }
1260 else
1261 {
1262 need_commit = 1;
1263 insert_insn_on_edge (mode_set, eg);
1264 }
9f09b1f2
R
1265 }
1266
1267 for (bb = n_basic_blocks - 1; bb >= 0; bb--)
f4e72d6e
RK
1268 if (TEST_BIT (delete[bb], j))
1269 {
1270 make_preds_opaque (BASIC_BLOCK (bb), j);
1271 /* Cancel the 'deleted' mode set. */
1272 bb_info[j][bb].seginfo->mode = no_mode;
1273 }
9f09b1f2 1274 }
f4e72d6e 1275
9f09b1f2
R
1276 free_edge_list (edge_list);
1277 }
1278
e8eacc3f
AO
1279#ifdef NORMAL_MODE
1280 /* Restore the special status of EXIT_BLOCK. */
1281 n_basic_blocks--;
1282 VARRAY_POP (basic_block_info);
1283 EXIT_BLOCK_PTR->index = EXIT_BLOCK;
1284#endif
b3bb6456 1285
9f09b1f2
R
1286 /* Now output the remaining mode sets in all the segments. */
1287 for (j = n_entities - 1; j >= 0; j--)
1288 {
1270c255
CP
1289 int no_mode = num_modes[entity_map[j]];
1290
e8eacc3f
AO
1291#ifdef NORMAL_MODE
1292 if (bb_info[j][n_basic_blocks].seginfo->mode != no_mode)
1293 {
1294 edge eg;
1295 struct seginfo *ptr = bb_info[j][n_basic_blocks].seginfo;
1296
1297 for (eg = EXIT_BLOCK_PTR->pred; eg; eg = eg->pred_next)
1298 {
1299 rtx mode_set;
1300
1301 if (bb_info[j][eg->src->index].computing == ptr->mode)
1302 continue;
1303
1304 start_sequence ();
1305 EMIT_MODE_SET (entity_map[j], ptr->mode, ptr->regs_live);
1306 mode_set = gen_sequence ();
1307 end_sequence ();
1308
1309 /* If this is an abnormal edge, we'll insert at the end of the
1310 previous block. */
1311 if (eg->flags & EDGE_ABNORMAL)
1312 {
1313 if (GET_CODE (eg->src->end) == JUMP_INSN)
1314 emit_insn_before (mode_set, eg->src->end);
1315 else if (GET_CODE (eg->src->end) == INSN)
1316 eg->src->end = emit_insn_after (mode_set, eg->src->end);
1317 else
1318 abort ();
1319 }
1320 else
1321 {
1322 need_commit = 1;
1323 insert_insn_on_edge (mode_set, eg);
1324 }
1325 }
b3bb6456 1326
e8eacc3f
AO
1327 }
1328#endif
1329
9f09b1f2
R
1330 for (bb = n_basic_blocks - 1; bb >= 0; bb--)
1331 {
1332 struct seginfo *ptr, *next;
1333 for (ptr = bb_info[j][bb].seginfo; ptr; ptr = next)
1334 {
1335 next = ptr->next;
1270c255 1336 if (ptr->mode != no_mode)
9f09b1f2
R
1337 {
1338 rtx mode_set;
1339
1340 start_sequence ();
1341 EMIT_MODE_SET (entity_map[j], ptr->mode, ptr->regs_live);
1342 mode_set = gen_sequence ();
1343 end_sequence ();
1344
25fa8bdc
AO
1345 if (GET_CODE (ptr->insn_ptr) == NOTE
1346 && (NOTE_LINE_NUMBER (ptr->insn_ptr)
1347 == NOTE_INSN_BASIC_BLOCK))
1270c255 1348 emit_block_insn_after (mode_set, ptr->insn_ptr,
b3bb6456 1349 BASIC_BLOCK (ptr->bbnum));
1270c255
CP
1350 else
1351 emit_block_insn_before (mode_set, ptr->insn_ptr,
1352 BASIC_BLOCK (ptr->bbnum));
9f09b1f2 1353 }
f4e72d6e 1354
9f09b1f2
R
1355 free (ptr);
1356 }
1357 }
f4e72d6e 1358
9f09b1f2
R
1359 free (bb_info[j]);
1360 }
1361
1362 /* Finished. Free up all the things we've allocated. */
b3bb6456 1363
9f09b1f2
R
1364 sbitmap_vector_free (kill);
1365 sbitmap_vector_free (antic);
1366 sbitmap_vector_free (transp);
1367 sbitmap_vector_free (comp);
1368 sbitmap_vector_free (delete);
1369 sbitmap_vector_free (insert);
1370
1371 if (need_commit)
1372 commit_edge_insertions ();
97d36f45
RH
1373
1374 /* Ideally we'd figure out what blocks were affected and start from
1375 there, but this is enormously complicated by commit_edge_insertions,
1376 which would screw up any indicies we'd collected, and also need to
1377 be involved in the update. Bail and recompute global life info for
1378 everything. */
1379
1380 allocate_reg_life_data ();
1381 update_life_info (NULL, UPDATE_LIFE_GLOBAL_RM_NOTES,
1382 (PROP_DEATH_NOTES | PROP_KILL_DEAD_CODE
1383 | PROP_SCAN_DEAD_CODE | PROP_REG_INFO));
1384
1385 return 1;
9f09b1f2 1386}
97d36f45 1387#endif /* OPTIMIZE_MODE_SWITCHING */
This page took 0.827541 seconds and 5 git commands to generate.