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