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

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

7 8
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
9
Software Foundation; either version 3, or (at your option) any later
10
version.
Jeffrey A Law committed
11

12 13 14 15
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
16 17

You should have received a copy of the GNU General Public License
18 19
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */
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
static void compute_antinout_edge (sbitmap *, sbitmap *, sbitmap *, sbitmap *);
static void compute_earliest (struct edge_list *, int, sbitmap *, sbitmap *,
			      sbitmap *, sbitmap *, sbitmap *);
static void compute_laterin (struct edge_list *, sbitmap *, sbitmap *,
			     sbitmap *, sbitmap *);
static void compute_insert_delete (struct edge_list *edge_list, sbitmap *,
				   sbitmap *, sbitmap *, sbitmap *, sbitmap *);
80 81

/* Edge based LCM routines on a reverse flowgraph.  */
82 83 84 85 86 87 88
static void compute_farthest (struct edge_list *, int, sbitmap *, sbitmap *,
			      sbitmap*, sbitmap *, sbitmap *);
static void compute_nearerout (struct edge_list *, sbitmap *, sbitmap *,
			       sbitmap *, sbitmap *);
static void compute_rev_insert_delete (struct edge_list *edge_list, sbitmap *,
				       sbitmap *, sbitmap *, sbitmap *,
				       sbitmap *);
89 90

/* Edge based lcm routines.  */
Daniel Berlin committed
91

92 93
/* 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.
94
   Other than that, its pretty much identical to compute_antinout.  */
Jeffrey A Law committed
95 96

static void
97 98
compute_antinout_edge (sbitmap *antloc, sbitmap *transp, sbitmap *antin,
		       sbitmap *antout)
Jeffrey A Law committed
99
{
100
  basic_block bb;
101
  edge e;
102 103
  basic_block *worklist, *qin, *qout, *qend;
  unsigned int qlen;
104
  edge_iterator ei;
Daniel Berlin committed
105

106 107 108
  /* 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.  */
109
  qin = qout = worklist = XNEWVEC (basic_block, n_basic_blocks);
Jeffrey A Law committed
110

111 112
  /* We want a maximal solution, so make an optimistic initialization of
     ANTIN.  */
113
  sbitmap_vector_ones (antin, last_basic_block);
Jeffrey A Law committed
114

115 116
  /* Put every block on the worklist; this is necessary because of the
     optimistic initialization of ANTIN above.  */
117
  FOR_EACH_BB_REVERSE (bb)
Jeffrey A Law committed
118
    {
119
      *qin++ = bb;
120
      bb->aux = bb;
121
    }
122

123
  qin = worklist;
124 125
  qend = &worklist[n_basic_blocks - NUM_FIXED_BLOCKS];
  qlen = n_basic_blocks - NUM_FIXED_BLOCKS;
Jeffrey A Law committed
126

127 128
  /* Mark blocks which are predecessors of the exit block so that we
     can easily identify them below.  */
129
  FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds)
130 131
    e->src->aux = EXIT_BLOCK_PTR;

132
  /* Iterate until the worklist is empty.  */
133
  while (qlen)
134 135
    {
      /* Take the first entry off the worklist.  */
136
      bb = *qout++;
137
      qlen--;
Daniel Berlin committed
138

139
      if (qout >= qend)
140
	qout = worklist;
Jeffrey A Law committed
141

142
      if (bb->aux == EXIT_BLOCK_PTR)
143 144 145
	/* 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.  */
146
	sbitmap_zero (antout[bb->index]);
147 148 149 150
      else
	{
	  /* Clear the aux field of this block so that it can be added to
	     the worklist again if necessary.  */
151 152
	  bb->aux = NULL;
	  sbitmap_intersection_of_succs (antout[bb->index], antin, bb->index);
153
	}
154

155 156
      if (sbitmap_a_or_b_and_c_cg (antin[bb->index], antloc[bb->index],
				   transp[bb->index], antout[bb->index]))
157 158 159
	/* 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.  */
160
	FOR_EACH_EDGE (e, ei, bb->preds)
161
	  if (!e->src->aux && e->src != ENTRY_BLOCK_PTR)
Jeffrey A Law committed
162
	    {
163
	      *qin++ = e->src;
164
	      e->src->aux = e;
165 166
	      qlen++;
	      if (qin >= qend)
167
		qin = worklist;
Jeffrey A Law committed
168 169
	    }
    }
170

171 172
  clear_aux_for_edges ();
  clear_aux_for_blocks ();
173
  free (worklist);
Jeffrey A Law committed
174 175
}

176
/* Compute the earliest vector for edge based lcm.  */
177

Jeffrey A Law committed
178
static void
179 180 181
compute_earliest (struct edge_list *edge_list, int n_exprs, sbitmap *antin,
		  sbitmap *antout, sbitmap *avout, sbitmap *kill,
		  sbitmap *earliest)
Jeffrey A Law committed
182
{
183
  sbitmap difference, temp_bitmap;
184
  int x, num_edges;
185
  basic_block pred, succ;
Jeffrey A Law committed
186

187
  num_edges = NUM_EDGES (edge_list);
Jeffrey A Law committed
188

189 190
  difference = sbitmap_alloc (n_exprs);
  temp_bitmap = sbitmap_alloc (n_exprs);
Jeffrey A Law committed
191

192
  for (x = 0; x < num_edges; x++)
Jeffrey A Law committed
193
    {
194 195 196
      pred = INDEX_EDGE_PRED_BB (edge_list, x);
      succ = INDEX_EDGE_SUCC_BB (edge_list, x);
      if (pred == ENTRY_BLOCK_PTR)
197
	sbitmap_copy (earliest[x], antin[succ->index]);
198
      else
199
	{
200
	  if (succ == EXIT_BLOCK_PTR)
201
	    sbitmap_zero (earliest[x]);
202
	  else
Jeffrey A Law committed
203
	    {
204 205 206
	      sbitmap_difference (difference, antin[succ->index],
				  avout[pred->index]);
	      sbitmap_not (temp_bitmap, antout[pred->index]);
207
	      sbitmap_a_and_b_or_c (earliest[x], difference,
208
				    kill[pred->index], temp_bitmap);
Jeffrey A Law committed
209 210 211
	    }
	}
    }
212

213 214
  sbitmap_free (temp_bitmap);
  sbitmap_free (difference);
Jeffrey A Law committed
215 216
}

217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244
/* 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.  */
245

Jeffrey A Law committed
246
static void
247 248
compute_laterin (struct edge_list *edge_list, sbitmap *earliest,
		 sbitmap *antloc, sbitmap *later, sbitmap *laterin)
Jeffrey A Law committed
249
{
250
  int num_edges, i;
251
  edge e;
252
  basic_block *worklist, *qin, *qout, *qend, bb;
253
  unsigned int qlen;
254
  edge_iterator ei;
Jeffrey A Law committed
255

256
  num_edges = NUM_EDGES (edge_list);
Jeffrey A Law committed
257

258 259 260
  /* 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.  */
261
  qin = qout = worklist
262
    = XNEWVEC (basic_block, n_basic_blocks);
263 264 265

  /* Initialize a mapping from each edge to its index.  */
  for (i = 0; i < num_edges; i++)
266
    INDEX_EDGE (edge_list, i)->aux = (void *) (size_t) i;
267 268 269 270 271 272 273 274 275 276 277 278 279

  /* 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);

280 281 282 283
  /* 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.  */
284
  FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
285
    sbitmap_copy (later[(size_t) e->aux], earliest[(size_t) e->aux]);
286

287 288
  /* Add all the blocks to the worklist.  This prevents an early exit from
     the loop given our optimistic initialization of LATER above.  */
289
  FOR_EACH_BB (bb)
Jeffrey A Law committed
290
    {
291 292
      *qin++ = bb;
      bb->aux = bb;
293
    }
294

295
  /* Note that we do not use the last allocated element for our queue,
296
     as EXIT_BLOCK is never inserted into it. */
297
  qin = worklist;
298 299
  qend = &worklist[n_basic_blocks - NUM_FIXED_BLOCKS];
  qlen = n_basic_blocks - NUM_FIXED_BLOCKS;
300

301
  /* Iterate until the worklist is empty.  */
302
  while (qlen)
303
    {
304
      /* Take the first entry off the worklist.  */
305 306
      bb = *qout++;
      bb->aux = NULL;
307 308
      qlen--;
      if (qout >= qend)
309
	qout = worklist;
310 311

      /* Compute the intersection of LATERIN for each incoming edge to B.  */
312
      sbitmap_ones (laterin[bb->index]);
313
      FOR_EACH_EDGE (e, ei, bb->preds)
314 315
	sbitmap_a_and_b (laterin[bb->index], laterin[bb->index],
			 later[(size_t)e->aux]);
316 317

      /* Calculate LATER for all outgoing edges.  */
318
      FOR_EACH_EDGE (e, ei, bb->succs)
319
	if (sbitmap_union_of_diff_cg (later[(size_t) e->aux],
320 321 322
				      earliest[(size_t) e->aux],
				      laterin[e->src->index],
				      antloc[e->src->index])
323 324 325 326
	    /* 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)
	  {
327
	    *qin++ = e->dest;
328
	    e->dest->aux = e;
329 330 331
	    qlen++;
	    if (qin >= qend)
	      qin = worklist;
332
	  }
Jeffrey A Law committed
333 334
    }

335 336 337
  /* 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.  */
338
  sbitmap_ones (laterin[last_basic_block]);
339
  FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds)
340 341
    sbitmap_a_and_b (laterin[last_basic_block],
		     laterin[last_basic_block],
342
		     later[(size_t) e->aux]);
343

344
  clear_aux_for_edges ();
345
  free (worklist);
Jeffrey A Law committed
346 347
}

348
/* Compute the insertion and deletion points for edge based LCM.  */
349

350
static void
351 352
compute_insert_delete (struct edge_list *edge_list, sbitmap *antloc,
		       sbitmap *later, sbitmap *laterin, sbitmap *insert,
353
		       sbitmap *del)
354 355
{
  int x;
356
  basic_block bb;
Jeffrey A Law committed
357

358
  FOR_EACH_BB (bb)
359
    sbitmap_difference (del[bb->index], antloc[bb->index],
360
			laterin[bb->index]);
361

362 363 364
  for (x = 0; x < NUM_EDGES (edge_list); x++)
    {
      basic_block b = INDEX_EDGE_SUCC_BB (edge_list, x);
365

366
      if (b == EXIT_BLOCK_PTR)
367
	sbitmap_difference (insert[x], later[x], laterin[last_basic_block]);
368
      else
369
	sbitmap_difference (insert[x], later[x], laterin[b->index]);
370 371
    }
}
Jeffrey A Law committed
372

373 374 375
/* 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
376

377
struct edge_list *
378
pre_edge_lcm (int n_exprs, sbitmap *transp,
379
	      sbitmap *avloc, sbitmap *antloc, sbitmap *kill,
380
	      sbitmap **insert, sbitmap **del)
Jeffrey A Law committed
381
{
382 383 384 385 386
  sbitmap *antin, *antout, *earliest;
  sbitmap *avin, *avout;
  sbitmap *later, *laterin;
  struct edge_list *edge_list;
  int num_edges;
Jeffrey A Law committed
387

388 389
  edge_list = create_edge_list ();
  num_edges = NUM_EDGES (edge_list);
Jeffrey A Law committed
390

391
#ifdef LCM_DEBUG_INFO
392
  if (dump_file)
Jeffrey A Law committed
393
    {
394 395 396 397 398 399 400
      fprintf (dump_file, "Edge List:\n");
      verify_edge_list (dump_file, edge_list);
      print_edge_list (dump_file, edge_list);
      dump_sbitmap_vector (dump_file, "transp", "", transp, last_basic_block);
      dump_sbitmap_vector (dump_file, "antloc", "", antloc, last_basic_block);
      dump_sbitmap_vector (dump_file, "avloc", "", avloc, last_basic_block);
      dump_sbitmap_vector (dump_file, "kill", "", kill, last_basic_block);
Jeffrey A Law committed
401
    }
402
#endif
Jeffrey A Law committed
403

404
  /* Compute global availability.  */
405 406
  avin = sbitmap_vector_alloc (last_basic_block, n_exprs);
  avout = sbitmap_vector_alloc (last_basic_block, n_exprs);
407
  compute_available (avloc, kill, avout, avin);
408
  sbitmap_vector_free (avin);
Jeffrey A Law committed
409

410
  /* Compute global anticipatability.  */
411 412
  antin = sbitmap_vector_alloc (last_basic_block, n_exprs);
  antout = sbitmap_vector_alloc (last_basic_block, n_exprs);
413
  compute_antinout_edge (antloc, transp, antin, antout);
Jeffrey A Law committed
414

415
#ifdef LCM_DEBUG_INFO
416
  if (dump_file)
Jeffrey A Law committed
417
    {
418 419
      dump_sbitmap_vector (dump_file, "antin", "", antin, last_basic_block);
      dump_sbitmap_vector (dump_file, "antout", "", antout, last_basic_block);
Jeffrey A Law committed
420
    }
421
#endif
Jeffrey A Law committed
422

423 424 425
  /* 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
426

427
#ifdef LCM_DEBUG_INFO
428 429
  if (dump_file)
    dump_sbitmap_vector (dump_file, "earliest", "", earliest, num_edges);
430
#endif
Jeffrey A Law committed
431

432 433 434
  sbitmap_vector_free (antout);
  sbitmap_vector_free (antin);
  sbitmap_vector_free (avout);
Jeffrey A Law committed
435

436
  later = sbitmap_vector_alloc (num_edges, n_exprs);
437

438
  /* Allocate an extra element for the exit block in the laterin vector.  */
439
  laterin = sbitmap_vector_alloc (last_basic_block + 1, n_exprs);
440 441
  compute_laterin (edge_list, earliest, antloc, later, laterin);

442
#ifdef LCM_DEBUG_INFO
443
  if (dump_file)
444
    {
445 446
      dump_sbitmap_vector (dump_file, "laterin", "", laterin, last_basic_block + 1);
      dump_sbitmap_vector (dump_file, "later", "", later, num_edges);
447 448
    }
#endif
Jeffrey A Law committed
449

450
  sbitmap_vector_free (earliest);
451 452

  *insert = sbitmap_vector_alloc (num_edges, n_exprs);
453 454
  *del = sbitmap_vector_alloc (last_basic_block, n_exprs);
  compute_insert_delete (edge_list, antloc, later, laterin, *insert, *del);
Jeffrey A Law committed
455

456 457
  sbitmap_vector_free (laterin);
  sbitmap_vector_free (later);
458 459

#ifdef LCM_DEBUG_INFO
460
  if (dump_file)
Jeffrey A Law committed
461
    {
462
      dump_sbitmap_vector (dump_file, "pre_insert_map", "", *insert, num_edges);
463
      dump_sbitmap_vector (dump_file, "pre_delete_map", "", *del,
464
			   last_basic_block);
Jeffrey A Law committed
465
    }
466
#endif
Jeffrey A Law committed
467

468 469
  return edge_list;
}
Daniel Berlin committed
470 471 472 473

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

474
void
475 476
compute_available (sbitmap *avloc, sbitmap *kill, sbitmap *avout,
		   sbitmap *avin)
Jeffrey A Law committed
477
{
Daniel Berlin committed
478
  edge e;
479
  basic_block *worklist, *qin, *qout, *qend, bb;
Daniel Berlin committed
480
  unsigned int qlen;
481
  edge_iterator ei;
Daniel Berlin committed
482 483 484 485

  /* 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.  */
486
  qin = qout = worklist = 
487
    XNEWVEC (basic_block, n_basic_blocks - NUM_FIXED_BLOCKS);
Daniel Berlin committed
488 489

  /* We want a maximal solution.  */
490
  sbitmap_vector_ones (avout, last_basic_block);
Daniel Berlin committed
491 492 493

  /* Put every block on the worklist; this is necessary because of the
     optimistic initialization of AVOUT above.  */
494
  FOR_EACH_BB (bb)
Daniel Berlin committed
495
    {
496 497
      *qin++ = bb;
      bb->aux = bb;
Daniel Berlin committed
498 499 500
    }

  qin = worklist;
501 502
  qend = &worklist[n_basic_blocks - NUM_FIXED_BLOCKS];
  qlen = n_basic_blocks - NUM_FIXED_BLOCKS;
Daniel Berlin committed
503 504 505

  /* Mark blocks which are successors of the entry block so that we
     can easily identify them below.  */
506
  FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
Daniel Berlin committed
507 508 509 510 511 512
    e->dest->aux = ENTRY_BLOCK_PTR;

  /* Iterate until the worklist is empty.  */
  while (qlen)
    {
      /* Take the first entry off the worklist.  */
513
      bb = *qout++;
Daniel Berlin committed
514 515 516
      qlen--;

      if (qout >= qend)
517
	qout = worklist;
Daniel Berlin committed
518 519 520 521

      /* 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.  */
522
      if (bb->aux == ENTRY_BLOCK_PTR)
Daniel Berlin committed
523 524
	/* 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.  */
525
	sbitmap_zero (avin[bb->index]);
Daniel Berlin committed
526 527 528 529
      else
	{
	  /* Clear the aux field of this block so that it can be added to
	     the worklist again if necessary.  */
530 531
	  bb->aux = NULL;
	  sbitmap_intersection_of_preds (avin[bb->index], avout, bb->index);
Daniel Berlin committed
532 533
	}

534 535
      if (sbitmap_union_of_diff_cg (avout[bb->index], avloc[bb->index],
				    avin[bb->index], kill[bb->index]))
Daniel Berlin committed
536 537 538
	/* 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.  */
539
	FOR_EACH_EDGE (e, ei, bb->succs)
Daniel Berlin committed
540 541 542 543 544 545 546
	  if (!e->dest->aux && e->dest != EXIT_BLOCK_PTR)
	    {
	      *qin++ = e->dest;
	      e->dest->aux = e;
	      qlen++;

	      if (qin >= qend)
547
		qin = worklist;
Daniel Berlin committed
548 549 550 551 552 553
	    }
    }

  clear_aux_for_edges ();
  clear_aux_for_blocks ();
  free (worklist);
Jeffrey A Law committed
554 555
}

556
/* Compute the farthest vector for edge based lcm.  */
557

Jeffrey A Law committed
558
static void
559 560 561
compute_farthest (struct edge_list *edge_list, int n_exprs,
		  sbitmap *st_avout, sbitmap *st_avin, sbitmap *st_antin,
		  sbitmap *kill, sbitmap *farthest)
Jeffrey A Law committed
562
{
563
  sbitmap difference, temp_bitmap;
564
  int x, num_edges;
565
  basic_block pred, succ;
Jeffrey A Law committed
566

567
  num_edges = NUM_EDGES (edge_list);
Jeffrey A Law committed
568

569 570
  difference = sbitmap_alloc (n_exprs);
  temp_bitmap = sbitmap_alloc (n_exprs);
Jeffrey A Law committed
571

572
  for (x = 0; x < num_edges; x++)
Jeffrey A Law committed
573
    {
574 575 576
      pred = INDEX_EDGE_PRED_BB (edge_list, x);
      succ = INDEX_EDGE_SUCC_BB (edge_list, x);
      if (succ == EXIT_BLOCK_PTR)
577
	sbitmap_copy (farthest[x], st_avout[pred->index]);
578
      else
Jeffrey A Law committed
579
	{
580
	  if (pred == ENTRY_BLOCK_PTR)
581
	    sbitmap_zero (farthest[x]);
582 583
	  else
	    {
584 585 586
	      sbitmap_difference (difference, st_avout[pred->index],
				  st_antin[succ->index]);
	      sbitmap_not (temp_bitmap, st_avin[succ->index]);
587
	      sbitmap_a_and_b_or_c (farthest[x], difference,
588
				    kill[succ->index], temp_bitmap);
589
	    }
Jeffrey A Law committed
590 591
	}
    }
592

593 594
  sbitmap_free (temp_bitmap);
  sbitmap_free (difference);
Jeffrey A Law committed
595 596
}

597 598 599 600 601
/* 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
602
static void
603 604
compute_nearerout (struct edge_list *edge_list, sbitmap *farthest,
		   sbitmap *st_avloc, sbitmap *nearer, sbitmap *nearerout)
Jeffrey A Law committed
605
{
606
  int num_edges, i;
607
  edge e;
608
  basic_block *worklist, *tos, bb;
609
  edge_iterator ei;
Jeffrey A Law committed
610

611
  num_edges = NUM_EDGES (edge_list);
Jeffrey A Law committed
612

613 614 615
  /* 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.  */
616
  tos = worklist = XNEWVEC (basic_block, n_basic_blocks + 1);
Jeffrey A Law committed
617

618 619 620
  /* Initialize NEARER for each edge and build a mapping from an edge to
     its index.  */
  for (i = 0; i < num_edges; i++)
621
    INDEX_EDGE (edge_list, i)->aux = (void *) (size_t) i;
622

623 624 625
  /* We want a maximal solution.  */
  sbitmap_vector_ones (nearer, num_edges);

626 627 628 629
  /* 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.  */
630
  FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR->preds)
631
    sbitmap_copy (nearer[(size_t)e->aux], farthest[(size_t)e->aux]);
632

633 634
  /* Add all the blocks to the worklist.  This prevents an early exit
     from the loop given our optimistic initialization of NEARER.  */
635
  FOR_EACH_BB (bb)
Jeffrey A Law committed
636
    {
637 638
      *tos++ = bb;
      bb->aux = bb;
639
    }
640

641 642
  /* Iterate until the worklist is empty.  */
  while (tos != worklist)
643
    {
644
      /* Take the first entry off the worklist.  */
645 646
      bb = *--tos;
      bb->aux = NULL;
647 648

      /* Compute the intersection of NEARER for each outgoing edge from B.  */
649
      sbitmap_ones (nearerout[bb->index]);
650
      FOR_EACH_EDGE (e, ei, bb->succs)
651
	sbitmap_a_and_b (nearerout[bb->index], nearerout[bb->index],
652
			 nearer[(size_t) e->aux]);
653 654

      /* Calculate NEARER for all incoming edges.  */
655
      FOR_EACH_EDGE (e, ei, bb->preds)
656
	if (sbitmap_union_of_diff_cg (nearer[(size_t) e->aux],
657 658 659
				      farthest[(size_t) e->aux],
				      nearerout[e->dest->index],
				      st_avloc[e->dest->index])
660 661 662 663 664 665 666
	    /* 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;
	  }
667
    }
Jeffrey A Law committed
668

669 670 671
  /* 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.  */
672
  sbitmap_ones (nearerout[last_basic_block]);
673
  FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR->succs)
674 675
    sbitmap_a_and_b (nearerout[last_basic_block],
		     nearerout[last_basic_block],
676
		     nearer[(size_t) e->aux]);
677

678
  clear_aux_for_edges ();
679
  free (tos);
680
}
Jeffrey A Law committed
681

682
/* Compute the insertion and deletion points for edge based LCM.  */
683

Jeffrey A Law committed
684
static void
685 686
compute_rev_insert_delete (struct edge_list *edge_list, sbitmap *st_avloc,
			   sbitmap *nearer, sbitmap *nearerout,
687
			   sbitmap *insert, sbitmap *del)
Jeffrey A Law committed
688
{
689
  int x;
690
  basic_block bb;
Jeffrey A Law committed
691

692
  FOR_EACH_BB (bb)
693
    sbitmap_difference (del[bb->index], st_avloc[bb->index],
694
			nearerout[bb->index]);
695

696
  for (x = 0; x < NUM_EDGES (edge_list); x++)
Jeffrey A Law committed
697
    {
698 699
      basic_block b = INDEX_EDGE_PRED_BB (edge_list, x);
      if (b == ENTRY_BLOCK_PTR)
700
	sbitmap_difference (insert[x], nearer[x], nearerout[last_basic_block]);
Jeffrey A Law committed
701
      else
702
	sbitmap_difference (insert[x], nearer[x], nearerout[b->index]);
Jeffrey A Law committed
703 704 705
    }
}

706
/* Given local properties TRANSP, ST_AVLOC, ST_ANTLOC, KILL return the
707 708 709
   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
710

711
struct edge_list *
712
pre_edge_rev_lcm (int n_exprs, sbitmap *transp,
713
		  sbitmap *st_avloc, sbitmap *st_antloc, sbitmap *kill,
714
		  sbitmap **insert, sbitmap **del)
Jeffrey A Law committed
715
{
716 717 718 719
  sbitmap *st_antin, *st_antout;
  sbitmap *st_avout, *st_avin, *farthest;
  sbitmap *nearer, *nearerout;
  struct edge_list *edge_list;
720
  int num_edges;
721 722 723 724

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

725 726
  st_antin = sbitmap_vector_alloc (last_basic_block, n_exprs);
  st_antout = sbitmap_vector_alloc (last_basic_block, n_exprs);
727 728
  sbitmap_vector_zero (st_antin, last_basic_block);
  sbitmap_vector_zero (st_antout, last_basic_block);
729 730 731
  compute_antinout_edge (st_antloc, transp, st_antin, st_antout);

  /* Compute global anticipatability.  */
732 733
  st_avout = sbitmap_vector_alloc (last_basic_block, n_exprs);
  st_avin = sbitmap_vector_alloc (last_basic_block, n_exprs);
734 735 736
  compute_available (st_avloc, kill, st_avout, st_avin);

#ifdef LCM_DEBUG_INFO
737
  if (dump_file)
738
    {
739 740 741 742 743 744 745 746 747
      fprintf (dump_file, "Edge List:\n");
      verify_edge_list (dump_file, edge_list);
      print_edge_list (dump_file, edge_list);
      dump_sbitmap_vector (dump_file, "transp", "", transp, last_basic_block);
      dump_sbitmap_vector (dump_file, "st_avloc", "", st_avloc, last_basic_block);
      dump_sbitmap_vector (dump_file, "st_antloc", "", st_antloc, last_basic_block);
      dump_sbitmap_vector (dump_file, "st_antin", "", st_antin, last_basic_block);
      dump_sbitmap_vector (dump_file, "st_antout", "", st_antout, last_basic_block);
      dump_sbitmap_vector (dump_file, "st_kill", "", kill, last_basic_block);
748 749
    }
#endif
Jeffrey A Law committed
750

751
#ifdef LCM_DEBUG_INFO
752
  if (dump_file)
753
    {
754 755
      dump_sbitmap_vector (dump_file, "st_avout", "", st_avout, last_basic_block);
      dump_sbitmap_vector (dump_file, "st_avin", "", st_avin, last_basic_block);
756 757
    }
#endif
Jeffrey A Law committed
758

759 760
  /* Compute farthestness.  */
  farthest = sbitmap_vector_alloc (num_edges, n_exprs);
761
  compute_farthest (edge_list, n_exprs, st_avout, st_avin, st_antin,
762 763 764
		    kill, farthest);

#ifdef LCM_DEBUG_INFO
765 766
  if (dump_file)
    dump_sbitmap_vector (dump_file, "farthest", "", farthest, num_edges);
767 768
#endif

769 770 771 772 773
  sbitmap_vector_free (st_antin);
  sbitmap_vector_free (st_antout);

  sbitmap_vector_free (st_avin);
  sbitmap_vector_free (st_avout);
774 775

  nearer = sbitmap_vector_alloc (num_edges, n_exprs);
776

777
  /* Allocate an extra element for the entry block.  */
778
  nearerout = sbitmap_vector_alloc (last_basic_block + 1, n_exprs);
779
  compute_nearerout (edge_list, farthest, st_avloc, nearer, nearerout);
780 781

#ifdef LCM_DEBUG_INFO
782
  if (dump_file)
Jeffrey A Law committed
783
    {
784
      dump_sbitmap_vector (dump_file, "nearerout", "", nearerout,
785
			   last_basic_block + 1);
786
      dump_sbitmap_vector (dump_file, "nearer", "", nearer, num_edges);
Jeffrey A Law committed
787
    }
788 789
#endif

790
  sbitmap_vector_free (farthest);
791 792

  *insert = sbitmap_vector_alloc (num_edges, n_exprs);
793
  *del = sbitmap_vector_alloc (last_basic_block, n_exprs);
794
  compute_rev_insert_delete (edge_list, st_avloc, nearer, nearerout,
795
			     *insert, *del);
796

797 798
  sbitmap_vector_free (nearerout);
  sbitmap_vector_free (nearer);
799 800

#ifdef LCM_DEBUG_INFO
801
  if (dump_file)
802
    {
803
      dump_sbitmap_vector (dump_file, "pre_insert_map", "", *insert, num_edges);
804
      dump_sbitmap_vector (dump_file, "pre_delete_map", "", *del,
805
			   last_basic_block);
806 807 808
    }
#endif
  return edge_list;
Jeffrey A Law committed
809
}
810