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