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