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