lcm.c 25.7 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, 2008,
3
   2010, 2011 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
#include "rtl.h"
#include "regs.h"
#include "hard-reg-set.h"
#include "flags.h"
#include "insn-config.h"
#include "recog.h"
#include "basic-block.h"
63
#include "output.h"
64
#include "tm_p.h"
65
#include "function.h"
66
#include "sbitmap.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
  *del = sbitmap_vector_alloc (last_basic_block, n_exprs);
454 455
  sbitmap_vector_zero (*insert, num_edges);
  sbitmap_vector_zero (*del, last_basic_block);
456
  compute_insert_delete (edge_list, antloc, later, laterin, *insert, *del);
Jeffrey A Law committed
457

458 459
  sbitmap_vector_free (laterin);
  sbitmap_vector_free (later);
460 461

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

470 471
  return edge_list;
}
Daniel Berlin committed
472 473 474 475

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

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

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

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

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

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

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

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

      if (qout >= qend)
519
	qout = worklist;
Daniel Berlin committed
520 521 522 523

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

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

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

  clear_aux_for_edges ();
  clear_aux_for_blocks ();
  free (worklist);
Jeffrey A Law committed
556 557
}

558
/* Compute the farthest vector for edge based lcm.  */
559

Jeffrey A Law committed
560
static void
561 562 563
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
564
{
565
  sbitmap difference, temp_bitmap;
566
  int x, num_edges;
567
  basic_block pred, succ;
Jeffrey A Law committed
568

569
  num_edges = NUM_EDGES (edge_list);
Jeffrey A Law committed
570

571 572
  difference = sbitmap_alloc (n_exprs);
  temp_bitmap = sbitmap_alloc (n_exprs);
Jeffrey A Law committed
573

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

595 596
  sbitmap_free (temp_bitmap);
  sbitmap_free (difference);
Jeffrey A Law committed
597 598
}

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

613
  num_edges = NUM_EDGES (edge_list);
Jeffrey A Law committed
614

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

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

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

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

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

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

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

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

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

680
  clear_aux_for_edges ();
681
  free (tos);
682
}
Jeffrey A Law committed
683

684
/* Compute the insertion and deletion points for edge based LCM.  */
685

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

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

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

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

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

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

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

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

#ifdef LCM_DEBUG_INFO
739
  if (dump_file)
740
    {
741 742 743 744 745 746 747 748 749
      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);
750 751
    }
#endif
Jeffrey A Law committed
752

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

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

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

771 772 773 774 775
  sbitmap_vector_free (st_antin);
  sbitmap_vector_free (st_antout);

  sbitmap_vector_free (st_avin);
  sbitmap_vector_free (st_avout);
776 777

  nearer = sbitmap_vector_alloc (num_edges, n_exprs);
778

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

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

792
  sbitmap_vector_free (farthest);
793 794

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

799 800
  sbitmap_vector_free (nearerout);
  sbitmap_vector_free (nearer);
801 802

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