lcm.c 40.5 KB
Newer Older
1
/* Generic partial redundancy elimination with lazy code motion support.
2
   Copyright (C) 1998, 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
Jeffrey A Law committed
3

4
This file is part of GCC.
Jeffrey A Law committed
5

6 7 8 9
GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 2, or (at your option) any later
version.
Jeffrey A Law committed
10

11 12 13 14
GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.
Jeffrey A Law committed
15 16

You should have received a copy of the GNU General Public License
17 18 19
along with GCC; see the file COPYING.  If not, write to the Free
Software Foundation, 59 Temple Place - Suite 330, Boston, MA
02111-1307, USA.  */
Jeffrey A Law committed
20 21

/* These routines are meant to be used by various optimization
22
   passes which can be modeled as lazy code motion problems.
Jeffrey A Law committed
23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
   Including, but not limited to:

	* Traditional partial redundancy elimination.

	* Placement of caller/caller register save/restores.

	* Load/store motion.

	* Copy motion.

	* Conversion of flat register files to a stacked register
	model.

	* Dead load/store elimination.

  These routines accept as input:

	* Basic block information (number of blocks, lists of
	predecessors and successors).  Note the granularity
	does not need to be basic block, they could be statements
	or functions.

	* Bitmaps of local properties (computed, transparent and
	anticipatable expressions).

  The output of these routines is bitmap of redundant computations
  and a bitmap of optimal placement points.  */


#include "config.h"
#include "system.h"
54 55
#include "coretypes.h"
#include "tm.h"
Jeffrey A Law committed
56 57 58 59 60 61 62 63
#include "rtl.h"
#include "regs.h"
#include "hard-reg-set.h"
#include "flags.h"
#include "real.h"
#include "insn-config.h"
#include "recog.h"
#include "basic-block.h"
64
#include "output.h"
65
#include "tm_p.h"
66
#include "function.h"
67

68 69 70
/* We want target macros for the mode switching code to be able to refer
   to instruction attribute values.  */
#include "insn-attr.h"
Jeffrey A Law committed
71

72
/* Edge based LCM routines.  */
73 74 75 76 77 78 79 80 81 82 83 84 85
static void compute_antinout_edge	PARAMS ((sbitmap *, sbitmap *,
						 sbitmap *, sbitmap *));
static void compute_earliest		PARAMS ((struct edge_list *, int,
						 sbitmap *, sbitmap *,
						 sbitmap *, sbitmap *,
						 sbitmap *));
static void compute_laterin		PARAMS ((struct edge_list *, sbitmap *,
						 sbitmap *, sbitmap *,
						 sbitmap *));
static void compute_insert_delete	PARAMS ((struct edge_list *edge_list,
						 sbitmap *, sbitmap *,
						 sbitmap *, sbitmap *,
						 sbitmap *));
86 87

/* Edge based LCM routines on a reverse flowgraph.  */
88 89 90 91 92 93 94 95 96 97 98
static void compute_farthest		PARAMS ((struct edge_list *, int,
						 sbitmap *, sbitmap *,
						 sbitmap*, sbitmap *,
						 sbitmap *));
static void compute_nearerout		PARAMS ((struct edge_list *, sbitmap *,
						 sbitmap *, sbitmap *,
						 sbitmap *));
static void compute_rev_insert_delete	PARAMS ((struct edge_list *edge_list,
						 sbitmap *, sbitmap *,
						 sbitmap *, sbitmap *,
						 sbitmap *));
99 100

/* Edge based lcm routines.  */
Daniel Berlin committed
101

102 103
/* Compute expression anticipatability at entrance and exit of each block.
   This is done based on the flow graph, and not on the pred-succ lists.
104
   Other than that, its pretty much identical to compute_antinout.  */
Jeffrey A Law committed
105 106

static void
107
compute_antinout_edge (antloc, transp, antin, antout)
Jeffrey A Law committed
108 109 110 111 112
     sbitmap *antloc;
     sbitmap *transp;
     sbitmap *antin;
     sbitmap *antout;
{
113
  basic_block bb;
114
  edge e;
115 116
  basic_block *worklist, *qin, *qout, *qend;
  unsigned int qlen;
Daniel Berlin committed
117

118 119 120
  /* Allocate a worklist array/queue.  Entries are only added to the
     list if they were not already on the list.  So the size is
     bounded by the number of basic blocks.  */
121
  qin = qout = worklist
122
    = (basic_block *) xmalloc (sizeof (basic_block) * n_basic_blocks);
Jeffrey A Law committed
123

124 125
  /* We want a maximal solution, so make an optimistic initialization of
     ANTIN.  */
126
  sbitmap_vector_ones (antin, last_basic_block);
Jeffrey A Law committed
127

128 129
  /* Put every block on the worklist; this is necessary because of the
     optimistic initialization of ANTIN above.  */
130
  FOR_EACH_BB_REVERSE (bb)
Jeffrey A Law committed
131
    {
132 133
      *qin++ =bb;
      bb->aux = bb;
134
    }
135

136
  qin = worklist;
137 138
  qend = &worklist[n_basic_blocks];
  qlen = n_basic_blocks;
Jeffrey A Law committed
139

140 141 142 143 144
  /* Mark blocks which are predecessors of the exit block so that we
     can easily identify them below.  */
  for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next)
    e->src->aux = EXIT_BLOCK_PTR;

145
  /* Iterate until the worklist is empty.  */
146
  while (qlen)
147 148
    {
      /* Take the first entry off the worklist.  */
149
      bb = *qout++;
150
      qlen--;
Daniel Berlin committed
151

152
      if (qout >= qend)
153
	qout = worklist;
Jeffrey A Law committed
154

155
      if (bb->aux == EXIT_BLOCK_PTR)
156 157 158
	/* Do not clear the aux field for blocks which are predecessors of
	   the EXIT block.  That way we never add then to the worklist
	   again.  */
159
	sbitmap_zero (antout[bb->index]);
160 161 162 163
      else
	{
	  /* Clear the aux field of this block so that it can be added to
	     the worklist again if necessary.  */
164 165
	  bb->aux = NULL;
	  sbitmap_intersection_of_succs (antout[bb->index], antin, bb->index);
166
	}
167

168 169
      if (sbitmap_a_or_b_and_c_cg (antin[bb->index], antloc[bb->index],
				   transp[bb->index], antout[bb->index]))
170 171 172
	/* If the in state of this block changed, then we need
	   to add the predecessors of this block to the worklist
	   if they are not already on the worklist.  */
173
	for (e = bb->pred; e; e = e->pred_next)
174
	  if (!e->src->aux && e->src != ENTRY_BLOCK_PTR)
Jeffrey A Law committed
175
	    {
176
	      *qin++ = e->src;
177
	      e->src->aux = e;
178 179
	      qlen++;
	      if (qin >= qend)
180
		qin = worklist;
Jeffrey A Law committed
181 182
	    }
    }
183

184 185
  clear_aux_for_edges ();
  clear_aux_for_blocks ();
186
  free (worklist);
Jeffrey A Law committed
187 188
}

189
/* Compute the earliest vector for edge based lcm.  */
190

Jeffrey A Law committed
191
static void
192 193
compute_earliest (edge_list, n_exprs, antin, antout, avout, kill, earliest)
     struct edge_list *edge_list;
Jeffrey A Law committed
194
     int n_exprs;
195
     sbitmap *antin, *antout, *avout, *kill, *earliest;
Jeffrey A Law committed
196
{
197
  sbitmap difference, temp_bitmap;
198
  int x, num_edges;
199
  basic_block pred, succ;
Jeffrey A Law committed
200

201
  num_edges = NUM_EDGES (edge_list);
Jeffrey A Law committed
202

203 204
  difference = sbitmap_alloc (n_exprs);
  temp_bitmap = sbitmap_alloc (n_exprs);
Jeffrey A Law committed
205

206
  for (x = 0; x < num_edges; x++)
Jeffrey A Law committed
207
    {
208 209 210
      pred = INDEX_EDGE_PRED_BB (edge_list, x);
      succ = INDEX_EDGE_SUCC_BB (edge_list, x);
      if (pred == ENTRY_BLOCK_PTR)
211
	sbitmap_copy (earliest[x], antin[succ->index]);
212
      else
213
	{
214
	  if (succ == EXIT_BLOCK_PTR)
215
	    sbitmap_zero (earliest[x]);
216
	  else
Jeffrey A Law committed
217
	    {
218 219 220
	      sbitmap_difference (difference, antin[succ->index],
				  avout[pred->index]);
	      sbitmap_not (temp_bitmap, antout[pred->index]);
221
	      sbitmap_a_and_b_or_c (earliest[x], difference,
222
				    kill[pred->index], temp_bitmap);
Jeffrey A Law committed
223 224 225
	    }
	}
    }
226

227 228
  sbitmap_free (temp_bitmap);
  sbitmap_free (difference);
Jeffrey A Law committed
229 230
}

231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258
/* later(p,s) is dependent on the calculation of laterin(p).
   laterin(p) is dependent on the calculation of later(p2,p).

     laterin(ENTRY) is defined as all 0's
     later(ENTRY, succs(ENTRY)) are defined using laterin(ENTRY)
     laterin(succs(ENTRY)) is defined by later(ENTRY, succs(ENTRY)).

   If we progress in this manner, starting with all basic blocks
   in the work list, anytime we change later(bb), we need to add
   succs(bb) to the worklist if they are not already on the worklist.

   Boundary conditions:

     We prime the worklist all the normal basic blocks.   The ENTRY block can
     never be added to the worklist since it is never the successor of any
     block.  We explicitly prevent the EXIT block from being added to the
     worklist.

     We optimistically initialize LATER.  That is the only time this routine
     will compute LATER for an edge out of the entry block since the entry
     block is never on the worklist.  Thus, LATERIN is neither used nor
     computed for the ENTRY block.

     Since the EXIT block is never added to the worklist, we will neither
     use nor compute LATERIN for the exit block.  Edges which reach the
     EXIT block are handled in the normal fashion inside the loop.  However,
     the insertion/deletion computation needs LATERIN(EXIT), so we have
     to compute it.  */
259

Jeffrey A Law committed
260
static void
261
compute_laterin (edge_list, earliest, antloc, later, laterin)
262 263
     struct edge_list *edge_list;
     sbitmap *earliest, *antloc, *later, *laterin;
Jeffrey A Law committed
264
{
265
  int num_edges, i;
266
  edge e;
267
  basic_block *worklist, *qin, *qout, *qend, bb;
268
  unsigned int qlen;
Jeffrey A Law committed
269

270
  num_edges = NUM_EDGES (edge_list);
Jeffrey A Law committed
271

272 273 274
  /* Allocate a worklist array/queue.  Entries are only added to the
     list if they were not already on the list.  So the size is
     bounded by the number of basic blocks.  */
275
  qin = qout = worklist
276
    = (basic_block *) xmalloc (sizeof (basic_block) * (n_basic_blocks + 1));
277 278 279

  /* Initialize a mapping from each edge to its index.  */
  for (i = 0; i < num_edges; i++)
280
    INDEX_EDGE (edge_list, i)->aux = (void *) (size_t) i;
281 282 283 284 285 286 287 288 289 290 291 292 293

  /* We want a maximal solution, so initially consider LATER true for
     all edges.  This allows propagation through a loop since the incoming
     loop edge will have LATER set, so if all the other incoming edges
     to the loop are set, then LATERIN will be set for the head of the
     loop.

     If the optimistic setting of LATER on that edge was incorrect (for
     example the expression is ANTLOC in a block within the loop) then
     this algorithm will detect it when we process the block at the head
     of the optimistic edge.  That will requeue the affected blocks.  */
  sbitmap_vector_ones (later, num_edges);

294 295 296 297 298
  /* Note that even though we want an optimistic setting of LATER, we
     do not want to be overly optimistic.  Consider an outgoing edge from
     the entry block.  That edge should always have a LATER value the
     same as EARLIEST for that edge.  */
  for (e = ENTRY_BLOCK_PTR->succ; e; e = e->succ_next)
299
    sbitmap_copy (later[(size_t) e->aux], earliest[(size_t) e->aux]);
300

301 302
  /* Add all the blocks to the worklist.  This prevents an early exit from
     the loop given our optimistic initialization of LATER above.  */
303
  FOR_EACH_BB (bb)
Jeffrey A Law committed
304
    {
305 306
      *qin++ = bb;
      bb->aux = bb;
307
    }
308 309 310
  qin = worklist;
  /* Note that we do not use the last allocated element for our queue,
     as EXIT_BLOCK is never inserted into it. In fact the above allocation
311
     of n_basic_blocks + 1 elements is not necessary.  */
312 313
  qend = &worklist[n_basic_blocks];
  qlen = n_basic_blocks;
314

315
  /* Iterate until the worklist is empty.  */
316
  while (qlen)
317
    {
318
      /* Take the first entry off the worklist.  */
319 320
      bb = *qout++;
      bb->aux = NULL;
321 322
      qlen--;
      if (qout >= qend)
323
	qout = worklist;
324 325

      /* Compute the intersection of LATERIN for each incoming edge to B.  */
326 327 328
      sbitmap_ones (laterin[bb->index]);
      for (e = bb->pred; e != NULL; e = e->pred_next)
	sbitmap_a_and_b (laterin[bb->index], laterin[bb->index], later[(size_t)e->aux]);
329 330

      /* Calculate LATER for all outgoing edges.  */
331
      for (e = bb->succ; e != NULL; e = e->succ_next)
332
	if (sbitmap_union_of_diff_cg (later[(size_t) e->aux],
333 334 335
				      earliest[(size_t) e->aux],
				      laterin[e->src->index],
				      antloc[e->src->index])
336 337 338 339
	    /* If LATER for an outgoing edge was changed, then we need
	       to add the target of the outgoing edge to the worklist.  */
	    && e->dest != EXIT_BLOCK_PTR && e->dest->aux == 0)
	  {
340
	    *qin++ = e->dest;
341
	    e->dest->aux = e;
342 343 344
	    qlen++;
	    if (qin >= qend)
	      qin = worklist;
345
	  }
Jeffrey A Law committed
346 347
    }

348 349 350
  /* Computation of insertion and deletion points requires computing LATERIN
     for the EXIT block.  We allocated an extra entry in the LATERIN array
     for just this purpose.  */
351
  sbitmap_ones (laterin[last_basic_block]);
352
  for (e = EXIT_BLOCK_PTR->pred; e != NULL; e = e->pred_next)
353 354
    sbitmap_a_and_b (laterin[last_basic_block],
		     laterin[last_basic_block],
355
		     later[(size_t) e->aux]);
356

357
  clear_aux_for_edges ();
358
  free (worklist);
Jeffrey A Law committed
359 360
}

361
/* Compute the insertion and deletion points for edge based LCM.  */
362

363 364 365 366 367 368 369
static void
compute_insert_delete (edge_list, antloc, later, laterin,
		       insert, delete)
     struct edge_list *edge_list;
     sbitmap *antloc, *later, *laterin, *insert, *delete;
{
  int x;
370
  basic_block bb;
Jeffrey A Law committed
371

372 373
  FOR_EACH_BB (bb)
    sbitmap_difference (delete[bb->index], antloc[bb->index], laterin[bb->index]);
374

375 376 377
  for (x = 0; x < NUM_EDGES (edge_list); x++)
    {
      basic_block b = INDEX_EDGE_SUCC_BB (edge_list, x);
378

379
      if (b == EXIT_BLOCK_PTR)
380
	sbitmap_difference (insert[x], later[x], laterin[last_basic_block]);
381
      else
382
	sbitmap_difference (insert[x], later[x], laterin[b->index]);
383 384
    }
}
Jeffrey A Law committed
385

386 387 388
/* Given local properties TRANSP, ANTLOC, AVOUT, KILL return the insert and
   delete vectors for edge based LCM.  Returns an edgelist which is used to
   map the insert vector to what edge an expression should be inserted on.  */
Jeffrey A Law committed
389

390 391
struct edge_list *
pre_edge_lcm (file, n_exprs, transp, avloc, antloc, kill, insert, delete)
392
     FILE *file ATTRIBUTE_UNUSED;
Jeffrey A Law committed
393
     int n_exprs;
394 395
     sbitmap *transp;
     sbitmap *avloc;
Jeffrey A Law committed
396
     sbitmap *antloc;
397 398 399
     sbitmap *kill;
     sbitmap **insert;
     sbitmap **delete;
Jeffrey A Law committed
400
{
401 402 403 404 405
  sbitmap *antin, *antout, *earliest;
  sbitmap *avin, *avout;
  sbitmap *later, *laterin;
  struct edge_list *edge_list;
  int num_edges;
Jeffrey A Law committed
406

407 408
  edge_list = create_edge_list ();
  num_edges = NUM_EDGES (edge_list);
Jeffrey A Law committed
409

410 411
#ifdef LCM_DEBUG_INFO
  if (file)
Jeffrey A Law committed
412
    {
413 414 415
      fprintf (file, "Edge List:\n");
      verify_edge_list (file, edge_list);
      print_edge_list (file, edge_list);
416 417 418 419
      dump_sbitmap_vector (file, "transp", "", transp, last_basic_block);
      dump_sbitmap_vector (file, "antloc", "", antloc, last_basic_block);
      dump_sbitmap_vector (file, "avloc", "", avloc, last_basic_block);
      dump_sbitmap_vector (file, "kill", "", kill, last_basic_block);
Jeffrey A Law committed
420
    }
421
#endif
Jeffrey A Law committed
422

423
  /* Compute global availability.  */
424 425
  avin = sbitmap_vector_alloc (last_basic_block, n_exprs);
  avout = sbitmap_vector_alloc (last_basic_block, n_exprs);
426
  compute_available (avloc, kill, avout, avin);
427
  sbitmap_vector_free (avin);
Jeffrey A Law committed
428

429
  /* Compute global anticipatability.  */
430 431
  antin = sbitmap_vector_alloc (last_basic_block, n_exprs);
  antout = sbitmap_vector_alloc (last_basic_block, n_exprs);
432
  compute_antinout_edge (antloc, transp, antin, antout);
Jeffrey A Law committed
433

434 435
#ifdef LCM_DEBUG_INFO
  if (file)
Jeffrey A Law committed
436
    {
437 438
      dump_sbitmap_vector (file, "antin", "", antin, last_basic_block);
      dump_sbitmap_vector (file, "antout", "", antout, last_basic_block);
Jeffrey A Law committed
439
    }
440
#endif
Jeffrey A Law committed
441

442 443 444
  /* Compute earliestness.  */
  earliest = sbitmap_vector_alloc (num_edges, n_exprs);
  compute_earliest (edge_list, n_exprs, antin, antout, avout, kill, earliest);
Jeffrey A Law committed
445

446 447 448 449
#ifdef LCM_DEBUG_INFO
  if (file)
    dump_sbitmap_vector (file, "earliest", "", earliest, num_edges);
#endif
Jeffrey A Law committed
450

451 452 453
  sbitmap_vector_free (antout);
  sbitmap_vector_free (antin);
  sbitmap_vector_free (avout);
Jeffrey A Law committed
454

455
  later = sbitmap_vector_alloc (num_edges, n_exprs);
456

457
  /* Allocate an extra element for the exit block in the laterin vector.  */
458
  laterin = sbitmap_vector_alloc (last_basic_block + 1, n_exprs);
459 460
  compute_laterin (edge_list, earliest, antloc, later, laterin);

461 462 463
#ifdef LCM_DEBUG_INFO
  if (file)
    {
464
      dump_sbitmap_vector (file, "laterin", "", laterin, last_basic_block + 1);
465 466 467
      dump_sbitmap_vector (file, "later", "", later, num_edges);
    }
#endif
Jeffrey A Law committed
468

469
  sbitmap_vector_free (earliest);
470 471

  *insert = sbitmap_vector_alloc (num_edges, n_exprs);
472
  *delete = sbitmap_vector_alloc (last_basic_block, n_exprs);
473
  compute_insert_delete (edge_list, antloc, later, laterin, *insert, *delete);
Jeffrey A Law committed
474

475 476
  sbitmap_vector_free (laterin);
  sbitmap_vector_free (later);
477 478 479

#ifdef LCM_DEBUG_INFO
  if (file)
Jeffrey A Law committed
480
    {
481
      dump_sbitmap_vector (file, "pre_insert_map", "", *insert, num_edges);
482
      dump_sbitmap_vector (file, "pre_delete_map", "", *delete,
483
			   last_basic_block);
Jeffrey A Law committed
484
    }
485
#endif
Jeffrey A Law committed
486

487 488
  return edge_list;
}
Daniel Berlin committed
489 490 491 492

/* Compute the AVIN and AVOUT vectors from the AVLOC and KILL vectors.
   Return the number of passes we performed to iterate to a solution.  */

493
void
494
compute_available (avloc, kill, avout, avin)
Daniel Berlin committed
495
     sbitmap *avloc, *kill, *avout, *avin;
Jeffrey A Law committed
496
{
Daniel Berlin committed
497
  edge e;
498
  basic_block *worklist, *qin, *qout, *qend, bb;
Daniel Berlin committed
499 500 501 502 503 504
  unsigned int qlen;

  /* Allocate a worklist array/queue.  Entries are only added to the
     list if they were not already on the list.  So the size is
     bounded by the number of basic blocks.  */
  qin = qout = worklist
505
    = (basic_block *) xmalloc (sizeof (basic_block) * n_basic_blocks);
Daniel Berlin committed
506 507

  /* We want a maximal solution.  */
508
  sbitmap_vector_ones (avout, last_basic_block);
Daniel Berlin committed
509 510 511

  /* Put every block on the worklist; this is necessary because of the
     optimistic initialization of AVOUT above.  */
512
  FOR_EACH_BB (bb)
Daniel Berlin committed
513
    {
514 515
      *qin++ = bb;
      bb->aux = bb;
Daniel Berlin committed
516 517 518
    }

  qin = worklist;
519 520
  qend = &worklist[n_basic_blocks];
  qlen = n_basic_blocks;
Daniel Berlin committed
521 522 523 524 525 526 527 528 529 530

  /* Mark blocks which are successors of the entry block so that we
     can easily identify them below.  */
  for (e = ENTRY_BLOCK_PTR->succ; e; e = e->succ_next)
    e->dest->aux = ENTRY_BLOCK_PTR;

  /* Iterate until the worklist is empty.  */
  while (qlen)
    {
      /* Take the first entry off the worklist.  */
531
      bb = *qout++;
Daniel Berlin committed
532 533 534
      qlen--;

      if (qout >= qend)
535
	qout = worklist;
Daniel Berlin committed
536 537 538 539

      /* If one of the predecessor blocks is the ENTRY block, then the
	 intersection of avouts is the null set.  We can identify such blocks
	 by the special value in the AUX field in the block structure.  */
540
      if (bb->aux == ENTRY_BLOCK_PTR)
Daniel Berlin committed
541 542
	/* Do not clear the aux field for blocks which are successors of the
	   ENTRY block.  That way we never add then to the worklist again.  */
543
	sbitmap_zero (avin[bb->index]);
Daniel Berlin committed
544 545 546 547
      else
	{
	  /* Clear the aux field of this block so that it can be added to
	     the worklist again if necessary.  */
548 549
	  bb->aux = NULL;
	  sbitmap_intersection_of_preds (avin[bb->index], avout, bb->index);
Daniel Berlin committed
550 551
	}

552
      if (sbitmap_union_of_diff_cg (avout[bb->index], avloc[bb->index], avin[bb->index], kill[bb->index]))
Daniel Berlin committed
553 554 555
	/* If the out state of this block changed, then we need
	   to add the successors of this block to the worklist
	   if they are not already on the worklist.  */
556
	for (e = bb->succ; e; e = e->succ_next)
Daniel Berlin committed
557 558 559 560 561 562 563
	  if (!e->dest->aux && e->dest != EXIT_BLOCK_PTR)
	    {
	      *qin++ = e->dest;
	      e->dest->aux = e;
	      qlen++;

	      if (qin >= qend)
564
		qin = worklist;
Daniel Berlin committed
565 566 567 568 569 570
	    }
    }

  clear_aux_for_edges ();
  clear_aux_for_blocks ();
  free (worklist);
Jeffrey A Law committed
571 572
}

573
/* Compute the farthest vector for edge based lcm.  */
574

Jeffrey A Law committed
575
static void
576
compute_farthest (edge_list, n_exprs, st_avout, st_avin, st_antin,
577 578
		  kill, farthest)
     struct edge_list *edge_list;
Jeffrey A Law committed
579
     int n_exprs;
580
     sbitmap *st_avout, *st_avin, *st_antin, *kill, *farthest;
Jeffrey A Law committed
581
{
582
  sbitmap difference, temp_bitmap;
583
  int x, num_edges;
584
  basic_block pred, succ;
Jeffrey A Law committed
585

586
  num_edges = NUM_EDGES (edge_list);
Jeffrey A Law committed
587

588 589
  difference = sbitmap_alloc (n_exprs);
  temp_bitmap = sbitmap_alloc (n_exprs);
Jeffrey A Law committed
590

591
  for (x = 0; x < num_edges; x++)
Jeffrey A Law committed
592
    {
593 594 595
      pred = INDEX_EDGE_PRED_BB (edge_list, x);
      succ = INDEX_EDGE_SUCC_BB (edge_list, x);
      if (succ == EXIT_BLOCK_PTR)
596
	sbitmap_copy (farthest[x], st_avout[pred->index]);
597
      else
Jeffrey A Law committed
598
	{
599
	  if (pred == ENTRY_BLOCK_PTR)
600
	    sbitmap_zero (farthest[x]);
601 602
	  else
	    {
603 604 605
	      sbitmap_difference (difference, st_avout[pred->index],
				  st_antin[succ->index]);
	      sbitmap_not (temp_bitmap, st_avin[succ->index]);
606
	      sbitmap_a_and_b_or_c (farthest[x], difference,
607
				    kill[succ->index], temp_bitmap);
608
	    }
Jeffrey A Law committed
609 610
	}
    }
611

612 613
  sbitmap_free (temp_bitmap);
  sbitmap_free (difference);
Jeffrey A Law committed
614 615
}

616 617 618 619 620
/* Compute nearer and nearerout vectors for edge based lcm.

   This is the mirror of compute_laterin, additional comments on the
   implementation can be found before compute_laterin.  */

Jeffrey A Law committed
621
static void
622
compute_nearerout (edge_list, farthest, st_avloc, nearer, nearerout)
623 624
     struct edge_list *edge_list;
     sbitmap *farthest, *st_avloc, *nearer, *nearerout;
Jeffrey A Law committed
625
{
626
  int num_edges, i;
627
  edge e;
628
  basic_block *worklist, *tos, bb;
Jeffrey A Law committed
629

630
  num_edges = NUM_EDGES (edge_list);
Jeffrey A Law committed
631

632 633 634
  /* Allocate a worklist array/queue.  Entries are only added to the
     list if they were not already on the list.  So the size is
     bounded by the number of basic blocks.  */
635
  tos = worklist
636
    = (basic_block *) xmalloc (sizeof (basic_block) * (n_basic_blocks + 1));
Jeffrey A Law committed
637

638 639 640
  /* Initialize NEARER for each edge and build a mapping from an edge to
     its index.  */
  for (i = 0; i < num_edges; i++)
641
    INDEX_EDGE (edge_list, i)->aux = (void *) (size_t) i;
642

643 644 645
  /* We want a maximal solution.  */
  sbitmap_vector_ones (nearer, num_edges);

646 647 648 649 650
  /* Note that even though we want an optimistic setting of NEARER, we
     do not want to be overly optimistic.  Consider an incoming edge to
     the exit block.  That edge should always have a NEARER value the
     same as FARTHEST for that edge.  */
  for (e = EXIT_BLOCK_PTR->pred; e; e = e->pred_next)
651
    sbitmap_copy (nearer[(size_t)e->aux], farthest[(size_t)e->aux]);
652

653 654
  /* Add all the blocks to the worklist.  This prevents an early exit
     from the loop given our optimistic initialization of NEARER.  */
655
  FOR_EACH_BB (bb)
Jeffrey A Law committed
656
    {
657 658
      *tos++ = bb;
      bb->aux = bb;
659
    }
660

661 662
  /* Iterate until the worklist is empty.  */
  while (tos != worklist)
663
    {
664
      /* Take the first entry off the worklist.  */
665 666
      bb = *--tos;
      bb->aux = NULL;
667 668

      /* Compute the intersection of NEARER for each outgoing edge from B.  */
669 670 671
      sbitmap_ones (nearerout[bb->index]);
      for (e = bb->succ; e != NULL; e = e->succ_next)
	sbitmap_a_and_b (nearerout[bb->index], nearerout[bb->index],
672
			 nearer[(size_t) e->aux]);
673 674

      /* Calculate NEARER for all incoming edges.  */
675
      for (e = bb->pred; e != NULL; e = e->pred_next)
676
	if (sbitmap_union_of_diff_cg (nearer[(size_t) e->aux],
677 678 679
				      farthest[(size_t) e->aux],
				      nearerout[e->dest->index],
				      st_avloc[e->dest->index])
680 681 682 683 684 685 686
	    /* If NEARER for an incoming edge was changed, then we need
	       to add the source of the incoming edge to the worklist.  */
	    && e->src != ENTRY_BLOCK_PTR && e->src->aux == 0)
	  {
	    *tos++ = e->src;
	    e->src->aux = e;
	  }
687
    }
Jeffrey A Law committed
688

689 690 691
  /* Computation of insertion and deletion points requires computing NEAREROUT
     for the ENTRY block.  We allocated an extra entry in the NEAREROUT array
     for just this purpose.  */
692
  sbitmap_ones (nearerout[last_basic_block]);
693
  for (e = ENTRY_BLOCK_PTR->succ; e != NULL; e = e->succ_next)
694 695
    sbitmap_a_and_b (nearerout[last_basic_block],
		     nearerout[last_basic_block],
696
		     nearer[(size_t) e->aux]);
697

698
  clear_aux_for_edges ();
699
  free (tos);
700
}
Jeffrey A Law committed
701

702
/* Compute the insertion and deletion points for edge based LCM.  */
703

Jeffrey A Law committed
704
static void
705 706 707 708
compute_rev_insert_delete (edge_list, st_avloc, nearer, nearerout,
			   insert, delete)
     struct edge_list *edge_list;
     sbitmap *st_avloc, *nearer, *nearerout, *insert, *delete;
Jeffrey A Law committed
709
{
710
  int x;
711
  basic_block bb;
Jeffrey A Law committed
712

713 714
  FOR_EACH_BB (bb)
    sbitmap_difference (delete[bb->index], st_avloc[bb->index], nearerout[bb->index]);
715

716
  for (x = 0; x < NUM_EDGES (edge_list); x++)
Jeffrey A Law committed
717
    {
718 719
      basic_block b = INDEX_EDGE_PRED_BB (edge_list, x);
      if (b == ENTRY_BLOCK_PTR)
720
	sbitmap_difference (insert[x], nearer[x], nearerout[last_basic_block]);
Jeffrey A Law committed
721
      else
722
	sbitmap_difference (insert[x], nearer[x], nearerout[b->index]);
Jeffrey A Law committed
723 724 725
    }
}

726
/* Given local properties TRANSP, ST_AVLOC, ST_ANTLOC, KILL return the
727 728 729
   insert and delete vectors for edge based reverse LCM.  Returns an
   edgelist which is used to map the insert vector to what edge
   an expression should be inserted on.  */
Jeffrey A Law committed
730

731
struct edge_list *
732
pre_edge_rev_lcm (file, n_exprs, transp, st_avloc, st_antloc, kill,
733
		  insert, delete)
734
     FILE *file ATTRIBUTE_UNUSED;
735 736 737 738 739 740 741
     int n_exprs;
     sbitmap *transp;
     sbitmap *st_avloc;
     sbitmap *st_antloc;
     sbitmap *kill;
     sbitmap **insert;
     sbitmap **delete;
Jeffrey A Law committed
742
{
743 744 745 746
  sbitmap *st_antin, *st_antout;
  sbitmap *st_avout, *st_avin, *farthest;
  sbitmap *nearer, *nearerout;
  struct edge_list *edge_list;
747
  int num_edges;
748 749 750 751

  edge_list = create_edge_list ();
  num_edges = NUM_EDGES (edge_list);

752 753 754 755
  st_antin = (sbitmap *) sbitmap_vector_alloc (last_basic_block, n_exprs);
  st_antout = (sbitmap *) sbitmap_vector_alloc (last_basic_block, n_exprs);
  sbitmap_vector_zero (st_antin, last_basic_block);
  sbitmap_vector_zero (st_antout, last_basic_block);
756 757 758
  compute_antinout_edge (st_antloc, transp, st_antin, st_antout);

  /* Compute global anticipatability.  */
759 760
  st_avout = sbitmap_vector_alloc (last_basic_block, n_exprs);
  st_avin = sbitmap_vector_alloc (last_basic_block, n_exprs);
761 762 763 764 765 766 767 768
  compute_available (st_avloc, kill, st_avout, st_avin);

#ifdef LCM_DEBUG_INFO
  if (file)
    {
      fprintf (file, "Edge List:\n");
      verify_edge_list (file, edge_list);
      print_edge_list (file, edge_list);
769 770 771 772 773 774
      dump_sbitmap_vector (file, "transp", "", transp, last_basic_block);
      dump_sbitmap_vector (file, "st_avloc", "", st_avloc, last_basic_block);
      dump_sbitmap_vector (file, "st_antloc", "", st_antloc, last_basic_block);
      dump_sbitmap_vector (file, "st_antin", "", st_antin, last_basic_block);
      dump_sbitmap_vector (file, "st_antout", "", st_antout, last_basic_block);
      dump_sbitmap_vector (file, "st_kill", "", kill, last_basic_block);
775 776
    }
#endif
Jeffrey A Law committed
777

778 779 780
#ifdef LCM_DEBUG_INFO
  if (file)
    {
781 782
      dump_sbitmap_vector (file, "st_avout", "", st_avout, last_basic_block);
      dump_sbitmap_vector (file, "st_avin", "", st_avin, last_basic_block);
783 784
    }
#endif
Jeffrey A Law committed
785

786 787
  /* Compute farthestness.  */
  farthest = sbitmap_vector_alloc (num_edges, n_exprs);
788
  compute_farthest (edge_list, n_exprs, st_avout, st_avin, st_antin,
789 790 791 792 793 794 795
		    kill, farthest);

#ifdef LCM_DEBUG_INFO
  if (file)
    dump_sbitmap_vector (file, "farthest", "", farthest, num_edges);
#endif

796 797 798 799 800
  sbitmap_vector_free (st_antin);
  sbitmap_vector_free (st_antout);

  sbitmap_vector_free (st_avin);
  sbitmap_vector_free (st_avout);
801 802

  nearer = sbitmap_vector_alloc (num_edges, n_exprs);
803

804
  /* Allocate an extra element for the entry block.  */
805
  nearerout = sbitmap_vector_alloc (last_basic_block + 1, n_exprs);
806
  compute_nearerout (edge_list, farthest, st_avloc, nearer, nearerout);
807 808 809

#ifdef LCM_DEBUG_INFO
  if (file)
Jeffrey A Law committed
810
    {
811
      dump_sbitmap_vector (file, "nearerout", "", nearerout,
812
			   last_basic_block + 1);
813
      dump_sbitmap_vector (file, "nearer", "", nearer, num_edges);
Jeffrey A Law committed
814
    }
815 816
#endif

817
  sbitmap_vector_free (farthest);
818 819

  *insert = sbitmap_vector_alloc (num_edges, n_exprs);
820
  *delete = sbitmap_vector_alloc (last_basic_block, n_exprs);
821 822
  compute_rev_insert_delete (edge_list, st_avloc, nearer, nearerout,
			     *insert, *delete);
823

824 825
  sbitmap_vector_free (nearerout);
  sbitmap_vector_free (nearer);
826 827 828 829 830

#ifdef LCM_DEBUG_INFO
  if (file)
    {
      dump_sbitmap_vector (file, "pre_insert_map", "", *insert, num_edges);
831
      dump_sbitmap_vector (file, "pre_delete_map", "", *delete,
832
			   last_basic_block);
833 834 835
    }
#endif
  return edge_list;
Jeffrey A Law committed
836
}
837

838 839 840
/* Mode switching:

   The algorithm for setting the modes consists of scanning the insn list
841 842 843 844 845 846 847 848 849 850 851 852
   and finding all the insns which require a specific mode.  Each insn gets
   a unique struct seginfo element.  These structures are inserted into a list
   for each basic block.  For each entity, there is an array of bb_info over
   the flow graph basic blocks (local var 'bb_info'), and contains a list
   of all insns within that basic block, in the order they are encountered.

   For each entity, any basic block WITHOUT any insns requiring a specific
   mode are given a single entry, without a mode.  (Each basic block
   in the flow graph must have at least one entry in the segment table.)

   The LCM algorithm is then run over the flow graph to determine where to
   place the sets to the highest-priority value in respect of first the first
853
   insn in any one block.  Any adjustments required to the transparency
854
   vectors are made, then the next iteration starts for the next-lower
855
   priority mode, till for each entity all modes are exhausted.
856 857 858 859

   More details are located in the code for optimize_mode_switching().  */

/* This structure contains the information for each insn which requires
860
   either single or double mode to be set.
861
   MODE is the mode this insn must be executed in.
862 863
   INSN_PTR is the insn to be executed (may be the note that marks the
   beginning of a basic block).
864 865
   BBNUM is the flow graph basic block this insn occurs in.
   NEXT is the next insn in the same basic block.  */
866
struct seginfo
867 868 869 870 871 872 873 874
{
  int mode;
  rtx insn_ptr;
  int bbnum;
  struct seginfo *next;
  HARD_REG_SET regs_live;
};

Daniel Berlin committed
875
struct bb_info
876 877 878 879 880 881 882
{
  struct seginfo *seginfo;
  int computing;
};

/* These bitmaps are used for the LCM algorithm.  */

883
#ifdef OPTIMIZE_MODE_SWITCHING
884 885 886 887 888 889
static sbitmap *antic;
static sbitmap *transp;
static sbitmap *comp;
static sbitmap *delete;
static sbitmap *insert;

890
static struct seginfo * new_seginfo PARAMS ((int, rtx, int, HARD_REG_SET));
Daniel Berlin committed
891
static void add_seginfo PARAMS ((struct bb_info *, struct seginfo *));
892 893
static void reg_dies PARAMS ((rtx, HARD_REG_SET));
static void reg_becomes_live PARAMS ((rtx, rtx, void *));
894 895 896 897
static void make_preds_opaque PARAMS ((basic_block, int));
#endif

#ifdef OPTIMIZE_MODE_SWITCHING
898 899

/* This function will allocate a new BBINFO structure, initialized
900
   with the MODE, INSN, and basic block BB parameters.  */
901

902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918
static struct seginfo *
new_seginfo (mode, insn, bb, regs_live)
     int mode;
     rtx insn;
     int bb;
     HARD_REG_SET regs_live;
{
  struct seginfo *ptr;
  ptr = xmalloc (sizeof (struct seginfo));
  ptr->mode = mode;
  ptr->insn_ptr = insn;
  ptr->bbnum = bb;
  ptr->next = NULL;
  COPY_HARD_REG_SET (ptr->regs_live, regs_live);
  return ptr;
}

919
/* Add a seginfo element to the end of a list.
920 921
   HEAD is a pointer to the list beginning.
   INFO is the structure to be linked in.  */
922

923 924
static void
add_seginfo (head, info)
Daniel Berlin committed
925
     struct bb_info *head;
926 927 928 929 930 931 932 933 934 935
     struct seginfo *info;
{
  struct seginfo *ptr;

  if (head->seginfo == NULL)
    head->seginfo = info;
  else
    {
      ptr = head->seginfo;
      while (ptr->next != NULL)
936
	ptr = ptr->next;
937 938 939 940 941 942 943 944 945
      ptr->next = info;
    }
}

/* Make all predecessors of basic block B opaque, recursively, till we hit
   some that are already non-transparent, or an edge where aux is set; that
   denotes that a mode set is to be done on that edge.
   J is the bit number in the bitmaps that corresponds to the entity that
   we are currently handling mode-switching for.  */
946

947 948 949 950 951 952 953 954 955 956
static void
make_preds_opaque (b, j)
     basic_block b;
     int j;
{
  edge e;

  for (e = b->pred; e; e = e->pred_next)
    {
      basic_block pb = e->src;
957

958
      if (e->aux || ! TEST_BIT (transp[pb->index], j))
959
	continue;
960

961
      RESET_BIT (transp[pb->index], j);
962 963 964 965 966
      make_preds_opaque (pb, j);
    }
}

/* Record in LIVE that register REG died.  */
967

968 969 970 971 972
static void
reg_dies (reg, live)
     rtx reg;
     HARD_REG_SET live;
{
973
  int regno, nregs;
974 975 976

  if (GET_CODE (reg) != REG)
    return;
977

978 979
  regno = REGNO (reg);
  if (regno < FIRST_PSEUDO_REGISTER)
980 981 982
    for (nregs = HARD_REGNO_NREGS (regno, GET_MODE (reg)) - 1; nregs >= 0;
	 nregs--)
      CLEAR_HARD_REG_BIT (live, regno + nregs);
983 984 985 986
}

/* Record in LIVE that register REG became live.
   This is called via note_stores.  */
987

988 989 990 991 992 993
static void
reg_becomes_live (reg, setter, live)
     rtx reg;
     rtx setter ATTRIBUTE_UNUSED;
     void *live;
{
994
  int regno, nregs;
995 996 997 998 999 1000 1001 1002 1003

  if (GET_CODE (reg) == SUBREG)
    reg = SUBREG_REG (reg);

  if (GET_CODE (reg) != REG)
    return;

  regno = REGNO (reg);
  if (regno < FIRST_PSEUDO_REGISTER)
1004 1005 1006
    for (nregs = HARD_REGNO_NREGS (regno, GET_MODE (reg)) - 1; nregs >= 0;
	 nregs--)
      SET_HARD_REG_BIT (* (HARD_REG_SET *) live, regno + nregs);
1007 1008
}

1009 1010
/* Find all insns that need a particular mode setting, and insert the
   necessary mode switches.  Return true if we did work.  */
1011

1012
int
1013
optimize_mode_switching (file)
1014
     FILE *file;
1015 1016
{
  rtx insn;
1017 1018
  int e;
  basic_block bb;
1019 1020 1021
  int need_commit = 0;
  sbitmap *kill;
  struct edge_list *edge_list;
1022
  static const int num_modes[] = NUM_MODES_FOR_MODE_SWITCHING;
1023
#define N_ENTITIES ARRAY_SIZE (num_modes)
1024
  int entity_map[N_ENTITIES];
Daniel Berlin committed
1025
  struct bb_info *bb_info[N_ENTITIES];
1026 1027 1028
  int i, j;
  int n_entities;
  int max_num_modes = 0;
1029
  bool emited = false;
1030
  basic_block post_entry ATTRIBUTE_UNUSED, pre_exit ATTRIBUTE_UNUSED;
1031

1032
  clear_bb_flags ();
1033

1034
  for (e = N_ENTITIES - 1, n_entities = 0; e >= 0; e--)
1035 1036
    if (OPTIMIZE_MODE_SWITCHING (e))
      {
1037 1038 1039 1040
	int entry_exit_extra = 0;

	/* Create the list of segments within each basic block.
	   If NORMAL_MODE is defined, allow for two extra
1041
	   blocks split from the entry and exit block.  */
1042 1043 1044
#ifdef NORMAL_MODE
	entry_exit_extra = 2;
#endif
1045
	bb_info[n_entities]
1046 1047
	  = (struct bb_info *) xcalloc (last_basic_block + entry_exit_extra,
					sizeof **bb_info);
1048 1049 1050 1051 1052
	entity_map[n_entities++] = e;
	if (num_modes[e] > max_num_modes)
	  max_num_modes = num_modes[e];
      }

1053
  if (! n_entities)
1054
    return 0;
1055

1056
#ifdef NORMAL_MODE
1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072 1073 1074 1075 1076 1077
  {
    /* Split the edge from the entry block and the fallthrough edge to the
       exit block, so that we can note that there NORMAL_MODE is supplied /
       required.  */
    edge eg;
    post_entry = split_edge (ENTRY_BLOCK_PTR->succ);
    /* The only non-call predecessor at this stage is a block with a
       fallthrough edge; there can be at most one, but there could be
       none at all, e.g. when exit is called.  */
    for (pre_exit = 0, eg = EXIT_BLOCK_PTR->pred; eg; eg = eg->pred_next)
      if (eg->flags & EDGE_FALLTHRU)
	{
	  regset live_at_end = eg->src->global_live_at_end;

	  if (pre_exit)
	    abort ();
	  pre_exit = split_edge (eg);
	  COPY_REG_SET (pre_exit->global_live_at_start, live_at_end);
	  COPY_REG_SET (pre_exit->global_live_at_end, live_at_end);
	}
  }
1078 1079
#endif

1080 1081
  /* Create the bitmap vectors.  */

1082 1083 1084
  antic = sbitmap_vector_alloc (last_basic_block, n_entities);
  transp = sbitmap_vector_alloc (last_basic_block, n_entities);
  comp = sbitmap_vector_alloc (last_basic_block, n_entities);
1085

1086
  sbitmap_vector_ones (transp, last_basic_block);
1087 1088 1089 1090 1091

  for (j = n_entities - 1; j >= 0; j--)
    {
      int e = entity_map[j];
      int no_mode = num_modes[e];
Daniel Berlin committed
1092
      struct bb_info *info = bb_info[j];
1093 1094

      /* Determine what the first use (if any) need for a mode of entity E is.
1095
	 This will be the mode that is anticipatable for this block.
1096
	 Also compute the initial transparency settings.  */
1097
      FOR_EACH_BB (bb)
1098 1099 1100 1101 1102 1103
	{
	  struct seginfo *ptr;
	  int last_mode = no_mode;
	  HARD_REG_SET live_now;

	  REG_SET_TO_HARD_REG_SET (live_now,
1104 1105 1106
				   bb->global_live_at_start);
	  for (insn = bb->head;
	       insn != NULL && insn != NEXT_INSN (bb->end);
1107 1108
	       insn = NEXT_INSN (insn))
	    {
1109
	      if (INSN_P (insn))
1110 1111 1112 1113 1114 1115 1116
		{
		  int mode = MODE_NEEDED (e, insn);
		  rtx link;

		  if (mode != no_mode && mode != last_mode)
		    {
		      last_mode = mode;
1117 1118 1119
		      ptr = new_seginfo (mode, insn, bb->index, live_now);
		      add_seginfo (info + bb->index, ptr);
		      RESET_BIT (transp[bb->index], j);
1120 1121 1122 1123 1124 1125
		    }

		  /* Update LIVE_NOW.  */
		  for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
		    if (REG_NOTE_KIND (link) == REG_DEAD)
		      reg_dies (XEXP (link, 0), live_now);
1126

1127 1128 1129 1130 1131 1132
		  note_stores (PATTERN (insn), reg_becomes_live, &live_now);
		  for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
		    if (REG_NOTE_KIND (link) == REG_UNUSED)
		      reg_dies (XEXP (link, 0), live_now);
		}
	    }
1133

1134
	  info[bb->index].computing = last_mode;
1135 1136 1137
	  /* Check for blocks without ANY mode requirements.  */
	  if (last_mode == no_mode)
	    {
1138
	      ptr = new_seginfo (no_mode, bb->end, bb->index, live_now);
1139
	      add_seginfo (info + bb->index, ptr);
1140 1141
	    }
	}
1142
#ifdef NORMAL_MODE
1143
      {
1144
	int mode = NORMAL_MODE (e);
1145

1146 1147
	if (mode != no_mode)
	  {
1148
	    bb = post_entry;
1149

1150 1151 1152 1153 1154
	    /* By always making this nontransparent, we save
	       an extra check in make_preds_opaque.  We also
	       need this to avoid confusing pre_edge_lcm when
	       antic is cleared but transp and comp are set.  */
	    RESET_BIT (transp[bb->index], j);
1155

1156 1157 1158 1159 1160 1161 1162
	    /* Insert a fake computing definition of MODE into entry
	       blocks which compute no mode. This represents the mode on
	       entry.  */
	    info[bb->index].computing = mode;

	    if (pre_exit)
	      info[pre_exit->index].seginfo->mode = mode;
1163 1164
	  }
      }
1165
#endif /* NORMAL_MODE */
1166 1167
    }

1168
  kill = sbitmap_vector_alloc (last_basic_block, n_entities);
1169 1170 1171 1172 1173
  for (i = 0; i < max_num_modes; i++)
    {
      int current_mode[N_ENTITIES];

      /* Set the anticipatable and computing arrays.  */
1174 1175
      sbitmap_vector_zero (antic, last_basic_block);
      sbitmap_vector_zero (comp, last_basic_block);
1176 1177 1178
      for (j = n_entities - 1; j >= 0; j--)
	{
	  int m = current_mode[j] = MODE_PRIORITY_TO_MODE (entity_map[j], i);
Daniel Berlin committed
1179
	  struct bb_info *info = bb_info[j];
1180

1181
	  FOR_EACH_BB (bb)
1182
	    {
1183 1184
	      if (info[bb->index].seginfo->mode == m)
		SET_BIT (antic[bb->index], j);
1185

1186 1187
	      if (info[bb->index].computing == m)
		SET_BIT (comp[bb->index], j);
1188 1189 1190 1191 1192 1193
	    }
	}

      /* Calculate the optimal locations for the
	 placement mode switches to modes with priority I.  */

1194 1195
      FOR_EACH_BB (bb)
	sbitmap_not (kill[bb->index], transp[bb->index]);
1196 1197 1198
      edge_list = pre_edge_lcm (file, 1, transp, comp, antic,
				kill, &insert, &delete);

1199
      for (j = n_entities - 1; j >= 0; j--)
1200 1201 1202
	{
	  /* Insert all mode sets that have been inserted by lcm.  */
	  int no_mode = num_modes[entity_map[j]];
1203

1204 1205 1206 1207 1208 1209 1210 1211 1212 1213 1214 1215 1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228
	  /* Wherever we have moved a mode setting upwards in the flow graph,
	     the blocks between the new setting site and the now redundant
	     computation ceases to be transparent for any lower-priority
	     mode of the same entity.  First set the aux field of each
	     insertion site edge non-transparent, then propagate the new
	     non-transparency from the redundant computation upwards till
	     we hit an insertion site or an already non-transparent block.  */
	  for (e = NUM_EDGES (edge_list) - 1; e >= 0; e--)
	    {
	      edge eg = INDEX_EDGE (edge_list, e);
	      int mode;
	      basic_block src_bb;
	      HARD_REG_SET live_at_edge;
	      rtx mode_set;

	      eg->aux = 0;

	      if (! TEST_BIT (insert[e], j))
		continue;

	      eg->aux = (void *)1;

	      mode = current_mode[j];
	      src_bb = eg->src;

1229 1230 1231
	      REG_SET_TO_HARD_REG_SET (live_at_edge,
				       src_bb->global_live_at_end);

1232 1233
	      start_sequence ();
	      EMIT_MODE_SET (entity_map[j], mode, live_at_edge);
1234
	      mode_set = get_insns ();
1235 1236
	      end_sequence ();

1237
	      /* Do not bother to insert empty sequence.  */
1238
	      if (mode_set == NULL_RTX)
1239 1240
		continue;

1241 1242
	      /* If this is an abnormal edge, we'll insert at the end
		 of the previous block.  */
1243 1244
	      if (eg->flags & EDGE_ABNORMAL)
		{
1245
		  emited = true;
1246 1247
		  if (GET_CODE (src_bb->end) == JUMP_INSN)
		    emit_insn_before (mode_set, src_bb->end);
1248 1249 1250 1251 1252 1253 1254 1255 1256 1257 1258 1259
		  /* It doesn't make sense to switch to normal mode
		     after a CALL_INSN, so we're going to abort if we
		     find one.  The cases in which a CALL_INSN may
		     have an abnormal edge are sibcalls and EH edges.
		     In the case of sibcalls, the dest basic-block is
		     the EXIT_BLOCK, that runs in normal mode; it is
		     assumed that a sibcall insn requires normal mode
		     itself, so no mode switch would be required after
		     the call (it wouldn't make sense, anyway).  In
		     the case of EH edges, EH entry points also start
		     in normal mode, so a similar reasoning applies.  */
		  else if (GET_CODE (src_bb->end) == INSN)
1260
		    emit_insn_after (mode_set, src_bb->end);
1261 1262
		  else
		    abort ();
1263 1264
		  bb_info[j][src_bb->index].computing = mode;
		  RESET_BIT (transp[src_bb->index], j);
1265 1266 1267 1268 1269 1270 1271 1272
		}
	      else
		{
		  need_commit = 1;
		  insert_insn_on_edge (mode_set, eg);
		}
	    }

1273 1274
	  FOR_EACH_BB_REVERSE (bb)
	    if (TEST_BIT (delete[bb->index], j))
1275
	      {
1276
		make_preds_opaque (bb, j);
1277
		/* Cancel the 'deleted' mode set.  */
1278
		bb_info[j][bb->index].seginfo->mode = no_mode;
1279
	      }
1280
	}
1281

1282
      clear_aux_for_edges ();
1283 1284 1285 1286 1287 1288
      free_edge_list (edge_list);
    }

  /* Now output the remaining mode sets in all the segments.  */
  for (j = n_entities - 1; j >= 0; j--)
    {
1289 1290
      int no_mode = num_modes[entity_map[j]];

1291
      FOR_EACH_BB_REVERSE (bb)
1292 1293
	{
	  struct seginfo *ptr, *next;
1294
	  for (ptr = bb_info[j][bb->index].seginfo; ptr; ptr = next)
1295 1296
	    {
	      next = ptr->next;
1297
	      if (ptr->mode != no_mode)
1298 1299 1300 1301 1302
		{
		  rtx mode_set;

		  start_sequence ();
		  EMIT_MODE_SET (entity_map[j], ptr->mode, ptr->regs_live);
1303
		  mode_set = get_insns ();
1304 1305
		  end_sequence ();

1306
		  /* Do not bother to insert empty sequence.  */
1307
		  if (mode_set == NULL_RTX)
1308 1309 1310
		    continue;

		  emited = true;
1311 1312 1313
		  if (GET_CODE (ptr->insn_ptr) == NOTE
		      && (NOTE_LINE_NUMBER (ptr->insn_ptr)
			  == NOTE_INSN_BASIC_BLOCK))
1314
		    emit_insn_after (mode_set, ptr->insn_ptr);
1315
		  else
1316
		    emit_insn_before (mode_set, ptr->insn_ptr);
1317
		}
1318

1319 1320 1321
	      free (ptr);
	    }
	}
1322

1323 1324 1325 1326
      free (bb_info[j]);
    }

  /* Finished. Free up all the things we've allocated.  */
1327

1328 1329 1330 1331 1332 1333 1334 1335 1336
  sbitmap_vector_free (kill);
  sbitmap_vector_free (antic);
  sbitmap_vector_free (transp);
  sbitmap_vector_free (comp);
  sbitmap_vector_free (delete);
  sbitmap_vector_free (insert);

  if (need_commit)
    commit_edge_insertions ();
1337

1338 1339 1340
#ifdef NORMAL_MODE
  cleanup_cfg (CLEANUP_NO_INSN_DEL);
#else
1341 1342
  if (!need_commit && !emited)
    return 0;
1343
#endif
1344

1345 1346 1347 1348 1349
  max_regno = max_reg_num ();
  allocate_reg_info (max_regno, FALSE, FALSE);
  update_life_info_in_dirty_blocks (UPDATE_LIFE_GLOBAL_RM_NOTES,
				    (PROP_DEATH_NOTES | PROP_KILL_DEAD_CODE
				     | PROP_SCAN_DEAD_CODE));
1350 1351

  return 1;
1352
}
1353
#endif /* OPTIMIZE_MODE_SWITCHING */