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

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

6 7
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
8
Software Foundation; either version 3, or (at your option) any later
9
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
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */
Jeffrey A Law committed
19 20

/* These routines are meant to be used by various optimization
21
   passes which can be modeled as lazy code motion problems.
Jeffrey A Law committed
22 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
   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"
53
#include "coretypes.h"
54
#include "backend.h"
55 56
#include "cfganal.h"
#include "lcm.h"
Jeffrey A Law committed
57

58
/* Edge based LCM routines.  */
59 60 61 62 63 64 65
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 *);
66 67

/* Edge based LCM routines on a reverse flowgraph.  */
68 69 70 71 72 73 74
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 *);
75 76

/* Edge based lcm routines.  */
Daniel Berlin committed
77

78 79
/* 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.
80
   Other than that, its pretty much identical to compute_antinout.  */
Jeffrey A Law committed
81 82

static void
83 84
compute_antinout_edge (sbitmap *antloc, sbitmap *transp, sbitmap *antin,
		       sbitmap *antout)
Jeffrey A Law committed
85
{
86
  basic_block bb;
87
  edge e;
88 89
  basic_block *worklist, *qin, *qout, *qend;
  unsigned int qlen;
90
  edge_iterator ei;
Daniel Berlin committed
91

92 93 94
  /* 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.  */
95
  qin = qout = worklist = XNEWVEC (basic_block, n_basic_blocks_for_fn (cfun));
Jeffrey A Law committed
96

97 98
  /* We want a maximal solution, so make an optimistic initialization of
     ANTIN.  */
99
  bitmap_vector_ones (antin, last_basic_block_for_fn (cfun));
Jeffrey A Law committed
100

101 102
  /* Put every block on the worklist; this is necessary because of the
     optimistic initialization of ANTIN above.  */
103 104 105
  int *postorder = XNEWVEC (int, n_basic_blocks_for_fn (cfun));
  int postorder_num = post_order_compute (postorder, false, false);
  for (int i = 0; i < postorder_num; ++i)
Jeffrey A Law committed
106
    {
107
      bb = BASIC_BLOCK_FOR_FN (cfun, postorder[i]);
108
      *qin++ = bb;
109
      bb->aux = bb;
110
    }
111
  free (postorder);
112

113
  qin = worklist;
114 115
  qend = &worklist[n_basic_blocks_for_fn (cfun) - NUM_FIXED_BLOCKS];
  qlen = n_basic_blocks_for_fn (cfun) - NUM_FIXED_BLOCKS;
Jeffrey A Law committed
116

117 118
  /* Mark blocks which are predecessors of the exit block so that we
     can easily identify them below.  */
119 120
  FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
    e->src->aux = EXIT_BLOCK_PTR_FOR_FN (cfun);
121

122
  /* Iterate until the worklist is empty.  */
123
  while (qlen)
124 125
    {
      /* Take the first entry off the worklist.  */
126
      bb = *qout++;
127
      qlen--;
Daniel Berlin committed
128

129
      if (qout >= qend)
130
	qout = worklist;
Jeffrey A Law committed
131

132
      if (bb->aux == EXIT_BLOCK_PTR_FOR_FN (cfun))
133 134 135
	/* 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.  */
136
	bitmap_clear (antout[bb->index]);
137 138 139 140
      else
	{
	  /* Clear the aux field of this block so that it can be added to
	     the worklist again if necessary.  */
141
	  bb->aux = NULL;
142
	  bitmap_intersection_of_succs (antout[bb->index], antin, bb);
143
	}
144

145
      if (bitmap_or_and (antin[bb->index], antloc[bb->index],
146
				   transp[bb->index], antout[bb->index]))
147 148 149
	/* 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.  */
150
	FOR_EACH_EDGE (e, ei, bb->preds)
151
	  if (!e->src->aux && e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun))
Jeffrey A Law committed
152
	    {
153
	      *qin++ = e->src;
154
	      e->src->aux = e;
155 156
	      qlen++;
	      if (qin >= qend)
157
		qin = worklist;
Jeffrey A Law committed
158 159
	    }
    }
160

161 162
  clear_aux_for_edges ();
  clear_aux_for_blocks ();
163
  free (worklist);
Jeffrey A Law committed
164 165
}

166
/* Compute the earliest vector for edge based lcm.  */
167

Jeffrey A Law committed
168
static void
169 170 171
compute_earliest (struct edge_list *edge_list, int n_exprs, sbitmap *antin,
		  sbitmap *antout, sbitmap *avout, sbitmap *kill,
		  sbitmap *earliest)
Jeffrey A Law committed
172
{
173
  int x, num_edges;
174
  basic_block pred, succ;
Jeffrey A Law committed
175

176
  num_edges = NUM_EDGES (edge_list);
Jeffrey A Law committed
177

178
  auto_sbitmap difference (n_exprs), temp_bitmap (n_exprs);
179
  for (x = 0; x < num_edges; x++)
Jeffrey A Law committed
180
    {
181 182
      pred = INDEX_EDGE_PRED_BB (edge_list, x);
      succ = INDEX_EDGE_SUCC_BB (edge_list, x);
183
      if (pred == ENTRY_BLOCK_PTR_FOR_FN (cfun))
184
	bitmap_copy (earliest[x], antin[succ->index]);
185
      else
186
	{
187
	  if (succ == EXIT_BLOCK_PTR_FOR_FN (cfun))
188
	    bitmap_clear (earliest[x]);
189
	  else
Jeffrey A Law committed
190
	    {
191
	      bitmap_and_compl (difference, antin[succ->index],
192
				  avout[pred->index]);
193 194
	      bitmap_not (temp_bitmap, antout[pred->index]);
	      bitmap_and_or (earliest[x], difference,
195
				    kill[pred->index], temp_bitmap);
Jeffrey A Law committed
196 197 198 199 200
	    }
	}
    }
}

201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228
/* 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.  */
229

Jeffrey A Law committed
230
static void
231 232
compute_laterin (struct edge_list *edge_list, sbitmap *earliest,
		 sbitmap *antloc, sbitmap *later, sbitmap *laterin)
Jeffrey A Law committed
233
{
234
  int num_edges, i;
235
  edge e;
236
  basic_block *worklist, *qin, *qout, *qend, bb;
237
  unsigned int qlen;
238
  edge_iterator ei;
Jeffrey A Law committed
239

240
  num_edges = NUM_EDGES (edge_list);
Jeffrey A Law committed
241

242 243 244
  /* 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.  */
245
  qin = qout = worklist
246
    = XNEWVEC (basic_block, n_basic_blocks_for_fn (cfun));
247 248 249

  /* Initialize a mapping from each edge to its index.  */
  for (i = 0; i < num_edges; i++)
250
    INDEX_EDGE (edge_list, i)->aux = (void *) (size_t) i;
251 252 253 254 255 256 257 258 259 260 261

  /* 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.  */
262
  bitmap_vector_ones (later, num_edges);
263

264 265 266 267
  /* 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.  */
268
  FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR_FOR_FN (cfun)->succs)
269
    bitmap_copy (later[(size_t) e->aux], earliest[(size_t) e->aux]);
270

271 272
  /* Add all the blocks to the worklist.  This prevents an early exit from
     the loop given our optimistic initialization of LATER above.  */
273 274 275
  auto_vec<int, 20> postorder;
  inverted_post_order_compute (&postorder);
  for (unsigned int i = 0; i < postorder.length (); ++i)
Jeffrey A Law committed
276
    {
277 278 279 280
      bb = BASIC_BLOCK_FOR_FN (cfun, postorder[i]);
      if (bb == EXIT_BLOCK_PTR_FOR_FN (cfun)
	  || bb == ENTRY_BLOCK_PTR_FOR_FN (cfun))
	continue;
281 282
      *qin++ = bb;
      bb->aux = bb;
283
    }
284

285
  /* Note that we do not use the last allocated element for our queue,
286
     as EXIT_BLOCK is never inserted into it. */
287
  qin = worklist;
288 289
  qend = &worklist[n_basic_blocks_for_fn (cfun) - NUM_FIXED_BLOCKS];
  qlen = n_basic_blocks_for_fn (cfun) - NUM_FIXED_BLOCKS;
290

291
  /* Iterate until the worklist is empty.  */
292
  while (qlen)
293
    {
294
      /* Take the first entry off the worklist.  */
295 296
      bb = *qout++;
      bb->aux = NULL;
297 298
      qlen--;
      if (qout >= qend)
299
	qout = worklist;
300 301

      /* Compute the intersection of LATERIN for each incoming edge to B.  */
302
      bitmap_ones (laterin[bb->index]);
303
      FOR_EACH_EDGE (e, ei, bb->preds)
304
	bitmap_and (laterin[bb->index], laterin[bb->index],
305
		    later[(size_t)e->aux]);
306 307

      /* Calculate LATER for all outgoing edges.  */
308
      FOR_EACH_EDGE (e, ei, bb->succs)
309
	if (bitmap_ior_and_compl (later[(size_t) e->aux],
310 311 312
				  earliest[(size_t) e->aux],
				  laterin[bb->index],
				  antloc[bb->index])
313 314
	    /* If LATER for an outgoing edge was changed, then we need
	       to add the target of the outgoing edge to the worklist.  */
315
	    && e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun) && e->dest->aux == 0)
316
	  {
317
	    *qin++ = e->dest;
318
	    e->dest->aux = e;
319 320 321
	    qlen++;
	    if (qin >= qend)
	      qin = worklist;
322
	  }
Jeffrey A Law committed
323 324
    }

325 326 327
  /* 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.  */
328
  bitmap_ones (laterin[last_basic_block_for_fn (cfun)]);
329
  FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
330
    bitmap_and (laterin[last_basic_block_for_fn (cfun)],
331 332
		laterin[last_basic_block_for_fn (cfun)],
		later[(size_t) e->aux]);
333

334
  clear_aux_for_edges ();
335
  free (worklist);
Jeffrey A Law committed
336 337
}

338
/* Compute the insertion and deletion points for edge based LCM.  */
339

340
static void
341 342
compute_insert_delete (struct edge_list *edge_list, sbitmap *antloc,
		       sbitmap *later, sbitmap *laterin, sbitmap *insert,
343
		       sbitmap *del)
344 345
{
  int x;
346
  basic_block bb;
Jeffrey A Law committed
347

348
  FOR_EACH_BB_FN (bb, cfun)
349
    bitmap_and_compl (del[bb->index], antloc[bb->index],
350
			laterin[bb->index]);
351

352 353 354
  for (x = 0; x < NUM_EDGES (edge_list); x++)
    {
      basic_block b = INDEX_EDGE_SUCC_BB (edge_list, x);
355

356
      if (b == EXIT_BLOCK_PTR_FOR_FN (cfun))
357 358
	bitmap_and_compl (insert[x], later[x],
			  laterin[last_basic_block_for_fn (cfun)]);
359
      else
360
	bitmap_and_compl (insert[x], later[x], laterin[b->index]);
361 362
    }
}
Jeffrey A Law committed
363

Christian Bruel committed
364 365
/* Given local properties TRANSP, ANTLOC, AVLOC, KILL return the insert and
   delete vectors for edge based LCM  and return the AVIN, AVOUT bitmap.
366
   map the insert vector to what edge an expression should be inserted on.  */
Jeffrey A Law committed
367

368
struct edge_list *
Christian Bruel committed
369
pre_edge_lcm_avs (int n_exprs, sbitmap *transp,
370
	      sbitmap *avloc, sbitmap *antloc, sbitmap *kill,
Christian Bruel committed
371
	      sbitmap *avin, sbitmap *avout,
372
	      sbitmap **insert, sbitmap **del)
Jeffrey A Law committed
373
{
374 375 376 377
  sbitmap *antin, *antout, *earliest;
  sbitmap *later, *laterin;
  struct edge_list *edge_list;
  int num_edges;
Jeffrey A Law committed
378

379 380
  edge_list = create_edge_list ();
  num_edges = NUM_EDGES (edge_list);
Jeffrey A Law committed
381

382
#ifdef LCM_DEBUG_INFO
383
  if (dump_file)
Jeffrey A Law committed
384
    {
385 386 387
      fprintf (dump_file, "Edge List:\n");
      verify_edge_list (dump_file, edge_list);
      print_edge_list (dump_file, edge_list);
388 389 390 391 392 393 394 395
      dump_bitmap_vector (dump_file, "transp", "", transp,
			  last_basic_block_for_fn (cfun));
      dump_bitmap_vector (dump_file, "antloc", "", antloc,
			  last_basic_block_for_fn (cfun));
      dump_bitmap_vector (dump_file, "avloc", "", avloc,
			  last_basic_block_for_fn (cfun));
      dump_bitmap_vector (dump_file, "kill", "", kill,
			  last_basic_block_for_fn (cfun));
Jeffrey A Law committed
396
    }
397
#endif
Jeffrey A Law committed
398

399 400
  /* Compute global availability.  */
  compute_available (avloc, kill, avout, avin);
Jeffrey A Law committed
401

402
  /* Compute global anticipatability.  */
403 404
  antin = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), n_exprs);
  antout = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), n_exprs);
405
  compute_antinout_edge (antloc, transp, antin, antout);
Jeffrey A Law committed
406

407
#ifdef LCM_DEBUG_INFO
408
  if (dump_file)
Jeffrey A Law committed
409
    {
410 411 412 413
      dump_bitmap_vector (dump_file, "antin", "", antin,
			  last_basic_block_for_fn (cfun));
      dump_bitmap_vector (dump_file, "antout", "", antout,
			  last_basic_block_for_fn (cfun));
Jeffrey A Law committed
414
    }
415
#endif
Jeffrey A Law committed
416

417 418 419
  /* 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
420

421
#ifdef LCM_DEBUG_INFO
422
  if (dump_file)
423
    dump_bitmap_vector (dump_file, "earliest", "", earliest, num_edges);
424
#endif
Jeffrey A Law committed
425

426 427
  sbitmap_vector_free (antout);
  sbitmap_vector_free (antin);
Jeffrey A Law committed
428

429
  later = sbitmap_vector_alloc (num_edges, n_exprs);
430

431
  /* Allocate an extra element for the exit block in the laterin vector.  */
432 433
  laterin = sbitmap_vector_alloc (last_basic_block_for_fn (cfun) + 1,
				  n_exprs);
434 435
  compute_laterin (edge_list, earliest, antloc, later, laterin);

436
#ifdef LCM_DEBUG_INFO
437
  if (dump_file)
438
    {
439 440
      dump_bitmap_vector (dump_file, "laterin", "", laterin,
			  last_basic_block_for_fn (cfun) + 1);
441
      dump_bitmap_vector (dump_file, "later", "", later, num_edges);
442 443
    }
#endif
Jeffrey A Law committed
444

445
  sbitmap_vector_free (earliest);
446 447

  *insert = sbitmap_vector_alloc (num_edges, n_exprs);
448
  *del = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), n_exprs);
449
  bitmap_vector_clear (*insert, num_edges);
450
  bitmap_vector_clear (*del, last_basic_block_for_fn (cfun));
451
  compute_insert_delete (edge_list, antloc, later, laterin, *insert, *del);
Jeffrey A Law committed
452

453 454
  sbitmap_vector_free (laterin);
  sbitmap_vector_free (later);
455 456

#ifdef LCM_DEBUG_INFO
457
  if (dump_file)
Jeffrey A Law committed
458
    {
459 460
      dump_bitmap_vector (dump_file, "pre_insert_map", "", *insert, num_edges);
      dump_bitmap_vector (dump_file, "pre_delete_map", "", *del,
461
			  last_basic_block_for_fn (cfun));
Jeffrey A Law committed
462
    }
463
#endif
Jeffrey A Law committed
464

465 466
  return edge_list;
}
Daniel Berlin committed
467

Christian Bruel committed
468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489
/* Wrapper to allocate avin/avout and call pre_edge_lcm_avs.  */

struct edge_list *
pre_edge_lcm (int n_exprs, sbitmap *transp,
	      sbitmap *avloc, sbitmap *antloc, sbitmap *kill,
	      sbitmap **insert, sbitmap **del)
{
  struct edge_list *edge_list;
  sbitmap *avin, *avout;

  avin = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), n_exprs);
  avout = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), n_exprs);

  edge_list = pre_edge_lcm_avs (n_exprs, transp, avloc, antloc, kill,
				 avin, avout, insert, del);

  sbitmap_vector_free (avout);
  sbitmap_vector_free (avin);

  return edge_list;
}

Daniel Berlin committed
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 495
compute_available (sbitmap *avloc, sbitmap *kill, sbitmap *avout,
		   sbitmap *avin)
Jeffrey A Law committed
496
{
Daniel Berlin committed
497
  edge e;
498
  basic_block *worklist, *qin, *qout, *qend, bb;
Daniel Berlin committed
499
  unsigned int qlen;
500
  edge_iterator ei;
Daniel Berlin committed
501 502 503 504

  /* 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
505
  qin = qout = worklist =
506
    XNEWVEC (basic_block, n_basic_blocks_for_fn (cfun) - NUM_FIXED_BLOCKS);
Daniel Berlin committed
507 508

  /* We want a maximal solution.  */
509
  bitmap_vector_ones (avout, last_basic_block_for_fn (cfun));
Daniel Berlin committed
510 511

  /* Put every block on the worklist; this is necessary because of the
512 513
     optimistic initialization of AVOUT above.  Use inverted postorder
     to make the dataflow problem require less iterations.  */
514 515 516
  auto_vec<int, 20> postorder;
  inverted_post_order_compute (&postorder);
  for (unsigned int i = 0; i < postorder.length (); ++i)
Daniel Berlin committed
517
    {
518 519 520 521
      bb = BASIC_BLOCK_FOR_FN (cfun, postorder[i]);
      if (bb == EXIT_BLOCK_PTR_FOR_FN (cfun)
	  || bb == ENTRY_BLOCK_PTR_FOR_FN (cfun))
	continue;
522 523
      *qin++ = bb;
      bb->aux = bb;
Daniel Berlin committed
524 525 526
    }

  qin = worklist;
527 528
  qend = &worklist[n_basic_blocks_for_fn (cfun) - NUM_FIXED_BLOCKS];
  qlen = n_basic_blocks_for_fn (cfun) - NUM_FIXED_BLOCKS;
Daniel Berlin committed
529 530 531

  /* Mark blocks which are successors of the entry block so that we
     can easily identify them below.  */
532 533
  FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR_FOR_FN (cfun)->succs)
    e->dest->aux = ENTRY_BLOCK_PTR_FOR_FN (cfun);
Daniel Berlin committed
534 535 536 537 538

  /* Iterate until the worklist is empty.  */
  while (qlen)
    {
      /* Take the first entry off the worklist.  */
539
      bb = *qout++;
Daniel Berlin committed
540 541 542
      qlen--;

      if (qout >= qend)
543
	qout = worklist;
Daniel Berlin committed
544 545 546 547

      /* 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.  */
548
      if (bb->aux == ENTRY_BLOCK_PTR_FOR_FN (cfun))
Daniel Berlin committed
549 550
	/* 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.  */
551
	bitmap_clear (avin[bb->index]);
Daniel Berlin committed
552 553 554 555
      else
	{
	  /* Clear the aux field of this block so that it can be added to
	     the worklist again if necessary.  */
556
	  bb->aux = NULL;
557
	  bitmap_intersection_of_preds (avin[bb->index], avout, bb);
Daniel Berlin committed
558 559
	}

560
      if (bitmap_ior_and_compl (avout[bb->index], avloc[bb->index],
561
				    avin[bb->index], kill[bb->index]))
Daniel Berlin committed
562 563 564
	/* 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.  */
565
	FOR_EACH_EDGE (e, ei, bb->succs)
566
	  if (!e->dest->aux && e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun))
Daniel Berlin committed
567 568 569 570 571 572
	    {
	      *qin++ = e->dest;
	      e->dest->aux = e;
	      qlen++;

	      if (qin >= qend)
573
		qin = worklist;
Daniel Berlin committed
574 575 576 577 578 579
	    }
    }

  clear_aux_for_edges ();
  clear_aux_for_blocks ();
  free (worklist);
Jeffrey A Law committed
580 581
}

582
/* Compute the farthest vector for edge based lcm.  */
583

Jeffrey A Law committed
584
static void
585 586 587
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
588
{
589
  int x, num_edges;
590
  basic_block pred, succ;
Jeffrey A Law committed
591

592
  num_edges = NUM_EDGES (edge_list);
Jeffrey A Law committed
593

594
  auto_sbitmap difference (n_exprs), temp_bitmap (n_exprs);
595
  for (x = 0; x < num_edges; x++)
Jeffrey A Law committed
596
    {
597 598
      pred = INDEX_EDGE_PRED_BB (edge_list, x);
      succ = INDEX_EDGE_SUCC_BB (edge_list, x);
599
      if (succ == EXIT_BLOCK_PTR_FOR_FN (cfun))
600
	bitmap_copy (farthest[x], st_avout[pred->index]);
601
      else
Jeffrey A Law committed
602
	{
603
	  if (pred == ENTRY_BLOCK_PTR_FOR_FN (cfun))
604
	    bitmap_clear (farthest[x]);
605 606
	  else
	    {
607
	      bitmap_and_compl (difference, st_avout[pred->index],
608
				  st_antin[succ->index]);
609 610
	      bitmap_not (temp_bitmap, st_avin[succ->index]);
	      bitmap_and_or (farthest[x], difference,
611
				    kill[succ->index], temp_bitmap);
612
	    }
Jeffrey A Law committed
613 614 615 616
	}
    }
}

617 618 619 620 621
/* 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
622
static void
623 624
compute_nearerout (struct edge_list *edge_list, sbitmap *farthest,
		   sbitmap *st_avloc, sbitmap *nearer, sbitmap *nearerout)
Jeffrey A Law committed
625
{
626
  int num_edges, i;
627
  edge e;
628
  basic_block *worklist, *tos, bb;
629
  edge_iterator ei;
Jeffrey A Law committed
630

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

633 634 635
  /* 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.  */
636
  tos = worklist = XNEWVEC (basic_block, n_basic_blocks_for_fn (cfun) + 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
  /* We want a maximal solution.  */
644
  bitmap_vector_ones (nearer, num_edges);
645

646 647 648 649
  /* 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.  */
650
  FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
651
    bitmap_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_FN (bb, cfun)
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
      bitmap_ones (nearerout[bb->index]);
670
      FOR_EACH_EDGE (e, ei, bb->succs)
671
	bitmap_and (nearerout[bb->index], nearerout[bb->index],
672
			 nearer[(size_t) e->aux]);
673 674

      /* Calculate NEARER for all incoming edges.  */
675
      FOR_EACH_EDGE (e, ei, bb->preds)
676
	if (bitmap_ior_and_compl (nearer[(size_t) e->aux],
677 678 679
				      farthest[(size_t) e->aux],
				      nearerout[e->dest->index],
				      st_avloc[e->dest->index])
680 681
	    /* If NEARER for an incoming edge was changed, then we need
	       to add the source of the incoming edge to the worklist.  */
682
	    && e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun) && e->src->aux == 0)
683 684 685 686
	  {
	    *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
  bitmap_ones (nearerout[last_basic_block_for_fn (cfun)]);
693
  FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR_FOR_FN (cfun)->succs)
694 695
    bitmap_and (nearerout[last_basic_block_for_fn (cfun)],
		     nearerout[last_basic_block_for_fn (cfun)],
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
compute_rev_insert_delete (struct edge_list *edge_list, sbitmap *st_avloc,
			   sbitmap *nearer, sbitmap *nearerout,
707
			   sbitmap *insert, sbitmap *del)
Jeffrey A Law committed
708
{
709
  int x;
710
  basic_block bb;
Jeffrey A Law committed
711

712
  FOR_EACH_BB_FN (bb, cfun)
713
    bitmap_and_compl (del[bb->index], st_avloc[bb->index],
714
			nearerout[bb->index]);
715

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

727
/* Given local properties TRANSP, ST_AVLOC, ST_ANTLOC, KILL return the
728 729 730
   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
731

732
struct edge_list *
733
pre_edge_rev_lcm (int n_exprs, sbitmap *transp,
734
		  sbitmap *st_avloc, sbitmap *st_antloc, sbitmap *kill,
735
		  sbitmap **insert, sbitmap **del)
Jeffrey A Law committed
736
{
737 738 739 740
  sbitmap *st_antin, *st_antout;
  sbitmap *st_avout, *st_avin, *farthest;
  sbitmap *nearer, *nearerout;
  struct edge_list *edge_list;
741
  int num_edges;
742 743 744 745

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

746 747 748 749
  st_antin = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), n_exprs);
  st_antout = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), n_exprs);
  bitmap_vector_clear (st_antin, last_basic_block_for_fn (cfun));
  bitmap_vector_clear (st_antout, last_basic_block_for_fn (cfun));
750 751 752
  compute_antinout_edge (st_antloc, transp, st_antin, st_antout);

  /* Compute global anticipatability.  */
753 754
  st_avout = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), n_exprs);
  st_avin = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), n_exprs);
755 756 757
  compute_available (st_avloc, kill, st_avout, st_avin);

#ifdef LCM_DEBUG_INFO
758
  if (dump_file)
759
    {
760 761 762
      fprintf (dump_file, "Edge List:\n");
      verify_edge_list (dump_file, edge_list);
      print_edge_list (dump_file, edge_list);
763 764 765 766 767 768 769 770 771 772 773 774
      dump_bitmap_vector (dump_file, "transp", "", transp,
			  last_basic_block_for_fn (cfun));
      dump_bitmap_vector (dump_file, "st_avloc", "", st_avloc,
			  last_basic_block_for_fn (cfun));
      dump_bitmap_vector (dump_file, "st_antloc", "", st_antloc,
			  last_basic_block_for_fn (cfun));
      dump_bitmap_vector (dump_file, "st_antin", "", st_antin,
			  last_basic_block_for_fn (cfun));
      dump_bitmap_vector (dump_file, "st_antout", "", st_antout,
			  last_basic_block_for_fn (cfun));
      dump_bitmap_vector (dump_file, "st_kill", "", kill,
			  last_basic_block_for_fn (cfun));
775 776
    }
#endif
Jeffrey A Law committed
777

778
#ifdef LCM_DEBUG_INFO
779
  if (dump_file)
780
    {
781 782
      dump_bitmap_vector (dump_file, "st_avout", "", st_avout, last_basic_block_for_fn (cfun));
      dump_bitmap_vector (dump_file, "st_avin", "", st_avin, last_basic_block_for_fn (cfun));
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
		    kill, farthest);

#ifdef LCM_DEBUG_INFO
792
  if (dump_file)
793
    dump_bitmap_vector (dump_file, "farthest", "", farthest, num_edges);
794 795
#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 806
  nearerout = sbitmap_vector_alloc (last_basic_block_for_fn (cfun) + 1,
				    n_exprs);
807
  compute_nearerout (edge_list, farthest, st_avloc, nearer, nearerout);
808 809

#ifdef LCM_DEBUG_INFO
810
  if (dump_file)
Jeffrey A Law committed
811
    {
812
      dump_bitmap_vector (dump_file, "nearerout", "", nearerout,
813
			   last_basic_block_for_fn (cfun) + 1);
814
      dump_bitmap_vector (dump_file, "nearer", "", nearer, num_edges);
Jeffrey A Law committed
815
    }
816 817
#endif

818
  sbitmap_vector_free (farthest);
819 820

  *insert = sbitmap_vector_alloc (num_edges, n_exprs);
821
  *del = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), n_exprs);
822
  compute_rev_insert_delete (edge_list, st_avloc, nearer, nearerout,
823
			     *insert, *del);
824

825 826
  sbitmap_vector_free (nearerout);
  sbitmap_vector_free (nearer);
827 828

#ifdef LCM_DEBUG_INFO
829
  if (dump_file)
830
    {
831 832
      dump_bitmap_vector (dump_file, "pre_insert_map", "", *insert, num_edges);
      dump_bitmap_vector (dump_file, "pre_delete_map", "", *del,
833
			   last_basic_block_for_fn (cfun));
834 835 836
    }
#endif
  return edge_list;
Jeffrey A Law committed
837
}
838