]> git.ipfire.org Git - thirdparty/gcc.git/blame - gcc/lcm.c
[C++] Protect call to copy_attributes_to_builtin (PR91505)
[thirdparty/gcc.git] / gcc / lcm.c
CommitLineData
9ca8d59e 1/* Generic partial redundancy elimination with lazy code motion support.
fbd26352 2 Copyright (C) 1998-2019 Free Software Foundation, Inc.
e48ba7af 3
f12b58b3 4This file is part of GCC.
e48ba7af 5
f12b58b3 6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
8c4c00c1 8Software Foundation; either version 3, or (at your option) any later
f12b58b3 9version.
e48ba7af 10
f12b58b3 11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
e48ba7af 15
16You should have received a copy of the GNU General Public License
8c4c00c1 17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
e48ba7af 19
20/* These routines are meant to be used by various optimization
5ab08585 21 passes which can be modeled as lazy code motion problems.
e48ba7af 22 Including, but not limited to:
23
24 * Traditional partial redundancy elimination.
25
26 * Placement of caller/caller register save/restores.
27
28 * Load/store motion.
29
30 * Copy motion.
31
32 * Conversion of flat register files to a stacked register
33 model.
34
35 * Dead load/store elimination.
36
37 These routines accept as input:
38
39 * Basic block information (number of blocks, lists of
40 predecessors and successors). Note the granularity
41 does not need to be basic block, they could be statements
42 or functions.
43
44 * Bitmaps of local properties (computed, transparent and
45 anticipatable expressions).
46
47 The output of these routines is bitmap of redundant computations
48 and a bitmap of optimal placement points. */
49
50
51#include "config.h"
52#include "system.h"
805e22b2 53#include "coretypes.h"
9ef16211 54#include "backend.h"
94ea8568 55#include "cfganal.h"
56#include "lcm.h"
e48ba7af 57
7bcd381b 58/* Edge based LCM routines. */
3ad4992f 59static void compute_antinout_edge (sbitmap *, sbitmap *, sbitmap *, sbitmap *);
60static void compute_earliest (struct edge_list *, int, sbitmap *, sbitmap *,
61 sbitmap *, sbitmap *, sbitmap *);
62static void compute_laterin (struct edge_list *, sbitmap *, sbitmap *,
63 sbitmap *, sbitmap *);
64static void compute_insert_delete (struct edge_list *edge_list, sbitmap *,
65 sbitmap *, sbitmap *, sbitmap *, sbitmap *);
7bcd381b 66
67/* Edge based LCM routines on a reverse flowgraph. */
3ad4992f 68static void compute_farthest (struct edge_list *, int, sbitmap *, sbitmap *,
69 sbitmap*, sbitmap *, sbitmap *);
70static void compute_nearerout (struct edge_list *, sbitmap *, sbitmap *,
71 sbitmap *, sbitmap *);
72static void compute_rev_insert_delete (struct edge_list *edge_list, sbitmap *,
73 sbitmap *, sbitmap *, sbitmap *,
74 sbitmap *);
7bcd381b 75\f
76/* Edge based lcm routines. */
3b7e1f27 77
5ab08585 78/* Compute expression anticipatability at entrance and exit of each block.
79 This is done based on the flow graph, and not on the pred-succ lists.
7bcd381b 80 Other than that, its pretty much identical to compute_antinout. */
e48ba7af 81
82static void
3ad4992f 83compute_antinout_edge (sbitmap *antloc, sbitmap *transp, sbitmap *antin,
84 sbitmap *antout)
e48ba7af 85{
4c26117a 86 basic_block bb;
7bcd381b 87 edge e;
2c59145b 88 basic_block *worklist, *qin, *qout, *qend;
89 unsigned int qlen;
cd665a06 90 edge_iterator ei;
3b7e1f27 91
2325f0e2 92 /* Allocate a worklist array/queue. Entries are only added to the
93 list if they were not already on the list. So the size is
94 bounded by the number of basic blocks. */
a28770e1 95 qin = qout = worklist = XNEWVEC (basic_block, n_basic_blocks_for_fn (cfun));
e48ba7af 96
2325f0e2 97 /* We want a maximal solution, so make an optimistic initialization of
98 ANTIN. */
fe672ac0 99 bitmap_vector_ones (antin, last_basic_block_for_fn (cfun));
e48ba7af 100
5d6931e2 101 /* Put every block on the worklist; this is necessary because of the
102 optimistic initialization of ANTIN above. */
17e85523 103 int *postorder = XNEWVEC (int, n_basic_blocks_for_fn (cfun));
104 int postorder_num = post_order_compute (postorder, false, false);
105 for (int i = 0; i < postorder_num; ++i)
e48ba7af 106 {
17e85523 107 bb = BASIC_BLOCK_FOR_FN (cfun, postorder[i]);
ea0041f4 108 *qin++ = bb;
4c26117a 109 bb->aux = bb;
2325f0e2 110 }
17e85523 111 free (postorder);
5ab08585 112
2c59145b 113 qin = worklist;
a28770e1 114 qend = &worklist[n_basic_blocks_for_fn (cfun) - NUM_FIXED_BLOCKS];
115 qlen = n_basic_blocks_for_fn (cfun) - NUM_FIXED_BLOCKS;
e48ba7af 116
5d6931e2 117 /* Mark blocks which are predecessors of the exit block so that we
118 can easily identify them below. */
34154e27 119 FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
120 e->src->aux = EXIT_BLOCK_PTR_FOR_FN (cfun);
5d6931e2 121
2325f0e2 122 /* Iterate until the worklist is empty. */
2c59145b 123 while (qlen)
2325f0e2 124 {
125 /* Take the first entry off the worklist. */
4c26117a 126 bb = *qout++;
2c59145b 127 qlen--;
3b7e1f27 128
2c59145b 129 if (qout >= qend)
8851e806 130 qout = worklist;
e48ba7af 131
34154e27 132 if (bb->aux == EXIT_BLOCK_PTR_FOR_FN (cfun))
9ca8d59e 133 /* Do not clear the aux field for blocks which are predecessors of
134 the EXIT block. That way we never add then to the worklist
135 again. */
53c5d9d4 136 bitmap_clear (antout[bb->index]);
2325f0e2 137 else
138 {
139 /* Clear the aux field of this block so that it can be added to
140 the worklist again if necessary. */
4c26117a 141 bb->aux = NULL;
08b7917c 142 bitmap_intersection_of_succs (antout[bb->index], antin, bb);
2325f0e2 143 }
7bcd381b 144
53c5d9d4 145 if (bitmap_or_and (antin[bb->index], antloc[bb->index],
4c26117a 146 transp[bb->index], antout[bb->index]))
9ca8d59e 147 /* If the in state of this block changed, then we need
148 to add the predecessors of this block to the worklist
149 if they are not already on the worklist. */
cd665a06 150 FOR_EACH_EDGE (e, ei, bb->preds)
34154e27 151 if (!e->src->aux && e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun))
e48ba7af 152 {
2c59145b 153 *qin++ = e->src;
9ca8d59e 154 e->src->aux = e;
2c59145b 155 qlen++;
156 if (qin >= qend)
8851e806 157 qin = worklist;
e48ba7af 158 }
e48ba7af 159 }
9ca8d59e 160
82f7392b 161 clear_aux_for_edges ();
162 clear_aux_for_blocks ();
2c59145b 163 free (worklist);
e48ba7af 164}
165
7bcd381b 166/* Compute the earliest vector for edge based lcm. */
9ca8d59e 167
e48ba7af 168static void
3ad4992f 169compute_earliest (struct edge_list *edge_list, int n_exprs, sbitmap *antin,
170 sbitmap *antout, sbitmap *avout, sbitmap *kill,
171 sbitmap *earliest)
e48ba7af 172{
5ab08585 173 int x, num_edges;
7bcd381b 174 basic_block pred, succ;
e48ba7af 175
7bcd381b 176 num_edges = NUM_EDGES (edge_list);
e48ba7af 177
3c6549f8 178 auto_sbitmap difference (n_exprs), temp_bitmap (n_exprs);
7bcd381b 179 for (x = 0; x < num_edges; x++)
e48ba7af 180 {
7bcd381b 181 pred = INDEX_EDGE_PRED_BB (edge_list, x);
182 succ = INDEX_EDGE_SUCC_BB (edge_list, x);
34154e27 183 if (pred == ENTRY_BLOCK_PTR_FOR_FN (cfun))
53c5d9d4 184 bitmap_copy (earliest[x], antin[succ->index]);
7bcd381b 185 else
8851e806 186 {
34154e27 187 if (succ == EXIT_BLOCK_PTR_FOR_FN (cfun))
53c5d9d4 188 bitmap_clear (earliest[x]);
7bcd381b 189 else
e48ba7af 190 {
53c5d9d4 191 bitmap_and_compl (difference, antin[succ->index],
b3d6de89 192 avout[pred->index]);
53c5d9d4 193 bitmap_not (temp_bitmap, antout[pred->index]);
194 bitmap_and_or (earliest[x], difference,
b3d6de89 195 kill[pred->index], temp_bitmap);
e48ba7af 196 }
197 }
e48ba7af 198 }
e48ba7af 199}
200
2325f0e2 201/* later(p,s) is dependent on the calculation of laterin(p).
202 laterin(p) is dependent on the calculation of later(p2,p).
203
204 laterin(ENTRY) is defined as all 0's
205 later(ENTRY, succs(ENTRY)) are defined using laterin(ENTRY)
206 laterin(succs(ENTRY)) is defined by later(ENTRY, succs(ENTRY)).
207
208 If we progress in this manner, starting with all basic blocks
209 in the work list, anytime we change later(bb), we need to add
210 succs(bb) to the worklist if they are not already on the worklist.
211
212 Boundary conditions:
213
214 We prime the worklist all the normal basic blocks. The ENTRY block can
215 never be added to the worklist since it is never the successor of any
216 block. We explicitly prevent the EXIT block from being added to the
217 worklist.
218
219 We optimistically initialize LATER. That is the only time this routine
220 will compute LATER for an edge out of the entry block since the entry
221 block is never on the worklist. Thus, LATERIN is neither used nor
222 computed for the ENTRY block.
223
224 Since the EXIT block is never added to the worklist, we will neither
225 use nor compute LATERIN for the exit block. Edges which reach the
226 EXIT block are handled in the normal fashion inside the loop. However,
227 the insertion/deletion computation needs LATERIN(EXIT), so we have
228 to compute it. */
5ab08585 229
e48ba7af 230static void
3ad4992f 231compute_laterin (struct edge_list *edge_list, sbitmap *earliest,
232 sbitmap *antloc, sbitmap *later, sbitmap *laterin)
e48ba7af 233{
4c26117a 234 int num_edges, i;
2325f0e2 235 edge e;
4c26117a 236 basic_block *worklist, *qin, *qout, *qend, bb;
2c59145b 237 unsigned int qlen;
cd665a06 238 edge_iterator ei;
e48ba7af 239
7bcd381b 240 num_edges = NUM_EDGES (edge_list);
e48ba7af 241
2325f0e2 242 /* Allocate a worklist array/queue. Entries are only added to the
243 list if they were not already on the list. So the size is
244 bounded by the number of basic blocks. */
2c59145b 245 qin = qout = worklist
a28770e1 246 = XNEWVEC (basic_block, n_basic_blocks_for_fn (cfun));
2325f0e2 247
248 /* Initialize a mapping from each edge to its index. */
249 for (i = 0; i < num_edges; i++)
9ffd5d6d 250 INDEX_EDGE (edge_list, i)->aux = (void *) (size_t) i;
2325f0e2 251
252 /* We want a maximal solution, so initially consider LATER true for
253 all edges. This allows propagation through a loop since the incoming
254 loop edge will have LATER set, so if all the other incoming edges
255 to the loop are set, then LATERIN will be set for the head of the
256 loop.
257
258 If the optimistic setting of LATER on that edge was incorrect (for
259 example the expression is ANTLOC in a block within the loop) then
260 this algorithm will detect it when we process the block at the head
261 of the optimistic edge. That will requeue the affected blocks. */
53c5d9d4 262 bitmap_vector_ones (later, num_edges);
2325f0e2 263
048599b9 264 /* Note that even though we want an optimistic setting of LATER, we
265 do not want to be overly optimistic. Consider an outgoing edge from
266 the entry block. That edge should always have a LATER value the
267 same as EARLIEST for that edge. */
34154e27 268 FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR_FOR_FN (cfun)->succs)
53c5d9d4 269 bitmap_copy (later[(size_t) e->aux], earliest[(size_t) e->aux]);
048599b9 270
2325f0e2 271 /* Add all the blocks to the worklist. This prevents an early exit from
272 the loop given our optimistic initialization of LATER above. */
a4421e7b 273 auto_vec<int, 20> postorder;
274 inverted_post_order_compute (&postorder);
275 for (unsigned int i = 0; i < postorder.length (); ++i)
e48ba7af 276 {
17e85523 277 bb = BASIC_BLOCK_FOR_FN (cfun, postorder[i]);
278 if (bb == EXIT_BLOCK_PTR_FOR_FN (cfun)
279 || bb == ENTRY_BLOCK_PTR_FOR_FN (cfun))
280 continue;
4c26117a 281 *qin++ = bb;
282 bb->aux = bb;
7bcd381b 283 }
d4d93ea0 284
2c59145b 285 /* Note that we do not use the last allocated element for our queue,
4d2e5d52 286 as EXIT_BLOCK is never inserted into it. */
d4d93ea0 287 qin = worklist;
a28770e1 288 qend = &worklist[n_basic_blocks_for_fn (cfun) - NUM_FIXED_BLOCKS];
289 qlen = n_basic_blocks_for_fn (cfun) - NUM_FIXED_BLOCKS;
7bcd381b 290
2325f0e2 291 /* Iterate until the worklist is empty. */
2c59145b 292 while (qlen)
7bcd381b 293 {
2325f0e2 294 /* Take the first entry off the worklist. */
4c26117a 295 bb = *qout++;
296 bb->aux = NULL;
2c59145b 297 qlen--;
298 if (qout >= qend)
8851e806 299 qout = worklist;
2325f0e2 300
301 /* Compute the intersection of LATERIN for each incoming edge to B. */
53c5d9d4 302 bitmap_ones (laterin[bb->index]);
cd665a06 303 FOR_EACH_EDGE (e, ei, bb->preds)
53c5d9d4 304 bitmap_and (laterin[bb->index], laterin[bb->index],
17e85523 305 later[(size_t)e->aux]);
2325f0e2 306
307 /* Calculate LATER for all outgoing edges. */
cd665a06 308 FOR_EACH_EDGE (e, ei, bb->succs)
53c5d9d4 309 if (bitmap_ior_and_compl (later[(size_t) e->aux],
17e85523 310 earliest[(size_t) e->aux],
311 laterin[bb->index],
312 antloc[bb->index])
9ca8d59e 313 /* If LATER for an outgoing edge was changed, then we need
314 to add the target of the outgoing edge to the worklist. */
34154e27 315 && e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun) && e->dest->aux == 0)
9ca8d59e 316 {
2c59145b 317 *qin++ = e->dest;
9ca8d59e 318 e->dest->aux = e;
2c59145b 319 qlen++;
320 if (qin >= qend)
321 qin = worklist;
9ca8d59e 322 }
e48ba7af 323 }
324
2325f0e2 325 /* Computation of insertion and deletion points requires computing LATERIN
326 for the EXIT block. We allocated an extra entry in the LATERIN array
327 for just this purpose. */
fe672ac0 328 bitmap_ones (laterin[last_basic_block_for_fn (cfun)]);
34154e27 329 FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
fe672ac0 330 bitmap_and (laterin[last_basic_block_for_fn (cfun)],
17e85523 331 laterin[last_basic_block_for_fn (cfun)],
332 later[(size_t) e->aux]);
2325f0e2 333
82f7392b 334 clear_aux_for_edges ();
2c59145b 335 free (worklist);
e48ba7af 336}
337
7bcd381b 338/* Compute the insertion and deletion points for edge based LCM. */
9ca8d59e 339
7bcd381b 340static void
3ad4992f 341compute_insert_delete (struct edge_list *edge_list, sbitmap *antloc,
342 sbitmap *later, sbitmap *laterin, sbitmap *insert,
9ce37fa7 343 sbitmap *del)
7bcd381b 344{
345 int x;
4c26117a 346 basic_block bb;
e48ba7af 347
fc00614f 348 FOR_EACH_BB_FN (bb, cfun)
53c5d9d4 349 bitmap_and_compl (del[bb->index], antloc[bb->index],
d4d93ea0 350 laterin[bb->index]);
5ab08585 351
7bcd381b 352 for (x = 0; x < NUM_EDGES (edge_list); x++)
353 {
354 basic_block b = INDEX_EDGE_SUCC_BB (edge_list, x);
9ca8d59e 355
34154e27 356 if (b == EXIT_BLOCK_PTR_FOR_FN (cfun))
fe672ac0 357 bitmap_and_compl (insert[x], later[x],
358 laterin[last_basic_block_for_fn (cfun)]);
7bcd381b 359 else
53c5d9d4 360 bitmap_and_compl (insert[x], later[x], laterin[b->index]);
7bcd381b 361 }
362}
e48ba7af 363
7fc0df2f 364/* Given local properties TRANSP, ANTLOC, AVLOC, KILL return the insert and
365 delete vectors for edge based LCM and return the AVIN, AVOUT bitmap.
9ca8d59e 366 map the insert vector to what edge an expression should be inserted on. */
e48ba7af 367
7bcd381b 368struct edge_list *
7fc0df2f 369pre_edge_lcm_avs (int n_exprs, sbitmap *transp,
3ad4992f 370 sbitmap *avloc, sbitmap *antloc, sbitmap *kill,
7fc0df2f 371 sbitmap *avin, sbitmap *avout,
9ce37fa7 372 sbitmap **insert, sbitmap **del)
e48ba7af 373{
7bcd381b 374 sbitmap *antin, *antout, *earliest;
7bcd381b 375 sbitmap *later, *laterin;
376 struct edge_list *edge_list;
377 int num_edges;
e48ba7af 378
7bcd381b 379 edge_list = create_edge_list ();
380 num_edges = NUM_EDGES (edge_list);
e48ba7af 381
7bcd381b 382#ifdef LCM_DEBUG_INFO
3f5be5f4 383 if (dump_file)
e48ba7af 384 {
3f5be5f4 385 fprintf (dump_file, "Edge List:\n");
386 verify_edge_list (dump_file, edge_list);
387 print_edge_list (dump_file, edge_list);
fe672ac0 388 dump_bitmap_vector (dump_file, "transp", "", transp,
389 last_basic_block_for_fn (cfun));
390 dump_bitmap_vector (dump_file, "antloc", "", antloc,
391 last_basic_block_for_fn (cfun));
392 dump_bitmap_vector (dump_file, "avloc", "", avloc,
393 last_basic_block_for_fn (cfun));
394 dump_bitmap_vector (dump_file, "kill", "", kill,
395 last_basic_block_for_fn (cfun));
e48ba7af 396 }
7bcd381b 397#endif
e48ba7af 398
7bcd381b 399 /* Compute global availability. */
7bcd381b 400 compute_available (avloc, kill, avout, avin);
e48ba7af 401
7bcd381b 402 /* Compute global anticipatability. */
fe672ac0 403 antin = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), n_exprs);
404 antout = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), n_exprs);
7bcd381b 405 compute_antinout_edge (antloc, transp, antin, antout);
e48ba7af 406
7bcd381b 407#ifdef LCM_DEBUG_INFO
3f5be5f4 408 if (dump_file)
e48ba7af 409 {
fe672ac0 410 dump_bitmap_vector (dump_file, "antin", "", antin,
411 last_basic_block_for_fn (cfun));
412 dump_bitmap_vector (dump_file, "antout", "", antout,
413 last_basic_block_for_fn (cfun));
e48ba7af 414 }
7bcd381b 415#endif
e48ba7af 416
7bcd381b 417 /* Compute earliestness. */
418 earliest = sbitmap_vector_alloc (num_edges, n_exprs);
419 compute_earliest (edge_list, n_exprs, antin, antout, avout, kill, earliest);
e48ba7af 420
7bcd381b 421#ifdef LCM_DEBUG_INFO
3f5be5f4 422 if (dump_file)
53c5d9d4 423 dump_bitmap_vector (dump_file, "earliest", "", earliest, num_edges);
7bcd381b 424#endif
e48ba7af 425
cca23eb2 426 sbitmap_vector_free (antout);
427 sbitmap_vector_free (antin);
e48ba7af 428
7bcd381b 429 later = sbitmap_vector_alloc (num_edges, n_exprs);
9ca8d59e 430
7bcd381b 431 /* Allocate an extra element for the exit block in the laterin vector. */
fe672ac0 432 laterin = sbitmap_vector_alloc (last_basic_block_for_fn (cfun) + 1,
433 n_exprs);
2325f0e2 434 compute_laterin (edge_list, earliest, antloc, later, laterin);
435
7bcd381b 436#ifdef LCM_DEBUG_INFO
3f5be5f4 437 if (dump_file)
7bcd381b 438 {
fe672ac0 439 dump_bitmap_vector (dump_file, "laterin", "", laterin,
440 last_basic_block_for_fn (cfun) + 1);
53c5d9d4 441 dump_bitmap_vector (dump_file, "later", "", later, num_edges);
7bcd381b 442 }
443#endif
e48ba7af 444
cca23eb2 445 sbitmap_vector_free (earliest);
7bcd381b 446
447 *insert = sbitmap_vector_alloc (num_edges, n_exprs);
fe672ac0 448 *del = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), n_exprs);
53c5d9d4 449 bitmap_vector_clear (*insert, num_edges);
fe672ac0 450 bitmap_vector_clear (*del, last_basic_block_for_fn (cfun));
9ce37fa7 451 compute_insert_delete (edge_list, antloc, later, laterin, *insert, *del);
e48ba7af 452
cca23eb2 453 sbitmap_vector_free (laterin);
454 sbitmap_vector_free (later);
7bcd381b 455
456#ifdef LCM_DEBUG_INFO
3f5be5f4 457 if (dump_file)
e48ba7af 458 {
53c5d9d4 459 dump_bitmap_vector (dump_file, "pre_insert_map", "", *insert, num_edges);
460 dump_bitmap_vector (dump_file, "pre_delete_map", "", *del,
fe672ac0 461 last_basic_block_for_fn (cfun));
e48ba7af 462 }
7bcd381b 463#endif
e48ba7af 464
7bcd381b 465 return edge_list;
466}
3b7e1f27 467
7fc0df2f 468/* Wrapper to allocate avin/avout and call pre_edge_lcm_avs. */
469
470struct edge_list *
471pre_edge_lcm (int n_exprs, sbitmap *transp,
472 sbitmap *avloc, sbitmap *antloc, sbitmap *kill,
473 sbitmap **insert, sbitmap **del)
474{
475 struct edge_list *edge_list;
476 sbitmap *avin, *avout;
477
478 avin = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), n_exprs);
479 avout = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), n_exprs);
480
481 edge_list = pre_edge_lcm_avs (n_exprs, transp, avloc, antloc, kill,
482 avin, avout, insert, del);
483
484 sbitmap_vector_free (avout);
485 sbitmap_vector_free (avin);
486
487 return edge_list;
488}
489
3b7e1f27 490/* Compute the AVIN and AVOUT vectors from the AVLOC and KILL vectors.
491 Return the number of passes we performed to iterate to a solution. */
492
2325f0e2 493void
3ad4992f 494compute_available (sbitmap *avloc, sbitmap *kill, sbitmap *avout,
495 sbitmap *avin)
e48ba7af 496{
3b7e1f27 497 edge e;
4c26117a 498 basic_block *worklist, *qin, *qout, *qend, bb;
3b7e1f27 499 unsigned int qlen;
cd665a06 500 edge_iterator ei;
3b7e1f27 501
502 /* Allocate a worklist array/queue. Entries are only added to the
503 list if they were not already on the list. So the size is
504 bounded by the number of basic blocks. */
48e1416a 505 qin = qout = worklist =
a28770e1 506 XNEWVEC (basic_block, n_basic_blocks_for_fn (cfun) - NUM_FIXED_BLOCKS);
3b7e1f27 507
508 /* We want a maximal solution. */
fe672ac0 509 bitmap_vector_ones (avout, last_basic_block_for_fn (cfun));
3b7e1f27 510
511 /* Put every block on the worklist; this is necessary because of the
a2028ebf 512 optimistic initialization of AVOUT above. Use inverted postorder
513 to make the dataflow problem require less iterations. */
a4421e7b 514 auto_vec<int, 20> postorder;
515 inverted_post_order_compute (&postorder);
516 for (unsigned int i = 0; i < postorder.length (); ++i)
3b7e1f27 517 {
a2028ebf 518 bb = BASIC_BLOCK_FOR_FN (cfun, postorder[i]);
519 if (bb == EXIT_BLOCK_PTR_FOR_FN (cfun)
520 || bb == ENTRY_BLOCK_PTR_FOR_FN (cfun))
521 continue;
4c26117a 522 *qin++ = bb;
523 bb->aux = bb;
3b7e1f27 524 }
525
526 qin = worklist;
a28770e1 527 qend = &worklist[n_basic_blocks_for_fn (cfun) - NUM_FIXED_BLOCKS];
528 qlen = n_basic_blocks_for_fn (cfun) - NUM_FIXED_BLOCKS;
3b7e1f27 529
530 /* Mark blocks which are successors of the entry block so that we
531 can easily identify them below. */
34154e27 532 FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR_FOR_FN (cfun)->succs)
533 e->dest->aux = ENTRY_BLOCK_PTR_FOR_FN (cfun);
3b7e1f27 534
535 /* Iterate until the worklist is empty. */
536 while (qlen)
537 {
538 /* Take the first entry off the worklist. */
4c26117a 539 bb = *qout++;
3b7e1f27 540 qlen--;
541
542 if (qout >= qend)
8851e806 543 qout = worklist;
3b7e1f27 544
545 /* If one of the predecessor blocks is the ENTRY block, then the
546 intersection of avouts is the null set. We can identify such blocks
547 by the special value in the AUX field in the block structure. */
34154e27 548 if (bb->aux == ENTRY_BLOCK_PTR_FOR_FN (cfun))
3b7e1f27 549 /* Do not clear the aux field for blocks which are successors of the
550 ENTRY block. That way we never add then to the worklist again. */
53c5d9d4 551 bitmap_clear (avin[bb->index]);
3b7e1f27 552 else
553 {
554 /* Clear the aux field of this block so that it can be added to
555 the worklist again if necessary. */
4c26117a 556 bb->aux = NULL;
08b7917c 557 bitmap_intersection_of_preds (avin[bb->index], avout, bb);
3b7e1f27 558 }
559
53c5d9d4 560 if (bitmap_ior_and_compl (avout[bb->index], avloc[bb->index],
d4d93ea0 561 avin[bb->index], kill[bb->index]))
3b7e1f27 562 /* If the out state of this block changed, then we need
563 to add the successors of this block to the worklist
564 if they are not already on the worklist. */
cd665a06 565 FOR_EACH_EDGE (e, ei, bb->succs)
34154e27 566 if (!e->dest->aux && e->dest != EXIT_BLOCK_PTR_FOR_FN (cfun))
3b7e1f27 567 {
568 *qin++ = e->dest;
569 e->dest->aux = e;
570 qlen++;
571
572 if (qin >= qend)
8851e806 573 qin = worklist;
3b7e1f27 574 }
575 }
576
577 clear_aux_for_edges ();
578 clear_aux_for_blocks ();
579 free (worklist);
e48ba7af 580}
581
7bcd381b 582/* Compute the farthest vector for edge based lcm. */
9ca8d59e 583
e48ba7af 584static void
3ad4992f 585compute_farthest (struct edge_list *edge_list, int n_exprs,
586 sbitmap *st_avout, sbitmap *st_avin, sbitmap *st_antin,
587 sbitmap *kill, sbitmap *farthest)
e48ba7af 588{
5ab08585 589 int x, num_edges;
7bcd381b 590 basic_block pred, succ;
e48ba7af 591
7bcd381b 592 num_edges = NUM_EDGES (edge_list);
e48ba7af 593
3c6549f8 594 auto_sbitmap difference (n_exprs), temp_bitmap (n_exprs);
7bcd381b 595 for (x = 0; x < num_edges; x++)
e48ba7af 596 {
7bcd381b 597 pred = INDEX_EDGE_PRED_BB (edge_list, x);
598 succ = INDEX_EDGE_SUCC_BB (edge_list, x);
34154e27 599 if (succ == EXIT_BLOCK_PTR_FOR_FN (cfun))
53c5d9d4 600 bitmap_copy (farthest[x], st_avout[pred->index]);
7bcd381b 601 else
e48ba7af 602 {
34154e27 603 if (pred == ENTRY_BLOCK_PTR_FOR_FN (cfun))
53c5d9d4 604 bitmap_clear (farthest[x]);
7bcd381b 605 else
606 {
53c5d9d4 607 bitmap_and_compl (difference, st_avout[pred->index],
b3d6de89 608 st_antin[succ->index]);
53c5d9d4 609 bitmap_not (temp_bitmap, st_avin[succ->index]);
610 bitmap_and_or (farthest[x], difference,
b3d6de89 611 kill[succ->index], temp_bitmap);
7bcd381b 612 }
e48ba7af 613 }
e48ba7af 614 }
e48ba7af 615}
616
2325f0e2 617/* Compute nearer and nearerout vectors for edge based lcm.
618
619 This is the mirror of compute_laterin, additional comments on the
620 implementation can be found before compute_laterin. */
621
e48ba7af 622static void
3ad4992f 623compute_nearerout (struct edge_list *edge_list, sbitmap *farthest,
624 sbitmap *st_avloc, sbitmap *nearer, sbitmap *nearerout)
e48ba7af 625{
4c26117a 626 int num_edges, i;
2325f0e2 627 edge e;
4c26117a 628 basic_block *worklist, *tos, bb;
cd665a06 629 edge_iterator ei;
e48ba7af 630
7bcd381b 631 num_edges = NUM_EDGES (edge_list);
e48ba7af 632
2325f0e2 633 /* Allocate a worklist array/queue. Entries are only added to the
634 list if they were not already on the list. So the size is
635 bounded by the number of basic blocks. */
a28770e1 636 tos = worklist = XNEWVEC (basic_block, n_basic_blocks_for_fn (cfun) + 1);
e48ba7af 637
2325f0e2 638 /* Initialize NEARER for each edge and build a mapping from an edge to
639 its index. */
640 for (i = 0; i < num_edges; i++)
9ffd5d6d 641 INDEX_EDGE (edge_list, i)->aux = (void *) (size_t) i;
7bcd381b 642
2325f0e2 643 /* We want a maximal solution. */
53c5d9d4 644 bitmap_vector_ones (nearer, num_edges);
2325f0e2 645
048599b9 646 /* Note that even though we want an optimistic setting of NEARER, we
647 do not want to be overly optimistic. Consider an incoming edge to
648 the exit block. That edge should always have a NEARER value the
649 same as FARTHEST for that edge. */
34154e27 650 FOR_EACH_EDGE (e, ei, EXIT_BLOCK_PTR_FOR_FN (cfun)->preds)
53c5d9d4 651 bitmap_copy (nearer[(size_t)e->aux], farthest[(size_t)e->aux]);
048599b9 652
2325f0e2 653 /* Add all the blocks to the worklist. This prevents an early exit
654 from the loop given our optimistic initialization of NEARER. */
fc00614f 655 FOR_EACH_BB_FN (bb, cfun)
e48ba7af 656 {
4c26117a 657 *tos++ = bb;
658 bb->aux = bb;
7bcd381b 659 }
5ab08585 660
2325f0e2 661 /* Iterate until the worklist is empty. */
662 while (tos != worklist)
7bcd381b 663 {
2325f0e2 664 /* Take the first entry off the worklist. */
4c26117a 665 bb = *--tos;
666 bb->aux = NULL;
2325f0e2 667
668 /* Compute the intersection of NEARER for each outgoing edge from B. */
53c5d9d4 669 bitmap_ones (nearerout[bb->index]);
cd665a06 670 FOR_EACH_EDGE (e, ei, bb->succs)
53c5d9d4 671 bitmap_and (nearerout[bb->index], nearerout[bb->index],
9ffd5d6d 672 nearer[(size_t) e->aux]);
2325f0e2 673
674 /* Calculate NEARER for all incoming edges. */
cd665a06 675 FOR_EACH_EDGE (e, ei, bb->preds)
53c5d9d4 676 if (bitmap_ior_and_compl (nearer[(size_t) e->aux],
b3d6de89 677 farthest[(size_t) e->aux],
678 nearerout[e->dest->index],
679 st_avloc[e->dest->index])
9ca8d59e 680 /* If NEARER for an incoming edge was changed, then we need
681 to add the source of the incoming edge to the worklist. */
34154e27 682 && e->src != ENTRY_BLOCK_PTR_FOR_FN (cfun) && e->src->aux == 0)
9ca8d59e 683 {
684 *tos++ = e->src;
685 e->src->aux = e;
686 }
7bcd381b 687 }
e48ba7af 688
2325f0e2 689 /* Computation of insertion and deletion points requires computing NEAREROUT
690 for the ENTRY block. We allocated an extra entry in the NEAREROUT array
691 for just this purpose. */
fe672ac0 692 bitmap_ones (nearerout[last_basic_block_for_fn (cfun)]);
34154e27 693 FOR_EACH_EDGE (e, ei, ENTRY_BLOCK_PTR_FOR_FN (cfun)->succs)
fe672ac0 694 bitmap_and (nearerout[last_basic_block_for_fn (cfun)],
695 nearerout[last_basic_block_for_fn (cfun)],
9ffd5d6d 696 nearer[(size_t) e->aux]);
2325f0e2 697
82f7392b 698 clear_aux_for_edges ();
2325f0e2 699 free (tos);
7bcd381b 700}
e48ba7af 701
7bcd381b 702/* Compute the insertion and deletion points for edge based LCM. */
9ca8d59e 703
e48ba7af 704static void
3ad4992f 705compute_rev_insert_delete (struct edge_list *edge_list, sbitmap *st_avloc,
706 sbitmap *nearer, sbitmap *nearerout,
9ce37fa7 707 sbitmap *insert, sbitmap *del)
e48ba7af 708{
7bcd381b 709 int x;
4c26117a 710 basic_block bb;
e48ba7af 711
fc00614f 712 FOR_EACH_BB_FN (bb, cfun)
53c5d9d4 713 bitmap_and_compl (del[bb->index], st_avloc[bb->index],
d4d93ea0 714 nearerout[bb->index]);
5ab08585 715
7bcd381b 716 for (x = 0; x < NUM_EDGES (edge_list); x++)
e48ba7af 717 {
7bcd381b 718 basic_block b = INDEX_EDGE_PRED_BB (edge_list, x);
34154e27 719 if (b == ENTRY_BLOCK_PTR_FOR_FN (cfun))
fe672ac0 720 bitmap_and_compl (insert[x], nearer[x],
721 nearerout[last_basic_block_for_fn (cfun)]);
e48ba7af 722 else
53c5d9d4 723 bitmap_and_compl (insert[x], nearer[x], nearerout[b->index]);
e48ba7af 724 }
e48ba7af 725}
726
5ab08585 727/* Given local properties TRANSP, ST_AVLOC, ST_ANTLOC, KILL return the
7bcd381b 728 insert and delete vectors for edge based reverse LCM. Returns an
729 edgelist which is used to map the insert vector to what edge
730 an expression should be inserted on. */
e48ba7af 731
7bcd381b 732struct edge_list *
3f5be5f4 733pre_edge_rev_lcm (int n_exprs, sbitmap *transp,
3ad4992f 734 sbitmap *st_avloc, sbitmap *st_antloc, sbitmap *kill,
9ce37fa7 735 sbitmap **insert, sbitmap **del)
e48ba7af 736{
7bcd381b 737 sbitmap *st_antin, *st_antout;
738 sbitmap *st_avout, *st_avin, *farthest;
739 sbitmap *nearer, *nearerout;
740 struct edge_list *edge_list;
27548a74 741 int num_edges;
7bcd381b 742
743 edge_list = create_edge_list ();
744 num_edges = NUM_EDGES (edge_list);
745
fe672ac0 746 st_antin = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), n_exprs);
747 st_antout = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), n_exprs);
748 bitmap_vector_clear (st_antin, last_basic_block_for_fn (cfun));
749 bitmap_vector_clear (st_antout, last_basic_block_for_fn (cfun));
7bcd381b 750 compute_antinout_edge (st_antloc, transp, st_antin, st_antout);
751
752 /* Compute global anticipatability. */
fe672ac0 753 st_avout = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), n_exprs);
754 st_avin = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), n_exprs);
7bcd381b 755 compute_available (st_avloc, kill, st_avout, st_avin);
756
757#ifdef LCM_DEBUG_INFO
3f5be5f4 758 if (dump_file)
7bcd381b 759 {
3f5be5f4 760 fprintf (dump_file, "Edge List:\n");
761 verify_edge_list (dump_file, edge_list);
762 print_edge_list (dump_file, edge_list);
fe672ac0 763 dump_bitmap_vector (dump_file, "transp", "", transp,
764 last_basic_block_for_fn (cfun));
765 dump_bitmap_vector (dump_file, "st_avloc", "", st_avloc,
766 last_basic_block_for_fn (cfun));
767 dump_bitmap_vector (dump_file, "st_antloc", "", st_antloc,
768 last_basic_block_for_fn (cfun));
769 dump_bitmap_vector (dump_file, "st_antin", "", st_antin,
770 last_basic_block_for_fn (cfun));
771 dump_bitmap_vector (dump_file, "st_antout", "", st_antout,
772 last_basic_block_for_fn (cfun));
773 dump_bitmap_vector (dump_file, "st_kill", "", kill,
774 last_basic_block_for_fn (cfun));
7bcd381b 775 }
776#endif
e48ba7af 777
7bcd381b 778#ifdef LCM_DEBUG_INFO
3f5be5f4 779 if (dump_file)
7bcd381b 780 {
fe672ac0 781 dump_bitmap_vector (dump_file, "st_avout", "", st_avout, last_basic_block_for_fn (cfun));
782 dump_bitmap_vector (dump_file, "st_avin", "", st_avin, last_basic_block_for_fn (cfun));
7bcd381b 783 }
784#endif
e48ba7af 785
7bcd381b 786 /* Compute farthestness. */
787 farthest = sbitmap_vector_alloc (num_edges, n_exprs);
5ab08585 788 compute_farthest (edge_list, n_exprs, st_avout, st_avin, st_antin,
7bcd381b 789 kill, farthest);
790
791#ifdef LCM_DEBUG_INFO
3f5be5f4 792 if (dump_file)
53c5d9d4 793 dump_bitmap_vector (dump_file, "farthest", "", farthest, num_edges);
7bcd381b 794#endif
795
cca23eb2 796 sbitmap_vector_free (st_antin);
797 sbitmap_vector_free (st_antout);
798
799 sbitmap_vector_free (st_avin);
800 sbitmap_vector_free (st_avout);
7bcd381b 801
802 nearer = sbitmap_vector_alloc (num_edges, n_exprs);
9ca8d59e 803
7bcd381b 804 /* Allocate an extra element for the entry block. */
fe672ac0 805 nearerout = sbitmap_vector_alloc (last_basic_block_for_fn (cfun) + 1,
806 n_exprs);
2325f0e2 807 compute_nearerout (edge_list, farthest, st_avloc, nearer, nearerout);
7bcd381b 808
809#ifdef LCM_DEBUG_INFO
3f5be5f4 810 if (dump_file)
e48ba7af 811 {
53c5d9d4 812 dump_bitmap_vector (dump_file, "nearerout", "", nearerout,
fe672ac0 813 last_basic_block_for_fn (cfun) + 1);
53c5d9d4 814 dump_bitmap_vector (dump_file, "nearer", "", nearer, num_edges);
e48ba7af 815 }
7bcd381b 816#endif
817
cca23eb2 818 sbitmap_vector_free (farthest);
7bcd381b 819
820 *insert = sbitmap_vector_alloc (num_edges, n_exprs);
fe672ac0 821 *del = sbitmap_vector_alloc (last_basic_block_for_fn (cfun), n_exprs);
9ca8d59e 822 compute_rev_insert_delete (edge_list, st_avloc, nearer, nearerout,
9ce37fa7 823 *insert, *del);
7bcd381b 824
cca23eb2 825 sbitmap_vector_free (nearerout);
826 sbitmap_vector_free (nearer);
7bcd381b 827
828#ifdef LCM_DEBUG_INFO
3f5be5f4 829 if (dump_file)
7bcd381b 830 {
53c5d9d4 831 dump_bitmap_vector (dump_file, "pre_insert_map", "", *insert, num_edges);
832 dump_bitmap_vector (dump_file, "pre_delete_map", "", *del,
fe672ac0 833 last_basic_block_for_fn (cfun));
7bcd381b 834 }
835#endif
7bcd381b 836 return edge_list;
e48ba7af 837}
18862b5a 838