]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/lcm.c
regenerate
[thirdparty/gcc.git] / gcc / lcm.c
CommitLineData
9ca8d59e 1/* Generic partial redundancy elimination with lazy code motion support.
b25a2bca 2 Copyright (C) 1998, 1999, 2000, 2001 Free Software Foundation, Inc.
e48ba7af 3
4This file is part of GNU CC.
5
6GNU CC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 2, or (at your option)
9any later version.
10
11GNU CC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU CC; see the file COPYING. If not, write to
18the Free Software Foundation, 59 Temple Place - Suite 330,
19Boston, MA 02111-1307, USA. */
20
21/* These routines are meant to be used by various optimization
22 passes which can be modeled as lazy code motion problems.
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"
e48ba7af 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"
18862b5a 62#include "tm_p.h"
9ca8d59e 63
18862b5a 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"
e48ba7af 67
7bcd381b 68/* Edge based LCM routines. */
9ca8d59e 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 *));
7bcd381b 82
83/* Edge based LCM routines on a reverse flowgraph. */
9ca8d59e 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 *));
7bcd381b 95\f
96/* Edge based lcm routines. */
97
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.
100 Other than that, its pretty much identical to compute_antinout. */
e48ba7af 101
102static void
7bcd381b 103compute_antinout_edge (antloc, transp, antin, antout)
e48ba7af 104 sbitmap *antloc;
105 sbitmap *transp;
106 sbitmap *antin;
107 sbitmap *antout;
108{
2325f0e2 109 int bb;
7bcd381b 110 edge e;
2c59145b 111 basic_block *worklist, *qin, *qout, *qend;
112 unsigned int qlen;
e48ba7af 113
2325f0e2 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. */
2c59145b 117 qin = qout = worklist
9ca8d59e 118 = (basic_block *) xmalloc (sizeof (basic_block) * n_basic_blocks);
e48ba7af 119
2325f0e2 120 /* We want a maximal solution, so make an optimistic initialization of
121 ANTIN. */
122 sbitmap_vector_ones (antin, n_basic_blocks);
e48ba7af 123
5d6931e2 124 /* Put every block on the worklist; this is necessary because of the
125 optimistic initialization of ANTIN above. */
2c59145b 126 for (bb = n_basic_blocks - 1; bb >= 0; bb--)
e48ba7af 127 {
2c59145b 128 *qin++ = BASIC_BLOCK (bb);
5d6931e2 129 BASIC_BLOCK (bb)->aux = BASIC_BLOCK (bb);
2325f0e2 130 }
2c59145b 131
132 qin = worklist;
133 qend = &worklist[n_basic_blocks];
134 qlen = n_basic_blocks;
e48ba7af 135
5d6931e2 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
2325f0e2 141 /* Iterate until the worklist is empty. */
2c59145b 142 while (qlen)
2325f0e2 143 {
144 /* Take the first entry off the worklist. */
2c59145b 145 basic_block b = *qout++;
2325f0e2 146 bb = b->index;
2c59145b 147 qlen--;
148
149 if (qout >= qend)
150 qout = worklist;
e48ba7af 151
2325f0e2 152 if (b->aux == EXIT_BLOCK_PTR)
9ca8d59e 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]);
2325f0e2 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 }
7bcd381b 164
2325f0e2 165 if (sbitmap_a_or_b_and_c (antin[bb], antloc[bb], transp[bb], antout[bb]))
9ca8d59e 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)
e48ba7af 171 {
2c59145b 172 *qin++ = e->src;
9ca8d59e 173 e->src->aux = e;
2c59145b 174 qlen++;
175 if (qin >= qend)
176 qin = worklist;
e48ba7af 177 }
e48ba7af 178 }
9ca8d59e 179
2c59145b 180 free (worklist);
e48ba7af 181}
182
7bcd381b 183/* Compute the earliest vector for edge based lcm. */
9ca8d59e 184
e48ba7af 185static void
7bcd381b 186compute_earliest (edge_list, n_exprs, antin, antout, avout, kill, earliest)
187 struct edge_list *edge_list;
e48ba7af 188 int n_exprs;
7bcd381b 189 sbitmap *antin, *antout, *avout, *kill, *earliest;
e48ba7af 190{
7bcd381b 191 sbitmap difference, temp_bitmap;
192 int x, num_edges;
193 basic_block pred, succ;
e48ba7af 194
7bcd381b 195 num_edges = NUM_EDGES (edge_list);
e48ba7af 196
7bcd381b 197 difference = sbitmap_alloc (n_exprs);
198 temp_bitmap = sbitmap_alloc (n_exprs);
e48ba7af 199
7bcd381b 200 for (x = 0; x < num_edges; x++)
e48ba7af 201 {
7bcd381b 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 {
1287c919 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)
9ca8d59e 213 sbitmap_zero (earliest[x]);
7bcd381b 214 else
e48ba7af 215 {
7bcd381b 216 sbitmap_difference (difference, antin[succ->index],
217 avout[pred->index]);
218 sbitmap_not (temp_bitmap, antout[pred->index]);
9ca8d59e 219 sbitmap_a_and_b_or_c (earliest[x], difference,
220 kill[pred->index], temp_bitmap);
e48ba7af 221 }
222 }
e48ba7af 223 }
9ca8d59e 224
e48ba7af 225 free (temp_bitmap);
7bcd381b 226 free (difference);
e48ba7af 227}
228
2325f0e2 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. */
257
e48ba7af 258static void
2325f0e2 259compute_laterin (edge_list, earliest, antloc, later, laterin)
7bcd381b 260 struct edge_list *edge_list;
7bcd381b 261 sbitmap *earliest, *antloc, *later, *laterin;
e48ba7af 262{
2325f0e2 263 int bb, num_edges, i;
264 edge e;
2c59145b 265 basic_block *worklist, *qin, *qout, *qend;
266 unsigned int qlen;
e48ba7af 267
7bcd381b 268 num_edges = NUM_EDGES (edge_list);
e48ba7af 269
2325f0e2 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. */
2c59145b 273 qin = qout = worklist
9ca8d59e 274 = (basic_block *) xmalloc (sizeof (basic_block) * (n_basic_blocks + 1));
2325f0e2 275
276 /* Initialize a mapping from each edge to its index. */
277 for (i = 0; i < num_edges; i++)
9ffd5d6d 278 INDEX_EDGE (edge_list, i)->aux = (void *) (size_t) i;
2325f0e2 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
048599b9 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)
9ca8d59e 297 sbitmap_copy (later[(size_t) e->aux], earliest[(size_t) e->aux]);
048599b9 298
2325f0e2 299 /* Add all the blocks to the worklist. This prevents an early exit from
300 the loop given our optimistic initialization of LATER above. */
2c59145b 301 for (bb = 0; bb < n_basic_blocks; bb++)
e48ba7af 302 {
2325f0e2 303 basic_block b = BASIC_BLOCK (bb);
2c59145b 304 *qin++ = b;
2325f0e2 305 b->aux = b;
7bcd381b 306 }
2c59145b 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
310 of n_basic_blocks + 1 elements is not encessary. */
311 qend = &worklist[n_basic_blocks];
312 qlen = n_basic_blocks;
7bcd381b 313
2325f0e2 314 /* Iterate until the worklist is empty. */
2c59145b 315 while (qlen)
7bcd381b 316 {
2325f0e2 317 /* Take the first entry off the worklist. */
2c59145b 318 basic_block b = *qout++;
2325f0e2 319 b->aux = NULL;
2c59145b 320 qlen--;
321 if (qout >= qend)
322 qout = worklist;
2325f0e2 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)
9ffd5d6d 328 sbitmap_a_and_b (laterin[bb], laterin[bb], later[(size_t)e->aux]);
2325f0e2 329
330 /* Calculate LATER for all outgoing edges. */
331 for (e = b->succ; e != NULL; e = e->succ_next)
9ca8d59e 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 {
2c59145b 340 *qin++ = e->dest;
9ca8d59e 341 e->dest->aux = e;
2c59145b 342 qlen++;
343 if (qin >= qend)
344 qin = worklist;
9ca8d59e 345 }
e48ba7af 346 }
347
2325f0e2 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],
9ffd5d6d 355 later[(size_t) e->aux]);
2325f0e2 356
2c59145b 357 free (worklist);
e48ba7af 358}
359
7bcd381b 360/* Compute the insertion and deletion points for edge based LCM. */
9ca8d59e 361
7bcd381b 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;
e48ba7af 369
7bcd381b 370 for (x = 0; x < n_basic_blocks; x++)
371 sbitmap_difference (delete[x], antloc[x], laterin[x]);
372
373 for (x = 0; x < NUM_EDGES (edge_list); x++)
374 {
375 basic_block b = INDEX_EDGE_SUCC_BB (edge_list, x);
9ca8d59e 376
7bcd381b 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}
e48ba7af 383
9ca8d59e 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. */
e48ba7af 387
7bcd381b 388struct edge_list *
389pre_edge_lcm (file, n_exprs, transp, avloc, antloc, kill, insert, delete)
27548a74 390 FILE *file ATTRIBUTE_UNUSED;
e48ba7af 391 int n_exprs;
7bcd381b 392 sbitmap *transp;
393 sbitmap *avloc;
e48ba7af 394 sbitmap *antloc;
7bcd381b 395 sbitmap *kill;
396 sbitmap **insert;
397 sbitmap **delete;
e48ba7af 398{
7bcd381b 399 sbitmap *antin, *antout, *earliest;
400 sbitmap *avin, *avout;
401 sbitmap *later, *laterin;
402 struct edge_list *edge_list;
403 int num_edges;
e48ba7af 404
7bcd381b 405 edge_list = create_edge_list ();
406 num_edges = NUM_EDGES (edge_list);
e48ba7af 407
7bcd381b 408#ifdef LCM_DEBUG_INFO
409 if (file)
e48ba7af 410 {
7bcd381b 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);
e48ba7af 418 }
7bcd381b 419#endif
e48ba7af 420
7bcd381b 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);
cca23eb2 425 sbitmap_vector_free (avin);
e48ba7af 426
7bcd381b 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);
e48ba7af 431
7bcd381b 432#ifdef LCM_DEBUG_INFO
433 if (file)
e48ba7af 434 {
7bcd381b 435 dump_sbitmap_vector (file, "antin", "", antin, n_basic_blocks);
436 dump_sbitmap_vector (file, "antout", "", antout, n_basic_blocks);
e48ba7af 437 }
7bcd381b 438#endif
e48ba7af 439
7bcd381b 440 /* Compute earliestness. */
441 earliest = sbitmap_vector_alloc (num_edges, n_exprs);
442 compute_earliest (edge_list, n_exprs, antin, antout, avout, kill, earliest);
e48ba7af 443
7bcd381b 444#ifdef LCM_DEBUG_INFO
445 if (file)
446 dump_sbitmap_vector (file, "earliest", "", earliest, num_edges);
447#endif
e48ba7af 448
cca23eb2 449 sbitmap_vector_free (antout);
450 sbitmap_vector_free (antin);
451 sbitmap_vector_free (avout);
e48ba7af 452
7bcd381b 453 later = sbitmap_vector_alloc (num_edges, n_exprs);
9ca8d59e 454
7bcd381b 455 /* Allocate an extra element for the exit block in the laterin vector. */
456 laterin = sbitmap_vector_alloc (n_basic_blocks + 1, n_exprs);
2325f0e2 457 compute_laterin (edge_list, earliest, antloc, later, laterin);
458
7bcd381b 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
e48ba7af 466
cca23eb2 467 sbitmap_vector_free (earliest);
7bcd381b 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);
e48ba7af 472
cca23eb2 473 sbitmap_vector_free (laterin);
474 sbitmap_vector_free (later);
7bcd381b 475
476#ifdef LCM_DEBUG_INFO
477 if (file)
e48ba7af 478 {
7bcd381b 479 dump_sbitmap_vector (file, "pre_insert_map", "", *insert, num_edges);
9ca8d59e 480 dump_sbitmap_vector (file, "pre_delete_map", "", *delete,
481 n_basic_blocks);
e48ba7af 482 }
7bcd381b 483#endif
e48ba7af 484
7bcd381b 485 return edge_list;
486}
e48ba7af 487
7bcd381b 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. */
9ca8d59e 490
2325f0e2 491void
7bcd381b 492compute_available (avloc, kill, avout, avin)
493 sbitmap *avloc, *kill, *avout, *avin;
e48ba7af 494{
2325f0e2 495 int bb;
496 edge e;
2c59145b 497 basic_block *worklist, *qin, *qout, *qend;
498 unsigned int qlen;
e48ba7af 499
2325f0e2 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. */
2c59145b 503 qin = qout = worklist
9ca8d59e 504 = (basic_block *) xmalloc (sizeof (basic_block) * n_basic_blocks);
e48ba7af 505
2325f0e2 506 /* We want a maximal solution. */
507 sbitmap_vector_ones (avout, n_basic_blocks);
508
5d6931e2 509 /* Put every block on the worklist; this is necessary because of the
510 optimistic initialization of AVOUT above. */
2c59145b 511 for (bb = 0; bb < n_basic_blocks; bb++)
e48ba7af 512 {
2c59145b 513 *qin++ = BASIC_BLOCK (bb);
5d6931e2 514 BASIC_BLOCK (bb)->aux = BASIC_BLOCK (bb);
e48ba7af 515 }
2c59145b 516
517 qin = worklist;
518 qend = &worklist[n_basic_blocks];
519 qlen = n_basic_blocks;
2325f0e2 520
5d6931e2 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
2325f0e2 526 /* Iterate until the worklist is empty. */
2c59145b 527 while (qlen)
2325f0e2 528 {
529 /* Take the first entry off the worklist. */
2c59145b 530 basic_block b = *qout++;
2325f0e2 531 bb = b->index;
2c59145b 532 qlen--;
533
534 if (qout >= qend)
535 qout = worklist;
2325f0e2 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)
9ca8d59e 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]);
2325f0e2 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]))
9ca8d59e 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)
2325f0e2 558 {
2c59145b 559 *qin++ = e->dest;
9ca8d59e 560 e->dest->aux = e;
2c59145b 561 qlen++;
562
563 if (qin >= qend)
564 qin = worklist;
2325f0e2 565 }
2325f0e2 566 }
9ca8d59e 567
2c59145b 568 free (worklist);
e48ba7af 569}
570
7bcd381b 571/* Compute the farthest vector for edge based lcm. */
9ca8d59e 572
e48ba7af 573static void
7bcd381b 574compute_farthest (edge_list, n_exprs, st_avout, st_avin, st_antin,
575 kill, farthest)
576 struct edge_list *edge_list;
e48ba7af 577 int n_exprs;
7bcd381b 578 sbitmap *st_avout, *st_avin, *st_antin, *kill, *farthest;
e48ba7af 579{
7bcd381b 580 sbitmap difference, temp_bitmap;
581 int x, num_edges;
582 basic_block pred, succ;
e48ba7af 583
7bcd381b 584 num_edges = NUM_EDGES (edge_list);
e48ba7af 585
7bcd381b 586 difference = sbitmap_alloc (n_exprs);
587 temp_bitmap = sbitmap_alloc (n_exprs);
e48ba7af 588
7bcd381b 589 for (x = 0; x < num_edges; x++)
e48ba7af 590 {
7bcd381b 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
e48ba7af 596 {
7bcd381b 597 if (pred == ENTRY_BLOCK_PTR)
9ca8d59e 598 sbitmap_zero (farthest[x]);
7bcd381b 599 else
600 {
601 sbitmap_difference (difference, st_avout[pred->index],
602 st_antin[succ->index]);
603 sbitmap_not (temp_bitmap, st_avin[succ->index]);
604 sbitmap_a_and_b_or_c (farthest[x], difference,
605 kill[succ->index], temp_bitmap);
606 }
e48ba7af 607 }
e48ba7af 608 }
9ca8d59e 609
e48ba7af 610 free (temp_bitmap);
7bcd381b 611 free (difference);
e48ba7af 612}
613
2325f0e2 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
e48ba7af 619static void
2325f0e2 620compute_nearerout (edge_list, farthest, st_avloc, nearer, nearerout)
7bcd381b 621 struct edge_list *edge_list;
7bcd381b 622 sbitmap *farthest, *st_avloc, *nearer, *nearerout;
e48ba7af 623{
2325f0e2 624 int bb, num_edges, i;
625 edge e;
626 basic_block *worklist, *tos;
e48ba7af 627
7bcd381b 628 num_edges = NUM_EDGES (edge_list);
e48ba7af 629
2325f0e2 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. */
9ca8d59e 633 tos = worklist
634 = (basic_block *) xmalloc (sizeof (basic_block) * (n_basic_blocks + 1));
e48ba7af 635
2325f0e2 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++)
9ffd5d6d 639 INDEX_EDGE (edge_list, i)->aux = (void *) (size_t) i;
7bcd381b 640
2325f0e2 641 /* We want a maximal solution. */
642 sbitmap_vector_ones (nearer, num_edges);
643
048599b9 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)
8b863f57 649 sbitmap_copy (nearer[(size_t)e->aux], farthest[(size_t)e->aux]);
048599b9 650
2325f0e2 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++)
e48ba7af 654 {
2325f0e2 655 basic_block b = BASIC_BLOCK (bb);
656 *tos++ = b;
657 b->aux = b;
7bcd381b 658 }
2325f0e2 659
660 /* Iterate until the worklist is empty. */
661 while (tos != worklist)
7bcd381b 662 {
2325f0e2 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)
9ffd5d6d 671 sbitmap_a_and_b (nearerout[bb], nearerout[bb],
672 nearer[(size_t) e->aux]);
2325f0e2 673
674 /* Calculate NEARER for all incoming edges. */
675 for (e = b->pred; e != NULL; e = e->pred_next)
9ca8d59e 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 }
7bcd381b 687 }
e48ba7af 688
2325f0e2 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],
9ffd5d6d 696 nearer[(size_t) e->aux]);
2325f0e2 697
698 free (tos);
7bcd381b 699}
e48ba7af 700
7bcd381b 701/* Compute the insertion and deletion points for edge based LCM. */
9ca8d59e 702
e48ba7af 703static void
7bcd381b 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;
e48ba7af 708{
7bcd381b 709 int x;
e48ba7af 710
7bcd381b 711 for (x = 0; x < n_basic_blocks; x++)
712 sbitmap_difference (delete[x], st_avloc[x], nearerout[x]);
713
714 for (x = 0; x < NUM_EDGES (edge_list); x++)
e48ba7af 715 {
7bcd381b 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]);
e48ba7af 719 else
7bcd381b 720 sbitmap_difference (insert[x], nearer[x], nearerout[b->index]);
e48ba7af 721 }
e48ba7af 722}
723
7bcd381b 724/* Given local properties TRANSP, ST_AVLOC, ST_ANTLOC, KILL return the
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. */
e48ba7af 728
7bcd381b 729struct edge_list *
730pre_edge_rev_lcm (file, n_exprs, transp, st_avloc, st_antloc, kill,
731 insert, delete)
27548a74 732 FILE *file ATTRIBUTE_UNUSED;
7bcd381b 733 int n_exprs;
734 sbitmap *transp;
735 sbitmap *st_avloc;
736 sbitmap *st_antloc;
737 sbitmap *kill;
738 sbitmap **insert;
739 sbitmap **delete;
e48ba7af 740{
7bcd381b 741 sbitmap *st_antin, *st_antout;
742 sbitmap *st_avout, *st_avin, *farthest;
743 sbitmap *nearer, *nearerout;
744 struct edge_list *edge_list;
27548a74 745 int num_edges;
7bcd381b 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
e48ba7af 775
7bcd381b 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
e48ba7af 783
7bcd381b 784 /* Compute farthestness. */
785 farthest = sbitmap_vector_alloc (num_edges, n_exprs);
786 compute_farthest (edge_list, n_exprs, st_avout, st_avin, st_antin,
787 kill, farthest);
788
789#ifdef LCM_DEBUG_INFO
790 if (file)
791 dump_sbitmap_vector (file, "farthest", "", farthest, num_edges);
792#endif
793
cca23eb2 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);
7bcd381b 799
800 nearer = sbitmap_vector_alloc (num_edges, n_exprs);
9ca8d59e 801
7bcd381b 802 /* Allocate an extra element for the entry block. */
803 nearerout = sbitmap_vector_alloc (n_basic_blocks + 1, n_exprs);
2325f0e2 804 compute_nearerout (edge_list, farthest, st_avloc, nearer, nearerout);
7bcd381b 805
806#ifdef LCM_DEBUG_INFO
807 if (file)
e48ba7af 808 {
7bcd381b 809 dump_sbitmap_vector (file, "nearerout", "", nearerout,
810 n_basic_blocks + 1);
811 dump_sbitmap_vector (file, "nearer", "", nearer, num_edges);
e48ba7af 812 }
7bcd381b 813#endif
814
cca23eb2 815 sbitmap_vector_free (farthest);
7bcd381b 816
817 *insert = sbitmap_vector_alloc (num_edges, n_exprs);
818 *delete = sbitmap_vector_alloc (n_basic_blocks, n_exprs);
9ca8d59e 819 compute_rev_insert_delete (edge_list, st_avloc, nearer, nearerout,
820 *insert, *delete);
7bcd381b 821
cca23eb2 822 sbitmap_vector_free (nearerout);
823 sbitmap_vector_free (nearer);
7bcd381b 824
825#ifdef LCM_DEBUG_INFO
826 if (file)
827 {
828 dump_sbitmap_vector (file, "pre_insert_map", "", *insert, num_edges);
9ca8d59e 829 dump_sbitmap_vector (file, "pre_delete_map", "", *delete,
830 n_basic_blocks);
7bcd381b 831 }
832#endif
7bcd381b 833 return edge_list;
e48ba7af 834}
18862b5a 835
9ca8d59e 836/* Mode switching:
837
838 The algorithm for setting the modes consists of scanning the insn list
18862b5a 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
858 either single or double mode to be set.
859 MODE is the mode this insn must be executed in.
f913e47c 860 INSN_PTR is the insn to be executed (may be the note that marks the
861 beginning of a basic block).
18862b5a 862 BBNUM is the flow graph basic block this insn occurs in.
863 NEXT is the next insn in the same basic block. */
864struct seginfo
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
29768226 881#ifdef OPTIMIZE_MODE_SWITCHING
18862b5a 882static sbitmap *antic;
883static sbitmap *transp;
884static sbitmap *comp;
885static sbitmap *delete;
886static sbitmap *insert;
887
7dff60c8 888static struct seginfo * new_seginfo PARAMS ((int, rtx, int, HARD_REG_SET));
18862b5a 889static void add_seginfo PARAMS ((struct bb_info *, struct seginfo *));
18862b5a 890static void reg_dies PARAMS ((rtx, HARD_REG_SET));
891static void reg_becomes_live PARAMS ((rtx, rtx, void *));
29768226 892static void make_preds_opaque PARAMS ((basic_block, int));
893#endif
894\f
895#ifdef OPTIMIZE_MODE_SWITCHING
18862b5a 896
897/* This function will allocate a new BBINFO structure, initialized
7dff60c8 898 with the MODE, INSN, and basic block BB parameters. */
29768226 899
18862b5a 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
917/* Add a seginfo element to the end of a list.
918 HEAD is a pointer to the list beginning.
919 INFO is the structure to be linked in. */
29768226 920
18862b5a 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. */
29768226 944
18862b5a 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;
9ca8d59e 955
18862b5a 956 if (e->aux || ! TEST_BIT (transp[pb->index], j))
957 continue;
9ca8d59e 958
18862b5a 959 RESET_BIT (transp[pb->index], j);
960 make_preds_opaque (pb, j);
961 }
962}
963
964/* Record in LIVE that register REG died. */
29768226 965
18862b5a 966static void
967reg_dies (reg, live)
968 rtx reg;
969 HARD_REG_SET live;
970{
9ca8d59e 971 int regno, nregs;
18862b5a 972
973 if (GET_CODE (reg) != REG)
974 return;
9ca8d59e 975
18862b5a 976 regno = REGNO (reg);
977 if (regno < FIRST_PSEUDO_REGISTER)
9ca8d59e 978 for (nregs = HARD_REGNO_NREGS (regno, GET_MODE (reg)) - 1; nregs >= 0;
979 nregs--)
980 CLEAR_HARD_REG_BIT (live, regno + nregs);
18862b5a 981}
982
983/* Record in LIVE that register REG became live.
984 This is called via note_stores. */
29768226 985
18862b5a 986static void
987reg_becomes_live (reg, setter, live)
988 rtx reg;
989 rtx setter ATTRIBUTE_UNUSED;
990 void *live;
991{
9ca8d59e 992 int regno, nregs;
18862b5a 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)
9ca8d59e 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);
18862b5a 1005}
1006
b78e14a8 1007/* Find all insns that need a particular mode setting, and insert the
1008 necessary mode switches. Return true if we did work. */
9ca8d59e 1009
b78e14a8 1010int
18862b5a 1011optimize_mode_switching (file)
b78e14a8 1012 FILE *file;
18862b5a 1013{
18862b5a 1014 rtx insn;
1015 int bb, e;
1016 edge eg;
1017 int need_commit = 0;
1018 sbitmap *kill;
1019 struct edge_list *edge_list;
1020 static int num_modes[] = NUM_MODES_FOR_MODE_SWITCHING;
1021#define N_ENTITIES (sizeof num_modes / sizeof (int))
1022 int entity_map[N_ENTITIES];
1023 struct bb_info *bb_info[N_ENTITIES];
1024 int i, j;
1025 int n_entities;
1026 int max_num_modes = 0;
1027
1287c919 1028#ifdef NORMAL_MODE
1029 /* Increment n_basic_blocks before allocating bb_info. */
1030 n_basic_blocks++;
1031#endif
1032
18862b5a 1033 for (e = N_ENTITIES - 1, n_entities = 0; e >= 0; e--)
9ca8d59e 1034 if (OPTIMIZE_MODE_SWITCHING (e))
1035 {
1036 /* Create the list of segments within each basic block. */
1037 bb_info[n_entities]
1038 = (struct bb_info *) xcalloc (n_basic_blocks, sizeof **bb_info);
1039 entity_map[n_entities++] = e;
1040 if (num_modes[e] > max_num_modes)
1041 max_num_modes = num_modes[e];
1042 }
1043
1287c919 1044#ifdef NORMAL_MODE
1045 /* Decrement it back in case we return below. */
1046 n_basic_blocks--;
1047#endif
1048
18862b5a 1049 if (! n_entities)
b78e14a8 1050 return 0;
18862b5a 1051
1287c919 1052#ifdef NORMAL_MODE
1053 /* We're going to pretend the EXIT_BLOCK is a regular basic block,
1054 so that switching back to normal mode when entering the
1055 EXIT_BLOCK isn't optimized away. We do this by incrementing the
1056 basic block count, growing the VARRAY of basic_block_info and
1057 appending the EXIT_BLOCK_PTR to it. */
1058 n_basic_blocks++;
1059 if (VARRAY_SIZE (basic_block_info) < n_basic_blocks)
1060 VARRAY_GROW (basic_block_info, n_basic_blocks);
1061 BASIC_BLOCK (n_basic_blocks - 1) = EXIT_BLOCK_PTR;
1062 EXIT_BLOCK_PTR->index = n_basic_blocks - 1;
1063#endif
1064
18862b5a 1065 /* Create the bitmap vectors. */
1066
1067 antic = sbitmap_vector_alloc (n_basic_blocks, n_entities);
1068 transp = sbitmap_vector_alloc (n_basic_blocks, n_entities);
1069 comp = sbitmap_vector_alloc (n_basic_blocks, n_entities);
1070
1071 sbitmap_vector_ones (transp, n_basic_blocks);
1072
1073 for (j = n_entities - 1; j >= 0; j--)
1074 {
1075 int e = entity_map[j];
1076 int no_mode = num_modes[e];
1077 struct bb_info *info = bb_info[j];
1078
1079 /* Determine what the first use (if any) need for a mode of entity E is.
b78e14a8 1080 This will be the mode that is anticipatable for this block.
18862b5a 1081 Also compute the initial transparency settings. */
1082 for (bb = 0 ; bb < n_basic_blocks; bb++)
1083 {
1084 struct seginfo *ptr;
1085 int last_mode = no_mode;
1086 HARD_REG_SET live_now;
1087
1088 REG_SET_TO_HARD_REG_SET (live_now,
1089 BASIC_BLOCK (bb)->global_live_at_start);
1090 for (insn = BLOCK_HEAD (bb);
1091 insn != NULL && insn != NEXT_INSN (BLOCK_END (bb));
1092 insn = NEXT_INSN (insn))
1093 {
9204e736 1094 if (INSN_P (insn))
18862b5a 1095 {
1096 int mode = MODE_NEEDED (e, insn);
1097 rtx link;
1098
1099 if (mode != no_mode && mode != last_mode)
1100 {
1101 last_mode = mode;
1102 ptr = new_seginfo (mode, insn, bb, live_now);
1103 add_seginfo (info + bb, ptr);
1104 RESET_BIT (transp[bb], j);
1105 }
1106
1107 /* Update LIVE_NOW. */
1108 for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
1109 if (REG_NOTE_KIND (link) == REG_DEAD)
1110 reg_dies (XEXP (link, 0), live_now);
9ca8d59e 1111
18862b5a 1112 note_stores (PATTERN (insn), reg_becomes_live, &live_now);
1113 for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
1114 if (REG_NOTE_KIND (link) == REG_UNUSED)
1115 reg_dies (XEXP (link, 0), live_now);
1116 }
1117 }
9ca8d59e 1118
18862b5a 1119 info[bb].computing = last_mode;
1120 /* Check for blocks without ANY mode requirements. */
1121 if (last_mode == no_mode)
1122 {
1123 ptr = new_seginfo (no_mode, insn, bb, live_now);
1124 add_seginfo (info + bb, ptr);
1125 }
1126 }
7dff60c8 1127#ifdef NORMAL_MODE
18862b5a 1128 {
7dff60c8 1129 int mode = NORMAL_MODE (e);
9ca8d59e 1130
18862b5a 1131 if (mode != no_mode)
1132 {
1133 for (eg = ENTRY_BLOCK_PTR->succ; eg; eg = eg->succ_next)
1134 {
1135 bb = eg->dest->index;
1136
1137 /* By always making this nontransparent, we save
1138 an extra check in make_preds_opaque. We also
1139 need this to avoid confusing pre_edge_lcm when
1140 antic is cleared but transp and comp are set. */
1141 RESET_BIT (transp[bb], j);
1142
1143 /* If the block already has MODE, pretend it
1144 has none (because we don't need to set it),
1145 but retain whatever mode it computes. */
1146 if (info[bb].seginfo->mode == mode)
9ca8d59e 1147 info[bb].seginfo->mode = no_mode;
1148
1149 /* Insert a fake computing definition of MODE into entry
1150 blocks which compute no mode. This represents the mode on
1151 entry. */
18862b5a 1152 else if (info[bb].computing == no_mode)
1153 {
1154 info[bb].computing = mode;
1155 info[bb].seginfo->mode = no_mode;
1156 }
1157 }
1287c919 1158
1159 bb = n_basic_blocks - 1;
1160 info[bb].seginfo->mode = mode;
18862b5a 1161 }
1162 }
7dff60c8 1163#endif /* NORMAL_MODE */
18862b5a 1164 }
1165
1166 kill = sbitmap_vector_alloc (n_basic_blocks, n_entities);
1167 for (i = 0; i < max_num_modes; i++)
1168 {
1169 int current_mode[N_ENTITIES];
1170
1171 /* Set the anticipatable and computing arrays. */
1172 sbitmap_vector_zero (antic, n_basic_blocks);
1173 sbitmap_vector_zero (comp, n_basic_blocks);
1174 for (j = n_entities - 1; j >= 0; j--)
1175 {
1176 int m = current_mode[j] = MODE_PRIORITY_TO_MODE (entity_map[j], i);
1177 struct bb_info *info = bb_info[j];
1178
1179 for (bb = 0 ; bb < n_basic_blocks; bb++)
1180 {
18862b5a 1181 if (info[bb].seginfo->mode == m)
1182 SET_BIT (antic[bb], j);
1183
1184 if (info[bb].computing == m)
1185 SET_BIT (comp[bb], j);
1186 }
1187 }
1188
1189 /* Calculate the optimal locations for the
1190 placement mode switches to modes with priority I. */
1191
1192 for (bb = n_basic_blocks - 1; bb >= 0; bb--)
1193 sbitmap_not (kill[bb], transp[bb]);
1194 edge_list = pre_edge_lcm (file, 1, transp, comp, antic,
1195 kill, &insert, &delete);
1196
9ca8d59e 1197 for (j = n_entities - 1; j >= 0; j--)
18862b5a 1198 {
1199 /* Insert all mode sets that have been inserted by lcm. */
1200 int no_mode = num_modes[entity_map[j]];
9ca8d59e 1201
18862b5a 1202 /* Wherever we have moved a mode setting upwards in the flow graph,
1203 the blocks between the new setting site and the now redundant
1204 computation ceases to be transparent for any lower-priority
1205 mode of the same entity. First set the aux field of each
1206 insertion site edge non-transparent, then propagate the new
1207 non-transparency from the redundant computation upwards till
1208 we hit an insertion site or an already non-transparent block. */
1209 for (e = NUM_EDGES (edge_list) - 1; e >= 0; e--)
1210 {
1211 edge eg = INDEX_EDGE (edge_list, e);
1212 int mode;
1213 basic_block src_bb;
1214 HARD_REG_SET live_at_edge;
1215 rtx mode_set;
1216
1217 eg->aux = 0;
1218
1219 if (! TEST_BIT (insert[e], j))
1220 continue;
1221
1222 eg->aux = (void *)1;
1223
1224 mode = current_mode[j];
1225 src_bb = eg->src;
1226
9ca8d59e 1227 REG_SET_TO_HARD_REG_SET (live_at_edge,
1228 src_bb->global_live_at_end);
1229
18862b5a 1230 start_sequence ();
1231 EMIT_MODE_SET (entity_map[j], mode, live_at_edge);
1232 mode_set = gen_sequence ();
1233 end_sequence ();
1234
1287c919 1235 /* If this is an abnormal edge, we'll insert at the end
1236 of the previous block. */
18862b5a 1237 if (eg->flags & EDGE_ABNORMAL)
1238 {
a24d0647 1239 if (GET_CODE (src_bb->end) == JUMP_INSN)
1240 emit_insn_before (mode_set, src_bb->end);
1287c919 1241 /* It doesn't make sense to switch to normal mode
1242 after a CALL_INSN, so we're going to abort if we
1243 find one. The cases in which a CALL_INSN may
1244 have an abnormal edge are sibcalls and EH edges.
1245 In the case of sibcalls, the dest basic-block is
1246 the EXIT_BLOCK, that runs in normal mode; it is
1247 assumed that a sibcall insn requires normal mode
1248 itself, so no mode switch would be required after
1249 the call (it wouldn't make sense, anyway). In
1250 the case of EH edges, EH entry points also start
1251 in normal mode, so a similar reasoning applies. */
1252 else if (GET_CODE (src_bb->end) == INSN)
a24d0647 1253 src_bb->end = emit_insn_after (mode_set, src_bb->end);
1287c919 1254 else
1255 abort ();
18862b5a 1256 bb_info[j][src_bb->index].computing = mode;
1257 RESET_BIT (transp[src_bb->index], j);
1258 }
1259 else
1260 {
1261 need_commit = 1;
1262 insert_insn_on_edge (mode_set, eg);
1263 }
18862b5a 1264 }
1265
1266 for (bb = n_basic_blocks - 1; bb >= 0; bb--)
9ca8d59e 1267 if (TEST_BIT (delete[bb], j))
1268 {
1269 make_preds_opaque (BASIC_BLOCK (bb), j);
1270 /* Cancel the 'deleted' mode set. */
1271 bb_info[j][bb].seginfo->mode = no_mode;
1272 }
18862b5a 1273 }
9ca8d59e 1274
18862b5a 1275 free_edge_list (edge_list);
1276 }
1277
1287c919 1278#ifdef NORMAL_MODE
1279 /* Restore the special status of EXIT_BLOCK. */
1280 n_basic_blocks--;
1281 VARRAY_POP (basic_block_info);
1282 EXIT_BLOCK_PTR->index = EXIT_BLOCK;
1283#endif
1284
18862b5a 1285 /* Now output the remaining mode sets in all the segments. */
1286 for (j = n_entities - 1; j >= 0; j--)
1287 {
7dff60c8 1288 int no_mode = num_modes[entity_map[j]];
1289
1287c919 1290#ifdef NORMAL_MODE
1291 if (bb_info[j][n_basic_blocks].seginfo->mode != no_mode)
1292 {
1293 edge eg;
1294 struct seginfo *ptr = bb_info[j][n_basic_blocks].seginfo;
1295
1296 for (eg = EXIT_BLOCK_PTR->pred; eg; eg = eg->pred_next)
1297 {
1298 rtx mode_set;
1299
1300 if (bb_info[j][eg->src->index].computing == ptr->mode)
1301 continue;
1302
1303 start_sequence ();
1304 EMIT_MODE_SET (entity_map[j], ptr->mode, ptr->regs_live);
1305 mode_set = gen_sequence ();
1306 end_sequence ();
1307
1308 /* If this is an abnormal edge, we'll insert at the end of the
1309 previous block. */
1310 if (eg->flags & EDGE_ABNORMAL)
1311 {
1312 if (GET_CODE (eg->src->end) == JUMP_INSN)
1313 emit_insn_before (mode_set, eg->src->end);
1314 else if (GET_CODE (eg->src->end) == INSN)
1315 eg->src->end = emit_insn_after (mode_set, eg->src->end);
1316 else
1317 abort ();
1318 }
1319 else
1320 {
1321 need_commit = 1;
1322 insert_insn_on_edge (mode_set, eg);
1323 }
1324 }
1325
1326 }
1327#endif
1328
18862b5a 1329 for (bb = n_basic_blocks - 1; bb >= 0; bb--)
1330 {
1331 struct seginfo *ptr, *next;
1332 for (ptr = bb_info[j][bb].seginfo; ptr; ptr = next)
1333 {
1334 next = ptr->next;
7dff60c8 1335 if (ptr->mode != no_mode)
18862b5a 1336 {
1337 rtx mode_set;
1338
1339 start_sequence ();
1340 EMIT_MODE_SET (entity_map[j], ptr->mode, ptr->regs_live);
1341 mode_set = gen_sequence ();
1342 end_sequence ();
1343
6484cd39 1344 if (GET_CODE (ptr->insn_ptr) == NOTE
1345 && (NOTE_LINE_NUMBER (ptr->insn_ptr)
1346 == NOTE_INSN_BASIC_BLOCK))
7dff60c8 1347 emit_block_insn_after (mode_set, ptr->insn_ptr,
1348 BASIC_BLOCK (ptr->bbnum));
1349 else
1350 emit_block_insn_before (mode_set, ptr->insn_ptr,
1351 BASIC_BLOCK (ptr->bbnum));
18862b5a 1352 }
9ca8d59e 1353
18862b5a 1354 free (ptr);
1355 }
1356 }
9ca8d59e 1357
18862b5a 1358 free (bb_info[j]);
1359 }
1360
1361 /* Finished. Free up all the things we've allocated. */
1362
1363 sbitmap_vector_free (kill);
1364 sbitmap_vector_free (antic);
1365 sbitmap_vector_free (transp);
1366 sbitmap_vector_free (comp);
1367 sbitmap_vector_free (delete);
1368 sbitmap_vector_free (insert);
1369
1370 if (need_commit)
1371 commit_edge_insertions ();
b78e14a8 1372
1373 /* Ideally we'd figure out what blocks were affected and start from
1374 there, but this is enormously complicated by commit_edge_insertions,
1375 which would screw up any indicies we'd collected, and also need to
1376 be involved in the update. Bail and recompute global life info for
1377 everything. */
1378
1379 allocate_reg_life_data ();
1380 update_life_info (NULL, UPDATE_LIFE_GLOBAL_RM_NOTES,
1381 (PROP_DEATH_NOTES | PROP_KILL_DEAD_CODE
1382 | PROP_SCAN_DEAD_CODE | PROP_REG_INFO));
1383
1384 return 1;
18862b5a 1385}
b78e14a8 1386#endif /* OPTIMIZE_MODE_SWITCHING */