Mercurial > hg > CbC > CbC_gcc
comparison gcc/dse.c @ 111:04ced10e8804
gcc 7
author | kono |
---|---|
date | Fri, 27 Oct 2017 22:46:09 +0900 |
parents | f6334be47118 |
children | 84e7813d76e9 |
comparison
equal
deleted
inserted
replaced
68:561a7518be6b | 111:04ced10e8804 |
---|---|
1 /* RTL dead store elimination. | 1 /* RTL dead store elimination. |
2 Copyright (C) 2005, 2006, 2007, 2008, 2009, 2010 | 2 Copyright (C) 2005-2017 Free Software Foundation, Inc. |
3 Free Software Foundation, Inc. | |
4 | 3 |
5 Contributed by Richard Sandiford <rsandifor@codesourcery.com> | 4 Contributed by Richard Sandiford <rsandifor@codesourcery.com> |
6 and Kenneth Zadeck <zadeck@naturalbridge.com> | 5 and Kenneth Zadeck <zadeck@naturalbridge.com> |
7 | 6 |
8 This file is part of GCC. | 7 This file is part of GCC. |
24 #undef BASELINE | 23 #undef BASELINE |
25 | 24 |
26 #include "config.h" | 25 #include "config.h" |
27 #include "system.h" | 26 #include "system.h" |
28 #include "coretypes.h" | 27 #include "coretypes.h" |
29 #include "hashtab.h" | 28 #include "backend.h" |
30 #include "tm.h" | 29 #include "target.h" |
31 #include "rtl.h" | 30 #include "rtl.h" |
32 #include "tree.h" | 31 #include "tree.h" |
32 #include "gimple.h" | |
33 #include "predict.h" | |
34 #include "df.h" | |
35 #include "memmodel.h" | |
33 #include "tm_p.h" | 36 #include "tm_p.h" |
34 #include "regs.h" | 37 #include "gimple-ssa.h" |
35 #include "hard-reg-set.h" | 38 #include "expmed.h" |
36 #include "flags.h" | 39 #include "optabs.h" |
37 #include "df.h" | 40 #include "emit-rtl.h" |
41 #include "recog.h" | |
42 #include "alias.h" | |
43 #include "stor-layout.h" | |
44 #include "cfgrtl.h" | |
38 #include "cselib.h" | 45 #include "cselib.h" |
39 #include "timevar.h" | |
40 #include "tree-pass.h" | 46 #include "tree-pass.h" |
41 #include "alloc-pool.h" | 47 #include "explow.h" |
42 #include "alias.h" | |
43 #include "insn-config.h" | |
44 #include "expr.h" | 48 #include "expr.h" |
45 #include "recog.h" | |
46 #include "dse.h" | |
47 #include "optabs.h" | |
48 #include "dbgcnt.h" | 49 #include "dbgcnt.h" |
49 #include "target.h" | 50 #include "params.h" |
51 #include "rtl-iter.h" | |
52 #include "cfgcleanup.h" | |
50 | 53 |
51 /* This file contains three techniques for performing Dead Store | 54 /* This file contains three techniques for performing Dead Store |
52 Elimination (dse). | 55 Elimination (dse). |
53 | 56 |
54 * The first technique performs dse locally on any base address. It | 57 * The first technique performs dse locally on any base address. It |
59 * The second technique performs dse globally but is restricted to | 62 * The second technique performs dse globally but is restricted to |
60 base addresses that are either constant or are relative to the | 63 base addresses that are either constant or are relative to the |
61 frame_pointer. | 64 frame_pointer. |
62 | 65 |
63 * The third technique, (which is only done after register allocation) | 66 * The third technique, (which is only done after register allocation) |
64 processes the spill spill slots. This differs from the second | 67 processes the spill slots. This differs from the second |
65 technique because it takes advantage of the fact that spilling is | 68 technique because it takes advantage of the fact that spilling is |
66 completely free from the effects of aliasing. | 69 completely free from the effects of aliasing. |
67 | 70 |
68 Logically, dse is a backwards dataflow problem. A store can be | 71 Logically, dse is a backwards dataflow problem. A store can be |
69 deleted if it if cannot be reached in the backward direction by any | 72 deleted if it if cannot be reached in the backward direction by any |
91 4) Solve the dataflow equations. | 94 4) Solve the dataflow equations. |
92 | 95 |
93 5) Delete the insns that the global analysis has indicated are | 96 5) Delete the insns that the global analysis has indicated are |
94 unnecessary. | 97 unnecessary. |
95 | 98 |
96 6) Delete insns that store the same value as preceeding store | 99 6) Delete insns that store the same value as preceding store |
97 where the earlier store couldn't be eliminated. | 100 where the earlier store couldn't be eliminated. |
98 | 101 |
99 7) Cleanup. | 102 7) Cleanup. |
100 | 103 |
101 This step uses cselib and canon_rtx to build the largest expression | 104 This step uses cselib and canon_rtx to build the largest expression |
102 possible for each address. This pass is a forwards pass through | 105 possible for each address. This pass is a forwards pass through |
103 each basic block. From the point of view of the global technique, | 106 each basic block. From the point of view of the global technique, |
104 the first pass could examine a block in either direction. The | 107 the first pass could examine a block in either direction. The |
105 forwards ordering is to accommodate cselib. | 108 forwards ordering is to accommodate cselib. |
106 | 109 |
107 We a simplifying assumption: addresses fall into four broad | 110 We make a simplifying assumption: addresses fall into four broad |
108 categories: | 111 categories: |
109 | 112 |
110 1) base has rtx_varies_p == false, offset is constant. | 113 1) base has rtx_varies_p == false, offset is constant. |
111 2) base has rtx_varies_p == false, offset variable. | 114 2) base has rtx_varies_p == false, offset variable. |
112 3) base has rtx_varies_p == true, offset constant. | 115 3) base has rtx_varies_p == true, offset constant. |
113 4) base has rtx_varies_p == true, offset variable. | 116 4) base has rtx_varies_p == true, offset variable. |
114 | 117 |
115 The local passes are able to process all 4 kinds of addresses. The | 118 The local passes are able to process all 4 kinds of addresses. The |
116 global pass only handles (1). | 119 global pass only handles 1). |
117 | 120 |
118 The global problem is formulated as follows: | 121 The global problem is formulated as follows: |
119 | 122 |
120 A store, S1, to address A, where A is not relative to the stack | 123 A store, S1, to address A, where A is not relative to the stack |
121 frame, can be eliminated if all paths from S1 to the end of the | 124 frame, can be eliminated if all paths from S1 to the end of the |
122 of the function contain another store to A before a read to A. | 125 function contain another store to A before a read to A. |
123 | 126 |
124 If the address A is relative to the stack frame, a store S2 to A | 127 If the address A is relative to the stack frame, a store S2 to A |
125 can be eliminated if there are no paths from S1 that reach the | 128 can be eliminated if there are no paths from S2 that reach the |
126 end of the function that read A before another store to A. In | 129 end of the function that read A before another store to A. In |
127 this case S2 can be deleted if there are paths to from S2 to the | 130 this case S2 can be deleted if there are paths from S2 to the |
128 end of the function that have no reads or writes to A. This | 131 end of the function that have no reads or writes to A. This |
129 second case allows stores to the stack frame to be deleted that | 132 second case allows stores to the stack frame to be deleted that |
130 would otherwise die when the function returns. This cannot be | 133 would otherwise die when the function returns. This cannot be |
131 done if stores_off_frame_dead_at_return is not true. See the doc | 134 done if stores_off_frame_dead_at_return is not true. See the doc |
132 for that variable for when this variable is false. | 135 for that variable for when this variable is false. |
133 | 136 |
134 The global problem is formulated as a backwards set union | 137 The global problem is formulated as a backwards set union |
135 dataflow problem where the stores are the gens and reads are the | 138 dataflow problem where the stores are the gens and reads are the |
136 kills. Set union problems are rare and require some special | 139 kills. Set union problems are rare and require some special |
137 handling given our representation of bitmaps. A straightforward | 140 handling given our representation of bitmaps. A straightforward |
138 implementation of requires a lot of bitmaps filled with 1s. | 141 implementation requires a lot of bitmaps filled with 1s. |
139 These are expensive and cumbersome in our bitmap formulation so | 142 These are expensive and cumbersome in our bitmap formulation so |
140 care has been taken to avoid large vectors filled with 1s. See | 143 care has been taken to avoid large vectors filled with 1s. See |
141 the comments in bb_info and in the dataflow confluence functions | 144 the comments in bb_info and in the dataflow confluence functions |
142 for details. | 145 for details. |
143 | 146 |
197 global problem. There are certainly test cases, that exceed this | 200 global problem. There are certainly test cases, that exceed this |
198 limit, however, it is unlikely that there are important programs | 201 limit, however, it is unlikely that there are important programs |
199 that really have constant offsets this size. */ | 202 that really have constant offsets this size. */ |
200 #define MAX_OFFSET (64 * 1024) | 203 #define MAX_OFFSET (64 * 1024) |
201 | 204 |
202 | 205 /* Obstack for the DSE dataflow bitmaps. We don't want to put these |
206 on the default obstack because these bitmaps can grow quite large | |
207 (~2GB for the small (!) test case of PR54146) and we'll hold on to | |
208 all that memory until the end of the compiler run. | |
209 As a bonus, delete_tree_live_info can destroy all the bitmaps by just | |
210 releasing the whole obstack. */ | |
211 static bitmap_obstack dse_bitmap_obstack; | |
212 | |
213 /* Obstack for other data. As for above: Kinda nice to be able to | |
214 throw it all away at the end in one big sweep. */ | |
215 static struct obstack dse_obstack; | |
216 | |
217 /* Scratch bitmap for cselib's cselib_expand_value_rtx. */ | |
203 static bitmap scratch = NULL; | 218 static bitmap scratch = NULL; |
204 struct insn_info; | 219 |
220 struct insn_info_type; | |
205 | 221 |
206 /* This structure holds information about a candidate store. */ | 222 /* This structure holds information about a candidate store. */ |
207 struct store_info | 223 struct store_info |
208 { | 224 { |
209 | 225 |
224 /* This canonized mem. */ | 240 /* This canonized mem. */ |
225 rtx mem; | 241 rtx mem; |
226 | 242 |
227 /* Canonized MEM address for use by canon_true_dependence. */ | 243 /* Canonized MEM address for use by canon_true_dependence. */ |
228 rtx mem_addr; | 244 rtx mem_addr; |
229 | |
230 /* If this is non-zero, it is the alias set of a spill location. */ | |
231 alias_set_type alias_set; | |
232 | 245 |
233 /* The offset of the first and byte before the last byte associated | 246 /* The offset of the first and byte before the last byte associated |
234 with the operation. */ | 247 with the operation. */ |
235 HOST_WIDE_INT begin, end; | 248 HOST_WIDE_INT begin, end; |
236 | 249 |
266 rtx const_rhs; | 279 rtx const_rhs; |
267 | 280 |
268 /* Set if this store stores the same constant value as REDUNDANT_REASON | 281 /* Set if this store stores the same constant value as REDUNDANT_REASON |
269 insn stored. These aren't eliminated early, because doing that | 282 insn stored. These aren't eliminated early, because doing that |
270 might prevent the earlier larger store to be eliminated. */ | 283 might prevent the earlier larger store to be eliminated. */ |
271 struct insn_info *redundant_reason; | 284 struct insn_info_type *redundant_reason; |
272 }; | 285 }; |
273 | 286 |
274 /* Return a bitmask with the first N low bits set. */ | 287 /* Return a bitmask with the first N low bits set. */ |
275 | 288 |
276 static unsigned HOST_WIDE_INT | 289 static unsigned HOST_WIDE_INT |
277 lowpart_bitmask (int n) | 290 lowpart_bitmask (int n) |
278 { | 291 { |
279 unsigned HOST_WIDE_INT mask = ~(unsigned HOST_WIDE_INT) 0; | 292 unsigned HOST_WIDE_INT mask = HOST_WIDE_INT_M1U; |
280 return mask >> (HOST_BITS_PER_WIDE_INT - n); | 293 return mask >> (HOST_BITS_PER_WIDE_INT - n); |
281 } | 294 } |
282 | 295 |
283 typedef struct store_info *store_info_t; | 296 static object_allocator<store_info> cse_store_info_pool ("cse_store_info_pool"); |
284 static alloc_pool cse_store_info_pool; | 297 |
285 static alloc_pool rtx_store_info_pool; | 298 static object_allocator<store_info> rtx_store_info_pool ("rtx_store_info_pool"); |
286 | 299 |
287 /* This structure holds information about a load. These are only | 300 /* This structure holds information about a load. These are only |
288 built for rtx bases. */ | 301 built for rtx bases. */ |
289 struct read_info | 302 struct read_info_type |
290 { | 303 { |
291 /* The id of the mem group of the base address. */ | 304 /* The id of the mem group of the base address. */ |
292 int group_id; | 305 int group_id; |
293 | |
294 /* If this is non-zero, it is the alias set of a spill location. */ | |
295 alias_set_type alias_set; | |
296 | 306 |
297 /* The offset of the first and byte after the last byte associated | 307 /* The offset of the first and byte after the last byte associated |
298 with the operation. If begin == end == 0, the read did not have | 308 with the operation. If begin == end == 0, the read did not have |
299 a constant offset. */ | 309 a constant offset. */ |
300 int begin, end; | 310 int begin, end; |
301 | 311 |
302 /* The mem being read. */ | 312 /* The mem being read. */ |
303 rtx mem; | 313 rtx mem; |
304 | 314 |
305 /* The next read_info for this insn. */ | 315 /* The next read_info for this insn. */ |
306 struct read_info *next; | 316 struct read_info_type *next; |
307 }; | 317 }; |
308 typedef struct read_info *read_info_t; | 318 typedef struct read_info_type *read_info_t; |
309 static alloc_pool read_info_pool; | 319 |
310 | 320 static object_allocator<read_info_type> read_info_type_pool ("read_info_pool"); |
311 | 321 |
312 /* One of these records is created for each insn. */ | 322 /* One of these records is created for each insn. */ |
313 | 323 |
314 struct insn_info | 324 struct insn_info_type |
315 { | 325 { |
316 /* Set true if the insn contains a store but the insn itself cannot | 326 /* Set true if the insn contains a store but the insn itself cannot |
317 be deleted. This is set if the insn is a parallel and there is | 327 be deleted. This is set if the insn is a parallel and there is |
318 more than one non dead output or if the insn is in some way | 328 more than one non dead output or if the insn is in some way |
319 volatile. */ | 329 volatile. */ |
322 /* This field is only used by the global algorithm. It is set true | 332 /* This field is only used by the global algorithm. It is set true |
323 if the insn contains any read of mem except for a (1). This is | 333 if the insn contains any read of mem except for a (1). This is |
324 also set if the insn is a call or has a clobber mem. If the insn | 334 also set if the insn is a call or has a clobber mem. If the insn |
325 contains a wild read, the use_rec will be null. */ | 335 contains a wild read, the use_rec will be null. */ |
326 bool wild_read; | 336 bool wild_read; |
337 | |
338 /* This is true only for CALL instructions which could potentially read | |
339 any non-frame memory location. This field is used by the global | |
340 algorithm. */ | |
341 bool non_frame_wild_read; | |
327 | 342 |
328 /* This field is only used for the processing of const functions. | 343 /* This field is only used for the processing of const functions. |
329 These functions cannot read memory, but they can read the stack | 344 These functions cannot read memory, but they can read the stack |
330 because that is where they may get their parms. We need to be | 345 because that is where they may get their parms. We need to be |
331 this conservative because, like the store motion pass, we don't | 346 this conservative because, like the store motion pass, we don't |
338 need not be killed upon encountering a const function call. | 353 need not be killed upon encountering a const function call. |
339 2. After reload, the stores related to outgoing arguments can be | 354 2. After reload, the stores related to outgoing arguments can be |
340 either stack pointer or hard frame pointer based. This means | 355 either stack pointer or hard frame pointer based. This means |
341 that we have no other choice than also killing all the frame | 356 that we have no other choice than also killing all the frame |
342 pointer based stores upon encountering a const function call. | 357 pointer based stores upon encountering a const function call. |
343 This field is set after reload for const function calls. Having | 358 This field is set after reload for const function calls and before |
344 this set is less severe than a wild read, it just means that all | 359 reload for const tail function calls on targets where arg pointer |
345 the frame related stores are killed rather than all the stores. */ | 360 is the frame pointer. Having this set is less severe than a wild |
361 read, it just means that all the frame related stores are killed | |
362 rather than all the stores. */ | |
346 bool frame_read; | 363 bool frame_read; |
347 | 364 |
348 /* This field is only used for the processing of const functions. | 365 /* This field is only used for the processing of const functions. |
349 It is set if the insn may contain a stack pointer based store. */ | 366 It is set if the insn may contain a stack pointer based store. */ |
350 bool stack_pointer_based; | 367 bool stack_pointer_based; |
353 cselib base. Such stores can only be deleted by the local | 370 cselib base. Such stores can only be deleted by the local |
354 algorithm. */ | 371 algorithm. */ |
355 bool contains_cselib_groups; | 372 bool contains_cselib_groups; |
356 | 373 |
357 /* The insn. */ | 374 /* The insn. */ |
358 rtx insn; | 375 rtx_insn *insn; |
359 | 376 |
360 /* The list of mem sets or mem clobbers that are contained in this | 377 /* The list of mem sets or mem clobbers that are contained in this |
361 insn. If the insn is deletable, it contains only one mem set. | 378 insn. If the insn is deletable, it contains only one mem set. |
362 But it could also contain clobbers. Insns that contain more than | 379 But it could also contain clobbers. Insns that contain more than |
363 one mem set are not deletable, but each of those mems are here in | 380 one mem set are not deletable, but each of those mems are here in |
364 order to provide info to delete other insns. */ | 381 order to provide info to delete other insns. */ |
365 store_info_t store_rec; | 382 store_info *store_rec; |
366 | 383 |
367 /* The linked list of mem uses in this insn. Only the reads from | 384 /* The linked list of mem uses in this insn. Only the reads from |
368 rtx bases are listed here. The reads to cselib bases are | 385 rtx bases are listed here. The reads to cselib bases are |
369 completely processed during the first scan and so are never | 386 completely processed during the first scan and so are never |
370 created. */ | 387 created. */ |
371 read_info_t read_rec; | 388 read_info_t read_rec; |
372 | 389 |
390 /* The live fixed registers. We assume only fixed registers can | |
391 cause trouble by being clobbered from an expanded pattern; | |
392 storing only the live fixed registers (rather than all registers) | |
393 means less memory needs to be allocated / copied for the individual | |
394 stores. */ | |
395 regset fixed_regs_live; | |
396 | |
373 /* The prev insn in the basic block. */ | 397 /* The prev insn in the basic block. */ |
374 struct insn_info * prev_insn; | 398 struct insn_info_type * prev_insn; |
375 | 399 |
376 /* The linked list of insns that are in consideration for removal in | 400 /* The linked list of insns that are in consideration for removal in |
377 the forwards pass thru the basic block. This pointer may be | 401 the forwards pass through the basic block. This pointer may be |
378 trash as it is not cleared when a wild read occurs. The only | 402 trash as it is not cleared when a wild read occurs. The only |
379 time it is guaranteed to be correct is when the traversal starts | 403 time it is guaranteed to be correct is when the traversal starts |
380 at active_local_stores. */ | 404 at active_local_stores. */ |
381 struct insn_info * next_local_store; | 405 struct insn_info_type * next_local_store; |
382 }; | 406 }; |
383 | 407 typedef struct insn_info_type *insn_info_t; |
384 typedef struct insn_info *insn_info_t; | 408 |
385 static alloc_pool insn_info_pool; | 409 static object_allocator<insn_info_type> insn_info_type_pool ("insn_info_pool"); |
386 | 410 |
387 /* The linked list of stores that are under consideration in this | 411 /* The linked list of stores that are under consideration in this |
388 basic block. */ | 412 basic block. */ |
389 static insn_info_t active_local_stores; | 413 static insn_info_t active_local_stores; |
390 | 414 static int active_local_stores_len; |
391 struct bb_info | 415 |
392 { | 416 struct dse_bb_info_type |
393 | 417 { |
394 /* Pointer to the insn info for the last insn in the block. These | 418 /* Pointer to the insn info for the last insn in the block. These |
395 are linked so this is how all of the insns are reached. During | 419 are linked so this is how all of the insns are reached. During |
396 scanning this is the current insn being scanned. */ | 420 scanning this is the current insn being scanned. */ |
397 insn_info_t last_insn; | 421 insn_info_t last_insn; |
398 | 422 |
438 bitmap out; | 462 bitmap out; |
439 | 463 |
440 /* The following bitvector is indexed by the reg number. It | 464 /* The following bitvector is indexed by the reg number. It |
441 contains the set of regs that are live at the current instruction | 465 contains the set of regs that are live at the current instruction |
442 being processed. While it contains info for all of the | 466 being processed. While it contains info for all of the |
443 registers, only the pseudos are actually examined. It is used to | 467 registers, only the hard registers are actually examined. It is used |
444 assure that shift sequences that are inserted do not accidently | 468 to assure that shift and/or add sequences that are inserted do not |
445 clobber live hard regs. */ | 469 accidentally clobber live hard regs. */ |
446 bitmap regs_live; | 470 bitmap regs_live; |
447 }; | 471 }; |
448 | 472 |
449 typedef struct bb_info *bb_info_t; | 473 typedef struct dse_bb_info_type *bb_info_t; |
450 static alloc_pool bb_info_pool; | 474 |
475 static object_allocator<dse_bb_info_type> dse_bb_info_type_pool | |
476 ("bb_info_pool"); | |
451 | 477 |
452 /* Table to hold all bb_infos. */ | 478 /* Table to hold all bb_infos. */ |
453 static bb_info_t *bb_table; | 479 static bb_info_t *bb_table; |
454 | 480 |
455 /* There is a group_info for each rtx base that is used to reference | 481 /* There is a group_info for each rtx base that is used to reference |
497 at globally. This is because stores to the stack frame that have | 523 at globally. This is because stores to the stack frame that have |
498 no other reads before the end of the function can also be | 524 no other reads before the end of the function can also be |
499 deleted. */ | 525 deleted. */ |
500 bitmap store1_n, store1_p, store2_n, store2_p; | 526 bitmap store1_n, store1_p, store2_n, store2_p; |
501 | 527 |
528 /* These bitmaps keep track of offsets in this group escape this function. | |
529 An offset escapes if it corresponds to a named variable whose | |
530 addressable flag is set. */ | |
531 bitmap escaped_n, escaped_p; | |
532 | |
502 /* The positions in this bitmap have the same assignments as the in, | 533 /* The positions in this bitmap have the same assignments as the in, |
503 out, gen and kill bitmaps. This bitmap is all zeros except for | 534 out, gen and kill bitmaps. This bitmap is all zeros except for |
504 the positions that are occupied by stores for this group. */ | 535 the positions that are occupied by stores for this group. */ |
505 bitmap group_kill; | 536 bitmap group_kill; |
506 | 537 |
509 the all of stores have been scanned and we know which ones we | 540 the all of stores have been scanned and we know which ones we |
510 care about. */ | 541 care about. */ |
511 int *offset_map_n, *offset_map_p; | 542 int *offset_map_n, *offset_map_p; |
512 int offset_map_size_n, offset_map_size_p; | 543 int offset_map_size_n, offset_map_size_p; |
513 }; | 544 }; |
514 typedef struct group_info *group_info_t; | 545 |
515 typedef const struct group_info *const_group_info_t; | 546 static object_allocator<group_info> group_info_pool ("rtx_group_info_pool"); |
516 static alloc_pool rtx_group_info_pool; | |
517 | |
518 /* Tables of group_info structures, hashed by base value. */ | |
519 static htab_t rtx_group_table; | |
520 | 547 |
521 /* Index into the rtx_group_vec. */ | 548 /* Index into the rtx_group_vec. */ |
522 static int rtx_group_next_id; | 549 static int rtx_group_next_id; |
523 | 550 |
524 DEF_VEC_P(group_info_t); | 551 |
525 DEF_VEC_ALLOC_P(group_info_t,heap); | 552 static vec<group_info *> rtx_group_vec; |
526 | |
527 static VEC(group_info_t,heap) *rtx_group_vec; | |
528 | 553 |
529 | 554 |
530 /* This structure holds the set of changes that are being deferred | 555 /* This structure holds the set of changes that are being deferred |
531 when removing read operation. See replace_read. */ | 556 when removing read operation. See replace_read. */ |
532 struct deferred_change | 557 struct deferred_change |
539 rtx reg; | 564 rtx reg; |
540 | 565 |
541 struct deferred_change *next; | 566 struct deferred_change *next; |
542 }; | 567 }; |
543 | 568 |
544 typedef struct deferred_change *deferred_change_t; | 569 static object_allocator<deferred_change> deferred_change_pool |
545 static alloc_pool deferred_change_pool; | 570 ("deferred_change_pool"); |
546 | 571 |
547 static deferred_change_t deferred_change_list = NULL; | 572 static deferred_change *deferred_change_list = NULL; |
548 | |
549 /* This are used to hold the alias sets of spill variables. Since | |
550 these are never aliased and there may be a lot of them, it makes | |
551 sense to treat them specially. This bitvector is only allocated in | |
552 calls from dse_record_singleton_alias_set which currently is only | |
553 made during reload1. So when dse is called before reload this | |
554 mechanism does nothing. */ | |
555 | |
556 static bitmap clear_alias_sets = NULL; | |
557 | |
558 /* The set of clear_alias_sets that have been disqualified because | |
559 there are loads or stores using a different mode than the alias set | |
560 was registered with. */ | |
561 static bitmap disqualified_clear_alias_sets = NULL; | |
562 | |
563 /* The group that holds all of the clear_alias_sets. */ | |
564 static group_info_t clear_alias_group; | |
565 | |
566 /* The modes of the clear_alias_sets. */ | |
567 static htab_t clear_alias_mode_table; | |
568 | |
569 /* Hash table element to look up the mode for an alias set. */ | |
570 struct clear_alias_mode_holder | |
571 { | |
572 alias_set_type alias_set; | |
573 enum machine_mode mode; | |
574 }; | |
575 | |
576 static alloc_pool clear_alias_mode_pool; | |
577 | 573 |
578 /* This is true except if cfun->stdarg -- i.e. we cannot do | 574 /* This is true except if cfun->stdarg -- i.e. we cannot do |
579 this for vararg functions because they play games with the frame. */ | 575 this for vararg functions because they play games with the frame. */ |
580 static bool stores_off_frame_dead_at_return; | 576 static bool stores_off_frame_dead_at_return; |
581 | 577 |
582 /* Counter for stats. */ | 578 /* Counter for stats. */ |
583 static int globally_deleted; | 579 static int globally_deleted; |
584 static int locally_deleted; | 580 static int locally_deleted; |
585 static int spill_deleted; | |
586 | 581 |
587 static bitmap all_blocks; | 582 static bitmap all_blocks; |
583 | |
584 /* Locations that are killed by calls in the global phase. */ | |
585 static bitmap kill_on_calls; | |
588 | 586 |
589 /* The number of bits used in the global bitmaps. */ | 587 /* The number of bits used in the global bitmaps. */ |
590 static unsigned int current_position; | 588 static unsigned int current_position; |
591 | |
592 | |
593 static bool gate_dse (void); | |
594 static bool gate_dse1 (void); | |
595 static bool gate_dse2 (void); | |
596 | |
597 | 589 |
598 /*---------------------------------------------------------------------------- | 590 /*---------------------------------------------------------------------------- |
599 Zeroth step. | 591 Zeroth step. |
600 | 592 |
601 Initialization. | 593 Initialization. |
602 ----------------------------------------------------------------------------*/ | 594 ----------------------------------------------------------------------------*/ |
603 | 595 |
596 | |
604 /* Hashtable callbacks for maintaining the "bases" field of | 597 /* Hashtable callbacks for maintaining the "bases" field of |
605 store_group_info, given that the addresses are function invariants. */ | 598 store_group_info, given that the addresses are function invariants. */ |
606 | 599 |
607 static int | 600 struct invariant_group_base_hasher : nofree_ptr_hash <group_info> |
608 clear_alias_mode_eq (const void *p1, const void *p2) | 601 { |
609 { | 602 static inline hashval_t hash (const group_info *); |
610 const struct clear_alias_mode_holder * h1 | 603 static inline bool equal (const group_info *, const group_info *); |
611 = (const struct clear_alias_mode_holder *) p1; | 604 }; |
612 const struct clear_alias_mode_holder * h2 | 605 |
613 = (const struct clear_alias_mode_holder *) p2; | 606 inline bool |
614 return h1->alias_set == h2->alias_set; | 607 invariant_group_base_hasher::equal (const group_info *gi1, |
615 } | 608 const group_info *gi2) |
616 | 609 { |
617 | |
618 static hashval_t | |
619 clear_alias_mode_hash (const void *p) | |
620 { | |
621 const struct clear_alias_mode_holder *holder | |
622 = (const struct clear_alias_mode_holder *) p; | |
623 return holder->alias_set; | |
624 } | |
625 | |
626 | |
627 /* Find the entry associated with ALIAS_SET. */ | |
628 | |
629 static struct clear_alias_mode_holder * | |
630 clear_alias_set_lookup (alias_set_type alias_set) | |
631 { | |
632 struct clear_alias_mode_holder tmp_holder; | |
633 void **slot; | |
634 | |
635 tmp_holder.alias_set = alias_set; | |
636 slot = htab_find_slot (clear_alias_mode_table, &tmp_holder, NO_INSERT); | |
637 gcc_assert (*slot); | |
638 | |
639 return (struct clear_alias_mode_holder *) *slot; | |
640 } | |
641 | |
642 | |
643 /* Hashtable callbacks for maintaining the "bases" field of | |
644 store_group_info, given that the addresses are function invariants. */ | |
645 | |
646 static int | |
647 invariant_group_base_eq (const void *p1, const void *p2) | |
648 { | |
649 const_group_info_t gi1 = (const_group_info_t) p1; | |
650 const_group_info_t gi2 = (const_group_info_t) p2; | |
651 return rtx_equal_p (gi1->rtx_base, gi2->rtx_base); | 610 return rtx_equal_p (gi1->rtx_base, gi2->rtx_base); |
652 } | 611 } |
653 | 612 |
654 | 613 inline hashval_t |
655 static hashval_t | 614 invariant_group_base_hasher::hash (const group_info *gi) |
656 invariant_group_base_hash (const void *p) | 615 { |
657 { | |
658 const_group_info_t gi = (const_group_info_t) p; | |
659 int do_not_record; | 616 int do_not_record; |
660 return hash_rtx (gi->rtx_base, Pmode, &do_not_record, NULL, false); | 617 return hash_rtx (gi->rtx_base, Pmode, &do_not_record, NULL, false); |
661 } | 618 } |
662 | 619 |
620 /* Tables of group_info structures, hashed by base value. */ | |
621 static hash_table<invariant_group_base_hasher> *rtx_group_table; | |
622 | |
663 | 623 |
664 /* Get the GROUP for BASE. Add a new group if it is not there. */ | 624 /* Get the GROUP for BASE. Add a new group if it is not there. */ |
665 | 625 |
666 static group_info_t | 626 static group_info * |
667 get_group_info (rtx base) | 627 get_group_info (rtx base) |
668 { | 628 { |
669 struct group_info tmp_gi; | 629 struct group_info tmp_gi; |
670 group_info_t gi; | 630 group_info *gi; |
671 void **slot; | 631 group_info **slot; |
672 | 632 |
673 if (base) | 633 gcc_assert (base != NULL_RTX); |
674 { | 634 |
675 /* Find the store_base_info structure for BASE, creating a new one | 635 /* Find the store_base_info structure for BASE, creating a new one |
676 if necessary. */ | 636 if necessary. */ |
677 tmp_gi.rtx_base = base; | 637 tmp_gi.rtx_base = base; |
678 slot = htab_find_slot (rtx_group_table, &tmp_gi, INSERT); | 638 slot = rtx_group_table->find_slot (&tmp_gi, INSERT); |
679 gi = (group_info_t) *slot; | 639 gi = *slot; |
680 } | |
681 else | |
682 { | |
683 if (!clear_alias_group) | |
684 { | |
685 clear_alias_group = gi = | |
686 (group_info_t) pool_alloc (rtx_group_info_pool); | |
687 memset (gi, 0, sizeof (struct group_info)); | |
688 gi->id = rtx_group_next_id++; | |
689 gi->store1_n = BITMAP_ALLOC (NULL); | |
690 gi->store1_p = BITMAP_ALLOC (NULL); | |
691 gi->store2_n = BITMAP_ALLOC (NULL); | |
692 gi->store2_p = BITMAP_ALLOC (NULL); | |
693 gi->group_kill = BITMAP_ALLOC (NULL); | |
694 gi->process_globally = false; | |
695 gi->offset_map_size_n = 0; | |
696 gi->offset_map_size_p = 0; | |
697 gi->offset_map_n = NULL; | |
698 gi->offset_map_p = NULL; | |
699 VEC_safe_push (group_info_t, heap, rtx_group_vec, gi); | |
700 } | |
701 return clear_alias_group; | |
702 } | |
703 | 640 |
704 if (gi == NULL) | 641 if (gi == NULL) |
705 { | 642 { |
706 *slot = gi = (group_info_t) pool_alloc (rtx_group_info_pool); | 643 *slot = gi = group_info_pool.allocate (); |
707 gi->rtx_base = base; | 644 gi->rtx_base = base; |
708 gi->id = rtx_group_next_id++; | 645 gi->id = rtx_group_next_id++; |
709 gi->base_mem = gen_rtx_MEM (BLKmode, base); | 646 gi->base_mem = gen_rtx_MEM (BLKmode, base); |
710 gi->canon_base_addr = canon_rtx (base); | 647 gi->canon_base_addr = canon_rtx (base); |
711 gi->store1_n = BITMAP_ALLOC (NULL); | 648 gi->store1_n = BITMAP_ALLOC (&dse_bitmap_obstack); |
712 gi->store1_p = BITMAP_ALLOC (NULL); | 649 gi->store1_p = BITMAP_ALLOC (&dse_bitmap_obstack); |
713 gi->store2_n = BITMAP_ALLOC (NULL); | 650 gi->store2_n = BITMAP_ALLOC (&dse_bitmap_obstack); |
714 gi->store2_p = BITMAP_ALLOC (NULL); | 651 gi->store2_p = BITMAP_ALLOC (&dse_bitmap_obstack); |
715 gi->group_kill = BITMAP_ALLOC (NULL); | 652 gi->escaped_p = BITMAP_ALLOC (&dse_bitmap_obstack); |
653 gi->escaped_n = BITMAP_ALLOC (&dse_bitmap_obstack); | |
654 gi->group_kill = BITMAP_ALLOC (&dse_bitmap_obstack); | |
716 gi->process_globally = false; | 655 gi->process_globally = false; |
717 gi->frame_related = | 656 gi->frame_related = |
718 (base == frame_pointer_rtx) || (base == hard_frame_pointer_rtx); | 657 (base == frame_pointer_rtx) || (base == hard_frame_pointer_rtx); |
719 gi->offset_map_size_n = 0; | 658 gi->offset_map_size_n = 0; |
720 gi->offset_map_size_p = 0; | 659 gi->offset_map_size_p = 0; |
721 gi->offset_map_n = NULL; | 660 gi->offset_map_n = NULL; |
722 gi->offset_map_p = NULL; | 661 gi->offset_map_p = NULL; |
723 VEC_safe_push (group_info_t, heap, rtx_group_vec, gi); | 662 rtx_group_vec.safe_push (gi); |
724 } | 663 } |
725 | 664 |
726 return gi; | 665 return gi; |
727 } | 666 } |
728 | 667 |
732 static void | 671 static void |
733 dse_step0 (void) | 672 dse_step0 (void) |
734 { | 673 { |
735 locally_deleted = 0; | 674 locally_deleted = 0; |
736 globally_deleted = 0; | 675 globally_deleted = 0; |
737 spill_deleted = 0; | 676 |
738 | 677 bitmap_obstack_initialize (&dse_bitmap_obstack); |
739 scratch = BITMAP_ALLOC (NULL); | 678 gcc_obstack_init (&dse_obstack); |
740 | 679 |
741 rtx_store_info_pool | 680 scratch = BITMAP_ALLOC (®_obstack); |
742 = create_alloc_pool ("rtx_store_info_pool", | 681 kill_on_calls = BITMAP_ALLOC (&dse_bitmap_obstack); |
743 sizeof (struct store_info), 100); | 682 |
744 read_info_pool | 683 |
745 = create_alloc_pool ("read_info_pool", | 684 rtx_group_table = new hash_table<invariant_group_base_hasher> (11); |
746 sizeof (struct read_info), 100); | 685 |
747 insn_info_pool | 686 bb_table = XNEWVEC (bb_info_t, last_basic_block_for_fn (cfun)); |
748 = create_alloc_pool ("insn_info_pool", | |
749 sizeof (struct insn_info), 100); | |
750 bb_info_pool | |
751 = create_alloc_pool ("bb_info_pool", | |
752 sizeof (struct bb_info), 100); | |
753 rtx_group_info_pool | |
754 = create_alloc_pool ("rtx_group_info_pool", | |
755 sizeof (struct group_info), 100); | |
756 deferred_change_pool | |
757 = create_alloc_pool ("deferred_change_pool", | |
758 sizeof (struct deferred_change), 10); | |
759 | |
760 rtx_group_table = htab_create (11, invariant_group_base_hash, | |
761 invariant_group_base_eq, NULL); | |
762 | |
763 bb_table = XCNEWVEC (bb_info_t, last_basic_block); | |
764 rtx_group_next_id = 0; | 687 rtx_group_next_id = 0; |
765 | 688 |
766 stores_off_frame_dead_at_return = !cfun->stdarg; | 689 stores_off_frame_dead_at_return = !cfun->stdarg; |
767 | 690 |
768 init_alias_analysis (); | 691 init_alias_analysis (); |
769 | |
770 if (clear_alias_sets) | |
771 clear_alias_group = get_group_info (NULL); | |
772 else | |
773 clear_alias_group = NULL; | |
774 } | 692 } |
775 | 693 |
776 | 694 |
777 | 695 |
778 /*---------------------------------------------------------------------------- | 696 /*---------------------------------------------------------------------------- |
786 /* Delete all of the store_info recs from INSN_INFO. */ | 704 /* Delete all of the store_info recs from INSN_INFO. */ |
787 | 705 |
788 static void | 706 static void |
789 free_store_info (insn_info_t insn_info) | 707 free_store_info (insn_info_t insn_info) |
790 { | 708 { |
791 store_info_t store_info = insn_info->store_rec; | 709 store_info *cur = insn_info->store_rec; |
792 while (store_info) | 710 while (cur) |
793 { | 711 { |
794 store_info_t next = store_info->next; | 712 store_info *next = cur->next; |
795 if (store_info->is_large) | 713 if (cur->is_large) |
796 BITMAP_FREE (store_info->positions_needed.large.bmap); | 714 BITMAP_FREE (cur->positions_needed.large.bmap); |
797 if (store_info->cse_base) | 715 if (cur->cse_base) |
798 pool_free (cse_store_info_pool, store_info); | 716 cse_store_info_pool.remove (cur); |
799 else | 717 else |
800 pool_free (rtx_store_info_pool, store_info); | 718 rtx_store_info_pool.remove (cur); |
801 store_info = next; | 719 cur = next; |
802 } | 720 } |
803 | 721 |
804 insn_info->cannot_delete = true; | 722 insn_info->cannot_delete = true; |
805 insn_info->contains_cselib_groups = false; | 723 insn_info->contains_cselib_groups = false; |
806 insn_info->store_rec = NULL; | 724 insn_info->store_rec = NULL; |
725 } | |
726 | |
727 struct note_add_store_info | |
728 { | |
729 rtx_insn *first, *current; | |
730 regset fixed_regs_live; | |
731 bool failure; | |
732 }; | |
733 | |
734 /* Callback for emit_inc_dec_insn_before via note_stores. | |
735 Check if a register is clobbered which is live afterwards. */ | |
736 | |
737 static void | |
738 note_add_store (rtx loc, const_rtx expr ATTRIBUTE_UNUSED, void *data) | |
739 { | |
740 rtx_insn *insn; | |
741 note_add_store_info *info = (note_add_store_info *) data; | |
742 | |
743 if (!REG_P (loc)) | |
744 return; | |
745 | |
746 /* If this register is referenced by the current or an earlier insn, | |
747 that's OK. E.g. this applies to the register that is being incremented | |
748 with this addition. */ | |
749 for (insn = info->first; | |
750 insn != NEXT_INSN (info->current); | |
751 insn = NEXT_INSN (insn)) | |
752 if (reg_referenced_p (loc, PATTERN (insn))) | |
753 return; | |
754 | |
755 /* If we come here, we have a clobber of a register that's only OK | |
756 if that register is not live. If we don't have liveness information | |
757 available, fail now. */ | |
758 if (!info->fixed_regs_live) | |
759 { | |
760 info->failure = true; | |
761 return; | |
762 } | |
763 /* Now check if this is a live fixed register. */ | |
764 unsigned int end_regno = END_REGNO (loc); | |
765 for (unsigned int regno = REGNO (loc); regno < end_regno; ++regno) | |
766 if (REGNO_REG_SET_P (info->fixed_regs_live, regno)) | |
767 info->failure = true; | |
807 } | 768 } |
808 | 769 |
809 /* Callback for for_each_inc_dec that emits an INSN that sets DEST to | 770 /* Callback for for_each_inc_dec that emits an INSN that sets DEST to |
810 SRC + SRCOFF before insn ARG. */ | 771 SRC + SRCOFF before insn ARG. */ |
811 | 772 |
812 static int | 773 static int |
813 emit_inc_dec_insn_before (rtx mem ATTRIBUTE_UNUSED, | 774 emit_inc_dec_insn_before (rtx mem ATTRIBUTE_UNUSED, |
814 rtx op ATTRIBUTE_UNUSED, | 775 rtx op ATTRIBUTE_UNUSED, |
815 rtx dest, rtx src, rtx srcoff, void *arg) | 776 rtx dest, rtx src, rtx srcoff, void *arg) |
816 { | 777 { |
817 rtx insn = (rtx)arg; | 778 insn_info_t insn_info = (insn_info_t) arg; |
818 | 779 rtx_insn *insn = insn_info->insn, *new_insn, *cur; |
819 if (srcoff) | 780 note_add_store_info info; |
820 src = gen_rtx_PLUS (GET_MODE (src), src, srcoff); | |
821 | 781 |
822 /* We can reuse all operands without copying, because we are about | 782 /* We can reuse all operands without copying, because we are about |
823 to delete the insn that contained it. */ | 783 to delete the insn that contained it. */ |
824 | 784 if (srcoff) |
825 emit_insn_before (gen_rtx_SET (VOIDmode, dest, src), insn); | 785 { |
826 | 786 start_sequence (); |
827 return -1; | 787 emit_insn (gen_add3_insn (dest, src, srcoff)); |
828 } | 788 new_insn = get_insns (); |
829 | 789 end_sequence (); |
830 /* Before we delete INSN, make sure that the auto inc/dec, if it is | 790 } |
831 there, is split into a separate insn. */ | 791 else |
832 | 792 new_insn = gen_move_insn (dest, src); |
833 void | 793 info.first = new_insn; |
834 check_for_inc_dec (rtx insn) | 794 info.fixed_regs_live = insn_info->fixed_regs_live; |
835 { | 795 info.failure = false; |
796 for (cur = new_insn; cur; cur = NEXT_INSN (cur)) | |
797 { | |
798 info.current = cur; | |
799 note_stores (PATTERN (cur), note_add_store, &info); | |
800 } | |
801 | |
802 /* If a failure was flagged above, return 1 so that for_each_inc_dec will | |
803 return it immediately, communicating the failure to its caller. */ | |
804 if (info.failure) | |
805 return 1; | |
806 | |
807 emit_insn_before (new_insn, insn); | |
808 | |
809 return 0; | |
810 } | |
811 | |
812 /* Before we delete INSN_INFO->INSN, make sure that the auto inc/dec, if it | |
813 is there, is split into a separate insn. | |
814 Return true on success (or if there was nothing to do), false on failure. */ | |
815 | |
816 static bool | |
817 check_for_inc_dec_1 (insn_info_t insn_info) | |
818 { | |
819 rtx_insn *insn = insn_info->insn; | |
836 rtx note = find_reg_note (insn, REG_INC, NULL_RTX); | 820 rtx note = find_reg_note (insn, REG_INC, NULL_RTX); |
837 if (note) | 821 if (note) |
838 for_each_inc_dec (&insn, emit_inc_dec_insn_before, insn); | 822 return for_each_inc_dec (PATTERN (insn), emit_inc_dec_insn_before, |
839 } | 823 insn_info) == 0; |
840 | 824 return true; |
825 } | |
826 | |
827 | |
828 /* Entry point for postreload. If you work on reload_cse, or you need this | |
829 anywhere else, consider if you can provide register liveness information | |
830 and add a parameter to this function so that it can be passed down in | |
831 insn_info.fixed_regs_live. */ | |
832 bool | |
833 check_for_inc_dec (rtx_insn *insn) | |
834 { | |
835 insn_info_type insn_info; | |
836 rtx note; | |
837 | |
838 insn_info.insn = insn; | |
839 insn_info.fixed_regs_live = NULL; | |
840 note = find_reg_note (insn, REG_INC, NULL_RTX); | |
841 if (note) | |
842 return for_each_inc_dec (PATTERN (insn), emit_inc_dec_insn_before, | |
843 &insn_info) == 0; | |
844 return true; | |
845 } | |
841 | 846 |
842 /* Delete the insn and free all of the fields inside INSN_INFO. */ | 847 /* Delete the insn and free all of the fields inside INSN_INFO. */ |
843 | 848 |
844 static void | 849 static void |
845 delete_dead_store_insn (insn_info_t insn_info) | 850 delete_dead_store_insn (insn_info_t insn_info) |
847 read_info_t read_info; | 852 read_info_t read_info; |
848 | 853 |
849 if (!dbg_cnt (dse)) | 854 if (!dbg_cnt (dse)) |
850 return; | 855 return; |
851 | 856 |
852 check_for_inc_dec (insn_info->insn); | 857 if (!check_for_inc_dec_1 (insn_info)) |
853 if (dump_file) | 858 return; |
854 { | 859 if (dump_file && (dump_flags & TDF_DETAILS)) |
855 fprintf (dump_file, "Locally deleting insn %d ", | 860 fprintf (dump_file, "Locally deleting insn %d\n", |
856 INSN_UID (insn_info->insn)); | 861 INSN_UID (insn_info->insn)); |
857 if (insn_info->store_rec->alias_set) | |
858 fprintf (dump_file, "alias set %d\n", | |
859 (int) insn_info->store_rec->alias_set); | |
860 else | |
861 fprintf (dump_file, "\n"); | |
862 } | |
863 | 862 |
864 free_store_info (insn_info); | 863 free_store_info (insn_info); |
865 read_info = insn_info->read_rec; | 864 read_info = insn_info->read_rec; |
866 | 865 |
867 while (read_info) | 866 while (read_info) |
868 { | 867 { |
869 read_info_t next = read_info->next; | 868 read_info_t next = read_info->next; |
870 pool_free (read_info_pool, read_info); | 869 read_info_type_pool.remove (read_info); |
871 read_info = next; | 870 read_info = next; |
872 } | 871 } |
873 insn_info->read_rec = NULL; | 872 insn_info->read_rec = NULL; |
874 | 873 |
875 delete_insn (insn_info->insn); | 874 delete_insn (insn_info->insn); |
877 insn_info->insn = NULL; | 876 insn_info->insn = NULL; |
878 | 877 |
879 insn_info->wild_read = false; | 878 insn_info->wild_read = false; |
880 } | 879 } |
881 | 880 |
881 /* Return whether DECL, a local variable, can possibly escape the current | |
882 function scope. */ | |
883 | |
884 static bool | |
885 local_variable_can_escape (tree decl) | |
886 { | |
887 if (TREE_ADDRESSABLE (decl)) | |
888 return true; | |
889 | |
890 /* If this is a partitioned variable, we need to consider all the variables | |
891 in the partition. This is necessary because a store into one of them can | |
892 be replaced with a store into another and this may not change the outcome | |
893 of the escape analysis. */ | |
894 if (cfun->gimple_df->decls_to_pointers != NULL) | |
895 { | |
896 tree *namep = cfun->gimple_df->decls_to_pointers->get (decl); | |
897 if (namep) | |
898 return TREE_ADDRESSABLE (*namep); | |
899 } | |
900 | |
901 return false; | |
902 } | |
903 | |
904 /* Return whether EXPR can possibly escape the current function scope. */ | |
905 | |
906 static bool | |
907 can_escape (tree expr) | |
908 { | |
909 tree base; | |
910 if (!expr) | |
911 return true; | |
912 base = get_base_address (expr); | |
913 if (DECL_P (base) | |
914 && !may_be_aliased (base) | |
915 && !(VAR_P (base) | |
916 && !DECL_EXTERNAL (base) | |
917 && !TREE_STATIC (base) | |
918 && local_variable_can_escape (base))) | |
919 return false; | |
920 return true; | |
921 } | |
882 | 922 |
883 /* Set the store* bitmaps offset_map_size* fields in GROUP based on | 923 /* Set the store* bitmaps offset_map_size* fields in GROUP based on |
884 OFFSET and WIDTH. */ | 924 OFFSET and WIDTH. */ |
885 | 925 |
886 static void | 926 static void |
887 set_usage_bits (group_info_t group, HOST_WIDE_INT offset, HOST_WIDE_INT width) | 927 set_usage_bits (group_info *group, HOST_WIDE_INT offset, HOST_WIDE_INT width, |
928 tree expr) | |
888 { | 929 { |
889 HOST_WIDE_INT i; | 930 HOST_WIDE_INT i; |
890 | 931 bool expr_escapes = can_escape (expr); |
891 if (offset > -MAX_OFFSET && offset + width < MAX_OFFSET) | 932 if (offset > -MAX_OFFSET && offset + width < MAX_OFFSET) |
892 for (i=offset; i<offset+width; i++) | 933 for (i=offset; i<offset+width; i++) |
893 { | 934 { |
894 bitmap store1; | 935 bitmap store1; |
895 bitmap store2; | 936 bitmap store2; |
937 bitmap escaped; | |
896 int ai; | 938 int ai; |
897 if (i < 0) | 939 if (i < 0) |
898 { | 940 { |
899 store1 = group->store1_n; | 941 store1 = group->store1_n; |
900 store2 = group->store2_n; | 942 store2 = group->store2_n; |
943 escaped = group->escaped_n; | |
901 ai = -i; | 944 ai = -i; |
902 } | 945 } |
903 else | 946 else |
904 { | 947 { |
905 store1 = group->store1_p; | 948 store1 = group->store1_p; |
906 store2 = group->store2_p; | 949 store2 = group->store2_p; |
950 escaped = group->escaped_p; | |
907 ai = i; | 951 ai = i; |
908 } | 952 } |
909 | 953 |
910 if (!bitmap_set_bit (store1, ai)) | 954 if (!bitmap_set_bit (store1, ai)) |
911 bitmap_set_bit (store2, ai); | 955 bitmap_set_bit (store2, ai); |
920 { | 964 { |
921 if (group->offset_map_size_p < ai) | 965 if (group->offset_map_size_p < ai) |
922 group->offset_map_size_p = ai; | 966 group->offset_map_size_p = ai; |
923 } | 967 } |
924 } | 968 } |
969 if (expr_escapes) | |
970 bitmap_set_bit (escaped, ai); | |
925 } | 971 } |
926 } | 972 } |
927 | 973 |
974 static void | |
975 reset_active_stores (void) | |
976 { | |
977 active_local_stores = NULL; | |
978 active_local_stores_len = 0; | |
979 } | |
980 | |
981 /* Free all READ_REC of the LAST_INSN of BB_INFO. */ | |
982 | |
983 static void | |
984 free_read_records (bb_info_t bb_info) | |
985 { | |
986 insn_info_t insn_info = bb_info->last_insn; | |
987 read_info_t *ptr = &insn_info->read_rec; | |
988 while (*ptr) | |
989 { | |
990 read_info_t next = (*ptr)->next; | |
991 read_info_type_pool.remove (*ptr); | |
992 *ptr = next; | |
993 } | |
994 } | |
928 | 995 |
929 /* Set the BB_INFO so that the last insn is marked as a wild read. */ | 996 /* Set the BB_INFO so that the last insn is marked as a wild read. */ |
930 | 997 |
931 static void | 998 static void |
932 add_wild_read (bb_info_t bb_info) | 999 add_wild_read (bb_info_t bb_info) |
933 { | 1000 { |
934 insn_info_t insn_info = bb_info->last_insn; | 1001 insn_info_t insn_info = bb_info->last_insn; |
935 read_info_t *ptr = &insn_info->read_rec; | |
936 | |
937 while (*ptr) | |
938 { | |
939 read_info_t next = (*ptr)->next; | |
940 if ((*ptr)->alias_set == 0) | |
941 { | |
942 pool_free (read_info_pool, *ptr); | |
943 *ptr = next; | |
944 } | |
945 else | |
946 ptr = &(*ptr)->next; | |
947 } | |
948 insn_info->wild_read = true; | 1002 insn_info->wild_read = true; |
949 active_local_stores = NULL; | 1003 free_read_records (bb_info); |
950 } | 1004 reset_active_stores (); |
951 | 1005 } |
1006 | |
1007 /* Set the BB_INFO so that the last insn is marked as a wild read of | |
1008 non-frame locations. */ | |
1009 | |
1010 static void | |
1011 add_non_frame_wild_read (bb_info_t bb_info) | |
1012 { | |
1013 insn_info_t insn_info = bb_info->last_insn; | |
1014 insn_info->non_frame_wild_read = true; | |
1015 free_read_records (bb_info); | |
1016 reset_active_stores (); | |
1017 } | |
952 | 1018 |
953 /* Return true if X is a constant or one of the registers that behave | 1019 /* Return true if X is a constant or one of the registers that behave |
954 as a constant over the life of a function. This is equivalent to | 1020 as a constant over the life of a function. This is equivalent to |
955 !rtx_varies_p for memory addresses. */ | 1021 !rtx_varies_p for memory addresses. */ |
956 | 1022 |
957 static bool | 1023 static bool |
958 const_or_frame_p (rtx x) | 1024 const_or_frame_p (rtx x) |
959 { | 1025 { |
960 switch (GET_CODE (x)) | 1026 if (CONSTANT_P (x)) |
961 { | 1027 return true; |
962 case CONST: | 1028 |
963 case CONST_INT: | 1029 if (GET_CODE (x) == REG) |
964 case CONST_DOUBLE: | 1030 { |
965 case CONST_VECTOR: | |
966 case SYMBOL_REF: | |
967 case LABEL_REF: | |
968 return true; | |
969 | |
970 case REG: | |
971 /* Note that we have to test for the actual rtx used for the frame | 1031 /* Note that we have to test for the actual rtx used for the frame |
972 and arg pointers and not just the register number in case we have | 1032 and arg pointers and not just the register number in case we have |
973 eliminated the frame and/or arg pointer and are using it | 1033 eliminated the frame and/or arg pointer and are using it |
974 for pseudos. */ | 1034 for pseudos. */ |
975 if (x == frame_pointer_rtx || x == hard_frame_pointer_rtx | 1035 if (x == frame_pointer_rtx || x == hard_frame_pointer_rtx |
976 /* The arg pointer varies if it is not a fixed register. */ | 1036 /* The arg pointer varies if it is not a fixed register. */ |
977 || (x == arg_pointer_rtx && fixed_regs[ARG_POINTER_REGNUM]) | 1037 || (x == arg_pointer_rtx && fixed_regs[ARG_POINTER_REGNUM]) |
978 || x == pic_offset_table_rtx) | 1038 || x == pic_offset_table_rtx) |
979 return true; | 1039 return true; |
980 return false; | 1040 return false; |
981 | 1041 } |
982 default: | 1042 |
983 return false; | 1043 return false; |
984 } | |
985 } | 1044 } |
986 | 1045 |
987 /* Take all reasonable action to put the address of MEM into the form | 1046 /* Take all reasonable action to put the address of MEM into the form |
988 that we can do analysis on. | 1047 that we can do analysis on. |
989 | 1048 |
1002 | 1061 |
1003 FOR_READ is true if this is a mem read and false if not. */ | 1062 FOR_READ is true if this is a mem read and false if not. */ |
1004 | 1063 |
1005 static bool | 1064 static bool |
1006 canon_address (rtx mem, | 1065 canon_address (rtx mem, |
1007 alias_set_type *alias_set_out, | |
1008 int *group_id, | 1066 int *group_id, |
1009 HOST_WIDE_INT *offset, | 1067 HOST_WIDE_INT *offset, |
1010 cselib_val **base) | 1068 cselib_val **base) |
1011 { | 1069 { |
1012 enum machine_mode address_mode | 1070 machine_mode address_mode = get_address_mode (mem); |
1013 = targetm.addr_space.address_mode (MEM_ADDR_SPACE (mem)); | |
1014 rtx mem_address = XEXP (mem, 0); | 1071 rtx mem_address = XEXP (mem, 0); |
1015 rtx expanded_address, address; | 1072 rtx expanded_address, address; |
1016 int expanded; | 1073 int expanded; |
1017 | 1074 |
1018 /* Make sure that cselib is has initialized all of the operands of | |
1019 the address before asking it to do the subst. */ | |
1020 | |
1021 if (clear_alias_sets) | |
1022 { | |
1023 /* If this is a spill, do not do any further processing. */ | |
1024 alias_set_type alias_set = MEM_ALIAS_SET (mem); | |
1025 if (dump_file) | |
1026 fprintf (dump_file, "found alias set %d\n", (int) alias_set); | |
1027 if (bitmap_bit_p (clear_alias_sets, alias_set)) | |
1028 { | |
1029 struct clear_alias_mode_holder *entry | |
1030 = clear_alias_set_lookup (alias_set); | |
1031 | |
1032 /* If the modes do not match, we cannot process this set. */ | |
1033 if (entry->mode != GET_MODE (mem)) | |
1034 { | |
1035 if (dump_file) | |
1036 fprintf (dump_file, | |
1037 "disqualifying alias set %d, (%s) != (%s)\n", | |
1038 (int) alias_set, GET_MODE_NAME (entry->mode), | |
1039 GET_MODE_NAME (GET_MODE (mem))); | |
1040 | |
1041 bitmap_set_bit (disqualified_clear_alias_sets, alias_set); | |
1042 return false; | |
1043 } | |
1044 | |
1045 *alias_set_out = alias_set; | |
1046 *group_id = clear_alias_group->id; | |
1047 return true; | |
1048 } | |
1049 } | |
1050 | |
1051 *alias_set_out = 0; | |
1052 | |
1053 cselib_lookup (mem_address, address_mode, 1, GET_MODE (mem)); | 1075 cselib_lookup (mem_address, address_mode, 1, GET_MODE (mem)); |
1054 | 1076 |
1055 if (dump_file) | 1077 if (dump_file && (dump_flags & TDF_DETAILS)) |
1056 { | 1078 { |
1057 fprintf (dump_file, " mem: "); | 1079 fprintf (dump_file, " mem: "); |
1058 print_inline_rtx (dump_file, mem_address, 0); | 1080 print_inline_rtx (dump_file, mem_address, 0); |
1059 fprintf (dump_file, "\n"); | 1081 fprintf (dump_file, "\n"); |
1060 } | 1082 } |
1090 /* Split the address into canonical BASE + OFFSET terms. */ | 1112 /* Split the address into canonical BASE + OFFSET terms. */ |
1091 address = canon_rtx (expanded_address); | 1113 address = canon_rtx (expanded_address); |
1092 | 1114 |
1093 *offset = 0; | 1115 *offset = 0; |
1094 | 1116 |
1095 if (dump_file) | 1117 if (dump_file && (dump_flags & TDF_DETAILS)) |
1096 { | 1118 { |
1097 if (expanded) | 1119 if (expanded) |
1098 { | 1120 { |
1099 fprintf (dump_file, "\n after cselib_expand address: "); | 1121 fprintf (dump_file, "\n after cselib_expand address: "); |
1100 print_inline_rtx (dump_file, expanded_address, 0); | 1122 print_inline_rtx (dump_file, expanded_address, 0); |
1117 } | 1139 } |
1118 | 1140 |
1119 if (ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (mem)) | 1141 if (ADDR_SPACE_GENERIC_P (MEM_ADDR_SPACE (mem)) |
1120 && const_or_frame_p (address)) | 1142 && const_or_frame_p (address)) |
1121 { | 1143 { |
1122 group_info_t group = get_group_info (address); | 1144 group_info *group = get_group_info (address); |
1123 | 1145 |
1124 if (dump_file) | 1146 if (dump_file && (dump_flags & TDF_DETAILS)) |
1125 fprintf (dump_file, " gid=%d offset=%d \n", | 1147 fprintf (dump_file, " gid=%d offset=%d \n", |
1126 group->id, (int)*offset); | 1148 group->id, (int)*offset); |
1127 *base = NULL; | 1149 *base = NULL; |
1128 *group_id = group->id; | 1150 *group_id = group->id; |
1129 return true; | 1151 return true; |
1133 *base = cselib_lookup (address, address_mode, true, GET_MODE (mem)); | 1155 *base = cselib_lookup (address, address_mode, true, GET_MODE (mem)); |
1134 *group_id = -1; | 1156 *group_id = -1; |
1135 | 1157 |
1136 if (*base == NULL) | 1158 if (*base == NULL) |
1137 { | 1159 { |
1138 if (dump_file) | 1160 if (dump_file && (dump_flags & TDF_DETAILS)) |
1139 fprintf (dump_file, " no cselib val - should be a wild read.\n"); | 1161 fprintf (dump_file, " no cselib val - should be a wild read.\n"); |
1140 return false; | 1162 return false; |
1141 } | 1163 } |
1142 if (dump_file) | 1164 if (dump_file && (dump_flags & TDF_DETAILS)) |
1143 fprintf (dump_file, " varying cselib base=%u:%u offset = %d\n", | 1165 fprintf (dump_file, " varying cselib base=%u:%u offset = %d\n", |
1144 (*base)->uid, (*base)->hash, (int)*offset); | 1166 (*base)->uid, (*base)->hash, (int)*offset); |
1145 return true; | 1167 return true; |
1146 } | 1168 } |
1147 | 1169 |
1153 { | 1175 { |
1154 insn_info_t ptr = active_local_stores; | 1176 insn_info_t ptr = active_local_stores; |
1155 | 1177 |
1156 while (ptr) | 1178 while (ptr) |
1157 { | 1179 { |
1158 store_info_t store_info = ptr->store_rec; | 1180 store_info *store_info = ptr->store_rec; |
1159 /* Skip the clobbers. */ | 1181 /* Skip the clobbers. */ |
1160 while (!store_info->is_set) | 1182 while (!store_info->is_set) |
1161 store_info = store_info->next; | 1183 store_info = store_info->next; |
1162 | 1184 |
1163 store_info->rhs = NULL; | 1185 store_info->rhs = NULL; |
1169 | 1191 |
1170 | 1192 |
1171 /* Mark byte POS bytes from the beginning of store S_INFO as unneeded. */ | 1193 /* Mark byte POS bytes from the beginning of store S_INFO as unneeded. */ |
1172 | 1194 |
1173 static inline void | 1195 static inline void |
1174 set_position_unneeded (store_info_t s_info, int pos) | 1196 set_position_unneeded (store_info *s_info, int pos) |
1175 { | 1197 { |
1176 if (__builtin_expect (s_info->is_large, false)) | 1198 if (__builtin_expect (s_info->is_large, false)) |
1177 { | 1199 { |
1178 if (bitmap_set_bit (s_info->positions_needed.large.bmap, pos)) | 1200 if (bitmap_set_bit (s_info->positions_needed.large.bmap, pos)) |
1179 s_info->positions_needed.large.count++; | 1201 s_info->positions_needed.large.count++; |
1180 } | 1202 } |
1181 else | 1203 else |
1182 s_info->positions_needed.small_bitmask | 1204 s_info->positions_needed.small_bitmask |
1183 &= ~(((unsigned HOST_WIDE_INT) 1) << pos); | 1205 &= ~(HOST_WIDE_INT_1U << pos); |
1184 } | 1206 } |
1185 | 1207 |
1186 /* Mark the whole store S_INFO as unneeded. */ | 1208 /* Mark the whole store S_INFO as unneeded. */ |
1187 | 1209 |
1188 static inline void | 1210 static inline void |
1189 set_all_positions_unneeded (store_info_t s_info) | 1211 set_all_positions_unneeded (store_info *s_info) |
1190 { | 1212 { |
1191 if (__builtin_expect (s_info->is_large, false)) | 1213 if (__builtin_expect (s_info->is_large, false)) |
1192 { | 1214 { |
1193 int pos, end = s_info->end - s_info->begin; | 1215 int pos, end = s_info->end - s_info->begin; |
1194 for (pos = 0; pos < end; pos++) | 1216 for (pos = 0; pos < end; pos++) |
1195 bitmap_set_bit (s_info->positions_needed.large.bmap, pos); | 1217 bitmap_set_bit (s_info->positions_needed.large.bmap, pos); |
1196 s_info->positions_needed.large.count = end; | 1218 s_info->positions_needed.large.count = end; |
1197 } | 1219 } |
1198 else | 1220 else |
1199 s_info->positions_needed.small_bitmask = (unsigned HOST_WIDE_INT) 0; | 1221 s_info->positions_needed.small_bitmask = HOST_WIDE_INT_0U; |
1200 } | 1222 } |
1201 | 1223 |
1202 /* Return TRUE if any bytes from S_INFO store are needed. */ | 1224 /* Return TRUE if any bytes from S_INFO store are needed. */ |
1203 | 1225 |
1204 static inline bool | 1226 static inline bool |
1205 any_positions_needed_p (store_info_t s_info) | 1227 any_positions_needed_p (store_info *s_info) |
1206 { | 1228 { |
1207 if (__builtin_expect (s_info->is_large, false)) | 1229 if (__builtin_expect (s_info->is_large, false)) |
1208 return (s_info->positions_needed.large.count | 1230 return (s_info->positions_needed.large.count |
1209 < s_info->end - s_info->begin); | 1231 < s_info->end - s_info->begin); |
1210 else | 1232 else |
1211 return (s_info->positions_needed.small_bitmask | 1233 return (s_info->positions_needed.small_bitmask != HOST_WIDE_INT_0U); |
1212 != (unsigned HOST_WIDE_INT) 0); | |
1213 } | 1234 } |
1214 | 1235 |
1215 /* Return TRUE if all bytes START through START+WIDTH-1 from S_INFO | 1236 /* Return TRUE if all bytes START through START+WIDTH-1 from S_INFO |
1216 store are needed. */ | 1237 store are needed. */ |
1217 | 1238 |
1218 static inline bool | 1239 static inline bool |
1219 all_positions_needed_p (store_info_t s_info, int start, int width) | 1240 all_positions_needed_p (store_info *s_info, int start, int width) |
1220 { | 1241 { |
1221 if (__builtin_expect (s_info->is_large, false)) | 1242 if (__builtin_expect (s_info->is_large, false)) |
1222 { | 1243 { |
1223 int end = start + width; | 1244 int end = start + width; |
1224 while (start < end) | 1245 while (start < end) |
1232 return (s_info->positions_needed.small_bitmask & mask) == mask; | 1253 return (s_info->positions_needed.small_bitmask & mask) == mask; |
1233 } | 1254 } |
1234 } | 1255 } |
1235 | 1256 |
1236 | 1257 |
1237 static rtx get_stored_val (store_info_t, enum machine_mode, HOST_WIDE_INT, | 1258 static rtx get_stored_val (store_info *, machine_mode, HOST_WIDE_INT, |
1238 HOST_WIDE_INT, basic_block, bool); | 1259 HOST_WIDE_INT, basic_block, bool); |
1239 | 1260 |
1240 | 1261 |
1241 /* BODY is an instruction pattern that belongs to INSN. Return 1 if | 1262 /* BODY is an instruction pattern that belongs to INSN. Return 1 if |
1242 there is a candidate store, after adding it to the appropriate | 1263 there is a candidate store, after adding it to the appropriate |
1246 record_store (rtx body, bb_info_t bb_info) | 1267 record_store (rtx body, bb_info_t bb_info) |
1247 { | 1268 { |
1248 rtx mem, rhs, const_rhs, mem_addr; | 1269 rtx mem, rhs, const_rhs, mem_addr; |
1249 HOST_WIDE_INT offset = 0; | 1270 HOST_WIDE_INT offset = 0; |
1250 HOST_WIDE_INT width = 0; | 1271 HOST_WIDE_INT width = 0; |
1251 alias_set_type spill_alias_set; | |
1252 insn_info_t insn_info = bb_info->last_insn; | 1272 insn_info_t insn_info = bb_info->last_insn; |
1253 store_info_t store_info = NULL; | 1273 store_info *store_info = NULL; |
1254 int group_id; | 1274 int group_id; |
1255 cselib_val *base = NULL; | 1275 cselib_val *base = NULL; |
1256 insn_info_t ptr, last, redundant_reason; | 1276 insn_info_t ptr, last, redundant_reason; |
1257 bool store_is_unused; | 1277 bool store_is_unused; |
1258 | 1278 |
1280 /* At this point we know mem is a mem. */ | 1300 /* At this point we know mem is a mem. */ |
1281 if (GET_MODE (mem) == BLKmode) | 1301 if (GET_MODE (mem) == BLKmode) |
1282 { | 1302 { |
1283 if (GET_CODE (XEXP (mem, 0)) == SCRATCH) | 1303 if (GET_CODE (XEXP (mem, 0)) == SCRATCH) |
1284 { | 1304 { |
1285 if (dump_file) | 1305 if (dump_file && (dump_flags & TDF_DETAILS)) |
1286 fprintf (dump_file, " adding wild read for (clobber (mem:BLK (scratch))\n"); | 1306 fprintf (dump_file, " adding wild read for (clobber (mem:BLK (scratch))\n"); |
1287 add_wild_read (bb_info); | 1307 add_wild_read (bb_info); |
1288 insn_info->cannot_delete = true; | 1308 insn_info->cannot_delete = true; |
1289 return 0; | 1309 return 0; |
1290 } | 1310 } |
1291 /* Handle (set (mem:BLK (addr) [... S36 ...]) (const_int 0)) | 1311 /* Handle (set (mem:BLK (addr) [... S36 ...]) (const_int 0)) |
1292 as memset (addr, 0, 36); */ | 1312 as memset (addr, 0, 36); */ |
1293 else if (!MEM_SIZE (mem) | 1313 else if (!MEM_SIZE_KNOWN_P (mem) |
1294 || !CONST_INT_P (MEM_SIZE (mem)) | 1314 || MEM_SIZE (mem) <= 0 |
1315 || MEM_SIZE (mem) > MAX_OFFSET | |
1295 || GET_CODE (body) != SET | 1316 || GET_CODE (body) != SET |
1296 || INTVAL (MEM_SIZE (mem)) <= 0 | |
1297 || INTVAL (MEM_SIZE (mem)) > MAX_OFFSET | |
1298 || !CONST_INT_P (SET_SRC (body))) | 1317 || !CONST_INT_P (SET_SRC (body))) |
1299 { | 1318 { |
1300 if (!store_is_unused) | 1319 if (!store_is_unused) |
1301 { | 1320 { |
1302 /* If the set or clobber is unused, then it does not effect our | 1321 /* If the set or clobber is unused, then it does not effect our |
1310 | 1329 |
1311 /* We can still process a volatile mem, we just cannot delete it. */ | 1330 /* We can still process a volatile mem, we just cannot delete it. */ |
1312 if (MEM_VOLATILE_P (mem)) | 1331 if (MEM_VOLATILE_P (mem)) |
1313 insn_info->cannot_delete = true; | 1332 insn_info->cannot_delete = true; |
1314 | 1333 |
1315 if (!canon_address (mem, &spill_alias_set, &group_id, &offset, &base)) | 1334 if (!canon_address (mem, &group_id, &offset, &base)) |
1316 { | 1335 { |
1317 clear_rhs_from_active_local_stores (); | 1336 clear_rhs_from_active_local_stores (); |
1318 return 0; | 1337 return 0; |
1319 } | 1338 } |
1320 | 1339 |
1321 if (GET_MODE (mem) == BLKmode) | 1340 if (GET_MODE (mem) == BLKmode) |
1322 width = INTVAL (MEM_SIZE (mem)); | 1341 width = MEM_SIZE (mem); |
1323 else | 1342 else |
1324 { | 1343 width = GET_MODE_SIZE (GET_MODE (mem)); |
1325 width = GET_MODE_SIZE (GET_MODE (mem)); | 1344 |
1326 gcc_assert ((unsigned) width <= HOST_BITS_PER_WIDE_INT); | 1345 if (group_id >= 0) |
1327 } | |
1328 | |
1329 if (spill_alias_set) | |
1330 { | |
1331 bitmap store1 = clear_alias_group->store1_p; | |
1332 bitmap store2 = clear_alias_group->store2_p; | |
1333 | |
1334 gcc_assert (GET_MODE (mem) != BLKmode); | |
1335 | |
1336 if (!bitmap_set_bit (store1, spill_alias_set)) | |
1337 bitmap_set_bit (store2, spill_alias_set); | |
1338 | |
1339 if (clear_alias_group->offset_map_size_p < spill_alias_set) | |
1340 clear_alias_group->offset_map_size_p = spill_alias_set; | |
1341 | |
1342 store_info = (store_info_t) pool_alloc (rtx_store_info_pool); | |
1343 | |
1344 if (dump_file) | |
1345 fprintf (dump_file, " processing spill store %d(%s)\n", | |
1346 (int) spill_alias_set, GET_MODE_NAME (GET_MODE (mem))); | |
1347 } | |
1348 else if (group_id >= 0) | |
1349 { | 1346 { |
1350 /* In the restrictive case where the base is a constant or the | 1347 /* In the restrictive case where the base is a constant or the |
1351 frame pointer we can do global analysis. */ | 1348 frame pointer we can do global analysis. */ |
1352 | 1349 |
1353 group_info_t group | 1350 group_info *group |
1354 = VEC_index (group_info_t, rtx_group_vec, group_id); | 1351 = rtx_group_vec[group_id]; |
1355 | 1352 tree expr = MEM_EXPR (mem); |
1356 store_info = (store_info_t) pool_alloc (rtx_store_info_pool); | 1353 |
1357 set_usage_bits (group, offset, width); | 1354 store_info = rtx_store_info_pool.allocate (); |
1358 | 1355 set_usage_bits (group, offset, width, expr); |
1359 if (dump_file) | 1356 |
1357 if (dump_file && (dump_flags & TDF_DETAILS)) | |
1360 fprintf (dump_file, " processing const base store gid=%d[%d..%d)\n", | 1358 fprintf (dump_file, " processing const base store gid=%d[%d..%d)\n", |
1361 group_id, (int)offset, (int)(offset+width)); | 1359 group_id, (int)offset, (int)(offset+width)); |
1362 } | 1360 } |
1363 else | 1361 else |
1364 { | 1362 { |
1365 rtx base_term = find_base_term (XEXP (mem, 0)); | 1363 if (may_be_sp_based_p (XEXP (mem, 0))) |
1366 if (!base_term | |
1367 || (GET_CODE (base_term) == ADDRESS | |
1368 && GET_MODE (base_term) == Pmode | |
1369 && XEXP (base_term, 0) == stack_pointer_rtx)) | |
1370 insn_info->stack_pointer_based = true; | 1364 insn_info->stack_pointer_based = true; |
1371 insn_info->contains_cselib_groups = true; | 1365 insn_info->contains_cselib_groups = true; |
1372 | 1366 |
1373 store_info = (store_info_t) pool_alloc (cse_store_info_pool); | 1367 store_info = cse_store_info_pool.allocate (); |
1374 group_id = -1; | 1368 group_id = -1; |
1375 | 1369 |
1376 if (dump_file) | 1370 if (dump_file && (dump_flags & TDF_DETAILS)) |
1377 fprintf (dump_file, " processing cselib store [%d..%d)\n", | 1371 fprintf (dump_file, " processing cselib store [%d..%d)\n", |
1378 (int)offset, (int)(offset+width)); | 1372 (int)offset, (int)(offset+width)); |
1379 } | 1373 } |
1380 | 1374 |
1381 const_rhs = rhs = NULL_RTX; | 1375 const_rhs = rhs = NULL_RTX; |
1412 dead. */ | 1406 dead. */ |
1413 ptr = active_local_stores; | 1407 ptr = active_local_stores; |
1414 last = NULL; | 1408 last = NULL; |
1415 redundant_reason = NULL; | 1409 redundant_reason = NULL; |
1416 mem = canon_rtx (mem); | 1410 mem = canon_rtx (mem); |
1417 /* For alias_set != 0 canon_true_dependence should be never called. */ | 1411 |
1418 if (spill_alias_set) | 1412 if (group_id < 0) |
1419 mem_addr = NULL_RTX; | 1413 mem_addr = base->val_rtx; |
1420 else | 1414 else |
1421 { | 1415 { |
1422 if (group_id < 0) | 1416 group_info *group = rtx_group_vec[group_id]; |
1423 mem_addr = base->val_rtx; | 1417 mem_addr = group->canon_base_addr; |
1424 else | 1418 } |
1425 { | 1419 if (offset) |
1426 group_info_t group | 1420 mem_addr = plus_constant (get_address_mode (mem), mem_addr, offset); |
1427 = VEC_index (group_info_t, rtx_group_vec, group_id); | |
1428 mem_addr = group->canon_base_addr; | |
1429 } | |
1430 if (offset) | |
1431 mem_addr = plus_constant (mem_addr, offset); | |
1432 } | |
1433 | 1421 |
1434 while (ptr) | 1422 while (ptr) |
1435 { | 1423 { |
1436 insn_info_t next = ptr->next_local_store; | 1424 insn_info_t next = ptr->next_local_store; |
1437 store_info_t s_info = ptr->store_rec; | 1425 struct store_info *s_info = ptr->store_rec; |
1438 bool del = true; | 1426 bool del = true; |
1439 | 1427 |
1440 /* Skip the clobbers. We delete the active insn if this insn | 1428 /* Skip the clobbers. We delete the active insn if this insn |
1441 shadows the set. To have been put on the active list, it | 1429 shadows the set. To have been put on the active list, it |
1442 has exactly on set. */ | 1430 has exactly on set. */ |
1443 while (!s_info->is_set) | 1431 while (!s_info->is_set) |
1444 s_info = s_info->next; | 1432 s_info = s_info->next; |
1445 | 1433 |
1446 if (s_info->alias_set != spill_alias_set) | 1434 if (s_info->group_id == group_id && s_info->cse_base == base) |
1447 del = false; | |
1448 else if (s_info->alias_set) | |
1449 { | |
1450 struct clear_alias_mode_holder *entry | |
1451 = clear_alias_set_lookup (s_info->alias_set); | |
1452 /* Generally, spills cannot be processed if and of the | |
1453 references to the slot have a different mode. But if | |
1454 we are in the same block and mode is exactly the same | |
1455 between this store and one before in the same block, | |
1456 we can still delete it. */ | |
1457 if ((GET_MODE (mem) == GET_MODE (s_info->mem)) | |
1458 && (GET_MODE (mem) == entry->mode)) | |
1459 { | |
1460 del = true; | |
1461 set_all_positions_unneeded (s_info); | |
1462 } | |
1463 if (dump_file) | |
1464 fprintf (dump_file, " trying spill store in insn=%d alias_set=%d\n", | |
1465 INSN_UID (ptr->insn), (int) s_info->alias_set); | |
1466 } | |
1467 else if ((s_info->group_id == group_id) | |
1468 && (s_info->cse_base == base)) | |
1469 { | 1435 { |
1470 HOST_WIDE_INT i; | 1436 HOST_WIDE_INT i; |
1471 if (dump_file) | 1437 if (dump_file && (dump_flags & TDF_DETAILS)) |
1472 fprintf (dump_file, " trying store in insn=%d gid=%d[%d..%d)\n", | 1438 fprintf (dump_file, " trying store in insn=%d gid=%d[%d..%d)\n", |
1473 INSN_UID (ptr->insn), s_info->group_id, | 1439 INSN_UID (ptr->insn), s_info->group_id, |
1474 (int)s_info->begin, (int)s_info->end); | 1440 (int)s_info->begin, (int)s_info->end); |
1475 | 1441 |
1476 /* Even if PTR won't be eliminated as unneeded, if both | 1442 /* Even if PTR won't be eliminated as unneeded, if both |
1516 else if (s_info->rhs) | 1482 else if (s_info->rhs) |
1517 /* Need to see if it is possible for this store to overwrite | 1483 /* Need to see if it is possible for this store to overwrite |
1518 the value of store_info. If it is, set the rhs to NULL to | 1484 the value of store_info. If it is, set the rhs to NULL to |
1519 keep it from being used to remove a load. */ | 1485 keep it from being used to remove a load. */ |
1520 { | 1486 { |
1521 if (canon_true_dependence (s_info->mem, | 1487 if (canon_output_dependence (s_info->mem, true, |
1522 GET_MODE (s_info->mem), | 1488 mem, GET_MODE (mem), |
1523 s_info->mem_addr, | 1489 mem_addr)) |
1524 mem, mem_addr, rtx_varies_p)) | |
1525 { | 1490 { |
1526 s_info->rhs = NULL; | 1491 s_info->rhs = NULL; |
1527 s_info->const_rhs = NULL; | 1492 s_info->const_rhs = NULL; |
1528 } | 1493 } |
1529 } | 1494 } |
1530 | 1495 |
1531 /* An insn can be deleted if every position of every one of | 1496 /* An insn can be deleted if every position of every one of |
1532 its s_infos is zero. */ | 1497 its s_infos is zero. */ |
1533 if (any_positions_needed_p (s_info) | 1498 if (any_positions_needed_p (s_info)) |
1534 || ptr->cannot_delete) | |
1535 del = false; | 1499 del = false; |
1536 | 1500 |
1537 if (del) | 1501 if (del) |
1538 { | 1502 { |
1539 insn_info_t insn_to_delete = ptr; | 1503 insn_info_t insn_to_delete = ptr; |
1540 | 1504 |
1505 active_local_stores_len--; | |
1541 if (last) | 1506 if (last) |
1542 last->next_local_store = ptr->next_local_store; | 1507 last->next_local_store = ptr->next_local_store; |
1543 else | 1508 else |
1544 active_local_stores = ptr->next_local_store; | 1509 active_local_stores = ptr->next_local_store; |
1545 | 1510 |
1546 delete_dead_store_insn (insn_to_delete); | 1511 if (!insn_to_delete->cannot_delete) |
1512 delete_dead_store_insn (insn_to_delete); | |
1547 } | 1513 } |
1548 else | 1514 else |
1549 last = ptr; | 1515 last = ptr; |
1550 | 1516 |
1551 ptr = next; | 1517 ptr = next; |
1553 | 1519 |
1554 /* Finish filling in the store_info. */ | 1520 /* Finish filling in the store_info. */ |
1555 store_info->next = insn_info->store_rec; | 1521 store_info->next = insn_info->store_rec; |
1556 insn_info->store_rec = store_info; | 1522 insn_info->store_rec = store_info; |
1557 store_info->mem = mem; | 1523 store_info->mem = mem; |
1558 store_info->alias_set = spill_alias_set; | |
1559 store_info->mem_addr = mem_addr; | 1524 store_info->mem_addr = mem_addr; |
1560 store_info->cse_base = base; | 1525 store_info->cse_base = base; |
1561 if (width > HOST_BITS_PER_WIDE_INT) | 1526 if (width > HOST_BITS_PER_WIDE_INT) |
1562 { | 1527 { |
1563 store_info->is_large = true; | 1528 store_info->is_large = true; |
1564 store_info->positions_needed.large.count = 0; | 1529 store_info->positions_needed.large.count = 0; |
1565 store_info->positions_needed.large.bmap = BITMAP_ALLOC (NULL); | 1530 store_info->positions_needed.large.bmap = BITMAP_ALLOC (&dse_bitmap_obstack); |
1566 } | 1531 } |
1567 else | 1532 else |
1568 { | 1533 { |
1569 store_info->is_large = false; | 1534 store_info->is_large = false; |
1570 store_info->positions_needed.small_bitmask = lowpart_bitmask (width); | 1535 store_info->positions_needed.small_bitmask = lowpart_bitmask (width); |
1601 shift sequence is returned or NULL if we failed to find a | 1566 shift sequence is returned or NULL if we failed to find a |
1602 shift. */ | 1567 shift. */ |
1603 | 1568 |
1604 static rtx | 1569 static rtx |
1605 find_shift_sequence (int access_size, | 1570 find_shift_sequence (int access_size, |
1606 store_info_t store_info, | 1571 store_info *store_info, |
1607 enum machine_mode read_mode, | 1572 machine_mode read_mode, |
1608 int shift, bool speed, bool require_cst) | 1573 int shift, bool speed, bool require_cst) |
1609 { | 1574 { |
1610 enum machine_mode store_mode = GET_MODE (store_info->mem); | 1575 machine_mode store_mode = GET_MODE (store_info->mem); |
1611 enum machine_mode new_mode; | 1576 scalar_int_mode new_mode; |
1612 rtx read_reg = NULL; | 1577 rtx read_reg = NULL; |
1613 | 1578 |
1614 /* Some machines like the x86 have shift insns for each size of | 1579 /* Some machines like the x86 have shift insns for each size of |
1615 operand. Other machines like the ppc or the ia-64 may only have | 1580 operand. Other machines like the ppc or the ia-64 may only have |
1616 shift insns that shift values within 32 or 64 bit registers. | 1581 shift insns that shift values within 32 or 64 bit registers. |
1617 This loop tries to find the smallest shift insn that will right | 1582 This loop tries to find the smallest shift insn that will right |
1618 justify the value we want to read but is available in one insn on | 1583 justify the value we want to read but is available in one insn on |
1619 the machine. */ | 1584 the machine. */ |
1620 | 1585 |
1621 for (new_mode = smallest_mode_for_size (access_size * BITS_PER_UNIT, | 1586 opt_scalar_int_mode new_mode_iter; |
1622 MODE_INT); | 1587 FOR_EACH_MODE_FROM (new_mode_iter, |
1623 GET_MODE_BITSIZE (new_mode) <= BITS_PER_WORD; | 1588 smallest_int_mode_for_size (access_size * BITS_PER_UNIT)) |
1624 new_mode = GET_MODE_WIDER_MODE (new_mode)) | 1589 { |
1625 { | 1590 rtx target, new_reg, new_lhs; |
1626 rtx target, new_reg, shift_seq, insn, new_lhs; | 1591 rtx_insn *shift_seq, *insn; |
1627 int cost; | 1592 int cost; |
1593 | |
1594 new_mode = new_mode_iter.require (); | |
1595 if (GET_MODE_BITSIZE (new_mode) > BITS_PER_WORD) | |
1596 break; | |
1628 | 1597 |
1629 /* If a constant was stored into memory, try to simplify it here, | 1598 /* If a constant was stored into memory, try to simplify it here, |
1630 otherwise the cost of the shift might preclude this optimization | 1599 otherwise the cost of the shift might preclude this optimization |
1631 e.g. at -Os, even when no actual shift will be needed. */ | 1600 e.g. at -Os, even when no actual shift will be needed. */ |
1632 if (store_info->const_rhs) | 1601 if (store_info->const_rhs) |
1641 if (ret && CONSTANT_P (ret)) | 1610 if (ret && CONSTANT_P (ret)) |
1642 { | 1611 { |
1643 byte = subreg_lowpart_offset (read_mode, new_mode); | 1612 byte = subreg_lowpart_offset (read_mode, new_mode); |
1644 ret = simplify_subreg (read_mode, ret, new_mode, byte); | 1613 ret = simplify_subreg (read_mode, ret, new_mode, byte); |
1645 if (ret && CONSTANT_P (ret) | 1614 if (ret && CONSTANT_P (ret) |
1646 && rtx_cost (ret, SET, speed) <= COSTS_N_INSNS (1)) | 1615 && (set_src_cost (ret, read_mode, speed) |
1616 <= COSTS_N_INSNS (1))) | |
1647 return ret; | 1617 return ret; |
1648 } | 1618 } |
1649 } | 1619 } |
1650 } | 1620 } |
1651 | 1621 |
1653 return NULL_RTX; | 1623 return NULL_RTX; |
1654 | 1624 |
1655 /* Try a wider mode if truncating the store mode to NEW_MODE | 1625 /* Try a wider mode if truncating the store mode to NEW_MODE |
1656 requires a real instruction. */ | 1626 requires a real instruction. */ |
1657 if (GET_MODE_BITSIZE (new_mode) < GET_MODE_BITSIZE (store_mode) | 1627 if (GET_MODE_BITSIZE (new_mode) < GET_MODE_BITSIZE (store_mode) |
1658 && !TRULY_NOOP_TRUNCATION (GET_MODE_BITSIZE (new_mode), | 1628 && !TRULY_NOOP_TRUNCATION_MODES_P (new_mode, store_mode)) |
1659 GET_MODE_BITSIZE (store_mode))) | |
1660 continue; | 1629 continue; |
1661 | 1630 |
1662 /* Also try a wider mode if the necessary punning is either not | 1631 /* Also try a wider mode if the necessary punning is either not |
1663 desirable or not possible. */ | 1632 desirable or not possible. */ |
1664 if (!CONSTANT_P (store_info->rhs) | 1633 if (!CONSTANT_P (store_info->rhs) |
1665 && !MODES_TIEABLE_P (new_mode, store_mode)) | 1634 && !targetm.modes_tieable_p (new_mode, store_mode)) |
1666 continue; | 1635 continue; |
1667 | 1636 |
1668 new_reg = gen_reg_rtx (new_mode); | 1637 new_reg = gen_reg_rtx (new_mode); |
1669 | 1638 |
1670 start_sequence (); | 1639 start_sequence (); |
1682 continue; | 1651 continue; |
1683 | 1652 |
1684 cost = 0; | 1653 cost = 0; |
1685 for (insn = shift_seq; insn != NULL_RTX; insn = NEXT_INSN (insn)) | 1654 for (insn = shift_seq; insn != NULL_RTX; insn = NEXT_INSN (insn)) |
1686 if (INSN_P (insn)) | 1655 if (INSN_P (insn)) |
1687 cost += insn_rtx_cost (PATTERN (insn), speed); | 1656 cost += insn_cost (insn, speed); |
1688 | 1657 |
1689 /* The computation up to here is essentially independent | 1658 /* The computation up to here is essentially independent |
1690 of the arguments and could be precomputed. It may | 1659 of the arguments and could be precomputed. It may |
1691 not be worth doing so. We could precompute if | 1660 not be worth doing so. We could precompute if |
1692 worthwhile or at least cache the results. The result | 1661 worthwhile or at least cache the results. The result |
1722 look_for_hardregs (rtx x, const_rtx pat ATTRIBUTE_UNUSED, void *data) | 1691 look_for_hardregs (rtx x, const_rtx pat ATTRIBUTE_UNUSED, void *data) |
1723 { | 1692 { |
1724 bitmap regs_set = (bitmap) data; | 1693 bitmap regs_set = (bitmap) data; |
1725 | 1694 |
1726 if (REG_P (x) | 1695 if (REG_P (x) |
1727 && REGNO (x) < FIRST_PSEUDO_REGISTER) | 1696 && HARD_REGISTER_P (x)) |
1728 { | 1697 bitmap_set_range (regs_set, REGNO (x), REG_NREGS (x)); |
1729 int regno = REGNO (x); | |
1730 int n = hard_regno_nregs[regno][GET_MODE (x)]; | |
1731 while (--n >= 0) | |
1732 bitmap_set_bit (regs_set, regno + n); | |
1733 } | |
1734 } | 1698 } |
1735 | 1699 |
1736 /* Helper function for replace_read and record_store. | 1700 /* Helper function for replace_read and record_store. |
1737 Attempt to return a value stored in STORE_INFO, from READ_BEGIN | 1701 Attempt to return a value stored in STORE_INFO, from READ_BEGIN |
1738 to one before READ_END bytes read in READ_MODE. Return NULL | 1702 to one before READ_END bytes read in READ_MODE. Return NULL |
1739 if not successful. If REQUIRE_CST is true, return always constant. */ | 1703 if not successful. If REQUIRE_CST is true, return always constant. */ |
1740 | 1704 |
1741 static rtx | 1705 static rtx |
1742 get_stored_val (store_info_t store_info, enum machine_mode read_mode, | 1706 get_stored_val (store_info *store_info, machine_mode read_mode, |
1743 HOST_WIDE_INT read_begin, HOST_WIDE_INT read_end, | 1707 HOST_WIDE_INT read_begin, HOST_WIDE_INT read_end, |
1744 basic_block bb, bool require_cst) | 1708 basic_block bb, bool require_cst) |
1745 { | 1709 { |
1746 enum machine_mode store_mode = GET_MODE (store_info->mem); | 1710 machine_mode store_mode = GET_MODE (store_info->mem); |
1747 int shift; | 1711 int shift; |
1748 int access_size; /* In bytes. */ | 1712 int access_size; /* In bytes. */ |
1749 rtx read_reg; | 1713 rtx read_reg; |
1750 | 1714 |
1751 /* To get here the read is within the boundaries of the write so | 1715 /* To get here the read is within the boundaries of the write so |
1769 require_cst); | 1733 require_cst); |
1770 else if (store_mode == BLKmode) | 1734 else if (store_mode == BLKmode) |
1771 { | 1735 { |
1772 /* The store is a memset (addr, const_val, const_size). */ | 1736 /* The store is a memset (addr, const_val, const_size). */ |
1773 gcc_assert (CONST_INT_P (store_info->rhs)); | 1737 gcc_assert (CONST_INT_P (store_info->rhs)); |
1774 store_mode = int_mode_for_mode (read_mode); | 1738 scalar_int_mode int_store_mode; |
1775 if (store_mode == BLKmode) | 1739 if (!int_mode_for_mode (read_mode).exists (&int_store_mode)) |
1776 read_reg = NULL_RTX; | 1740 read_reg = NULL_RTX; |
1777 else if (store_info->rhs == const0_rtx) | 1741 else if (store_info->rhs == const0_rtx) |
1778 read_reg = extract_low_bits (read_mode, store_mode, const0_rtx); | 1742 read_reg = extract_low_bits (read_mode, int_store_mode, const0_rtx); |
1779 else if (GET_MODE_BITSIZE (store_mode) > HOST_BITS_PER_WIDE_INT | 1743 else if (GET_MODE_BITSIZE (int_store_mode) > HOST_BITS_PER_WIDE_INT |
1780 || BITS_PER_UNIT >= HOST_BITS_PER_WIDE_INT) | 1744 || BITS_PER_UNIT >= HOST_BITS_PER_WIDE_INT) |
1781 read_reg = NULL_RTX; | 1745 read_reg = NULL_RTX; |
1782 else | 1746 else |
1783 { | 1747 { |
1784 unsigned HOST_WIDE_INT c | 1748 unsigned HOST_WIDE_INT c |
1785 = INTVAL (store_info->rhs) | 1749 = INTVAL (store_info->rhs) |
1786 & (((HOST_WIDE_INT) 1 << BITS_PER_UNIT) - 1); | 1750 & ((HOST_WIDE_INT_1 << BITS_PER_UNIT) - 1); |
1787 int shift = BITS_PER_UNIT; | 1751 int shift = BITS_PER_UNIT; |
1788 while (shift < HOST_BITS_PER_WIDE_INT) | 1752 while (shift < HOST_BITS_PER_WIDE_INT) |
1789 { | 1753 { |
1790 c |= (c << shift); | 1754 c |= (c << shift); |
1791 shift <<= 1; | 1755 shift <<= 1; |
1792 } | 1756 } |
1793 read_reg = GEN_INT (trunc_int_for_mode (c, store_mode)); | 1757 read_reg = gen_int_mode (c, int_store_mode); |
1794 read_reg = extract_low_bits (read_mode, store_mode, read_reg); | 1758 read_reg = extract_low_bits (read_mode, int_store_mode, read_reg); |
1795 } | 1759 } |
1796 } | 1760 } |
1797 else if (store_info->const_rhs | 1761 else if (store_info->const_rhs |
1798 && (require_cst | 1762 && (require_cst |
1799 || GET_MODE_CLASS (read_mode) != GET_MODE_CLASS (store_mode))) | 1763 || GET_MODE_CLASS (read_mode) != GET_MODE_CLASS (store_mode))) |
1837 The STORE_INFO and STORE_INSN are for the store and READ_INFO | 1801 The STORE_INFO and STORE_INSN are for the store and READ_INFO |
1838 and READ_INSN are for the read. Return true if the replacement | 1802 and READ_INSN are for the read. Return true if the replacement |
1839 went ok. */ | 1803 went ok. */ |
1840 | 1804 |
1841 static bool | 1805 static bool |
1842 replace_read (store_info_t store_info, insn_info_t store_insn, | 1806 replace_read (store_info *store_info, insn_info_t store_insn, |
1843 read_info_t read_info, insn_info_t read_insn, rtx *loc, | 1807 read_info_t read_info, insn_info_t read_insn, rtx *loc, |
1844 bitmap regs_live) | 1808 bitmap regs_live) |
1845 { | 1809 { |
1846 enum machine_mode store_mode = GET_MODE (store_info->mem); | 1810 machine_mode store_mode = GET_MODE (store_info->mem); |
1847 enum machine_mode read_mode = GET_MODE (read_info->mem); | 1811 machine_mode read_mode = GET_MODE (read_info->mem); |
1848 rtx insns, this_insn, read_reg; | 1812 rtx_insn *insns, *this_insn; |
1813 rtx read_reg; | |
1849 basic_block bb; | 1814 basic_block bb; |
1850 | 1815 |
1851 if (!dbg_cnt (dse)) | 1816 if (!dbg_cnt (dse)) |
1852 return false; | 1817 return false; |
1853 | 1818 |
1858 We need to keep this in perspective. We are replacing a read | 1823 We need to keep this in perspective. We are replacing a read |
1859 with a sequence of insns, but the read will almost certainly be | 1824 with a sequence of insns, but the read will almost certainly be |
1860 in cache, so it is not going to be an expensive one. Thus, we | 1825 in cache, so it is not going to be an expensive one. Thus, we |
1861 are not willing to do a multi insn shift or worse a subroutine | 1826 are not willing to do a multi insn shift or worse a subroutine |
1862 call to get rid of the read. */ | 1827 call to get rid of the read. */ |
1863 if (dump_file) | 1828 if (dump_file && (dump_flags & TDF_DETAILS)) |
1864 fprintf (dump_file, "trying to replace %smode load in insn %d" | 1829 fprintf (dump_file, "trying to replace %smode load in insn %d" |
1865 " from %smode store in insn %d\n", | 1830 " from %smode store in insn %d\n", |
1866 GET_MODE_NAME (read_mode), INSN_UID (read_insn->insn), | 1831 GET_MODE_NAME (read_mode), INSN_UID (read_insn->insn), |
1867 GET_MODE_NAME (store_mode), INSN_UID (store_insn->insn)); | 1832 GET_MODE_NAME (store_mode), INSN_UID (store_insn->insn)); |
1868 start_sequence (); | 1833 start_sequence (); |
1871 read_mode, read_info->begin, read_info->end, | 1836 read_mode, read_info->begin, read_info->end, |
1872 bb, false); | 1837 bb, false); |
1873 if (read_reg == NULL_RTX) | 1838 if (read_reg == NULL_RTX) |
1874 { | 1839 { |
1875 end_sequence (); | 1840 end_sequence (); |
1876 if (dump_file) | 1841 if (dump_file && (dump_flags & TDF_DETAILS)) |
1877 fprintf (dump_file, " -- could not extract bits of stored value\n"); | 1842 fprintf (dump_file, " -- could not extract bits of stored value\n"); |
1878 return false; | 1843 return false; |
1879 } | 1844 } |
1880 /* Force the value into a new register so that it won't be clobbered | 1845 /* Force the value into a new register so that it won't be clobbered |
1881 between the store and the load. */ | 1846 between the store and the load. */ |
1888 /* Now we have to scan the set of new instructions to see if the | 1853 /* Now we have to scan the set of new instructions to see if the |
1889 sequence contains and sets of hardregs that happened to be | 1854 sequence contains and sets of hardregs that happened to be |
1890 live at this point. For instance, this can happen if one of | 1855 live at this point. For instance, this can happen if one of |
1891 the insns sets the CC and the CC happened to be live at that | 1856 the insns sets the CC and the CC happened to be live at that |
1892 point. This does occasionally happen, see PR 37922. */ | 1857 point. This does occasionally happen, see PR 37922. */ |
1893 bitmap regs_set = BITMAP_ALLOC (NULL); | 1858 bitmap regs_set = BITMAP_ALLOC (®_obstack); |
1894 | 1859 |
1895 for (this_insn = insns; this_insn != NULL_RTX; this_insn = NEXT_INSN (this_insn)) | 1860 for (this_insn = insns; this_insn != NULL_RTX; this_insn = NEXT_INSN (this_insn)) |
1896 note_stores (PATTERN (this_insn), look_for_hardregs, regs_set); | 1861 note_stores (PATTERN (this_insn), look_for_hardregs, regs_set); |
1897 | 1862 |
1898 bitmap_and_into (regs_set, regs_live); | 1863 bitmap_and_into (regs_set, regs_live); |
1899 if (!bitmap_empty_p (regs_set)) | 1864 if (!bitmap_empty_p (regs_set)) |
1900 { | 1865 { |
1901 if (dump_file) | 1866 if (dump_file && (dump_flags & TDF_DETAILS)) |
1902 { | 1867 { |
1903 fprintf (dump_file, | 1868 fprintf (dump_file, |
1904 "abandoning replacement because sequence clobbers live hardregs:"); | 1869 "abandoning replacement because sequence clobbers live hardregs:"); |
1905 df_print_regset (dump_file, regs_set); | 1870 df_print_regset (dump_file, regs_set); |
1906 } | 1871 } |
1911 BITMAP_FREE (regs_set); | 1876 BITMAP_FREE (regs_set); |
1912 } | 1877 } |
1913 | 1878 |
1914 if (validate_change (read_insn->insn, loc, read_reg, 0)) | 1879 if (validate_change (read_insn->insn, loc, read_reg, 0)) |
1915 { | 1880 { |
1916 deferred_change_t deferred_change = | 1881 deferred_change *change = deferred_change_pool.allocate (); |
1917 (deferred_change_t) pool_alloc (deferred_change_pool); | |
1918 | 1882 |
1919 /* Insert this right before the store insn where it will be safe | 1883 /* Insert this right before the store insn where it will be safe |
1920 from later insns that might change it before the read. */ | 1884 from later insns that might change it before the read. */ |
1921 emit_insn_before (insns, store_insn->insn); | 1885 emit_insn_before (insns, store_insn->insn); |
1922 | 1886 |
1942 and when we are finished with the block, we undo this. We | 1906 and when we are finished with the block, we undo this. We |
1943 keep a table of mems to get rid of. At the end of the basic | 1907 keep a table of mems to get rid of. At the end of the basic |
1944 block we can put them back. */ | 1908 block we can put them back. */ |
1945 | 1909 |
1946 *loc = read_info->mem; | 1910 *loc = read_info->mem; |
1947 deferred_change->next = deferred_change_list; | 1911 change->next = deferred_change_list; |
1948 deferred_change_list = deferred_change; | 1912 deferred_change_list = change; |
1949 deferred_change->loc = loc; | 1913 change->loc = loc; |
1950 deferred_change->reg = read_reg; | 1914 change->reg = read_reg; |
1951 | 1915 |
1952 /* Get rid of the read_info, from the point of view of the | 1916 /* Get rid of the read_info, from the point of view of the |
1953 rest of dse, play like this read never happened. */ | 1917 rest of dse, play like this read never happened. */ |
1954 read_insn->read_rec = read_info->next; | 1918 read_insn->read_rec = read_info->next; |
1955 pool_free (read_info_pool, read_info); | 1919 read_info_type_pool.remove (read_info); |
1956 if (dump_file) | 1920 if (dump_file && (dump_flags & TDF_DETAILS)) |
1957 { | 1921 { |
1958 fprintf (dump_file, " -- replaced the loaded MEM with "); | 1922 fprintf (dump_file, " -- replaced the loaded MEM with "); |
1959 print_simple_rtl (dump_file, read_reg); | 1923 print_simple_rtl (dump_file, read_reg); |
1960 fprintf (dump_file, "\n"); | 1924 fprintf (dump_file, "\n"); |
1961 } | 1925 } |
1962 return true; | 1926 return true; |
1963 } | 1927 } |
1964 else | 1928 else |
1965 { | 1929 { |
1966 if (dump_file) | 1930 if (dump_file && (dump_flags & TDF_DETAILS)) |
1967 { | 1931 { |
1968 fprintf (dump_file, " -- replacing the loaded MEM with "); | 1932 fprintf (dump_file, " -- replacing the loaded MEM with "); |
1969 print_simple_rtl (dump_file, read_reg); | 1933 print_simple_rtl (dump_file, read_reg); |
1970 fprintf (dump_file, " led to an invalid instruction\n"); | 1934 fprintf (dump_file, " led to an invalid instruction\n"); |
1971 } | 1935 } |
1972 return false; | 1936 return false; |
1973 } | 1937 } |
1974 } | 1938 } |
1975 | 1939 |
1976 /* A for_each_rtx callback in which DATA is the bb_info. Check to see | 1940 /* Check the address of MEM *LOC and kill any appropriate stores that may |
1977 if LOC is a mem and if it is look at the address and kill any | 1941 be active. */ |
1978 appropriate stores that may be active. */ | 1942 |
1979 | 1943 static void |
1980 static int | 1944 check_mem_read_rtx (rtx *loc, bb_info_t bb_info) |
1981 check_mem_read_rtx (rtx *loc, void *data) | |
1982 { | 1945 { |
1983 rtx mem = *loc, mem_addr; | 1946 rtx mem = *loc, mem_addr; |
1984 bb_info_t bb_info; | |
1985 insn_info_t insn_info; | 1947 insn_info_t insn_info; |
1986 HOST_WIDE_INT offset = 0; | 1948 HOST_WIDE_INT offset = 0; |
1987 HOST_WIDE_INT width = 0; | 1949 HOST_WIDE_INT width = 0; |
1988 alias_set_type spill_alias_set = 0; | |
1989 cselib_val *base = NULL; | 1950 cselib_val *base = NULL; |
1990 int group_id; | 1951 int group_id; |
1991 read_info_t read_info; | 1952 read_info_t read_info; |
1992 | 1953 |
1993 if (!mem || !MEM_P (mem)) | |
1994 return 0; | |
1995 | |
1996 bb_info = (bb_info_t) data; | |
1997 insn_info = bb_info->last_insn; | 1954 insn_info = bb_info->last_insn; |
1998 | 1955 |
1999 if ((MEM_ALIAS_SET (mem) == ALIAS_SET_MEMORY_BARRIER) | 1956 if ((MEM_ALIAS_SET (mem) == ALIAS_SET_MEMORY_BARRIER) |
2000 || (MEM_VOLATILE_P (mem))) | 1957 || (MEM_VOLATILE_P (mem))) |
2001 { | 1958 { |
2002 if (dump_file) | 1959 if (dump_file && (dump_flags & TDF_DETAILS)) |
2003 fprintf (dump_file, " adding wild read, volatile or barrier.\n"); | 1960 fprintf (dump_file, " adding wild read, volatile or barrier.\n"); |
2004 add_wild_read (bb_info); | 1961 add_wild_read (bb_info); |
2005 insn_info->cannot_delete = true; | 1962 insn_info->cannot_delete = true; |
2006 return 0; | 1963 return; |
2007 } | 1964 } |
2008 | 1965 |
2009 /* If it is reading readonly mem, then there can be no conflict with | 1966 /* If it is reading readonly mem, then there can be no conflict with |
2010 another write. */ | 1967 another write. */ |
2011 if (MEM_READONLY_P (mem)) | 1968 if (MEM_READONLY_P (mem)) |
2012 return 0; | 1969 return; |
2013 | 1970 |
2014 if (!canon_address (mem, &spill_alias_set, &group_id, &offset, &base)) | 1971 if (!canon_address (mem, &group_id, &offset, &base)) |
2015 { | 1972 { |
2016 if (dump_file) | 1973 if (dump_file && (dump_flags & TDF_DETAILS)) |
2017 fprintf (dump_file, " adding wild read, canon_address failure.\n"); | 1974 fprintf (dump_file, " adding wild read, canon_address failure.\n"); |
2018 add_wild_read (bb_info); | 1975 add_wild_read (bb_info); |
2019 return 0; | 1976 return; |
2020 } | 1977 } |
2021 | 1978 |
2022 if (GET_MODE (mem) == BLKmode) | 1979 if (GET_MODE (mem) == BLKmode) |
2023 width = -1; | 1980 width = -1; |
2024 else | 1981 else |
2025 width = GET_MODE_SIZE (GET_MODE (mem)); | 1982 width = GET_MODE_SIZE (GET_MODE (mem)); |
2026 | 1983 |
2027 read_info = (read_info_t) pool_alloc (read_info_pool); | 1984 read_info = read_info_type_pool.allocate (); |
2028 read_info->group_id = group_id; | 1985 read_info->group_id = group_id; |
2029 read_info->mem = mem; | 1986 read_info->mem = mem; |
2030 read_info->alias_set = spill_alias_set; | |
2031 read_info->begin = offset; | 1987 read_info->begin = offset; |
2032 read_info->end = offset + width; | 1988 read_info->end = offset + width; |
2033 read_info->next = insn_info->read_rec; | 1989 read_info->next = insn_info->read_rec; |
2034 insn_info->read_rec = read_info; | 1990 insn_info->read_rec = read_info; |
2035 /* For alias_set != 0 canon_true_dependence should be never called. */ | 1991 if (group_id < 0) |
2036 if (spill_alias_set) | 1992 mem_addr = base->val_rtx; |
2037 mem_addr = NULL_RTX; | |
2038 else | 1993 else |
2039 { | 1994 { |
2040 if (group_id < 0) | 1995 group_info *group = rtx_group_vec[group_id]; |
2041 mem_addr = base->val_rtx; | 1996 mem_addr = group->canon_base_addr; |
2042 else | 1997 } |
2043 { | 1998 if (offset) |
2044 group_info_t group | 1999 mem_addr = plus_constant (get_address_mode (mem), mem_addr, offset); |
2045 = VEC_index (group_info_t, rtx_group_vec, group_id); | 2000 |
2046 mem_addr = group->canon_base_addr; | 2001 if (group_id >= 0) |
2047 } | |
2048 if (offset) | |
2049 mem_addr = plus_constant (mem_addr, offset); | |
2050 } | |
2051 | |
2052 /* We ignore the clobbers in store_info. The is mildly aggressive, | |
2053 but there really should not be a clobber followed by a read. */ | |
2054 | |
2055 if (spill_alias_set) | |
2056 { | |
2057 insn_info_t i_ptr = active_local_stores; | |
2058 insn_info_t last = NULL; | |
2059 | |
2060 if (dump_file) | |
2061 fprintf (dump_file, " processing spill load %d\n", | |
2062 (int) spill_alias_set); | |
2063 | |
2064 while (i_ptr) | |
2065 { | |
2066 store_info_t store_info = i_ptr->store_rec; | |
2067 | |
2068 /* Skip the clobbers. */ | |
2069 while (!store_info->is_set) | |
2070 store_info = store_info->next; | |
2071 | |
2072 if (store_info->alias_set == spill_alias_set) | |
2073 { | |
2074 if (dump_file) | |
2075 dump_insn_info ("removing from active", i_ptr); | |
2076 | |
2077 if (last) | |
2078 last->next_local_store = i_ptr->next_local_store; | |
2079 else | |
2080 active_local_stores = i_ptr->next_local_store; | |
2081 } | |
2082 else | |
2083 last = i_ptr; | |
2084 i_ptr = i_ptr->next_local_store; | |
2085 } | |
2086 } | |
2087 else if (group_id >= 0) | |
2088 { | 2002 { |
2089 /* This is the restricted case where the base is a constant or | 2003 /* This is the restricted case where the base is a constant or |
2090 the frame pointer and offset is a constant. */ | 2004 the frame pointer and offset is a constant. */ |
2091 insn_info_t i_ptr = active_local_stores; | 2005 insn_info_t i_ptr = active_local_stores; |
2092 insn_info_t last = NULL; | 2006 insn_info_t last = NULL; |
2093 | 2007 |
2094 if (dump_file) | 2008 if (dump_file && (dump_flags & TDF_DETAILS)) |
2095 { | 2009 { |
2096 if (width == -1) | 2010 if (width == -1) |
2097 fprintf (dump_file, " processing const load gid=%d[BLK]\n", | 2011 fprintf (dump_file, " processing const load gid=%d[BLK]\n", |
2098 group_id); | 2012 group_id); |
2099 else | 2013 else |
2102 } | 2016 } |
2103 | 2017 |
2104 while (i_ptr) | 2018 while (i_ptr) |
2105 { | 2019 { |
2106 bool remove = false; | 2020 bool remove = false; |
2107 store_info_t store_info = i_ptr->store_rec; | 2021 store_info *store_info = i_ptr->store_rec; |
2108 | 2022 |
2109 /* Skip the clobbers. */ | 2023 /* Skip the clobbers. */ |
2110 while (!store_info->is_set) | 2024 while (!store_info->is_set) |
2111 store_info = store_info->next; | 2025 store_info = store_info->next; |
2112 | 2026 |
2116 const base. */ | 2030 const base. */ |
2117 remove | 2031 remove |
2118 = canon_true_dependence (store_info->mem, | 2032 = canon_true_dependence (store_info->mem, |
2119 GET_MODE (store_info->mem), | 2033 GET_MODE (store_info->mem), |
2120 store_info->mem_addr, | 2034 store_info->mem_addr, |
2121 mem, mem_addr, rtx_varies_p); | 2035 mem, mem_addr); |
2122 | 2036 |
2123 else if (group_id == store_info->group_id) | 2037 else if (group_id == store_info->group_id) |
2124 { | 2038 { |
2125 /* This is a block mode load. We may get lucky and | 2039 /* This is a block mode load. We may get lucky and |
2126 canon_true_dependence may save the day. */ | 2040 canon_true_dependence may save the day. */ |
2127 if (width == -1) | 2041 if (width == -1) |
2128 remove | 2042 remove |
2129 = canon_true_dependence (store_info->mem, | 2043 = canon_true_dependence (store_info->mem, |
2130 GET_MODE (store_info->mem), | 2044 GET_MODE (store_info->mem), |
2131 store_info->mem_addr, | 2045 store_info->mem_addr, |
2132 mem, mem_addr, rtx_varies_p); | 2046 mem, mem_addr); |
2133 | 2047 |
2134 /* If this read is just reading back something that we just | 2048 /* If this read is just reading back something that we just |
2135 stored, rewrite the read. */ | 2049 stored, rewrite the read. */ |
2136 else | 2050 else |
2137 { | 2051 { |
2141 && all_positions_needed_p (store_info, | 2055 && all_positions_needed_p (store_info, |
2142 offset - store_info->begin, | 2056 offset - store_info->begin, |
2143 width) | 2057 width) |
2144 && replace_read (store_info, i_ptr, read_info, | 2058 && replace_read (store_info, i_ptr, read_info, |
2145 insn_info, loc, bb_info->regs_live)) | 2059 insn_info, loc, bb_info->regs_live)) |
2146 return 0; | 2060 return; |
2147 | 2061 |
2148 /* The bases are the same, just see if the offsets | 2062 /* The bases are the same, just see if the offsets |
2149 overlap. */ | 2063 overlap. */ |
2150 if ((offset < store_info->end) | 2064 if ((offset < store_info->end) |
2151 && (offset + width > store_info->begin)) | 2065 && (offset + width > store_info->begin)) |
2158 bases are constant but different. There is nothing | 2072 bases are constant but different. There is nothing |
2159 to do here because there is no overlap. */ | 2073 to do here because there is no overlap. */ |
2160 | 2074 |
2161 if (remove) | 2075 if (remove) |
2162 { | 2076 { |
2163 if (dump_file) | 2077 if (dump_file && (dump_flags & TDF_DETAILS)) |
2164 dump_insn_info ("removing from active", i_ptr); | 2078 dump_insn_info ("removing from active", i_ptr); |
2165 | 2079 |
2080 active_local_stores_len--; | |
2166 if (last) | 2081 if (last) |
2167 last->next_local_store = i_ptr->next_local_store; | 2082 last->next_local_store = i_ptr->next_local_store; |
2168 else | 2083 else |
2169 active_local_stores = i_ptr->next_local_store; | 2084 active_local_stores = i_ptr->next_local_store; |
2170 } | 2085 } |
2175 } | 2090 } |
2176 else | 2091 else |
2177 { | 2092 { |
2178 insn_info_t i_ptr = active_local_stores; | 2093 insn_info_t i_ptr = active_local_stores; |
2179 insn_info_t last = NULL; | 2094 insn_info_t last = NULL; |
2180 if (dump_file) | 2095 if (dump_file && (dump_flags & TDF_DETAILS)) |
2181 { | 2096 { |
2182 fprintf (dump_file, " processing cselib load mem:"); | 2097 fprintf (dump_file, " processing cselib load mem:"); |
2183 print_inline_rtx (dump_file, mem, 0); | 2098 print_inline_rtx (dump_file, mem, 0); |
2184 fprintf (dump_file, "\n"); | 2099 fprintf (dump_file, "\n"); |
2185 } | 2100 } |
2186 | 2101 |
2187 while (i_ptr) | 2102 while (i_ptr) |
2188 { | 2103 { |
2189 bool remove = false; | 2104 bool remove = false; |
2190 store_info_t store_info = i_ptr->store_rec; | 2105 store_info *store_info = i_ptr->store_rec; |
2191 | 2106 |
2192 if (dump_file) | 2107 if (dump_file && (dump_flags & TDF_DETAILS)) |
2193 fprintf (dump_file, " processing cselib load against insn %d\n", | 2108 fprintf (dump_file, " processing cselib load against insn %d\n", |
2194 INSN_UID (i_ptr->insn)); | 2109 INSN_UID (i_ptr->insn)); |
2195 | 2110 |
2196 /* Skip the clobbers. */ | 2111 /* Skip the clobbers. */ |
2197 while (!store_info->is_set) | 2112 while (!store_info->is_set) |
2207 && offset + width <= store_info->end | 2122 && offset + width <= store_info->end |
2208 && all_positions_needed_p (store_info, | 2123 && all_positions_needed_p (store_info, |
2209 offset - store_info->begin, width) | 2124 offset - store_info->begin, width) |
2210 && replace_read (store_info, i_ptr, read_info, insn_info, loc, | 2125 && replace_read (store_info, i_ptr, read_info, insn_info, loc, |
2211 bb_info->regs_live)) | 2126 bb_info->regs_live)) |
2212 return 0; | 2127 return; |
2213 | 2128 |
2214 if (!store_info->alias_set) | 2129 remove = canon_true_dependence (store_info->mem, |
2215 remove = canon_true_dependence (store_info->mem, | 2130 GET_MODE (store_info->mem), |
2216 GET_MODE (store_info->mem), | 2131 store_info->mem_addr, |
2217 store_info->mem_addr, | 2132 mem, mem_addr); |
2218 mem, mem_addr, rtx_varies_p); | |
2219 | 2133 |
2220 if (remove) | 2134 if (remove) |
2221 { | 2135 { |
2222 if (dump_file) | 2136 if (dump_file && (dump_flags & TDF_DETAILS)) |
2223 dump_insn_info ("removing from active", i_ptr); | 2137 dump_insn_info ("removing from active", i_ptr); |
2224 | 2138 |
2139 active_local_stores_len--; | |
2225 if (last) | 2140 if (last) |
2226 last->next_local_store = i_ptr->next_local_store; | 2141 last->next_local_store = i_ptr->next_local_store; |
2227 else | 2142 else |
2228 active_local_stores = i_ptr->next_local_store; | 2143 active_local_stores = i_ptr->next_local_store; |
2229 } | 2144 } |
2230 else | 2145 else |
2231 last = i_ptr; | 2146 last = i_ptr; |
2232 i_ptr = i_ptr->next_local_store; | 2147 i_ptr = i_ptr->next_local_store; |
2233 } | 2148 } |
2234 } | 2149 } |
2235 return 0; | 2150 } |
2236 } | 2151 |
2237 | 2152 /* A note_uses callback in which DATA points the INSN_INFO for |
2238 /* A for_each_rtx callback in which DATA points the INSN_INFO for | |
2239 as check_mem_read_rtx. Nullify the pointer if i_m_r_m_r returns | 2153 as check_mem_read_rtx. Nullify the pointer if i_m_r_m_r returns |
2240 true for any part of *LOC. */ | 2154 true for any part of *LOC. */ |
2241 | 2155 |
2242 static void | 2156 static void |
2243 check_mem_read_use (rtx *loc, void *data) | 2157 check_mem_read_use (rtx *loc, void *data) |
2244 { | 2158 { |
2245 for_each_rtx (loc, check_mem_read_rtx, data); | 2159 subrtx_ptr_iterator::array_type array; |
2160 FOR_EACH_SUBRTX_PTR (iter, array, loc, NONCONST) | |
2161 { | |
2162 rtx *loc = *iter; | |
2163 if (MEM_P (*loc)) | |
2164 check_mem_read_rtx (loc, (bb_info_t) data); | |
2165 } | |
2246 } | 2166 } |
2247 | 2167 |
2248 | 2168 |
2249 /* Get arguments passed to CALL_INSN. Return TRUE if successful. | 2169 /* Get arguments passed to CALL_INSN. Return TRUE if successful. |
2250 So far it only handles arguments passed in registers. */ | 2170 So far it only handles arguments passed in registers. */ |
2251 | 2171 |
2252 static bool | 2172 static bool |
2253 get_call_args (rtx call_insn, tree fn, rtx *args, int nargs) | 2173 get_call_args (rtx call_insn, tree fn, rtx *args, int nargs) |
2254 { | 2174 { |
2255 CUMULATIVE_ARGS args_so_far; | 2175 CUMULATIVE_ARGS args_so_far_v; |
2176 cumulative_args_t args_so_far; | |
2256 tree arg; | 2177 tree arg; |
2257 int idx; | 2178 int idx; |
2258 | 2179 |
2259 INIT_CUMULATIVE_ARGS (args_so_far, TREE_TYPE (fn), NULL_RTX, 0, 3); | 2180 INIT_CUMULATIVE_ARGS (args_so_far_v, TREE_TYPE (fn), NULL_RTX, 0, 3); |
2181 args_so_far = pack_cumulative_args (&args_so_far_v); | |
2260 | 2182 |
2261 arg = TYPE_ARG_TYPES (TREE_TYPE (fn)); | 2183 arg = TYPE_ARG_TYPES (TREE_TYPE (fn)); |
2262 for (idx = 0; | 2184 for (idx = 0; |
2263 arg != void_list_node && idx < nargs; | 2185 arg != void_list_node && idx < nargs; |
2264 arg = TREE_CHAIN (arg), idx++) | 2186 arg = TREE_CHAIN (arg), idx++) |
2265 { | 2187 { |
2266 enum machine_mode mode = TYPE_MODE (TREE_VALUE (arg)); | 2188 scalar_int_mode mode; |
2267 rtx reg, link, tmp; | 2189 rtx reg, link, tmp; |
2268 reg = targetm.calls.function_arg (&args_so_far, mode, NULL_TREE, true); | 2190 |
2269 if (!reg || !REG_P (reg) || GET_MODE (reg) != mode | 2191 if (!is_int_mode (TYPE_MODE (TREE_VALUE (arg)), &mode)) |
2270 || GET_MODE_CLASS (mode) != MODE_INT) | 2192 return false; |
2193 | |
2194 reg = targetm.calls.function_arg (args_so_far, mode, NULL_TREE, true); | |
2195 if (!reg || !REG_P (reg) || GET_MODE (reg) != mode) | |
2271 return false; | 2196 return false; |
2272 | 2197 |
2273 for (link = CALL_INSN_FUNCTION_USAGE (call_insn); | 2198 for (link = CALL_INSN_FUNCTION_USAGE (call_insn); |
2274 link; | 2199 link; |
2275 link = XEXP (link, 1)) | 2200 link = XEXP (link, 1)) |
2276 if (GET_CODE (XEXP (link, 0)) == USE) | 2201 if (GET_CODE (XEXP (link, 0)) == USE) |
2277 { | 2202 { |
2203 scalar_int_mode arg_mode; | |
2278 args[idx] = XEXP (XEXP (link, 0), 0); | 2204 args[idx] = XEXP (XEXP (link, 0), 0); |
2279 if (REG_P (args[idx]) | 2205 if (REG_P (args[idx]) |
2280 && REGNO (args[idx]) == REGNO (reg) | 2206 && REGNO (args[idx]) == REGNO (reg) |
2281 && (GET_MODE (args[idx]) == mode | 2207 && (GET_MODE (args[idx]) == mode |
2282 || (GET_MODE_CLASS (GET_MODE (args[idx])) == MODE_INT | 2208 || (is_int_mode (GET_MODE (args[idx]), &arg_mode) |
2283 && (GET_MODE_SIZE (GET_MODE (args[idx])) | 2209 && (GET_MODE_SIZE (arg_mode) <= UNITS_PER_WORD) |
2284 <= UNITS_PER_WORD) | 2210 && (GET_MODE_SIZE (arg_mode) > GET_MODE_SIZE (mode))))) |
2285 && (GET_MODE_SIZE (GET_MODE (args[idx])) | |
2286 > GET_MODE_SIZE (mode))))) | |
2287 break; | 2211 break; |
2288 } | 2212 } |
2289 if (!link) | 2213 if (!link) |
2290 return false; | 2214 return false; |
2291 | 2215 |
2292 tmp = cselib_expand_value_rtx (args[idx], scratch, 5); | 2216 tmp = cselib_expand_value_rtx (args[idx], scratch, 5); |
2293 if (GET_MODE (args[idx]) != mode) | 2217 if (GET_MODE (args[idx]) != mode) |
2294 { | 2218 { |
2295 if (!tmp || !CONST_INT_P (tmp)) | 2219 if (!tmp || !CONST_INT_P (tmp)) |
2296 return false; | 2220 return false; |
2297 tmp = GEN_INT (trunc_int_for_mode (INTVAL (tmp), mode)); | 2221 tmp = gen_int_mode (INTVAL (tmp), mode); |
2298 } | 2222 } |
2299 if (tmp) | 2223 if (tmp) |
2300 args[idx] = tmp; | 2224 args[idx] = tmp; |
2301 | 2225 |
2302 targetm.calls.function_arg_advance (&args_so_far, mode, NULL_TREE, true); | 2226 targetm.calls.function_arg_advance (args_so_far, mode, NULL_TREE, true); |
2303 } | 2227 } |
2304 if (arg != void_list_node || idx != nargs) | 2228 if (arg != void_list_node || idx != nargs) |
2305 return false; | 2229 return false; |
2306 return true; | 2230 return true; |
2307 } | 2231 } |
2308 | 2232 |
2233 /* Return a bitmap of the fixed registers contained in IN. */ | |
2234 | |
2235 static bitmap | |
2236 copy_fixed_regs (const_bitmap in) | |
2237 { | |
2238 bitmap ret; | |
2239 | |
2240 ret = ALLOC_REG_SET (NULL); | |
2241 bitmap_and (ret, in, fixed_reg_set_regset); | |
2242 return ret; | |
2243 } | |
2309 | 2244 |
2310 /* Apply record_store to all candidate stores in INSN. Mark INSN | 2245 /* Apply record_store to all candidate stores in INSN. Mark INSN |
2311 if some part of it is not a candidate store and assigns to a | 2246 if some part of it is not a candidate store and assigns to a |
2312 non-register target. */ | 2247 non-register target. */ |
2313 | 2248 |
2314 static void | 2249 static void |
2315 scan_insn (bb_info_t bb_info, rtx insn) | 2250 scan_insn (bb_info_t bb_info, rtx_insn *insn) |
2316 { | 2251 { |
2317 rtx body; | 2252 rtx body; |
2318 insn_info_t insn_info = (insn_info_t) pool_alloc (insn_info_pool); | 2253 insn_info_type *insn_info = insn_info_type_pool.allocate (); |
2319 int mems_found = 0; | 2254 int mems_found = 0; |
2320 memset (insn_info, 0, sizeof (struct insn_info)); | 2255 memset (insn_info, 0, sizeof (struct insn_info_type)); |
2321 | 2256 |
2322 if (dump_file) | 2257 if (dump_file && (dump_flags & TDF_DETAILS)) |
2323 fprintf (dump_file, "\n**scanning insn=%d\n", | 2258 fprintf (dump_file, "\n**scanning insn=%d\n", |
2324 INSN_UID (insn)); | 2259 INSN_UID (insn)); |
2325 | 2260 |
2326 insn_info->prev_insn = bb_info->last_insn; | 2261 insn_info->prev_insn = bb_info->last_insn; |
2327 insn_info->insn = insn; | 2262 insn_info->insn = insn; |
2331 { | 2266 { |
2332 insn_info->cannot_delete = true; | 2267 insn_info->cannot_delete = true; |
2333 return; | 2268 return; |
2334 } | 2269 } |
2335 | 2270 |
2336 /* Cselib clears the table for this case, so we have to essentially | |
2337 do the same. */ | |
2338 if (NONJUMP_INSN_P (insn) | |
2339 && GET_CODE (PATTERN (insn)) == ASM_OPERANDS | |
2340 && MEM_VOLATILE_P (PATTERN (insn))) | |
2341 { | |
2342 add_wild_read (bb_info); | |
2343 insn_info->cannot_delete = true; | |
2344 return; | |
2345 } | |
2346 | |
2347 /* Look at all of the uses in the insn. */ | 2271 /* Look at all of the uses in the insn. */ |
2348 note_uses (&PATTERN (insn), check_mem_read_use, bb_info); | 2272 note_uses (&PATTERN (insn), check_mem_read_use, bb_info); |
2349 | 2273 |
2350 if (CALL_P (insn)) | 2274 if (CALL_P (insn)) |
2351 { | 2275 { |
2352 bool const_call; | 2276 bool const_call; |
2277 rtx call, sym; | |
2353 tree memset_call = NULL_TREE; | 2278 tree memset_call = NULL_TREE; |
2354 | 2279 |
2355 insn_info->cannot_delete = true; | 2280 insn_info->cannot_delete = true; |
2356 | 2281 |
2357 /* Const functions cannot do anything bad i.e. read memory, | 2282 /* Const functions cannot do anything bad i.e. read memory, |
2358 however, they can read their parameters which may have | 2283 however, they can read their parameters which may have |
2359 been pushed onto the stack. | 2284 been pushed onto the stack. |
2360 memset and bzero don't read memory either. */ | 2285 memset and bzero don't read memory either. */ |
2361 const_call = RTL_CONST_CALL_P (insn); | 2286 const_call = RTL_CONST_CALL_P (insn); |
2362 if (!const_call) | 2287 if (!const_call |
2363 { | 2288 && (call = get_call_rtx_from (insn)) |
2364 rtx call = PATTERN (insn); | 2289 && (sym = XEXP (XEXP (call, 0), 0)) |
2365 if (GET_CODE (call) == PARALLEL) | 2290 && GET_CODE (sym) == SYMBOL_REF |
2366 call = XVECEXP (call, 0, 0); | 2291 && SYMBOL_REF_DECL (sym) |
2367 if (GET_CODE (call) == SET) | 2292 && TREE_CODE (SYMBOL_REF_DECL (sym)) == FUNCTION_DECL |
2368 call = SET_SRC (call); | 2293 && DECL_BUILT_IN_CLASS (SYMBOL_REF_DECL (sym)) == BUILT_IN_NORMAL |
2369 if (GET_CODE (call) == CALL | 2294 && DECL_FUNCTION_CODE (SYMBOL_REF_DECL (sym)) == BUILT_IN_MEMSET) |
2370 && MEM_P (XEXP (call, 0)) | 2295 memset_call = SYMBOL_REF_DECL (sym); |
2371 && GET_CODE (XEXP (XEXP (call, 0), 0)) == SYMBOL_REF) | 2296 |
2372 { | |
2373 rtx symbol = XEXP (XEXP (call, 0), 0); | |
2374 if (SYMBOL_REF_DECL (symbol) | |
2375 && TREE_CODE (SYMBOL_REF_DECL (symbol)) == FUNCTION_DECL) | |
2376 { | |
2377 if ((DECL_BUILT_IN_CLASS (SYMBOL_REF_DECL (symbol)) | |
2378 == BUILT_IN_NORMAL | |
2379 && (DECL_FUNCTION_CODE (SYMBOL_REF_DECL (symbol)) | |
2380 == BUILT_IN_MEMSET)) | |
2381 || SYMBOL_REF_DECL (symbol) == block_clear_fn) | |
2382 memset_call = SYMBOL_REF_DECL (symbol); | |
2383 } | |
2384 } | |
2385 } | |
2386 if (const_call || memset_call) | 2297 if (const_call || memset_call) |
2387 { | 2298 { |
2388 insn_info_t i_ptr = active_local_stores; | 2299 insn_info_t i_ptr = active_local_stores; |
2389 insn_info_t last = NULL; | 2300 insn_info_t last = NULL; |
2390 | 2301 |
2391 if (dump_file) | 2302 if (dump_file && (dump_flags & TDF_DETAILS)) |
2392 fprintf (dump_file, "%s call %d\n", | 2303 fprintf (dump_file, "%s call %d\n", |
2393 const_call ? "const" : "memset", INSN_UID (insn)); | 2304 const_call ? "const" : "memset", INSN_UID (insn)); |
2394 | 2305 |
2395 /* See the head comment of the frame_read field. */ | 2306 /* See the head comment of the frame_read field. */ |
2396 if (reload_completed) | 2307 if (reload_completed |
2308 /* Tail calls are storing their arguments using | |
2309 arg pointer. If it is a frame pointer on the target, | |
2310 even before reload we need to kill frame pointer based | |
2311 stores. */ | |
2312 || (SIBLING_CALL_P (insn) | |
2313 && HARD_FRAME_POINTER_IS_ARG_POINTER)) | |
2397 insn_info->frame_read = true; | 2314 insn_info->frame_read = true; |
2398 | 2315 |
2399 /* Loop over the active stores and remove those which are | 2316 /* Loop over the active stores and remove those which are |
2400 killed by the const function call. */ | 2317 killed by the const function call. */ |
2401 while (i_ptr) | 2318 while (i_ptr) |
2407 remove_store = true; | 2324 remove_store = true; |
2408 | 2325 |
2409 /* If the frame is read, the frame related stores are killed. */ | 2326 /* If the frame is read, the frame related stores are killed. */ |
2410 else if (insn_info->frame_read) | 2327 else if (insn_info->frame_read) |
2411 { | 2328 { |
2412 store_info_t store_info = i_ptr->store_rec; | 2329 store_info *store_info = i_ptr->store_rec; |
2413 | 2330 |
2414 /* Skip the clobbers. */ | 2331 /* Skip the clobbers. */ |
2415 while (!store_info->is_set) | 2332 while (!store_info->is_set) |
2416 store_info = store_info->next; | 2333 store_info = store_info->next; |
2417 | 2334 |
2418 if (store_info->group_id >= 0 | 2335 if (store_info->group_id >= 0 |
2419 && VEC_index (group_info_t, rtx_group_vec, | 2336 && rtx_group_vec[store_info->group_id]->frame_related) |
2420 store_info->group_id)->frame_related) | |
2421 remove_store = true; | 2337 remove_store = true; |
2422 } | 2338 } |
2423 | 2339 |
2424 if (remove_store) | 2340 if (remove_store) |
2425 { | 2341 { |
2426 if (dump_file) | 2342 if (dump_file && (dump_flags & TDF_DETAILS)) |
2427 dump_insn_info ("removing from active", i_ptr); | 2343 dump_insn_info ("removing from active", i_ptr); |
2428 | 2344 |
2345 active_local_stores_len--; | |
2429 if (last) | 2346 if (last) |
2430 last->next_local_store = i_ptr->next_local_store; | 2347 last->next_local_store = i_ptr->next_local_store; |
2431 else | 2348 else |
2432 active_local_stores = i_ptr->next_local_store; | 2349 active_local_stores = i_ptr->next_local_store; |
2433 } | 2350 } |
2444 && CONST_INT_P (args[1]) | 2361 && CONST_INT_P (args[1]) |
2445 && CONST_INT_P (args[2]) | 2362 && CONST_INT_P (args[2]) |
2446 && INTVAL (args[2]) > 0) | 2363 && INTVAL (args[2]) > 0) |
2447 { | 2364 { |
2448 rtx mem = gen_rtx_MEM (BLKmode, args[0]); | 2365 rtx mem = gen_rtx_MEM (BLKmode, args[0]); |
2449 set_mem_size (mem, args[2]); | 2366 set_mem_size (mem, INTVAL (args[2])); |
2450 body = gen_rtx_SET (VOIDmode, mem, args[1]); | 2367 body = gen_rtx_SET (mem, args[1]); |
2451 mems_found += record_store (body, bb_info); | 2368 mems_found += record_store (body, bb_info); |
2452 if (dump_file) | 2369 if (dump_file && (dump_flags & TDF_DETAILS)) |
2453 fprintf (dump_file, "handling memset as BLKmode store\n"); | 2370 fprintf (dump_file, "handling memset as BLKmode store\n"); |
2454 if (mems_found == 1) | 2371 if (mems_found == 1) |
2455 { | 2372 { |
2373 if (active_local_stores_len++ | |
2374 >= PARAM_VALUE (PARAM_MAX_DSE_ACTIVE_LOCAL_STORES)) | |
2375 { | |
2376 active_local_stores_len = 1; | |
2377 active_local_stores = NULL; | |
2378 } | |
2379 insn_info->fixed_regs_live | |
2380 = copy_fixed_regs (bb_info->regs_live); | |
2456 insn_info->next_local_store = active_local_stores; | 2381 insn_info->next_local_store = active_local_stores; |
2457 active_local_stores = insn_info; | 2382 active_local_stores = insn_info; |
2458 } | 2383 } |
2459 } | 2384 } |
2385 else | |
2386 clear_rhs_from_active_local_stores (); | |
2460 } | 2387 } |
2461 } | 2388 } |
2462 | 2389 else if (SIBLING_CALL_P (insn) && reload_completed) |
2390 /* Arguments for a sibling call that are pushed to memory are passed | |
2391 using the incoming argument pointer of the current function. After | |
2392 reload that might be (and likely is) frame pointer based. */ | |
2393 add_wild_read (bb_info); | |
2463 else | 2394 else |
2464 /* Every other call, including pure functions, may read memory. */ | 2395 /* Every other call, including pure functions, may read any memory |
2465 add_wild_read (bb_info); | 2396 that is not relative to the frame. */ |
2397 add_non_frame_wild_read (bb_info); | |
2466 | 2398 |
2467 return; | 2399 return; |
2468 } | 2400 } |
2469 | 2401 |
2470 /* Assuming that there are sets in these insns, we cannot delete | 2402 /* Assuming that there are sets in these insns, we cannot delete |
2471 them. */ | 2403 them. */ |
2472 if ((GET_CODE (PATTERN (insn)) == CLOBBER) | 2404 if ((GET_CODE (PATTERN (insn)) == CLOBBER) |
2473 || volatile_refs_p (PATTERN (insn)) | 2405 || volatile_refs_p (PATTERN (insn)) |
2474 || insn_could_throw_p (insn) | 2406 || (!cfun->can_delete_dead_exceptions && !insn_nothrow_p (insn)) |
2475 || (RTX_FRAME_RELATED_P (insn)) | 2407 || (RTX_FRAME_RELATED_P (insn)) |
2476 || find_reg_note (insn, REG_FRAME_RELATED_EXPR, NULL_RTX)) | 2408 || find_reg_note (insn, REG_FRAME_RELATED_EXPR, NULL_RTX)) |
2477 insn_info->cannot_delete = true; | 2409 insn_info->cannot_delete = true; |
2478 | 2410 |
2479 body = PATTERN (insn); | 2411 body = PATTERN (insn); |
2484 mems_found += record_store (XVECEXP (body, 0, i), bb_info); | 2416 mems_found += record_store (XVECEXP (body, 0, i), bb_info); |
2485 } | 2417 } |
2486 else | 2418 else |
2487 mems_found += record_store (body, bb_info); | 2419 mems_found += record_store (body, bb_info); |
2488 | 2420 |
2489 if (dump_file) | 2421 if (dump_file && (dump_flags & TDF_DETAILS)) |
2490 fprintf (dump_file, "mems_found = %d, cannot_delete = %s\n", | 2422 fprintf (dump_file, "mems_found = %d, cannot_delete = %s\n", |
2491 mems_found, insn_info->cannot_delete ? "true" : "false"); | 2423 mems_found, insn_info->cannot_delete ? "true" : "false"); |
2492 | 2424 |
2493 /* If we found some sets of mems, add it into the active_local_stores so | 2425 /* If we found some sets of mems, add it into the active_local_stores so |
2494 that it can be locally deleted if found dead or used for | 2426 that it can be locally deleted if found dead or used for |
2495 replace_read and redundant constant store elimination. Otherwise mark | 2427 replace_read and redundant constant store elimination. Otherwise mark |
2496 it as cannot delete. This simplifies the processing later. */ | 2428 it as cannot delete. This simplifies the processing later. */ |
2497 if (mems_found == 1) | 2429 if (mems_found == 1) |
2498 { | 2430 { |
2431 if (active_local_stores_len++ | |
2432 >= PARAM_VALUE (PARAM_MAX_DSE_ACTIVE_LOCAL_STORES)) | |
2433 { | |
2434 active_local_stores_len = 1; | |
2435 active_local_stores = NULL; | |
2436 } | |
2437 insn_info->fixed_regs_live = copy_fixed_regs (bb_info->regs_live); | |
2499 insn_info->next_local_store = active_local_stores; | 2438 insn_info->next_local_store = active_local_stores; |
2500 active_local_stores = insn_info; | 2439 active_local_stores = insn_info; |
2501 } | 2440 } |
2502 else | 2441 else |
2503 insn_info->cannot_delete = true; | 2442 insn_info->cannot_delete = true; |
2514 insn_info_t insn_info = active_local_stores; | 2453 insn_info_t insn_info = active_local_stores; |
2515 insn_info_t last = NULL; | 2454 insn_info_t last = NULL; |
2516 | 2455 |
2517 while (insn_info) | 2456 while (insn_info) |
2518 { | 2457 { |
2519 store_info_t store_info = insn_info->store_rec; | 2458 store_info *store_info = insn_info->store_rec; |
2520 bool del = false; | 2459 bool del = false; |
2521 | 2460 |
2522 /* If ANY of the store_infos match the cselib group that is | 2461 /* If ANY of the store_infos match the cselib group that is |
2523 being deleted, then the insn can not be deleted. */ | 2462 being deleted, then the insn can not be deleted. */ |
2524 while (store_info) | 2463 while (store_info) |
2532 store_info = store_info->next; | 2471 store_info = store_info->next; |
2533 } | 2472 } |
2534 | 2473 |
2535 if (del) | 2474 if (del) |
2536 { | 2475 { |
2476 active_local_stores_len--; | |
2537 if (last) | 2477 if (last) |
2538 last->next_local_store = insn_info->next_local_store; | 2478 last->next_local_store = insn_info->next_local_store; |
2539 else | 2479 else |
2540 active_local_stores = insn_info->next_local_store; | 2480 active_local_stores = insn_info->next_local_store; |
2541 free_store_info (insn_info); | 2481 free_store_info (insn_info); |
2552 | 2492 |
2553 static void | 2493 static void |
2554 dse_step1 (void) | 2494 dse_step1 (void) |
2555 { | 2495 { |
2556 basic_block bb; | 2496 basic_block bb; |
2557 bitmap regs_live = BITMAP_ALLOC (NULL); | 2497 bitmap regs_live = BITMAP_ALLOC (®_obstack); |
2558 | 2498 |
2559 cselib_init (0); | 2499 cselib_init (0); |
2560 all_blocks = BITMAP_ALLOC (NULL); | 2500 all_blocks = BITMAP_ALLOC (NULL); |
2561 bitmap_set_bit (all_blocks, ENTRY_BLOCK); | 2501 bitmap_set_bit (all_blocks, ENTRY_BLOCK); |
2562 bitmap_set_bit (all_blocks, EXIT_BLOCK); | 2502 bitmap_set_bit (all_blocks, EXIT_BLOCK); |
2563 | 2503 |
2564 FOR_ALL_BB (bb) | 2504 FOR_ALL_BB_FN (bb, cfun) |
2565 { | 2505 { |
2566 insn_info_t ptr; | 2506 insn_info_t ptr; |
2567 bb_info_t bb_info = (bb_info_t) pool_alloc (bb_info_pool); | 2507 bb_info_t bb_info = dse_bb_info_type_pool.allocate (); |
2568 | 2508 |
2569 memset (bb_info, 0, sizeof (struct bb_info)); | 2509 memset (bb_info, 0, sizeof (dse_bb_info_type)); |
2570 bitmap_set_bit (all_blocks, bb->index); | 2510 bitmap_set_bit (all_blocks, bb->index); |
2571 bb_info->regs_live = regs_live; | 2511 bb_info->regs_live = regs_live; |
2572 | 2512 |
2573 bitmap_copy (regs_live, DF_LR_IN (bb)); | 2513 bitmap_copy (regs_live, DF_LR_IN (bb)); |
2574 df_simulate_initialize_forwards (bb, regs_live); | 2514 df_simulate_initialize_forwards (bb, regs_live); |
2576 bb_table[bb->index] = bb_info; | 2516 bb_table[bb->index] = bb_info; |
2577 cselib_discard_hook = remove_useless_values; | 2517 cselib_discard_hook = remove_useless_values; |
2578 | 2518 |
2579 if (bb->index >= NUM_FIXED_BLOCKS) | 2519 if (bb->index >= NUM_FIXED_BLOCKS) |
2580 { | 2520 { |
2581 rtx insn; | 2521 rtx_insn *insn; |
2582 | 2522 |
2583 cse_store_info_pool | |
2584 = create_alloc_pool ("cse_store_info_pool", | |
2585 sizeof (struct store_info), 100); | |
2586 active_local_stores = NULL; | 2523 active_local_stores = NULL; |
2524 active_local_stores_len = 0; | |
2587 cselib_clear_table (); | 2525 cselib_clear_table (); |
2588 | 2526 |
2589 /* Scan the insns. */ | 2527 /* Scan the insns. */ |
2590 FOR_BB_INSNS (bb, insn) | 2528 FOR_BB_INSNS (bb, insn) |
2591 { | 2529 { |
2606 stores at the end of the function and delete all of the | 2544 stores at the end of the function and delete all of the |
2607 frame and spill based ones. */ | 2545 frame and spill based ones. */ |
2608 if (stores_off_frame_dead_at_return | 2546 if (stores_off_frame_dead_at_return |
2609 && (EDGE_COUNT (bb->succs) == 0 | 2547 && (EDGE_COUNT (bb->succs) == 0 |
2610 || (single_succ_p (bb) | 2548 || (single_succ_p (bb) |
2611 && single_succ (bb) == EXIT_BLOCK_PTR | 2549 && single_succ (bb) == EXIT_BLOCK_PTR_FOR_FN (cfun) |
2612 && ! crtl->calls_eh_return))) | 2550 && ! crtl->calls_eh_return))) |
2613 { | 2551 { |
2614 insn_info_t i_ptr = active_local_stores; | 2552 insn_info_t i_ptr = active_local_stores; |
2615 while (i_ptr) | 2553 while (i_ptr) |
2616 { | 2554 { |
2617 store_info_t store_info = i_ptr->store_rec; | 2555 store_info *store_info = i_ptr->store_rec; |
2618 | 2556 |
2619 /* Skip the clobbers. */ | 2557 /* Skip the clobbers. */ |
2620 while (!store_info->is_set) | 2558 while (!store_info->is_set) |
2621 store_info = store_info->next; | 2559 store_info = store_info->next; |
2622 if (store_info->alias_set && !i_ptr->cannot_delete) | 2560 if (store_info->group_id >= 0) |
2623 delete_dead_store_insn (i_ptr); | 2561 { |
2624 else | 2562 group_info *group = rtx_group_vec[store_info->group_id]; |
2625 if (store_info->group_id >= 0) | 2563 if (group->frame_related && !i_ptr->cannot_delete) |
2626 { | 2564 delete_dead_store_insn (i_ptr); |
2627 group_info_t group | 2565 } |
2628 = VEC_index (group_info_t, rtx_group_vec, store_info->group_id); | |
2629 if (group->frame_related && !i_ptr->cannot_delete) | |
2630 delete_dead_store_insn (i_ptr); | |
2631 } | |
2632 | 2566 |
2633 i_ptr = i_ptr->next_local_store; | 2567 i_ptr = i_ptr->next_local_store; |
2634 } | 2568 } |
2635 } | 2569 } |
2636 | 2570 |
2637 /* Get rid of the loads that were discovered in | 2571 /* Get rid of the loads that were discovered in |
2638 replace_read. Cselib is finished with this block. */ | 2572 replace_read. Cselib is finished with this block. */ |
2639 while (deferred_change_list) | 2573 while (deferred_change_list) |
2640 { | 2574 { |
2641 deferred_change_t next = deferred_change_list->next; | 2575 deferred_change *next = deferred_change_list->next; |
2642 | 2576 |
2643 /* There is no reason to validate this change. That was | 2577 /* There is no reason to validate this change. That was |
2644 done earlier. */ | 2578 done earlier. */ |
2645 *deferred_change_list->loc = deferred_change_list->reg; | 2579 *deferred_change_list->loc = deferred_change_list->reg; |
2646 pool_free (deferred_change_pool, deferred_change_list); | 2580 deferred_change_pool.remove (deferred_change_list); |
2647 deferred_change_list = next; | 2581 deferred_change_list = next; |
2648 } | 2582 } |
2649 | 2583 |
2650 /* Get rid of all of the cselib based store_infos in this | 2584 /* Get rid of all of the cselib based store_infos in this |
2651 block and mark the containing insns as not being | 2585 block and mark the containing insns as not being |
2653 ptr = bb_info->last_insn; | 2587 ptr = bb_info->last_insn; |
2654 while (ptr) | 2588 while (ptr) |
2655 { | 2589 { |
2656 if (ptr->contains_cselib_groups) | 2590 if (ptr->contains_cselib_groups) |
2657 { | 2591 { |
2658 store_info_t s_info = ptr->store_rec; | 2592 store_info *s_info = ptr->store_rec; |
2659 while (s_info && !s_info->is_set) | 2593 while (s_info && !s_info->is_set) |
2660 s_info = s_info->next; | 2594 s_info = s_info->next; |
2661 if (s_info | 2595 if (s_info |
2662 && s_info->redundant_reason | 2596 && s_info->redundant_reason |
2663 && s_info->redundant_reason->insn | 2597 && s_info->redundant_reason->insn |
2664 && !ptr->cannot_delete) | 2598 && !ptr->cannot_delete) |
2665 { | 2599 { |
2666 if (dump_file) | 2600 if (dump_file && (dump_flags & TDF_DETAILS)) |
2667 fprintf (dump_file, "Locally deleting insn %d " | 2601 fprintf (dump_file, "Locally deleting insn %d " |
2668 "because insn %d stores the " | 2602 "because insn %d stores the " |
2669 "same value and couldn't be " | 2603 "same value and couldn't be " |
2670 "eliminated\n", | 2604 "eliminated\n", |
2671 INSN_UID (ptr->insn), | 2605 INSN_UID (ptr->insn), |
2672 INSN_UID (s_info->redundant_reason->insn)); | 2606 INSN_UID (s_info->redundant_reason->insn)); |
2673 delete_dead_store_insn (ptr); | 2607 delete_dead_store_insn (ptr); |
2674 } | 2608 } |
2675 if (s_info) | |
2676 s_info->redundant_reason = NULL; | |
2677 free_store_info (ptr); | 2609 free_store_info (ptr); |
2678 } | 2610 } |
2679 else | 2611 else |
2680 { | 2612 { |
2681 store_info_t s_info; | 2613 store_info *s_info; |
2682 | 2614 |
2683 /* Free at least positions_needed bitmaps. */ | 2615 /* Free at least positions_needed bitmaps. */ |
2684 for (s_info = ptr->store_rec; s_info; s_info = s_info->next) | 2616 for (s_info = ptr->store_rec; s_info; s_info = s_info->next) |
2685 if (s_info->is_large) | 2617 if (s_info->is_large) |
2686 { | 2618 { |
2689 } | 2621 } |
2690 } | 2622 } |
2691 ptr = ptr->prev_insn; | 2623 ptr = ptr->prev_insn; |
2692 } | 2624 } |
2693 | 2625 |
2694 free_alloc_pool (cse_store_info_pool); | 2626 cse_store_info_pool.release (); |
2695 } | 2627 } |
2696 bb_info->regs_live = NULL; | 2628 bb_info->regs_live = NULL; |
2697 } | 2629 } |
2698 | 2630 |
2699 BITMAP_FREE (regs_live); | 2631 BITMAP_FREE (regs_live); |
2700 cselib_finish (); | 2632 cselib_finish (); |
2701 htab_empty (rtx_group_table); | 2633 rtx_group_table->empty (); |
2702 } | 2634 } |
2703 | 2635 |
2704 | 2636 |
2705 /*---------------------------------------------------------------------------- | 2637 /*---------------------------------------------------------------------------- |
2706 Second step. | 2638 Second step. |
2712 | 2644 |
2713 static void | 2645 static void |
2714 dse_step2_init (void) | 2646 dse_step2_init (void) |
2715 { | 2647 { |
2716 unsigned int i; | 2648 unsigned int i; |
2717 group_info_t group; | 2649 group_info *group; |
2718 | 2650 |
2719 FOR_EACH_VEC_ELT (group_info_t, rtx_group_vec, i, group) | 2651 FOR_EACH_VEC_ELT (rtx_group_vec, i, group) |
2720 { | 2652 { |
2721 /* For all non stack related bases, we only consider a store to | 2653 /* For all non stack related bases, we only consider a store to |
2722 be deletable if there are two or more stores for that | 2654 be deletable if there are two or more stores for that |
2723 position. This is because it takes one store to make the | 2655 position. This is because it takes one store to make the |
2724 other store redundant. However, for the stores that are | 2656 other store redundant. However, for the stores that are |
2734 | 2666 |
2735 if (stores_off_frame_dead_at_return && group->frame_related) | 2667 if (stores_off_frame_dead_at_return && group->frame_related) |
2736 { | 2668 { |
2737 bitmap_ior_into (group->store2_n, group->store1_n); | 2669 bitmap_ior_into (group->store2_n, group->store1_n); |
2738 bitmap_ior_into (group->store2_p, group->store1_p); | 2670 bitmap_ior_into (group->store2_p, group->store1_p); |
2739 if (dump_file) | 2671 if (dump_file && (dump_flags & TDF_DETAILS)) |
2740 fprintf (dump_file, "group %d is frame related ", i); | 2672 fprintf (dump_file, "group %d is frame related ", i); |
2741 } | 2673 } |
2742 | 2674 |
2743 group->offset_map_size_n++; | 2675 group->offset_map_size_n++; |
2744 group->offset_map_n = XNEWVEC (int, group->offset_map_size_n); | 2676 group->offset_map_n = XOBNEWVEC (&dse_obstack, int, |
2677 group->offset_map_size_n); | |
2745 group->offset_map_size_p++; | 2678 group->offset_map_size_p++; |
2746 group->offset_map_p = XNEWVEC (int, group->offset_map_size_p); | 2679 group->offset_map_p = XOBNEWVEC (&dse_obstack, int, |
2680 group->offset_map_size_p); | |
2747 group->process_globally = false; | 2681 group->process_globally = false; |
2748 if (dump_file) | 2682 if (dump_file && (dump_flags & TDF_DETAILS)) |
2749 { | 2683 { |
2750 fprintf (dump_file, "group %d(%d+%d): ", i, | 2684 fprintf (dump_file, "group %d(%d+%d): ", i, |
2751 (int)bitmap_count_bits (group->store2_n), | 2685 (int)bitmap_count_bits (group->store2_n), |
2752 (int)bitmap_count_bits (group->store2_p)); | 2686 (int)bitmap_count_bits (group->store2_p)); |
2753 bitmap_print (dump_file, group->store2_n, "n ", " "); | 2687 bitmap_print (dump_file, group->store2_n, "n ", " "); |
2755 } | 2689 } |
2756 } | 2690 } |
2757 } | 2691 } |
2758 | 2692 |
2759 | 2693 |
2760 /* Init the offset tables for the normal case. */ | 2694 /* Init the offset tables. */ |
2761 | 2695 |
2762 static bool | 2696 static bool |
2763 dse_step2_nospill (void) | 2697 dse_step2 (void) |
2764 { | 2698 { |
2765 unsigned int i; | 2699 unsigned int i; |
2766 group_info_t group; | 2700 group_info *group; |
2767 /* Position 0 is unused because 0 is used in the maps to mean | 2701 /* Position 0 is unused because 0 is used in the maps to mean |
2768 unused. */ | 2702 unused. */ |
2769 current_position = 1; | 2703 current_position = 1; |
2770 | 2704 FOR_EACH_VEC_ELT (rtx_group_vec, i, group) |
2771 FOR_EACH_VEC_ELT (group_info_t, rtx_group_vec, i, group) | |
2772 { | 2705 { |
2773 bitmap_iterator bi; | 2706 bitmap_iterator bi; |
2774 unsigned int j; | 2707 unsigned int j; |
2775 | 2708 |
2776 if (group == clear_alias_group) | 2709 memset (group->offset_map_n, 0, sizeof (int) * group->offset_map_size_n); |
2777 continue; | 2710 memset (group->offset_map_p, 0, sizeof (int) * group->offset_map_size_p); |
2778 | |
2779 memset (group->offset_map_n, 0, sizeof(int) * group->offset_map_size_n); | |
2780 memset (group->offset_map_p, 0, sizeof(int) * group->offset_map_size_p); | |
2781 bitmap_clear (group->group_kill); | 2711 bitmap_clear (group->group_kill); |
2782 | 2712 |
2783 EXECUTE_IF_SET_IN_BITMAP (group->store2_n, 0, j, bi) | 2713 EXECUTE_IF_SET_IN_BITMAP (group->store2_n, 0, j, bi) |
2784 { | 2714 { |
2785 bitmap_set_bit (group->group_kill, current_position); | 2715 bitmap_set_bit (group->group_kill, current_position); |
2716 if (bitmap_bit_p (group->escaped_n, j)) | |
2717 bitmap_set_bit (kill_on_calls, current_position); | |
2786 group->offset_map_n[j] = current_position++; | 2718 group->offset_map_n[j] = current_position++; |
2787 group->process_globally = true; | 2719 group->process_globally = true; |
2788 } | 2720 } |
2789 EXECUTE_IF_SET_IN_BITMAP (group->store2_p, 0, j, bi) | 2721 EXECUTE_IF_SET_IN_BITMAP (group->store2_p, 0, j, bi) |
2790 { | 2722 { |
2791 bitmap_set_bit (group->group_kill, current_position); | 2723 bitmap_set_bit (group->group_kill, current_position); |
2724 if (bitmap_bit_p (group->escaped_p, j)) | |
2725 bitmap_set_bit (kill_on_calls, current_position); | |
2792 group->offset_map_p[j] = current_position++; | 2726 group->offset_map_p[j] = current_position++; |
2793 group->process_globally = true; | 2727 group->process_globally = true; |
2794 } | 2728 } |
2795 } | 2729 } |
2796 return current_position != 1; | |
2797 } | |
2798 | |
2799 | |
2800 /* Init the offset tables for the spill case. */ | |
2801 | |
2802 static bool | |
2803 dse_step2_spill (void) | |
2804 { | |
2805 unsigned int j; | |
2806 group_info_t group = clear_alias_group; | |
2807 bitmap_iterator bi; | |
2808 | |
2809 /* Position 0 is unused because 0 is used in the maps to mean | |
2810 unused. */ | |
2811 current_position = 1; | |
2812 | |
2813 if (dump_file) | |
2814 { | |
2815 bitmap_print (dump_file, clear_alias_sets, | |
2816 "clear alias sets ", "\n"); | |
2817 bitmap_print (dump_file, disqualified_clear_alias_sets, | |
2818 "disqualified clear alias sets ", "\n"); | |
2819 } | |
2820 | |
2821 memset (group->offset_map_n, 0, sizeof(int) * group->offset_map_size_n); | |
2822 memset (group->offset_map_p, 0, sizeof(int) * group->offset_map_size_p); | |
2823 bitmap_clear (group->group_kill); | |
2824 | |
2825 /* Remove the disqualified positions from the store2_p set. */ | |
2826 bitmap_and_compl_into (group->store2_p, disqualified_clear_alias_sets); | |
2827 | |
2828 /* We do not need to process the store2_n set because | |
2829 alias_sets are always positive. */ | |
2830 EXECUTE_IF_SET_IN_BITMAP (group->store2_p, 0, j, bi) | |
2831 { | |
2832 bitmap_set_bit (group->group_kill, current_position); | |
2833 group->offset_map_p[j] = current_position++; | |
2834 group->process_globally = true; | |
2835 } | |
2836 | |
2837 return current_position != 1; | 2730 return current_position != 1; |
2838 } | 2731 } |
2839 | 2732 |
2840 | 2733 |
2841 | 2734 |
2844 | 2737 |
2845 Build the bit vectors for the transfer functions. | 2738 Build the bit vectors for the transfer functions. |
2846 ----------------------------------------------------------------------------*/ | 2739 ----------------------------------------------------------------------------*/ |
2847 | 2740 |
2848 | 2741 |
2849 /* Note that this is NOT a general purpose function. Any mem that has | |
2850 an alias set registered here expected to be COMPLETELY unaliased: | |
2851 i.e it's addresses are not and need not be examined. | |
2852 | |
2853 It is known that all references to this address will have this | |
2854 alias set and there are NO other references to this address in the | |
2855 function. | |
2856 | |
2857 Currently the only place that is known to be clean enough to use | |
2858 this interface is the code that assigns the spill locations. | |
2859 | |
2860 All of the mems that have alias_sets registered are subjected to a | |
2861 very powerful form of dse where function calls, volatile reads and | |
2862 writes, and reads from random location are not taken into account. | |
2863 | |
2864 It is also assumed that these locations go dead when the function | |
2865 returns. This assumption could be relaxed if there were found to | |
2866 be places that this assumption was not correct. | |
2867 | |
2868 The MODE is passed in and saved. The mode of each load or store to | |
2869 a mem with ALIAS_SET is checked against MEM. If the size of that | |
2870 load or store is different from MODE, processing is halted on this | |
2871 alias set. For the vast majority of aliases sets, all of the loads | |
2872 and stores will use the same mode. But vectors are treated | |
2873 differently: the alias set is established for the entire vector, | |
2874 but reload will insert loads and stores for individual elements and | |
2875 we do not necessarily have the information to track those separate | |
2876 elements. So when we see a mode mismatch, we just bail. */ | |
2877 | |
2878 | |
2879 void | |
2880 dse_record_singleton_alias_set (alias_set_type alias_set, | |
2881 enum machine_mode mode) | |
2882 { | |
2883 struct clear_alias_mode_holder tmp_holder; | |
2884 struct clear_alias_mode_holder *entry; | |
2885 void **slot; | |
2886 | |
2887 /* If we are not going to run dse, we need to return now or there | |
2888 will be problems with allocating the bitmaps. */ | |
2889 if ((!gate_dse()) || !alias_set) | |
2890 return; | |
2891 | |
2892 if (!clear_alias_sets) | |
2893 { | |
2894 clear_alias_sets = BITMAP_ALLOC (NULL); | |
2895 disqualified_clear_alias_sets = BITMAP_ALLOC (NULL); | |
2896 clear_alias_mode_table = htab_create (11, clear_alias_mode_hash, | |
2897 clear_alias_mode_eq, NULL); | |
2898 clear_alias_mode_pool = create_alloc_pool ("clear_alias_mode_pool", | |
2899 sizeof (struct clear_alias_mode_holder), 100); | |
2900 } | |
2901 | |
2902 bitmap_set_bit (clear_alias_sets, alias_set); | |
2903 | |
2904 tmp_holder.alias_set = alias_set; | |
2905 | |
2906 slot = htab_find_slot (clear_alias_mode_table, &tmp_holder, INSERT); | |
2907 gcc_assert (*slot == NULL); | |
2908 | |
2909 *slot = entry = | |
2910 (struct clear_alias_mode_holder *) pool_alloc (clear_alias_mode_pool); | |
2911 entry->alias_set = alias_set; | |
2912 entry->mode = mode; | |
2913 } | |
2914 | |
2915 | |
2916 /* Remove ALIAS_SET from the sets of stack slots being considered. */ | |
2917 | |
2918 void | |
2919 dse_invalidate_singleton_alias_set (alias_set_type alias_set) | |
2920 { | |
2921 if ((!gate_dse()) || !alias_set) | |
2922 return; | |
2923 | |
2924 bitmap_clear_bit (clear_alias_sets, alias_set); | |
2925 } | |
2926 | |
2927 | |
2928 /* Look up the bitmap index for OFFSET in GROUP_INFO. If it is not | 2742 /* Look up the bitmap index for OFFSET in GROUP_INFO. If it is not |
2929 there, return 0. */ | 2743 there, return 0. */ |
2930 | 2744 |
2931 static int | 2745 static int |
2932 get_bitmap_index (group_info_t group_info, HOST_WIDE_INT offset) | 2746 get_bitmap_index (group_info *group_info, HOST_WIDE_INT offset) |
2933 { | 2747 { |
2934 if (offset < 0) | 2748 if (offset < 0) |
2935 { | 2749 { |
2936 HOST_WIDE_INT offset_p = -offset; | 2750 HOST_WIDE_INT offset_p = -offset; |
2937 if (offset_p >= group_info->offset_map_size_n) | 2751 if (offset_p >= group_info->offset_map_size_n) |
2949 | 2763 |
2950 /* Process the STORE_INFOs into the bitmaps into GEN and KILL. KILL | 2764 /* Process the STORE_INFOs into the bitmaps into GEN and KILL. KILL |
2951 may be NULL. */ | 2765 may be NULL. */ |
2952 | 2766 |
2953 static void | 2767 static void |
2954 scan_stores_nospill (store_info_t store_info, bitmap gen, bitmap kill) | 2768 scan_stores (store_info *store_info, bitmap gen, bitmap kill) |
2955 { | 2769 { |
2956 while (store_info) | 2770 while (store_info) |
2957 { | 2771 { |
2958 HOST_WIDE_INT i; | 2772 HOST_WIDE_INT i; |
2959 group_info_t group_info | 2773 group_info *group_info |
2960 = VEC_index (group_info_t, rtx_group_vec, store_info->group_id); | 2774 = rtx_group_vec[store_info->group_id]; |
2961 if (group_info->process_globally) | 2775 if (group_info->process_globally) |
2962 for (i = store_info->begin; i < store_info->end; i++) | 2776 for (i = store_info->begin; i < store_info->end; i++) |
2963 { | 2777 { |
2964 int index = get_bitmap_index (group_info, i); | 2778 int index = get_bitmap_index (group_info, i); |
2965 if (index != 0) | 2779 if (index != 0) |
2972 store_info = store_info->next; | 2786 store_info = store_info->next; |
2973 } | 2787 } |
2974 } | 2788 } |
2975 | 2789 |
2976 | 2790 |
2977 /* Process the STORE_INFOs into the bitmaps into GEN and KILL. KILL | |
2978 may be NULL. */ | |
2979 | |
2980 static void | |
2981 scan_stores_spill (store_info_t store_info, bitmap gen, bitmap kill) | |
2982 { | |
2983 while (store_info) | |
2984 { | |
2985 if (store_info->alias_set) | |
2986 { | |
2987 int index = get_bitmap_index (clear_alias_group, | |
2988 store_info->alias_set); | |
2989 if (index != 0) | |
2990 { | |
2991 bitmap_set_bit (gen, index); | |
2992 if (kill) | |
2993 bitmap_clear_bit (kill, index); | |
2994 } | |
2995 } | |
2996 store_info = store_info->next; | |
2997 } | |
2998 } | |
2999 | |
3000 | |
3001 /* Process the READ_INFOs into the bitmaps into GEN and KILL. KILL | 2791 /* Process the READ_INFOs into the bitmaps into GEN and KILL. KILL |
3002 may be NULL. */ | 2792 may be NULL. */ |
3003 | 2793 |
3004 static void | 2794 static void |
3005 scan_reads_nospill (insn_info_t insn_info, bitmap gen, bitmap kill) | 2795 scan_reads (insn_info_t insn_info, bitmap gen, bitmap kill) |
3006 { | 2796 { |
3007 read_info_t read_info = insn_info->read_rec; | 2797 read_info_t read_info = insn_info->read_rec; |
3008 int i; | 2798 int i; |
3009 group_info_t group; | 2799 group_info *group; |
3010 | 2800 |
3011 /* If this insn reads the frame, kill all the frame related stores. */ | 2801 /* If this insn reads the frame, kill all the frame related stores. */ |
3012 if (insn_info->frame_read) | 2802 if (insn_info->frame_read) |
3013 { | 2803 { |
3014 FOR_EACH_VEC_ELT (group_info_t, rtx_group_vec, i, group) | 2804 FOR_EACH_VEC_ELT (rtx_group_vec, i, group) |
3015 if (group->process_globally && group->frame_related) | 2805 if (group->process_globally && group->frame_related) |
3016 { | 2806 { |
3017 if (kill) | 2807 if (kill) |
3018 bitmap_ior_into (kill, group->group_kill); | 2808 bitmap_ior_into (kill, group->group_kill); |
3019 bitmap_and_compl_into (gen, group->group_kill); | 2809 bitmap_and_compl_into (gen, group->group_kill); |
3020 } | 2810 } |
3021 } | 2811 } |
3022 | 2812 if (insn_info->non_frame_wild_read) |
2813 { | |
2814 /* Kill all non-frame related stores. Kill all stores of variables that | |
2815 escape. */ | |
2816 if (kill) | |
2817 bitmap_ior_into (kill, kill_on_calls); | |
2818 bitmap_and_compl_into (gen, kill_on_calls); | |
2819 FOR_EACH_VEC_ELT (rtx_group_vec, i, group) | |
2820 if (group->process_globally && !group->frame_related) | |
2821 { | |
2822 if (kill) | |
2823 bitmap_ior_into (kill, group->group_kill); | |
2824 bitmap_and_compl_into (gen, group->group_kill); | |
2825 } | |
2826 } | |
3023 while (read_info) | 2827 while (read_info) |
3024 { | 2828 { |
3025 FOR_EACH_VEC_ELT (group_info_t, rtx_group_vec, i, group) | 2829 FOR_EACH_VEC_ELT (rtx_group_vec, i, group) |
3026 { | 2830 { |
3027 if (group->process_globally) | 2831 if (group->process_globally) |
3028 { | 2832 { |
3029 if (i == read_info->group_id) | 2833 if (i == read_info->group_id) |
3030 { | 2834 { |
3062 base. */ | 2866 base. */ |
3063 if ((read_info->group_id < 0) | 2867 if ((read_info->group_id < 0) |
3064 && canon_true_dependence (group->base_mem, | 2868 && canon_true_dependence (group->base_mem, |
3065 GET_MODE (group->base_mem), | 2869 GET_MODE (group->base_mem), |
3066 group->canon_base_addr, | 2870 group->canon_base_addr, |
3067 read_info->mem, NULL_RTX, | 2871 read_info->mem, NULL_RTX)) |
3068 rtx_varies_p)) | |
3069 { | 2872 { |
3070 if (kill) | 2873 if (kill) |
3071 bitmap_ior_into (kill, group->group_kill); | 2874 bitmap_ior_into (kill, group->group_kill); |
3072 bitmap_and_compl_into (gen, group->group_kill); | 2875 bitmap_and_compl_into (gen, group->group_kill); |
3073 } | 2876 } |
3077 | 2880 |
3078 read_info = read_info->next; | 2881 read_info = read_info->next; |
3079 } | 2882 } |
3080 } | 2883 } |
3081 | 2884 |
3082 /* Process the READ_INFOs into the bitmaps into GEN and KILL. KILL | |
3083 may be NULL. */ | |
3084 | |
3085 static void | |
3086 scan_reads_spill (read_info_t read_info, bitmap gen, bitmap kill) | |
3087 { | |
3088 while (read_info) | |
3089 { | |
3090 if (read_info->alias_set) | |
3091 { | |
3092 int index = get_bitmap_index (clear_alias_group, | |
3093 read_info->alias_set); | |
3094 if (index != 0) | |
3095 { | |
3096 if (kill) | |
3097 bitmap_set_bit (kill, index); | |
3098 bitmap_clear_bit (gen, index); | |
3099 } | |
3100 } | |
3101 | |
3102 read_info = read_info->next; | |
3103 } | |
3104 } | |
3105 | |
3106 | 2885 |
3107 /* Return the insn in BB_INFO before the first wild read or if there | 2886 /* Return the insn in BB_INFO before the first wild read or if there |
3108 are no wild reads in the block, return the last insn. */ | 2887 are no wild reads in the block, return the last insn. */ |
3109 | 2888 |
3110 static insn_info_t | 2889 static insn_info_t |
3139 the first insn with a wild read. In the latter case we are able to | 2918 the first insn with a wild read. In the latter case we are able to |
3140 skip the rest of the block because it just does not matter: | 2919 skip the rest of the block because it just does not matter: |
3141 anything that happens is hidden by the wild read. */ | 2920 anything that happens is hidden by the wild read. */ |
3142 | 2921 |
3143 static void | 2922 static void |
3144 dse_step3_scan (bool for_spills, basic_block bb) | 2923 dse_step3_scan (basic_block bb) |
3145 { | 2924 { |
3146 bb_info_t bb_info = bb_table[bb->index]; | 2925 bb_info_t bb_info = bb_table[bb->index]; |
3147 insn_info_t insn_info; | 2926 insn_info_t insn_info; |
3148 | 2927 |
3149 if (for_spills) | 2928 insn_info = find_insn_before_first_wild_read (bb_info); |
3150 /* There are no wild reads in the spill case. */ | |
3151 insn_info = bb_info->last_insn; | |
3152 else | |
3153 insn_info = find_insn_before_first_wild_read (bb_info); | |
3154 | 2929 |
3155 /* In the spill case or in the no_spill case if there is no wild | 2930 /* In the spill case or in the no_spill case if there is no wild |
3156 read in the block, we will need a kill set. */ | 2931 read in the block, we will need a kill set. */ |
3157 if (insn_info == bb_info->last_insn) | 2932 if (insn_info == bb_info->last_insn) |
3158 { | 2933 { |
3159 if (bb_info->kill) | 2934 if (bb_info->kill) |
3160 bitmap_clear (bb_info->kill); | 2935 bitmap_clear (bb_info->kill); |
3161 else | 2936 else |
3162 bb_info->kill = BITMAP_ALLOC (NULL); | 2937 bb_info->kill = BITMAP_ALLOC (&dse_bitmap_obstack); |
3163 } | 2938 } |
3164 else | 2939 else |
3165 if (bb_info->kill) | 2940 if (bb_info->kill) |
3166 BITMAP_FREE (bb_info->kill); | 2941 BITMAP_FREE (bb_info->kill); |
3167 | 2942 |
3169 { | 2944 { |
3170 /* There may have been code deleted by the dce pass run before | 2945 /* There may have been code deleted by the dce pass run before |
3171 this phase. */ | 2946 this phase. */ |
3172 if (insn_info->insn && INSN_P (insn_info->insn)) | 2947 if (insn_info->insn && INSN_P (insn_info->insn)) |
3173 { | 2948 { |
3174 /* Process the read(s) last. */ | 2949 scan_stores (insn_info->store_rec, bb_info->gen, bb_info->kill); |
3175 if (for_spills) | 2950 scan_reads (insn_info, bb_info->gen, bb_info->kill); |
3176 { | |
3177 scan_stores_spill (insn_info->store_rec, bb_info->gen, bb_info->kill); | |
3178 scan_reads_spill (insn_info->read_rec, bb_info->gen, bb_info->kill); | |
3179 } | |
3180 else | |
3181 { | |
3182 scan_stores_nospill (insn_info->store_rec, bb_info->gen, bb_info->kill); | |
3183 scan_reads_nospill (insn_info, bb_info->gen, bb_info->kill); | |
3184 } | |
3185 } | 2951 } |
3186 | 2952 |
3187 insn_info = insn_info->prev_insn; | 2953 insn_info = insn_info->prev_insn; |
3188 } | 2954 } |
3189 } | 2955 } |
3199 frame_pointer_group. */ | 2965 frame_pointer_group. */ |
3200 | 2966 |
3201 if (stores_off_frame_dead_at_return) | 2967 if (stores_off_frame_dead_at_return) |
3202 { | 2968 { |
3203 unsigned int i; | 2969 unsigned int i; |
3204 group_info_t group; | 2970 group_info *group; |
3205 | 2971 |
3206 FOR_EACH_VEC_ELT (group_info_t, rtx_group_vec, i, group) | 2972 FOR_EACH_VEC_ELT (rtx_group_vec, i, group) |
3207 { | 2973 { |
3208 if (group->process_globally && group->frame_related) | 2974 if (group->process_globally && group->frame_related) |
3209 bitmap_ior_into (bb_info->gen, group->group_kill); | 2975 bitmap_ior_into (bb_info->gen, group->group_kill); |
3210 } | 2976 } |
3211 } | 2977 } |
3221 mark_reachable_blocks (sbitmap unreachable_blocks, basic_block bb) | 2987 mark_reachable_blocks (sbitmap unreachable_blocks, basic_block bb) |
3222 { | 2988 { |
3223 edge e; | 2989 edge e; |
3224 edge_iterator ei; | 2990 edge_iterator ei; |
3225 | 2991 |
3226 if (TEST_BIT (unreachable_blocks, bb->index)) | 2992 if (bitmap_bit_p (unreachable_blocks, bb->index)) |
3227 { | 2993 { |
3228 RESET_BIT (unreachable_blocks, bb->index); | 2994 bitmap_clear_bit (unreachable_blocks, bb->index); |
3229 FOR_EACH_EDGE (e, ei, bb->preds) | 2995 FOR_EACH_EDGE (e, ei, bb->preds) |
3230 { | 2996 { |
3231 mark_reachable_blocks (unreachable_blocks, e->src); | 2997 mark_reachable_blocks (unreachable_blocks, e->src); |
3232 } | 2998 } |
3233 } | 2999 } |
3234 } | 3000 } |
3235 | 3001 |
3236 /* Build the transfer functions for the function. */ | 3002 /* Build the transfer functions for the function. */ |
3237 | 3003 |
3238 static void | 3004 static void |
3239 dse_step3 (bool for_spills) | 3005 dse_step3 () |
3240 { | 3006 { |
3241 basic_block bb; | 3007 basic_block bb; |
3242 sbitmap unreachable_blocks = sbitmap_alloc (last_basic_block); | |
3243 sbitmap_iterator sbi; | 3008 sbitmap_iterator sbi; |
3244 bitmap all_ones = NULL; | 3009 bitmap all_ones = NULL; |
3245 unsigned int i; | 3010 unsigned int i; |
3246 | 3011 |
3247 sbitmap_ones (unreachable_blocks); | 3012 auto_sbitmap unreachable_blocks (last_basic_block_for_fn (cfun)); |
3248 | 3013 bitmap_ones (unreachable_blocks); |
3249 FOR_ALL_BB (bb) | 3014 |
3015 FOR_ALL_BB_FN (bb, cfun) | |
3250 { | 3016 { |
3251 bb_info_t bb_info = bb_table[bb->index]; | 3017 bb_info_t bb_info = bb_table[bb->index]; |
3252 if (bb_info->gen) | 3018 if (bb_info->gen) |
3253 bitmap_clear (bb_info->gen); | 3019 bitmap_clear (bb_info->gen); |
3254 else | 3020 else |
3255 bb_info->gen = BITMAP_ALLOC (NULL); | 3021 bb_info->gen = BITMAP_ALLOC (&dse_bitmap_obstack); |
3256 | 3022 |
3257 if (bb->index == ENTRY_BLOCK) | 3023 if (bb->index == ENTRY_BLOCK) |
3258 ; | 3024 ; |
3259 else if (bb->index == EXIT_BLOCK) | 3025 else if (bb->index == EXIT_BLOCK) |
3260 dse_step3_exit_block_scan (bb_info); | 3026 dse_step3_exit_block_scan (bb_info); |
3261 else | 3027 else |
3262 dse_step3_scan (for_spills, bb); | 3028 dse_step3_scan (bb); |
3263 if (EDGE_COUNT (bb->succs) == 0) | 3029 if (EDGE_COUNT (bb->succs) == 0) |
3264 mark_reachable_blocks (unreachable_blocks, bb); | 3030 mark_reachable_blocks (unreachable_blocks, bb); |
3265 | 3031 |
3266 /* If this is the second time dataflow is run, delete the old | 3032 /* If this is the second time dataflow is run, delete the old |
3267 sets. */ | 3033 sets. */ |
3272 } | 3038 } |
3273 | 3039 |
3274 /* For any block in an infinite loop, we must initialize the out set | 3040 /* For any block in an infinite loop, we must initialize the out set |
3275 to all ones. This could be expensive, but almost never occurs in | 3041 to all ones. This could be expensive, but almost never occurs in |
3276 practice. However, it is common in regression tests. */ | 3042 practice. However, it is common in regression tests. */ |
3277 EXECUTE_IF_SET_IN_SBITMAP (unreachable_blocks, 0, i, sbi) | 3043 EXECUTE_IF_SET_IN_BITMAP (unreachable_blocks, 0, i, sbi) |
3278 { | 3044 { |
3279 if (bitmap_bit_p (all_blocks, i)) | 3045 if (bitmap_bit_p (all_blocks, i)) |
3280 { | 3046 { |
3281 bb_info_t bb_info = bb_table[i]; | 3047 bb_info_t bb_info = bb_table[i]; |
3282 if (!all_ones) | 3048 if (!all_ones) |
3283 { | 3049 { |
3284 unsigned int j; | 3050 unsigned int j; |
3285 group_info_t group; | 3051 group_info *group; |
3286 | 3052 |
3287 all_ones = BITMAP_ALLOC (NULL); | 3053 all_ones = BITMAP_ALLOC (&dse_bitmap_obstack); |
3288 FOR_EACH_VEC_ELT (group_info_t, rtx_group_vec, j, group) | 3054 FOR_EACH_VEC_ELT (rtx_group_vec, j, group) |
3289 bitmap_ior_into (all_ones, group->group_kill); | 3055 bitmap_ior_into (all_ones, group->group_kill); |
3290 } | 3056 } |
3291 if (!bb_info->out) | 3057 if (!bb_info->out) |
3292 { | 3058 { |
3293 bb_info->out = BITMAP_ALLOC (NULL); | 3059 bb_info->out = BITMAP_ALLOC (&dse_bitmap_obstack); |
3294 bitmap_copy (bb_info->out, all_ones); | 3060 bitmap_copy (bb_info->out, all_ones); |
3295 } | 3061 } |
3296 } | 3062 } |
3297 } | 3063 } |
3298 | 3064 |
3299 if (all_ones) | 3065 if (all_ones) |
3300 BITMAP_FREE (all_ones); | 3066 BITMAP_FREE (all_ones); |
3301 sbitmap_free (unreachable_blocks); | |
3302 } | 3067 } |
3303 | 3068 |
3304 | 3069 |
3305 | 3070 |
3306 /*---------------------------------------------------------------------------- | 3071 /*---------------------------------------------------------------------------- |
3324 if (bb->index == EXIT_BLOCK) | 3089 if (bb->index == EXIT_BLOCK) |
3325 return; | 3090 return; |
3326 | 3091 |
3327 if (!bb_info->out) | 3092 if (!bb_info->out) |
3328 { | 3093 { |
3329 bb_info->out = BITMAP_ALLOC (NULL); | 3094 bb_info->out = BITMAP_ALLOC (&dse_bitmap_obstack); |
3330 bitmap_copy (bb_info->out, bb_table[EXIT_BLOCK]->gen); | 3095 bitmap_copy (bb_info->out, bb_table[EXIT_BLOCK]->gen); |
3331 } | 3096 } |
3332 } | 3097 } |
3333 | 3098 |
3334 /* Propagate the information from the in set of the dest of E to the | 3099 /* Propagate the information from the in set of the dest of E to the |
3345 { | 3110 { |
3346 if (src_info->out) | 3111 if (src_info->out) |
3347 bitmap_and_into (src_info->out, dest_info->in); | 3112 bitmap_and_into (src_info->out, dest_info->in); |
3348 else | 3113 else |
3349 { | 3114 { |
3350 src_info->out = BITMAP_ALLOC (NULL); | 3115 src_info->out = BITMAP_ALLOC (&dse_bitmap_obstack); |
3351 bitmap_copy (src_info->out, dest_info->in); | 3116 bitmap_copy (src_info->out, dest_info->in); |
3352 } | 3117 } |
3353 } | 3118 } |
3354 return true; | 3119 return true; |
3355 } | 3120 } |
3384 if (bb_info->in) | 3149 if (bb_info->in) |
3385 return bitmap_ior_and_compl (bb_info->in, bb_info->gen, | 3150 return bitmap_ior_and_compl (bb_info->in, bb_info->gen, |
3386 bb_info->out, bb_info->kill); | 3151 bb_info->out, bb_info->kill); |
3387 else | 3152 else |
3388 { | 3153 { |
3389 bb_info->in = BITMAP_ALLOC (NULL); | 3154 bb_info->in = BITMAP_ALLOC (&dse_bitmap_obstack); |
3390 bitmap_ior_and_compl (bb_info->in, bb_info->gen, | 3155 bitmap_ior_and_compl (bb_info->in, bb_info->gen, |
3391 bb_info->out, bb_info->kill); | 3156 bb_info->out, bb_info->kill); |
3392 return true; | 3157 return true; |
3393 } | 3158 } |
3394 } | 3159 } |
3402 happens. */ | 3167 happens. */ |
3403 if (bb_info->in) | 3168 if (bb_info->in) |
3404 return false; | 3169 return false; |
3405 else | 3170 else |
3406 { | 3171 { |
3407 bb_info->in = BITMAP_ALLOC (NULL); | 3172 bb_info->in = BITMAP_ALLOC (&dse_bitmap_obstack); |
3408 bitmap_copy (bb_info->in, bb_info->gen); | 3173 bitmap_copy (bb_info->in, bb_info->gen); |
3409 return true; | 3174 return true; |
3410 } | 3175 } |
3411 } | 3176 } |
3412 } | 3177 } |
3418 { | 3183 { |
3419 df_simple_dataflow (DF_BACKWARD, NULL, dse_confluence_0, | 3184 df_simple_dataflow (DF_BACKWARD, NULL, dse_confluence_0, |
3420 dse_confluence_n, dse_transfer_function, | 3185 dse_confluence_n, dse_transfer_function, |
3421 all_blocks, df_get_postorder (DF_BACKWARD), | 3186 all_blocks, df_get_postorder (DF_BACKWARD), |
3422 df_get_n_blocks (DF_BACKWARD)); | 3187 df_get_n_blocks (DF_BACKWARD)); |
3423 if (dump_file) | 3188 if (dump_file && (dump_flags & TDF_DETAILS)) |
3424 { | 3189 { |
3425 basic_block bb; | 3190 basic_block bb; |
3426 | 3191 |
3427 fprintf (dump_file, "\n\n*** Global dataflow info after analysis.\n"); | 3192 fprintf (dump_file, "\n\n*** Global dataflow info after analysis.\n"); |
3428 FOR_ALL_BB (bb) | 3193 FOR_ALL_BB_FN (bb, cfun) |
3429 { | 3194 { |
3430 bb_info_t bb_info = bb_table[bb->index]; | 3195 bb_info_t bb_info = bb_table[bb->index]; |
3431 | 3196 |
3432 df_print_bb_index (bb, dump_file); | 3197 df_print_bb_index (bb, dump_file); |
3433 if (bb_info->in) | 3198 if (bb_info->in) |
3458 Delete the stores that can only be deleted using the global information. | 3223 Delete the stores that can only be deleted using the global information. |
3459 ----------------------------------------------------------------------------*/ | 3224 ----------------------------------------------------------------------------*/ |
3460 | 3225 |
3461 | 3226 |
3462 static void | 3227 static void |
3463 dse_step5_nospill (void) | 3228 dse_step5 (void) |
3464 { | 3229 { |
3465 basic_block bb; | 3230 basic_block bb; |
3466 FOR_EACH_BB (bb) | 3231 FOR_EACH_BB_FN (bb, cfun) |
3467 { | 3232 { |
3468 bb_info_t bb_info = bb_table[bb->index]; | 3233 bb_info_t bb_info = bb_table[bb->index]; |
3469 insn_info_t insn_info = bb_info->last_insn; | 3234 insn_info_t insn_info = bb_info->last_insn; |
3470 bitmap v = bb_info->out; | 3235 bitmap v = bb_info->out; |
3471 | 3236 |
3484 if (insn_info->insn | 3249 if (insn_info->insn |
3485 && INSN_P (insn_info->insn) | 3250 && INSN_P (insn_info->insn) |
3486 && (!insn_info->cannot_delete) | 3251 && (!insn_info->cannot_delete) |
3487 && (!bitmap_empty_p (v))) | 3252 && (!bitmap_empty_p (v))) |
3488 { | 3253 { |
3489 store_info_t store_info = insn_info->store_rec; | 3254 store_info *store_info = insn_info->store_rec; |
3490 | 3255 |
3491 /* Try to delete the current insn. */ | 3256 /* Try to delete the current insn. */ |
3492 deleted = true; | 3257 deleted = true; |
3493 | 3258 |
3494 /* Skip the clobbers. */ | 3259 /* Skip the clobbers. */ |
3495 while (!store_info->is_set) | 3260 while (!store_info->is_set) |
3496 store_info = store_info->next; | 3261 store_info = store_info->next; |
3497 | 3262 |
3498 if (store_info->alias_set) | 3263 HOST_WIDE_INT i; |
3499 deleted = false; | 3264 group_info *group_info = rtx_group_vec[store_info->group_id]; |
3500 else | 3265 |
3266 for (i = store_info->begin; i < store_info->end; i++) | |
3501 { | 3267 { |
3502 HOST_WIDE_INT i; | 3268 int index = get_bitmap_index (group_info, i); |
3503 group_info_t group_info | 3269 |
3504 = VEC_index (group_info_t, rtx_group_vec, store_info->group_id); | 3270 if (dump_file && (dump_flags & TDF_DETAILS)) |
3505 | 3271 fprintf (dump_file, "i = %d, index = %d\n", (int)i, index); |
3506 for (i = store_info->begin; i < store_info->end; i++) | 3272 if (index == 0 || !bitmap_bit_p (v, index)) |
3507 { | 3273 { |
3508 int index = get_bitmap_index (group_info, i); | 3274 if (dump_file && (dump_flags & TDF_DETAILS)) |
3509 | 3275 fprintf (dump_file, "failing at i = %d\n", (int)i); |
3510 if (dump_file) | 3276 deleted = false; |
3511 fprintf (dump_file, "i = %d, index = %d\n", (int)i, index); | 3277 break; |
3512 if (index == 0 || !bitmap_bit_p (v, index)) | |
3513 { | |
3514 if (dump_file) | |
3515 fprintf (dump_file, "failing at i = %d\n", (int)i); | |
3516 deleted = false; | |
3517 break; | |
3518 } | |
3519 } | 3278 } |
3520 } | 3279 } |
3521 if (deleted) | 3280 if (deleted) |
3522 { | 3281 { |
3523 if (dbg_cnt (dse)) | 3282 if (dbg_cnt (dse) |
3283 && check_for_inc_dec_1 (insn_info)) | |
3524 { | 3284 { |
3525 check_for_inc_dec (insn_info->insn); | |
3526 delete_insn (insn_info->insn); | 3285 delete_insn (insn_info->insn); |
3527 insn_info->insn = NULL; | 3286 insn_info->insn = NULL; |
3528 globally_deleted++; | 3287 globally_deleted++; |
3529 } | 3288 } |
3530 } | 3289 } |
3534 no longer need to trash the info. */ | 3293 no longer need to trash the info. */ |
3535 if (insn_info->insn | 3294 if (insn_info->insn |
3536 && INSN_P (insn_info->insn) | 3295 && INSN_P (insn_info->insn) |
3537 && (!deleted)) | 3296 && (!deleted)) |
3538 { | 3297 { |
3539 scan_stores_nospill (insn_info->store_rec, v, NULL); | 3298 scan_stores (insn_info->store_rec, v, NULL); |
3540 if (insn_info->wild_read) | 3299 if (insn_info->wild_read) |
3541 { | 3300 { |
3542 if (dump_file) | 3301 if (dump_file && (dump_flags & TDF_DETAILS)) |
3543 fprintf (dump_file, "wild read\n"); | 3302 fprintf (dump_file, "wild read\n"); |
3544 bitmap_clear (v); | 3303 bitmap_clear (v); |
3545 } | 3304 } |
3546 else if (insn_info->read_rec) | 3305 else if (insn_info->read_rec |
3306 || insn_info->non_frame_wild_read | |
3307 || insn_info->frame_read) | |
3547 { | 3308 { |
3548 if (dump_file) | 3309 if (dump_file && (dump_flags & TDF_DETAILS)) |
3549 fprintf (dump_file, "regular read\n"); | 3310 { |
3550 scan_reads_nospill (insn_info, v, NULL); | 3311 if (!insn_info->non_frame_wild_read |
3312 && !insn_info->frame_read) | |
3313 fprintf (dump_file, "regular read\n"); | |
3314 if (insn_info->non_frame_wild_read) | |
3315 fprintf (dump_file, "non-frame wild read\n"); | |
3316 if (insn_info->frame_read) | |
3317 fprintf (dump_file, "frame read\n"); | |
3318 } | |
3319 scan_reads (insn_info, v, NULL); | |
3551 } | 3320 } |
3552 } | |
3553 | |
3554 insn_info = insn_info->prev_insn; | |
3555 } | |
3556 } | |
3557 } | |
3558 | |
3559 | |
3560 static void | |
3561 dse_step5_spill (void) | |
3562 { | |
3563 basic_block bb; | |
3564 FOR_EACH_BB (bb) | |
3565 { | |
3566 bb_info_t bb_info = bb_table[bb->index]; | |
3567 insn_info_t insn_info = bb_info->last_insn; | |
3568 bitmap v = bb_info->out; | |
3569 | |
3570 while (insn_info) | |
3571 { | |
3572 bool deleted = false; | |
3573 /* There may have been code deleted by the dce pass run before | |
3574 this phase. */ | |
3575 if (insn_info->insn | |
3576 && INSN_P (insn_info->insn) | |
3577 && (!insn_info->cannot_delete) | |
3578 && (!bitmap_empty_p (v))) | |
3579 { | |
3580 /* Try to delete the current insn. */ | |
3581 store_info_t store_info = insn_info->store_rec; | |
3582 deleted = true; | |
3583 | |
3584 while (store_info) | |
3585 { | |
3586 if (store_info->alias_set) | |
3587 { | |
3588 int index = get_bitmap_index (clear_alias_group, | |
3589 store_info->alias_set); | |
3590 if (index == 0 || !bitmap_bit_p (v, index)) | |
3591 { | |
3592 deleted = false; | |
3593 break; | |
3594 } | |
3595 } | |
3596 else | |
3597 deleted = false; | |
3598 store_info = store_info->next; | |
3599 } | |
3600 if (deleted && dbg_cnt (dse)) | |
3601 { | |
3602 if (dump_file) | |
3603 fprintf (dump_file, "Spill deleting insn %d\n", | |
3604 INSN_UID (insn_info->insn)); | |
3605 check_for_inc_dec (insn_info->insn); | |
3606 delete_insn (insn_info->insn); | |
3607 spill_deleted++; | |
3608 insn_info->insn = NULL; | |
3609 } | |
3610 } | |
3611 | |
3612 if (insn_info->insn | |
3613 && INSN_P (insn_info->insn) | |
3614 && (!deleted)) | |
3615 { | |
3616 scan_stores_spill (insn_info->store_rec, v, NULL); | |
3617 scan_reads_spill (insn_info->read_rec, v, NULL); | |
3618 } | 3321 } |
3619 | 3322 |
3620 insn_info = insn_info->prev_insn; | 3323 insn_info = insn_info->prev_insn; |
3621 } | 3324 } |
3622 } | 3325 } |
3634 static void | 3337 static void |
3635 dse_step6 (void) | 3338 dse_step6 (void) |
3636 { | 3339 { |
3637 basic_block bb; | 3340 basic_block bb; |
3638 | 3341 |
3639 FOR_ALL_BB (bb) | 3342 FOR_ALL_BB_FN (bb, cfun) |
3640 { | 3343 { |
3641 bb_info_t bb_info = bb_table[bb->index]; | 3344 bb_info_t bb_info = bb_table[bb->index]; |
3642 insn_info_t insn_info = bb_info->last_insn; | 3345 insn_info_t insn_info = bb_info->last_insn; |
3643 | 3346 |
3644 while (insn_info) | 3347 while (insn_info) |
3647 this phase. */ | 3350 this phase. */ |
3648 if (insn_info->insn | 3351 if (insn_info->insn |
3649 && INSN_P (insn_info->insn) | 3352 && INSN_P (insn_info->insn) |
3650 && !insn_info->cannot_delete) | 3353 && !insn_info->cannot_delete) |
3651 { | 3354 { |
3652 store_info_t s_info = insn_info->store_rec; | 3355 store_info *s_info = insn_info->store_rec; |
3653 | 3356 |
3654 while (s_info && !s_info->is_set) | 3357 while (s_info && !s_info->is_set) |
3655 s_info = s_info->next; | 3358 s_info = s_info->next; |
3656 if (s_info | 3359 if (s_info |
3657 && s_info->redundant_reason | 3360 && s_info->redundant_reason |
3658 && s_info->redundant_reason->insn | 3361 && s_info->redundant_reason->insn |
3659 && INSN_P (s_info->redundant_reason->insn)) | 3362 && INSN_P (s_info->redundant_reason->insn)) |
3660 { | 3363 { |
3661 rtx rinsn = s_info->redundant_reason->insn; | 3364 rtx_insn *rinsn = s_info->redundant_reason->insn; |
3662 if (dump_file) | 3365 if (dump_file && (dump_flags & TDF_DETAILS)) |
3663 fprintf (dump_file, "Locally deleting insn %d " | 3366 fprintf (dump_file, "Locally deleting insn %d " |
3664 "because insn %d stores the " | 3367 "because insn %d stores the " |
3665 "same value and couldn't be " | 3368 "same value and couldn't be " |
3666 "eliminated\n", | 3369 "eliminated\n", |
3667 INSN_UID (insn_info->insn), | 3370 INSN_UID (insn_info->insn), |
3679 | 3382 |
3680 Destroy everything left standing. | 3383 Destroy everything left standing. |
3681 ----------------------------------------------------------------------------*/ | 3384 ----------------------------------------------------------------------------*/ |
3682 | 3385 |
3683 static void | 3386 static void |
3684 dse_step7 (bool global_done) | 3387 dse_step7 (void) |
3685 { | 3388 { |
3686 unsigned int i; | 3389 bitmap_obstack_release (&dse_bitmap_obstack); |
3687 group_info_t group; | 3390 obstack_free (&dse_obstack, NULL); |
3688 basic_block bb; | |
3689 | |
3690 FOR_EACH_VEC_ELT (group_info_t, rtx_group_vec, i, group) | |
3691 { | |
3692 free (group->offset_map_n); | |
3693 free (group->offset_map_p); | |
3694 BITMAP_FREE (group->store1_n); | |
3695 BITMAP_FREE (group->store1_p); | |
3696 BITMAP_FREE (group->store2_n); | |
3697 BITMAP_FREE (group->store2_p); | |
3698 BITMAP_FREE (group->group_kill); | |
3699 } | |
3700 | |
3701 if (global_done) | |
3702 FOR_ALL_BB (bb) | |
3703 { | |
3704 bb_info_t bb_info = bb_table[bb->index]; | |
3705 BITMAP_FREE (bb_info->gen); | |
3706 if (bb_info->kill) | |
3707 BITMAP_FREE (bb_info->kill); | |
3708 if (bb_info->in) | |
3709 BITMAP_FREE (bb_info->in); | |
3710 if (bb_info->out) | |
3711 BITMAP_FREE (bb_info->out); | |
3712 } | |
3713 | |
3714 if (clear_alias_sets) | |
3715 { | |
3716 BITMAP_FREE (clear_alias_sets); | |
3717 BITMAP_FREE (disqualified_clear_alias_sets); | |
3718 free_alloc_pool (clear_alias_mode_pool); | |
3719 htab_delete (clear_alias_mode_table); | |
3720 } | |
3721 | 3391 |
3722 end_alias_analysis (); | 3392 end_alias_analysis (); |
3723 free (bb_table); | 3393 free (bb_table); |
3724 htab_delete (rtx_group_table); | 3394 delete rtx_group_table; |
3725 VEC_free (group_info_t, heap, rtx_group_vec); | 3395 rtx_group_table = NULL; |
3396 rtx_group_vec.release (); | |
3726 BITMAP_FREE (all_blocks); | 3397 BITMAP_FREE (all_blocks); |
3727 BITMAP_FREE (scratch); | 3398 BITMAP_FREE (scratch); |
3728 | 3399 |
3729 free_alloc_pool (rtx_store_info_pool); | 3400 rtx_store_info_pool.release (); |
3730 free_alloc_pool (read_info_pool); | 3401 read_info_type_pool.release (); |
3731 free_alloc_pool (insn_info_pool); | 3402 insn_info_type_pool.release (); |
3732 free_alloc_pool (bb_info_pool); | 3403 dse_bb_info_type_pool.release (); |
3733 free_alloc_pool (rtx_group_info_pool); | 3404 group_info_pool.release (); |
3734 free_alloc_pool (deferred_change_pool); | 3405 deferred_change_pool.release (); |
3735 } | 3406 } |
3736 | 3407 |
3737 | 3408 |
3738 /* ------------------------------------------------------------------------- | 3409 /* ------------------------------------------------------------------------- |
3739 DSE | 3410 DSE |
3742 /* Callback for running pass_rtl_dse. */ | 3413 /* Callback for running pass_rtl_dse. */ |
3743 | 3414 |
3744 static unsigned int | 3415 static unsigned int |
3745 rest_of_handle_dse (void) | 3416 rest_of_handle_dse (void) |
3746 { | 3417 { |
3747 bool did_global = false; | |
3748 | |
3749 df_set_flags (DF_DEFER_INSN_RESCAN); | 3418 df_set_flags (DF_DEFER_INSN_RESCAN); |
3750 | 3419 |
3751 /* Need the notes since we must track live hardregs in the forwards | 3420 /* Need the notes since we must track live hardregs in the forwards |
3752 direction. */ | 3421 direction. */ |
3753 df_note_add_problem (); | 3422 df_note_add_problem (); |
3754 df_analyze (); | 3423 df_analyze (); |
3755 | 3424 |
3756 dse_step0 (); | 3425 dse_step0 (); |
3757 dse_step1 (); | 3426 dse_step1 (); |
3758 dse_step2_init (); | 3427 dse_step2_init (); |
3759 if (dse_step2_nospill ()) | 3428 if (dse_step2 ()) |
3760 { | 3429 { |
3761 df_set_flags (DF_LR_RUN_DCE); | 3430 df_set_flags (DF_LR_RUN_DCE); |
3762 df_analyze (); | 3431 df_analyze (); |
3763 did_global = true; | 3432 if (dump_file && (dump_flags & TDF_DETAILS)) |
3764 if (dump_file) | |
3765 fprintf (dump_file, "doing global processing\n"); | 3433 fprintf (dump_file, "doing global processing\n"); |
3766 dse_step3 (false); | 3434 dse_step3 (); |
3767 dse_step4 (); | 3435 dse_step4 (); |
3768 dse_step5_nospill (); | 3436 dse_step5 (); |
3769 } | |
3770 | |
3771 /* For the instance of dse that runs after reload, we make a special | |
3772 pass to process the spills. These are special in that they are | |
3773 totally transparent, i.e, there is no aliasing issues that need | |
3774 to be considered. This means that the wild reads that kill | |
3775 everything else do not apply here. */ | |
3776 if (clear_alias_sets && dse_step2_spill ()) | |
3777 { | |
3778 if (!did_global) | |
3779 { | |
3780 df_set_flags (DF_LR_RUN_DCE); | |
3781 df_analyze (); | |
3782 } | |
3783 did_global = true; | |
3784 if (dump_file) | |
3785 fprintf (dump_file, "doing global spill processing\n"); | |
3786 dse_step3 (true); | |
3787 dse_step4 (); | |
3788 dse_step5_spill (); | |
3789 } | 3437 } |
3790 | 3438 |
3791 dse_step6 (); | 3439 dse_step6 (); |
3792 dse_step7 (did_global); | 3440 dse_step7 (); |
3793 | 3441 |
3794 if (dump_file) | 3442 if (dump_file) |
3795 fprintf (dump_file, "dse: local deletions = %d, global deletions = %d, spill deletions = %d\n", | 3443 fprintf (dump_file, "dse: local deletions = %d, global deletions = %d\n", |
3796 locally_deleted, globally_deleted, spill_deleted); | 3444 locally_deleted, globally_deleted); |
3445 | |
3446 /* DSE can eliminate potentially-trapping MEMs. | |
3447 Remove any EH edges associated with them. */ | |
3448 if ((locally_deleted || globally_deleted) | |
3449 && cfun->can_throw_non_call_exceptions | |
3450 && purge_all_dead_edges ()) | |
3451 cleanup_cfg (0); | |
3452 | |
3797 return 0; | 3453 return 0; |
3798 } | 3454 } |
3799 | 3455 |
3800 static bool | 3456 namespace { |
3801 gate_dse (void) | 3457 |
3802 { | 3458 const pass_data pass_data_rtl_dse1 = |
3803 return gate_dse1 () || gate_dse2 (); | 3459 { |
3804 } | 3460 RTL_PASS, /* type */ |
3805 | 3461 "dse1", /* name */ |
3806 static bool | 3462 OPTGROUP_NONE, /* optinfo_flags */ |
3807 gate_dse1 (void) | 3463 TV_DSE1, /* tv_id */ |
3808 { | 3464 0, /* properties_required */ |
3809 return optimize > 0 && flag_dse | 3465 0, /* properties_provided */ |
3810 && dbg_cnt (dse1); | 3466 0, /* properties_destroyed */ |
3811 } | 3467 0, /* todo_flags_start */ |
3812 | 3468 TODO_df_finish, /* todo_flags_finish */ |
3813 static bool | |
3814 gate_dse2 (void) | |
3815 { | |
3816 return optimize > 0 && flag_dse | |
3817 && dbg_cnt (dse2); | |
3818 } | |
3819 | |
3820 struct rtl_opt_pass pass_rtl_dse1 = | |
3821 { | |
3822 { | |
3823 RTL_PASS, | |
3824 "dse1", /* name */ | |
3825 gate_dse1, /* gate */ | |
3826 rest_of_handle_dse, /* execute */ | |
3827 NULL, /* sub */ | |
3828 NULL, /* next */ | |
3829 0, /* static_pass_number */ | |
3830 TV_DSE1, /* tv_id */ | |
3831 0, /* properties_required */ | |
3832 0, /* properties_provided */ | |
3833 0, /* properties_destroyed */ | |
3834 0, /* todo_flags_start */ | |
3835 TODO_dump_func | | |
3836 TODO_df_finish | TODO_verify_rtl_sharing | | |
3837 TODO_ggc_collect /* todo_flags_finish */ | |
3838 } | |
3839 }; | 3469 }; |
3840 | 3470 |
3841 struct rtl_opt_pass pass_rtl_dse2 = | 3471 class pass_rtl_dse1 : public rtl_opt_pass |
3842 { | 3472 { |
3843 { | 3473 public: |
3844 RTL_PASS, | 3474 pass_rtl_dse1 (gcc::context *ctxt) |
3845 "dse2", /* name */ | 3475 : rtl_opt_pass (pass_data_rtl_dse1, ctxt) |
3846 gate_dse2, /* gate */ | 3476 {} |
3847 rest_of_handle_dse, /* execute */ | 3477 |
3848 NULL, /* sub */ | 3478 /* opt_pass methods: */ |
3849 NULL, /* next */ | 3479 virtual bool gate (function *) |
3850 0, /* static_pass_number */ | 3480 { |
3851 TV_DSE2, /* tv_id */ | 3481 return optimize > 0 && flag_dse && dbg_cnt (dse1); |
3852 0, /* properties_required */ | 3482 } |
3853 0, /* properties_provided */ | 3483 |
3854 0, /* properties_destroyed */ | 3484 virtual unsigned int execute (function *) { return rest_of_handle_dse (); } |
3855 0, /* todo_flags_start */ | 3485 |
3856 TODO_dump_func | | 3486 }; // class pass_rtl_dse1 |
3857 TODO_df_finish | TODO_verify_rtl_sharing | | 3487 |
3858 TODO_ggc_collect /* todo_flags_finish */ | 3488 } // anon namespace |
3859 } | 3489 |
3490 rtl_opt_pass * | |
3491 make_pass_rtl_dse1 (gcc::context *ctxt) | |
3492 { | |
3493 return new pass_rtl_dse1 (ctxt); | |
3494 } | |
3495 | |
3496 namespace { | |
3497 | |
3498 const pass_data pass_data_rtl_dse2 = | |
3499 { | |
3500 RTL_PASS, /* type */ | |
3501 "dse2", /* name */ | |
3502 OPTGROUP_NONE, /* optinfo_flags */ | |
3503 TV_DSE2, /* tv_id */ | |
3504 0, /* properties_required */ | |
3505 0, /* properties_provided */ | |
3506 0, /* properties_destroyed */ | |
3507 0, /* todo_flags_start */ | |
3508 TODO_df_finish, /* todo_flags_finish */ | |
3860 }; | 3509 }; |
3510 | |
3511 class pass_rtl_dse2 : public rtl_opt_pass | |
3512 { | |
3513 public: | |
3514 pass_rtl_dse2 (gcc::context *ctxt) | |
3515 : rtl_opt_pass (pass_data_rtl_dse2, ctxt) | |
3516 {} | |
3517 | |
3518 /* opt_pass methods: */ | |
3519 virtual bool gate (function *) | |
3520 { | |
3521 return optimize > 0 && flag_dse && dbg_cnt (dse2); | |
3522 } | |
3523 | |
3524 virtual unsigned int execute (function *) { return rest_of_handle_dse (); } | |
3525 | |
3526 }; // class pass_rtl_dse2 | |
3527 | |
3528 } // anon namespace | |
3529 | |
3530 rtl_opt_pass * | |
3531 make_pass_rtl_dse2 (gcc::context *ctxt) | |
3532 { | |
3533 return new pass_rtl_dse2 (ctxt); | |
3534 } |