Bug Summary

File:build/gcc/combine.c
Warning:line 3279, column 7
Value stored to 'i2_is_used' is never read

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name combine.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -analyzer-config-compatibility-mode=true -mrelocation-model static -mframe-pointer=none -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -tune-cpu generic -debugger-tuning=gdb -fcoverage-compilation-dir=/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/objdir/gcc -resource-dir /usr/lib64/clang/13.0.0 -D IN_GCC -D HAVE_CONFIG_H -I . -I . -I /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc -I /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/. -I /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../include -I /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libcpp/include -I /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libcody -I /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libdecnumber -I /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libdecnumber/bid -I ../libdecnumber -I /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/../libbacktrace -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/11/../../../../include/c++/11 -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/11/../../../../include/c++/11/x86_64-suse-linux -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/11/../../../../include/c++/11/backward -internal-isystem /usr/lib64/clang/13.0.0/include -internal-isystem /usr/local/include -internal-isystem /usr/bin/../lib64/gcc/x86_64-suse-linux/11/../../../../x86_64-suse-linux/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O2 -Wno-narrowing -Wwrite-strings -Wno-error=format-diag -Wno-long-long -Wno-variadic-macros -Wno-overlength-strings -fdeprecated-macro -fdebug-compilation-dir=/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/objdir/gcc -ferror-limit 19 -fno-rtti -fgnuc-version=4.2.1 -vectorize-loops -vectorize-slp -analyzer-output=plist-html -analyzer-config silence-checkers=core.NullDereference -faddrsig -D__GCC_HAVE_DWARF2_CFI_ASM=1 -o /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/objdir/clang-static-analyzer/2021-11-20-133755-20252-1/report-QVvYnx.plist -x c++ /home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/combine.c
1/* Optimize by combining instructions for GNU compiler.
2 Copyright (C) 1987-2021 Free Software Foundation, Inc.
3
4This file is part of GCC.
5
6GCC is free software; you can redistribute it and/or modify it under
7the terms of the GNU General Public License as published by the Free
8Software Foundation; either version 3, or (at your option) any later
9version.
10
11GCC is distributed in the hope that it will be useful, but WITHOUT ANY
12WARRANTY; without even the implied warranty of MERCHANTABILITY or
13FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14for more details.
15
16You should have received a copy of the GNU General Public License
17along with GCC; see the file COPYING3. If not see
18<http://www.gnu.org/licenses/>. */
19
20/* This module is essentially the "combiner" phase of the U. of Arizona
21 Portable Optimizer, but redone to work on our list-structured
22 representation for RTL instead of their string representation.
23
24 The LOG_LINKS of each insn identify the most recent assignment
25 to each REG used in the insn. It is a list of previous insns,
26 each of which contains a SET for a REG that is used in this insn
27 and not used or set in between. LOG_LINKs never cross basic blocks.
28 They were set up by the preceding pass (lifetime analysis).
29
30 We try to combine each pair of insns joined by a logical link.
31 We also try to combine triplets of insns A, B and C when C has
32 a link back to B and B has a link back to A. Likewise for a
33 small number of quadruplets of insns A, B, C and D for which
34 there's high likelihood of success.
35
36 We check (with modified_between_p) to avoid combining in such a way
37 as to move a computation to a place where its value would be different.
38
39 Combination is done by mathematically substituting the previous
40 insn(s) values for the regs they set into the expressions in
41 the later insns that refer to these regs. If the result is a valid insn
42 for our target machine, according to the machine description,
43 we install it, delete the earlier insns, and update the data flow
44 information (LOG_LINKS and REG_NOTES) for what we did.
45
46 There are a few exceptions where the dataflow information isn't
47 completely updated (however this is only a local issue since it is
48 regenerated before the next pass that uses it):
49
50 - reg_live_length is not updated
51 - reg_n_refs is not adjusted in the rare case when a register is
52 no longer required in a computation
53 - there are extremely rare cases (see distribute_notes) when a
54 REG_DEAD note is lost
55 - a LOG_LINKS entry that refers to an insn with multiple SETs may be
56 removed because there is no way to know which register it was
57 linking
58
59 To simplify substitution, we combine only when the earlier insn(s)
60 consist of only a single assignment. To simplify updating afterward,
61 we never combine when a subroutine call appears in the middle. */
62
63#include "config.h"
64#include "system.h"
65#include "coretypes.h"
66#include "backend.h"
67#include "target.h"
68#include "rtl.h"
69#include "tree.h"
70#include "cfghooks.h"
71#include "predict.h"
72#include "df.h"
73#include "memmodel.h"
74#include "tm_p.h"
75#include "optabs.h"
76#include "regs.h"
77#include "emit-rtl.h"
78#include "recog.h"
79#include "cgraph.h"
80#include "stor-layout.h"
81#include "cfgrtl.h"
82#include "cfgcleanup.h"
83/* Include expr.h after insn-config.h so we get HAVE_conditional_move. */
84#include "explow.h"
85#include "insn-attr.h"
86#include "rtlhooks-def.h"
87#include "expr.h"
88#include "tree-pass.h"
89#include "valtrack.h"
90#include "rtl-iter.h"
91#include "print-rtl.h"
92#include "function-abi.h"
93#include "rtlanal.h"
94
95/* Number of attempts to combine instructions in this function. */
96
97static int combine_attempts;
98
99/* Number of attempts that got as far as substitution in this function. */
100
101static int combine_merges;
102
103/* Number of instructions combined with added SETs in this function. */
104
105static int combine_extras;
106
107/* Number of instructions combined in this function. */
108
109static int combine_successes;
110
111/* Totals over entire compilation. */
112
113static int total_attempts, total_merges, total_extras, total_successes;
114
115/* combine_instructions may try to replace the right hand side of the
116 second instruction with the value of an associated REG_EQUAL note
117 before throwing it at try_combine. That is problematic when there
118 is a REG_DEAD note for a register used in the old right hand side
119 and can cause distribute_notes to do wrong things. This is the
120 second instruction if it has been so modified, null otherwise. */
121
122static rtx_insn *i2mod;
123
124/* When I2MOD is nonnull, this is a copy of the old right hand side. */
125
126static rtx i2mod_old_rhs;
127
128/* When I2MOD is nonnull, this is a copy of the new right hand side. */
129
130static rtx i2mod_new_rhs;
131
132struct reg_stat_type {
133 /* Record last point of death of (hard or pseudo) register n. */
134 rtx_insn *last_death;
135
136 /* Record last point of modification of (hard or pseudo) register n. */
137 rtx_insn *last_set;
138
139 /* The next group of fields allows the recording of the last value assigned
140 to (hard or pseudo) register n. We use this information to see if an
141 operation being processed is redundant given a prior operation performed
142 on the register. For example, an `and' with a constant is redundant if
143 all the zero bits are already known to be turned off.
144
145 We use an approach similar to that used by cse, but change it in the
146 following ways:
147
148 (1) We do not want to reinitialize at each label.
149 (2) It is useful, but not critical, to know the actual value assigned
150 to a register. Often just its form is helpful.
151
152 Therefore, we maintain the following fields:
153
154 last_set_value the last value assigned
155 last_set_label records the value of label_tick when the
156 register was assigned
157 last_set_table_tick records the value of label_tick when a
158 value using the register is assigned
159 last_set_invalid set to nonzero when it is not valid
160 to use the value of this register in some
161 register's value
162
163 To understand the usage of these tables, it is important to understand
164 the distinction between the value in last_set_value being valid and
165 the register being validly contained in some other expression in the
166 table.
167
168 (The next two parameters are out of date).
169
170 reg_stat[i].last_set_value is valid if it is nonzero, and either
171 reg_n_sets[i] is 1 or reg_stat[i].last_set_label == label_tick.
172
173 Register I may validly appear in any expression returned for the value
174 of another register if reg_n_sets[i] is 1. It may also appear in the
175 value for register J if reg_stat[j].last_set_invalid is zero, or
176 reg_stat[i].last_set_label < reg_stat[j].last_set_label.
177
178 If an expression is found in the table containing a register which may
179 not validly appear in an expression, the register is replaced by
180 something that won't match, (clobber (const_int 0)). */
181
182 /* Record last value assigned to (hard or pseudo) register n. */
183
184 rtx last_set_value;
185
186 /* Record the value of label_tick when an expression involving register n
187 is placed in last_set_value. */
188
189 int last_set_table_tick;
190
191 /* Record the value of label_tick when the value for register n is placed in
192 last_set_value. */
193
194 int last_set_label;
195
196 /* These fields are maintained in parallel with last_set_value and are
197 used to store the mode in which the register was last set, the bits
198 that were known to be zero when it was last set, and the number of
199 sign bits copies it was known to have when it was last set. */
200
201 unsigned HOST_WIDE_INTlong last_set_nonzero_bits;
202 char last_set_sign_bit_copies;
203 ENUM_BITFIELD(machine_mode)enum machine_mode last_set_mode : 8;
204
205 /* Set nonzero if references to register n in expressions should not be
206 used. last_set_invalid is set nonzero when this register is being
207 assigned to and last_set_table_tick == label_tick. */
208
209 char last_set_invalid;
210
211 /* Some registers that are set more than once and used in more than one
212 basic block are nevertheless always set in similar ways. For example,
213 a QImode register may be loaded from memory in two places on a machine
214 where byte loads zero extend.
215
216 We record in the following fields if a register has some leading bits
217 that are always equal to the sign bit, and what we know about the
218 nonzero bits of a register, specifically which bits are known to be
219 zero.
220
221 If an entry is zero, it means that we don't know anything special. */
222
223 unsigned char sign_bit_copies;
224
225 unsigned HOST_WIDE_INTlong nonzero_bits;
226
227 /* Record the value of the label_tick when the last truncation
228 happened. The field truncated_to_mode is only valid if
229 truncation_label == label_tick. */
230
231 int truncation_label;
232
233 /* Record the last truncation seen for this register. If truncation
234 is not a nop to this mode we might be able to save an explicit
235 truncation if we know that value already contains a truncated
236 value. */
237
238 ENUM_BITFIELD(machine_mode)enum machine_mode truncated_to_mode : 8;
239};
240
241
242static vec<reg_stat_type> reg_stat;
243
244/* One plus the highest pseudo for which we track REG_N_SETS.
245 regstat_init_n_sets_and_refs allocates the array for REG_N_SETS just once,
246 but during combine_split_insns new pseudos can be created. As we don't have
247 updated DF information in that case, it is hard to initialize the array
248 after growing. The combiner only cares about REG_N_SETS (regno) == 1,
249 so instead of growing the arrays, just assume all newly created pseudos
250 during combine might be set multiple times. */
251
252static unsigned int reg_n_sets_max;
253
254/* Record the luid of the last insn that invalidated memory
255 (anything that writes memory, and subroutine calls, but not pushes). */
256
257static int mem_last_set;
258
259/* Record the luid of the last CALL_INSN
260 so we can tell whether a potential combination crosses any calls. */
261
262static int last_call_luid;
263
264/* When `subst' is called, this is the insn that is being modified
265 (by combining in a previous insn). The PATTERN of this insn
266 is still the old pattern partially modified and it should not be
267 looked at, but this may be used to examine the successors of the insn
268 to judge whether a simplification is valid. */
269
270static rtx_insn *subst_insn;
271
272/* This is the lowest LUID that `subst' is currently dealing with.
273 get_last_value will not return a value if the register was set at or
274 after this LUID. If not for this mechanism, we could get confused if
275 I2 or I1 in try_combine were an insn that used the old value of a register
276 to obtain a new value. In that case, we might erroneously get the
277 new value of the register when we wanted the old one. */
278
279static int subst_low_luid;
280
281/* This contains any hard registers that are used in newpat; reg_dead_at_p
282 must consider all these registers to be always live. */
283
284static HARD_REG_SET newpat_used_regs;
285
286/* This is an insn to which a LOG_LINKS entry has been added. If this
287 insn is the earlier than I2 or I3, combine should rescan starting at
288 that location. */
289
290static rtx_insn *added_links_insn;
291
292/* And similarly, for notes. */
293
294static rtx_insn *added_notes_insn;
295
296/* Basic block in which we are performing combines. */
297static basic_block this_basic_block;
298static bool optimize_this_for_speed_p;
299
300
301/* Length of the currently allocated uid_insn_cost array. */
302
303static int max_uid_known;
304
305/* The following array records the insn_cost for every insn
306 in the instruction stream. */
307
308static int *uid_insn_cost;
309
310/* The following array records the LOG_LINKS for every insn in the
311 instruction stream as struct insn_link pointers. */
312
313struct insn_link {
314 rtx_insn *insn;
315 unsigned int regno;
316 struct insn_link *next;
317};
318
319static struct insn_link **uid_log_links;
320
321static inline int
322insn_uid_check (const_rtx insn)
323{
324 int uid = INSN_UID (insn);
325 gcc_checking_assert (uid <= max_uid_known)((void)(!(uid <= max_uid_known) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/combine.c"
, 325, __FUNCTION__), 0 : 0))
;
326 return uid;
327}
328
329#define INSN_COST(INSN)(uid_insn_cost[insn_uid_check (INSN)]) (uid_insn_cost[insn_uid_check (INSN)])
330#define LOG_LINKS(INSN)(uid_log_links[insn_uid_check (INSN)]) (uid_log_links[insn_uid_check (INSN)])
331
332#define FOR_EACH_LOG_LINK(L, INSN)for ((L) = (uid_log_links[insn_uid_check (INSN)]); (L); (L) =
(L)->next)
\
333 for ((L) = LOG_LINKS (INSN)(uid_log_links[insn_uid_check (INSN)]); (L); (L) = (L)->next)
334
335/* Links for LOG_LINKS are allocated from this obstack. */
336
337static struct obstack insn_link_obstack;
338
339/* Allocate a link. */
340
341static inline struct insn_link *
342alloc_insn_link (rtx_insn *insn, unsigned int regno, struct insn_link *next)
343{
344 struct insn_link *l
345 = (struct insn_link *) obstack_alloc (&insn_link_obstack,__extension__ ({ struct obstack *__h = (&insn_link_obstack
); __extension__ ({ struct obstack *__o = (__h); size_t __len
= ((sizeof (struct insn_link))); if (__extension__ ({ struct
obstack const *__o1 = (__o); (size_t) (__o1->chunk_limit -
__o1->next_free); }) < __len) _obstack_newchunk (__o, __len
); ((void) ((__o)->next_free += (__len))); }); __extension__
({ struct obstack *__o1 = (__h); void *__value = (void *) __o1
->object_base; if (__o1->next_free == __value) __o1->
maybe_empty_object = 1; __o1->next_free = (sizeof (ptrdiff_t
) < sizeof (void *) ? ((__o1->object_base) + (((__o1->
next_free) - (__o1->object_base) + (__o1->alignment_mask
)) & ~(__o1->alignment_mask))) : (char *) (((ptrdiff_t
) (__o1->next_free) + (__o1->alignment_mask)) & ~(__o1
->alignment_mask))); if ((size_t) (__o1->next_free - (char
*) __o1->chunk) > (size_t) (__o1->chunk_limit - (char
*) __o1->chunk)) __o1->next_free = __o1->chunk_limit
; __o1->object_base = __o1->next_free; __value; }); })
346 sizeof (struct insn_link))__extension__ ({ struct obstack *__h = (&insn_link_obstack
); __extension__ ({ struct obstack *__o = (__h); size_t __len
= ((sizeof (struct insn_link))); if (__extension__ ({ struct
obstack const *__o1 = (__o); (size_t) (__o1->chunk_limit -
__o1->next_free); }) < __len) _obstack_newchunk (__o, __len
); ((void) ((__o)->next_free += (__len))); }); __extension__
({ struct obstack *__o1 = (__h); void *__value = (void *) __o1
->object_base; if (__o1->next_free == __value) __o1->
maybe_empty_object = 1; __o1->next_free = (sizeof (ptrdiff_t
) < sizeof (void *) ? ((__o1->object_base) + (((__o1->
next_free) - (__o1->object_base) + (__o1->alignment_mask
)) & ~(__o1->alignment_mask))) : (char *) (((ptrdiff_t
) (__o1->next_free) + (__o1->alignment_mask)) & ~(__o1
->alignment_mask))); if ((size_t) (__o1->next_free - (char
*) __o1->chunk) > (size_t) (__o1->chunk_limit - (char
*) __o1->chunk)) __o1->next_free = __o1->chunk_limit
; __o1->object_base = __o1->next_free; __value; }); })
;
347 l->insn = insn;
348 l->regno = regno;
349 l->next = next;
350 return l;
351}
352
353/* Incremented for each basic block. */
354
355static int label_tick;
356
357/* Reset to label_tick for each extended basic block in scanning order. */
358
359static int label_tick_ebb_start;
360
361/* Mode used to compute significance in reg_stat[].nonzero_bits. It is the
362 largest integer mode that can fit in HOST_BITS_PER_WIDE_INT. */
363
364static scalar_int_mode nonzero_bits_mode;
365
366/* Nonzero when reg_stat[].nonzero_bits and reg_stat[].sign_bit_copies can
367 be safely used. It is zero while computing them and after combine has
368 completed. This former test prevents propagating values based on
369 previously set values, which can be incorrect if a variable is modified
370 in a loop. */
371
372static int nonzero_sign_valid;
373
374
375/* Record one modification to rtl structure
376 to be undone by storing old_contents into *where. */
377
378enum undo_kind { UNDO_RTX, UNDO_INT, UNDO_MODE, UNDO_LINKS };
379
380struct undo
381{
382 struct undo *next;
383 enum undo_kind kind;
384 union { rtx r; int i; machine_mode m; struct insn_link *l; } old_contents;
385 union { rtx *r; int *i; struct insn_link **l; } where;
386};
387
388/* Record a bunch of changes to be undone, up to MAX_UNDO of them.
389 num_undo says how many are currently recorded.
390
391 other_insn is nonzero if we have modified some other insn in the process
392 of working on subst_insn. It must be verified too. */
393
394struct undobuf
395{
396 struct undo *undos;
397 struct undo *frees;
398 rtx_insn *other_insn;
399};
400
401static struct undobuf undobuf;
402
403/* Number of times the pseudo being substituted for
404 was found and replaced. */
405
406static int n_occurrences;
407
408static rtx reg_nonzero_bits_for_combine (const_rtx, scalar_int_mode,
409 scalar_int_mode,
410 unsigned HOST_WIDE_INTlong *);
411static rtx reg_num_sign_bit_copies_for_combine (const_rtx, scalar_int_mode,
412 scalar_int_mode,
413 unsigned int *);
414static void do_SUBST (rtx *, rtx);
415static void do_SUBST_INT (int *, int);
416static void init_reg_last (void);
417static void setup_incoming_promotions (rtx_insn *);
418static void set_nonzero_bits_and_sign_copies (rtx, const_rtx, void *);
419static int cant_combine_insn_p (rtx_insn *);
420static int can_combine_p (rtx_insn *, rtx_insn *, rtx_insn *, rtx_insn *,
421 rtx_insn *, rtx_insn *, rtx *, rtx *);
422static int combinable_i3pat (rtx_insn *, rtx *, rtx, rtx, rtx, int, int, rtx *);
423static int contains_muldiv (rtx);
424static rtx_insn *try_combine (rtx_insn *, rtx_insn *, rtx_insn *, rtx_insn *,
425 int *, rtx_insn *);
426static void undo_all (void);
427static void undo_commit (void);
428static rtx *find_split_point (rtx *, rtx_insn *, bool);
429static rtx subst (rtx, rtx, rtx, int, int, int);
430static rtx combine_simplify_rtx (rtx, machine_mode, int, int);
431static rtx simplify_if_then_else (rtx);
432static rtx simplify_set (rtx);
433static rtx simplify_logical (rtx);
434static rtx expand_compound_operation (rtx);
435static const_rtx expand_field_assignment (const_rtx);
436static rtx make_extraction (machine_mode, rtx, HOST_WIDE_INTlong,
437 rtx, unsigned HOST_WIDE_INTlong, int, int, int);
438static int get_pos_from_mask (unsigned HOST_WIDE_INTlong,
439 unsigned HOST_WIDE_INTlong *);
440static rtx canon_reg_for_combine (rtx, rtx);
441static rtx force_int_to_mode (rtx, scalar_int_mode, scalar_int_mode,
442 scalar_int_mode, unsigned HOST_WIDE_INTlong, int);
443static rtx force_to_mode (rtx, machine_mode,
444 unsigned HOST_WIDE_INTlong, int);
445static rtx if_then_else_cond (rtx, rtx *, rtx *);
446static rtx known_cond (rtx, enum rtx_code, rtx, rtx);
447static int rtx_equal_for_field_assignment_p (rtx, rtx, bool = false);
448static rtx make_field_assignment (rtx);
449static rtx apply_distributive_law (rtx);
450static rtx distribute_and_simplify_rtx (rtx, int);
451static rtx simplify_and_const_int_1 (scalar_int_mode, rtx,
452 unsigned HOST_WIDE_INTlong);
453static rtx simplify_and_const_int (rtx, scalar_int_mode, rtx,
454 unsigned HOST_WIDE_INTlong);
455static int merge_outer_ops (enum rtx_code *, HOST_WIDE_INTlong *, enum rtx_code,
456 HOST_WIDE_INTlong, machine_mode, int *);
457static rtx simplify_shift_const_1 (enum rtx_code, machine_mode, rtx, int);
458static rtx simplify_shift_const (rtx, enum rtx_code, machine_mode, rtx,
459 int);
460static int recog_for_combine (rtx *, rtx_insn *, rtx *);
461static rtx gen_lowpart_for_combine (machine_mode, rtx);
462static enum rtx_code simplify_compare_const (enum rtx_code, machine_mode,
463 rtx, rtx *);
464static enum rtx_code simplify_comparison (enum rtx_code, rtx *, rtx *);
465static void update_table_tick (rtx);
466static void record_value_for_reg (rtx, rtx_insn *, rtx);
467static void check_promoted_subreg (rtx_insn *, rtx);
468static void record_dead_and_set_regs_1 (rtx, const_rtx, void *);
469static void record_dead_and_set_regs (rtx_insn *);
470static int get_last_value_validate (rtx *, rtx_insn *, int, int);
471static rtx get_last_value (const_rtx);
472static void reg_dead_at_p_1 (rtx, const_rtx, void *);
473static int reg_dead_at_p (rtx, rtx_insn *);
474static void move_deaths (rtx, rtx, int, rtx_insn *, rtx *);
475static int reg_bitfield_target_p (rtx, rtx);
476static void distribute_notes (rtx, rtx_insn *, rtx_insn *, rtx_insn *, rtx, rtx, rtx);
477static void distribute_links (struct insn_link *);
478static void mark_used_regs_combine (rtx);
479static void record_promoted_value (rtx_insn *, rtx);
480static bool unmentioned_reg_p (rtx, rtx);
481static void record_truncated_values (rtx *, void *);
482static bool reg_truncated_to_mode (machine_mode, const_rtx);
483static rtx gen_lowpart_or_truncate (machine_mode, rtx);
484
485
486/* It is not safe to use ordinary gen_lowpart in combine.
487 See comments in gen_lowpart_for_combine. */
488#undef RTL_HOOKS_GEN_LOWPARTgen_lowpart_for_combine
489#define RTL_HOOKS_GEN_LOWPARTgen_lowpart_for_combine gen_lowpart_for_combine
490
491/* Our implementation of gen_lowpart never emits a new pseudo. */
492#undef RTL_HOOKS_GEN_LOWPART_NO_EMITgen_lowpart_for_combine
493#define RTL_HOOKS_GEN_LOWPART_NO_EMITgen_lowpart_for_combine gen_lowpart_for_combine
494
495#undef RTL_HOOKS_REG_NONZERO_REG_BITSreg_nonzero_bits_for_combine
496#define RTL_HOOKS_REG_NONZERO_REG_BITSreg_nonzero_bits_for_combine reg_nonzero_bits_for_combine
497
498#undef RTL_HOOKS_REG_NUM_SIGN_BIT_COPIESreg_num_sign_bit_copies_for_combine
499#define RTL_HOOKS_REG_NUM_SIGN_BIT_COPIESreg_num_sign_bit_copies_for_combine reg_num_sign_bit_copies_for_combine
500
501#undef RTL_HOOKS_REG_TRUNCATED_TO_MODEreg_truncated_to_mode
502#define RTL_HOOKS_REG_TRUNCATED_TO_MODEreg_truncated_to_mode reg_truncated_to_mode
503
504static const struct rtl_hooks combine_rtl_hooks = RTL_HOOKS_INITIALIZER{ gen_lowpart_for_combine, gen_lowpart_for_combine, reg_nonzero_bits_for_combine
, reg_num_sign_bit_copies_for_combine, reg_truncated_to_mode }
;
505
506
507/* Convenience wrapper for the canonicalize_comparison target hook.
508 Target hooks cannot use enum rtx_code. */
509static inline void
510target_canonicalize_comparison (enum rtx_code *code, rtx *op0, rtx *op1,
511 bool op0_preserve_value)
512{
513 int code_int = (int)*code;
514 targetm.canonicalize_comparison (&code_int, op0, op1, op0_preserve_value);
515 *code = (enum rtx_code)code_int;
516}
517
518/* Try to split PATTERN found in INSN. This returns NULL_RTX if
519 PATTERN cannot be split. Otherwise, it returns an insn sequence.
520 This is a wrapper around split_insns which ensures that the
521 reg_stat vector is made larger if the splitter creates a new
522 register. */
523
524static rtx_insn *
525combine_split_insns (rtx pattern, rtx_insn *insn)
526{
527 rtx_insn *ret;
528 unsigned int nregs;
529
530 ret = split_insns (pattern, insn);
531 nregs = max_reg_num ();
532 if (nregs > reg_stat.length ())
533 reg_stat.safe_grow_cleared (nregs, true);
534 return ret;
535}
536
537/* This is used by find_single_use to locate an rtx in LOC that
538 contains exactly one use of DEST, which is typically a REG.
539 It returns a pointer to the innermost rtx expression
540 containing DEST. Appearances of DEST that are being used to
541 totally replace it are not counted. */
542
543static rtx *
544find_single_use_1 (rtx dest, rtx *loc)
545{
546 rtx x = *loc;
547 enum rtx_code code = GET_CODE (x)((enum rtx_code) (x)->code);
548 rtx *result = NULLnullptr;
549 rtx *this_result;
550 int i;
551 const char *fmt;
552
553 switch (code)
554 {
555 case CONST:
556 case LABEL_REF:
557 case SYMBOL_REF:
558 CASE_CONST_ANYcase CONST_INT: case CONST_WIDE_INT: case CONST_POLY_INT: case
CONST_DOUBLE: case CONST_FIXED: case CONST_VECTOR
:
559 case CLOBBER:
560 return 0;
561
562 case SET:
563 /* If the destination is anything other than PC, a REG or a SUBREG
564 of a REG that occupies all of the REG, the insn uses DEST if
565 it is mentioned in the destination or the source. Otherwise, we
566 need just check the source. */
567 if (GET_CODE (SET_DEST (x))((enum rtx_code) ((((x)->u.fld[0]).rt_rtx))->code) != PC
568 && !REG_P (SET_DEST (x))(((enum rtx_code) ((((x)->u.fld[0]).rt_rtx))->code) == REG
)
569 && ! (GET_CODE (SET_DEST (x))((enum rtx_code) ((((x)->u.fld[0]).rt_rtx))->code) == SUBREG
570 && REG_P (SUBREG_REG (SET_DEST (x)))(((enum rtx_code) (((((((x)->u.fld[0]).rt_rtx))->u.fld[
0]).rt_rtx))->code) == REG)
571 && !read_modify_subreg_p (SET_DEST (x)(((x)->u.fld[0]).rt_rtx))))
572 break;
573
574 return find_single_use_1 (dest, &SET_SRC (x)(((x)->u.fld[1]).rt_rtx));
575
576 case MEM:
577 case SUBREG:
578 return find_single_use_1 (dest, &XEXP (x, 0)(((x)->u.fld[0]).rt_rtx));
579
580 default:
581 break;
582 }
583
584 /* If it wasn't one of the common cases above, check each expression and
585 vector of this code. Look for a unique usage of DEST. */
586
587 fmt = GET_RTX_FORMAT (code)(rtx_format[(int) (code)]);
588 for (i = GET_RTX_LENGTH (code)(rtx_length[(int) (code)]) - 1; i >= 0; i--)
589 {
590 if (fmt[i] == 'e')
591 {
592 if (dest == XEXP (x, i)(((x)->u.fld[i]).rt_rtx)
593 || (REG_P (dest)(((enum rtx_code) (dest)->code) == REG) && REG_P (XEXP (x, i))(((enum rtx_code) ((((x)->u.fld[i]).rt_rtx))->code) == REG
)
594 && REGNO (dest)(rhs_regno(dest)) == REGNO (XEXP (x, i))(rhs_regno((((x)->u.fld[i]).rt_rtx)))))
595 this_result = loc;
596 else
597 this_result = find_single_use_1 (dest, &XEXP (x, i)(((x)->u.fld[i]).rt_rtx));
598
599 if (result == NULLnullptr)
600 result = this_result;
601 else if (this_result)
602 /* Duplicate usage. */
603 return NULLnullptr;
604 }
605 else if (fmt[i] == 'E')
606 {
607 int j;
608
609 for (j = XVECLEN (x, i)(((((x)->u.fld[i]).rt_rtvec))->num_elem) - 1; j >= 0; j--)
610 {
611 if (XVECEXP (x, i, j)(((((x)->u.fld[i]).rt_rtvec))->elem[j]) == dest
612 || (REG_P (dest)(((enum rtx_code) (dest)->code) == REG)
613 && REG_P (XVECEXP (x, i, j))(((enum rtx_code) ((((((x)->u.fld[i]).rt_rtvec))->elem[
j]))->code) == REG)
614 && REGNO (XVECEXP (x, i, j))(rhs_regno((((((x)->u.fld[i]).rt_rtvec))->elem[j]))) == REGNO (dest)(rhs_regno(dest))))
615 this_result = loc;
616 else
617 this_result = find_single_use_1 (dest, &XVECEXP (x, i, j)(((((x)->u.fld[i]).rt_rtvec))->elem[j]));
618
619 if (result == NULLnullptr)
620 result = this_result;
621 else if (this_result)
622 return NULLnullptr;
623 }
624 }
625 }
626
627 return result;
628}
629
630
631/* See if DEST, produced in INSN, is used only a single time in the
632 sequel. If so, return a pointer to the innermost rtx expression in which
633 it is used.
634
635 If PLOC is nonzero, *PLOC is set to the insn containing the single use.
636
637 Otherwise, we find the single use by finding an insn that has a
638 LOG_LINKS pointing at INSN and has a REG_DEAD note for DEST. If DEST is
639 only referenced once in that insn, we know that it must be the first
640 and last insn referencing DEST. */
641
642static rtx *
643find_single_use (rtx dest, rtx_insn *insn, rtx_insn **ploc)
644{
645 basic_block bb;
646 rtx_insn *next;
647 rtx *result;
648 struct insn_link *link;
649
650 if (!REG_P (dest)(((enum rtx_code) (dest)->code) == REG))
651 return 0;
652
653 bb = BLOCK_FOR_INSN (insn);
654 for (next = NEXT_INSN (insn);
655 next && BLOCK_FOR_INSN (next) == bb;
656 next = NEXT_INSN (next))
657 if (NONDEBUG_INSN_P (next)((((enum rtx_code) (next)->code) == INSN) || (((enum rtx_code
) (next)->code) == JUMP_INSN) || (((enum rtx_code) (next)->
code) == CALL_INSN))
&& dead_or_set_p (next, dest))
658 {
659 FOR_EACH_LOG_LINK (link, next)for ((link) = (uid_log_links[insn_uid_check (next)]); (link);
(link) = (link)->next)
660 if (link->insn == insn && link->regno == REGNO (dest)(rhs_regno(dest)))
661 break;
662
663 if (link)
664 {
665 result = find_single_use_1 (dest, &PATTERN (next));
666 if (ploc)
667 *ploc = next;
668 return result;
669 }
670 }
671
672 return 0;
673}
674
675/* Substitute NEWVAL, an rtx expression, into INTO, a place in some
676 insn. The substitution can be undone by undo_all. If INTO is already
677 set to NEWVAL, do not record this change. Because computing NEWVAL might
678 also call SUBST, we have to compute it before we put anything into
679 the undo table. */
680
681static void
682do_SUBST (rtx *into, rtx newval)
683{
684 struct undo *buf;
685 rtx oldval = *into;
686
687 if (oldval == newval)
688 return;
689
690 /* We'd like to catch as many invalid transformations here as
691 possible. Unfortunately, there are way too many mode changes
692 that are perfectly valid, so we'd waste too much effort for
693 little gain doing the checks here. Focus on catching invalid
694 transformations involving integer constants. */
695 if (GET_MODE_CLASS (GET_MODE (oldval))((enum mode_class) mode_class[((machine_mode) (oldval)->mode
)])
== MODE_INT
696 && CONST_INT_P (newval)(((enum rtx_code) (newval)->code) == CONST_INT))
697 {
698 /* Sanity check that we're replacing oldval with a CONST_INT
699 that is a valid sign-extension for the original mode. */
700 gcc_assert (INTVAL (newval)((void)(!(((newval)->u.hwint[0]) == trunc_int_for_mode (((
newval)->u.hwint[0]), ((machine_mode) (oldval)->mode)))
? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/combine.c"
, 701, __FUNCTION__), 0 : 0))
701 == trunc_int_for_mode (INTVAL (newval), GET_MODE (oldval)))((void)(!(((newval)->u.hwint[0]) == trunc_int_for_mode (((
newval)->u.hwint[0]), ((machine_mode) (oldval)->mode)))
? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/combine.c"
, 701, __FUNCTION__), 0 : 0))
;
702
703 /* Replacing the operand of a SUBREG or a ZERO_EXTEND with a
704 CONST_INT is not valid, because after the replacement, the
705 original mode would be gone. Unfortunately, we can't tell
706 when do_SUBST is called to replace the operand thereof, so we
707 perform this test on oldval instead, checking whether an
708 invalid replacement took place before we got here. */
709 gcc_assert (!(GET_CODE (oldval) == SUBREG((void)(!(!(((enum rtx_code) (oldval)->code) == SUBREG &&
(((enum rtx_code) ((((oldval)->u.fld[0]).rt_rtx))->code
) == CONST_INT))) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/combine.c"
, 710, __FUNCTION__), 0 : 0))
710 && CONST_INT_P (SUBREG_REG (oldval))))((void)(!(!(((enum rtx_code) (oldval)->code) == SUBREG &&
(((enum rtx_code) ((((oldval)->u.fld[0]).rt_rtx))->code
) == CONST_INT))) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/combine.c"
, 710, __FUNCTION__), 0 : 0))
;
711 gcc_assert (!(GET_CODE (oldval) == ZERO_EXTEND((void)(!(!(((enum rtx_code) (oldval)->code) == ZERO_EXTEND
&& (((enum rtx_code) ((((oldval)->u.fld[0]).rt_rtx
))->code) == CONST_INT))) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/combine.c"
, 712, __FUNCTION__), 0 : 0))
712 && CONST_INT_P (XEXP (oldval, 0))))((void)(!(!(((enum rtx_code) (oldval)->code) == ZERO_EXTEND
&& (((enum rtx_code) ((((oldval)->u.fld[0]).rt_rtx
))->code) == CONST_INT))) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/combine.c"
, 712, __FUNCTION__), 0 : 0))
;
713 }
714
715 if (undobuf.frees)
716 buf = undobuf.frees, undobuf.frees = buf->next;
717 else
718 buf = XNEW (struct undo)((struct undo *) xmalloc (sizeof (struct undo)));
719
720 buf->kind = UNDO_RTX;
721 buf->where.r = into;
722 buf->old_contents.r = oldval;
723 *into = newval;
724
725 buf->next = undobuf.undos, undobuf.undos = buf;
726}
727
728#define SUBST(INTO, NEWVAL)do_SUBST (&(INTO), (NEWVAL)) do_SUBST (&(INTO), (NEWVAL))
729
730/* Similar to SUBST, but NEWVAL is an int expression. Note that substitution
731 for the value of a HOST_WIDE_INT value (including CONST_INT) is
732 not safe. */
733
734static void
735do_SUBST_INT (int *into, int newval)
736{
737 struct undo *buf;
738 int oldval = *into;
739
740 if (oldval == newval)
741 return;
742
743 if (undobuf.frees)
744 buf = undobuf.frees, undobuf.frees = buf->next;
745 else
746 buf = XNEW (struct undo)((struct undo *) xmalloc (sizeof (struct undo)));
747
748 buf->kind = UNDO_INT;
749 buf->where.i = into;
750 buf->old_contents.i = oldval;
751 *into = newval;
752
753 buf->next = undobuf.undos, undobuf.undos = buf;
754}
755
756#define SUBST_INT(INTO, NEWVAL)do_SUBST_INT (&(INTO), (NEWVAL)) do_SUBST_INT (&(INTO), (NEWVAL))
757
758/* Similar to SUBST, but just substitute the mode. This is used when
759 changing the mode of a pseudo-register, so that any other
760 references to the entry in the regno_reg_rtx array will change as
761 well. */
762
763static void
764do_SUBST_MODE (rtx *into, machine_mode newval)
765{
766 struct undo *buf;
767 machine_mode oldval = GET_MODE (*into)((machine_mode) (*into)->mode);
768
769 if (oldval == newval)
770 return;
771
772 if (undobuf.frees)
773 buf = undobuf.frees, undobuf.frees = buf->next;
774 else
775 buf = XNEW (struct undo)((struct undo *) xmalloc (sizeof (struct undo)));
776
777 buf->kind = UNDO_MODE;
778 buf->where.r = into;
779 buf->old_contents.m = oldval;
780 adjust_reg_mode (*into, newval);
781
782 buf->next = undobuf.undos, undobuf.undos = buf;
783}
784
785#define SUBST_MODE(INTO, NEWVAL)do_SUBST_MODE (&(INTO), (NEWVAL)) do_SUBST_MODE (&(INTO), (NEWVAL))
786
787/* Similar to SUBST, but NEWVAL is a LOG_LINKS expression. */
788
789static void
790do_SUBST_LINK (struct insn_link **into, struct insn_link *newval)
791{
792 struct undo *buf;
793 struct insn_link * oldval = *into;
794
795 if (oldval == newval)
796 return;
797
798 if (undobuf.frees)
799 buf = undobuf.frees, undobuf.frees = buf->next;
800 else
801 buf = XNEW (struct undo)((struct undo *) xmalloc (sizeof (struct undo)));
802
803 buf->kind = UNDO_LINKS;
804 buf->where.l = into;
805 buf->old_contents.l = oldval;
806 *into = newval;
807
808 buf->next = undobuf.undos, undobuf.undos = buf;
809}
810
811#define SUBST_LINK(oldval, newval)do_SUBST_LINK (&oldval, newval) do_SUBST_LINK (&oldval, newval)
812
813/* Subroutine of try_combine. Determine whether the replacement patterns
814 NEWPAT, NEWI2PAT and NEWOTHERPAT are cheaper according to insn_cost
815 than the original sequence I0, I1, I2, I3 and undobuf.other_insn. Note
816 that I0, I1 and/or NEWI2PAT may be NULL_RTX. Similarly, NEWOTHERPAT and
817 undobuf.other_insn may also both be NULL_RTX. Return false if the cost
818 of all the instructions can be estimated and the replacements are more
819 expensive than the original sequence. */
820
821static bool
822combine_validate_cost (rtx_insn *i0, rtx_insn *i1, rtx_insn *i2, rtx_insn *i3,
823 rtx newpat, rtx newi2pat, rtx newotherpat)
824{
825 int i0_cost, i1_cost, i2_cost, i3_cost;
826 int new_i2_cost, new_i3_cost;
827 int old_cost, new_cost;
828
829 /* Lookup the original insn_costs. */
830 i2_cost = INSN_COST (i2)(uid_insn_cost[insn_uid_check (i2)]);
831 i3_cost = INSN_COST (i3)(uid_insn_cost[insn_uid_check (i3)]);
832
833 if (i1)
834 {
835 i1_cost = INSN_COST (i1)(uid_insn_cost[insn_uid_check (i1)]);
836 if (i0)
837 {
838 i0_cost = INSN_COST (i0)(uid_insn_cost[insn_uid_check (i0)]);
839 old_cost = (i0_cost > 0 && i1_cost > 0 && i2_cost > 0 && i3_cost > 0
840 ? i0_cost + i1_cost + i2_cost + i3_cost : 0);
841 }
842 else
843 {
844 old_cost = (i1_cost > 0 && i2_cost > 0 && i3_cost > 0
845 ? i1_cost + i2_cost + i3_cost : 0);
846 i0_cost = 0;
847 }
848 }
849 else
850 {
851 old_cost = (i2_cost > 0 && i3_cost > 0) ? i2_cost + i3_cost : 0;
852 i1_cost = i0_cost = 0;
853 }
854
855 /* If we have split a PARALLEL I2 to I1,I2, we have counted its cost twice;
856 correct that. */
857 if (old_cost && i1 && INSN_UID (i1) == INSN_UID (i2))
858 old_cost -= i1_cost;
859
860
861 /* Calculate the replacement insn_costs. */
862 rtx tmp = PATTERN (i3);
863 PATTERN (i3) = newpat;
864 int tmpi = INSN_CODE (i3)(((i3)->u.fld[5]).rt_int);
865 INSN_CODE (i3)(((i3)->u.fld[5]).rt_int) = -1;
866 new_i3_cost = insn_cost (i3, optimize_this_for_speed_p);
867 PATTERN (i3) = tmp;
868 INSN_CODE (i3)(((i3)->u.fld[5]).rt_int) = tmpi;
869 if (newi2pat)
870 {
871 tmp = PATTERN (i2);
872 PATTERN (i2) = newi2pat;
873 tmpi = INSN_CODE (i2)(((i2)->u.fld[5]).rt_int);
874 INSN_CODE (i2)(((i2)->u.fld[5]).rt_int) = -1;
875 new_i2_cost = insn_cost (i2, optimize_this_for_speed_p);
876 PATTERN (i2) = tmp;
877 INSN_CODE (i2)(((i2)->u.fld[5]).rt_int) = tmpi;
878 new_cost = (new_i2_cost > 0 && new_i3_cost > 0)
879 ? new_i2_cost + new_i3_cost : 0;
880 }
881 else
882 {
883 new_cost = new_i3_cost;
884 new_i2_cost = 0;
885 }
886
887 if (undobuf.other_insn)
888 {
889 int old_other_cost, new_other_cost;
890
891 old_other_cost = INSN_COST (undobuf.other_insn)(uid_insn_cost[insn_uid_check (undobuf.other_insn)]);
892 tmp = PATTERN (undobuf.other_insn);
893 PATTERN (undobuf.other_insn) = newotherpat;
894 tmpi = INSN_CODE (undobuf.other_insn)(((undobuf.other_insn)->u.fld[5]).rt_int);
895 INSN_CODE (undobuf.other_insn)(((undobuf.other_insn)->u.fld[5]).rt_int) = -1;
896 new_other_cost = insn_cost (undobuf.other_insn,
897 optimize_this_for_speed_p);
898 PATTERN (undobuf.other_insn) = tmp;
899 INSN_CODE (undobuf.other_insn)(((undobuf.other_insn)->u.fld[5]).rt_int) = tmpi;
900 if (old_other_cost > 0 && new_other_cost > 0)
901 {
902 old_cost += old_other_cost;
903 new_cost += new_other_cost;
904 }
905 else
906 old_cost = 0;
907 }
908
909 /* Disallow this combination if both new_cost and old_cost are greater than
910 zero, and new_cost is greater than old cost. */
911 int reject = old_cost > 0 && new_cost > old_cost;
912
913 if (dump_file)
914 {
915 fprintf (dump_file, "%s combination of insns ",
916 reject ? "rejecting" : "allowing");
917 if (i0)
918 fprintf (dump_file, "%d, ", INSN_UID (i0));
919 if (i1 && INSN_UID (i1) != INSN_UID (i2))
920 fprintf (dump_file, "%d, ", INSN_UID (i1));
921 fprintf (dump_file, "%d and %d\n", INSN_UID (i2), INSN_UID (i3));
922
923 fprintf (dump_file, "original costs ");
924 if (i0)
925 fprintf (dump_file, "%d + ", i0_cost);
926 if (i1 && INSN_UID (i1) != INSN_UID (i2))
927 fprintf (dump_file, "%d + ", i1_cost);
928 fprintf (dump_file, "%d + %d = %d\n", i2_cost, i3_cost, old_cost);
929
930 if (newi2pat)
931 fprintf (dump_file, "replacement costs %d + %d = %d\n",
932 new_i2_cost, new_i3_cost, new_cost);
933 else
934 fprintf (dump_file, "replacement cost %d\n", new_cost);
935 }
936
937 if (reject)
938 return false;
939
940 /* Update the uid_insn_cost array with the replacement costs. */
941 INSN_COST (i2)(uid_insn_cost[insn_uid_check (i2)]) = new_i2_cost;
942 INSN_COST (i3)(uid_insn_cost[insn_uid_check (i3)]) = new_i3_cost;
943 if (i1)
944 {
945 INSN_COST (i1)(uid_insn_cost[insn_uid_check (i1)]) = 0;
946 if (i0)
947 INSN_COST (i0)(uid_insn_cost[insn_uid_check (i0)]) = 0;
948 }
949
950 return true;
951}
952
953
954/* Delete any insns that copy a register to itself.
955 Return true if the CFG was changed. */
956
957static bool
958delete_noop_moves (void)
959{
960 rtx_insn *insn, *next;
961 basic_block bb;
962
963 bool edges_deleted = false;
964
965 FOR_EACH_BB_FN (bb, cfun)for (bb = ((cfun + 0))->cfg->x_entry_block_ptr->next_bb
; bb != ((cfun + 0))->cfg->x_exit_block_ptr; bb = bb->
next_bb)
966 {
967 for (insn = BB_HEAD (bb)(bb)->il.x.head_; insn != NEXT_INSN (BB_END (bb)(bb)->il.x.rtl->end_); insn = next)
968 {
969 next = NEXT_INSN (insn);
970 if (INSN_P (insn)(((((enum rtx_code) (insn)->code) == INSN) || (((enum rtx_code
) (insn)->code) == JUMP_INSN) || (((enum rtx_code) (insn)->
code) == CALL_INSN)) || (((enum rtx_code) (insn)->code) ==
DEBUG_INSN))
&& noop_move_p (insn))
971 {
972 if (dump_file)
973 fprintf (dump_file, "deleting noop move %d\n", INSN_UID (insn));
974
975 edges_deleted |= delete_insn_and_edges (insn);
976 }
977 }
978 }
979
980 return edges_deleted;
981}
982
983
984/* Return false if we do not want to (or cannot) combine DEF. */
985static bool
986can_combine_def_p (df_ref def)
987{
988 /* Do not consider if it is pre/post modification in MEM. */
989 if (DF_REF_FLAGS (def)((def)->base.flags) & DF_REF_PRE_POST_MODIFY)
990 return false;
991
992 unsigned int regno = DF_REF_REGNO (def)((def)->base.regno);
993
994 /* Do not combine frame pointer adjustments. */
995 if ((regno == FRAME_POINTER_REGNUM19
996 && (!reload_completed || frame_pointer_needed((&x_rtl)->frame_pointer_needed)))
997 || (!HARD_FRAME_POINTER_IS_FRAME_POINTER(6 == 19)
998 && regno == HARD_FRAME_POINTER_REGNUM6
999 && (!reload_completed || frame_pointer_needed((&x_rtl)->frame_pointer_needed)))
1000 || (FRAME_POINTER_REGNUM19 != ARG_POINTER_REGNUM16
1001 && regno == ARG_POINTER_REGNUM16 && fixed_regs(this_target_hard_regs->x_fixed_regs)[regno]))
1002 return false;
1003
1004 return true;
1005}
1006
1007/* Return false if we do not want to (or cannot) combine USE. */
1008static bool
1009can_combine_use_p (df_ref use)
1010{
1011 /* Do not consider the usage of the stack pointer by function call. */
1012 if (DF_REF_FLAGS (use)((use)->base.flags) & DF_REF_CALL_STACK_USAGE)
1013 return false;
1014
1015 return true;
1016}
1017
1018/* Fill in log links field for all insns. */
1019
1020static void
1021create_log_links (void)
1022{
1023 basic_block bb;
1024 rtx_insn **next_use;
1025 rtx_insn *insn;
1026 df_ref def, use;
1027
1028 next_use = XCNEWVEC (rtx_insn *, max_reg_num ())((rtx_insn * *) xcalloc ((max_reg_num ()), sizeof (rtx_insn *
)))
;
1029
1030 /* Pass through each block from the end, recording the uses of each
1031 register and establishing log links when def is encountered.
1032 Note that we do not clear next_use array in order to save time,
1033 so we have to test whether the use is in the same basic block as def.
1034
1035 There are a few cases below when we do not consider the definition or
1036 usage -- these are taken from original flow.c did. Don't ask me why it is
1037 done this way; I don't know and if it works, I don't want to know. */
1038
1039 FOR_EACH_BB_FN (bb, cfun)for (bb = ((cfun + 0))->cfg->x_entry_block_ptr->next_bb
; bb != ((cfun + 0))->cfg->x_exit_block_ptr; bb = bb->
next_bb)
1040 {
1041 FOR_BB_INSNS_REVERSE (bb, insn)for ((insn) = (bb)->il.x.rtl->end_; (insn) && (
insn) != PREV_INSN ((bb)->il.x.head_); (insn) = PREV_INSN (
insn))
1042 {
1043 if (!NONDEBUG_INSN_P (insn)((((enum rtx_code) (insn)->code) == INSN) || (((enum rtx_code
) (insn)->code) == JUMP_INSN) || (((enum rtx_code) (insn)->
code) == CALL_INSN))
)
1044 continue;
1045
1046 /* Log links are created only once. */
1047 gcc_assert (!LOG_LINKS (insn))((void)(!(!(uid_log_links[insn_uid_check (insn)])) ? fancy_abort
("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/combine.c"
, 1047, __FUNCTION__), 0 : 0))
;
1048
1049 FOR_EACH_INSN_DEF (def, insn)for (def = (((df->insns[(INSN_UID (insn))]))->defs); def
; def = ((def)->base.next_loc))
1050 {
1051 unsigned int regno = DF_REF_REGNO (def)((def)->base.regno);
1052 rtx_insn *use_insn;
1053
1054 if (!next_use[regno])
1055 continue;
1056
1057 if (!can_combine_def_p (def))
1058 continue;
1059
1060 use_insn = next_use[regno];
1061 next_use[regno] = NULLnullptr;
1062
1063 if (BLOCK_FOR_INSN (use_insn) != bb)
1064 continue;
1065
1066 /* flow.c claimed:
1067
1068 We don't build a LOG_LINK for hard registers contained
1069 in ASM_OPERANDs. If these registers get replaced,
1070 we might wind up changing the semantics of the insn,
1071 even if reload can make what appear to be valid
1072 assignments later. */
1073 if (regno < FIRST_PSEUDO_REGISTER76
1074 && asm_noperands (PATTERN (use_insn)) >= 0)
1075 continue;
1076
1077 /* Don't add duplicate links between instructions. */
1078 struct insn_link *links;
1079 FOR_EACH_LOG_LINK (links, use_insn)for ((links) = (uid_log_links[insn_uid_check (use_insn)]); (links
); (links) = (links)->next)
1080 if (insn == links->insn && regno == links->regno)
1081 break;
1082
1083 if (!links)
1084 LOG_LINKS (use_insn)(uid_log_links[insn_uid_check (use_insn)])
1085 = alloc_insn_link (insn, regno, LOG_LINKS (use_insn)(uid_log_links[insn_uid_check (use_insn)]));
1086 }
1087
1088 FOR_EACH_INSN_USE (use, insn)for (use = (((df->insns[(INSN_UID (insn))]))->uses); use
; use = ((use)->base.next_loc))
1089 if (can_combine_use_p (use))
1090 next_use[DF_REF_REGNO (use)((use)->base.regno)] = insn;
1091 }
1092 }
1093
1094 free (next_use);
1095}
1096
1097/* Walk the LOG_LINKS of insn B to see if we find a reference to A. Return
1098 true if we found a LOG_LINK that proves that A feeds B. This only works
1099 if there are no instructions between A and B which could have a link
1100 depending on A, since in that case we would not record a link for B. */
1101
1102static bool
1103insn_a_feeds_b (rtx_insn *a, rtx_insn *b)
1104{
1105 struct insn_link *links;
1106 FOR_EACH_LOG_LINK (links, b)for ((links) = (uid_log_links[insn_uid_check (b)]); (links); (
links) = (links)->next)
1107 if (links->insn == a)
1108 return true;
1109 return false;
1110}
1111
1112/* Main entry point for combiner. F is the first insn of the function.
1113 NREGS is the first unused pseudo-reg number.
1114
1115 Return nonzero if the CFG was changed (e.g. if the combiner has
1116 turned an indirect jump instruction into a direct jump). */
1117static int
1118combine_instructions (rtx_insn *f, unsigned int nregs)
1119{
1120 rtx_insn *insn, *next;
1121 struct insn_link *links, *nextlinks;
1122 rtx_insn *first;
1123 basic_block last_bb;
1124
1125 int new_direct_jump_p = 0;
1126
1127 for (first = f; first && !NONDEBUG_INSN_P (first)((((enum rtx_code) (first)->code) == INSN) || (((enum rtx_code
) (first)->code) == JUMP_INSN) || (((enum rtx_code) (first
)->code) == CALL_INSN))
; )
1128 first = NEXT_INSN (first);
1129 if (!first)
1130 return 0;
1131
1132 combine_attempts = 0;
1133 combine_merges = 0;
1134 combine_extras = 0;
1135 combine_successes = 0;
1136
1137 rtl_hooks = combine_rtl_hooks;
1138
1139 reg_stat.safe_grow_cleared (nregs, true);
1140
1141 init_recog_no_volatile ();
1142
1143 /* Allocate array for insn info. */
1144 max_uid_known = get_max_uid ();
1145 uid_log_links = XCNEWVEC (struct insn_link *, max_uid_known + 1)((struct insn_link * *) xcalloc ((max_uid_known + 1), sizeof (
struct insn_link *)))
;
1146 uid_insn_cost = XCNEWVEC (int, max_uid_known + 1)((int *) xcalloc ((max_uid_known + 1), sizeof (int)));
1147 gcc_obstack_init (&insn_link_obstack)_obstack_begin (((&insn_link_obstack)), (memory_block_pool
::block_size), (0), (mempool_obstack_chunk_alloc), (mempool_obstack_chunk_free
))
;
1148
1149 nonzero_bits_mode = int_mode_for_size (HOST_BITS_PER_WIDE_INT64, 0).require ();
1150
1151 /* Don't use reg_stat[].nonzero_bits when computing it. This can cause
1152 problems when, for example, we have j <<= 1 in a loop. */
1153
1154 nonzero_sign_valid = 0;
1155 label_tick = label_tick_ebb_start = 1;
1156
1157 /* Scan all SETs and see if we can deduce anything about what
1158 bits are known to be zero for some registers and how many copies
1159 of the sign bit are known to exist for those registers.
1160
1161 Also set any known values so that we can use it while searching
1162 for what bits are known to be set. */
1163
1164 setup_incoming_promotions (first);
1165 /* Allow the entry block and the first block to fall into the same EBB.
1166 Conceptually the incoming promotions are assigned to the entry block. */
1167 last_bb = ENTRY_BLOCK_PTR_FOR_FN (cfun)(((cfun + 0))->cfg->x_entry_block_ptr);
1168
1169 create_log_links ();
1170 FOR_EACH_BB_FN (this_basic_block, cfun)for (this_basic_block = ((cfun + 0))->cfg->x_entry_block_ptr
->next_bb; this_basic_block != ((cfun + 0))->cfg->x_exit_block_ptr
; this_basic_block = this_basic_block->next_bb)
1171 {
1172 optimize_this_for_speed_p = optimize_bb_for_speed_p (this_basic_block);
1173 last_call_luid = 0;
1174 mem_last_set = -1;
1175
1176 label_tick++;
1177 if (!single_pred_p (this_basic_block)
1178 || single_pred (this_basic_block) != last_bb)
1179 label_tick_ebb_start = label_tick;
1180 last_bb = this_basic_block;
1181
1182 FOR_BB_INSNS (this_basic_block, insn)for ((insn) = (this_basic_block)->il.x.head_; (insn) &&
(insn) != NEXT_INSN ((this_basic_block)->il.x.rtl->end_
); (insn) = NEXT_INSN (insn))
1183 if (INSN_P (insn)(((((enum rtx_code) (insn)->code) == INSN) || (((enum rtx_code
) (insn)->code) == JUMP_INSN) || (((enum rtx_code) (insn)->
code) == CALL_INSN)) || (((enum rtx_code) (insn)->code) ==
DEBUG_INSN))
&& BLOCK_FOR_INSN (insn))
1184 {
1185 rtx links;
1186
1187 subst_low_luid = DF_INSN_LUID (insn)((((df->insns[(INSN_UID (insn))]))->luid));
1188 subst_insn = insn;
1189
1190 note_stores (insn, set_nonzero_bits_and_sign_copies, insn);
1191 record_dead_and_set_regs (insn);
1192
1193 if (AUTO_INC_DEC0)
1194 for (links = REG_NOTES (insn)(((insn)->u.fld[6]).rt_rtx); links; links = XEXP (links, 1)(((links)->u.fld[1]).rt_rtx))
1195 if (REG_NOTE_KIND (links)((enum reg_note) ((machine_mode) (links)->mode)) == REG_INC)
1196 set_nonzero_bits_and_sign_copies (XEXP (links, 0)(((links)->u.fld[0]).rt_rtx), NULL_RTX(rtx) 0,
1197 insn);
1198
1199 /* Record the current insn_cost of this instruction. */
1200 INSN_COST (insn)(uid_insn_cost[insn_uid_check (insn)]) = insn_cost (insn, optimize_this_for_speed_p);
1201 if (dump_file)
1202 {
1203 fprintf (dump_file, "insn_cost %d for ", INSN_COST (insn)(uid_insn_cost[insn_uid_check (insn)]));
1204 dump_insn_slim (dump_file, insn);
1205 }
1206 }
1207 }
1208
1209 nonzero_sign_valid = 1;
1210
1211 /* Now scan all the insns in forward order. */
1212 label_tick = label_tick_ebb_start = 1;
1213 init_reg_last ();
1214 setup_incoming_promotions (first);
1215 last_bb = ENTRY_BLOCK_PTR_FOR_FN (cfun)(((cfun + 0))->cfg->x_entry_block_ptr);
1216 int max_combine = param_max_combine_insnsglobal_options.x_param_max_combine_insns;
1217
1218 FOR_EACH_BB_FN (this_basic_block, cfun)for (this_basic_block = ((cfun + 0))->cfg->x_entry_block_ptr
->next_bb; this_basic_block != ((cfun + 0))->cfg->x_exit_block_ptr
; this_basic_block = this_basic_block->next_bb)
1219 {
1220 rtx_insn *last_combined_insn = NULLnullptr;
1221
1222 /* Ignore instruction combination in basic blocks that are going to
1223 be removed as unreachable anyway. See PR82386. */
1224 if (EDGE_COUNT (this_basic_block->preds)vec_safe_length (this_basic_block->preds) == 0)
1225 continue;
1226
1227 optimize_this_for_speed_p = optimize_bb_for_speed_p (this_basic_block);
1228 last_call_luid = 0;
1229 mem_last_set = -1;
1230
1231 label_tick++;
1232 if (!single_pred_p (this_basic_block)
1233 || single_pred (this_basic_block) != last_bb)
1234 label_tick_ebb_start = label_tick;
1235 last_bb = this_basic_block;
1236
1237 rtl_profile_for_bb (this_basic_block);
1238 for (insn = BB_HEAD (this_basic_block)(this_basic_block)->il.x.head_;
1239 insn != NEXT_INSN (BB_END (this_basic_block)(this_basic_block)->il.x.rtl->end_);
1240 insn = next ? next : NEXT_INSN (insn))
1241 {
1242 next = 0;
1243 if (!NONDEBUG_INSN_P (insn)((((enum rtx_code) (insn)->code) == INSN) || (((enum rtx_code
) (insn)->code) == JUMP_INSN) || (((enum rtx_code) (insn)->
code) == CALL_INSN))
)
1244 continue;
1245
1246 while (last_combined_insn
1247 && (!NONDEBUG_INSN_P (last_combined_insn)((((enum rtx_code) (last_combined_insn)->code) == INSN) ||
(((enum rtx_code) (last_combined_insn)->code) == JUMP_INSN
) || (((enum rtx_code) (last_combined_insn)->code) == CALL_INSN
))
1248 || last_combined_insn->deleted ()))
1249 last_combined_insn = PREV_INSN (last_combined_insn);
1250 if (last_combined_insn == NULL_RTX(rtx) 0
1251 || BLOCK_FOR_INSN (last_combined_insn) != this_basic_block
1252 || DF_INSN_LUID (last_combined_insn)((((df->insns[(INSN_UID (last_combined_insn))]))->luid)
)
<= DF_INSN_LUID (insn)((((df->insns[(INSN_UID (insn))]))->luid)))
1253 last_combined_insn = insn;
1254
1255 /* See if we know about function return values before this
1256 insn based upon SUBREG flags. */
1257 check_promoted_subreg (insn, PATTERN (insn));
1258
1259 /* See if we can find hardregs and subreg of pseudos in
1260 narrower modes. This could help turning TRUNCATEs
1261 into SUBREGs. */
1262 note_uses (&PATTERN (insn), record_truncated_values, NULLnullptr);
1263
1264 /* Try this insn with each insn it links back to. */
1265
1266 FOR_EACH_LOG_LINK (links, insn)for ((links) = (uid_log_links[insn_uid_check (insn)]); (links
); (links) = (links)->next)
1267 if ((next = try_combine (insn, links->insn, NULLnullptr,
1268 NULLnullptr, &new_direct_jump_p,
1269 last_combined_insn)) != 0)
1270 {
1271 statistics_counter_event (cfun(cfun + 0), "two-insn combine", 1);
1272 goto retry;
1273 }
1274
1275 /* Try each sequence of three linked insns ending with this one. */
1276
1277 if (max_combine >= 3)
1278 FOR_EACH_LOG_LINK (links, insn)for ((links) = (uid_log_links[insn_uid_check (insn)]); (links
); (links) = (links)->next)
1279 {
1280 rtx_insn *link = links->insn;
1281
1282 /* If the linked insn has been replaced by a note, then there
1283 is no point in pursuing this chain any further. */
1284 if (NOTE_P (link)(((enum rtx_code) (link)->code) == NOTE))
1285 continue;
1286
1287 FOR_EACH_LOG_LINK (nextlinks, link)for ((nextlinks) = (uid_log_links[insn_uid_check (link)]); (nextlinks
); (nextlinks) = (nextlinks)->next)
1288 if ((next = try_combine (insn, link, nextlinks->insn,
1289 NULLnullptr, &new_direct_jump_p,
1290 last_combined_insn)) != 0)
1291 {
1292 statistics_counter_event (cfun(cfun + 0), "three-insn combine", 1);
1293 goto retry;
1294 }
1295 }
1296
1297 /* Try combining an insn with two different insns whose results it
1298 uses. */
1299 if (max_combine >= 3)
1300 FOR_EACH_LOG_LINK (links, insn)for ((links) = (uid_log_links[insn_uid_check (insn)]); (links
); (links) = (links)->next)
1301 for (nextlinks = links->next; nextlinks;
1302 nextlinks = nextlinks->next)
1303 if ((next = try_combine (insn, links->insn,
1304 nextlinks->insn, NULLnullptr,
1305 &new_direct_jump_p,
1306 last_combined_insn)) != 0)
1307
1308 {
1309 statistics_counter_event (cfun(cfun + 0), "three-insn combine", 1);
1310 goto retry;
1311 }
1312
1313 /* Try four-instruction combinations. */
1314 if (max_combine >= 4)
1315 FOR_EACH_LOG_LINK (links, insn)for ((links) = (uid_log_links[insn_uid_check (insn)]); (links
); (links) = (links)->next)
1316 {
1317 struct insn_link *next1;
1318 rtx_insn *link = links->insn;
1319
1320 /* If the linked insn has been replaced by a note, then there
1321 is no point in pursuing this chain any further. */
1322 if (NOTE_P (link)(((enum rtx_code) (link)->code) == NOTE))
1323 continue;
1324
1325 FOR_EACH_LOG_LINK (next1, link)for ((next1) = (uid_log_links[insn_uid_check (link)]); (next1
); (next1) = (next1)->next)
1326 {
1327 rtx_insn *link1 = next1->insn;
1328 if (NOTE_P (link1)(((enum rtx_code) (link1)->code) == NOTE))
1329 continue;
1330 /* I0 -> I1 -> I2 -> I3. */
1331 FOR_EACH_LOG_LINK (nextlinks, link1)for ((nextlinks) = (uid_log_links[insn_uid_check (link1)]); (
nextlinks); (nextlinks) = (nextlinks)->next)
1332 if ((next = try_combine (insn, link, link1,
1333 nextlinks->insn,
1334 &new_direct_jump_p,
1335 last_combined_insn)) != 0)
1336 {
1337 statistics_counter_event (cfun(cfun + 0), "four-insn combine", 1);
1338 goto retry;
1339 }
1340 /* I0, I1 -> I2, I2 -> I3. */
1341 for (nextlinks = next1->next; nextlinks;
1342 nextlinks = nextlinks->next)
1343 if ((next = try_combine (insn, link, link1,
1344 nextlinks->insn,
1345 &new_direct_jump_p,
1346 last_combined_insn)) != 0)
1347 {
1348 statistics_counter_event (cfun(cfun + 0), "four-insn combine", 1);
1349 goto retry;
1350 }
1351 }
1352
1353 for (next1 = links->next; next1; next1 = next1->next)
1354 {
1355 rtx_insn *link1 = next1->insn;
1356 if (NOTE_P (link1)(((enum rtx_code) (link1)->code) == NOTE))
1357 continue;
1358 /* I0 -> I2; I1, I2 -> I3. */
1359 FOR_EACH_LOG_LINK (nextlinks, link)for ((nextlinks) = (uid_log_links[insn_uid_check (link)]); (nextlinks
); (nextlinks) = (nextlinks)->next)
1360 if ((next = try_combine (insn, link, link1,
1361 nextlinks->insn,
1362 &new_direct_jump_p,
1363 last_combined_insn)) != 0)
1364 {
1365 statistics_counter_event (cfun(cfun + 0), "four-insn combine", 1);
1366 goto retry;
1367 }
1368 /* I0 -> I1; I1, I2 -> I3. */
1369 FOR_EACH_LOG_LINK (nextlinks, link1)for ((nextlinks) = (uid_log_links[insn_uid_check (link1)]); (
nextlinks); (nextlinks) = (nextlinks)->next)
1370 if ((next = try_combine (insn, link, link1,
1371 nextlinks->insn,
1372 &new_direct_jump_p,
1373 last_combined_insn)) != 0)
1374 {
1375 statistics_counter_event (cfun(cfun + 0), "four-insn combine", 1);
1376 goto retry;
1377 }
1378 }
1379 }
1380
1381 /* Try this insn with each REG_EQUAL note it links back to. */
1382 FOR_EACH_LOG_LINK (links, insn)for ((links) = (uid_log_links[insn_uid_check (insn)]); (links
); (links) = (links)->next)
1383 {
1384 rtx set, note;
1385 rtx_insn *temp = links->insn;
1386 if ((set = single_set (temp)) != 0
1387 && (note = find_reg_equal_equiv_note (temp)) != 0
1388 && (note = XEXP (note, 0)(((note)->u.fld[0]).rt_rtx), GET_CODE (note)((enum rtx_code) (note)->code)) != EXPR_LIST
1389 && ! side_effects_p (SET_SRC (set)(((set)->u.fld[1]).rt_rtx))
1390 /* Avoid using a register that may already been marked
1391 dead by an earlier instruction. */
1392 && ! unmentioned_reg_p (note, SET_SRC (set)(((set)->u.fld[1]).rt_rtx))
1393 && (GET_MODE (note)((machine_mode) (note)->mode) == VOIDmode((void) 0, E_VOIDmode)
1394 ? SCALAR_INT_MODE_P (GET_MODE (SET_DEST (set)))(((enum mode_class) mode_class[((machine_mode) ((((set)->u
.fld[0]).rt_rtx))->mode)]) == MODE_INT || ((enum mode_class
) mode_class[((machine_mode) ((((set)->u.fld[0]).rt_rtx))->
mode)]) == MODE_PARTIAL_INT)
1395 : (GET_MODE (SET_DEST (set))((machine_mode) ((((set)->u.fld[0]).rt_rtx))->mode) == GET_MODE (note)((machine_mode) (note)->mode)
1396 && (GET_CODE (SET_DEST (set))((enum rtx_code) ((((set)->u.fld[0]).rt_rtx))->code) != ZERO_EXTRACT
1397 || (GET_MODE (XEXP (SET_DEST (set), 0))((machine_mode) (((((((set)->u.fld[0]).rt_rtx))->u.fld[
0]).rt_rtx))->mode)
1398 == GET_MODE (note)((machine_mode) (note)->mode))))))
1399 {
1400 /* Temporarily replace the set's source with the
1401 contents of the REG_EQUAL note. The insn will
1402 be deleted or recognized by try_combine. */
1403 rtx orig_src = SET_SRC (set)(((set)->u.fld[1]).rt_rtx);
1404 rtx orig_dest = SET_DEST (set)(((set)->u.fld[0]).rt_rtx);
1405 if (GET_CODE (SET_DEST (set))((enum rtx_code) ((((set)->u.fld[0]).rt_rtx))->code) == ZERO_EXTRACT)
1406 SET_DEST (set)(((set)->u.fld[0]).rt_rtx) = XEXP (SET_DEST (set), 0)((((((set)->u.fld[0]).rt_rtx))->u.fld[0]).rt_rtx);
1407 SET_SRC (set)(((set)->u.fld[1]).rt_rtx) = note;
1408 i2mod = temp;
1409 i2mod_old_rhs = copy_rtx (orig_src);
1410 i2mod_new_rhs = copy_rtx (note);
1411 next = try_combine (insn, i2mod, NULLnullptr, NULLnullptr,
1412 &new_direct_jump_p,
1413 last_combined_insn);
1414 i2mod = NULLnullptr;
1415 if (next)
1416 {
1417 statistics_counter_event (cfun(cfun + 0), "insn-with-note combine", 1);
1418 goto retry;
1419 }
1420 SET_SRC (set)(((set)->u.fld[1]).rt_rtx) = orig_src;
1421 SET_DEST (set)(((set)->u.fld[0]).rt_rtx) = orig_dest;
1422 }
1423 }
1424
1425 if (!NOTE_P (insn)(((enum rtx_code) (insn)->code) == NOTE))
1426 record_dead_and_set_regs (insn);
1427
1428retry:
1429 ;
1430 }
1431 }
1432
1433 default_rtl_profile ();
1434 clear_bb_flags ();
1435 new_direct_jump_p |= purge_all_dead_edges ();
1436 new_direct_jump_p |= delete_noop_moves ();
1437
1438 /* Clean up. */
1439 obstack_free (&insn_link_obstack, NULL)__extension__ ({ struct obstack *__o = (&insn_link_obstack
); void *__obj = (void *) (nullptr); if (__obj > (void *) __o
->chunk && __obj < (void *) __o->chunk_limit
) __o->next_free = __o->object_base = (char *) __obj; else
_obstack_free (__o, __obj); })
;
1440 free (uid_log_links);
1441 free (uid_insn_cost);
1442 reg_stat.release ();
1443
1444 {
1445 struct undo *undo, *next;
1446 for (undo = undobuf.frees; undo; undo = next)
1447 {
1448 next = undo->next;
1449 free (undo);
1450 }
1451 undobuf.frees = 0;
1452 }
1453
1454 total_attempts += combine_attempts;
1455 total_merges += combine_merges;
1456 total_extras += combine_extras;
1457 total_successes += combine_successes;
1458
1459 nonzero_sign_valid = 0;
1460 rtl_hooks = general_rtl_hooks;
1461
1462 /* Make recognizer allow volatile MEMs again. */
1463 init_recog ();
1464
1465 return new_direct_jump_p;
1466}
1467
1468/* Wipe the last_xxx fields of reg_stat in preparation for another pass. */
1469
1470static void
1471init_reg_last (void)
1472{
1473 unsigned int i;
1474 reg_stat_type *p;
1475
1476 FOR_EACH_VEC_ELT (reg_stat, i, p)for (i = 0; (reg_stat).iterate ((i), &(p)); ++(i))
1477 memset (p, 0, offsetof (reg_stat_type, sign_bit_copies)__builtin_offsetof(reg_stat_type, sign_bit_copies));
1478}
1479
1480/* Set up any promoted values for incoming argument registers. */
1481
1482static void
1483setup_incoming_promotions (rtx_insn *first)
1484{
1485 tree arg;
1486 bool strictly_local = false;
1487
1488 for (arg = DECL_ARGUMENTS (current_function_decl)((tree_check ((current_function_decl), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/combine.c"
, 1488, __FUNCTION__, (FUNCTION_DECL)))->function_decl.arguments
)
; arg;
1489 arg = DECL_CHAIN (arg)(((contains_struct_check (((contains_struct_check ((arg), (TS_DECL_MINIMAL
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/combine.c"
, 1489, __FUNCTION__))), (TS_COMMON), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/combine.c"
, 1489, __FUNCTION__))->common.chain))
)
1490 {
1491 rtx x, reg = DECL_INCOMING_RTL (arg)((tree_check ((arg), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/combine.c"
, 1491, __FUNCTION__, (PARM_DECL)))->parm_decl.incoming_rtl
)
;
1492 int uns1, uns3;
1493 machine_mode mode1, mode2, mode3, mode4;
1494
1495 /* Only continue if the incoming argument is in a register. */
1496 if (!REG_P (reg)(((enum rtx_code) (reg)->code) == REG))
1497 continue;
1498
1499 /* Determine, if possible, whether all call sites of the current
1500 function lie within the current compilation unit. (This does
1501 take into account the exporting of a function via taking its
1502 address, and so forth.) */
1503 strictly_local
1504 = cgraph_node::local_info_node (current_function_decl)->local;
1505
1506 /* The mode and signedness of the argument before any promotions happen
1507 (equal to the mode of the pseudo holding it at that stage). */
1508 mode1 = TYPE_MODE (TREE_TYPE (arg))((((enum tree_code) ((tree_class_check ((((contains_struct_check
((arg), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/combine.c"
, 1508, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/combine.c"
, 1508, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(((contains_struct_check ((arg), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/combine.c"
, 1508, __FUNCTION__))->typed.type)) : (((contains_struct_check
((arg), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/combine.c"
, 1508, __FUNCTION__))->typed.type))->type_common.mode)
;
1509 uns1 = TYPE_UNSIGNED (TREE_TYPE (arg))((tree_class_check ((((contains_struct_check ((arg), (TS_TYPED
), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/combine.c"
, 1509, __FUNCTION__))->typed.type)), (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/combine.c"
, 1509, __FUNCTION__))->base.u.bits.unsigned_flag)
;
1510
1511 /* The mode and signedness of the argument after any source language and
1512 TARGET_PROMOTE_PROTOTYPES-driven promotions. */
1513 mode2 = TYPE_MODE (DECL_ARG_TYPE (arg))((((enum tree_code) ((tree_class_check ((((tree_check ((arg),
"/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/combine.c"
, 1513, __FUNCTION__, (PARM_DECL)))->decl_common.initial))
, (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/combine.c"
, 1513, __FUNCTION__)))->base.code) == VECTOR_TYPE) ? vector_type_mode
(((tree_check ((arg), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/combine.c"
, 1513, __FUNCTION__, (PARM_DECL)))->decl_common.initial))
: (((tree_check ((arg), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/combine.c"
, 1513, __FUNCTION__, (PARM_DECL)))->decl_common.initial))
->type_common.mode)
;
1514 uns3 = TYPE_UNSIGNED (DECL_ARG_TYPE (arg))((tree_class_check ((((tree_check ((arg), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/combine.c"
, 1514, __FUNCTION__, (PARM_DECL)))->decl_common.initial))
, (tcc_type), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/combine.c"
, 1514, __FUNCTION__))->base.u.bits.unsigned_flag)
;
1515
1516 /* The mode and signedness of the argument as it is actually passed,
1517 see assign_parm_setup_reg in function.c. */
1518 mode3 = promote_function_mode (TREE_TYPE (arg)((contains_struct_check ((arg), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/combine.c"
, 1518, __FUNCTION__))->typed.type)
, mode1, &uns3,
1519 TREE_TYPE (cfun->decl)((contains_struct_check (((cfun + 0)->decl), (TS_TYPED), "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/combine.c"
, 1519, __FUNCTION__))->typed.type)
, 0);
1520
1521 /* The mode of the register in which the argument is being passed. */
1522 mode4 = GET_MODE (reg)((machine_mode) (reg)->mode);
1523
1524 /* Eliminate sign extensions in the callee when:
1525 (a) A mode promotion has occurred; */
1526 if (mode1 == mode3)
1527 continue;
1528 /* (b) The mode of the register is the same as the mode of
1529 the argument as it is passed; */
1530 if (mode3 != mode4)
1531 continue;
1532 /* (c) There's no language level extension; */
1533 if (mode1 == mode2)
1534 ;
1535 /* (c.1) All callers are from the current compilation unit. If that's
1536 the case we don't have to rely on an ABI, we only have to know
1537 what we're generating right now, and we know that we will do the
1538 mode1 to mode2 promotion with the given sign. */
1539 else if (!strictly_local)
1540 continue;
1541 /* (c.2) The combination of the two promotions is useful. This is
1542 true when the signs match, or if the first promotion is unsigned.
1543 In the later case, (sign_extend (zero_extend x)) is the same as
1544 (zero_extend (zero_extend x)), so make sure to force UNS3 true. */
1545 else if (uns1)
1546 uns3 = true;
1547 else if (uns3)
1548 continue;
1549
1550 /* Record that the value was promoted from mode1 to mode3,
1551 so that any sign extension at the head of the current
1552 function may be eliminated. */
1553 x = gen_rtx_CLOBBER (mode1, const0_rtx)gen_rtx_fmt_e_stat ((CLOBBER), ((mode1)), (((const_int_rtx[64
]))) )
;
1554 x = gen_rtx_fmt_e ((uns3 ? ZERO_EXTEND : SIGN_EXTEND), mode3, x)gen_rtx_fmt_e_stat (((uns3 ? ZERO_EXTEND : SIGN_EXTEND)), (mode3
), (x) )
;
1555 record_value_for_reg (reg, first, x);
1556 }
1557}
1558
1559/* If MODE has a precision lower than PREC and SRC is a non-negative constant
1560 that would appear negative in MODE, sign-extend SRC for use in nonzero_bits
1561 because some machines (maybe most) will actually do the sign-extension and
1562 this is the conservative approach.
1563
1564 ??? For 2.5, try to tighten up the MD files in this regard instead of this
1565 kludge. */
1566
1567static rtx
1568sign_extend_short_imm (rtx src, machine_mode mode, unsigned int prec)
1569{
1570 scalar_int_mode int_mode;
1571 if (CONST_INT_P (src)(((enum rtx_code) (src)->code) == CONST_INT)
1572 && is_a <scalar_int_mode> (mode, &int_mode)
1573 && GET_MODE_PRECISION (int_mode) < prec
1574 && INTVAL (src)((src)->u.hwint[0]) > 0
1575 && val_signbit_known_set_p (int_mode, INTVAL (src)((src)->u.hwint[0])))
1576 src = GEN_INT (INTVAL (src) | ~GET_MODE_MASK (int_mode))gen_rtx_CONST_INT (((void) 0, E_VOIDmode), (((src)->u.hwint
[0]) | ~mode_mask_array[int_mode]))
;
1577
1578 return src;
1579}
1580
1581/* Update RSP for pseudo-register X from INSN's REG_EQUAL note (if one exists)
1582 and SET. */
1583
1584static void
1585update_rsp_from_reg_equal (reg_stat_type *rsp, rtx_insn *insn, const_rtx set,
1586 rtx x)
1587{
1588 rtx reg_equal_note = insn ? find_reg_equal_equiv_note (insn) : NULL_RTX(rtx) 0;
1589 unsigned HOST_WIDE_INTlong bits = 0;
1590 rtx reg_equal = NULLnullptr, src = SET_SRC (set)(((set)->u.fld[1]).rt_rtx);
1591 unsigned int num = 0;
1592
1593 if (reg_equal_note)
1594 reg_equal = XEXP (reg_equal_note, 0)(((reg_equal_note)->u.fld[0]).rt_rtx);
1595
1596 if (SHORT_IMMEDIATES_SIGN_EXTEND0)
1597 {
1598 src = sign_extend_short_imm (src, GET_MODE (x)((machine_mode) (x)->mode), BITS_PER_WORD((8) * (((global_options.x_ix86_isa_flags & (1UL <<
1)) != 0) ? 8 : 4))
);
1599 if (reg_equal)
1600 reg_equal = sign_extend_short_imm (reg_equal, GET_MODE (x)((machine_mode) (x)->mode), BITS_PER_WORD((8) * (((global_options.x_ix86_isa_flags & (1UL <<
1)) != 0) ? 8 : 4))
);
1601 }
1602
1603 /* Don't call nonzero_bits if it cannot change anything. */
1604 if (rsp->nonzero_bits != HOST_WIDE_INT_M1U-1UL)
1605 {
1606 machine_mode mode = GET_MODE (x)((machine_mode) (x)->mode);
1607 if (GET_MODE_CLASS (mode)((enum mode_class) mode_class[mode]) == MODE_INT
1608 && HWI_COMPUTABLE_MODE_P (mode))
1609 mode = nonzero_bits_mode;
1610 bits = nonzero_bits (src, mode);
1611 if (reg_equal && bits)
1612 bits &= nonzero_bits (reg_equal, mode);
1613 rsp->nonzero_bits |= bits;
1614 }
1615
1616 /* Don't call num_sign_bit_copies if it cannot change anything. */
1617 if (rsp->sign_bit_copies != 1)
1618 {
1619 num = num_sign_bit_copies (SET_SRC (set)(((set)->u.fld[1]).rt_rtx), GET_MODE (x)((machine_mode) (x)->mode));
1620 if (reg_equal && maybe_ne (num, GET_MODE_PRECISION (GET_MODE (x)((machine_mode) (x)->mode))))
1621 {
1622 unsigned int numeq = num_sign_bit_copies (reg_equal, GET_MODE (x)((machine_mode) (x)->mode));
1623 if (num == 0 || numeq > num)
1624 num = numeq;
1625 }
1626 if (rsp->sign_bit_copies == 0 || num < rsp->sign_bit_copies)
1627 rsp->sign_bit_copies = num;
1628 }
1629}
1630
1631/* Called via note_stores. If X is a pseudo that is narrower than
1632 HOST_BITS_PER_WIDE_INT and is being set, record what bits are known zero.
1633
1634 If we are setting only a portion of X and we can't figure out what
1635 portion, assume all bits will be used since we don't know what will
1636 be happening.
1637
1638 Similarly, set how many bits of X are known to be copies of the sign bit
1639 at all locations in the function. This is the smallest number implied
1640 by any set of X. */
1641
1642static void
1643set_nonzero_bits_and_sign_copies (rtx x, const_rtx set, void *data)
1644{
1645 rtx_insn *insn = (rtx_insn *) data;
1646 scalar_int_mode mode;
1647
1648 if (REG_P (x)(((enum rtx_code) (x)->code) == REG)
1649 && REGNO (x)(rhs_regno(x)) >= FIRST_PSEUDO_REGISTER76
1650 /* If this register is undefined at the start of the file, we can't
1651 say what its contents were. */
1652 && ! REGNO_REG_SET_Pbitmap_bit_p ((&(df_lr_get_bb_info (((((cfun + 0))->cfg
->x_entry_block_ptr)->next_bb)->index))->in), (rhs_regno
(x)))
1653 (DF_LR_IN (ENTRY_BLOCK_PTR_FOR_FN (cfun)->next_bb), REGNO (x))bitmap_bit_p ((&(df_lr_get_bb_info (((((cfun + 0))->cfg
->x_entry_block_ptr)->next_bb)->index))->in), (rhs_regno
(x)))
1654 && is_a <scalar_int_mode> (GET_MODE (x)((machine_mode) (x)->mode), &mode)
1655 && HWI_COMPUTABLE_MODE_P (mode))
1656 {
1657 reg_stat_type *rsp = &reg_stat[REGNO (x)(rhs_regno(x))];
1658
1659 if (set == 0 || GET_CODE (set)((enum rtx_code) (set)->code) == CLOBBER)
1660 {
1661 rsp->nonzero_bits = GET_MODE_MASK (mode)mode_mask_array[mode];
1662 rsp->sign_bit_copies = 1;
1663 return;
1664 }
1665
1666 /* If this register is being initialized using itself, and the
1667 register is uninitialized in this basic block, and there are
1668 no LOG_LINKS which set the register, then part of the
1669 register is uninitialized. In that case we can't assume
1670 anything about the number of nonzero bits.
1671
1672 ??? We could do better if we checked this in
1673 reg_{nonzero_bits,num_sign_bit_copies}_for_combine. Then we
1674 could avoid making assumptions about the insn which initially
1675 sets the register, while still using the information in other
1676 insns. We would have to be careful to check every insn
1677 involved in the combination. */
1678
1679 if (insn
1680 && reg_referenced_p (x, PATTERN (insn))
1681 && !REGNO_REG_SET_P (DF_LR_IN (BLOCK_FOR_INSN (insn)),bitmap_bit_p ((&(df_lr_get_bb_info ((BLOCK_FOR_INSN (insn
))->index))->in), (rhs_regno(x)))
1682 REGNO (x))bitmap_bit_p ((&(df_lr_get_bb_info ((BLOCK_FOR_INSN (insn
))->index))->in), (rhs_regno(x)))
)
1683 {
1684 struct insn_link *link;
1685
1686 FOR_EACH_LOG_LINK (link, insn)for ((link) = (uid_log_links[insn_uid_check (insn)]); (link);
(link) = (link)->next)
1687 if (dead_or_set_p (link->insn, x))
1688 break;
1689 if (!link)
1690 {
1691 rsp->nonzero_bits = GET_MODE_MASK (mode)mode_mask_array[mode];
1692 rsp->sign_bit_copies = 1;
1693 return;
1694 }
1695 }
1696
1697 /* If this is a complex assignment, see if we can convert it into a
1698 simple assignment. */
1699 set = expand_field_assignment (set);
1700
1701 /* If this is a simple assignment, or we have a paradoxical SUBREG,
1702 set what we know about X. */
1703
1704 if (SET_DEST (set)(((set)->u.fld[0]).rt_rtx) == x
1705 || (paradoxical_subreg_p (SET_DEST (set)(((set)->u.fld[0]).rt_rtx))
1706 && SUBREG_REG (SET_DEST (set))((((((set)->u.fld[0]).rt_rtx))->u.fld[0]).rt_rtx) == x))
1707 update_rsp_from_reg_equal (rsp, insn, set, x);
1708 else
1709 {
1710 rsp->nonzero_bits = GET_MODE_MASK (mode)mode_mask_array[mode];
1711 rsp->sign_bit_copies = 1;
1712 }
1713 }
1714}
1715
1716/* See if INSN can be combined into I3. PRED, PRED2, SUCC and SUCC2 are
1717 optionally insns that were previously combined into I3 or that will be
1718 combined into the merger of INSN and I3. The order is PRED, PRED2,
1719 INSN, SUCC, SUCC2, I3.
1720
1721 Return 0 if the combination is not allowed for any reason.
1722
1723 If the combination is allowed, *PDEST will be set to the single
1724 destination of INSN and *PSRC to the single source, and this function
1725 will return 1. */
1726
1727static int
1728can_combine_p (rtx_insn *insn, rtx_insn *i3, rtx_insn *pred ATTRIBUTE_UNUSED__attribute__ ((__unused__)),
1729 rtx_insn *pred2 ATTRIBUTE_UNUSED__attribute__ ((__unused__)), rtx_insn *succ, rtx_insn *succ2,
1730 rtx *pdest, rtx *psrc)
1731{
1732 int i;
1733 const_rtx set = 0;
1734 rtx src, dest;
1735 rtx_insn *p;
1736 rtx link;
1737 bool all_adjacent = true;
1738 int (*is_volatile_p) (const_rtx);
1739
1740 if (succ)
1741 {
1742 if (succ2)
1743 {
1744 if (next_active_insn (succ2) != i3)
1745 all_adjacent = false;
1746 if (next_active_insn (succ) != succ2)
1747 all_adjacent = false;
1748 }
1749 else if (next_active_insn (succ) != i3)
1750 all_adjacent = false;
1751 if (next_active_insn (insn) != succ)
1752 all_adjacent = false;
1753 }
1754 else if (next_active_insn (insn) != i3)
1755 all_adjacent = false;
1756
1757 /* Can combine only if previous insn is a SET of a REG or a SUBREG,
1758 or a PARALLEL consisting of such a SET and CLOBBERs.
1759
1760 If INSN has CLOBBER parallel parts, ignore them for our processing.
1761 By definition, these happen during the execution of the insn. When it
1762 is merged with another insn, all bets are off. If they are, in fact,
1763 needed and aren't also supplied in I3, they may be added by
1764 recog_for_combine. Otherwise, it won't match.
1765
1766 We can also ignore a SET whose SET_DEST is mentioned in a REG_UNUSED
1767 note.
1768
1769 Get the source and destination of INSN. If more than one, can't
1770 combine. */
1771
1772 if (GET_CODE (PATTERN (insn))((enum rtx_code) (PATTERN (insn))->code) == SET)
1773 set = PATTERN (insn);
1774 else if (GET_CODE (PATTERN (insn))((enum rtx_code) (PATTERN (insn))->code) == PARALLEL
1775 && GET_CODE (XVECEXP (PATTERN (insn), 0, 0))((enum rtx_code) ((((((PATTERN (insn))->u.fld[0]).rt_rtvec
))->elem[0]))->code)
== SET)
1776 {
1777 for (i = 0; i < XVECLEN (PATTERN (insn), 0)(((((PATTERN (insn))->u.fld[0]).rt_rtvec))->num_elem); i++)
1778 {
1779 rtx elt = XVECEXP (PATTERN (insn), 0, i)(((((PATTERN (insn))->u.fld[0]).rt_rtvec))->elem[i]);
1780
1781 switch (GET_CODE (elt)((enum rtx_code) (elt)->code))
1782 {
1783 /* This is important to combine floating point insns
1784 for the SH4 port. */
1785 case USE:
1786 /* Combining an isolated USE doesn't make sense.
1787 We depend here on combinable_i3pat to reject them. */
1788 /* The code below this loop only verifies that the inputs of
1789 the SET in INSN do not change. We call reg_set_between_p
1790 to verify that the REG in the USE does not change between
1791 I3 and INSN.
1792 If the USE in INSN was for a pseudo register, the matching
1793 insn pattern will likely match any register; combining this
1794 with any other USE would only be safe if we knew that the
1795 used registers have identical values, or if there was
1796 something to tell them apart, e.g. different modes. For
1797 now, we forgo such complicated tests and simply disallow
1798 combining of USES of pseudo registers with any other USE. */
1799 if (REG_P (XEXP (elt, 0))(((enum rtx_code) ((((elt)->u.fld[0]).rt_rtx))->code) ==
REG)
1800 && GET_CODE (PATTERN (i3))((enum rtx_code) (PATTERN (i3))->code) == PARALLEL)
1801 {
1802 rtx i3pat = PATTERN (i3);
1803 int i = XVECLEN (i3pat, 0)(((((i3pat)->u.fld[0]).rt_rtvec))->num_elem) - 1;
1804 unsigned int regno = REGNO (XEXP (elt, 0))(rhs_regno((((elt)->u.fld[0]).rt_rtx)));
1805
1806 do
1807 {
1808 rtx i3elt = XVECEXP (i3pat, 0, i)(((((i3pat)->u.fld[0]).rt_rtvec))->elem[i]);
1809
1810 if (GET_CODE (i3elt)((enum rtx_code) (i3elt)->code) == USE
1811 && REG_P (XEXP (i3elt, 0))(((enum rtx_code) ((((i3elt)->u.fld[0]).rt_rtx))->code)
== REG)
1812 && (REGNO (XEXP (i3elt, 0))(rhs_regno((((i3elt)->u.fld[0]).rt_rtx))) == regno
1813 ? reg_set_between_p (XEXP (elt, 0)(((elt)->u.fld[0]).rt_rtx),
1814 PREV_INSN (insn), i3)
1815 : regno >= FIRST_PSEUDO_REGISTER76))
1816 return 0;
1817 }
1818 while (--i >= 0);
1819 }
1820 break;
1821
1822 /* We can ignore CLOBBERs. */
1823 case CLOBBER:
1824 break;
1825
1826 case SET:
1827 /* Ignore SETs whose result isn't used but not those that
1828 have side-effects. */
1829 if (find_reg_note (insn, REG_UNUSED, SET_DEST (elt)(((elt)->u.fld[0]).rt_rtx))
1830 && insn_nothrow_p (insn)
1831 && !side_effects_p (elt))
1832 break;
1833
1834 /* If we have already found a SET, this is a second one and
1835 so we cannot combine with this insn. */
1836 if (set)
1837 return 0;
1838
1839 set = elt;
1840 break;
1841
1842 default:
1843 /* Anything else means we can't combine. */
1844 return 0;
1845 }
1846 }
1847
1848 if (set == 0
1849 /* If SET_SRC is an ASM_OPERANDS we can't throw away these CLOBBERs,
1850 so don't do anything with it. */
1851 || GET_CODE (SET_SRC (set))((enum rtx_code) ((((set)->u.fld[1]).rt_rtx))->code) == ASM_OPERANDS)
1852 return 0;
1853 }
1854 else
1855 return 0;
1856
1857 if (set == 0)
1858 return 0;
1859
1860 /* The simplification in expand_field_assignment may call back to
1861 get_last_value, so set safe guard here. */
1862 subst_low_luid = DF_INSN_LUID (insn)((((df->insns[(INSN_UID (insn))]))->luid));
1863
1864 set = expand_field_assignment (set);
1865 src = SET_SRC (set)(((set)->u.fld[1]).rt_rtx), dest = SET_DEST (set)(((set)->u.fld[0]).rt_rtx);
1866
1867 /* Do not eliminate user-specified register if it is in an
1868 asm input because we may break the register asm usage defined
1869 in GCC manual if allow to do so.
1870 Be aware that this may cover more cases than we expect but this
1871 should be harmless. */
1872 if (REG_P (dest)(((enum rtx_code) (dest)->code) == REG) && REG_USERVAR_P (dest)(__extension__ ({ __typeof ((dest)) const _rtx = ((dest)); if
(((enum rtx_code) (_rtx)->code) != REG) rtl_check_failed_flag
("REG_USERVAR_P", _rtx, "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/combine.c"
, 1872, __FUNCTION__); _rtx; })->volatil)
&& HARD_REGISTER_P (dest)((((rhs_regno(dest))) < 76))
1873 && extract_asm_operands (PATTERN (i3)))
1874 return 0;
1875
1876 /* Don't eliminate a store in the stack pointer. */
1877 if (dest == stack_pointer_rtx((this_target_rtl->x_global_rtl)[GR_STACK_POINTER])
1878 /* Don't combine with an insn that sets a register to itself if it has
1879 a REG_EQUAL note. This may be part of a LIBCALL sequence. */
1880 || (rtx_equal_p (src, dest) && find_reg_note (insn, REG_EQUAL, NULL_RTX(rtx) 0))
1881 /* Can't merge an ASM_OPERANDS. */
1882 || GET_CODE (src)((enum rtx_code) (src)->code) == ASM_OPERANDS
1883 /* Can't merge a function call. */
1884 || GET_CODE (src)((enum rtx_code) (src)->code) == CALL
1885 /* Don't eliminate a function call argument. */
1886 || (CALL_P (i3)(((enum rtx_code) (i3)->code) == CALL_INSN)
1887 && (find_reg_fusage (i3, USE, dest)
1888 || (REG_P (dest)(((enum rtx_code) (dest)->code) == REG)
1889 && REGNO (dest)(rhs_regno(dest)) < FIRST_PSEUDO_REGISTER76
1890 && global_regs[REGNO (dest)(rhs_regno(dest))])))
1891 /* Don't substitute into an incremented register. */
1892 || FIND_REG_INC_NOTE (i3, dest)0
1893 || (succ && FIND_REG_INC_NOTE (succ, dest)0)
1894 || (succ2 && FIND_REG_INC_NOTE (succ2, dest)0)
1895 /* Don't substitute into a non-local goto, this confuses CFG. */
1896 || (JUMP_P (i3)(((enum rtx_code) (i3)->code) == JUMP_INSN) && find_reg_note (i3, REG_NON_LOCAL_GOTO, NULL_RTX(rtx) 0))
1897 /* Make sure that DEST is not used after INSN but before SUCC, or
1898 after SUCC and before SUCC2, or after SUCC2 but before I3. */
1899 || (!all_adjacent
1900 && ((succ2
1901 && (reg_used_between_p (dest, succ2, i3)
1902 || reg_used_between_p (dest, succ, succ2)))
1903 || (!succ2 && succ && reg_used_between_p (dest, succ, i3))
1904 || (!succ2 && !succ && reg_used_between_p (dest, insn, i3))
1905 || (succ
1906 /* SUCC and SUCC2 can be split halves from a PARALLEL; in
1907 that case SUCC is not in the insn stream, so use SUCC2
1908 instead for this test. */
1909 && reg_used_between_p (dest, insn,
1910 succ2
1911 && INSN_UID (succ) == INSN_UID (succ2)
1912 ? succ2 : succ))))
1913 /* Make sure that the value that is to be substituted for the register
1914 does not use any registers whose values alter in between. However,
1915 If the insns are adjacent, a use can't cross a set even though we
1916 think it might (this can happen for a sequence of insns each setting
1917 the same destination; last_set of that register might point to
1918 a NOTE). If INSN has a REG_EQUIV note, the register is always
1919 equivalent to the memory so the substitution is valid even if there
1920 are intervening stores. Also, don't move a volatile asm or
1921 UNSPEC_VOLATILE across any other insns. */
1922 || (! all_adjacent
1923 && (((!MEM_P (src)(((enum rtx_code) (src)->code) == MEM)
1924 || ! find_reg_note (insn, REG_EQUIV, src))
1925 && modified_between_p (src, insn, i3))
1926 || (GET_CODE (src)((enum rtx_code) (src)->code) == ASM_OPERANDS && MEM_VOLATILE_P (src)(__extension__ ({ __typeof ((src)) const _rtx = ((src)); if (
((enum rtx_code) (_rtx)->code) != MEM && ((enum rtx_code
) (_rtx)->code) != ASM_OPERANDS && ((enum rtx_code
) (_rtx)->code) != ASM_INPUT) rtl_check_failed_flag ("MEM_VOLATILE_P"
, _rtx, "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/combine.c"
, 1926, __FUNCTION__); _rtx; })->volatil)
)
1927 || GET_CODE (src)((enum rtx_code) (src)->code) == UNSPEC_VOLATILE))
1928 /* Don't combine across a CALL_INSN, because that would possibly
1929 change whether the life span of some REGs crosses calls or not,
1930 and it is a pain to update that information.
1931 Exception: if source is a constant, moving it later can't hurt.
1932 Accept that as a special case. */
1933 || (DF_INSN_LUID (insn)((((df->insns[(INSN_UID (insn))]))->luid)) < last_call_luid && ! CONSTANT_P (src)((rtx_class[(int) (((enum rtx_code) (src)->code))]) == RTX_CONST_OBJ
)
))
1934 return 0;
1935
1936 /* DEST must be a REG. */
1937 if (REG_P (dest)(((enum rtx_code) (dest)->code) == REG))
1938 {
1939 /* If register alignment is being enforced for multi-word items in all
1940 cases except for parameters, it is possible to have a register copy
1941 insn referencing a hard register that is not allowed to contain the
1942 mode being copied and which would not be valid as an operand of most
1943 insns. Eliminate this problem by not combining with such an insn.
1944
1945 Also, on some machines we don't want to extend the life of a hard
1946 register. */
1947
1948 if (REG_P (src)(((enum rtx_code) (src)->code) == REG)
1949 && ((REGNO (dest)(rhs_regno(dest)) < FIRST_PSEUDO_REGISTER76
1950 && !targetm.hard_regno_mode_ok (REGNO (dest)(rhs_regno(dest)), GET_MODE (dest)((machine_mode) (dest)->mode)))
1951 /* Don't extend the life of a hard register unless it is
1952 user variable (if we have few registers) or it can't
1953 fit into the desired register (meaning something special
1954 is going on).
1955 Also avoid substituting a return register into I3, because
1956 reload can't handle a conflict with constraints of other
1957 inputs. */
1958 || (REGNO (src)(rhs_regno(src)) < FIRST_PSEUDO_REGISTER76
1959 && !targetm.hard_regno_mode_ok (REGNO (src)(rhs_regno(src)),
1960 GET_MODE (src)((machine_mode) (src)->mode)))))
1961 return 0;
1962 }
1963 else
1964 return 0;
1965
1966
1967 if (GET_CODE (PATTERN (i3))((enum rtx_code) (PATTERN (i3))->code) == PARALLEL)
1968 for (i = XVECLEN (PATTERN (i3), 0)(((((PATTERN (i3))->u.fld[0]).rt_rtvec))->num_elem) - 1; i >= 0; i--)
1969 if (GET_CODE (XVECEXP (PATTERN (i3), 0, i))((enum rtx_code) ((((((PATTERN (i3))->u.fld[0]).rt_rtvec))
->elem[i]))->code)
== CLOBBER)
1970 {
1971 rtx reg = XEXP (XVECEXP (PATTERN (i3), 0, i), 0)((((((((PATTERN (i3))->u.fld[0]).rt_rtvec))->elem[i]))->
u.fld[0]).rt_rtx)
;
1972
1973 /* If the clobber represents an earlyclobber operand, we must not
1974 substitute an expression containing the clobbered register.
1975 As we do not analyze the constraint strings here, we have to
1976 make the conservative assumption. However, if the register is
1977 a fixed hard reg, the clobber cannot represent any operand;
1978 we leave it up to the machine description to either accept or
1979 reject use-and-clobber patterns. */
1980 if (!REG_P (reg)(((enum rtx_code) (reg)->code) == REG)
1981 || REGNO (reg)(rhs_regno(reg)) >= FIRST_PSEUDO_REGISTER76
1982 || !fixed_regs(this_target_hard_regs->x_fixed_regs)[REGNO (reg)(rhs_regno(reg))])
1983 if (reg_overlap_mentioned_p (reg, src))
1984 return 0;
1985 }
1986
1987 /* If INSN contains anything volatile, or is an `asm' (whether volatile
1988 or not), reject, unless nothing volatile comes between it and I3 */
1989
1990 if (GET_CODE (src)((enum rtx_code) (src)->code) == ASM_OPERANDS || volatile_refs_p (src))
1991 {
1992 /* Make sure neither succ nor succ2 contains a volatile reference. */
1993 if (succ2 != 0 && volatile_refs_p (PATTERN (succ2)))
1994 return 0;
1995 if (succ != 0 && volatile_refs_p (PATTERN (succ)))
1996 return 0;
1997 /* We'll check insns between INSN and I3 below. */
1998 }
1999
2000 /* If INSN is an asm, and DEST is a hard register, reject, since it has
2001 to be an explicit register variable, and was chosen for a reason. */
2002
2003 if (GET_CODE (src)((enum rtx_code) (src)->code) == ASM_OPERANDS
2004 && REG_P (dest)(((enum rtx_code) (dest)->code) == REG) && REGNO (dest)(rhs_regno(dest)) < FIRST_PSEUDO_REGISTER76)
2005 return 0;
2006
2007 /* If INSN contains volatile references (specifically volatile MEMs),
2008 we cannot combine across any other volatile references.
2009 Even if INSN doesn't contain volatile references, any intervening
2010 volatile insn might affect machine state. */
2011
2012 is_volatile_p = volatile_refs_p (PATTERN (insn))
2013 ? volatile_refs_p
2014 : volatile_insn_p;
2015
2016 for (p = NEXT_INSN (insn); p != i3; p = NEXT_INSN (p))
2017 if (INSN_P (p)(((((enum rtx_code) (p)->code) == INSN) || (((enum rtx_code
) (p)->code) == JUMP_INSN) || (((enum rtx_code) (p)->code
) == CALL_INSN)) || (((enum rtx_code) (p)->code) == DEBUG_INSN
))
&& p != succ && p != succ2 && is_volatile_p (PATTERN (p)))
2018 return 0;
2019
2020 /* If INSN contains an autoincrement or autodecrement, make sure that
2021 register is not used between there and I3, and not already used in
2022 I3 either. Neither must it be used in PRED or SUCC, if they exist.
2023 Also insist that I3 not be a jump if using LRA; if it were one
2024 and the incremented register were spilled, we would lose.
2025 Reload handles this correctly. */
2026
2027 if (AUTO_INC_DEC0)
2028 for (link = REG_NOTES (insn)(((insn)->u.fld[6]).rt_rtx); link; link = XEXP (link, 1)(((link)->u.fld[1]).rt_rtx))
2029 if (REG_NOTE_KIND (link)((enum reg_note) ((machine_mode) (link)->mode)) == REG_INC
2030 && ((JUMP_P (i3)(((enum rtx_code) (i3)->code) == JUMP_INSN) && targetm.lra_p ())
2031 || reg_used_between_p (XEXP (link, 0)(((link)->u.fld[0]).rt_rtx), insn, i3)
2032 || (pred != NULL_RTX(rtx) 0
2033 && reg_overlap_mentioned_p (XEXP (link, 0)(((link)->u.fld[0]).rt_rtx), PATTERN (pred)))
2034 || (pred2 != NULL_RTX(rtx) 0
2035 && reg_overlap_mentioned_p (XEXP (link, 0)(((link)->u.fld[0]).rt_rtx), PATTERN (pred2)))
2036 || (succ != NULL_RTX(rtx) 0
2037 && reg_overlap_mentioned_p (XEXP (link, 0)(((link)->u.fld[0]).rt_rtx), PATTERN (succ)))
2038 || (succ2 != NULL_RTX(rtx) 0
2039 && reg_overlap_mentioned_p (XEXP (link, 0)(((link)->u.fld[0]).rt_rtx), PATTERN (succ2)))
2040 || reg_overlap_mentioned_p (XEXP (link, 0)(((link)->u.fld[0]).rt_rtx), PATTERN (i3))))
2041 return 0;
2042
2043 /* If we get here, we have passed all the tests and the combination is
2044 to be allowed. */
2045
2046 *pdest = dest;
2047 *psrc = src;
2048
2049 return 1;
2050}
2051
2052/* LOC is the location within I3 that contains its pattern or the component
2053 of a PARALLEL of the pattern. We validate that it is valid for combining.
2054
2055 One problem is if I3 modifies its output, as opposed to replacing it
2056 entirely, we can't allow the output to contain I2DEST, I1DEST or I0DEST as
2057 doing so would produce an insn that is not equivalent to the original insns.
2058
2059 Consider:
2060
2061 (set (reg:DI 101) (reg:DI 100))
2062 (set (subreg:SI (reg:DI 101) 0) <foo>)
2063
2064 This is NOT equivalent to:
2065
2066 (parallel [(set (subreg:SI (reg:DI 100) 0) <foo>)
2067 (set (reg:DI 101) (reg:DI 100))])
2068
2069 Not only does this modify 100 (in which case it might still be valid
2070 if 100 were dead in I2), it sets 101 to the ORIGINAL value of 100.
2071
2072 We can also run into a problem if I2 sets a register that I1
2073 uses and I1 gets directly substituted into I3 (not via I2). In that
2074 case, we would be getting the wrong value of I2DEST into I3, so we
2075 must reject the combination. This case occurs when I2 and I1 both
2076 feed into I3, rather than when I1 feeds into I2, which feeds into I3.
2077 If I1_NOT_IN_SRC is nonzero, it means that finding I1 in the source
2078 of a SET must prevent combination from occurring. The same situation
2079 can occur for I0, in which case I0_NOT_IN_SRC is set.
2080
2081 Before doing the above check, we first try to expand a field assignment
2082 into a set of logical operations.
2083
2084 If PI3_DEST_KILLED is nonzero, it is a pointer to a location in which
2085 we place a register that is both set and used within I3. If more than one
2086 such register is detected, we fail.
2087
2088 Return 1 if the combination is valid, zero otherwise. */
2089
2090static int
2091combinable_i3pat (rtx_insn *i3, rtx *loc, rtx i2dest, rtx i1dest, rtx i0dest,
2092 int i1_not_in_src, int i0_not_in_src, rtx *pi3dest_killed)
2093{
2094 rtx x = *loc;
2095
2096 if (GET_CODE (x)((enum rtx_code) (x)->code) == SET)
2097 {
2098 rtx set = x ;
2099 rtx dest = SET_DEST (set)(((set)->u.fld[0]).rt_rtx);
2100 rtx src = SET_SRC (set)(((set)->u.fld[1]).rt_rtx);
2101 rtx inner_dest = dest;
2102 rtx subdest;
2103
2104 while (GET_CODE (inner_dest)((enum rtx_code) (inner_dest)->code) == STRICT_LOW_PART
2105 || GET_CODE (inner_dest)((enum rtx_code) (inner_dest)->code) == SUBREG
2106 || GET_CODE (inner_dest)((enum rtx_code) (inner_dest)->code) == ZERO_EXTRACT)
2107 inner_dest = XEXP (inner_dest, 0)(((inner_dest)->u.fld[0]).rt_rtx);
2108
2109 /* Check for the case where I3 modifies its output, as discussed
2110 above. We don't want to prevent pseudos from being combined
2111 into the address of a MEM, so only prevent the combination if
2112 i1 or i2 set the same MEM. */
2113 if ((inner_dest != dest &&
2114 (!MEM_P (inner_dest)(((enum rtx_code) (inner_dest)->code) == MEM)
2115 || rtx_equal_p (i2dest, inner_dest)
2116 || (i1dest && rtx_equal_p (i1dest, inner_dest))
2117 || (i0dest && rtx_equal_p (i0dest, inner_dest)))
2118 && (reg_overlap_mentioned_p (i2dest, inner_dest)
2119 || (i1dest && reg_overlap_mentioned_p (i1dest, inner_dest))
2120 || (i0dest && reg_overlap_mentioned_p (i0dest, inner_dest))))
2121
2122 /* This is the same test done in can_combine_p except we can't test
2123 all_adjacent; we don't have to, since this instruction will stay
2124 in place, thus we are not considering increasing the lifetime of
2125 INNER_DEST.
2126
2127 Also, if this insn sets a function argument, combining it with
2128 something that might need a spill could clobber a previous
2129 function argument; the all_adjacent test in can_combine_p also
2130 checks this; here, we do a more specific test for this case. */
2131
2132 || (REG_P (inner_dest)(((enum rtx_code) (inner_dest)->code) == REG)
2133 && REGNO (inner_dest)(rhs_regno(inner_dest)) < FIRST_PSEUDO_REGISTER76
2134 && !targetm.hard_regno_mode_ok (REGNO (inner_dest)(rhs_regno(inner_dest)),
2135 GET_MODE (inner_dest)((machine_mode) (inner_dest)->mode)))
2136 || (i1_not_in_src && reg_overlap_mentioned_p (i1dest, src))
2137 || (i0_not_in_src && reg_overlap_mentioned_p (i0dest, src)))
2138 return 0;
2139
2140 /* If DEST is used in I3, it is being killed in this insn, so
2141 record that for later. We have to consider paradoxical
2142 subregs here, since they kill the whole register, but we
2143 ignore partial subregs, STRICT_LOW_PART, etc.
2144 Never add REG_DEAD notes for the FRAME_POINTER_REGNUM or the
2145 STACK_POINTER_REGNUM, since these are always considered to be
2146 live. Similarly for ARG_POINTER_REGNUM if it is fixed. */
2147 subdest = dest;
2148 if (GET_CODE (subdest)((enum rtx_code) (subdest)->code) == SUBREG && !partial_subreg_p (subdest))
2149 subdest = SUBREG_REG (subdest)(((subdest)->u.fld[0]).rt_rtx);
2150 if (pi3dest_killed
2151 && REG_P (subdest)(((enum rtx_code) (subdest)->code) == REG)
2152 && reg_referenced_p (subdest, PATTERN (i3))
2153 && REGNO (subdest)(rhs_regno(subdest)) != FRAME_POINTER_REGNUM19
2154 && (HARD_FRAME_POINTER_IS_FRAME_POINTER(6 == 19)
2155 || REGNO (subdest)(rhs_regno(subdest)) != HARD_FRAME_POINTER_REGNUM6)
2156 && (FRAME_POINTER_REGNUM19 == ARG_POINTER_REGNUM16
2157 || (REGNO (subdest)(rhs_regno(subdest)) != ARG_POINTER_REGNUM16
2158 || ! fixed_regs(this_target_hard_regs->x_fixed_regs) [REGNO (subdest)(rhs_regno(subdest))]))
2159 && REGNO (subdest)(rhs_regno(subdest)) != STACK_POINTER_REGNUM7)
2160 {
2161 if (*pi3dest_killed)
2162 return 0;
2163
2164 *pi3dest_killed = subdest;
2165 }
2166 }
2167
2168 else if (GET_CODE (x)((enum rtx_code) (x)->code) == PARALLEL)
2169 {
2170 int i;
2171
2172 for (i = 0; i < XVECLEN (x, 0)(((((x)->u.fld[0]).rt_rtvec))->num_elem); i++)
2173 if (! combinable_i3pat (i3, &XVECEXP (x, 0, i)(((((x)->u.fld[0]).rt_rtvec))->elem[i]), i2dest, i1dest, i0dest,
2174 i1_not_in_src, i0_not_in_src, pi3dest_killed))
2175 return 0;
2176 }
2177
2178 return 1;
2179}
2180
2181/* Return 1 if X is an arithmetic expression that contains a multiplication
2182 and division. We don't count multiplications by powers of two here. */
2183
2184static int
2185contains_muldiv (rtx x)
2186{
2187 switch (GET_CODE (x)((enum rtx_code) (x)->code))
2188 {
2189 case MOD: case DIV: case UMOD: case UDIV:
2190 return 1;
2191
2192 case MULT:
2193 return ! (CONST_INT_P (XEXP (x, 1))(((enum rtx_code) ((((x)->u.fld[1]).rt_rtx))->code) == CONST_INT
)
2194 && pow2p_hwi (UINTVAL (XEXP (x, 1))((unsigned long) (((((x)->u.fld[1]).rt_rtx))->u.hwint[0
]))
));
2195 default:
2196 if (BINARY_P (x)(((rtx_class[(int) (((enum rtx_code) (x)->code))]) & (
~3)) == (RTX_COMPARE & (~3)))
)
2197 return contains_muldiv (XEXP (x, 0)(((x)->u.fld[0]).rt_rtx))
2198 || contains_muldiv (XEXP (x, 1)(((x)->u.fld[1]).rt_rtx));
2199
2200 if (UNARY_P (x)((rtx_class[(int) (((enum rtx_code) (x)->code))]) == RTX_UNARY
)
)
2201 return contains_muldiv (XEXP (x, 0)(((x)->u.fld[0]).rt_rtx));
2202
2203 return 0;
2204 }
2205}
2206
2207/* Determine whether INSN can be used in a combination. Return nonzero if
2208 not. This is used in try_combine to detect early some cases where we
2209 can't perform combinations. */
2210
2211static int
2212cant_combine_insn_p (rtx_insn *insn)
2213{
2214 rtx set;
2215 rtx src, dest;
2216
2217 /* If this isn't really an insn, we can't do anything.
2218 This can occur when flow deletes an insn that it has merged into an
2219 auto-increment address. */
2220 if (!NONDEBUG_INSN_P (insn)((((enum rtx_code) (insn)->code) == INSN) || (((enum rtx_code
) (insn)->code) == JUMP_INSN) || (((enum rtx_code) (insn)->
code) == CALL_INSN))
)
2221 return 1;
2222
2223 /* Never combine loads and stores involving hard regs that are likely
2224 to be spilled. The register allocator can usually handle such
2225 reg-reg moves by tying. If we allow the combiner to make
2226 substitutions of likely-spilled regs, reload might die.
2227 As an exception, we allow combinations involving fixed regs; these are
2228 not available to the register allocator so there's no risk involved. */
2229
2230 set = single_set (insn);
2231 if (! set)
2232 return 0;
2233 src = SET_SRC (set)(((set)->u.fld[1]).rt_rtx);
2234 dest = SET_DEST (set)(((set)->u.fld[0]).rt_rtx);
2235 if (GET_CODE (src)((enum rtx_code) (src)->code) == SUBREG)
2236 src = SUBREG_REG (src)(((src)->u.fld[0]).rt_rtx);
2237 if (GET_CODE (dest)((enum rtx_code) (dest)->code) == SUBREG)
2238 dest = SUBREG_REG (dest)(((dest)->u.fld[0]).rt_rtx);
2239 if (REG_P (src)(((enum rtx_code) (src)->code) == REG) && REG_P (dest)(((enum rtx_code) (dest)->code) == REG)
2240 && ((HARD_REGISTER_P (src)((((rhs_regno(src))) < 76))
2241 && ! TEST_HARD_REG_BIT (fixed_reg_set(this_target_hard_regs->x_fixed_reg_set), REGNO (src)(rhs_regno(src)))
2242#ifdef LEAF_REGISTERS
2243 && ! LEAF_REGISTERS [REGNO (src)(rhs_regno(src))])
2244#else
2245 )
2246#endif
2247 || (HARD_REGISTER_P (dest)((((rhs_regno(dest))) < 76))
2248 && ! TEST_HARD_REG_BIT (fixed_reg_set(this_target_hard_regs->x_fixed_reg_set), REGNO (dest)(rhs_regno(dest)))
2249 && targetm.class_likely_spilled_p (REGNO_REG_CLASS (REGNO (dest))(regclass_map[((rhs_regno(dest)))])))))
2250 return 1;
2251
2252 return 0;
2253}
2254
2255struct likely_spilled_retval_info
2256{
2257 unsigned regno, nregs;
2258 unsigned mask;
2259};
2260
2261/* Called via note_stores by likely_spilled_retval_p. Remove from info->mask
2262 hard registers that are known to be written to / clobbered in full. */
2263static void
2264likely_spilled_retval_1 (rtx x, const_rtx set, void *data)
2265{
2266 struct likely_spilled_retval_info *const info =
2267 (struct likely_spilled_retval_info *) data;
2268 unsigned regno, nregs;
2269 unsigned new_mask;
2270
2271 if (!REG_P (XEXP (set, 0))(((enum rtx_code) ((((set)->u.fld[0]).rt_rtx))->code) ==
REG)
)
2272 return;
2273 regno = REGNO (x)(rhs_regno(x));
2274 if (regno >= info->regno + info->nregs)
2275 return;
2276 nregs = REG_NREGS (x)((&(x)->u.reg)->nregs);
2277 if (regno + nregs <= info->regno)
2278 return;
2279 new_mask = (2U << (nregs - 1)) - 1;
2280 if (regno < info->regno)
2281 new_mask >>= info->regno - regno;
2282 else
2283 new_mask <<= regno - info->regno;
2284 info->mask &= ~new_mask;
2285}
2286
2287/* Return nonzero iff part of the return value is live during INSN, and
2288 it is likely spilled. This can happen when more than one insn is needed
2289 to copy the return value, e.g. when we consider to combine into the
2290 second copy insn for a complex value. */
2291
2292static int
2293likely_spilled_retval_p (rtx_insn *insn)
2294{
2295 rtx_insn *use = BB_END (this_basic_block)(this_basic_block)->il.x.rtl->end_;
2296 rtx reg;
2297 rtx_insn *p;
2298 unsigned regno, nregs;
2299 /* We assume here that no machine mode needs more than
2300 32 hard registers when the value overlaps with a register
2301 for which TARGET_FUNCTION_VALUE_REGNO_P is true. */
2302 unsigned mask;
2303 struct likely_spilled_retval_info info;
2304
2305 if (!NONJUMP_INSN_P (use)(((enum rtx_code) (use)->code) == INSN) || GET_CODE (PATTERN (use))((enum rtx_code) (PATTERN (use))->code) != USE || insn == use)
2306 return 0;
2307 reg = XEXP (PATTERN (use), 0)(((PATTERN (use))->u.fld[0]).rt_rtx);
2308 if (!REG_P (reg)(((enum rtx_code) (reg)->code) == REG) || !targetm.calls.function_value_regno_p (REGNO (reg)(rhs_regno(reg))))
2309 return 0;
2310 regno = REGNO (reg)(rhs_regno(reg));
2311 nregs = REG_NREGS (reg)((&(reg)->u.reg)->nregs);
2312 if (nregs == 1)
2313 return 0;
2314 mask = (2U << (nregs - 1)) - 1;
2315
2316 /* Disregard parts of the return value that are set later. */
2317 info.regno = regno;
2318 info.nregs = nregs;
2319 info.mask = mask;
2320 for (p = PREV_INSN (use); info.mask && p != insn; p = PREV_INSN (p))
2321 if (INSN_P (p)(((((enum rtx_code) (p)->code) == INSN) || (((enum rtx_code
) (p)->code) == JUMP_INSN) || (((enum rtx_code) (p)->code
) == CALL_INSN)) || (((enum rtx_code) (p)->code) == DEBUG_INSN
))
)
2322 note_stores (p, likely_spilled_retval_1, &info);
2323 mask = info.mask;
2324
2325 /* Check if any of the (probably) live return value registers is
2326 likely spilled. */
2327 nregs --;
2328 do
2329 {
2330 if ((mask & 1 << nregs)
2331 && targetm.class_likely_spilled_p (REGNO_REG_CLASS (regno + nregs)(regclass_map[(regno + nregs)])))
2332 return 1;
2333 } while (nregs--);
2334 return 0;
2335}
2336
2337/* Adjust INSN after we made a change to its destination.
2338
2339 Changing the destination can invalidate notes that say something about
2340 the results of the insn and a LOG_LINK pointing to the insn. */
2341
2342static void
2343adjust_for_new_dest (rtx_insn *insn)
2344{
2345 /* For notes, be conservative and simply remove them. */
2346 remove_reg_equal_equiv_notes (insn, true);
2347
2348 /* The new insn will have a destination that was previously the destination
2349 of an insn just above it. Call distribute_links to make a LOG_LINK from
2350 the next use of that destination. */
2351
2352 rtx set = single_set (insn);
2353 gcc_assert (set)((void)(!(set) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/combine.c"
, 2353, __FUNCTION__), 0 : 0))
;
2354
2355 rtx reg = SET_DEST (set)(((set)->u.fld[0]).rt_rtx);
2356
2357 while (GET_CODE (reg)((enum rtx_code) (reg)->code) == ZERO_EXTRACT
2358 || GET_CODE (reg)((enum rtx_code) (reg)->code) == STRICT_LOW_PART
2359 || GET_CODE (reg)((enum rtx_code) (reg)->code) == SUBREG)
2360 reg = XEXP (reg, 0)(((reg)->u.fld[0]).rt_rtx);
2361 gcc_assert (REG_P (reg))((void)(!((((enum rtx_code) (reg)->code) == REG)) ? fancy_abort
("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/combine.c"
, 2361, __FUNCTION__), 0 : 0))
;
2362
2363 distribute_links (alloc_insn_link (insn, REGNO (reg)(rhs_regno(reg)), NULLnullptr));
2364
2365 df_insn_rescan (insn);
2366}
2367
2368/* Return TRUE if combine can reuse reg X in mode MODE.
2369 ADDED_SETS is nonzero if the original set is still required. */
2370static bool
2371can_change_dest_mode (rtx x, int added_sets, machine_mode mode)
2372{
2373 unsigned int regno;
2374
2375 if (!REG_P (x)(((enum rtx_code) (x)->code) == REG))
2376 return false;
2377
2378 /* Don't change between modes with different underlying register sizes,
2379 since this could lead to invalid subregs. */
2380 if (maybe_ne (REGMODE_NATURAL_SIZE (mode)ix86_regmode_natural_size (mode),
2381 REGMODE_NATURAL_SIZE (GET_MODE (x))ix86_regmode_natural_size (((machine_mode) (x)->mode))))
2382 return false;
2383
2384 regno = REGNO (x)(rhs_regno(x));
2385 /* Allow hard registers if the new mode is legal, and occupies no more
2386 registers than the old mode. */
2387 if (regno < FIRST_PSEUDO_REGISTER76)
2388 return (targetm.hard_regno_mode_ok (regno, mode)
2389 && REG_NREGS (x)((&(x)->u.reg)->nregs) >= hard_regno_nregs (regno, mode));
2390
2391 /* Or a pseudo that is only used once. */
2392 return (regno < reg_n_sets_max
2393 && REG_N_SETS (regno) == 1
2394 && !added_sets
2395 && !REG_USERVAR_P (x)(__extension__ ({ __typeof ((x)) const _rtx = ((x)); if (((enum
rtx_code) (_rtx)->code) != REG) rtl_check_failed_flag ("REG_USERVAR_P"
, _rtx, "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/combine.c"
, 2395, __FUNCTION__); _rtx; })->volatil)
);
2396}
2397
2398
2399/* Check whether X, the destination of a set, refers to part of
2400 the register specified by REG. */
2401
2402static bool
2403reg_subword_p (rtx x, rtx reg)
2404{
2405 /* Check that reg is an integer mode register. */
2406 if (!REG_P (reg)(((enum rtx_code) (reg)->code) == REG) || GET_MODE_CLASS (GET_MODE (reg))((enum mode_class) mode_class[((machine_mode) (reg)->mode)
])
!= MODE_INT)
2407 return false;
2408
2409 if (GET_CODE (x)((enum rtx_code) (x)->code) == STRICT_LOW_PART
2410 || GET_CODE (x)((enum rtx_code) (x)->code) == ZERO_EXTRACT)
2411 x = XEXP (x, 0)(((x)->u.fld[0]).rt_rtx);
2412
2413 return GET_CODE (x)((enum rtx_code) (x)->code) == SUBREG
2414 && SUBREG_REG (x)(((x)->u.fld[0]).rt_rtx) == reg
2415 && GET_MODE_CLASS (GET_MODE (x))((enum mode_class) mode_class[((machine_mode) (x)->mode)]) == MODE_INT;
2416}
2417
2418/* Return whether PAT is a PARALLEL of exactly N register SETs followed
2419 by an arbitrary number of CLOBBERs. */
2420static bool
2421is_parallel_of_n_reg_sets (rtx pat, int n)
2422{
2423 if (GET_CODE (pat)((enum rtx_code) (pat)->code) != PARALLEL)
2424 return false;
2425
2426 int len = XVECLEN (pat, 0)(((((pat)->u.fld[0]).rt_rtvec))->num_elem);
2427 if (len < n)
2428 return false;
2429
2430 int i;
2431 for (i = 0; i < n; i++)
2432 if (GET_CODE (XVECEXP (pat, 0, i))((enum rtx_code) ((((((pat)->u.fld[0]).rt_rtvec))->elem
[i]))->code)
!= SET
2433 || !REG_P (SET_DEST (XVECEXP (pat, 0, i)))(((enum rtx_code) (((((((((pat)->u.fld[0]).rt_rtvec))->
elem[i]))->u.fld[0]).rt_rtx))->code) == REG)
)
2434 return false;
2435 for ( ; i < len; i++)
2436 switch (GET_CODE (XVECEXP (pat, 0, i))((enum rtx_code) ((((((pat)->u.fld[0]).rt_rtvec))->elem
[i]))->code)
)
2437 {
2438 case CLOBBER:
2439 if (XEXP (XVECEXP (pat, 0, i), 0)((((((((pat)->u.fld[0]).rt_rtvec))->elem[i]))->u.fld
[0]).rt_rtx)
== const0_rtx(const_int_rtx[64]))
2440 return false;
2441 break;
2442 default:
2443 return false;
2444 }
2445 return true;
2446}
2447
2448/* Return whether INSN, a PARALLEL of N register SETs (and maybe some
2449 CLOBBERs), can be split into individual SETs in that order, without
2450 changing semantics. */
2451static bool
2452can_split_parallel_of_n_reg_sets (rtx_insn *insn, int n)
2453{
2454 if (!insn_nothrow_p (insn))
2455 return false;
2456
2457 rtx pat = PATTERN (insn);
2458
2459 int i, j;
2460 for (i = 0; i < n; i++)
2461 {
2462 if (side_effects_p (SET_SRC (XVECEXP (pat, 0, i))((((((((pat)->u.fld[0]).rt_rtvec))->elem[i]))->u.fld
[1]).rt_rtx)
))
2463 return false;
2464
2465 rtx reg = SET_DEST (XVECEXP (pat, 0, i))((((((((pat)->u.fld[0]).rt_rtvec))->elem[i]))->u.fld
[0]).rt_rtx)
;
2466
2467 for (j = i + 1; j < n; j++)
2468 if (reg_referenced_p (reg, XVECEXP (pat, 0, j)(((((pat)->u.fld[0]).rt_rtvec))->elem[j])))
2469 return false;
2470 }
2471
2472 return true;
2473}
2474
2475/* Return whether X is just a single_set, with the source
2476 a general_operand. */
2477static bool
2478is_just_move (rtx_insn *x)
2479{
2480 rtx set = single_set (x);
2481 if (!set)
2482 return false;
2483
2484 return general_operand (SET_SRC (set)(((set)->u.fld[1]).rt_rtx), VOIDmode((void) 0, E_VOIDmode));
2485}
2486
2487/* Callback function to count autoincs. */
2488
2489static int
2490count_auto_inc (rtx, rtx, rtx, rtx, rtx, void *arg)
2491{
2492 (*((int *) arg))++;
2493
2494 return 0;
2495}
2496
2497/* Try to combine the insns I0, I1 and I2 into I3.
2498 Here I0, I1 and I2 appear earlier than I3.
2499 I0 and I1 can be zero; then we combine just I2 into I3, or I1 and I2 into
2500 I3.
2501
2502 If we are combining more than two insns and the resulting insn is not
2503 recognized, try splitting it into two insns. If that happens, I2 and I3
2504 are retained and I1/I0 are pseudo-deleted by turning them into a NOTE.
2505 Otherwise, I0, I1 and I2 are pseudo-deleted.
2506
2507 Return 0 if the combination does not work. Then nothing is changed.
2508 If we did the combination, return the insn at which combine should
2509 resume scanning.
2510
2511 Set NEW_DIRECT_JUMP_P to a nonzero value if try_combine creates a
2512 new direct jump instruction.
2513
2514 LAST_COMBINED_INSN is either I3, or some insn after I3 that has
2515 been I3 passed to an earlier try_combine within the same basic
2516 block. */
2517
2518static rtx_insn *
2519try_combine (rtx_insn *i3, rtx_insn *i2, rtx_insn *i1, rtx_insn *i0,
2520 int *new_direct_jump_p, rtx_insn *last_combined_insn)
2521{
2522 /* New patterns for I3 and I2, respectively. */
2523 rtx newpat, newi2pat = 0;
2524 rtvec newpat_vec_with_clobbers = 0;
2525 int substed_i2 = 0, substed_i1 = 0, substed_i0 = 0;
2526 /* Indicates need to preserve SET in I0, I1 or I2 in I3 if it is not
2527 dead. */
2528 int added_sets_0, added_sets_1, added_sets_2;
2529 /* Total number of SETs to put into I3. */
2530 int total_sets;
2531 /* Nonzero if I2's or I1's body now appears in I3. */
2532 int i2_is_used = 0, i1_is_used = 0;
2533 /* INSN_CODEs for new I3, new I2, and user of condition code. */
2534 int insn_code_number, i2_code_number = 0, other_code_number = 0;
2535 /* Contains I3 if the destination of I3 is used in its source, which means
2536 that the old life of I3 is being killed. If that usage is placed into
2537 I2 and not in I3, a REG_DEAD note must be made. */
2538 rtx i3dest_killed = 0;
2539 /* SET_DEST and SET_SRC of I2, I1 and I0. */
2540 rtx i2dest = 0, i2src = 0, i1dest = 0, i1src = 0, i0dest = 0, i0src = 0;
2541 /* Copy of SET_SRC of I1 and I0, if needed. */
2542 rtx i1src_copy = 0, i0src_copy = 0, i0src_copy2 = 0;
2543 /* Set if I2DEST was reused as a scratch register. */
2544 bool i2scratch = false;
2545 /* The PATTERNs of I0, I1, and I2, or a copy of them in certain cases. */
2546 rtx i0pat = 0, i1pat = 0, i2pat = 0;
2547 /* Indicates if I2DEST or I1DEST is in I2SRC or I1_SRC. */
2548 int i2dest_in_i2src = 0, i1dest_in_i1src = 0, i2dest_in_i1src = 0;
2549 int i0dest_in_i0src = 0, i1dest_in_i0src = 0, i2dest_in_i0src = 0;
2550 int i2dest_killed = 0, i1dest_killed = 0, i0dest_killed = 0;
2551 int i1_feeds_i2_n = 0, i0_feeds_i2_n = 0, i0_feeds_i1_n = 0;
2552 /* Notes that must be added to REG_NOTES in I3 and I2. */
2553 rtx new_i3_notes, new_i2_notes;
2554 /* Notes that we substituted I3 into I2 instead of the normal case. */
2555 int i3_subst_into_i2 = 0;
2556 /* Notes that I1, I2 or I3 is a MULT operation. */
2557 int have_mult = 0;
2558 int swap_i2i3 = 0;
2559 int split_i2i3 = 0;
2560 int changed_i3_dest = 0;
2561 bool i2_was_move = false, i3_was_move = false;
2562 int n_auto_inc = 0;
2563
2564 int maxreg;
2565 rtx_insn *temp_insn;
2566 rtx temp_expr;
2567 struct insn_link *link;
2568 rtx other_pat = 0;
2569 rtx new_other_notes;
2570 int i;
2571 scalar_int_mode dest_mode, temp_mode;
2572
2573 /* Immediately return if any of I0,I1,I2 are the same insn (I3 can
2574 never be). */
2575 if (i1 == i2 || i0 == i2 || (i0 && i0 == i1))
2576 return 0;
2577
2578 /* Only try four-insn combinations when there's high likelihood of
2579 success. Look for simple insns, such as loads of constants or
2580 binary operations involving a constant. */
2581 if (i0)
2582 {
2583 int i;
2584 int ngood = 0;
2585 int nshift = 0;
2586 rtx set0, set3;
2587
2588 if (!flag_expensive_optimizationsglobal_options.x_flag_expensive_optimizations)
2589 return 0;
2590
2591 for (i = 0; i < 4; i++)
2592 {
2593 rtx_insn *insn = i == 0 ? i0 : i == 1 ? i1 : i == 2 ? i2 : i3;
2594 rtx set = single_set (insn);
2595 rtx src;
2596 if (!set)
2597 continue;
2598 src = SET_SRC (set)(((set)->u.fld[1]).rt_rtx);
2599 if (CONSTANT_P (src)((rtx_class[(int) (((enum rtx_code) (src)->code))]) == RTX_CONST_OBJ
)
)
2600 {
2601 ngood += 2;
2602 break;
2603 }
2604 else if (BINARY_P (src)(((rtx_class[(int) (((enum rtx_code) (src)->code))]) &
(~3)) == (RTX_COMPARE & (~3)))
&& CONSTANT_P (XEXP (src, 1))((rtx_class[(int) (((enum rtx_code) ((((src)->u.fld[1]).rt_rtx
))->code))]) == RTX_CONST_OBJ)
)
2605 ngood++;
2606 else if (GET_CODE (src)((enum rtx_code) (src)->code) == ASHIFT || GET_CODE (src)((enum rtx_code) (src)->code) == ASHIFTRT
2607 || GET_CODE (src)((enum rtx_code) (src)->code) == LSHIFTRT)
2608 nshift++;
2609 }
2610
2611 /* If I0 loads a memory and I3 sets the same memory, then I1 and I2
2612 are likely manipulating its value. Ideally we'll be able to combine
2613 all four insns into a bitfield insertion of some kind.
2614
2615 Note the source in I0 might be inside a sign/zero extension and the
2616 memory modes in I0 and I3 might be different. So extract the address
2617 from the destination of I3 and search for it in the source of I0.
2618
2619 In the event that there's a match but the source/dest do not actually
2620 refer to the same memory, the worst that happens is we try some
2621 combinations that we wouldn't have otherwise. */
2622 if ((set0 = single_set (i0))
2623 /* Ensure the source of SET0 is a MEM, possibly buried inside
2624 an extension. */
2625 && (GET_CODE (SET_SRC (set0))((enum rtx_code) ((((set0)->u.fld[1]).rt_rtx))->code) == MEM
2626 || ((GET_CODE (SET_SRC (set0))((enum rtx_code) ((((set0)->u.fld[1]).rt_rtx))->code) == ZERO_EXTEND
2627 || GET_CODE (SET_SRC (set0))((enum rtx_code) ((((set0)->u.fld[1]).rt_rtx))->code) == SIGN_EXTEND)
2628 && GET_CODE (XEXP (SET_SRC (set0), 0))((enum rtx_code) (((((((set0)->u.fld[1]).rt_rtx))->u.fld
[0]).rt_rtx))->code)
== MEM))
2629 && (set3 = single_set (i3))
2630 /* Ensure the destination of SET3 is a MEM. */
2631 && GET_CODE (SET_DEST (set3))((enum rtx_code) ((((set3)->u.fld[0]).rt_rtx))->code) == MEM
2632 /* Would it be better to extract the base address for the MEM
2633 in SET3 and look for that? I don't have cases where it matters
2634 but I could envision such cases. */
2635 && rtx_referenced_p (XEXP (SET_DEST (set3), 0)((((((set3)->u.fld[0]).rt_rtx))->u.fld[0]).rt_rtx), SET_SRC (set0)(((set0)->u.fld[1]).rt_rtx)))
2636 ngood += 2;
2637
2638 if (ngood < 2 && nshift < 2)
2639 return 0;
2640 }
2641
2642 /* Exit early if one of the insns involved can't be used for
2643 combinations. */
2644 if (CALL_P (i2)(((enum rtx_code) (i2)->code) == CALL_INSN)
2645 || (i1 && CALL_P (i1)(((enum rtx_code) (i1)->code) == CALL_INSN))
2646 || (i0 && CALL_P (i0)(((enum rtx_code) (i0)->code) == CALL_INSN))
2647 || cant_combine_insn_p (i3)
2648 || cant_combine_insn_p (i2)
2649 || (i1 && cant_combine_insn_p (i1))
2650 || (i0 && cant_combine_insn_p (i0))
2651 || likely_spilled_retval_p (i3))
2652 return 0;
2653
2654 combine_attempts++;
2655 undobuf.other_insn = 0;
2656
2657 /* Reset the hard register usage information. */
2658 CLEAR_HARD_REG_SET (newpat_used_regs);
2659
2660 if (dump_file && (dump_flags & TDF_DETAILS))
2661 {
2662 if (i0)
2663 fprintf (dump_file, "\nTrying %d, %d, %d -> %d:\n",
2664 INSN_UID (i0), INSN_UID (i1), INSN_UID (i2), INSN_UID (i3));
2665 else if (i1)
2666 fprintf (dump_file, "\nTrying %d, %d -> %d:\n",
2667 INSN_UID (i1), INSN_UID (i2), INSN_UID (i3));
2668 else
2669 fprintf (dump_file, "\nTrying %d -> %d:\n",
2670 INSN_UID (i2), INSN_UID (i3));
2671
2672 if (i0)
2673 dump_insn_slim (dump_file, i0);
2674 if (i1)
2675 dump_insn_slim (dump_file, i1);
2676 dump_insn_slim (dump_file, i2);
2677 dump_insn_slim (dump_file, i3);
2678 }
2679
2680 /* If multiple insns feed into one of I2 or I3, they can be in any
2681 order. To simplify the code below, reorder them in sequence. */
2682 if (i0 && DF_INSN_LUID (i0)((((df->insns[(INSN_UID (i0))]))->luid)) > DF_INSN_LUID (i2)((((df->insns[(INSN_UID (i2))]))->luid)))
2683 std::swap (i0, i2);
2684 if (i0 && DF_INSN_LUID (i0)((((df->insns[(INSN_UID (i0))]))->luid)) > DF_INSN_LUID (i1)((((df->insns[(INSN_UID (i1))]))->luid)))
2685 std::swap (i0, i1);
2686 if (i1 && DF_INSN_LUID (i1)((((df->insns[(INSN_UID (i1))]))->luid)) > DF_INSN_LUID (i2)((((df->insns[(INSN_UID (i2))]))->luid)))
2687 std::swap (i1, i2);
2688
2689 added_links_insn = 0;
2690 added_notes_insn = 0;
2691
2692 /* First check for one important special case that the code below will
2693 not handle. Namely, the case where I1 is zero, I2 is a PARALLEL
2694 and I3 is a SET whose SET_SRC is a SET_DEST in I2. In that case,
2695 we may be able to replace that destination with the destination of I3.
2696 This occurs in the common code where we compute both a quotient and
2697 remainder into a structure, in which case we want to do the computation
2698 directly into the structure to avoid register-register copies.
2699
2700 Note that this case handles both multiple sets in I2 and also cases
2701 where I2 has a number of CLOBBERs inside the PARALLEL.
2702
2703 We make very conservative checks below and only try to handle the
2704 most common cases of this. For example, we only handle the case
2705 where I2 and I3 are adjacent to avoid making difficult register
2706 usage tests. */
2707
2708 if (i1 == 0 && NONJUMP_INSN_P (i3)(((enum rtx_code) (i3)->code) == INSN) && GET_CODE (PATTERN (i3))((enum rtx_code) (PATTERN (i3))->code) == SET
2709 && REG_P (SET_SRC (PATTERN (i3)))(((enum rtx_code) ((((PATTERN (i3))->u.fld[1]).rt_rtx))->
code) == REG)
2710 && REGNO (SET_SRC (PATTERN (i3)))(rhs_regno((((PATTERN (i3))->u.fld[1]).rt_rtx))) >= FIRST_PSEUDO_REGISTER76
2711 && find_reg_note (i3, REG_DEAD, SET_SRC (PATTERN (i3))(((PATTERN (i3))->u.fld[1]).rt_rtx))
2712 && GET_CODE (PATTERN (i2))((enum rtx_code) (PATTERN (i2))->code) == PARALLEL
2713 && ! side_effects_p (SET_DEST (PATTERN (i3))(((PATTERN (i3))->u.fld[0]).rt_rtx))
2714 /* If the dest of I3 is a ZERO_EXTRACT or STRICT_LOW_PART, the code
2715 below would need to check what is inside (and reg_overlap_mentioned_p
2716 doesn't support those codes anyway). Don't allow those destinations;
2717 the resulting insn isn't likely to be recognized anyway. */
2718 && GET_CODE (SET_DEST (PATTERN (i3)))((enum rtx_code) ((((PATTERN (i3))->u.fld[0]).rt_rtx))->
code)
!= ZERO_EXTRACT
2719 && GET_CODE (SET_DEST (PATTERN (i3)))((enum rtx_code) ((((PATTERN (i3))->u.fld[0]).rt_rtx))->
code)
!= STRICT_LOW_PART
2720 && ! reg_overlap_mentioned_p (SET_SRC (PATTERN (i3))(((PATTERN (i3))->u.fld[1]).rt_rtx),
2721 SET_DEST (PATTERN (i3))(((PATTERN (i3))->u.fld[0]).rt_rtx))
2722 && next_active_insn (i2) == i3)
2723 {
2724 rtx p2 = PATTERN (i2);
2725
2726 /* Make sure that the destination of I3,
2727 which we are going to substitute into one output of I2,
2728 is not used within another output of I2. We must avoid making this:
2729 (parallel [(set (mem (reg 69)) ...)
2730 (set (reg 69) ...)])
2731 which is not well-defined as to order of actions.
2732 (Besides, reload can't handle output reloads for this.)
2733
2734 The problem can also happen if the dest of I3 is a memory ref,
2735 if another dest in I2 is an indirect memory ref.
2736
2737 Neither can this PARALLEL be an asm. We do not allow combining
2738 that usually (see can_combine_p), so do not here either. */
2739 bool ok = true;
2740 for (i = 0; ok && i < XVECLEN (p2, 0)(((((p2)->u.fld[0]).rt_rtvec))->num_elem); i++)
2741 {
2742 if ((GET_CODE (XVECEXP (p2, 0, i))((enum rtx_code) ((((((p2)->u.fld[0]).rt_rtvec))->elem[
i]))->code)
== SET
2743 || GET_CODE (XVECEXP (p2, 0, i))((enum rtx_code) ((((((p2)->u.fld[0]).rt_rtvec))->elem[
i]))->code)
== CLOBBER)
2744 && reg_overlap_mentioned_p (SET_DEST (PATTERN (i3))(((PATTERN (i3))->u.fld[0]).rt_rtx),
2745 SET_DEST (XVECEXP (p2, 0, i))((((((((p2)->u.fld[0]).rt_rtvec))->elem[i]))->u.fld[
0]).rt_rtx)
))
2746 ok = false;
2747 else if (GET_CODE (XVECEXP (p2, 0, i))((enum rtx_code) ((((((p2)->u.fld[0]).rt_rtvec))->elem[
i]))->code)
== SET
2748 && GET_CODE (SET_SRC (XVECEXP (p2, 0, i)))((enum rtx_code) (((((((((p2)->u.fld[0]).rt_rtvec))->elem
[i]))->u.fld[1]).rt_rtx))->code)
== ASM_OPERANDS)
2749 ok = false;
2750 }
2751
2752 if (ok)
2753 for (i = 0; i < XVECLEN (p2, 0)(((((p2)->u.fld[0]).rt_rtvec))->num_elem); i++)
2754 if (GET_CODE (XVECEXP (p2, 0, i))((enum rtx_code) ((((((p2)->u.fld[0]).rt_rtvec))->elem[
i]))->code)
== SET
2755 && SET_DEST (XVECEXP (p2, 0, i))((((((((p2)->u.fld[0]).rt_rtvec))->elem[i]))->u.fld[
0]).rt_rtx)
== SET_SRC (PATTERN (i3))(((PATTERN (i3))->u.fld[1]).rt_rtx))
2756 {
2757 combine_merges++;
2758
2759 subst_insn = i3;
2760 subst_low_luid = DF_INSN_LUID (i2)((((df->insns[(INSN_UID (i2))]))->luid));
2761
2762 added_sets_2 = added_sets_1 = added_sets_0 = 0;
2763 i2src = SET_SRC (XVECEXP (p2, 0, i))((((((((p2)->u.fld[0]).rt_rtvec))->elem[i]))->u.fld[
1]).rt_rtx)
;
2764 i2dest = SET_DEST (XVECEXP (p2, 0, i))((((((((p2)->u.fld[0]).rt_rtvec))->elem[i]))->u.fld[
0]).rt_rtx)
;
2765 i2dest_killed = dead_or_set_p (i2, i2dest);
2766
2767 /* Replace the dest in I2 with our dest and make the resulting
2768 insn the new pattern for I3. Then skip to where we validate
2769 the pattern. Everything was set up above. */
2770 SUBST (SET_DEST (XVECEXP (p2, 0, i)), SET_DEST (PATTERN (i3)))do_SUBST (&(((((((((p2)->u.fld[0]).rt_rtvec))->elem
[i]))->u.fld[0]).rt_rtx)), ((((PATTERN (i3))->u.fld[0])
.rt_rtx)))
;
2771 newpat = p2;
2772 i3_subst_into_i2 = 1;
2773 goto validate_replacement;
2774 }
2775 }
2776
2777 /* If I2 is setting a pseudo to a constant and I3 is setting some
2778 sub-part of it to another constant, merge them by making a new
2779 constant. */
2780 if (i1 == 0
2781 && (temp_expr = single_set (i2)) != 0
2782 && is_a <scalar_int_mode> (GET_MODE (SET_DEST (temp_expr))((machine_mode) ((((temp_expr)->u.fld[0]).rt_rtx))->mode
)
, &temp_mode)
2783 && CONST_SCALAR_INT_P (SET_SRC (temp_expr))((((enum rtx_code) ((((temp_expr)->u.fld[1]).rt_rtx))->
code) == CONST_INT) || (((enum rtx_code) ((((temp_expr)->u
.fld[1]).rt_rtx))->code) == CONST_WIDE_INT))
2784 && GET_CODE (PATTERN (i3))((enum rtx_code) (PATTERN (i3))->code) == SET
2785 && CONST_SCALAR_INT_P (SET_SRC (PATTERN (i3)))((((enum rtx_code) ((((PATTERN (i3))->u.fld[1]).rt_rtx))->
code) == CONST_INT) || (((enum rtx_code) ((((PATTERN (i3))->
u.fld[1]).rt_rtx))->code) == CONST_WIDE_INT))
2786 && reg_subword_p (SET_DEST (PATTERN (i3))(((PATTERN (i3))->u.fld[0]).rt_rtx), SET_DEST (temp_expr)(((temp_expr)->u.fld[0]).rt_rtx)))
2787 {
2788 rtx dest = SET_DEST (PATTERN (i3))(((PATTERN (i3))->u.fld[0]).rt_rtx);
2789 rtx temp_dest = SET_DEST (temp_expr)(((temp_expr)->u.fld[0]).rt_rtx);
2790 int offset = -1;
2791 int width = 0;
2792
2793 if (GET_CODE (dest)((enum rtx_code) (dest)->code) == ZERO_EXTRACT)
2794 {
2795 if (CONST_INT_P (XEXP (dest, 1))(((enum rtx_code) ((((dest)->u.fld[1]).rt_rtx))->code) ==
CONST_INT)
2796 && CONST_INT_P (XEXP (dest, 2))(((enum rtx_code) ((((dest)->u.fld[2]).rt_rtx))->code) ==
CONST_INT)
2797 && is_a <scalar_int_mode> (GET_MODE (XEXP (dest, 0))((machine_mode) ((((dest)->u.fld[0]).rt_rtx))->mode),
2798 &dest_mode))
2799 {
2800 width = INTVAL (XEXP (dest, 1))(((((dest)->u.fld[1]).rt_rtx))->u.hwint[0]);
2801 offset = INTVAL (XEXP (dest, 2))(((((dest)->u.fld[2]).rt_rtx))->u.hwint[0]);
2802 dest = XEXP (dest, 0)(((dest)->u.fld[0]).rt_rtx);
2803 if (BITS_BIG_ENDIAN0)
2804 offset = GET_MODE_PRECISION (dest_mode) - width - offset;
2805 }
2806 }
2807 else
2808 {
2809 if (GET_CODE (dest)((enum rtx_code) (dest)->code) == STRICT_LOW_PART)
2810 dest = XEXP (dest, 0)(((dest)->u.fld[0]).rt_rtx);
2811 if (is_a <scalar_int_mode> (GET_MODE (dest)((machine_mode) (dest)->mode), &dest_mode))
2812 {
2813 width = GET_MODE_PRECISION (dest_mode);
2814 offset = 0;
2815 }
2816 }
2817
2818 if (offset >= 0)
2819 {
2820 /* If this is the low part, we're done. */
2821 if (subreg_lowpart_p (dest))
2822 ;
2823 /* Handle the case where inner is twice the size of outer. */
2824 else if (GET_MODE_PRECISION (temp_mode)
2825 == 2 * GET_MODE_PRECISION (dest_mode))
2826 offset += GET_MODE_PRECISION (dest_mode);
2827 /* Otherwise give up for now. */
2828 else
2829 offset = -1;
2830 }
2831
2832 if (offset >= 0)
2833 {
2834 rtx inner = SET_SRC (PATTERN (i3))(((PATTERN (i3))->u.fld[1]).rt_rtx);
2835 rtx outer = SET_SRC (temp_expr)(((temp_expr)->u.fld[1]).rt_rtx);
2836
2837 wide_int o = wi::insert (rtx_mode_t (outer, temp_mode),
2838 rtx_mode_t (inner, dest_mode),
2839 offset, width);
2840
2841 combine_merges++;
2842 subst_insn = i3;
2843 subst_low_luid = DF_INSN_LUID (i2)((((df->insns[(INSN_UID (i2))]))->luid));
2844 added_sets_2 = added_sets_1 = added_sets_0 = 0;
2845 i2dest = temp_dest;
2846 i2dest_killed = dead_or_set_p (i2, i2dest);
2847
2848 /* Replace the source in I2 with the new constant and make the
2849 resulting insn the new pattern for I3. Then skip to where we
2850 validate the pattern. Everything was set up above. */
2851 SUBST (SET_SRC (temp_expr),do_SUBST (&((((temp_expr)->u.fld[1]).rt_rtx)), (immed_wide_int_const
(o, temp_mode)))
2852 immed_wide_int_const (o, temp_mode))do_SUBST (&((((temp_expr)->u.fld[1]).rt_rtx)), (immed_wide_int_const
(o, temp_mode)))
;
2853
2854 newpat = PATTERN (i2);
2855
2856 /* The dest of I3 has been replaced with the dest of I2. */
2857 changed_i3_dest = 1;
2858 goto validate_replacement;
2859 }
2860 }
2861
2862 /* If we have no I1 and I2 looks like:
2863 (parallel [(set (reg:CC X) (compare:CC OP (const_int 0)))
2864 (set Y OP)])
2865 make up a dummy I1 that is
2866 (set Y OP)
2867 and change I2 to be
2868 (set (reg:CC X) (compare:CC Y (const_int 0)))
2869
2870 (We can ignore any trailing CLOBBERs.)
2871
2872 This undoes a previous combination and allows us to match a branch-and-
2873 decrement insn. */
2874
2875 if (i1 == 0
2876 && is_parallel_of_n_reg_sets (PATTERN (i2), 2)
2877 && (GET_MODE_CLASS (GET_MODE (SET_DEST (XVECEXP (PATTERN (i2), 0, 0))))((enum mode_class) mode_class[((machine_mode) (((((((((PATTERN
(i2))->u.fld[0]).rt_rtvec))->elem[0]))->u.fld[0]).rt_rtx
))->mode)])
2878 == MODE_CC)
2879 && GET_CODE (SET_SRC (XVECEXP (PATTERN (i2), 0, 0)))((enum rtx_code) (((((((((PATTERN (i2))->u.fld[0]).rt_rtvec
))->elem[0]))->u.fld[1]).rt_rtx))->code)
== COMPARE
2880 && XEXP (SET_SRC (XVECEXP (PATTERN (i2), 0, 0)), 1)(((((((((((PATTERN (i2))->u.fld[0]).rt_rtvec))->elem[0]
))->u.fld[1]).rt_rtx))->u.fld[1]).rt_rtx)
== const0_rtx(const_int_rtx[64])
2881 && rtx_equal_p (XEXP (SET_SRC (XVECEXP (PATTERN (i2), 0, 0)), 0)(((((((((((PATTERN (i2))->u.fld[0]).rt_rtvec))->elem[0]
))->u.fld[1]).rt_rtx))->u.fld[0]).rt_rtx)
,
2882 SET_SRC (XVECEXP (PATTERN (i2), 0, 1))((((((((PATTERN (i2))->u.fld[0]).rt_rtvec))->elem[1]))->
u.fld[1]).rt_rtx)
)
2883 && !reg_used_between_p (SET_DEST (XVECEXP (PATTERN (i2), 0, 0))((((((((PATTERN (i2))->u.fld[0]).rt_rtvec))->elem[0]))->
u.fld[0]).rt_rtx)
, i2, i3)
2884 && !reg_used_between_p (SET_DEST (XVECEXP (PATTERN (i2), 0, 1))((((((((PATTERN (i2))->u.fld[0]).rt_rtvec))->elem[1]))->
u.fld[0]).rt_rtx)
, i2, i3))
2885 {
2886 /* We make I1 with the same INSN_UID as I2. This gives it
2887 the same DF_INSN_LUID for value tracking. Our fake I1 will
2888 never appear in the insn stream so giving it the same INSN_UID
2889 as I2 will not cause a problem. */
2890
2891 i1 = gen_rtx_INSN (VOIDmode((void) 0, E_VOIDmode), NULLnullptr, i2, BLOCK_FOR_INSN (i2),
2892 XVECEXP (PATTERN (i2), 0, 1)(((((PATTERN (i2))->u.fld[0]).rt_rtvec))->elem[1]), INSN_LOCATION (i2),
2893 -1, NULL_RTX(rtx) 0);
2894 INSN_UID (i1) = INSN_UID (i2);
2895
2896 SUBST (PATTERN (i2), XVECEXP (PATTERN (i2), 0, 0))do_SUBST (&(PATTERN (i2)), ((((((PATTERN (i2))->u.fld[
0]).rt_rtvec))->elem[0])))
;
2897 SUBST (XEXP (SET_SRC (PATTERN (i2)), 0),do_SUBST (&(((((((PATTERN (i2))->u.fld[1]).rt_rtx))->
u.fld[0]).rt_rtx)), ((((PATTERN (i1))->u.fld[0]).rt_rtx)))
2898 SET_DEST (PATTERN (i1)))do_SUBST (&(((((((PATTERN (i2))->u.fld[1]).rt_rtx))->
u.fld[0]).rt_rtx)), ((((PATTERN (i1))->u.fld[0]).rt_rtx)))
;
2899 unsigned int regno = REGNO (SET_DEST (PATTERN (i1)))(rhs_regno((((PATTERN (i1))->u.fld[0]).rt_rtx)));
2900 SUBST_LINK (LOG_LINKS (i2),do_SUBST_LINK (&(uid_log_links[insn_uid_check (i2)]), alloc_insn_link
(i1, regno, (uid_log_links[insn_uid_check (i2)])))
2901 alloc_insn_link (i1, regno, LOG_LINKS (i2)))do_SUBST_LINK (&(uid_log_links[insn_uid_check (i2)]), alloc_insn_link
(i1, regno, (uid_log_links[insn_uid_check (i2)])))
;
2902 }
2903
2904 /* If I2 is a PARALLEL of two SETs of REGs (and perhaps some CLOBBERs),
2905 make those two SETs separate I1 and I2 insns, and make an I0 that is
2906 the original I1. */
2907 if (i0 == 0
2908 && is_parallel_of_n_reg_sets (PATTERN (i2), 2)
2909 && can_split_parallel_of_n_reg_sets (i2, 2)
2910 && !reg_used_between_p (SET_DEST (XVECEXP (PATTERN (i2), 0, 0))((((((((PATTERN (i2))->u.fld[0]).rt_rtvec))->elem[0]))->
u.fld[0]).rt_rtx)
, i2, i3)
2911 && !reg_used_between_p (SET_DEST (XVECEXP (PATTERN (i2), 0, 1))((((((((PATTERN (i2))->u.fld[0]).rt_rtvec))->elem[1]))->
u.fld[0]).rt_rtx)
, i2, i3)
2912 && !reg_set_between_p (SET_DEST (XVECEXP (PATTERN (i2), 0, 0))((((((((PATTERN (i2))->u.fld[0]).rt_rtvec))->elem[0]))->
u.fld[0]).rt_rtx)
, i2, i3)
2913 && !reg_set_between_p (SET_DEST (XVECEXP (PATTERN (i2), 0, 1))((((((((PATTERN (i2))->u.fld[0]).rt_rtvec))->elem[1]))->
u.fld[0]).rt_rtx)
, i2, i3))
2914 {
2915 /* If there is no I1, there is no I0 either. */
2916 i0 = i1;
2917
2918 /* We make I1 with the same INSN_UID as I2. This gives it
2919 the same DF_INSN_LUID for value tracking. Our fake I1 will
2920 never appear in the insn stream so giving it the same INSN_UID
2921 as I2 will not cause a problem. */
2922
2923 i1 = gen_rtx_INSN (VOIDmode((void) 0, E_VOIDmode), NULLnullptr, i2, BLOCK_FOR_INSN (i2),
2924 XVECEXP (PATTERN (i2), 0, 0)(((((PATTERN (i2))->u.fld[0]).rt_rtvec))->elem[0]), INSN_LOCATION (i2),
2925 -1, NULL_RTX(rtx) 0);
2926 INSN_UID (i1) = INSN_UID (i2);
2927
2928 SUBST (PATTERN (i2), XVECEXP (PATTERN (i2), 0, 1))do_SUBST (&(PATTERN (i2)), ((((((PATTERN (i2))->u.fld[
0]).rt_rtvec))->elem[1])))
;
2929 }
2930
2931 /* Verify that I2 and maybe I1 and I0 can be combined into I3. */
2932 if (!can_combine_p (i2, i3, i0, i1, NULLnullptr, NULLnullptr, &i2dest, &i2src))
2933 {
2934 if (dump_file && (dump_flags & TDF_DETAILS))
2935 fprintf (dump_file, "Can't combine i2 into i3\n");
2936 undo_all ();
2937 return 0;
2938 }
2939 if (i1 && !can_combine_p (i1, i3, i0, NULLnullptr, i2, NULLnullptr, &i1dest, &i1src))
2940 {
2941 if (dump_file && (dump_flags & TDF_DETAILS))
2942 fprintf (dump_file, "Can't combine i1 into i3\n");
2943 undo_all ();
2944 return 0;
2945 }
2946 if (i0 && !can_combine_p (i0, i3, NULLnullptr, NULLnullptr, i1, i2, &i0dest, &i0src))
2947 {
2948 if (dump_file && (dump_flags & TDF_DETAILS))
2949 fprintf (dump_file, "Can't combine i0 into i3\n");
2950 undo_all ();
2951 return 0;
2952 }
2953
2954 /* Record whether i2 and i3 are trivial moves. */
2955 i2_was_move = is_just_move (i2);
2956 i3_was_move = is_just_move (i3);
2957
2958 /* Record whether I2DEST is used in I2SRC and similarly for the other
2959 cases. Knowing this will help in register status updating below. */
2960 i2dest_in_i2src = reg_overlap_mentioned_p (i2dest, i2src);
2961 i1dest_in_i1src = i1 && reg_overlap_mentioned_p (i1dest, i1src);
2962 i2dest_in_i1src = i1 && reg_overlap_mentioned_p (i2dest, i1src);
2963 i0dest_in_i0src = i0 && reg_overlap_mentioned_p (i0dest, i0src);
2964 i1dest_in_i0src = i0 && reg_overlap_mentioned_p (i1dest, i0src);
2965 i2dest_in_i0src = i0 && reg_overlap_mentioned_p (i2dest, i0src);
2966 i2dest_killed = dead_or_set_p (i2, i2dest);
2967 i1dest_killed = i1 && dead_or_set_p (i1, i1dest);
2968 i0dest_killed = i0 && dead_or_set_p (i0, i0dest);
2969
2970 /* For the earlier insns, determine which of the subsequent ones they
2971 feed. */
2972 i1_feeds_i2_n = i1 && insn_a_feeds_b (i1, i2);
2973 i0_feeds_i1_n = i0 && insn_a_feeds_b (i0, i1);
2974 i0_feeds_i2_n = (i0 && (!i0_feeds_i1_n ? insn_a_feeds_b (i0, i2)
2975 : (!reg_overlap_mentioned_p (i1dest, i0dest)
2976 && reg_overlap_mentioned_p (i0dest, i2src))));
2977
2978 /* Ensure that I3's pattern can be the destination of combines. */
2979 if (! combinable_i3pat (i3, &PATTERN (i3), i2dest, i1dest, i0dest,
2980 i1 && i2dest_in_i1src && !i1_feeds_i2_n,
2981 i0 && ((i2dest_in_i0src && !i0_feeds_i2_n)
2982 || (i1dest_in_i0src && !i0_feeds_i1_n)),
2983 &i3dest_killed))
2984 {
2985 undo_all ();
2986 return 0;
2987 }
2988
2989 /* See if any of the insns is a MULT operation. Unless one is, we will
2990 reject a combination that is, since it must be slower. Be conservative
2991 here. */
2992 if (GET_CODE (i2src)((enum rtx_code) (i2src)->code) == MULT
2993 || (i1 != 0 && GET_CODE (i1src)((enum rtx_code) (i1src)->code) == MULT)
2994 || (i0 != 0 && GET_CODE (i0src)((enum rtx_code) (i0src)->code) == MULT)
2995 || (GET_CODE (PATTERN (i3))((enum rtx_code) (PATTERN (i3))->code) == SET
2996 && GET_CODE (SET_SRC (PATTERN (i3)))((enum rtx_code) ((((PATTERN (i3))->u.fld[1]).rt_rtx))->
code)
== MULT))
2997 have_mult = 1;
2998
2999 /* If I3 has an inc, then give up if I1 or I2 uses the reg that is inc'd.
3000 We used to do this EXCEPT in one case: I3 has a post-inc in an
3001 output operand. However, that exception can give rise to insns like
3002 mov r3,(r3)+
3003 which is a famous insn on the PDP-11 where the value of r3 used as the
3004 source was model-dependent. Avoid this sort of thing. */
3005
3006#if 0
3007 if (!(GET_CODE (PATTERN (i3))((enum rtx_code) (PATTERN (i3))->code) == SET
3008 && REG_P (SET_SRC (PATTERN (i3)))(((enum rtx_code) ((((PATTERN (i3))->u.fld[1]).rt_rtx))->
code) == REG)
3009 && MEM_P (SET_DEST (PATTERN (i3)))(((enum rtx_code) ((((PATTERN (i3))->u.fld[0]).rt_rtx))->
code) == MEM)
3010 && (GET_CODE (XEXP (SET_DEST (PATTERN (i3)), 0))((enum rtx_code) (((((((PATTERN (i3))->u.fld[0]).rt_rtx))->
u.fld[0]).rt_rtx))->code)
== POST_INC
3011 || GET_CODE (XEXP (SET_DEST (PATTERN (i3)), 0))((enum rtx_code) (((((((PATTERN (i3))->u.fld[0]).rt_rtx))->
u.fld[0]).rt_rtx))->code)
== POST_DEC)))
3012 /* It's not the exception. */
3013#endif
3014 if (AUTO_INC_DEC0)
3015 {
3016 rtx link;
3017 for (link = REG_NOTES (i3)(((i3)->u.fld[6]).rt_rtx); link; link = XEXP (link, 1)(((link)->u.fld[1]).rt_rtx))
3018 if (REG_NOTE_KIND (link)((enum reg_note) ((machine_mode) (link)->mode)) == REG_INC
3019 && (reg_overlap_mentioned_p (XEXP (link, 0)(((link)->u.fld[0]).rt_rtx), PATTERN (i2))
3020 || (i1 != 0
3021 && reg_overlap_mentioned_p (XEXP (link, 0)(((link)->u.fld[0]).rt_rtx), PATTERN (i1)))))
3022 {
3023 undo_all ();
3024 return 0;
3025 }
3026 }
3027
3028 /* See if the SETs in I1 or I2 need to be kept around in the merged
3029 instruction: whenever the value set there is still needed past I3.
3030 For the SET in I2, this is easy: we see if I2DEST dies or is set in I3.
3031
3032 For the SET in I1, we have two cases: if I1 and I2 independently feed
3033 into I3, the set in I1 needs to be kept around unless I1DEST dies
3034 or is set in I3. Otherwise (if I1 feeds I2 which feeds I3), the set
3035 in I1 needs to be kept around unless I1DEST dies or is set in either
3036 I2 or I3. The same considerations apply to I0. */
3037
3038 added_sets_2 = !dead_or_set_p (i3, i2dest);
3039
3040 if (i1)
3041 added_sets_1 = !(dead_or_set_p (i3, i1dest)
3042 || (i1_feeds_i2_n && dead_or_set_p (i2, i1dest)));
3043 else
3044 added_sets_1 = 0;
3045
3046 if (i0)
3047 added_sets_0 = !(dead_or_set_p (i3, i0dest)
3048 || (i0_feeds_i1_n && dead_or_set_p (i1, i0dest))
3049 || ((i0_feeds_i2_n || (i0_feeds_i1_n && i1_feeds_i2_n))
3050 && dead_or_set_p (i2, i0dest)));
3051 else
3052 added_sets_0 = 0;
3053
3054 /* We are about to copy insns for the case where they need to be kept
3055 around. Check that they can be copied in the merged instruction. */
3056
3057 if (targetm.cannot_copy_insn_p
3058 && ((added_sets_2 && targetm.cannot_copy_insn_p (i2))
3059 || (i1 && added_sets_1 && targetm.cannot_copy_insn_p (i1))
3060 || (i0 && added_sets_0 && targetm.cannot_copy_insn_p (i0))))
3061 {
3062 undo_all ();
3063 return 0;
3064 }
3065
3066 /* We cannot safely duplicate volatile references in any case. */
3067
3068 if ((added_sets_2 && volatile_refs_p (PATTERN (i2)))
3069 || (added_sets_1 && volatile_refs_p (PATTERN (i1)))
3070 || (added_sets_0 && volatile_refs_p (PATTERN (i0))))
3071 {
3072 undo_all ();
3073 return 0;
3074 }
3075
3076 /* Count how many auto_inc expressions there were in the original insns;
3077 we need to have the same number in the resulting patterns. */
3078
3079 if (i0)
3080 for_each_inc_dec (PATTERN (i0), count_auto_inc, &n_auto_inc);
3081 if (i1)
3082 for_each_inc_dec (PATTERN (i1), count_auto_inc, &n_auto_inc);
3083 for_each_inc_dec (PATTERN (i2), count_auto_inc, &n_auto_inc);
3084 for_each_inc_dec (PATTERN (i3), count_auto_inc, &n_auto_inc);
3085
3086 /* If the set in I2 needs to be kept around, we must make a copy of
3087 PATTERN (I2), so that when we substitute I1SRC for I1DEST in
3088 PATTERN (I2), we are only substituting for the original I1DEST, not into
3089 an already-substituted copy. This also prevents making self-referential
3090 rtx. If I2 is a PARALLEL, we just need the piece that assigns I2SRC to
3091 I2DEST. */
3092
3093 if (added_sets_2)
3094 {
3095 if (GET_CODE (PATTERN (i2))((enum rtx_code) (PATTERN (i2))->code) == PARALLEL)
3096 i2pat = gen_rtx_SET (i2dest, copy_rtx (i2src))gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((i2dest
)), ((copy_rtx (i2src))) )
;
3097 else
3098 i2pat = copy_rtx (PATTERN (i2));
3099 }
3100
3101 if (added_sets_1)
3102 {
3103 if (GET_CODE (PATTERN (i1))((enum rtx_code) (PATTERN (i1))->code) == PARALLEL)
3104 i1pat = gen_rtx_SET (i1dest, copy_rtx (i1src))gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((i1dest
)), ((copy_rtx (i1src))) )
;
3105 else
3106 i1pat = copy_rtx (PATTERN (i1));
3107 }
3108
3109 if (added_sets_0)
3110 {
3111 if (GET_CODE (PATTERN (i0))((enum rtx_code) (PATTERN (i0))->code) == PARALLEL)
3112 i0pat = gen_rtx_SET (i0dest, copy_rtx (i0src))gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((i0dest
)), ((copy_rtx (i0src))) )
;
3113 else
3114 i0pat = copy_rtx (PATTERN (i0));
3115 }
3116
3117 combine_merges++;
3118
3119 /* Substitute in the latest insn for the regs set by the earlier ones. */
3120
3121 maxreg = max_reg_num ();
3122
3123 subst_insn = i3;
3124
3125 /* Many machines have insns that can both perform an
3126 arithmetic operation and set the condition code. These operations will
3127 be represented as a PARALLEL with the first element of the vector
3128 being a COMPARE of an arithmetic operation with the constant zero.
3129 The second element of the vector will set some pseudo to the result
3130 of the same arithmetic operation. If we simplify the COMPARE, we won't
3131 match such a pattern and so will generate an extra insn. Here we test
3132 for this case, where both the comparison and the operation result are
3133 needed, and make the PARALLEL by just replacing I2DEST in I3SRC with
3134 I2SRC. Later we will make the PARALLEL that contains I2. */
3135
3136 if (i1 == 0 && added_sets_2 && GET_CODE (PATTERN (i3))((enum rtx_code) (PATTERN (i3))->code) == SET
3137 && GET_CODE (SET_SRC (PATTERN (i3)))((enum rtx_code) ((((PATTERN (i3))->u.fld[1]).rt_rtx))->
code)
== COMPARE
3138 && CONST_INT_P (XEXP (SET_SRC (PATTERN (i3)), 1))(((enum rtx_code) (((((((PATTERN (i3))->u.fld[1]).rt_rtx))
->u.fld[1]).rt_rtx))->code) == CONST_INT)
3139 && rtx_equal_p (XEXP (SET_SRC (PATTERN (i3)), 0)((((((PATTERN (i3))->u.fld[1]).rt_rtx))->u.fld[0]).rt_rtx
)
, i2dest))
3140 {
3141 rtx newpat_dest;
3142 rtx *cc_use_loc = NULLnullptr;
3143 rtx_insn *cc_use_insn = NULLnullptr;
3144 rtx op0 = i2src, op1 = XEXP (SET_SRC (PATTERN (i3)), 1)((((((PATTERN (i3))->u.fld[1]).rt_rtx))->u.fld[1]).rt_rtx
)
;
3145 machine_mode compare_mode, orig_compare_mode;
3146 enum rtx_code compare_code = UNKNOWN, orig_compare_code = UNKNOWN;
3147 scalar_int_mode mode;
3148
3149 newpat = PATTERN (i3);
3150 newpat_dest = SET_DEST (newpat)(((newpat)->u.fld[0]).rt_rtx);
3151 compare_mode = orig_compare_mode = GET_MODE (newpat_dest)((machine_mode) (newpat_dest)->mode);
3152
3153 if (undobuf.other_insn == 0
3154 && (cc_use_loc = find_single_use (SET_DEST (newpat)(((newpat)->u.fld[0]).rt_rtx), i3,
3155 &cc_use_insn)))
3156 {
3157 compare_code = orig_compare_code = GET_CODE (*cc_use_loc)((enum rtx_code) (*cc_use_loc)->code);
3158 if (is_a <scalar_int_mode> (GET_MODE (i2dest)((machine_mode) (i2dest)->mode), &mode))
3159 compare_code = simplify_compare_const (compare_code, mode,
3160 op0, &op1);
3161 target_canonicalize_comparison (&compare_code, &op0, &op1, 1);
3162 }
3163
3164 /* Do the rest only if op1 is const0_rtx, which may be the
3165 result of simplification. */
3166 if (op1 == const0_rtx(const_int_rtx[64]))
3167 {
3168 /* If a single use of the CC is found, prepare to modify it
3169 when SELECT_CC_MODE returns a new CC-class mode, or when
3170 the above simplify_compare_const() returned a new comparison
3171 operator. undobuf.other_insn is assigned the CC use insn
3172 when modifying it. */
3173 if (cc_use_loc)
3174 {
3175#ifdef SELECT_CC_MODE
3176 machine_mode new_mode
3177 = SELECT_CC_MODE (compare_code, op0, op1)ix86_cc_mode ((compare_code), (op0), (op1));
3178 if (new_mode != orig_compare_mode
3179 && can_change_dest_mode (SET_DEST (newpat)(((newpat)->u.fld[0]).rt_rtx),
3180 added_sets_2, new_mode))
3181 {
3182 unsigned int regno = REGNO (newpat_dest)(rhs_regno(newpat_dest));
3183 compare_mode = new_mode;
3184 if (regno < FIRST_PSEUDO_REGISTER76)
3185 newpat_dest = gen_rtx_REG (compare_mode, regno);
3186 else
3187 {
3188 SUBST_MODE (regno_reg_rtx[regno], compare_mode)do_SUBST_MODE (&(regno_reg_rtx[regno]), (compare_mode));
3189 newpat_dest = regno_reg_rtx[regno];
3190 }
3191 }
3192#endif
3193 /* Cases for modifying the CC-using comparison. */
3194 if (compare_code != orig_compare_code
3195 /* ??? Do we need to verify the zero rtx? */
3196 && XEXP (*cc_use_loc, 1)(((*cc_use_loc)->u.fld[1]).rt_rtx) == const0_rtx(const_int_rtx[64]))
3197 {
3198 /* Replace cc_use_loc with entire new RTX. */
3199 SUBST (*cc_use_loc,do_SUBST (&(*cc_use_loc), (gen_rtx_fmt_ee_stat ((compare_code
), (((machine_mode) (*cc_use_loc)->mode)), (newpat_dest), (
(const_int_rtx[64])) )))
3200 gen_rtx_fmt_ee (compare_code, GET_MODE (*cc_use_loc),do_SUBST (&(*cc_use_loc), (gen_rtx_fmt_ee_stat ((compare_code
), (((machine_mode) (*cc_use_loc)->mode)), (newpat_dest), (
(const_int_rtx[64])) )))
3201 newpat_dest, const0_rtx))do_SUBST (&(*cc_use_loc), (gen_rtx_fmt_ee_stat ((compare_code
), (((machine_mode) (*cc_use_loc)->mode)), (newpat_dest), (
(const_int_rtx[64])) )))
;
3202 undobuf.other_insn = cc_use_insn;
3203 }
3204 else if (compare_mode != orig_compare_mode)
3205 {
3206 /* Just replace the CC reg with a new mode. */
3207 SUBST (XEXP (*cc_use_loc, 0), newpat_dest)do_SUBST (&((((*cc_use_loc)->u.fld[0]).rt_rtx)), (newpat_dest
))
;
3208 undobuf.other_insn = cc_use_insn;
3209 }
3210 }
3211
3212 /* Now we modify the current newpat:
3213 First, SET_DEST(newpat) is updated if the CC mode has been
3214 altered. For targets without SELECT_CC_MODE, this should be
3215 optimized away. */
3216 if (compare_mode != orig_compare_mode)
3217 SUBST (SET_DEST (newpat), newpat_dest)do_SUBST (&((((newpat)->u.fld[0]).rt_rtx)), (newpat_dest
))
;
3218 /* This is always done to propagate i2src into newpat. */
3219 SUBST (SET_SRC (newpat),do_SUBST (&((((newpat)->u.fld[1]).rt_rtx)), (gen_rtx_fmt_ee_stat
((COMPARE), ((compare_mode)), ((op0)), ((op1)) )))
3220 gen_rtx_COMPARE (compare_mode, op0, op1))do_SUBST (&((((newpat)->u.fld[1]).rt_rtx)), (gen_rtx_fmt_ee_stat
((COMPARE), ((compare_mode)), ((op0)), ((op1)) )))
;
3221 /* Create new version of i2pat if needed; the below PARALLEL
3222 creation needs this to work correctly. */
3223 if (! rtx_equal_p (i2src, op0))
3224 i2pat = gen_rtx_SET (i2dest, op0)gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((i2dest
)), ((op0)) )
;
3225 i2_is_used = 1;
3226 }
3227 }
3228
3229 if (i2_is_used == 0)
3230 {
3231 /* It is possible that the source of I2 or I1 may be performing
3232 an unneeded operation, such as a ZERO_EXTEND of something
3233 that is known to have the high part zero. Handle that case
3234 by letting subst look at the inner insns.
3235
3236 Another way to do this would be to have a function that tries
3237 to simplify a single insn instead of merging two or more
3238 insns. We don't do this because of the potential of infinite
3239 loops and because of the potential extra memory required.
3240 However, doing it the way we are is a bit of a kludge and
3241 doesn't catch all cases.
3242
3243 But only do this if -fexpensive-optimizations since it slows
3244 things down and doesn't usually win.
3245
3246 This is not done in the COMPARE case above because the
3247 unmodified I2PAT is used in the PARALLEL and so a pattern
3248 with a modified I2SRC would not match. */
3249
3250 if (flag_expensive_optimizationsglobal_options.x_flag_expensive_optimizations)
3251 {
3252 /* Pass pc_rtx so no substitutions are done, just
3253 simplifications. */
3254 if (i1)
3255 {
3256 subst_low_luid = DF_INSN_LUID (i1)((((df->insns[(INSN_UID (i1))]))->luid));
3257 i1src = subst (i1src, pc_rtx, pc_rtx, 0, 0, 0);
3258 }
3259
3260 subst_low_luid = DF_INSN_LUID (i2)((((df->insns[(INSN_UID (i2))]))->luid));
3261 i2src = subst (i2src, pc_rtx, pc_rtx, 0, 0, 0);
3262 }
3263
3264 n_occurrences = 0; /* `subst' counts here */
3265 subst_low_luid = DF_INSN_LUID (i2)((((df->insns[(INSN_UID (i2))]))->luid));
3266
3267 /* If I1 feeds into I2 and I1DEST is in I1SRC, we need to make a unique
3268 copy of I2SRC each time we substitute it, in order to avoid creating
3269 self-referential RTL when we will be substituting I1SRC for I1DEST
3270 later. Likewise if I0 feeds into I2, either directly or indirectly
3271 through I1, and I0DEST is in I0SRC. */
3272 newpat = subst (PATTERN (i3), i2dest, i2src, 0, 0,
3273 (i1_feeds_i2_n && i1dest_in_i1src)
3274 || ((i0_feeds_i2_n || (i0_feeds_i1_n && i1_feeds_i2_n))
3275 && i0dest_in_i0src));
3276 substed_i2 = 1;
3277
3278 /* Record whether I2's body now appears within I3's body. */
3279 i2_is_used = n_occurrences;
Value stored to 'i2_is_used' is never read
3280 }
3281
3282 /* If we already got a failure, don't try to do more. Otherwise, try to
3283 substitute I1 if we have it. */
3284
3285 if (i1 && GET_CODE (newpat)((enum rtx_code) (newpat)->code) != CLOBBER)
3286 {
3287 /* Before we can do this substitution, we must redo the test done
3288 above (see detailed comments there) that ensures I1DEST isn't
3289 mentioned in any SETs in NEWPAT that are field assignments. */
3290 if (!combinable_i3pat (NULLnullptr, &newpat, i1dest, NULL_RTX(rtx) 0, NULL_RTX(rtx) 0,
3291 0, 0, 0))
3292 {
3293 undo_all ();
3294 return 0;
3295 }
3296
3297 n_occurrences = 0;
3298 subst_low_luid = DF_INSN_LUID (i1)((((df->insns[(INSN_UID (i1))]))->luid));
3299
3300 /* If the following substitution will modify I1SRC, make a copy of it
3301 for the case where it is substituted for I1DEST in I2PAT later. */
3302 if (added_sets_2 && i1_feeds_i2_n)
3303 i1src_copy = copy_rtx (i1src);
3304
3305 /* If I0 feeds into I1 and I0DEST is in I0SRC, we need to make a unique
3306 copy of I1SRC each time we substitute it, in order to avoid creating
3307 self-referential RTL when we will be substituting I0SRC for I0DEST
3308 later. */
3309 newpat = subst (newpat, i1dest, i1src, 0, 0,
3310 i0_feeds_i1_n && i0dest_in_i0src);
3311 substed_i1 = 1;
3312
3313 /* Record whether I1's body now appears within I3's body. */
3314 i1_is_used = n_occurrences;
3315 }
3316
3317 /* Likewise for I0 if we have it. */
3318
3319 if (i0 && GET_CODE (newpat)((enum rtx_code) (newpat)->code) != CLOBBER)
3320 {
3321 if (!combinable_i3pat (NULLnullptr, &newpat, i0dest, NULL_RTX(rtx) 0, NULL_RTX(rtx) 0,
3322 0, 0, 0))
3323 {
3324 undo_all ();
3325 return 0;
3326 }
3327
3328 /* If the following substitution will modify I0SRC, make a copy of it
3329 for the case where it is substituted for I0DEST in I1PAT later. */
3330 if (added_sets_1 && i0_feeds_i1_n)
3331 i0src_copy = copy_rtx (i0src);
3332 /* And a copy for I0DEST in I2PAT substitution. */
3333 if (added_sets_2 && ((i0_feeds_i1_n && i1_feeds_i2_n)
3334 || (i0_feeds_i2_n)))
3335 i0src_copy2 = copy_rtx (i0src);
3336
3337 n_occurrences = 0;
3338 subst_low_luid = DF_INSN_LUID (i0)((((df->insns[(INSN_UID (i0))]))->luid));
3339 newpat = subst (newpat, i0dest, i0src, 0, 0, 0);
3340 substed_i0 = 1;
3341 }
3342
3343 if (n_auto_inc)
3344 {
3345 int new_n_auto_inc = 0;
3346 for_each_inc_dec (newpat, count_auto_inc, &new_n_auto_inc);
3347
3348 if (n_auto_inc != new_n_auto_inc)
3349 {
3350 if (dump_file && (dump_flags & TDF_DETAILS))
3351 fprintf (dump_file, "Number of auto_inc expressions changed\n");
3352 undo_all ();
3353 return 0;
3354 }
3355 }
3356
3357 /* Fail if an autoincrement side-effect has been duplicated. Be careful
3358 to count all the ways that I2SRC and I1SRC can be used. */
3359 if ((FIND_REG_INC_NOTE (i2, NULL_RTX)0 != 0
3360 && i2_is_used + added_sets_2 > 1)
3361 || (i1 != 0 && FIND_REG_INC_NOTE (i1, NULL_RTX)0 != 0
3362 && (i1_is_used + added_sets_1 + (added_sets_2 && i1_feeds_i2_n)
3363 > 1))
3364 || (i0 != 0 && FIND_REG_INC_NOTE (i0, NULL_RTX)0 != 0
3365 && (n_occurrences + added_sets_0
3366 + (added_sets_1 && i0_feeds_i1_n)
3367 + (added_sets_2 && i0_feeds_i2_n)
3368 > 1))
3369 /* Fail if we tried to make a new register. */
3370 || max_reg_num () != maxreg
3371 /* Fail if we couldn't do something and have a CLOBBER. */
3372 || GET_CODE (newpat)((enum rtx_code) (newpat)->code) == CLOBBER
3373 /* Fail if this new pattern is a MULT and we didn't have one before
3374 at the outer level. */
3375 || (GET_CODE (newpat)((enum rtx_code) (newpat)->code) == SET && GET_CODE (SET_SRC (newpat))((enum rtx_code) ((((newpat)->u.fld[1]).rt_rtx))->code) == MULT
3376 && ! have_mult))
3377 {
3378 undo_all ();
3379 return 0;
3380 }
3381
3382 /* If the actions of the earlier insns must be kept
3383 in addition to substituting them into the latest one,
3384 we must make a new PARALLEL for the latest insn
3385 to hold additional the SETs. */
3386
3387 if (added_sets_0 || added_sets_1 || added_sets_2)
3388 {
3389 int extra_sets = added_sets_0 + added_sets_1 + added_sets_2;
3390 combine_extras++;
3391
3392 if (GET_CODE (newpat)((enum rtx_code) (newpat)->code) == PARALLEL)
3393 {
3394 rtvec old = XVEC (newpat, 0)(((newpat)->u.fld[0]).rt_rtvec);
3395 total_sets = XVECLEN (newpat, 0)(((((newpat)->u.fld[0]).rt_rtvec))->num_elem) + extra_sets;
3396 newpat = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (total_sets))gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(rtvec_alloc (total_sets))) )
;
3397 memcpy (XVEC (newpat, 0)(((newpat)->u.fld[0]).rt_rtvec)->elem, &old->elem[0],
3398 sizeof (old->elem[0]) * old->num_elem);
3399 }
3400 else
3401 {
3402 rtx old = newpat;
3403 total_sets = 1 + extra_sets;
3404 newpat = gen_rtx_PARALLEL (VOIDmode, rtvec_alloc (total_sets))gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(rtvec_alloc (total_sets))) )
;
3405 XVECEXP (newpat, 0, 0)(((((newpat)->u.fld[0]).rt_rtvec))->elem[0]) = old;
3406 }
3407
3408 if (added_sets_0)
3409 XVECEXP (newpat, 0, --total_sets)(((((newpat)->u.fld[0]).rt_rtvec))->elem[--total_sets]) = i0pat;
3410
3411 if (added_sets_1)
3412 {
3413 rtx t = i1pat;
3414 if (i0_feeds_i1_n)
3415 t = subst (t, i0dest, i0src_copy ? i0src_copy : i0src, 0, 0, 0);
3416
3417 XVECEXP (newpat, 0, --total_sets)(((((newpat)->u.fld[0]).rt_rtvec))->elem[--total_sets]) = t;
3418 }
3419 if (added_sets_2)
3420 {
3421 rtx t = i2pat;
3422 if (i1_feeds_i2_n)
3423 t = subst (t, i1dest, i1src_copy ? i1src_copy : i1src, 0, 0,
3424 i0_feeds_i1_n && i0dest_in_i0src);
3425 if ((i0_feeds_i1_n && i1_feeds_i2_n) || i0_feeds_i2_n)
3426 t = subst (t, i0dest, i0src_copy2 ? i0src_copy2 : i0src, 0, 0, 0);
3427
3428 XVECEXP (newpat, 0, --total_sets)(((((newpat)->u.fld[0]).rt_rtvec))->elem[--total_sets]) = t;
3429 }
3430 }
3431
3432 validate_replacement:
3433
3434 /* Note which hard regs this insn has as inputs. */
3435 mark_used_regs_combine (newpat);
3436
3437 /* If recog_for_combine fails, it strips existing clobbers. If we'll
3438 consider splitting this pattern, we might need these clobbers. */
3439 if (i1 && GET_CODE (newpat)((enum rtx_code) (newpat)->code) == PARALLEL
3440 && GET_CODE (XVECEXP (newpat, 0, XVECLEN (newpat, 0) - 1))((enum rtx_code) ((((((newpat)->u.fld[0]).rt_rtvec))->elem
[(((((newpat)->u.fld[0]).rt_rtvec))->num_elem) - 1]))->
code)
== CLOBBER)
3441 {
3442 int len = XVECLEN (newpat, 0)(((((newpat)->u.fld[0]).rt_rtvec))->num_elem);
3443
3444 newpat_vec_with_clobbers = rtvec_alloc (len);
3445 for (i = 0; i < len; i++)
3446 RTVEC_ELT (newpat_vec_with_clobbers, i)((newpat_vec_with_clobbers)->elem[i]) = XVECEXP (newpat, 0, i)(((((newpat)->u.fld[0]).rt_rtvec))->elem[i]);
3447 }
3448
3449 /* We have recognized nothing yet. */
3450 insn_code_number = -1;
3451
3452 /* See if this is a PARALLEL of two SETs where one SET's destination is
3453 a register that is unused and this isn't marked as an instruction that
3454 might trap in an EH region. In that case, we just need the other SET.
3455 We prefer this over the PARALLEL.
3456
3457 This can occur when simplifying a divmod insn. We *must* test for this
3458 case here because the code below that splits two independent SETs doesn't
3459 handle this case correctly when it updates the register status.
3460
3461 It's pointless doing this if we originally had two sets, one from
3462 i3, and one from i2. Combining then splitting the parallel results
3463 in the original i2 again plus an invalid insn (which we delete).
3464 The net effect is only to move instructions around, which makes
3465 debug info less accurate.
3466
3467 If the remaining SET came from I2 its destination should not be used
3468 between I2 and I3. See PR82024. */
3469
3470 if (!(added_sets_2 && i1 == 0)
3471 && is_parallel_of_n_reg_sets (newpat, 2)
3472 && asm_noperands (newpat) < 0)
3473 {
3474 rtx set0 = XVECEXP (newpat, 0, 0)(((((newpat)->u.fld[0]).rt_rtvec))->elem[0]);
3475 rtx set1 = XVECEXP (newpat, 0, 1)(((((newpat)->u.fld[0]).rt_rtvec))->elem[1]);
3476 rtx oldpat = newpat;
3477
3478 if (((REG_P (SET_DEST (set1))(((enum rtx_code) ((((set1)->u.fld[0]).rt_rtx))->code) ==
REG)
3479 && find_reg_note (i3, REG_UNUSED, SET_DEST (set1)(((set1)->u.fld[0]).rt_rtx)))
3480 || (GET_CODE (SET_DEST (set1))((enum rtx_code) ((((set1)->u.fld[0]).rt_rtx))->code) == SUBREG
3481 && find_reg_note (i3, REG_UNUSED, SUBREG_REG (SET_DEST (set1))((((((set1)->u.fld[0]).rt_rtx))->u.fld[0]).rt_rtx))))
3482 && insn_nothrow_p (i3)
3483 && !side_effects_p (SET_SRC (set1)(((set1)->u.fld[1]).rt_rtx)))
3484 {
3485 newpat = set0;
3486 insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
3487 }
3488
3489 else if (((REG_P (SET_DEST (set0))(((enum rtx_code) ((((set0)->u.fld[0]).rt_rtx))->code) ==
REG)
3490 && find_reg_note (i3, REG_UNUSED, SET_DEST (set0)(((set0)->u.fld[0]).rt_rtx)))
3491 || (GET_CODE (SET_DEST (set0))((enum rtx_code) ((((set0)->u.fld[0]).rt_rtx))->code) == SUBREG
3492 && find_reg_note (i3, REG_UNUSED,
3493 SUBREG_REG (SET_DEST (set0))((((((set0)->u.fld[0]).rt_rtx))->u.fld[0]).rt_rtx))))
3494 && insn_nothrow_p (i3)
3495 && !side_effects_p (SET_SRC (set0)(((set0)->u.fld[1]).rt_rtx)))
3496 {
3497 rtx dest = SET_DEST (set1)(((set1)->u.fld[0]).rt_rtx);
3498 if (GET_CODE (dest)((enum rtx_code) (dest)->code) == SUBREG)
3499 dest = SUBREG_REG (dest)(((dest)->u.fld[0]).rt_rtx);
3500 if (!reg_used_between_p (dest, i2, i3))
3501 {
3502 newpat = set1;
3503 insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
3504
3505 if (insn_code_number >= 0)
3506 changed_i3_dest = 1;
3507 }
3508 }
3509
3510 if (insn_code_number < 0)
3511 newpat = oldpat;
3512 }
3513
3514 /* Is the result of combination a valid instruction? */
3515 if (insn_code_number < 0)
3516 insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
3517
3518 /* If we were combining three insns and the result is a simple SET
3519 with no ASM_OPERANDS that wasn't recognized, try to split it into two
3520 insns. There are two ways to do this. It can be split using a
3521 machine-specific method (like when you have an addition of a large
3522 constant) or by combine in the function find_split_point. */
3523
3524 if (i1 && insn_code_number < 0 && GET_CODE (newpat)((enum rtx_code) (newpat)->code) == SET
3525 && asm_noperands (newpat) < 0)
3526 {
3527 rtx parallel, *split;
3528 rtx_insn *m_split_insn;
3529
3530 /* See if the MD file can split NEWPAT. If it can't, see if letting it
3531 use I2DEST as a scratch register will help. In the latter case,
3532 convert I2DEST to the mode of the source of NEWPAT if we can. */
3533
3534 m_split_insn = combine_split_insns (newpat, i3);
3535
3536 /* We can only use I2DEST as a scratch reg if it doesn't overlap any
3537 inputs of NEWPAT. */
3538
3539 /* ??? If I2DEST is not safe, and I1DEST exists, then it would be
3540 possible to try that as a scratch reg. This would require adding
3541 more code to make it work though. */
3542
3543 if (m_split_insn == 0 && ! reg_overlap_mentioned_p (i2dest, newpat))
3544 {
3545 machine_mode new_mode = GET_MODE (SET_DEST (newpat))((machine_mode) ((((newpat)->u.fld[0]).rt_rtx))->mode);
3546
3547 /* ??? Reusing i2dest without resetting the reg_stat entry for it
3548 (temporarily, until we are committed to this instruction
3549 combination) does not work: for example, any call to nonzero_bits
3550 on the register (from a splitter in the MD file, for example)
3551 will get the old information, which is invalid.
3552
3553 Since nowadays we can create registers during combine just fine,
3554 we should just create a new one here, not reuse i2dest. */
3555
3556 /* First try to split using the original register as a
3557 scratch register. */
3558 parallel = gen_rtx_PARALLEL (VOIDmode,gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (2, newpat, gen_rtx_fmt_e_stat ((CLOBBER), ((((void
) 0, E_VOIDmode))), ((i2dest)) )))) )
3559 gen_rtvec (2, newpat,gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (2, newpat, gen_rtx_fmt_e_stat ((CLOBBER), ((((void
) 0, E_VOIDmode))), ((i2dest)) )))) )
3560 gen_rtx_CLOBBER (VOIDmode,gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (2, newpat, gen_rtx_fmt_e_stat ((CLOBBER), ((((void
) 0, E_VOIDmode))), ((i2dest)) )))) )
3561 i2dest)))gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (2, newpat, gen_rtx_fmt_e_stat ((CLOBBER), ((((void
) 0, E_VOIDmode))), ((i2dest)) )))) )
;
3562 m_split_insn = combine_split_insns (parallel, i3);
3563
3564 /* If that didn't work, try changing the mode of I2DEST if
3565 we can. */
3566 if (m_split_insn == 0
3567 && new_mode != GET_MODE (i2dest)((machine_mode) (i2dest)->mode)
3568 && new_mode != VOIDmode((void) 0, E_VOIDmode)
3569 && can_change_dest_mode (i2dest, added_sets_2, new_mode))
3570 {
3571 machine_mode old_mode = GET_MODE (i2dest)((machine_mode) (i2dest)->mode);
3572 rtx ni2dest;
3573
3574 if (REGNO (i2dest)(rhs_regno(i2dest)) < FIRST_PSEUDO_REGISTER76)
3575 ni2dest = gen_rtx_REG (new_mode, REGNO (i2dest)(rhs_regno(i2dest)));
3576 else
3577 {
3578 SUBST_MODE (regno_reg_rtx[REGNO (i2dest)], new_mode)do_SUBST_MODE (&(regno_reg_rtx[(rhs_regno(i2dest))]), (new_mode
))
;
3579 ni2dest = regno_reg_rtx[REGNO (i2dest)(rhs_regno(i2dest))];
3580 }
3581
3582 parallel = (gen_rtx_PARALLELgen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (2, newpat, gen_rtx_fmt_e_stat ((CLOBBER), ((((void
) 0, E_VOIDmode))), ((ni2dest)) )))) )
3583 (VOIDmode,gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (2, newpat, gen_rtx_fmt_e_stat ((CLOBBER), ((((void
) 0, E_VOIDmode))), ((ni2dest)) )))) )
3584 gen_rtvec (2, newpat,gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (2, newpat, gen_rtx_fmt_e_stat ((CLOBBER), ((((void
) 0, E_VOIDmode))), ((ni2dest)) )))) )
3585 gen_rtx_CLOBBER (VOIDmode,gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (2, newpat, gen_rtx_fmt_e_stat ((CLOBBER), ((((void
) 0, E_VOIDmode))), ((ni2dest)) )))) )
3586 ni2dest)))gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(gen_rtvec (2, newpat, gen_rtx_fmt_e_stat ((CLOBBER), ((((void
) 0, E_VOIDmode))), ((ni2dest)) )))) )
);
3587 m_split_insn = combine_split_insns (parallel, i3);
3588
3589 if (m_split_insn == 0
3590 && REGNO (i2dest)(rhs_regno(i2dest)) >= FIRST_PSEUDO_REGISTER76)
3591 {
3592 struct undo *buf;
3593
3594 adjust_reg_mode (regno_reg_rtx[REGNO (i2dest)(rhs_regno(i2dest))], old_mode);
3595 buf = undobuf.undos;
3596 undobuf.undos = buf->next;
3597 buf->next = undobuf.frees;
3598 undobuf.frees = buf;
3599 }
3600 }
3601
3602 i2scratch = m_split_insn != 0;
3603 }
3604
3605 /* If recog_for_combine has discarded clobbers, try to use them
3606 again for the split. */
3607 if (m_split_insn == 0 && newpat_vec_with_clobbers)
3608 {
3609 parallel = gen_rtx_PARALLEL (VOIDmode, newpat_vec_with_clobbers)gen_rtx_fmt_E_stat ((PARALLEL), ((((void) 0, E_VOIDmode))), (
(newpat_vec_with_clobbers)) )
;
3610 m_split_insn = combine_split_insns (parallel, i3);
3611 }
3612
3613 if (m_split_insn && NEXT_INSN (m_split_insn) == NULL_RTX(rtx) 0)
3614 {
3615 rtx m_split_pat = PATTERN (m_split_insn);
3616 insn_code_number = recog_for_combine (&m_split_pat, i3, &new_i3_notes);
3617 if (insn_code_number >= 0)
3618 newpat = m_split_pat;
3619 }
3620 else if (m_split_insn && NEXT_INSN (NEXT_INSN (m_split_insn)) == NULL_RTX(rtx) 0
3621 && (next_nonnote_nondebug_insn (i2) == i3
3622 || !modified_between_p (PATTERN (m_split_insn), i2, i3)))
3623 {
3624 rtx i2set, i3set;
3625 rtx newi3pat = PATTERN (NEXT_INSN (m_split_insn));
3626 newi2pat = PATTERN (m_split_insn);
3627
3628 i3set = single_set (NEXT_INSN (m_split_insn));
3629 i2set = single_set (m_split_insn);
3630
3631 i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes);
3632
3633 /* If I2 or I3 has multiple SETs, we won't know how to track
3634 register status, so don't use these insns. If I2's destination
3635 is used between I2 and I3, we also can't use these insns. */
3636
3637 if (i2_code_number >= 0 && i2set && i3set
3638 && (next_nonnote_nondebug_insn (i2) == i3
3639 || ! reg_used_between_p (SET_DEST (i2set)(((i2set)->u.fld[0]).rt_rtx), i2, i3)))
3640 insn_code_number = recog_for_combine (&newi3pat, i3,
3641 &new_i3_notes);
3642 if (insn_code_number >= 0)
3643 newpat = newi3pat;
3644
3645 /* It is possible that both insns now set the destination of I3.
3646 If so, we must show an extra use of it. */
3647
3648 if (insn_code_number >= 0)
3649 {
3650 rtx new_i3_dest = SET_DEST (i3set)(((i3set)->u.fld[0]).rt_rtx);
3651 rtx new_i2_dest = SET_DEST (i2set)(((i2set)->u.fld[0]).rt_rtx);
3652
3653 while (GET_CODE (new_i3_dest)((enum rtx_code) (new_i3_dest)->code) == ZERO_EXTRACT
3654 || GET_CODE (new_i3_dest)((enum rtx_code) (new_i3_dest)->code) == STRICT_LOW_PART
3655 || GET_CODE (new_i3_dest)((enum rtx_code) (new_i3_dest)->code) == SUBREG)
3656 new_i3_dest = XEXP (new_i3_dest, 0)(((new_i3_dest)->u.fld[0]).rt_rtx);
3657
3658 while (GET_CODE (new_i2_dest)((enum rtx_code) (new_i2_dest)->code) == ZERO_EXTRACT
3659 || GET_CODE (new_i2_dest)((enum rtx_code) (new_i2_dest)->code) == STRICT_LOW_PART
3660 || GET_CODE (new_i2_dest)((enum rtx_code) (new_i2_dest)->code) == SUBREG)
3661 new_i2_dest = XEXP (new_i2_dest, 0)(((new_i2_dest)->u.fld[0]).rt_rtx);
3662
3663 if (REG_P (new_i3_dest)(((enum rtx_code) (new_i3_dest)->code) == REG)
3664 && REG_P (new_i2_dest)(((enum rtx_code) (new_i2_dest)->code) == REG)
3665 && REGNO (new_i3_dest)(rhs_regno(new_i3_dest)) == REGNO (new_i2_dest)(rhs_regno(new_i2_dest))
3666 && REGNO (new_i2_dest)(rhs_regno(new_i2_dest)) < reg_n_sets_max)
3667 INC_REG_N_SETS (REGNO (new_i2_dest), 1)(regstat_n_sets_and_refs[(rhs_regno(new_i2_dest))].sets += 1);
3668 }
3669 }
3670
3671 /* If we can split it and use I2DEST, go ahead and see if that
3672 helps things be recognized. Verify that none of the registers
3673 are set between I2 and I3. */
3674 if (insn_code_number < 0
3675 && (split = find_split_point (&newpat, i3, false)) != 0
3676 /* We need I2DEST in the proper mode. If it is a hard register
3677 or the only use of a pseudo, we can change its mode.
3678 Make sure we don't change a hard register to have a mode that
3679 isn't valid for it, or change the number of registers. */
3680 && (GET_MODE (*split)((machine_mode) (*split)->mode) == GET_MODE (i2dest)((machine_mode) (i2dest)->mode)
3681 || GET_MODE (*split)((machine_mode) (*split)->mode) == VOIDmode((void) 0, E_VOIDmode)
3682 || can_change_dest_mode (i2dest, added_sets_2,
3683 GET_MODE (*split)((machine_mode) (*split)->mode)))
3684 && (next_nonnote_nondebug_insn (i2) == i3
3685 || !modified_between_p (*split, i2, i3))
3686 /* We can't overwrite I2DEST if its value is still used by
3687 NEWPAT. */
3688 && ! reg_referenced_p (i2dest, newpat))
3689 {
3690 rtx newdest = i2dest;
3691 enum rtx_code split_code = GET_CODE (*split)((enum rtx_code) (*split)->code);
3692 machine_mode split_mode = GET_MODE (*split)((machine_mode) (*split)->mode);
3693 bool subst_done = false;
3694 newi2pat = NULL_RTX(rtx) 0;
3695
3696 i2scratch = true;
3697
3698 /* *SPLIT may be part of I2SRC, so make sure we have the
3699 original expression around for later debug processing.
3700 We should not need I2SRC any more in other cases. */
3701 if (MAY_HAVE_DEBUG_BIND_INSNSglobal_options.x_flag_var_tracking_assignments)
3702 i2src = copy_rtx (i2src);
3703 else
3704 i2src = NULLnullptr;
3705
3706 /* Get NEWDEST as a register in the proper mode. We have already
3707 validated that we can do this. */
3708 if (GET_MODE (i2dest)((machine_mode) (i2dest)->mode) != split_mode && split_mode != VOIDmode((void) 0, E_VOIDmode))
3709 {
3710 if (REGNO (i2dest)(rhs_regno(i2dest)) < FIRST_PSEUDO_REGISTER76)
3711 newdest = gen_rtx_REG (split_mode, REGNO (i2dest)(rhs_regno(i2dest)));
3712 else
3713 {
3714 SUBST_MODE (regno_reg_rtx[REGNO (i2dest)], split_mode)do_SUBST_MODE (&(regno_reg_rtx[(rhs_regno(i2dest))]), (split_mode
))
;
3715 newdest = regno_reg_rtx[REGNO (i2dest)(rhs_regno(i2dest))];
3716 }
3717 }
3718
3719 /* If *SPLIT is a (mult FOO (const_int pow2)), convert it to
3720 an ASHIFT. This can occur if it was inside a PLUS and hence
3721 appeared to be a memory address. This is a kludge. */
3722 if (split_code == MULT
3723 && CONST_INT_P (XEXP (*split, 1))(((enum rtx_code) ((((*split)->u.fld[1]).rt_rtx))->code
) == CONST_INT)
3724 && INTVAL (XEXP (*split, 1))(((((*split)->u.fld[1]).rt_rtx))->u.hwint[0]) > 0
3725 && (i = exact_log2 (UINTVAL (XEXP (*split, 1))((unsigned long) (((((*split)->u.fld[1]).rt_rtx))->u.hwint
[0]))
)) >= 0)
3726 {
3727 rtx i_rtx = gen_int_shift_amount (split_mode, i);
3728 SUBST (*split, gen_rtx_ASHIFT (split_mode,do_SUBST (&(*split), (gen_rtx_fmt_ee_stat ((ASHIFT), ((split_mode
)), (((((*split)->u.fld[0]).rt_rtx))), ((i_rtx)) )))
3729 XEXP (*split, 0), i_rtx))do_SUBST (&(*split), (gen_rtx_fmt_ee_stat ((ASHIFT), ((split_mode
)), (((((*split)->u.fld[0]).rt_rtx))), ((i_rtx)) )))
;
3730 /* Update split_code because we may not have a multiply
3731 anymore. */
3732 split_code = GET_CODE (*split)((enum rtx_code) (*split)->code);
3733 }
3734
3735 /* Similarly for (plus (mult FOO (const_int pow2))). */
3736 if (split_code == PLUS
3737 && GET_CODE (XEXP (*split, 0))((enum rtx_code) ((((*split)->u.fld[0]).rt_rtx))->code) == MULT
3738 && CONST_INT_P (XEXP (XEXP (*split, 0), 1))(((enum rtx_code) (((((((*split)->u.fld[0]).rt_rtx))->u
.fld[1]).rt_rtx))->code) == CONST_INT)
3739 && INTVAL (XEXP (XEXP (*split, 0), 1))((((((((*split)->u.fld[0]).rt_rtx))->u.fld[1]).rt_rtx))
->u.hwint[0])
> 0
3740 && (i = exact_log2 (UINTVAL (XEXP (XEXP (*split, 0), 1))((unsigned long) ((((((((*split)->u.fld[0]).rt_rtx))->u
.fld[1]).rt_rtx))->u.hwint[0]))
)) >= 0)
3741 {
3742 rtx nsplit = XEXP (*split, 0)(((*split)->u.fld[0]).rt_rtx);
3743 rtx i_rtx = gen_int_shift_amount (GET_MODE (nsplit)((machine_mode) (nsplit)->mode), i);
3744 SUBST (XEXP (*split, 0), gen_rtx_ASHIFT (GET_MODE (nsplit),do_SUBST (&((((*split)->u.fld[0]).rt_rtx)), (gen_rtx_fmt_ee_stat
((ASHIFT), ((((machine_mode) (nsplit)->mode))), (((((nsplit
)->u.fld[0]).rt_rtx))), ((i_rtx)) )))
3745 XEXP (nsplit, 0),do_SUBST (&((((*split)->u.fld[0]).rt_rtx)), (gen_rtx_fmt_ee_stat
((ASHIFT), ((((machine_mode) (nsplit)->mode))), (((((nsplit
)->u.fld[0]).rt_rtx))), ((i_rtx)) )))
3746 i_rtx))do_SUBST (&((((*split)->u.fld[0]).rt_rtx)), (gen_rtx_fmt_ee_stat
((ASHIFT), ((((machine_mode) (nsplit)->mode))), (((((nsplit
)->u.fld[0]).rt_rtx))), ((i_rtx)) )))
;
3747 /* Update split_code because we may not have a multiply
3748 anymore. */
3749 split_code = GET_CODE (*split)((enum rtx_code) (*split)->code);
3750 }
3751
3752#ifdef INSN_SCHEDULING
3753 /* If *SPLIT is a paradoxical SUBREG, when we split it, it should
3754 be written as a ZERO_EXTEND. */
3755 if (split_code == SUBREG && MEM_P (SUBREG_REG (*split))(((enum rtx_code) ((((*split)->u.fld[0]).rt_rtx))->code
) == MEM)
)
3756 {
3757 /* Or as a SIGN_EXTEND if LOAD_EXTEND_OP says that that's
3758 what it really is. */
3759 if (load_extend_op (GET_MODE (SUBREG_REG (*split))((machine_mode) ((((*split)->u.fld[0]).rt_rtx))->mode))
3760 == SIGN_EXTEND)
3761 SUBST (*split, gen_rtx_SIGN_EXTEND (split_mode,do_SUBST (&(*split), (gen_rtx_fmt_e_stat ((SIGN_EXTEND), (
(split_mode)), (((((*split)->u.fld[0]).rt_rtx))) )))
3762 SUBREG_REG (*split)))do_SUBST (&(*split), (gen_rtx_fmt_e_stat ((SIGN_EXTEND), (
(split_mode)), (((((*split)->u.fld[0]).rt_rtx))) )))
;
3763 else
3764 SUBST (*split, gen_rtx_ZERO_EXTEND (split_mode,do_SUBST (&(*split), (gen_rtx_fmt_e_stat ((ZERO_EXTEND), (
(split_mode)), (((((*split)->u.fld[0]).rt_rtx))) )))
3765 SUBREG_REG (*split)))do_SUBST (&(*split), (gen_rtx_fmt_e_stat ((ZERO_EXTEND), (
(split_mode)), (((((*split)->u.fld[0]).rt_rtx))) )))
;
3766 }
3767#endif
3768
3769 /* Attempt to split binary operators using arithmetic identities. */
3770 if (BINARY_P (SET_SRC (newpat))(((rtx_class[(int) (((enum rtx_code) ((((newpat)->u.fld[1]
).rt_rtx))->code))]) & (~3)) == (RTX_COMPARE & (~3
)))
3771 && split_mode == GET_MODE (SET_SRC (newpat))((machine_mode) ((((newpat)->u.fld[1]).rt_rtx))->mode)
3772 && ! side_effects_p (SET_SRC (newpat)(((newpat)->u.fld[1]).rt_rtx)))
3773 {
3774 rtx setsrc = SET_SRC (newpat)(((newpat)->u.fld[1]).rt_rtx);
3775 machine_mode mode = GET_MODE (setsrc)((machine_mode) (setsrc)->mode);
3776 enum rtx_code code = GET_CODE (setsrc)((enum rtx_code) (setsrc)->code);
3777 rtx src_op0 = XEXP (setsrc, 0)(((setsrc)->u.fld[0]).rt_rtx);
3778 rtx src_op1 = XEXP (setsrc, 1)(((setsrc)->u.fld[1]).rt_rtx);
3779
3780 /* Split "X = Y op Y" as "Z = Y; X = Z op Z". */
3781 if (rtx_equal_p (src_op0, src_op1))
3782 {
3783 newi2pat = gen_rtx_SET (newdest, src_op0)gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((newdest
)), ((src_op0)) )
;
3784 SUBST (XEXP (setsrc, 0), newdest)do_SUBST (&((((setsrc)->u.fld[0]).rt_rtx)), (newdest));
3785 SUBST (XEXP (setsrc, 1), newdest)do_SUBST (&((((setsrc)->u.fld[1]).rt_rtx)), (newdest));
3786 subst_done = true;
3787 }
3788 /* Split "((P op Q) op R) op S" where op is PLUS or MULT. */
3789 else if ((code == PLUS || code == MULT)
3790 && GET_CODE (src_op0)((enum rtx_code) (src_op0)->code) == code
3791 && GET_CODE (XEXP (src_op0, 0))((enum rtx_code) ((((src_op0)->u.fld[0]).rt_rtx))->code
)
== code
3792 && (INTEGRAL_MODE_P (mode)(((enum mode_class) mode_class[mode]) == MODE_INT || ((enum mode_class
) mode_class[mode]) == MODE_PARTIAL_INT || ((enum mode_class)
mode_class[mode]) == MODE_COMPLEX_INT || ((enum mode_class) mode_class
[mode]) == MODE_VECTOR_BOOL || ((enum mode_class) mode_class[
mode]) == MODE_VECTOR_INT)
3793 || (FLOAT_MODE_P (mode)(((enum mode_class) mode_class[mode]) == MODE_FLOAT || ((enum
mode_class) mode_class[mode]) == MODE_DECIMAL_FLOAT || ((enum
mode_class) mode_class[mode]) == MODE_COMPLEX_FLOAT || ((enum
mode_class) mode_class[mode]) == MODE_VECTOR_FLOAT)
3794 && flag_unsafe_math_optimizationsglobal_options.x_flag_unsafe_math_optimizations)))
3795 {
3796 rtx p = XEXP (XEXP (src_op0, 0), 0)((((((src_op0)->u.fld[0]).rt_rtx))->u.fld[0]).rt_rtx);
3797 rtx q = XEXP (XEXP (src_op0, 0), 1)((((((src_op0)->u.fld[0]).rt_rtx))->u.fld[1]).rt_rtx);
3798 rtx r = XEXP (src_op0, 1)(((src_op0)->u.fld[1]).rt_rtx);
3799 rtx s = src_op1;
3800
3801 /* Split both "((X op Y) op X) op Y" and
3802 "((X op Y) op Y) op X" as "T op T" where T is
3803 "X op Y". */
3804 if ((rtx_equal_p (p,r) && rtx_equal_p (q,s))
3805 || (rtx_equal_p (p,s) && rtx_equal_p (q,r)))
3806 {
3807 newi2pat = gen_rtx_SET (newdest, XEXP (src_op0, 0))gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((newdest
)), (((((src_op0)->u.fld[0]).rt_rtx))) )
;
3808 SUBST (XEXP (setsrc, 0), newdest)do_SUBST (&((((setsrc)->u.fld[0]).rt_rtx)), (newdest));
3809 SUBST (XEXP (setsrc, 1), newdest)do_SUBST (&((((setsrc)->u.fld[1]).rt_rtx)), (newdest));
3810 subst_done = true;
3811 }
3812 /* Split "((X op X) op Y) op Y)" as "T op T" where
3813 T is "X op Y". */
3814 else if (rtx_equal_p (p,q) && rtx_equal_p (r,s))
3815 {
3816 rtx tmp = simplify_gen_binary (code, mode, p, r);
3817 newi2pat = gen_rtx_SET (newdest, tmp)gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((newdest
)), ((tmp)) )
;
3818 SUBST (XEXP (setsrc, 0), newdest)do_SUBST (&((((setsrc)->u.fld[0]).rt_rtx)), (newdest));
3819 SUBST (XEXP (setsrc, 1), newdest)do_SUBST (&((((setsrc)->u.fld[1]).rt_rtx)), (newdest));
3820 subst_done = true;
3821 }
3822 }
3823 }
3824
3825 if (!subst_done)
3826 {
3827 newi2pat = gen_rtx_SET (newdest, *split)gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((newdest
)), ((*split)) )
;
3828 SUBST (*split, newdest)do_SUBST (&(*split), (newdest));
3829 }
3830
3831 i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes);
3832
3833 /* recog_for_combine might have added CLOBBERs to newi2pat.
3834 Make sure NEWPAT does not depend on the clobbered regs. */
3835 if (GET_CODE (newi2pat)((enum rtx_code) (newi2pat)->code) == PARALLEL)
3836 for (i = XVECLEN (newi2pat, 0)(((((newi2pat)->u.fld[0]).rt_rtvec))->num_elem) - 1; i >= 0; i--)
3837 if (GET_CODE (XVECEXP (newi2pat, 0, i))((enum rtx_code) ((((((newi2pat)->u.fld[0]).rt_rtvec))->
elem[i]))->code)
== CLOBBER)
3838 {
3839 rtx reg = XEXP (XVECEXP (newi2pat, 0, i), 0)((((((((newi2pat)->u.fld[0]).rt_rtvec))->elem[i]))->
u.fld[0]).rt_rtx)
;
3840 if (reg_overlap_mentioned_p (reg, newpat))
3841 {
3842 undo_all ();
3843 return 0;
3844 }
3845 }
3846
3847 /* If the split point was a MULT and we didn't have one before,
3848 don't use one now. */
3849 if (i2_code_number >= 0 && ! (split_code == MULT && ! have_mult))
3850 insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
3851 }
3852 }
3853
3854 /* Check for a case where we loaded from memory in a narrow mode and
3855 then sign extended it, but we need both registers. In that case,
3856 we have a PARALLEL with both loads from the same memory location.
3857 We can split this into a load from memory followed by a register-register
3858 copy. This saves at least one insn, more if register allocation can
3859 eliminate the copy.
3860
3861 We cannot do this if the destination of the first assignment is a
3862 condition code register. We eliminate this case by making sure
3863 the SET_DEST and SET_SRC have the same mode.
3864
3865 We cannot do this if the destination of the second assignment is
3866 a register that we have already assumed is zero-extended. Similarly
3867 for a SUBREG of such a register. */
3868
3869 else if (i1 && insn_code_number < 0 && asm_noperands (newpat) < 0
3870 && GET_CODE (newpat)((enum rtx_code) (newpat)->code) == PARALLEL
3871 && XVECLEN (newpat, 0)(((((newpat)->u.fld[0]).rt_rtvec))->num_elem) == 2
3872 && GET_CODE (XVECEXP (newpat, 0, 0))((enum rtx_code) ((((((newpat)->u.fld[0]).rt_rtvec))->elem
[0]))->code)
== SET
3873 && GET_CODE (SET_SRC (XVECEXP (newpat, 0, 0)))((enum rtx_code) (((((((((newpat)->u.fld[0]).rt_rtvec))->
elem[0]))->u.fld[1]).rt_rtx))->code)
== SIGN_EXTEND
3874 && (GET_MODE (SET_DEST (XVECEXP (newpat, 0, 0)))((machine_mode) (((((((((newpat)->u.fld[0]).rt_rtvec))->
elem[0]))->u.fld[0]).rt_rtx))->mode)
3875 == GET_MODE (SET_SRC (XVECEXP (newpat, 0, 0)))((machine_mode) (((((((((newpat)->u.fld[0]).rt_rtvec))->
elem[0]))->u.fld[1]).rt_rtx))->mode)
)
3876 && GET_CODE (XVECEXP (newpat, 0, 1))((enum rtx_code) ((((((newpat)->u.fld[0]).rt_rtvec))->elem
[1]))->code)
== SET
3877 && rtx_equal_p (SET_SRC (XVECEXP (newpat, 0, 1))((((((((newpat)->u.fld[0]).rt_rtvec))->elem[1]))->u.
fld[1]).rt_rtx)
,
3878 XEXP (SET_SRC (XVECEXP (newpat, 0, 0)), 0)(((((((((((newpat)->u.fld[0]).rt_rtvec))->elem[0]))->
u.fld[1]).rt_rtx))->u.fld[0]).rt_rtx)
)
3879 && !modified_between_p (SET_SRC (XVECEXP (newpat, 0, 1))((((((((newpat)->u.fld[0]).rt_rtvec))->elem[1]))->u.
fld[1]).rt_rtx)
, i2, i3)
3880 && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1)))((enum rtx_code) (((((((((newpat)->u.fld[0]).rt_rtvec))->
elem[1]))->u.fld[0]).rt_rtx))->code)
!= ZERO_EXTRACT
3881 && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1)))((enum rtx_code) (((((((((newpat)->u.fld[0]).rt_rtvec))->
elem[1]))->u.fld[0]).rt_rtx))->code)
!= STRICT_LOW_PART
3882 && ! (temp_expr = SET_DEST (XVECEXP (newpat, 0, 1))((((((((newpat)->u.fld[0]).rt_rtvec))->elem[1]))->u.
fld[0]).rt_rtx)
,
3883 (REG_P (temp_expr)(((enum rtx_code) (temp_expr)->code) == REG)
3884 && reg_stat[REGNO (temp_expr)(rhs_regno(temp_expr))].nonzero_bits != 0
3885 && known_lt (GET_MODE_PRECISION (GET_MODE (temp_expr)),(!maybe_le (((8) * (((global_options.x_ix86_isa_flags & (
1UL << 1)) != 0) ? 8 : 4)), GET_MODE_PRECISION (((machine_mode
) (temp_expr)->mode))))
3886 BITS_PER_WORD)(!maybe_le (((8) * (((global_options.x_ix86_isa_flags & (
1UL << 1)) != 0) ? 8 : 4)), GET_MODE_PRECISION (((machine_mode
) (temp_expr)->mode))))
3887 && known_lt (GET_MODE_PRECISION (GET_MODE (temp_expr)),(!maybe_le ((8 * 4), GET_MODE_PRECISION (((machine_mode) (temp_expr
)->mode))))
3888 HOST_BITS_PER_INT)(!maybe_le ((8 * 4), GET_MODE_PRECISION (((machine_mode) (temp_expr
)->mode))))
3889 && (reg_stat[REGNO (temp_expr)(rhs_regno(temp_expr))].nonzero_bits
3890 != GET_MODE_MASK (word_mode)mode_mask_array[word_mode])))
3891 && ! (GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1)))((enum rtx_code) (((((((((newpat)->u.fld[0]).rt_rtvec))->
elem[1]))->u.fld[0]).rt_rtx))->code)
== SUBREG
3892 && (temp_expr = SUBREG_REG (SET_DEST (XVECEXP (newpat, 0, 1)))(((((((((((newpat)->u.fld[0]).rt_rtvec))->elem[1]))->
u.fld[0]).rt_rtx))->u.fld[0]).rt_rtx)
,
3893 (REG_P (temp_expr)(((enum rtx_code) (temp_expr)->code) == REG)
3894 && reg_stat[REGNO (temp_expr)(rhs_regno(temp_expr))].nonzero_bits != 0
3895 && known_lt (GET_MODE_PRECISION (GET_MODE (temp_expr)),(!maybe_le (((8) * (((global_options.x_ix86_isa_flags & (
1UL << 1)) != 0) ? 8 : 4)), GET_MODE_PRECISION (((machine_mode
) (temp_expr)->mode))))
3896 BITS_PER_WORD)(!maybe_le (((8) * (((global_options.x_ix86_isa_flags & (
1UL << 1)) != 0) ? 8 : 4)), GET_MODE_PRECISION (((machine_mode
) (temp_expr)->mode))))
3897 && known_lt (GET_MODE_PRECISION (GET_MODE (temp_expr)),(!maybe_le ((8 * 4), GET_MODE_PRECISION (((machine_mode) (temp_expr
)->mode))))
3898 HOST_BITS_PER_INT)(!maybe_le ((8 * 4), GET_MODE_PRECISION (((machine_mode) (temp_expr
)->mode))))
3899 && (reg_stat[REGNO (temp_expr)(rhs_regno(temp_expr))].nonzero_bits
3900 != GET_MODE_MASK (word_mode)mode_mask_array[word_mode]))))
3901 && ! reg_overlap_mentioned_p (SET_DEST (XVECEXP (newpat, 0, 1))((((((((newpat)->u.fld[0]).rt_rtvec))->elem[1]))->u.
fld[0]).rt_rtx)
,
3902 SET_SRC (XVECEXP (newpat, 0, 1))((((((((newpat)->u.fld[0]).rt_rtvec))->elem[1]))->u.
fld[1]).rt_rtx)
)
3903 && ! find_reg_note (i3, REG_UNUSED,
3904 SET_DEST (XVECEXP (newpat, 0, 0))((((((((newpat)->u.fld[0]).rt_rtvec))->elem[0]))->u.
fld[0]).rt_rtx)
))
3905 {
3906 rtx ni2dest;
3907
3908 newi2pat = XVECEXP (newpat, 0, 0)(((((newpat)->u.fld[0]).rt_rtvec))->elem[0]);
3909 ni2dest = SET_DEST (XVECEXP (newpat, 0, 0))((((((((newpat)->u.fld[0]).rt_rtvec))->elem[0]))->u.
fld[0]).rt_rtx)
;
3910 newpat = XVECEXP (newpat, 0, 1)(((((newpat)->u.fld[0]).rt_rtvec))->elem[1]);
3911 SUBST (SET_SRC (newpat),do_SUBST (&((((newpat)->u.fld[1]).rt_rtx)), (rtl_hooks
.gen_lowpart (((machine_mode) ((((newpat)->u.fld[1]).rt_rtx
))->mode), ni2dest)))
3912 gen_lowpart (GET_MODE (SET_SRC (newpat)), ni2dest))do_SUBST (&((((newpat)->u.fld[1]).rt_rtx)), (rtl_hooks
.gen_lowpart (((machine_mode) ((((newpat)->u.fld[1]).rt_rtx
))->mode), ni2dest)))
;
3913 i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes);
3914
3915 if (i2_code_number >= 0)
3916 insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
3917
3918 if (insn_code_number >= 0)
3919 swap_i2i3 = 1;
3920 }
3921
3922 /* Similarly, check for a case where we have a PARALLEL of two independent
3923 SETs but we started with three insns. In this case, we can do the sets
3924 as two separate insns. This case occurs when some SET allows two
3925 other insns to combine, but the destination of that SET is still live.
3926
3927 Also do this if we started with two insns and (at least) one of the
3928 resulting sets is a noop; this noop will be deleted later.
3929
3930 Also do this if we started with two insns neither of which was a simple
3931 move. */
3932
3933 else if (insn_code_number < 0 && asm_noperands (newpat) < 0
3934 && GET_CODE (newpat)((enum rtx_code) (newpat)->code) == PARALLEL
3935 && XVECLEN (newpat, 0)(((((newpat)->u.fld[0]).rt_rtvec))->num_elem) == 2
3936 && GET_CODE (XVECEXP (newpat, 0, 0))((enum rtx_code) ((((((newpat)->u.fld[0]).rt_rtvec))->elem
[0]))->code)
== SET
3937 && GET_CODE (XVECEXP (newpat, 0, 1))((enum rtx_code) ((((((newpat)->u.fld[0]).rt_rtvec))->elem
[1]))->code)
== SET
3938 && (i1
3939 || set_noop_p (XVECEXP (newpat, 0, 0)(((((newpat)->u.fld[0]).rt_rtvec))->elem[0]))
3940 || set_noop_p (XVECEXP (newpat, 0, 1)(((((newpat)->u.fld[0]).rt_rtvec))->elem[1]))
3941 || (!i2_was_move && !i3_was_move))
3942 && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 0)))((enum rtx_code) (((((((((newpat)->u.fld[0]).rt_rtvec))->
elem[0]))->u.fld[0]).rt_rtx))->code)
!= ZERO_EXTRACT
3943 && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 0)))((enum rtx_code) (((((((((newpat)->u.fld[0]).rt_rtvec))->
elem[0]))->u.fld[0]).rt_rtx))->code)
!= STRICT_LOW_PART
3944 && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1)))((enum rtx_code) (((((((((newpat)->u.fld[0]).rt_rtvec))->
elem[1]))->u.fld[0]).rt_rtx))->code)
!= ZERO_EXTRACT
3945 && GET_CODE (SET_DEST (XVECEXP (newpat, 0, 1)))((enum rtx_code) (((((((((newpat)->u.fld[0]).rt_rtvec))->
elem[1]))->u.fld[0]).rt_rtx))->code)
!= STRICT_LOW_PART
3946 && ! reg_referenced_p (SET_DEST (XVECEXP (newpat, 0, 1))((((((((newpat)->u.fld[0]).rt_rtvec))->elem[1]))->u.
fld[0]).rt_rtx)
,
3947 XVECEXP (newpat, 0, 0)(((((newpat)->u.fld[0]).rt_rtvec))->elem[0]))
3948 && ! reg_referenced_p (SET_DEST (XVECEXP (newpat, 0, 0))((((((((newpat)->u.fld[0]).rt_rtvec))->elem[0]))->u.
fld[0]).rt_rtx)
,
3949 XVECEXP (newpat, 0, 1)(((((newpat)->u.fld[0]).rt_rtvec))->elem[1]))
3950 && ! (contains_muldiv (SET_SRC (XVECEXP (newpat, 0, 0))((((((((newpat)->u.fld[0]).rt_rtvec))->elem[0]))->u.
fld[1]).rt_rtx)
)
3951 && contains_muldiv (SET_SRC (XVECEXP (newpat, 0, 1))((((((((newpat)->u.fld[0]).rt_rtvec))->elem[1]))->u.
fld[1]).rt_rtx)
)))
3952 {
3953 rtx set0 = XVECEXP (newpat, 0, 0)(((((newpat)->u.fld[0]).rt_rtvec))->elem[0]);
3954 rtx set1 = XVECEXP (newpat, 0, 1)(((((newpat)->u.fld[0]).rt_rtvec))->elem[1]);
3955
3956 /* Normally, it doesn't matter which of the two is done first, but
3957 one which uses any regs/memory set in between i2 and i3 can't
3958 be first. The PARALLEL might also have been pre-existing in i3,
3959 so we need to make sure that we won't wrongly hoist a SET to i2
3960 that would conflict with a death note present in there, or would
3961 have its dest modified between i2 and i3. */
3962 if (!modified_between_p (SET_SRC (set1)(((set1)->u.fld[1]).rt_rtx), i2, i3)
3963 && !(REG_P (SET_DEST (set1))(((enum rtx_code) ((((set1)->u.fld[0]).rt_rtx))->code) ==
REG)
3964 && find_reg_note (i2, REG_DEAD, SET_DEST (set1)(((set1)->u.fld[0]).rt_rtx)))
3965 && !(GET_CODE (SET_DEST (set1))((enum rtx_code) ((((set1)->u.fld[0]).rt_rtx))->code) == SUBREG
3966 && find_reg_note (i2, REG_DEAD,
3967 SUBREG_REG (SET_DEST (set1))((((((set1)->u.fld[0]).rt_rtx))->u.fld[0]).rt_rtx)))
3968 && !modified_between_p (SET_DEST (set1)(((set1)->u.fld[0]).rt_rtx), i2, i3)
3969 /* If I3 is a jump, ensure that set0 is a jump so that
3970 we do not create invalid RTL. */
3971 && (!JUMP_P (i3)(((enum rtx_code) (i3)->code) == JUMP_INSN) || SET_DEST (set0)(((set0)->u.fld[0]).rt_rtx) == pc_rtx)
3972 )
3973 {
3974 newi2pat = set1;
3975 newpat = set0;
3976 }
3977 else if (!modified_between_p (SET_SRC (set0)(((set0)->u.fld[1]).rt_rtx), i2, i3)
3978 && !(REG_P (SET_DEST (set0))(((enum rtx_code) ((((set0)->u.fld[0]).rt_rtx))->code) ==
REG)
3979 && find_reg_note (i2, REG_DEAD, SET_DEST (set0)(((set0)->u.fld[0]).rt_rtx)))
3980 && !(GET_CODE (SET_DEST (set0))((enum rtx_code) ((((set0)->u.fld[0]).rt_rtx))->code) == SUBREG
3981 && find_reg_note (i2, REG_DEAD,
3982 SUBREG_REG (SET_DEST (set0))((((((set0)->u.fld[0]).rt_rtx))->u.fld[0]).rt_rtx)))
3983 && !modified_between_p (SET_DEST (set0)(((set0)->u.fld[0]).rt_rtx), i2, i3)
3984 /* If I3 is a jump, ensure that set1 is a jump so that
3985 we do not create invalid RTL. */
3986 && (!JUMP_P (i3)(((enum rtx_code) (i3)->code) == JUMP_INSN) || SET_DEST (set1)(((set1)->u.fld[0]).rt_rtx) == pc_rtx)
3987 )
3988 {
3989 newi2pat = set0;
3990 newpat = set1;
3991 }
3992 else
3993 {
3994 undo_all ();
3995 return 0;
3996 }
3997
3998 i2_code_number = recog_for_combine (&newi2pat, i2, &new_i2_notes);
3999
4000 if (i2_code_number >= 0)
4001 {
4002 /* recog_for_combine might have added CLOBBERs to newi2pat.
4003 Make sure NEWPAT does not depend on the clobbered regs. */
4004 if (GET_CODE (newi2pat)((enum rtx_code) (newi2pat)->code) == PARALLEL)
4005 {
4006 for (i = XVECLEN (newi2pat, 0)(((((newi2pat)->u.fld[0]).rt_rtvec))->num_elem) - 1; i >= 0; i--)
4007 if (GET_CODE (XVECEXP (newi2pat, 0, i))((enum rtx_code) ((((((newi2pat)->u.fld[0]).rt_rtvec))->
elem[i]))->code)
== CLOBBER)
4008 {
4009 rtx reg = XEXP (XVECEXP (newi2pat, 0, i), 0)((((((((newi2pat)->u.fld[0]).rt_rtvec))->elem[i]))->
u.fld[0]).rt_rtx)
;
4010 if (reg_overlap_mentioned_p (reg, newpat))
4011 {
4012 undo_all ();
4013 return 0;
4014 }
4015 }
4016 }
4017
4018 insn_code_number = recog_for_combine (&newpat, i3, &new_i3_notes);
4019
4020 if (insn_code_number >= 0)
4021 split_i2i3 = 1;
4022 }
4023 }
4024
4025 /* If it still isn't recognized, fail and change things back the way they
4026 were. */
4027 if ((insn_code_number < 0
4028 /* Is the result a reasonable ASM_OPERANDS? */
4029 && (! check_asm_operands (newpat) || added_sets_1 || added_sets_2)))
4030 {
4031 undo_all ();
4032 return 0;
4033 }
4034
4035 /* If we had to change another insn, make sure it is valid also. */
4036 if (undobuf.other_insn)
4037 {
4038 CLEAR_HARD_REG_SET (newpat_used_regs);
4039
4040 other_pat = PATTERN (undobuf.other_insn);
4041 other_code_number = recog_for_combine (&other_pat, undobuf.other_insn,
4042 &new_other_notes);
4043
4044 if (other_code_number < 0 && ! check_asm_operands (other_pat))
4045 {
4046 undo_all ();
4047 return 0;
4048 }
4049 }
4050
4051 /* Only allow this combination if insn_cost reports that the
4052 replacement instructions are cheaper than the originals. */
4053 if (!combine_validate_cost (i0, i1, i2, i3, newpat, newi2pat, other_pat))
4054 {
4055 undo_all ();
4056 return 0;
4057 }
4058
4059 if (MAY_HAVE_DEBUG_BIND_INSNSglobal_options.x_flag_var_tracking_assignments)
4060 {
4061 struct undo *undo;
4062
4063 for (undo = undobuf.undos; undo; undo = undo->next)
4064 if (undo->kind == UNDO_MODE)
4065 {
4066 rtx reg = *undo->where.r;
4067 machine_mode new_mode = GET_MODE (reg)((machine_mode) (reg)->mode);
4068 machine_mode old_mode = undo->old_contents.m;
4069
4070 /* Temporarily revert mode back. */
4071 adjust_reg_mode (reg, old_mode);
4072
4073 if (reg == i2dest && i2scratch)
4074 {
4075 /* If we used i2dest as a scratch register with a
4076 different mode, substitute it for the original
4077 i2src while its original mode is temporarily
4078 restored, and then clear i2scratch so that we don't
4079 do it again later. */
4080 propagate_for_debug (i2, last_combined_insn, reg, i2src,
4081 this_basic_block);
4082 i2scratch = false;
4083 /* Put back the new mode. */
4084 adjust_reg_mode (reg, new_mode);
4085 }
4086 else
4087 {
4088 rtx tempreg = gen_raw_REG (old_mode, REGNO (reg)(rhs_regno(reg)));
4089 rtx_insn *first, *last;
4090
4091 if (reg == i2dest)
4092 {
4093 first = i2;
4094 last = last_combined_insn;
4095 }
4096 else
4097 {
4098 first = i3;
4099 last = undobuf.other_insn;
4100 gcc_assert (last)((void)(!(last) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/combine.c"
, 4100, __FUNCTION__), 0 : 0))
;
4101 if (DF_INSN_LUID (last)((((df->insns[(INSN_UID (last))]))->luid))
4102 < DF_INSN_LUID (last_combined_insn)((((df->insns[(INSN_UID (last_combined_insn))]))->luid)
)
)
4103 last = last_combined_insn;
4104 }
4105
4106 /* We're dealing with a reg that changed mode but not
4107 meaning, so we want to turn it into a subreg for
4108 the new mode. However, because of REG sharing and
4109 because its mode had already changed, we have to do
4110 it in two steps. First, replace any debug uses of
4111 reg, with its original mode temporarily restored,
4112 with this copy we have created; then, replace the
4113 copy with the SUBREG of the original shared reg,
4114 once again changed to the new mode. */
4115 propagate_for_debug (first, last, reg, tempreg,
4116 this_basic_block);
4117 adjust_reg_mode (reg, new_mode);
4118 propagate_for_debug (first, last, tempreg,
4119 lowpart_subreg (old_mode, reg, new_mode),
4120 this_basic_block);
4121 }
4122 }
4123 }
4124
4125 /* If we will be able to accept this, we have made a
4126 change to the destination of I3. This requires us to
4127 do a few adjustments. */
4128
4129 if (changed_i3_dest)
4130 {
4131 PATTERN (i3) = newpat;
4132 adjust_for_new_dest (i3);
4133 }
4134
4135 /* We now know that we can do this combination. Merge the insns and
4136 update the status of registers and LOG_LINKS. */
4137
4138 if (undobuf.other_insn)
4139 {
4140 rtx note, next;
4141
4142 PATTERN (undobuf.other_insn) = other_pat;
4143
4144 /* If any of the notes in OTHER_INSN were REG_DEAD or REG_UNUSED,
4145 ensure that they are still valid. Then add any non-duplicate
4146 notes added by recog_for_combine. */
4147 for (note = REG_NOTES (undobuf.other_insn)(((undobuf.other_insn)->u.fld[6]).rt_rtx); note; note = next)
4148 {
4149 next = XEXP (note, 1)(((note)->u.fld[1]).rt_rtx);
4150
4151 if ((REG_NOTE_KIND (note)((enum reg_note) ((machine_mode) (note)->mode)) == REG_DEAD
4152 && !reg_referenced_p (XEXP (note, 0)(((note)->u.fld[0]).rt_rtx),
4153 PATTERN (undobuf.other_insn)))
4154 ||(REG_NOTE_KIND (note)((enum reg_note) ((machine_mode) (note)->mode)) == REG_UNUSED
4155 && !reg_set_p (XEXP (note, 0)(((note)->u.fld[0]).rt_rtx),
4156 PATTERN (undobuf.other_insn)))
4157 /* Simply drop equal note since it may be no longer valid
4158 for other_insn. It may be possible to record that CC
4159 register is changed and only discard those notes, but
4160 in practice it's unnecessary complication and doesn't
4161 give any meaningful improvement.
4162
4163 See PR78559. */
4164 || REG_NOTE_KIND (note)((enum reg_note) ((machine_mode) (note)->mode)) == REG_EQUAL
4165 || REG_NOTE_KIND (note)((enum reg_note) ((machine_mode) (note)->mode)) == REG_EQUIV)
4166 remove_note (undobuf.other_insn, note);
4167 }
4168
4169 distribute_notes (new_other_notes, undobuf.other_insn,
4170 undobuf.other_insn, NULLnullptr, NULL_RTX(rtx) 0, NULL_RTX(rtx) 0,
4171 NULL_RTX(rtx) 0);
4172 }
4173
4174 if (swap_i2i3)
4175 {
4176 /* I3 now uses what used to be its destination and which is now
4177 I2's destination. This requires us to do a few adjustments. */
4178 PATTERN (i3) = newpat;
4179 adjust_for_new_dest (i3);
4180 }
4181
4182 if (swap_i2i3 || split_i2i3)
4183 {
4184 /* We might need a LOG_LINK from I3 to I2. But then we used to
4185 have one, so we still will.
4186
4187 However, some later insn might be using I2's dest and have
4188 a LOG_LINK pointing at I3. We should change it to point at
4189 I2 instead. */
4190
4191 /* newi2pat is usually a SET here; however, recog_for_combine might
4192 have added some clobbers. */
4193 rtx x = newi2pat;
4194 if (GET_CODE (x)((enum rtx_code) (x)->code) == PARALLEL)
4195 x = XVECEXP (newi2pat, 0, 0)(((((newi2pat)->u.fld[0]).rt_rtvec))->elem[0]);
4196
4197 if (REG_P (SET_DEST (x))(((enum rtx_code) ((((x)->u.fld[0]).rt_rtx))->code) == REG
)
4198 || (GET_CODE (SET_DEST (x))((enum rtx_code) ((((x)->u.fld[0]).rt_rtx))->code) == SUBREG
4199 && REG_P (SUBREG_REG (SET_DEST (x)))(((enum rtx_code) (((((((x)->u.fld[0]).rt_rtx))->u.fld[
0]).rt_rtx))->code) == REG)
))
4200 {
4201 unsigned int regno = reg_or_subregno (SET_DEST (x)(((x)->u.fld[0]).rt_rtx));
4202
4203 bool done = false;
4204 for (rtx_insn *insn = NEXT_INSN (i3);
4205 !done
4206 && insn
4207 && NONDEBUG_INSN_P (insn)((((enum rtx_code) (insn)->code) == INSN) || (((enum rtx_code
) (insn)->code) == JUMP_INSN) || (((enum rtx_code) (insn)->
code) == CALL_INSN))
4208 && BLOCK_FOR_INSN (insn) == this_basic_block;
4209 insn = NEXT_INSN (insn))
4210 {
4211 struct insn_link *link;
4212 FOR_EACH_LOG_LINK (link, insn)for ((link) = (uid_log_links[insn_uid_check (insn)]); (link);
(link) = (link)->next)
4213 if (link->insn == i3 && link->regno == regno)
4214 {
4215 link->insn = i2;
4216 done = true;
4217 break;
4218 }
4219 }
4220 }
4221 }
4222
4223 {
4224 rtx i3notes, i2notes, i1notes = 0, i0notes = 0;
4225 struct insn_link *i3links, *i2links, *i1links = 0, *i0links = 0;
4226 rtx midnotes = 0;
4227 int from_luid;
4228 /* Compute which registers we expect to eliminate. newi2pat may be setting
4229 either i3dest or i2dest, so we must check it. */
4230 rtx elim_i2 = ((newi2pat && reg_set_p (i2dest, newi2pat))
4231 || i2dest_in_i2src || i2dest_in_i1src || i2dest_in_i0src
4232 || !i2dest_killed
4233 ? 0 : i2dest);
4234 /* For i1, we need to compute both local elimination and global
4235 elimination information with respect to newi2pat because i1dest
4236 may be the same as i3dest, in which case newi2pat may be setting
4237 i1dest. Global information is used when distributing REG_DEAD
4238 note for i2 and i3, in which case it does matter if newi2pat sets
4239 i1dest or not.
4240
4241 Local information is used when distributing REG_DEAD note for i1,
4242 in which case it doesn't matter if newi2pat sets i1dest or not.
4243 See PR62151, if we have four insns combination:
4244 i0: r0 <- i0src
4245 i1: r1 <- i1src (using r0)
4246 REG_DEAD (r0)
4247 i2: r0 <- i2src (using r1)
4248 i3: r3 <- i3src (using r0)
4249 ix: using r0
4250 From i1's point of view, r0 is eliminated, no matter if it is set
4251 by newi2pat or not. In other words, REG_DEAD info for r0 in i1
4252 should be discarded.
4253
4254 Note local information only affects cases in forms like "I1->I2->I3",
4255 "I0->I1->I2->I3" or "I0&I1->I2, I2->I3". For other cases like
4256 "I0->I1, I1&I2->I3" or "I1&I2->I3", newi2pat won't set i1dest or
4257 i0dest anyway. */
4258 rtx local_elim_i1 = (i1 == 0 || i1dest_in_i1src || i1dest_in_i0src
4259 || !i1dest_killed
4260 ? 0 : i1dest);
4261 rtx elim_i1 = (local_elim_i1 == 0
4262 || (newi2pat && reg_set_p (i1dest, newi2pat))
4263 ? 0 : i1dest);
4264 /* Same case as i1. */
4265 rtx local_elim_i0 = (i0 == 0 || i0dest_in_i0src || !i0dest_killed
4266 ? 0 : i0dest);
4267 rtx elim_i0 = (local_elim_i0 == 0
4268 || (newi2pat && reg_set_p (i0dest, newi2pat))
4269 ? 0 : i0dest);
4270
4271 /* Get the old REG_NOTES and LOG_LINKS from all our insns and
4272 clear them. */
4273 i3notes = REG_NOTES (i3)(((i3)->u.fld[6]).rt_rtx), i3links = LOG_LINKS (i3)(uid_log_links[insn_uid_check (i3)]);
4274 i2notes = REG_NOTES (i2)(((i2)->u.fld[6]).rt_rtx), i2links = LOG_LINKS (i2)(uid_log_links[insn_uid_check (i2)]);
4275 if (i1)
4276 i1notes = REG_NOTES (i1)(((i1)->u.fld[6]).rt_rtx), i1links = LOG_LINKS (i1)(uid_log_links[insn_uid_check (i1)]);
4277 if (i0)
4278 i0notes = REG_NOTES (i0)(((i0)->u.fld[6]).rt_rtx), i0links = LOG_LINKS (i0)(uid_log_links[insn_uid_check (i0)]);
4279
4280 /* Ensure that we do not have something that should not be shared but
4281 occurs multiple times in the new insns. Check this by first
4282 resetting all the `used' flags and then copying anything is shared. */
4283
4284 reset_used_flags (i3notes);
4285 reset_used_flags (i2notes);
4286 reset_used_flags (i1notes);
4287 reset_used_flags (i0notes);
4288 reset_used_flags (newpat);
4289 reset_used_flags (newi2pat);
4290 if (undobuf.other_insn)
4291 reset_used_flags (PATTERN (undobuf.other_insn));
4292
4293 i3notes = copy_rtx_if_shared (i3notes);
4294 i2notes = copy_rtx_if_shared (i2notes);
4295 i1notes = copy_rtx_if_shared (i1notes);
4296 i0notes = copy_rtx_if_shared (i0notes);
4297 newpat = copy_rtx_if_shared (newpat);
4298 newi2pat = copy_rtx_if_shared (newi2pat);
4299 if (undobuf.other_insn)
4300 reset_used_flags (PATTERN (undobuf.other_insn));
4301
4302 INSN_CODE (i3)(((i3)->u.fld[5]).rt_int) = insn_code_number;
4303 PATTERN (i3) = newpat;
4304
4305 if (CALL_P (i3)(((enum rtx_code) (i3)->code) == CALL_INSN) && CALL_INSN_FUNCTION_USAGE (i3)(((i3)->u.fld[7]).rt_rtx))
4306 {
4307 for (rtx link = CALL_INSN_FUNCTION_USAGE (i3)(((i3)->u.fld[7]).rt_rtx); link;
4308 link = XEXP (link, 1)(((link)->u.fld[1]).rt_rtx))
4309 {
4310 if (substed_i2)
4311 {
4312 /* I2SRC must still be meaningful at this point. Some
4313 splitting operations can invalidate I2SRC, but those
4314 operations do not apply to calls. */
4315 gcc_assert (i2src)((void)(!(i2src) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/combine.c"
, 4315, __FUNCTION__), 0 : 0))
;
4316 XEXP (link, 0)(((link)->u.fld[0]).rt_rtx) = simplify_replace_rtx (XEXP (link, 0)(((link)->u.fld[0]).rt_rtx),
4317 i2dest, i2src);
4318 }
4319 if (substed_i1)
4320 XEXP (link, 0)(((link)->u.fld[0]).rt_rtx) = simplify_replace_rtx (XEXP (link, 0)(((link)->u.fld[0]).rt_rtx),
4321 i1dest, i1src);
4322 if (substed_i0)
4323 XEXP (link, 0)(((link)->u.fld[0]).rt_rtx) = simplify_replace_rtx (XEXP (link, 0)(((link)->u.fld[0]).rt_rtx),
4324 i0dest, i0src);
4325 }
4326 }
4327
4328 if (undobuf.other_insn)
4329 INSN_CODE (undobuf.other_insn)(((undobuf.other_insn)->u.fld[5]).rt_int) = other_code_number;
4330
4331 /* We had one special case above where I2 had more than one set and
4332 we replaced a destination of one of those sets with the destination
4333 of I3. In that case, we have to update LOG_LINKS of insns later
4334 in this basic block. Note that this (expensive) case is rare.
4335
4336 Also, in this case, we must pretend that all REG_NOTEs for I2
4337 actually came from I3, so that REG_UNUSED notes from I2 will be
4338 properly handled. */
4339
4340 if (i3_subst_into_i2)
4341 {
4342 for (i = 0; i < XVECLEN (PATTERN (i2), 0)(((((PATTERN (i2))->u.fld[0]).rt_rtvec))->num_elem); i++)
4343 if ((GET_CODE (XVECEXP (PATTERN (i2), 0, i))((enum rtx_code) ((((((PATTERN (i2))->u.fld[0]).rt_rtvec))
->elem[i]))->code)
== SET
4344 || GET_CODE (XVECEXP (PATTERN (i2), 0, i))((enum rtx_code) ((((((PATTERN (i2))->u.fld[0]).rt_rtvec))
->elem[i]))->code)
== CLOBBER)
4345 && REG_P (SET_DEST (XVECEXP (PATTERN (i2), 0, i)))(((enum rtx_code) (((((((((PATTERN (i2))->u.fld[0]).rt_rtvec
))->elem[i]))->u.fld[0]).rt_rtx))->code) == REG)
4346 && SET_DEST (XVECEXP (PATTERN (i2), 0, i))((((((((PATTERN (i2))->u.fld[0]).rt_rtvec))->elem[i]))->
u.fld[0]).rt_rtx)
!= i2dest
4347 && ! find_reg_note (i2, REG_UNUSED,
4348 SET_DEST (XVECEXP (PATTERN (i2), 0, i))((((((((PATTERN (i2))->u.fld[0]).rt_rtvec))->elem[i]))->
u.fld[0]).rt_rtx)
))
4349 for (temp_insn = NEXT_INSN (i2);
4350 temp_insn
4351 && (this_basic_block->next_bb == EXIT_BLOCK_PTR_FOR_FN (cfun)(((cfun + 0))->cfg->x_exit_block_ptr)
4352 || BB_HEAD (this_basic_block)(this_basic_block)->il.x.head_ != temp_insn);
4353 temp_insn = NEXT_INSN (temp_insn))
4354 if (temp_insn != i3 && NONDEBUG_INSN_P (temp_insn)((((enum rtx_code) (temp_insn)->code) == INSN) || (((enum rtx_code
) (temp_insn)->code) == JUMP_INSN) || (((enum rtx_code) (temp_insn
)->code) == CALL_INSN))
)
4355 FOR_EACH_LOG_LINK (link, temp_insn)for ((link) = (uid_log_links[insn_uid_check (temp_insn)]); (link
); (link) = (link)->next)
4356 if (link->insn == i2)
4357 link->insn = i3;
4358
4359 if (i3notes)
4360 {
4361 rtx link = i3notes;
4362 while (XEXP (link, 1)(((link)->u.fld[1]).rt_rtx))
4363 link = XEXP (link, 1)(((link)->u.fld[1]).rt_rtx);
4364 XEXP (link, 1)(((link)->u.fld[1]).rt_rtx) = i2notes;
4365 }
4366 else
4367 i3notes = i2notes;
4368 i2notes = 0;
4369 }
4370
4371 LOG_LINKS (i3)(uid_log_links[insn_uid_check (i3)]) = NULLnullptr;
4372 REG_NOTES (i3)(((i3)->u.fld[6]).rt_rtx) = 0;
4373 LOG_LINKS (i2)(uid_log_links[insn_uid_check (i2)]) = NULLnullptr;
4374 REG_NOTES (i2)(((i2)->u.fld[6]).rt_rtx) = 0;
4375
4376 if (newi2pat)
4377 {
4378 if (MAY_HAVE_DEBUG_BIND_INSNSglobal_options.x_flag_var_tracking_assignments && i2scratch)
4379 propagate_for_debug (i2, last_combined_insn, i2dest, i2src,
4380 this_basic_block);
4381 INSN_CODE (i2)(((i2)->u.fld[5]).rt_int) = i2_code_number;
4382 PATTERN (i2) = newi2pat;
4383 }
4384 else
4385 {
4386 if (MAY_HAVE_DEBUG_BIND_INSNSglobal_options.x_flag_var_tracking_assignments && i2src)
4387 propagate_for_debug (i2, last_combined_insn, i2dest, i2src,
4388 this_basic_block);
4389 SET_INSN_DELETED (i2)set_insn_deleted (i2);;
4390 }
4391
4392 if (i1)
4393 {
4394 LOG_LINKS (i1)(uid_log_links[insn_uid_check (i1)]) = NULLnullptr;
4395 REG_NOTES (i1)(((i1)->u.fld[6]).rt_rtx) = 0;
4396 if (MAY_HAVE_DEBUG_BIND_INSNSglobal_options.x_flag_var_tracking_assignments)
4397 propagate_for_debug (i1, last_combined_insn, i1dest, i1src,
4398 this_basic_block);
4399 SET_INSN_DELETED (i1)set_insn_deleted (i1);;
4400 }
4401
4402 if (i0)
4403 {
4404 LOG_LINKS (i0)(uid_log_links[insn_uid_check (i0)]) = NULLnullptr;
4405 REG_NOTES (i0)(((i0)->u.fld[6]).rt_rtx) = 0;
4406 if (MAY_HAVE_DEBUG_BIND_INSNSglobal_options.x_flag_var_tracking_assignments)
4407 propagate_for_debug (i0, last_combined_insn, i0dest, i0src,
4408 this_basic_block);
4409 SET_INSN_DELETED (i0)set_insn_deleted (i0);;
4410 }
4411
4412 /* Get death notes for everything that is now used in either I3 or
4413 I2 and used to die in a previous insn. If we built two new
4414 patterns, move from I1 to I2 then I2 to I3 so that we get the
4415 proper movement on registers that I2 modifies. */
4416
4417 if (i0)
4418 from_luid = DF_INSN_LUID (i0)((((df->insns[(INSN_UID (i0))]))->luid));
4419 else if (i1)
4420 from_luid = DF_INSN_LUID (i1)((((df->insns[(INSN_UID (i1))]))->luid));
4421 else
4422 from_luid = DF_INSN_LUID (i2)((((df->insns[(INSN_UID (i2))]))->luid));
4423 if (newi2pat)
4424 move_deaths (newi2pat, NULL_RTX(rtx) 0, from_luid, i2, &midnotes);
4425 move_deaths (newpat, newi2pat, from_luid, i3, &midnotes);
4426
4427 /* Distribute all the LOG_LINKS and REG_NOTES from I1, I2, and I3. */
4428 if (i3notes)
4429 distribute_notes (i3notes, i3, i3, newi2pat ? i2 : NULLnullptr,
4430 elim_i2, elim_i1, elim_i0);
4431 if (i2notes)
4432 distribute_notes (i2notes, i2, i3, newi2pat ? i2 : NULLnullptr,
4433 elim_i2, elim_i1, elim_i0);
4434 if (i1notes)
4435 distribute_notes (i1notes, i1, i3, newi2pat ? i2 : NULLnullptr,
4436 elim_i2, local_elim_i1, local_elim_i0);
4437 if (i0notes)
4438 distribute_notes (i0notes, i0, i3, newi2pat ? i2 : NULLnullptr,
4439 elim_i2, elim_i1, local_elim_i0);
4440 if (midnotes)
4441 distribute_notes (midnotes, NULLnullptr, i3, newi2pat ? i2 : NULLnullptr,
4442 elim_i2, elim_i1, elim_i0);
4443
4444 /* Distribute any notes added to I2 or I3 by recog_for_combine. We
4445 know these are REG_UNUSED and want them to go to the desired insn,
4446 so we always pass it as i3. */
4447
4448 if (newi2pat && new_i2_notes)
4449 distribute_notes (new_i2_notes, i2, i2, NULLnullptr, NULL_RTX(rtx) 0, NULL_RTX(rtx) 0,
4450 NULL_RTX(rtx) 0);
4451
4452 if (new_i3_notes)
4453 distribute_notes (new_i3_notes, i3, i3, NULLnullptr, NULL_RTX(rtx) 0, NULL_RTX(rtx) 0,
4454 NULL_RTX(rtx) 0);
4455
4456 /* If I3DEST was used in I3SRC, it really died in I3. We may need to
4457 put a REG_DEAD note for it somewhere. If NEWI2PAT exists and sets
4458 I3DEST, the death must be somewhere before I2, not I3. If we passed I3
4459 in that case, it might delete I2. Similarly for I2 and I1.
4460 Show an additional death due to the REG_DEAD note we make here. If
4461 we discard it in distribute_notes, we will decrement it again. */
4462
4463 if (i3dest_killed)
4464 {
4465 rtx new_note = alloc_reg_note (REG_DEAD, i3dest_killed, NULL_RTX(rtx) 0);
4466 if (newi2pat && reg_set_p (i3dest_killed, newi2pat))
4467 distribute_notes (new_note, NULLnullptr, i2, NULLnullptr, elim_i2,
4468 elim_i1, elim_i0);
4469 else
4470 distribute_notes (new_note, NULLnullptr, i3, newi2pat ? i2 : NULLnullptr,
4471 elim_i2, elim_i1, elim_i0);
4472 }
4473
4474 if (i2dest_in_i2src)
4475 {
4476 rtx new_note = alloc_reg_note (REG_DEAD, i2dest, NULL_RTX(rtx) 0);
4477 if (newi2pat && reg_set_p (i2dest, newi2pat))
4478 distribute_notes (new_note, NULLnullptr, i2, NULLnullptr, NULL_RTX(rtx) 0,
4479 NULL_RTX(rtx) 0, NULL_RTX(rtx) 0);
4480 else
4481 distribute_notes (new_note, NULLnullptr, i3, newi2pat ? i2 : NULLnullptr,
4482 NULL_RTX(rtx) 0, NULL_RTX(rtx) 0, NULL_RTX(rtx) 0);
4483 }
4484
4485 if (i1dest_in_i1src)
4486 {
4487 rtx new_note = alloc_reg_note (REG_DEAD, i1dest, NULL_RTX(rtx) 0);
4488 if (newi2pat && reg_set_p (i1dest, newi2pat))
4489 distribute_notes (new_note, NULLnullptr, i2, NULLnullptr, NULL_RTX(rtx) 0,
4490 NULL_RTX(rtx) 0, NULL_RTX(rtx) 0);
4491 else
4492 distribute_notes (new_note, NULLnullptr, i3, newi2pat ? i2 : NULLnullptr,
4493 NULL_RTX(rtx) 0, NULL_RTX(rtx) 0, NULL_RTX(rtx) 0);
4494 }
4495
4496 if (i0dest_in_i0src)
4497 {
4498 rtx new_note = alloc_reg_note (REG_DEAD, i0dest, NULL_RTX(rtx) 0);
4499 if (newi2pat && reg_set_p (i0dest, newi2pat))
4500 distribute_notes (new_note, NULLnullptr, i2, NULLnullptr, NULL_RTX(rtx) 0,
4501 NULL_RTX(rtx) 0, NULL_RTX(rtx) 0);
4502 else
4503 distribute_notes (new_note, NULLnullptr, i3, newi2pat ? i2 : NULLnullptr,
4504 NULL_RTX(rtx) 0, NULL_RTX(rtx) 0, NULL_RTX(rtx) 0);
4505 }
4506
4507 distribute_links (i3links);
4508 distribute_links (i2links);
4509 distribute_links (i1links);
4510 distribute_links (i0links);
4511
4512 if (REG_P (i2dest)(((enum rtx_code) (i2dest)->code) == REG))
4513 {
4514 struct insn_link *link;
4515 rtx_insn *i2_insn = 0;
4516 rtx i2_val = 0, set;
4517
4518 /* The insn that used to set this register doesn't exist, and
4519 this life of the register may not exist either. See if one of
4520 I3's links points to an insn that sets I2DEST. If it does,
4521 that is now the last known value for I2DEST. If we don't update
4522 this and I2 set the register to a value that depended on its old
4523 contents, we will get confused. If this insn is used, thing
4524 will be set correctly in combine_instructions. */
4525 FOR_EACH_LOG_LINK (link, i3)for ((link) = (uid_log_links[insn_uid_check (i3)]); (link); (
link) = (link)->next)
4526 if ((set = single_set (link->insn)) != 0
4527 && rtx_equal_p (i2dest, SET_DEST (set)(((set)->u.fld[0]).rt_rtx)))
4528 i2_insn = link->insn, i2_val = SET_SRC (set)(((set)->u.fld[1]).rt_rtx);
4529
4530 record_value_for_reg (i2dest, i2_insn, i2_val);
4531
4532 /* If the reg formerly set in I2 died only once and that was in I3,
4533 zero its use count so it won't make `reload' do any work. */
4534 if (! added_sets_2
4535 && (newi2pat == 0 || ! reg_mentioned_p (i2dest, newi2pat))
4536 && ! i2dest_in_i2src
4537 && REGNO (i2dest)(rhs_regno(i2dest)) < reg_n_sets_max)
4538 INC_REG_N_SETS (REGNO (i2dest), -1)(regstat_n_sets_and_refs[(rhs_regno(i2dest))].sets += -1);
4539 }
4540
4541 if (i1 && REG_P (i1dest)(((enum rtx_code) (i1dest)->code) == REG))
4542 {
4543 struct insn_link *link;
4544 rtx_insn *i1_insn = 0;
4545 rtx i1_val = 0, set;
4546
4547 FOR_EACH_LOG_LINK (link, i3)for ((link) = (uid_log_links[insn_uid_check (i3)]); (link); (
link) = (link)->next)
4548 if ((set = single_set (link->insn)) != 0
4549 && rtx_equal_p (i1dest, SET_DEST (set)(((set)->u.fld[0]).rt_rtx)))
4550 i1_insn = link->insn, i1_val = SET_SRC (set)(((set)->u.fld[1]).rt_rtx);
4551
4552 record_value_for_reg (i1dest, i1_insn, i1_val);
4553
4554 if (! added_sets_1
4555 && ! i1dest_in_i1src
4556 && REGNO (i1dest)(rhs_regno(i1dest)) < reg_n_sets_max)
4557 INC_REG_N_SETS (REGNO (i1dest), -1)(regstat_n_sets_and_refs[(rhs_regno(i1dest))].sets += -1);
4558 }
4559
4560 if (i0 && REG_P (i0dest)(((enum rtx_code) (i0dest)->code) == REG))
4561 {
4562 struct insn_link *link;
4563 rtx_insn *i0_insn = 0;
4564 rtx i0_val = 0, set;
4565
4566 FOR_EACH_LOG_LINK (link, i3)for ((link) = (uid_log_links[insn_uid_check (i3)]); (link); (
link) = (link)->next)
4567 if ((set = single_set (link->insn)) != 0
4568 && rtx_equal_p (i0dest, SET_DEST (set)(((set)->u.fld[0]).rt_rtx)))
4569 i0_insn = link->insn, i0_val = SET_SRC (set)(((set)->u.fld[1]).rt_rtx);
4570
4571 record_value_for_reg (i0dest, i0_insn, i0_val);
4572
4573 if (! added_sets_0
4574 && ! i0dest_in_i0src
4575 && REGNO (i0dest)(rhs_regno(i0dest)) < reg_n_sets_max)
4576 INC_REG_N_SETS (REGNO (i0dest), -1)(regstat_n_sets_and_refs[(rhs_regno(i0dest))].sets += -1);
4577 }
4578
4579 /* Update reg_stat[].nonzero_bits et al for any changes that may have
4580 been made to this insn. The order is important, because newi2pat
4581 can affect nonzero_bits of newpat. */
4582 if (newi2pat)
4583 note_pattern_stores (newi2pat, set_nonzero_bits_and_sign_copies, NULLnullptr);
4584 note_pattern_stores (newpat, set_nonzero_bits_and_sign_copies, NULLnullptr);
4585 }
4586
4587 if (undobuf.other_insn != NULL_RTX(rtx) 0)
4588 {
4589 if (dump_file)
4590 {
4591 fprintf (dump_file, "modifying other_insn ");
4592 dump_insn_slim (dump_file, undobuf.other_insn);
4593 }
4594 df_insn_rescan (undobuf.other_insn);
4595 }
4596
4597 if (i0 && !(NOTE_P (i0)(((enum rtx_code) (i0)->code) == NOTE) && (NOTE_KIND (i0)(((i0)->u.fld[4]).rt_int) == NOTE_INSN_DELETED)))
4598 {
4599 if (dump_file)
4600 {
4601 fprintf (dump_file, "modifying insn i0 ");
4602 dump_insn_slim (dump_file, i0);
4603 }
4604 df_insn_rescan (i0);
4605 }
4606
4607 if (i1 && !(NOTE_P (i1)(((enum rtx_code) (i1)->code) == NOTE) && (NOTE_KIND (i1)(((i1)->u.fld[4]).rt_int) == NOTE_INSN_DELETED)))
4608 {
4609 if (dump_file)
4610 {
4611 fprintf (dump_file, "modifying insn i1 ");
4612 dump_insn_slim (dump_file, i1);
4613 }
4614 df_insn_rescan (i1);
4615 }
4616
4617 if (i2 && !(NOTE_P (i2)(((enum rtx_code) (i2)->code) == NOTE) && (NOTE_KIND (i2)(((i2)->u.fld[4]).rt_int) == NOTE_INSN_DELETED)))
4618 {
4619 if (dump_file)
4620 {
4621 fprintf (dump_file, "modifying insn i2 ");
4622 dump_insn_slim (dump_file, i2);
4623 }
4624 df_insn_rescan (i2);
4625 }
4626
4627 if (i3 && !(NOTE_P (i3)(((enum rtx_code) (i3)->code) == NOTE) && (NOTE_KIND (i3)(((i3)->u.fld[4]).rt_int) == NOTE_INSN_DELETED)))
4628 {
4629 if (dump_file)
4630 {
4631 fprintf (dump_file, "modifying insn i3 ");
4632 dump_insn_slim (dump_file, i3);
4633 }
4634 df_insn_rescan (i3);
4635 }
4636
4637 /* Set new_direct_jump_p if a new return or simple jump instruction
4638 has been created. Adjust the CFG accordingly. */
4639 if (returnjump_p (i3) || any_uncondjump_p (i3))
4640 {
4641 *new_direct_jump_p = 1;
4642 mark_jump_label (PATTERN (i3), i3, 0);
4643 update_cfg_for_uncondjump (i3);
4644 }
4645
4646 if (undobuf.other_insn != NULL_RTX(rtx) 0
4647 && (returnjump_p (undobuf.other_insn)
4648 || any_uncondjump_p (undobuf.other_insn)))
4649 {
4650 *new_direct_jump_p = 1;
4651 update_cfg_for_uncondjump (undobuf.other_insn);
4652 }
4653
4654 if (GET_CODE (PATTERN (i3))((enum rtx_code) (PATTERN (i3))->code) == TRAP_IF
4655 && XEXP (PATTERN (i3), 0)(((PATTERN (i3))->u.fld[0]).rt_rtx) == const1_rtx(const_int_rtx[64 +1]))
4656 {
4657 basic_block bb = BLOCK_FOR_INSN (i3);
4658 gcc_assert (bb)((void)(!(bb) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/combine.c"
, 4658, __FUNCTION__), 0 : 0))
;
4659 remove_edge (split_block (bb, i3));
4660 emit_barrier_after_bb (bb);
4661 *new_direct_jump_p = 1;
4662 }
4663
4664 if (undobuf.other_insn
4665 && GET_CODE (PATTERN (undobuf.other_insn))((enum rtx_code) (PATTERN (undobuf.other_insn))->code) == TRAP_IF
4666 && XEXP (PATTERN (undobuf.other_insn), 0)(((PATTERN (undobuf.other_insn))->u.fld[0]).rt_rtx) == const1_rtx(const_int_rtx[64 +1]))
4667 {
4668 basic_block bb = BLOCK_FOR_INSN (undobuf.other_insn);
4669 gcc_assert (bb)((void)(!(bb) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/combine.c"
, 4669, __FUNCTION__), 0 : 0))
;
4670 remove_edge (split_block (bb, undobuf.other_insn));
4671 emit_barrier_after_bb (bb);
4672 *new_direct_jump_p = 1;
4673 }
4674
4675 /* A noop might also need cleaning up of CFG, if it comes from the
4676 simplification of a jump. */
4677 if (JUMP_P (i3)(((enum rtx_code) (i3)->code) == JUMP_INSN)
4678 && GET_CODE (newpat)((enum rtx_code) (newpat)->code) == SET
4679 && SET_SRC (newpat)(((newpat)->u.fld[1]).rt_rtx) == pc_rtx
4680 && SET_DEST (newpat)(((newpat)->u.fld[0]).rt_rtx) == pc_rtx)
4681 {
4682 *new_direct_jump_p = 1;
4683 update_cfg_for_uncondjump (i3);
4684 }
4685
4686 if (undobuf.other_insn != NULL_RTX(rtx) 0
4687 && JUMP_P (undobuf.other_insn)(((enum rtx_code) (undobuf.other_insn)->code) == JUMP_INSN
)
4688 && GET_CODE (PATTERN (undobuf.other_insn))((enum rtx_code) (PATTERN (undobuf.other_insn))->code) == SET
4689 && SET_SRC (PATTERN (undobuf.other_insn))(((PATTERN (undobuf.other_insn))->u.fld[1]).rt_rtx) == pc_rtx
4690 && SET_DEST (PATTERN (undobuf.other_insn))(((PATTERN (undobuf.other_insn))->u.fld[0]).rt_rtx) == pc_rtx)
4691 {
4692 *new_direct_jump_p = 1;
4693 update_cfg_for_uncondjump (undobuf.other_insn);
4694 }
4695
4696 combine_successes++;
4697 undo_commit ();
4698
4699 rtx_insn *ret = newi2pat ? i2 : i3;
4700 if (added_links_insn && DF_INSN_LUID (added_links_insn)((((df->insns[(INSN_UID (added_links_insn))]))->luid)) < DF_INSN_LUID (ret)((((df->insns[(INSN_UID (ret))]))->luid)))
4701 ret = added_links_insn;
4702 if (added_notes_insn && DF_INSN_LUID (added_notes_insn)((((df->insns[(INSN_UID (added_notes_insn))]))->luid)) < DF_INSN_LUID (ret)((((df->insns[(INSN_UID (ret))]))->luid)))
4703 ret = added_notes_insn;
4704
4705 return ret;
4706}
4707
4708/* Get a marker for undoing to the current state. */
4709
4710static void *
4711get_undo_marker (void)
4712{
4713 return undobuf.undos;
4714}
4715
4716/* Undo the modifications up to the marker. */
4717
4718static void
4719undo_to_marker (void *marker)
4720{
4721 struct undo *undo, *next;
4722
4723 for (undo = undobuf.undos; undo != marker; undo = next)
4724 {
4725 gcc_assert (undo)((void)(!(undo) ? fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/combine.c"
, 4725, __FUNCTION__), 0 : 0))
;
4726
4727 next = undo->next;
4728 switch (undo->kind)
4729 {
4730 case UNDO_RTX:
4731 *undo->where.r = undo->old_contents.r;
4732 break;
4733 case UNDO_INT:
4734 *undo->where.i = undo->old_contents.i;
4735 break;
4736 case UNDO_MODE:
4737 adjust_reg_mode (*undo->where.r, undo->old_contents.m);
4738 break;
4739 case UNDO_LINKS:
4740 *undo->where.l = undo->old_contents.l;
4741 break;
4742 default:
4743 gcc_unreachable ()(fancy_abort ("/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/combine.c"
, 4743, __FUNCTION__))
;
4744 }
4745
4746 undo->next = undobuf.frees;
4747 undobuf.frees = undo;
4748 }
4749
4750 undobuf.undos = (struct undo *) marker;
4751}
4752
4753/* Undo all the modifications recorded in undobuf. */
4754
4755static void
4756undo_all (void)
4757{
4758 undo_to_marker (0);
4759}
4760
4761/* We've committed to accepting the changes we made. Move all
4762 of the undos to the free list. */
4763
4764static void
4765undo_commit (void)
4766{
4767 struct undo *undo, *next;
4768
4769 for (undo = undobuf.undos; undo; undo = next)
4770 {
4771 next = undo->next;
4772 undo->next = undobuf.frees;
4773 undobuf.frees = undo;
4774 }
4775 undobuf.undos = 0;
4776}
4777
4778/* Find the innermost point within the rtx at LOC, possibly LOC itself,
4779 where we have an arithmetic expression and return that point. LOC will
4780 be inside INSN.
4781
4782 try_combine will call this function to see if an insn can be split into
4783 two insns. */
4784
4785static rtx *
4786find_split_point (rtx *loc, rtx_insn *insn, bool set_src)
4787{
4788 rtx x = *loc;
4789 enum rtx_code code = GET_CODE (x)((enum rtx_code) (x)->code);
4790 rtx *split;
4791 unsigned HOST_WIDE_INTlong len = 0;
4792 HOST_WIDE_INTlong pos = 0;
4793 int unsignedp = 0;
4794 rtx inner = NULL_RTX(rtx) 0;
4795 scalar_int_mode mode, inner_mode;
4796
4797 /* First special-case some codes. */
4798 switch (code)
4799 {
4800 case SUBREG:
4801#ifdef INSN_SCHEDULING
4802 /* If we are making a paradoxical SUBREG invalid, it becomes a split
4803 point. */
4804 if (MEM_P (SUBREG_REG (x))(((enum rtx_code) ((((x)->u.fld[0]).rt_rtx))->code) == MEM
)
)
4805 return loc;
4806#endif
4807 return find_split_point (&SUBREG_REG (x)(((x)->u.fld[0]).rt_rtx), insn, false);
4808
4809 case MEM:
4810 /* If we have (mem (const ..)) or (mem (symbol_ref ...)), split it
4811 using LO_SUM and HIGH. */
4812 if (HAVE_lo_sum0 && (GET_CODE (XEXP (x, 0))((enum rtx_code) ((((x)->u.fld[0]).rt_rtx))->code) == CONST
4813 || GET_CODE (XEXP (x, 0))((enum rtx_code) ((((x)->u.fld[0]).rt_rtx))->code) == SYMBOL_REF))
4814 {
4815 machine_mode address_mode = get_address_mode (x);
4816
4817 SUBST (XEXP (x, 0),do_SUBST (&((((x)->u.fld[0]).rt_rtx)), (gen_rtx_fmt_ee_stat
((LO_SUM), ((address_mode)), ((gen_rtx_fmt_e_stat ((HIGH), (
(address_mode)), (((((x)->u.fld[0]).rt_rtx))) ))), (((((x)
->u.fld[0]).rt_rtx))) )))
4818 gen_rtx_LO_SUM (address_mode,do_SUBST (&((((x)->u.fld[0]).rt_rtx)), (gen_rtx_fmt_ee_stat
((LO_SUM), ((address_mode)), ((gen_rtx_fmt_e_stat ((HIGH), (
(address_mode)), (((((x)->u.fld[0]).rt_rtx))) ))), (((((x)
->u.fld[0]).rt_rtx))) )))
4819 gen_rtx_HIGH (address_mode, XEXP (x, 0)),do_SUBST (&((((x)->u.fld[0]).rt_rtx)), (gen_rtx_fmt_ee_stat
((LO_SUM), ((address_mode)), ((gen_rtx_fmt_e_stat ((HIGH), (
(address_mode)), (((((x)->u.fld[0]).rt_rtx))) ))), (((((x)
->u.fld[0]).rt_rtx))) )))
4820 XEXP (x, 0)))do_SUBST (&((((x)->u.fld[0]).rt_rtx)), (gen_rtx_fmt_ee_stat
((LO_SUM), ((address_mode)), ((gen_rtx_fmt_e_stat ((HIGH), (
(address_mode)), (((((x)->u.fld[0]).rt_rtx))) ))), (((((x)
->u.fld[0]).rt_rtx))) )))
;
4821 return &XEXP (XEXP (x, 0), 0)((((((x)->u.fld[0]).rt_rtx))->u.fld[0]).rt_rtx);
4822 }
4823
4824 /* If we have a PLUS whose second operand is a constant and the
4825 address is not valid, perhaps we can split it up using
4826 the machine-specific way to split large constants. We use
4827 the first pseudo-reg (one of the virtual regs) as a placeholder;
4828 it will not remain in the result. */
4829 if (GET_CODE (XEXP (x, 0))((enum rtx_code) ((((x)->u.fld[0]).rt_rtx))->code) == PLUS
4830 && CONST_INT_P (XEXP (XEXP (x, 0), 1))(((enum rtx_code) (((((((x)->u.fld[0]).rt_rtx))->u.fld[
1]).rt_rtx))->code) == CONST_INT)
4831 && ! memory_address_addr_space_p (GET_MODE (x)((machine_mode) (x)->mode), XEXP (x, 0)(((x)->u.fld[0]).rt_rtx),
4832 MEM_ADDR_SPACE (x)(get_mem_attrs (x)->addrspace)))
4833 {
4834 rtx reg = regno_reg_rtx[FIRST_PSEUDO_REGISTER76];
4835 rtx_insn *seq = combine_split_insns (gen_rtx_SET (reg, XEXP (x, 0))gen_rtx_fmt_ee_stat ((SET), (((void) 0, E_VOIDmode)), ((reg))
, (((((x)->u.fld[0]).rt_rtx))) )
,
4836 subst_insn);
4837
4838 /* This should have produced two insns, each of which sets our
4839 placeholder. If the source of the second is a valid address,
4840 we can put both sources together and make a split point
4841 in the middle. */
4842
4843 if (seq
4844 && NEXT_INSN (seq) != NULL_RTX(rtx) 0
4845 && NEXT_INSN (NEXT_INSN (seq)) == NULL_RTX(rtx) 0
4846 && NONJUMP_INSN_P (seq)(((enum rtx_code) (seq)->code) == INSN)
4847 && GET_CODE (PATTERN (seq))((enum rtx_code) (PATTERN (seq))->code) == SET
4848 && SET_DEST (PATTERN (seq))(((PATTERN (seq))->u.fld[0]).rt_rtx) == reg
4849 && ! reg_mentioned_p (reg,
4850 SET_SRC (PATTERN (seq))(((PATTERN (seq))->u.fld[1]).rt_rtx))
4851 && NONJUMP_INSN_P (NEXT_INSN (seq))(((enum rtx_code) (NEXT_INSN (seq))->code) == INSN)
4852 && GET_CODE (PATTERN (NEXT_INSN (seq)))((enum rtx_code) (PATTERN (NEXT_INSN (seq)))->code) == SET
4853 && SET_DEST (PATTERN (NEXT_INSN (seq)))(((PATTERN (NEXT_INSN (seq)))->u.fld[0]).rt_rtx) == reg
4854 && memory_address_addr_space_p
4855 (GET_MODE (x)((machine_mode) (x)->mode), SET_SRC (PATTERN (NEXT_INSN (seq)))(((PATTERN (NEXT_INSN (seq)))->u.fld[1]).rt_rtx),
4856 MEM_ADDR_SPACE (x)(get_mem_attrs (x)->addrspace)))
4857 {
4858 rtx src1 = SET_SRC (PATTERN (seq))(((PATTERN (seq))->u.fld[1]).rt_rtx);
4859 rtx src2 = SET_SRC (PATTERN (NEXT_INSN (seq)))(((PATTERN (NEXT_INSN (seq)))->u.fld[1]).rt_rtx);
4860
4861 /* Replace the placeholder in SRC2 with SRC1. If we can
4862 find where in SRC2 it was placed, that can become our
4863 split point and we can replace this address with SRC2.
4864 Just try two obvious places. */
4865
4866 src2 = replace_rtx (src2, reg, src1);
4867 split = 0;
4868 if (XEXP (src2, 0)(((src2)->u.fld[0]).rt_rtx) == src1)
4869 split = &XEXP (src2, 0)(((src2)->u.fld[0]).rt_rtx);
4870 else if (GET_RTX_FORMAT (GET_CODE (XEXP (src2, 0)))(rtx_format[(int) (((enum rtx_code) ((((src2)->u.fld[0]).rt_rtx
))->code))])
[0] == 'e'
4871 && XEXP (XEXP (src2, 0), 0)((((((src2)->u.fld[0]).rt_rtx))->u.fld[0]).rt_rtx) == src1)
4872 split = &XEXP (XEXP (src2, 0), 0)((((((src2)->u.fld[0]).rt_rtx))->u.fld[0]).rt_rtx);
4873
4874 if (split)
4875 {
4876 SUBST (XEXP (x, 0), src2)do_SUBST (&((((x)->u.fld[0]).rt_rtx)), (src2));
4877 return split;
4878 }
4879 }
4880
4881 /* If that didn't work and we have a nested plus, like:
4882 ((REG1 * CONST1) + REG2) + CONST2 and (REG1 + REG2) + CONST2
4883 is valid address, try to split (REG1 * CONST1). */
4884 if (GET_CODE (XEXP (XEXP (x, 0), 0))((enum rtx_code) (((((((x)->u.fld[0]).rt_rtx))->u.fld[0
]).rt_rtx))->code)
== PLUS
4885 && !OBJECT_P (XEXP (XEXP (XEXP (x, 0), 0), 0))(((rtx_class[(int) (((enum rtx_code) ((((((((((x)->u.fld[0
]).rt_rtx))->u.fld[0]).rt_rtx))->u.fld[0]).rt_rtx))->
code))]) & (~1)) == (RTX_OBJ & (~1)))
4886 && OBJECT_P (XEXP (XEXP (XEXP (x, 0), 0), 1))(((rtx_class[(int) (((enum rtx_code) ((((((((((x)->u.fld[0
]).rt_rtx))->u.fld[0]).rt_rtx))->u.fld[1]).rt_rtx))->
code))]) & (~1)) == (RTX_OBJ & (~1)))
4887 && ! (GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 0))((enum rtx_code) ((((((((((x)->u.fld[0]).rt_rtx))->u.fld
[0]).rt_rtx))->u.fld[0]).rt_rtx))->code)
== SUBREG
4888 && OBJECT_P (SUBREG_REG (XEXP (XEXP (XEXP (x, 0),(((rtx_class[(int) (((enum rtx_code) (((((((((((((x)->u.fld
[0]).rt_rtx))->u.fld[0]).rt_rtx))->u.fld[0]).rt_rtx))->
u.fld[0]).rt_rtx))->code))]) & (~1)) == (RTX_OBJ &
(~1)))
4889 0), 0)))(((rtx_class[(int) (((enum rtx_code) (((((((((((((x)->u.fld
[0]).rt_rtx))->u.fld[0]).rt_rtx))->u.fld[0]).rt_rtx))->
u.fld[0]).rt_rtx))->code))]) & (~1)) == (RTX_OBJ &
(~1)))
))
4890 {
4891 rtx tem = XEXP (XEXP (XEXP (x, 0), 0), 0)(((((((((x)->u.fld[0]).rt_rtx))->u.fld[0]).rt_rtx))->
u.fld[0]).rt_rtx)
;
4892 XEXP (XEXP (XEXP (x, 0), 0), 0)(((((((((x)->u.fld[0]).rt_rtx))->u.fld[0]).rt_rtx))->
u.fld[0]).rt_rtx)
= reg;
4893 if (memory_address_addr_space_p (GET_MODE (x)((machine_mode) (x)->mode), XEXP (x, 0)(((x)->u.fld[0]).rt_rtx),
4894 MEM_ADDR_SPACE (x)(get_mem_attrs (x)->addrspace)))
4895 {
4896 XEXP (XEXP (XEXP (x, 0), 0), 0)(((((((((x)->u.fld[0]).rt_rtx))->u.fld[0]).rt_rtx))->
u.fld[0]).rt_rtx)
= tem;
4897 return &XEXP (XEXP (XEXP (x, 0), 0), 0)(((((((((x)->u.fld[0]).rt_rtx))->u.fld[0]).rt_rtx))->
u.fld[0]).rt_rtx)
;
4898 }
4899 XEXP (XEXP (XEXP (x, 0), 0), 0)(((((((((x)->u.fld[0]).rt_rtx))->u.fld[0]).rt_rtx))->
u.fld[0]).rt_rtx)
= tem;
4900 }
4901 else if (GET_CODE (XEXP (XEXP (x, 0), 0))((enum rtx_code) (((((((x)->u.fld[0]).rt_rtx))->u.fld[0
]).rt_rtx))->code)
== PLUS
4902 && OBJECT_P (XEXP (XEXP (XEXP (x, 0), 0), 0))(((rtx_class[(int) (((enum rtx_code) ((((((((((x)->u.fld[0
]).rt_rtx))->u.fld[0]).rt_rtx))->u.fld[0]).rt_rtx))->
code))]) & (~1)) == (RTX_OBJ & (~1)))
4903 && !OBJECT_P (XEXP (XEXP (XEXP (x, 0), 0), 1))(((rtx_class[(int) (((enum rtx_code) ((((((((((x)->u.fld[0
]).rt_rtx))->u.fld[0]).rt_rtx))->u.fld[1]).rt_rtx))->
code))]) & (~1)) == (RTX_OBJ & (~1)))
4904 && ! (GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1))((enum rtx_code) ((((((((((x)->u.fld[0]).rt_rtx))->u.fld
[0]).rt_rtx))->u.fld[1]).rt_rtx))->code)
== SUBREG
4905 && OBJECT_P (SUBREG_REG (XEXP (XEXP (XEXP (x, 0),(((rtx_class[(int) (((enum rtx_code) (((((((((((((x)->u.fld
[0]).rt_rtx))->u.fld[0]).rt_rtx))->u.fld[1]).rt_rtx))->
u.fld[0]).rt_rtx))->code))]) & (~1)) == (RTX_OBJ &
(~1)))
4906 0), 1)))(((rtx_class[(int) (((enum rtx_code) (((((((((((((x)->u.fld
[0]).rt_rtx))->u.fld[0]).rt_rtx))->u.fld[1]).rt_rtx))->
u.fld[0]).rt_rtx))->code))]) & (~1)) == (RTX_OBJ &
(~1)))
))
4907 {
4908 rtx tem = XEXP (XEXP (XEXP (x, 0), 0), 1)(((((((((x)->u.fld[0]).rt_rtx))->u.fld[0]).rt_rtx))->
u.fld[1]).rt_rtx)
;
4909 XEXP (XEXP (XEXP (x, 0), 0), 1)(((((((((x)->u.fld[0]).rt_rtx))->u.fld[0]).rt_rtx))->
u.fld[1]).rt_rtx)
= reg;
4910 if (memory_address_addr_space_p (GET_MODE (x)((machine_mode) (x)->mode), XEXP (x, 0)(((x)->u.fld[0]).rt_rtx),
4911 MEM_ADDR_SPACE (x)(get_mem_attrs (x)->addrspace)))
4912 {
4913 XEXP (XEXP (XEXP (x, 0), 0), 1)(((((((((x)->u.fld[0]).rt_rtx))->u.fld[0]).rt_rtx))->
u.fld[1]).rt_rtx)
= tem;
4914 return &XEXP (XEXP (XEXP (x, 0), 0), 1)(((((((((x)->u.fld[0]).rt_rtx))->u.fld[0]).rt_rtx))->
u.fld[1]).rt_rtx)
;
4915 }
4916 XEXP (XEXP (XEXP (x, 0), 0), 1)(((((((((x)->u.fld[0]).rt_rtx))->u.fld[0]).rt_rtx))->
u.fld[1]).rt_rtx)
= tem;
4917 }
4918
4919 /* If that didn't work, perhaps the first operand is complex and
4920 needs to be computed separately, so make a split point there.
4921 This will occur on machines that just support REG + CONST
4922 and have a constant moved through some previous computation. */
4923 if (!OBJECT_P (XEXP (XEXP (x, 0), 0))(((rtx_class[(int) (((enum rtx_code) (((((((x)->u.fld[0]).
rt_rtx))->u.fld[0]).rt_rtx))->code))]) & (~1)) == (
RTX_OBJ & (~1)))
4924 && ! (GET_CODE (XEXP (XEXP (x, 0), 0))((enum rtx_code) (((((((x)->u.fld[0]).rt_rtx))->u.fld[0
]).rt_rtx))->code)
== SUBREG
4925 && OBJECT_P (SUBREG_REG (XEXP (XEXP (x, 0), 0)))(((rtx_class[(int) (((enum rtx_code) ((((((((((x)->u.fld[0
]).rt_rtx))->u.fld[0]).rt_rtx))->u.fld[0]).rt_rtx))->
code))]) & (~1)) == (RTX_OBJ & (~1)))
))
4926 return &XEXP (XEXP (x, 0), 0)((((((x)->u.fld[0]).rt_rtx))->u.fld[0]).rt_rtx);
4927 }
4928
4929 /* If we have a PLUS whose first operand is complex, try computing it
4930 separately by making a split there. */
4931 if (GET_CODE (XEXP (x, 0))((enum rtx_code) ((((x)->u.fld[0]).rt_rtx))->code) == PLUS
4932 && ! memory_address_addr_space_p (GET_MODE (x)((machine_mode) (x)->mode), XEXP (x, 0)(((x)->u.fld[0]).rt_rtx),
4933 MEM_ADDR_SPACE (x)(get_mem_attrs (x)->addrspace))
4934 && ! OBJECT_P (XEXP (XEXP (x, 0), 0))(((rtx_class[(int) (((enum rtx_code) (((((((x)->u.fld[0]).
rt_rtx))->u.fld[0]).rt_rtx))->code))]) & (~1)) == (
RTX_OBJ & (~1)))
4935 && ! (GET_CODE (XEXP (XEXP (x, 0), 0))((enum rtx_code) (((((((x)->u.fld[0]).rt_rtx))->u.fld[0
]).rt_rtx))->code)
== SUBREG
4936 && OBJECT_P (SUBREG_REG (XEXP (XEXP (x, 0), 0)))(((rtx_class[(int) (((enum rtx_code) ((((((((((x)->u.fld[0
]).rt_rtx))->u.fld[0]).rt_rtx))->u.fld[0]).rt_rtx))->
code))]) & (~1)) == (RTX_OBJ & (~1)))
))
4937 return &XEXP (XEXP (x, 0), 0)((((((x)->u.fld[0]).rt_rtx))->u.fld[0]).rt_rtx);
4938 break;
4939
4940 case SET:
4941 /* See if we can split SET_SRC as it stands. */
4942 split = find_split_point (&SET_SRC (x)(((x)->u.fld[1]).rt_rtx), insn, true);
4943 if (split && split != &SET_SRC (x)(((x)->u.fld[1]).rt_rtx))
4944 return split;
4945
4946 /* See if we can split SET_DEST as it stands. */
4947 split = find_split_point (&SET_DEST (x)(((x)->u.fld[0]).rt_rtx), insn, false);
4948 if (split && split != &SET_DEST (x)(((x)->u.fld[0]).rt_rtx))
4949 return split;
4950
4951 /* See if this is a bitfield assignment with everything constant. If
4952 so, this is an IOR of an AND, so split it into that. */
4953 if (GET_CODE (SET_DEST (x))((enum rtx_code) ((((x)->u.fld[0]).rt_rtx))->code) == ZERO_EXTRACT
4954 && is_a <scalar_int_mode> (GET_MODE (XEXP (SET_DEST (x), 0))((machine_mode) (((((((x)->u.fld[0]).rt_rtx))->u.fld[0]
).rt_rtx))->mode)
,
4955 &inner_mode)
4956 && HWI_COMPUTABLE_MODE_P (inner_mode)
4957 && CONST_INT_P (XEXP (SET_DEST (x), 1))(((enum rtx_code) (((((((x)->u.fld[0]).rt_rtx))->u.fld[
1]).rt_rtx))->code) == CONST_INT)
4958 && CONST_INT_P (XEXP (SET_DEST (x), 2))(((enum rtx_code) (((((((x)->u.fld[0]).rt_rtx))->u.fld[
2]).rt_rtx))->code) == CONST_INT)
4959 && CONST_INT_P (SET_SRC (x))(((enum rtx_code) ((((x)->u.fld[1]).rt_rtx))->code) == CONST_INT
)
4960 && ((INTVAL (XEXP (SET_DEST (x), 1))((((((((x)->u.fld[0]).rt_rtx))->u.fld[1]).rt_rtx))->
u.hwint[0])
4961 + INTVAL (XEXP (SET_DEST (x), 2))((((((((x)->u.fld[0]).rt_rtx))->u.fld[2]).rt_rtx))->
u.hwint[0])
)
4962 <= GET_MODE_PRECISION (inner_mode))
4963 && ! side_effects_p (XEXP (SET_DEST (x), 0)((((((x)->u.fld[0]).rt_rtx))->u.fld[0]).rt_rtx)))
4964 {
4965 HOST_WIDE_INTlong pos = INTVAL (XEXP (SET_DEST (x), 2))((((((((x)->u.fld[0]).rt_rtx))->u.fld[2]).rt_rtx))->
u.hwint[0])
;
4966 unsigned HOST_WIDE_INTlong len = INTVAL (XEXP (SET_DEST (x), 1))((((((((x)->u.fld[0]).rt_rtx))->u.fld[1]).rt_rtx))->
u.hwint[0])
;
4967 rtx dest = XEXP (SET_DEST (x), 0)((((((x)->u.fld[0]).rt_rtx))->u.fld[0]).rt_rtx);
4968 unsigned HOST_WIDE_INTlong mask = (HOST_WIDE_INT_1U1UL << len) - 1;
4969 unsigned HOST_WIDE_INTlong src = INTVAL (SET_SRC (x))(((((x)->u.fld[1]).rt_rtx))->u.hwint[0]) & mask;
4970 rtx or_mask;
4971
4972 if (BITS_BIG_ENDIAN0)
4973 pos = GET_MODE_PRECISION (inner_mode) - len - pos;
4974
4975 or_mask = gen_int_mode (src << pos, inner_mode);
4976 if (src == mask)
4977 SUBST (SET_SRC (x),do_SUBST (&((((x)->u.fld[1]).rt_rtx)), (simplify_gen_binary
(IOR, inner_mode, dest, or_mask)))
4978 simplify_gen_binary (IOR, inner_mode, dest, or_mask))do_SUBST (&((((x)->u.fld[1]).rt_rtx)), (simplify_gen_binary
(IOR, inner_mode, dest, or_mask)))
;
4979 else
4980 {
4981 rtx negmask = gen_int_mode (~(mask << pos), inner_mode);
4982 SUBST (SET_SRC (x),do_SUBST (&((((x)->u.fld[1]).rt_rtx)), (simplify_gen_binary
(IOR, inner_mode, simplify_gen_binary (AND, inner_mode, dest
, negmask), or_mask)))
4983 simplify_gen_binary (IOR, inner_mode,do_SUBST (&((((x)->u.fld[1]).rt_rtx)), (simplify_gen_binary
(IOR, inner_mode, simplify_gen_binary (AND, inner_mode, dest
, negmask), or_mask)))
4984 simplify_gen_binary (AND, inner_mode,do_SUBST (&((((x)->u.fld[1]).rt_rtx)), (simplify_gen_binary
(IOR, inner_mode, simplify_gen_binary (AND, inner_mode, dest
, negmask), or_mask)))
4985 dest, negmask),do_SUBST (&((((x)->u.fld[1]).rt_rtx)), (simplify_gen_binary
(IOR, inner_mode, simplify_gen_binary (AND, inner_mode, dest
, negmask), or_mask)))
4986 or_mask))do_SUBST (&((((x)->u.fld[1]).rt_rtx)), (simplify_gen_binary
(IOR, inner_mode, simplify_gen_binary (AND, inner_mode, dest
, negmask), or_mask)))
;
4987 }
4988
4989 SUBST (SET_DEST (x), dest)do_SUBST (&((((x)->u.fld[0]).rt_rtx)), (dest));
4990
4991 split = find_split_point (&SET_SRC (x)(((x)->u.fld[1]).rt_rtx), insn, true);
4992 if (split && split != &SET_SRC (x)(((x)->u.fld[1]).rt_rtx))
4993 return split;
4994 }
4995
4996 /* Otherwise, see if this is an operation that we can split into two.
4997 If so, try to split that. */
4998 code = GET_CODE (SET_SRC (x))((enum rtx_code) ((((x)->u.fld[1]).rt_rtx))->code);
4999
5000 switch (code)
5001 {
5002 case AND:
5003 /* If we are AND'ing with a large constant that is only a single
5004 bit and the result is only being used in a context where we
5005 need to know if it is zero or nonzero, replace it with a bit
5006 extraction. This will avoid the large constant, which might
5007 have taken more than one insn to make. If the constant were
5008 not a valid argument to the AND but took only one insn to make,
5009 this is no worse, but if it took more than one insn, it will
5010 be better. */
5011
5012 if (CONST_INT_P (XEXP (SET_SRC (x), 1))(((enum rtx_code) (((((((x)->u.fld[1]).rt_rtx))->u.fld[
1]).rt_rtx))->code) == CONST_INT)
5013 && REG_P (XEXP (SET_SRC (x), 0))(((enum rtx_code) (((((((x)->u.fld[1]).rt_rtx))->u.fld[
0]).rt_rtx))->code) == REG)
5014 && (pos = exact_log2 (UINTVAL (XEXP (SET_SRC (x), 1))((unsigned long) ((((((((x)->u.fld[1]).rt_rtx))->u.fld[
1]).rt_rtx))->u.hwint[0]))
)) >= 7
5015 && REG_P (SET_DEST (x))(((enum rtx_code) ((((x)->u.fld[0]).rt_rtx))->code) == REG
)
5016 && (split = find_single_use (SET_DEST (x)(((x)->u.fld[0]).rt_rtx), insn, NULLnullptr)) != 0
5017 && (GET_CODE (*split)((enum rtx_code) (*split)->code) == EQ || GET_CODE (*split)((enum rtx_code) (*split)->code) == NE)
5018 && XEXP (*split, 0)(((*split)->u.fld[0]).rt_rtx) == SET_DEST (x)(((x)->u.fld[0]).rt_rtx)
5019 && XEXP (*split, 1)(((*split)->u.fld[1]).rt_rtx) == const0_rtx(const_int_rtx[64]))
5020 {
5021 rtx extraction = make_extraction (GET_MODE (SET_DEST (x))((machine_mode) ((((x)->u.fld[0]).rt_rtx))->mode),
5022 XEXP (SET_SRC (x), 0)((((((x)->u.fld[1]).rt_rtx))->u.fld[0]).rt_rtx),
5023 pos, NULL_RTX(rtx) 0, 1, 1, 0, 0);
5024 if (extraction != 0)
5025 {
5026 SUBST (SET_SRC (x), extraction)do_SUBST (&((((x)->u.fld[1]).rt_rtx)), (extraction));
5027 return find_split_point (loc, insn, false);
5028 }
5029 }
5030 break;
5031
5032 case NE:
5033 /* If STORE_FLAG_VALUE is -1, this is (NE X 0) and only one bit of X
5034 is known to be on, this can be converted into a NEG of a shift. */
5035 if (STORE_FLAG_VALUE1 == -1 && XEXP (SET_SRC (x), 1)((((((x)->u.fld[1]).rt_rtx))->u.fld[1]).rt_rtx) == const0_rtx(const_int_rtx[64])
5036 && GET_MODE (SET_SRC (x))((machine_mode) ((((x)->u.fld[1]).rt_rtx))->mode) == GET_MODE (XEXP (SET_SRC (x), 0))((machine_mode) (((((((x)->u.fld[1]).rt_rtx))->u.fld[0]
).rt_rtx))->mode)
5037 && ((pos = exact_log2 (nonzero_bits (XEXP (SET_SRC (x), 0)((((((x)->u.fld[1]).rt_rtx))->u.fld[0]).rt_rtx),
5038 GET_MODE (XEXP (SET_SRC (x),((machine_mode) (((((((x)->u.fld[1]).rt_rtx))->u.fld[0]
).rt_rtx))->mode)
5039 0))((machine_mode) (((((((x)->u.fld[1]).rt_rtx))->u.fld[0]
).rt_rtx))->mode)
))) >= 1))
5040 {
5041 machine_mode mode = GET_MODE (XEXP (SET_SRC (x), 0))((machine_mode) (((((((x)->u.fld[1]).rt_rtx))->u.fld[0]
).rt_rtx))->mode)
;
5042 rtx pos_rtx = gen_int_shift_amount (mode, pos);
5043 SUBST (SET_SRC (x),do_SUBST (&((((x)->u.fld[1]).rt_rtx)), (gen_rtx_fmt_e_stat
((NEG), ((mode)), ((gen_rtx_fmt_ee_stat ((LSHIFTRT), ((mode)
), ((((((((x)->u.fld[1]).rt_rtx))->u.fld[0]).rt_rtx))),
((pos_rtx)) ))) )))
5044 gen_rtx_NEG (mode,do_SUBST (&((((x)->u.fld[1]).rt_rtx)), (gen_rtx_fmt_e_stat
((NEG), ((mode)), ((gen_rtx_fmt_ee_stat ((LSHIFTRT), ((mode)
), ((((((((x)->u.fld[1]).rt_rtx))->u.fld[0]).rt_rtx))),
((pos_rtx)) ))) )))
5045 gen_rtx_LSHIFTRT (mode,do_SUBST (&((((x)->u.fld[1]).rt_rtx)), (gen_rtx_fmt_e_stat
((NEG), ((mode)), ((gen_rtx_fmt_ee_stat ((LSHIFTRT), ((mode)
), ((((((((x)->u.fld[1]).rt_rtx))->u.fld[0]).rt_rtx))),
((pos_rtx)) ))) )))
5046 XEXP (SET_SRC (x), 0),do_SUBST (&((((x)->u.fld[1]).rt_rtx)), (gen_rtx_fmt_e_stat
((NEG), ((mode)), ((gen_rtx_fmt_ee_stat ((LSHIFTRT), ((mode)
), ((((((((x)->u.fld[1]).rt_rtx))->u.fld[0]).rt_rtx))),
((pos_rtx)) ))) )))
5047 pos_rtx)))do_SUBST (&((((x)->u.fld[1]).rt_rtx)), (gen_rtx_fmt_e_stat
((NEG), ((mode)), ((gen_rtx_fmt_ee_stat ((LSHIFTRT), ((mode)
), ((((((((x)->u.fld[1]).rt_rtx))->u.fld[0]).rt_rtx))),
((pos_rtx)) ))) )))
;
5048
5049 split = find_split_point (&SET_SRC (x)(((x)->u.fld[1]).rt_rtx), insn, true);
5050 if (split && split != &SET_SRC (x)(((x)->u.fld[1]).rt_rtx))
5051 return split;
5052 }
5053 break;
5054
5055 case SIGN_EXTEND:
5056 inner = XEXP (SET_SRC (x), 0)((((((x)->u.fld[1]).rt_rtx))->u.fld[0]).rt_rtx);
5057
5058 /* We can't optimize if either mode is a partial integer
5059 mode as we don't know how many bits are significant
5060 in those modes. */
5061 if (!is_int_mode (GET_MODE (inner)((machine_mode) (inner)->mode), &inner_mode)
5062 || GET_MODE_CLASS (GET_MODE (SET_SRC (x)))((enum mode_class) mode_class[((machine_mode) ((((x)->u.fld
[1]).rt_rtx))->mode)])
== MODE_PARTIAL_INT)
5063 break;
5064
5065 pos = 0;
5066 len = GET_MODE_PRECISION (inner_mode);
5067 unsignedp = 0;
5068 break;
5069
5070 case SIGN_EXTRACT:
5071 case ZERO_EXTRACT:
5072 if (is_a <scalar_int_mode> (GET_MODE (XEXP (SET_SRC (x), 0))((machine_mode) (((((((x)->u.fld[1]).rt_rtx))->u.fld[0]
).rt_rtx))->mode)
,
5073 &inner_mode)
5074 && CONST_INT_P (XEXP (SET_SRC (x), 1))(((enum rtx_code) (((((((x)->u.fld[1]).rt_rtx))->u.fld[
1]).rt_rtx))->code) == CONST_INT)
5075 && CONST_INT_P (XEXP (SET_SRC (x), 2))(((enum rtx_code) (((((((x)->u.fld[1]).rt_rtx))->u.fld[
2]).rt_rtx))->code) == CONST_INT)
)
5076 {
5077 inner = XEXP (SET_SRC (x), 0)((((((x)->u.fld[1]).rt_rtx))->u.fld[0]).rt_rtx);
5078 len = INTVAL (XEXP (SET_SRC (x), 1))((((((((x)->u.fld[1]).rt_rtx))->u.fld[1]).rt_rtx))->
u.hwint[0])
;
5079 pos = INTVAL (XEXP (SET_SRC (x), 2))((((((((x)->u.fld[1]).rt_rtx))->u.fld[2]).rt_rtx))->
u.hwint[0])
;
5080
5081 if (BITS_BIG_ENDIAN0)
5082 pos = GET_MODE_PRECISION (inner_mode) - len - pos;
5083 unsignedp = (code == ZERO_EXTRACT);
5084 }
5085 break;
5086
5087 default:
5088 break;
5089 }
5090
5091 if (len
5092 && known_subrange_p (pos, len,
5093 0, GET_MODE_PRECISION (GET_MODE (inner)((machine_mode) (inner)->mode)))
5094 && is_a <scalar_int_mode> (GET_MODE (SET_SRC (x))((machine_mode) ((((x)->u.fld[1]).rt_rtx))->mode), &mode))
5095 {
5096 /* For unsigned, we have a choice of a shift followed by an
5097 AND or two shifts. Use two shifts for field sizes where the
5098 constant might be too large. We assume here that we can
5099 always at least get 8-bit constants in an AND insn, which is
5100 true for every current RISC. */
5101
5102 if (unsignedp && len <= 8)
5103 {
5104 unsigned HOST_WIDE_INTlong mask
5105 = (HOST_WIDE_INT_1U1UL << len) - 1;
5106 rtx pos_rtx = gen_int_shift_amount (mode, pos);
5107 SUBST (SET_SRC (x),do_SUBST (&((((x)->u.fld[1]).rt_rtx)), (gen_rtx_fmt_ee_stat
((AND), ((mode)), ((gen_rtx_fmt_ee_stat ((LSHIFTRT), ((mode)
), ((rtl_hooks.gen_lowpart (mode, inner))), ((pos_rtx)) ))), (
(gen_int_mode (mask, mode))) )))
5108 gen_rtx_AND (mode,do_SUBST (&((((x)->u.fld[1]).rt_rtx)), (gen_rtx_fmt_ee_stat
((AND), ((mode)), ((gen_rtx_fmt_ee_stat ((LSHIFTRT), ((mode)
), ((rtl_hooks.gen_lowpart (mode, inner))), ((pos_rtx)) ))), (
(gen_int_mode (mask, mode))) )))
5109 gen_rtx_LSHIFTRTdo_SUBST (&((((x)->u.fld[1]).rt_rtx)), (gen_rtx_fmt_ee_stat
((AND), ((mode)), ((gen_rtx_fmt_ee_stat ((LSHIFTRT), ((mode)
), ((rtl_hooks.gen_lowpart (mode, inner))), ((pos_rtx)) ))), (
(gen_int_mode (mask, mode))) )))
5110 (mode, gen_lowpart (mode, inner), pos_rtx),do_SUBST (&((((x)->u.fld[1]).rt_rtx)), (gen_rtx_fmt_ee_stat
((AND), ((mode)), ((gen_rtx_fmt_ee_stat ((LSHIFTRT), ((mode)
), ((rtl_hooks.gen_lowpart (mode, inner))), ((pos_rtx)) ))), (
(gen_int_mode (mask, mode))) )))
5111 gen_int_mode (mask, mode)))do_SUBST (&((((x)->u.fld[1]).rt_rtx)), (gen_rtx_fmt_ee_stat
((AND), ((mode)), ((gen_rtx_fmt_ee_stat ((LSHIFTRT), ((mode)
), ((rtl_hooks.gen_lowpart (mode, inner))), ((pos_rtx)) ))), (
(gen_int_mode (mask, mode))) )))
;
5112
5113 split = find_split_point (&SET_SRC (x)(((x)->u.fld[1]).rt_rtx), insn, true);
5114 if (split && split != &SET_SRC (x)(((x)->u.fld[1]).rt_rtx))
5115 return split;
5116 }
5117 else
5118 {
5119 int left_bits = GET_MODE_PRECISION (mode) - len - pos;
5120 int right_bits = GET_MODE_PRECISION (mode) - len;
5121 SUBST (SET_SRC (x),do_SUBST (&((((x)->u.fld[1]).rt_rtx)), (gen_rtx_fmt_ee_stat
((unsignedp ? LSHIFTRT : ASHIFTRT), (mode), (gen_rtx_fmt_ee_stat
((ASHIFT), ((mode)), ((rtl_hooks.gen_lowpart (mode, inner)))
, ((gen_int_shift_amount (mode, left_bits))) )), (gen_int_shift_amount
(mode, right_bits)) )))
5122 gen_rtx_fmt_eedo_SUBST (&((((x)->u.fld[1]).rt_rtx)), (gen_rtx_fmt_ee_stat
((unsignedp ? LSHIFTRT : ASHIFTRT), (mode), (gen_rtx_fmt_ee_stat
((ASHIFT), ((mode)), ((rtl_hooks.gen_lowpart (mode, inner)))
, ((gen_int_shift_amount (mode, left_bits))) )), (gen_int_shift_amount
(mode, right_bits)) )))
5123 (unsignedp ? LSHIFTRT : ASHIFTRT, mode,do_SUBST (&((((x)->u.fld[1]).rt_rtx)), (gen_rtx_fmt_ee_stat
((unsignedp ? LSHIFTRT : ASHIFTRT), (mode), (gen_rtx_fmt_ee_stat
((ASHIFT), ((mode)), ((rtl_hooks.gen_lowpart (mode, inner)))
, ((gen_int_shift_amount (mode, left_bits))) )), (gen_int_shift_amount
(mode, right_bits)) )))
5124 gen_rtx_ASHIFT (mode,do_SUBST (&((((x)->u.fld[1]).rt_rtx)), (gen_rtx_fmt_ee_stat
((unsignedp ? LSHIFTRT : ASHIFTRT), (mode), (gen_rtx_fmt_ee_stat
((ASHIFT), ((mode)), ((rtl_hooks.gen_lowpart (mode, inner)))
, ((gen_int_shift_amount (mode, left_bits))) )), (gen_int_shift_amount
(mode, right_bits)) )))
5125 gen_lowpart (mode, inner),do_SUBST (&((((x)->u.fld[1]).rt_rtx)), (gen_rtx_fmt_ee_stat
((unsignedp ? LSHIFTRT : ASHIFTRT), (mode), (gen_rtx_fmt_ee_stat
((ASHIFT), ((mode)), ((rtl_hooks.gen_lowpart (mode, inner)))
, ((gen_int_shift_amount (mode, left_bits))) )), (gen_int_shift_amount
(mode, right_bits)) )))
5126 gen_int_shift_amount (mode, left_bits)),do_SUBST (&((((x)->u.fld[1]).rt_rtx)), (gen_rtx_fmt_ee_stat
((unsignedp ? LSHIFTRT : ASHIFTRT), (mode), (gen_rtx_fmt_ee_stat
((ASHIFT), ((mode)), ((rtl_hooks.gen_lowpart (mode, inner)))
, ((gen_int_shift_amount (mode, left_bits))) )), (gen_int_shift_amount
(mode, right_bits)) )))
5127 gen_int_shift_amount (mode, right_bits)))do_SUBST (&((((x)->u.fld[1]).rt_rtx)), (gen_rtx_fmt_ee_stat
((unsignedp ? LSHIFTRT : ASHIFTRT), (mode), (gen_rtx_fmt_ee_stat
((ASHIFT), ((mode)), ((rtl_hooks.gen_lowpart (mode, inner)))
, ((gen_int_shift_amount (mode, left_bits))) )), (gen_int_shift_amount
(mode, right_bits)) )))
;
5128
5129 split = find_split_point (&SET_SRC (x)(((x)->u.fld[1]).rt_rtx), insn, true);
5130 if (split && split != &SET_SRC (x)(((x)->u.fld[1]).rt_rtx))
5131 return split;
5132 }
5133 }
5134
5135 /* See if this is a simple operation with a constant as the second
5136 operand. It might be that this constant is out of range and hence
5137 could be used as a split point. */
5138 if (BINARY_P (SET_SRC (x))(((rtx_class[(int) (((enum rtx_code) ((((x)->u.fld[1]).rt_rtx
))->code))]) & (~3)) == (RTX_COMPARE & (~3)))
5139 && CONSTANT_P (XEXP (SET_SRC (x), 1))((rtx_class[(int) (((enum rtx_code) (((((((x)->u.fld[1]).rt_rtx
))->u.fld[1]).rt_rtx))->code))]) == RTX_CONST_OBJ)
5140 && (OBJECT_P (XEXP (SET_SRC (x), 0))(((rtx_class[(int) (((enum rtx_code) (((((((x)->u.fld[1]).
rt_rtx))->u.fld[0]).rt_rtx))->code))]) & (~1)) == (
RTX_OBJ & (~1)))
5141 || (GET_CODE (XEXP (SET_SRC (x), 0))((enum rtx_code) (((((((x)->u.fld[1]).rt_rtx))->u.fld[0
]).rt_rtx))->code)
== SUBREG
5142 && OBJECT_P (SUBREG_REG (XEXP (SET_SRC (x), 0)))(((rtx_class[(int) (((enum rtx_code) ((((((((((x)->u.fld[1
]).rt_rtx))->u.fld[0]).rt_rtx))->u.fld[0]).rt_rtx))->
code))]) & (~1)) == (RTX_OBJ & (~1)))
)))
5143 return &XEXP (SET_SRC (x), 1)((((((x)->u.fld[1]).rt_rtx))->u.fld[1]).rt_rtx);
5144
5145 /* Finally, see if this is a simple operation with its first operand
5146 not in a register. The operation might require this operand in a
5147 register, so return it as a split point. We can always do this
5148 because if the first operand were another operation, we would have
5149 already found it as a split point. */
5150 if ((BINARY_P (SET_SRC (x))(((rtx_class[(int) (((enum rtx_code) ((((x)->u.fld[1]).rt_rtx
))->code))]) & (~3)) == (RTX_COMPARE & (~3)))
|| UNARY_P (SET_SRC (x))((rtx_class[(int) (((enum rtx_code) ((((x)->u.fld[1]).rt_rtx
))->code))]) == RTX_UNARY)
)
5151 && ! register_operand (XEXP (SET_SRC (x), 0)((((((x)->u.fld[1]).rt_rtx))->u.fld[0]).rt_rtx), VOIDmode((void) 0, E_VOIDmode)))
5152 return &XEXP (SET_SRC (x), 0)((((((x)->u.fld[1]).rt_rtx))->u.fld[0]).rt_rtx);
5153
5154 return 0;
5155
5156 case AND:
5157 case IOR:
5158 /* We write NOR as (and (not A) (not B)), but if we don't have a NOR,
5159 it is better to write this as (not (ior A B)) so we can split it.
5160 Similarly for IOR. */
5161 if (GET_CODE (XEXP (x, 0))((enum rtx_code) ((((x)->u.fld[0]).rt_rtx))->code) == NOT && GET_CODE (XEXP (x, 1))((enum rtx_code) ((((x)->u.fld[1]).rt_rtx))->code) == NOT)
5162 {
5163 SUBST (*loc,do_SUBST (&(*loc), (gen_rtx_fmt_e_stat ((NOT), ((((machine_mode
) (x)->mode))), ((gen_rtx_fmt_ee_stat ((code == IOR ? AND :
IOR), (((machine_mode) (x)->mode)), (((((((x)->u.fld[0
]).rt_rtx))->u.fld[0]).rt_rtx)), (((((((x)->u.fld[1]).rt_rtx
))->u.fld[0]).rt_rtx)) ))) )))
5164 gen_rtx_NOT (GET_MODE (x),do_SUBST (&(*loc), (gen_rtx_fmt_e_stat ((NOT), ((((machine_mode
) (x)->mode))), ((gen_rtx_fmt_ee_stat ((code == IOR ? AND :
IOR), (((machine_mode) (x)->mode)), (((((((x)->u.fld[0
]).rt_rtx))->u.fld[0]).rt_rtx)), (((((((x)->u.fld[1]).rt_rtx
))->u.fld[0]).rt_rtx)) ))) )))
5165 gen_rtx_fmt_ee (code == IOR ? AND : IOR,do_SUBST (&(*loc), (gen_rtx_fmt_e_stat ((NOT), ((((machine_mode
) (x)->mode))), ((gen_rtx_fmt_ee_stat ((code == IOR ? AND :
IOR), (((machine_mode) (x)->mode)), (((((((x)->u.fld[0
]).rt_rtx))->u.fld[0]).rt_rtx)), (((((((x)->u.fld[1]).rt_rtx
))->u.fld[0]).rt_rtx)) ))) )))
5166 GET_MODE (x),do_SUBST (&(*loc), (gen_rtx_fmt_e_stat ((NOT), ((((machine_mode
) (x)->mode))), ((gen_rtx_fmt_ee_stat ((code == IOR ? AND :
IOR), (((machine_mode) (x)->mode)), (((((((x)->u.fld[0
]).rt_rtx))->u.fld[0]).rt_rtx)), (((((((x)->u.fld[1]).rt_rtx
))->u.fld[0]).rt_rtx)) ))) )))
5167 XEXP (XEXP (x, 0), 0),do_SUBST (&(*loc), (gen_rtx_fmt_e_stat ((NOT), ((((machine_mode
) (x)->mode))), ((gen_rtx_fmt_ee_stat ((code == IOR ? AND :
IOR), (((machine_mode) (x)->mode)), (((((((x)->u.fld[0
]).rt_rtx))->u.fld[0]).rt_rtx)), (((((((x)->u.fld[1]).rt_rtx
))->u.fld[0]).rt_rtx)) ))) )))
5168 XEXP (XEXP (x, 1), 0))))do_SUBST (&(*loc), (gen_rtx_fmt_e_stat ((NOT), ((((machine_mode
) (x)->mode))), ((gen_rtx_fmt_ee_stat ((code == IOR ? AND :
IOR), (((machine_mode) (x)->mode)), (((((((x)->u.fld[0
]).rt_rtx))->u.fld[0]).rt_rtx)), (((((((x)->u.fld[1]).rt_rtx
))->u.fld[0]).rt_rtx)) ))) )))
;
5169 return find_split_point (loc, insn, set_src);
5170 }
5171
5172 /* Many RISC machines have a large set of logical insns. If the
5173 second operand is a NOT, put it first so we will try to split the
5174 other operand first. */
5175 if (GET_CODE (XEXP (x, 1))((enum rtx_code) ((((x)->u.fld[1]).rt_rtx))->code) == NOT)
5176 {
5177 rtx tem = XEXP (x, 0)(((x)->u.fld[0]).rt_rtx);
5178 SUBST (XEXP (x, 0), XEXP (x, 1))do_SUBST (&((((x)->u.fld[0]).rt_rtx)), ((((x)->u.fld
[1]).rt_rtx)))
;
5179 SUBST (XEXP (x, 1), tem)do_SUBST (&((((x)->u.fld[1]).rt_rtx)), (tem));
5180 }
5181 break;
5182
5183 case PLUS:
5184 case MINUS:
5185 /* Canonicalization can produce (minus A (mult B C)), where C is a
5186 constant. It may be better to try splitting (plus (mult B -C) A)
5187 instead if this isn't a multiply by a power of two. */
5188 if (set_src && code == MINUS && GET_CODE (XEXP (x, 1))((enum rtx_code) ((((x)->u.fld[1]).rt_rtx))->code) == MULT
5189 && GET_CODE (XEXP (XEXP (x, 1), 1))((enum rtx_code) (((((((x)->u.fld[1]).rt_rtx))->u.fld[1
]).rt_rtx))->code)
== CONST_INT
5190 && !pow2p_hwi (INTVAL (XEXP (XEXP (x, 1), 1))((((((((x)->u.fld[1]).rt_rtx))->u.fld[1]).rt_rtx))->
u.hwint[0])
))
5191 {
5192 machine_mode mode = GET_MODE (x)((machine_mode) (x)->mode);
5193 unsigned HOST_WIDE_INTlong this_int = INTVAL (XEXP (XEXP (x, 1), 1))((((((((x)->u.fld[1]).rt_rtx))->u.fld[1]).rt_rtx))->
u.hwint[0])
;
5194 HOST_WIDE_INTlong other_int = trunc_int_for_mode (-this_int, mode);
5195 SUBST (*loc, gen_rtx_PLUS (mode,do_SUBST (&(*loc), (gen_rtx_fmt_ee_stat ((PLUS), ((mode))
, ((gen_rtx_fmt_ee_stat ((MULT), ((mode)), ((((((((x)->u.fld
[1]).rt_rtx))->u.fld[0]).rt_rtx))), ((gen_int_mode (other_int
, mode))) ))), (((((x)->u.fld[0]).rt_rtx))) )))
5196 gen_rtx_MULT (mode,do_SUBST (&(*loc), (gen_rtx_fmt_ee_stat ((PLUS), ((mode))
, ((gen_rtx_fmt_ee_stat ((MULT), ((mode)), ((((((((x)->u.fld
[1]).rt_rtx))->u.fld[0]).rt_rtx))), ((gen_int_mode (other_int
, mode))) ))), (((((x)->u.fld[0]).rt_rtx))) )))
5197 XEXP (XEXP (x, 1), 0),do_SUBST (&(*loc), (gen_rtx_fmt_ee_stat ((PLUS), ((mode))
, ((gen_rtx_fmt_ee_stat ((MULT), ((mode)), ((((((((x)->u.fld
[1]).rt_rtx))->u.fld[0]).rt_rtx))), ((gen_int_mode (other_int
, mode))) ))), (((((x)->u.fld[0]).rt_rtx))) )))
5198 gen_int_mode (other_int,do_SUBST (&(*loc), (gen_rtx_fmt_ee_stat ((PLUS), ((mode))
, ((gen_rtx_fmt_ee_stat ((MULT), ((mode)), ((((((((x)->u.fld
[1]).rt_rtx))->u.fld[0]).rt_rtx))), ((gen_int_mode (other_int
, mode))) ))), (((((x)->u.fld[0]).rt_rtx))) )))
5199 mode)),do_SUBST (&(*loc), (gen_rtx_fmt_ee_stat ((PLUS), ((mode))
, ((gen_rtx_fmt_ee_stat ((MULT), ((mode)), ((((((((x)->u.fld
[1]).rt_rtx))->u.fld[0]).rt_rtx))), ((gen_int_mode (other_int
, mode))) ))), (((((x)->u.fld[0]).rt_rtx))) )))
5200 XEXP (x, 0)))do_SUBST (&(*loc), (gen_rtx_fmt_ee_stat ((PLUS), ((mode))
, ((gen_rtx_fmt_ee_stat ((MULT), ((mode)), ((((((((x)->u.fld
[1]).rt_rtx))->u.fld[0]).rt_rtx))), ((gen_int_mode (other_int
, mode))) ))), (((((x)->u.fld[0]).rt_rtx))) )))
;
5201 return find_split_point (loc, insn, set_src);
5202 }
5203
5204 /* Split at a multiply-accumulate instruction. However if this is
5205 the SET_SRC, we likely do not have such an instruction and it's
5206 worthless to try this split. */
5207 if (!set_src
5208 && (GET_CODE (XEXP (x, 0))((enum rtx_code) ((((x)->u.fld[0]).rt_rtx))->code) == MULT
5209 || (GET_CODE (XEXP (x, 0))((enum rtx_code) ((((x)->u.fld[0]).rt_rtx))->code) == ASHIFT
5210 && GET_CODE (XEXP (XEXP (x, 0), 1))((enum rtx_code) (((((((x)->u.fld[0]).rt_rtx))->u.fld[1
]).rt_rtx))->code)
== CONST_INT)))
5211 return loc;
5212
5213 default:
5214 break;
5215 }
5216
5217 /* Otherwise, select our actions depending on our rtx class. */
5218 switch (GET_RTX_CLASS (code)(rtx_class[(int) (code)]))
5219 {
5220 case RTX_BITFIELD_OPS: /* This is ZERO_EXTRACT and SIGN_EXTRACT. */
5221 case RTX_TERNARY:
5222 split = find_split_point (&XEXP (x, 2)(((x)->u.fld[2]).rt_rtx), insn, false);
5223 if (split)
5224 return split;
5225 /* fall through */
5226 case RTX_BIN_ARITH:
5227 case RTX_COMM_ARITH:
5228 case RTX_COMPARE:
5229 case RTX_COMM_COMPARE:
5230 split = find_split_point (&XEXP (x, 1)(((x)->u.fld[1]).rt_rtx), insn, false);
5231 if (split)
5232 return split;
5233 /* fall through */
5234 case RTX_UNARY:
5235 /* Some machines have (and (shift ...) ...) insns. If X is not
5236 an AND, but XEXP (X, 0) is, use it as our split point. */
5237 if (GET_CODE (x)((enum rtx_code) (x)->code) != AND && GET_CODE (XEXP (x, 0))((enum rtx_code) ((((x)->u.fld[0]).rt_rtx))->code) == AND)
5238 return &XEXP (x, 0)(((x)->u.fld[0]).rt_rtx);
5239
5240 split = find_split_point (&XEXP (x, 0)(((x)->u.fld[0]).rt_rtx), insn, false);
5241 if (split)
5242 return split;
5243 return loc;
5244
5245 default:
5246 /* Otherwise, we don't have a split point. */
5247 return 0;
5248 }
5249}
5250
5251/* Throughout X, replace FROM with TO, and return the result.
5252 The result is TO if X is FROM;
5253 otherwise the result is X, but its contents may have been modified.
5254 If they were modified, a record was made in undobuf so that
5255 undo_all will (among other things) return X to its original state.
5256
5257 If the number of changes necessary is too much to record to undo,
5258 the excess changes are not made, so the result is invalid.
5259 The changes already made can still be undone.
5260 undobuf.num_undo is incremented for such changes, so by testing that
5261 the caller can tell whether the result is valid.
5262
5263 `n_occurrences' is incremented each time FROM is replaced.
5264
5265 IN_DEST is nonzero if we are processing the SET_DEST of a SET.
5266
5267 IN_COND is nonzero if we are at the top level of a condition.
5268
5269 UNIQUE_COPY is nonzero if each substitution must be unique. We do this
5270 by copying if `n_occurrences' is nonzero. */
5271
5272static rtx
5273subst (rtx x, rtx from, rtx to, int in_dest, int in_cond, int unique_copy)
5274{
5275 enum rtx_code code = GET_CODE (x)((enum rtx_code) (x)->code);
5276 machine_mode op0_mode = VOIDmode((void) 0, E_VOIDmode);
5277 const char *fmt;
5278 int len, i;
5279 rtx new_rtx;
5280
5281/* Two expressions are equal if they are identical copies of a shared
5282 RTX or if they are both registers with the same register number
5283 and mode. */
5284
5285#define COMBINE_RTX_EQUAL_P(X,Y)((X) == (Y) || ((((enum rtx_code) (X)->code) == REG) &&
(((enum rtx_code) (Y)->code) == REG) && (rhs_regno
(X)) == (rhs_regno(Y)) && ((machine_mode) (X)->mode
) == ((machine_mode) (Y)->mode)))
\
5286 ((X) == (Y) \
5287 || (REG_P (X)(((enum rtx_code) (X)->code) == REG) && REG_P (Y)(((enum rtx_code) (Y)->code) == REG) \
5288 && REGNO (X)(rhs_regno(X)) == REGNO (Y)(rhs_regno(Y)) && GET_MODE (X)((machine_mode) (X)->mode) == GET_MODE (Y)((machine_mode) (Y)->mode)))
5289
5290 /* Do not substitute into clobbers of regs -- this will never result in
5291 valid RTL. */
5292 if (GET_CODE (x)((enum rtx_code) (x)->code) == CLOBBER && REG_P (XEXP (x, 0))(((enum rtx_code) ((((x)->u.fld[0]).rt_rtx))->code) == REG
)
)
5293 return x;
5294
5295 if (! in_dest && COMBINE_RTX_EQUAL_P (x, from)((x) == (from) || ((((enum rtx_code) (x)->code) == REG) &&
(((enum rtx_code) (from)->code) == REG) && (rhs_regno
(x)) == (rhs_regno(from)) && ((machine_mode) (x)->
mode) == ((machine_mode) (from)->mode)))
)
5296 {
5297 n_occurrences++;
5298 return (unique_copy && n_occurrences > 1 ? copy_rtx (to) : to);
5299 }
5300
5301 /* If X and FROM are the same register but different modes, they
5302 will not have been seen as equal above. However, the log links code
5303 will make a LOG_LINKS entry for that case. If we do nothing, we
5304 will try to rerecognize our original insn and, when it succeeds,
5305 we will delete the feeding insn, which is incorrect.
5306
5307 So force this insn not to match in this (rare) case. */
5308 if (! in_dest && code == REG && REG_P (from)(((enum rtx_code) (from)->code) == REG)
5309 && reg_overlap_mentioned_p (x, from))
5310 return gen_rtx_CLOBBER (GET_MODE (x), const0_rtx)gen_rtx_fmt_e_stat ((CLOBBER), ((((machine_mode) (x)->mode
))), (((const_int_rtx[64]))) )
;
5311
5312 /* If this is an object, we are done unless it is a MEM or LO_SUM, both
5313 of which may contain things that can be combined. */
5314 if (code != MEM && code != LO_SUM && OBJECT_P (x)(((rtx_class[(int) (((enum rtx_code) (x)->code))]) & (
~1)) == (RTX_OBJ & (~1)))
)
5315 return x;
5316
5317 /* It is possible to have a subexpression appear twice in the insn.
5318 Suppose that FROM is a register that appears within TO.
5319 Then, after that subexpression has been scanned once by `subst',
5320 the second time it is scanned, TO may be found. If we were
5321 to scan TO here, we would find FROM within it and create a
5322 self-referent rtl structure which is completely wrong. */
5323 if (COMBINE_RTX_EQUAL_P (x, to)((x) == (to) || ((((enum rtx_code) (x)->code) == REG) &&
(((enum rtx_code) (to)->code) == REG) && (rhs_regno
(x)) == (rhs_regno(to)) && ((machine_mode) (x)->mode
) == ((machine_mode) (to)->mode)))
)
5324 return to;
5325
5326 /* Parallel asm_operands need special attention because all of the
5327 inputs are shared across the arms. Furthermore, unsharing the
5328 rtl results in recognition failures. Failure to handle this case
5329 specially can result in circular rtl.
5330
5331 Solve this by doing a normal pass across the first entry of the
5332 parallel, and only processing the SET_DESTs of the subsequent
5333 entries. Ug. */
5334
5335 if (code == PARALLEL
5336 && GET_CODE (XVECEXP (x, 0, 0))((enum rtx_code) ((((((x)->u.fld[0]).rt_rtvec))->elem[0
]))->code)
== SET
5337 && GET_CODE (SET_SRC (XVECEXP (x, 0, 0)))((enum rtx_code) (((((((((x)->u.fld[0]).rt_rtvec))->elem
[0]))->u.fld[1]).rt_rtx))->code)
== ASM_OPERANDS)
5338 {
5339 new_rtx = subst (XVECEXP (x, 0, 0)(((((x)->u.fld[0]).rt_rtvec))->elem[0]), from, to, 0, 0, unique_copy);
5340
5341 /* If this substitution failed, this whole thing fails. */
5342 if (GET_CODE (new_rtx)((enum rtx_code) (new_rtx)->code) == CLOBBER
5343 && XEXP (new_rtx, 0)(((new_rtx)->u.fld[0]).rt_rtx) == const0_rtx(const_int_rtx[64]))
5344 return new_rtx;
5345
5346 SUBST (XVECEXP (x, 0, 0), new_rtx)do_SUBST (&((((((x)->u.fld[0]).rt_rtvec))->elem[0])
), (new_rtx))
;
5347
5348 for (i = XVECLEN (x, 0)(((((x)->u.fld[0]).rt_rtvec))->num_elem) - 1; i >= 1; i--)
5349 {
5350 rtx dest = SET_DEST (XVECEXP (x, 0, i))((((((((x)->u.fld[0]).rt_rtvec))->elem[i]))->u.fld[0
]).rt_rtx)
;
5351
5352 if (!REG_P (dest)(((enum rtx_code) (dest)->code) == REG) && GET_CODE (dest)((enum rtx_code) (dest)->code) != PC)
5353 {
5354 new_rtx = subst (dest, from, to, 0, 0, unique_copy);
5355
5356 /* If this substitution failed, this whole thing fails. */
5357 if (GET_CODE (new_rtx)((enum rtx_code) (new_rtx)->code) == CLOBBER
5358 && XEXP (new_rtx, 0)(((new_rtx)->u.fld[0]).rt_rtx) == const0_rtx(const_int_rtx[64]))
5359 return new_rtx;
5360
5361 SUBST (SET_DEST (XVECEXP (x, 0, i)), new_rtx)do_SUBST (&(((((((((x)->u.fld[0]).rt_rtvec))->elem[
i]))->u.fld[0]).rt_rtx)), (new_rtx))
;
5362 }
5363 }
5364 }
5365 else
5366 {
5367 len = GET_RTX_LENGTH (code)(rtx_length[(int) (code)]);
5368 fmt = GET_RTX_FORMAT (code)(rtx_format[(int) (code)]);
5369
5370 /* We don't need to process a SET_DEST that is a register or PC, so
5371 set up to skip this common case. All other cases where we want
5372 to suppress replacing something inside a SET_SRC are handled via
5373 the IN_DEST operand. */
5374 if (code == SET
5375 && (REG_P (SET_DEST (x))(((enum rtx_code) ((((x)->u.fld[0]).rt_rtx))->code) == REG
)
5376 || GET_CODE (SET_DEST (x))((enum rtx_code) ((((x)->u.fld[0]).rt_rtx))->code) == PC))
5377 fmt = "ie";
5378
5379 /* Trying to simplify the operands of a widening MULT is not likely
5380 to create RTL matching a machine insn. */
5381 if (code == MULT
5382 && (GET_CODE (XEXP (x, 0))((enum rtx_code) ((((x)->u.fld[0]).rt_rtx))->code) == ZERO_EXTEND
5383 || GET_CODE (XEXP (x, 0))((enum rtx_code) ((((x)->u.fld[0]).rt_rtx))->code) == SIGN_EXTEND)
5384 && (GET_CODE (XEXP (x, 1))((enum rtx_code) ((((x)->u.fld[1]).rt_rtx))->code) == ZERO_EXTEND
5385 || GET_CODE (XEXP (x, 1))((enum rtx_code) ((((x)->u.fld[1]).rt_rtx))->code) == SIGN_EXTEND)
5386 && REG_P (XEXP (XEXP (x, 0), 0))(((enum rtx_code) (((((((x)->u.fld[0]).rt_rtx))->u.fld[
0]).rt_rtx))->code) == REG)
5387 && REG_P (XEXP (XEXP (x, 1), 0))(((enum rtx_code) (((((((x)->u.fld[1]).rt_rtx))->u.fld[
0]).rt_rtx))->code) == REG)
5388 && from == to)
5389 return x;
5390
5391
5392 /* Get the mode of operand 0 in case X is now a SIGN_EXTEND of a
5393 constant. */
5394 if (fmt[0] == 'e')
5395 op0_mode = GET_MODE (XEXP (x, 0))((machine_mode) ((((x)->u.fld[0]).rt_rtx))->mode);
5396
5397 for (i = 0; i < len; i++)
5398 {
5399 if (fmt[i] == 'E')
5400 {
5401 int j;
5402 for (j = XVECLEN (x, i)(((((x)->u.fld[i]).rt_rtvec))->num_elem) - 1; j >= 0; j--)
5403 {
5404 if (COMBINE_RTX_EQUAL_P (XVECEXP (x, i, j), from)(((((((x)->u.fld[i]).rt_rtvec))->elem[j])) == (from) ||
((((enum rtx_code) ((((((x)->u.fld[i]).rt_rtvec))->elem
[j]))->code) == REG) && (((enum rtx_code) (from)->
code) == REG) && (rhs_regno((((((x)->u.fld[i]).rt_rtvec
))->elem[j]))) == (rhs_regno(from)) && ((machine_mode
) ((((((x)->u.fld[i]).rt_rtvec))->elem[j]))->mode) ==
((machine_mode) (from)->mode)))
)
5405 {
5406 new_rtx = (unique_copy && n_occurrences
5407 ? copy_rtx (to) : to);
5408 n_occurrences++;
5409 }
5410 else
5411 {
5412 new_rtx = subst (XVECEXP (x, i, j)(((((x)->u.fld[i]).rt_rtvec))->elem[j]), from, to, 0, 0,
5413 unique_copy);
5414
5415 /* If this substitution failed, this whole thing
5416 fails. */
5417 if (GET_CODE (new_rtx)((enum rtx_code) (new_rtx)->code) == CLOBBER
5418 && XEXP (new_rtx, 0)(((new_rtx)->u.fld[0]).rt_rtx) == const0_rtx(const_int_rtx[64]))
5419 return new_rtx;
5420 }
5421
5422 SUBST (XVECEXP (x, i, j), new_rtx)do_SUBST (&((((((x)->u.fld[i]).rt_rtvec))->elem[j])
), (new_rtx))
;
5423 }
5424 }
5425 else if (fmt[i] == 'e')
5426 {
5427 /* If this is a register being set, ignore it. */
5428 new_rtx = XEXP (x, i)(((x)->u.fld[i]).rt_rtx);
5429 if (in_dest
5430 && i == 0
5431 && (((code == SUBREG || code == ZERO_EXTRACT)
5432 && REG_P (new_rtx)(((enum rtx_code) (new_rtx)->code) == REG))
5433 || code == STRICT_LOW_PART))
5434 ;
5435
5436 else if (COMBINE_RTX_EQUAL_P (XEXP (x, i), from)(((((x)->u.fld[i]).rt_rtx)) == (from) || ((((enum rtx_code
) ((((x)->u.fld[i]).rt_rtx))->code) == REG) && (
((enum rtx_code) (from)->code) == REG) && (rhs_regno
((((x)->u.fld[i]).rt_rtx))) == (rhs_regno(from)) &&
((machine_mode) ((((x)->u.fld[i]).rt_rtx))->mode) == (
(machine_mode) (from)->mode)))
)
5437 {
5438 /* In general, don't install a subreg involving two
5439 modes not tieable. It can worsen register
5440 allocation, and can even make invalid reload
5441 insns, since the reg inside may need to be copied
5442 from in the outside mode, and that may be invalid
5443 if it is an fp reg copied in integer mode.
5444
5445 We allow an exception to this: It is valid if
5446 it is inside another SUBREG and the mode of that
5447 SUBREG and the mode of the inside of TO is
5448 tieable. */
5449
5450 if (GET_CODE (to)((enum rtx_code) (to)->code) == SUBREG
5451 && !targetm.modes_tieable_p (GET_MODE (to)((machine_mode) (to)->mode),
5452 GET_MODE (SUBREG_REG (to))((machine_mode) ((((to)->u.fld[0]).rt_rtx))->mode))
5453 && ! (code == SUBREG
5454 && (targetm.modes_tieable_p
5455 (GET_MODE (x)((machine_mode) (x)->mode), GET_MODE (SUBREG_REG (to))((machine_mode) ((((to)->u.fld[0]).rt_rtx))->mode)))))
5456 return gen_rtx_CLOBBER (VOIDmode, const0_rtx)gen_rtx_fmt_e_stat ((CLOBBER), ((((void) 0, E_VOIDmode))), ((
(const_int_rtx[64]))) )
;
5457
5458 if (code == SUBREG
5459 && REG_P (to)(((enum rtx_code) (to)->code) == REG)
5460 && REGNO (to)(rhs_regno(to)) < FIRST_PSEUDO_REGISTER76
5461 && simplify_subreg_regno (REGNO (to)(rhs_regno(to)), GET_MODE (to)((machine_mode) (to)->mode),
5462 SUBREG_BYTE (x)(((x)->u.fld[1]).rt_subreg),
5463 GET_MODE (x)((machine_mode) (x)->mode)) < 0)
5464 return gen_rtx_CLOBBER (VOIDmode, const0_rtx)gen_rtx_fmt_e_stat ((CLOBBER), ((((void) 0, E_VOIDmode))), ((
(const_int_rtx[64]))) )
;
5465
5466 new_rtx = (unique_copy && n_occurrences ? copy_rtx (to) : to);
5467 n_occurrences++;
5468 }
5469 else
5470 /* If we are in a SET_DEST, suppress most cases unless we
5471 have gone inside a MEM, in which case we want to
5472 simplify the address. We assume here that things that
5473 are actually part of the destination have their inner
5474 parts in the first expression. This is true for SUBREG,
5475 STRICT_LOW_PART, and ZERO_EXTRACT, which are the only
5476 things aside from REG and MEM that should appear in a
5477 SET_DEST. */
5478 new_rtx = subst (XEXP (x, i)(((x)->u.fld[i]).rt_rtx), from, to,
5479 (((in_dest
5480 && (code == SUBREG || code == STRICT_LOW_PART
5481 || code == ZERO_EXTRACT))
5482 || code == SET)
5483 && i == 0),
5484 code == IF_THEN_ELSE && i == 0,
5485 unique_copy);
5486
5487 /* If we found that we will have to reject this combination,
5488 indicate that by returning the CLOBBER ourselves, rather than
5489 an expression containing it. This will speed things up as
5490 well as prevent accidents where two CLOBBERs are considered
5491 to be equal, thus producing an incorrect simplification. */
5492
5493 if (GET_CODE (new_rtx)((enum rtx_code) (new_rtx)->code) == CLOBBER && XEXP (new_rtx, 0)(((new_rtx)->u.fld[0]).rt_rtx) == const0_rtx(const_int_rtx[64]))
5494 return new_rtx;
5495
5496 if (GET_CODE (x)((enum rtx_code) (x)->code) == SUBREG && CONST_SCALAR_INT_P (new_rtx)((((enum rtx_code) (new_rtx)->code) == CONST_INT) || (((enum
rtx_code) (new_rtx)->code) == CONST_WIDE_INT))
)
5497 {
5498 machine_mode mode = GET_MODE (x)((machine_mode) (x)->mode);
5499
5500 x = simplify_subreg (GET_MODE (x)((machine_mode) (x)->mode), new_rtx,
5501 GET_MODE (SUBREG_REG (x))((machine_mode) ((((x)->u.fld[0]).rt_rtx))->mode),
5502 SUBREG_BYTE (x)(((x)->u.fld[1]).rt_subreg));
5503 if (! x)
5504 x = gen_rtx_CLOBBER (mode, const0_rtx)gen_rtx_fmt_e_stat ((CLOBBER), ((mode)), (((const_int_rtx[64]
))) )
;
5505 }
5506 else if (CONST_SCALAR_INT_P (new_rtx)((((enum rtx_code) (new_rtx)->code) == CONST_INT) || (((enum
rtx_code) (new_rtx)->code) == CONST_WIDE_INT))
5507 && (GET_CODE (x)((enum rtx_code) (x)->code) == ZERO_EXTEND
5508 || GET_CODE (x)((enum rtx_code) (x)->code) == SIGN_EXTEND
5509 || GET_CODE (x)((enum rtx_code) (x)->code) == FLOAT
5510 || GET_CODE (x)((enum rtx_code) (x)->code) == UNSIGNED_FLOAT))
5511 {
5512 x = simplify_unary_operation (GET_CODE (x)((enum rtx_code) (x)->code), GET_MODE (x)((machine_mode) (x)->mode),
5513 new_rtx,
5514 GET_MODE (XEXP (x, 0))((machine_mode) ((((x)->u.fld[0]).rt_rtx))->mode));
5515 if (!x)
5516 return gen_rtx_CLOBBER (VOIDmode, const0_rtx)gen_rtx_fmt_e_stat ((CLOBBER), ((((void) 0, E_VOIDmode))), ((
(const_int_rtx[64]))) )
;
5517 }
5518 else
5519 SUBST (XEXP (x, i), new_rtx)do_SUBST (&((((x)->u.fld[i]).rt_rtx)), (new_rtx));
5520 }
5521 }
5522 }
5523
5524 /* Check if we are loading something from the constant pool via float
5525 extension; in this case we would undo compress_float_constant
5526 optimization and degenerate constant load to an immediate value. */
5527 if (GET_CODE (x)((enum rtx_code) (x)->code) == FLOAT_EXTEND
5528 && MEM_P (XEXP (x, 0))(((enum rtx_code) ((((x)->u.fld[0]).rt_rtx))->code) == MEM
)
5529 && MEM_READONLY_P (XEXP (x, 0))(__extension__ ({ __typeof (((((x)->u.fld[0]).rt_rtx))) const
_rtx = (((((x)->u.fld[0]).rt_rtx))); if (((enum rtx_code)
(_rtx)->code) != MEM) rtl_check_failed_flag ("MEM_READONLY_P"
, _rtx, "/home/marxin/BIG/buildbot/buildworker/marxinbox-gcc-clang-static-analyzer/build/gcc/combine.c"
, 5529, __FUNCTION__); _rtx; })->unchanging)
)
5530 {
5531 rtx tmp = avoid_constant_pool_reference (x);
5532 if (x != tmp)
5533 return x;
5534 }
5535
5536 /* Try to simplify X. If the simplification changed the code, it is likely
5537 that further simplification will help, so loop, but limit the number
5538 of repetitions that will be performed. */
5539
5540 for (i = 0; i < 4; i++)
5541 {
5542 /* If X is sufficiently simple, don't bother trying to do anything
5543 with it. */
5544 if (code != CONST_INT && code != REG && code != CLOBBER)
5545 x = combine_simplify_rtx (x, op0_mode, in_dest, in_cond);
5546
5547 if (GET_CODE (x)((enum rtx_code) (x)->code) == code)
5548 break;
5549
5550 code = GET_CODE (x)((enum rtx_code) (x)->code);
5551
5552 /* We no longer know the original mode of operand 0 since we
5553 have changed the form of X) */
5554 op0_mode = VOIDmode((void) 0, E_VOIDmode);
5555 }
5556
5557 return x;
5558}
5559
5560/* If X is a commutative operation whose operands are not in the canonical
5561 order, use substitutions to swap them. */
5562