|
|
1.1 root 1: /* Optimize by combining instructions for GNU compiler.
1.1.1.2 root 2: Copyright (C) 1987, 1988 Free Software Foundation, Inc.
1.1 root 3:
4: This file is part of GNU CC.
5:
1.1.1.13 root 6: GNU CC is free software; you can redistribute it and/or modify
7: it under the terms of the GNU General Public License as published by
8: the Free Software Foundation; either version 1, or (at your option)
9: any later version.
10:
1.1 root 11: GNU CC is distributed in the hope that it will be useful,
1.1.1.13 root 12: but WITHOUT ANY WARRANTY; without even the implied warranty of
13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14: GNU General Public License for more details.
15:
16: You should have received a copy of the GNU General Public License
17: along with GNU CC; see the file COPYING. If not, write to
18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
1.1 root 19:
20:
21: /* This module is essentially the "combiner" phase of the U. of Arizona
22: Portable Optimizer, but redone to work on our list-structured
23: representation for RTL instead of their string representation.
24:
25: The LOG_LINKS of each insn identify the most recent assignment
26: to each REG used in the insn. It is a list of previous insns,
27: each of which contains a SET for a REG that is used in this insn
28: and not used or set in between. LOG_LINKs never cross basic blocks.
29: They were set up by the preceding pass (lifetime analysis).
30:
31: We try to combine each pair of insns joined by a logical link.
32: We also try to combine triples of insns A, B and C when
33: C has a link back to B and B has a link back to A.
34:
35: LOG_LINKS does not have links for use of the CC0. They don't
36: need to, because the insn that sets the CC0 is always immediately
37: before the insn that tests it. So we always regard a branch
38: insn as having a logical link to the preceding insn.
39:
40: We check (with use_crosses_set_p) to avoid combining in such a way
41: as to move a computation to a place where its value would be different.
42:
43: Combination is done by mathematically substituting the previous
44: insn(s) values for the regs they set into the expressions in
45: the later insns that refer to these regs. If the result is a valid insn
46: for our target machine, according to the machine description,
47: we install it, delete the earlier insns, and update the data flow
48: information (LOG_LINKS and REG_NOTES) for what we did.
49:
50: To simplify substitution, we combine only when the earlier insn(s)
51: consist of only a single assignment. To simplify updating afterward,
52: we never combine when a subroutine call appears in the middle.
53:
54: Since we do not represent assignments to CC0 explicitly except when that
55: is all an insn does, there is no LOG_LINKS entry in an insn that uses
56: the condition code for the insn that set the condition code.
57: Fortunately, these two insns must be consecutive.
58: Therefore, every JUMP_INSN is taken to have an implicit logical link
59: to the preceding insn. This is not quite right, since non-jumps can
60: also use the condition code; but in practice such insns would not
61: combine anyway. */
62:
1.1.1.15 root 63: #include <stdio.h>
64:
1.1 root 65: #include "config.h"
66: #include "rtl.h"
1.1.1.2 root 67: #include "flags.h"
1.1 root 68: #include "regs.h"
69: #include "basic-block.h"
70: #include "insn-config.h"
71: #include "recog.h"
72:
73: #define max(A,B) ((A) > (B) ? (A) : (B))
74: #define min(A,B) ((A) < (B) ? (A) : (B))
75:
1.1.1.2 root 76: /* It is not safe to use ordinary gen_lowpart in combine.
77: Use gen_lowpart_for_combine instead. See comments there. */
78: #define gen_lowpart dont_use_gen_lowpart_you_dummy
79:
1.1 root 80: /* Number of attempts to combine instructions in this function. */
81:
82: static int combine_attempts;
1.1.1.7 root 83: static int distrib_attempts;
1.1 root 84:
85: /* Number of attempts that got as far as substitution in this function. */
86:
87: static int combine_merges;
1.1.1.7 root 88: static int distrib_merges_1, distrib_merges_2;
1.1 root 89:
90: /* Number of instructions combined with added SETs in this function. */
91:
92: static int combine_extras;
93:
94: /* Number of instructions combined in this function. */
95:
96: static int combine_successes;
1.1.1.7 root 97: static int distrib_successes;
1.1 root 98:
99: /* Totals over entire compilation. */
100:
101: static int total_attempts, total_merges, total_extras, total_successes;
1.1.1.7 root 102: static int total_distrib_attempts, total_distrib_merges_1, total_distrib_merges_2, total_distrib_successes;
1.1 root 103:
104:
105: /* Vector mapping INSN_UIDs to cuids.
106: The cuids are like uids but increase monononically always.
107: Combine always uses cuids so that it can compare them.
108: But actually renumbering the uids, which we used to do,
109: proves to be a bad idea because it makes it hard to compare
110: the dumps produced by earlier passes with those from later passes. */
111:
1.1.1.16 root 112: static int *uid_cuid;
1.1 root 113:
114: /* Get the cuid of an insn. */
115:
116: #define INSN_CUID(INSN) (uid_cuid[INSN_UID (INSN)])
117:
118:
119: /* Record last point of death of (hard or pseudo) register n. */
120:
121: static rtx *reg_last_death;
122:
123: /* Record last point of modification of (hard or pseudo) register n. */
124:
125: static rtx *reg_last_set;
126:
127: /* Record the cuid of the last insn that invalidated memory
128: (anything that writes memory, and subroutine calls). */
129:
130: static int mem_last_set;
131:
132: /* Record the cuid of the last CALL_INSN
133: so we can tell whether a potential combination crosses any calls. */
134:
135: static int last_call_cuid;
136:
137: /* When `subst' is called, this is the insn that is being modified
138: (by combining in a previous insn). The PATTERN of this insn
139: is still the old pattern partially modified and it should not be
140: looked at, but this may be used to examine the successors of the insn
141: to judge whether a simplification is valid. */
142:
143: static rtx subst_insn;
144:
145: /* Record one modification to rtl structure
1.1.1.12 root 146: to be undone by storing old_contents into *where.
147: is_int is 1 if the contents are an int. */
1.1 root 148:
149: struct undo
150: {
151: rtx *where;
152: rtx old_contents;
1.1.1.12 root 153: int is_int;
1.1 root 154: };
155:
1.1.1.11 root 156: struct undo_int
157: {
158: int *where;
159: int old_contents;
1.1.1.12 root 160: int is_int;
1.1.1.11 root 161: };
162:
1.1 root 163: /* Record a bunch of changes to be undone, up to MAX_UNDO of them.
164: num_undo says how many are currently recorded.
165: storage is nonzero if we must undo the allocation of new storage.
166: The value of storage is what to pass to obfree. */
167:
168: #define MAX_UNDO 10
169:
170: struct undobuf
171: {
172: int num_undo;
173: char *storage;
174: struct undo undo[MAX_UNDO];
175: };
176:
177: static struct undobuf undobuf;
178:
1.1.1.2 root 179: /* Number of times the pseudo being substituted for
180: was found and replaced. */
181:
182: static int n_occurrences;
183:
1.1 root 184: static void move_deaths ();
1.1.1.7 root 185: static void move_deaths_2 ();
1.1.1.4 root 186: void remove_death ();
1.1 root 187: static void record_dead_and_set_regs ();
188: int regno_dead_p ();
189: static int use_crosses_set_p ();
1.1.1.4 root 190: static int try_combine ();
1.1.1.7 root 191: static rtx try_distrib ();
1.1 root 192: static rtx subst ();
193: static void undo_all ();
1.1.1.2 root 194: static void copy_substitutions ();
1.1 root 195: static void add_links ();
1.1.1.7 root 196: static void remove_links ();
1.1 root 197: static void add_incs ();
198: static int adjacent_insns_p ();
1.1.1.11 root 199: static int check_asm_operands ();
1.1 root 200: static rtx simplify_and_const_int ();
201: static rtx gen_lowpart_for_combine ();
202: static void simplify_set_cc0_and ();
203:
204: /* Main entry point for combiner. F is the first insn of the function.
205: NREGS is the first unused pseudo-reg number. */
206:
207: void
208: combine_instructions (f, nregs)
209: rtx f;
210: int nregs;
211: {
212: register rtx insn;
213: register int i;
214: register rtx links, nextlinks;
215: rtx prev;
216:
217: combine_attempts = 0;
218: combine_merges = 0;
219: combine_extras = 0;
220: combine_successes = 0;
1.1.1.7 root 221: distrib_attempts = 0;
222: distrib_merges_1 = 0;
223: distrib_merges_2 = 0;
224: distrib_successes = 0;
1.1 root 225:
226: reg_last_death = (rtx *) alloca (nregs * sizeof (rtx));
227: reg_last_set = (rtx *) alloca (nregs * sizeof (rtx));
228: bzero (reg_last_death, nregs * sizeof (rtx));
229: bzero (reg_last_set, nregs * sizeof (rtx));
230:
231: init_recog ();
232:
233: /* Compute maximum uid value so uid_cuid can be allocated. */
234:
235: for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
236: if (INSN_UID (insn) > i)
237: i = INSN_UID (insn);
238:
1.1.1.16 root 239: uid_cuid = (int *) alloca ((i + 1) * sizeof (int));
1.1 root 240:
241: /* Compute the mapping from uids to cuids.
242: Cuids are numbers assigned to insns, like uids,
243: except that cuids increase monotonically through the code. */
244:
245: for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
246: INSN_CUID (insn) = ++i;
247:
248: /* Now scan all the insns in forward order. */
249:
250: last_call_cuid = 0;
251: mem_last_set = 0;
252: prev = 0;
253:
254: for (insn = f; insn; insn = NEXT_INSN (insn))
255: {
256: if (GET_CODE (insn) == INSN
257: || GET_CODE (insn) == CALL_INSN
258: || GET_CODE (insn) == JUMP_INSN)
259: {
260: retry:
261: /* Try this insn with each insn it links back to. */
262:
263: for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
264: if (try_combine (insn, XEXP (links, 0), 0))
265: goto retry;
266:
267: /* Try each sequence of three linked insns ending with this one. */
268:
269: for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
270: if (GET_CODE (XEXP (links, 0)) != NOTE)
271: for (nextlinks = LOG_LINKS (XEXP (links, 0)); nextlinks;
272: nextlinks = XEXP (nextlinks, 1))
273: if (try_combine (insn, XEXP (links, 0), XEXP (nextlinks, 0)))
274: goto retry;
275:
276: /* Try to combine a jump insn that uses CC0
277: with a preceding insn that sets CC0, and maybe with its
278: logical predecessor as well.
279: This is how we make decrement-and-branch insns.
280: We need this special code because data flow connections
281: via CC0 do not get entered in LOG_LINKS. */
282:
283: if (GET_CODE (insn) == JUMP_INSN
284: && prev != 0
285: && GET_CODE (prev) == INSN
286: && GET_CODE (PATTERN (prev)) == SET
287: && GET_CODE (SET_DEST (PATTERN (prev))) == CC0)
288: {
289: if (try_combine (insn, prev, 0))
1.1.1.11 root 290: goto retry;
1.1 root 291:
292: if (GET_CODE (prev) != NOTE)
293: for (nextlinks = LOG_LINKS (prev); nextlinks;
294: nextlinks = XEXP (nextlinks, 1))
295: if (try_combine (insn, prev, XEXP (nextlinks, 0)))
296: goto retry;
297: }
1.1.1.7 root 298:
299: /* Try to apply the distributive law to this insn
300: and two insns that compute the operands of this one. */
301: for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
302: if (GET_CODE (XEXP (links, 0)) != NOTE)
303: for (nextlinks = XEXP (links, 1); nextlinks; nextlinks = XEXP (nextlinks, 1))
304: if (GET_CODE (XEXP (nextlinks, 0)) != NOTE)
305: {
306: rtx try_from = 0;
307:
308: if (GET_CODE (PATTERN (XEXP (links, 0))) == SET
309: && find_reg_note (insn, REG_DEAD, SET_DEST (PATTERN (XEXP (links, 0))))
310: && GET_CODE (PATTERN (XEXP (nextlinks, 0))) == SET
311: && find_reg_note (insn, REG_DEAD, SET_DEST (PATTERN (XEXP (nextlinks, 0)))))
312: try_from = try_distrib (insn, XEXP (links, 0), XEXP (nextlinks, 0));
313: if (try_from != 0)
314: {
315: insn = try_from;
316: goto retry;
317: }
318: }
1.1 root 319: #if 0
320: /* Turned off because on 68020 it takes four insns to make
321: something like (a[b / 32] & (1 << (31 - (b % 32)))) != 0
322: that could actually be optimized, and that's an unlikely piece of code. */
323: /* If an insn gets or sets a bit field, try combining it
324: with two different insns whose results it uses. */
325: if (GET_CODE (insn) == INSN
326: && GET_CODE (PATTERN (insn)) == SET
327: && (GET_CODE (SET_DEST (PATTERN (insn))) == ZERO_EXTRACT
328: || GET_CODE (SET_DEST (PATTERN (insn))) == SIGN_EXTRACT
329: || GET_CODE (SET_SRC (PATTERN (insn))) == ZERO_EXTRACT
330: || GET_CODE (SET_SRC (PATTERN (insn))) == SIGN_EXTRACT))
331: {
332: for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
333: if (GET_CODE (XEXP (links, 0)) != NOTE)
334: for (nextlinks = XEXP (links, 1); nextlinks;
335: nextlinks = XEXP (nextlinks, 1))
336: if (try_combine (insn, XEXP (links, 0), XEXP (nextlinks, 0)))
337: goto retry;
338: }
339: #endif
1.1.1.15 root 340: if (GET_CODE (insn) != NOTE)
341: record_dead_and_set_regs (insn);
1.1 root 342: prev = insn;
343: }
344: else if (GET_CODE (insn) != NOTE)
345: prev = 0;
346: }
347: total_attempts += combine_attempts;
348: total_merges += combine_merges;
349: total_extras += combine_extras;
350: total_successes += combine_successes;
351: }
352:
353: /* Try to combine the insns I1 and I2 into I3.
354: Here I1 appears earlier than I2, which is earlier than I3.
355: I1 can be zero; then we combine just I2 into I3.
356:
357: Return 1 if successful; if that happens, I1 and I2 are pseudo-deleted
358: by turning them into NOTEs, and I3 is modified.
359: Return 0 if the combination does not work. Then nothing is changed. */
360:
361: static int
362: try_combine (i3, i2, i1)
363: register rtx i3, i2, i1;
364: {
365: register rtx newpat;
366: int added_sets_1 = 0;
367: int added_sets_2 = 0;
368: int total_sets;
369: int i2_is_used;
370: register rtx link;
371: int insn_code_number;
372: rtx i2dest, i2src;
373: rtx i1dest, i1src;
1.1.1.2 root 374: int maxreg;
1.1.1.11 root 375: rtx temp;
1.1.1.15 root 376: int i;
1.1 root 377:
378: combine_attempts++;
379:
380: /* Don't combine with something already used up by combination. */
381:
382: if (GET_CODE (i2) == NOTE
383: || (i1 && GET_CODE (i1) == NOTE))
384: return 0;
385:
386: /* Don't combine across a CALL_INSN, because that would possibly
387: change whether the life span of some REGs crosses calls or not,
388: and it is a pain to update that information. */
389:
390: if (INSN_CUID (i2) < last_call_cuid
391: || (i1 && INSN_CUID (i1) < last_call_cuid))
392: return 0;
393:
394: /* Can combine only if previous insn is a SET of a REG, a SUBREG or CC0.
395: That REG must be either set or dead by the final instruction
396: (so that we can safely forget about setting it).
397: Also test use_crosses_set_p to make sure that the value
398: that is to be substituted for the register
399: does not use any registers whose values alter in between.
400: Do not try combining with moves from one register to another
401: since it is better to let them be tied by register allocation.
1.1.1.2 root 402: (There is a switch to permit such combination; except the insns
403: that copy a function value into another register are never combined
404: because moving that too far away from the function call could cause
405: something else to be stored in that register in the interim.)
1.1 root 406:
407: A set of a SUBREG is considered as if it were a set from
408: SUBREG. Thus, (SET (SUBREG:X (REG:Y...)) (something:X...))
409: is handled by substituting (SUBREG:Y (something:X...)) for (REG:Y...). */
410:
411: if (GET_CODE (PATTERN (i2)) != SET)
412: return 0;
413: i2dest = SET_DEST (PATTERN (i2));
414: i2src = SET_SRC (PATTERN (i2));
415: if (GET_CODE (i2dest) == SUBREG)
416: {
417: i2dest = SUBREG_REG (i2dest);
418: i2src = gen_rtx (SUBREG, GET_MODE (i2dest), i2src, 0);
419: }
1.1.1.4 root 420: /* Don't eliminate a store in the stack pointer. */
421: if (i2dest == stack_pointer_rtx)
422: return 0;
1.1.1.16 root 423: /* Don't install a subreg involving two modes not tieable.
424: It can worsen register allocation, and can even make invalid reload insns,
425: since the reg inside may need to be copied from in the outside mode,
426: and that may be invalid if it is an fp reg copied in integer mode. */
427: if (GET_CODE (i2src) == SUBREG
428: && ! MODES_TIEABLE_P (GET_MODE (i2src), GET_MODE (SUBREG_REG (i2src))))
429: return 0;
1.1 root 430: if (GET_CODE (i2dest) != CC0
431: && (GET_CODE (i2dest) != REG
1.1.1.2 root 432: || (GET_CODE (i2src) == REG
1.1.1.16 root 433: /* Do allow the combination of y = x; x = y; (with x dead)
434: because the result will turn into nothing. */
435: && !(GET_CODE (PATTERN (i3)) == SET
436: && i2src == SET_DEST (PATTERN (i3)))
1.1.1.2 root 437: && (!flag_combine_regs
1.1.1.5 root 438: /* Don't substitute a function value reg for any other. */
1.1.1.9 root 439: || FUNCTION_VALUE_REGNO_P (REGNO (i2src))))
1.1.1.2 root 440: || GET_CODE (i2src) == CALL
1.1.1.9 root 441: /* Don't substitute into an incremented register. */
442: || find_reg_note (i3, REG_INC, i2dest)
1.1 root 443: || use_crosses_set_p (i2src, INSN_CUID (i2))))
444: return 0;
1.1.1.16 root 445: if (GET_CODE (i2src) == ASM_OPERANDS && MEM_VOLATILE_P (i2src))
446: return 0;
1.1.1.15 root 447: /* Don't substitute for a register intended as a clobberable operand. */
448: if (GET_CODE (PATTERN (i3)) == PARALLEL)
449: for (i = 0; i < XVECLEN (PATTERN (i3), 0); i++)
450: if (GET_CODE (XVECEXP (PATTERN (i3), 0, i)) == CLOBBER
451: && XEXP (XVECEXP (PATTERN (i3), 0, i), 0) == i2dest)
452: return 0;
1.1 root 453:
454: if (i1 != 0)
455: {
456: if (GET_CODE (PATTERN (i1)) != SET)
457: return 0;
458: i1dest = SET_DEST (PATTERN (i1));
459: i1src = SET_SRC (PATTERN (i1));
460: if (GET_CODE (i1dest) == SUBREG)
461: {
462: i1dest = SUBREG_REG (i1dest);
463: i1src = gen_rtx (SUBREG, GET_MODE (i1dest), i1src, 0);
464: }
1.1.1.4 root 465: if (i1dest == stack_pointer_rtx)
466: return 0;
1.1.1.16 root 467: if (GET_CODE (i1src) == SUBREG
468: && ! MODES_TIEABLE_P (GET_MODE (i1src),
469: GET_MODE (SUBREG_REG (i1src))))
470: return 0;
1.1 root 471: if (GET_CODE (i1dest) != CC0
472: && (GET_CODE (i1dest) != REG
1.1.1.2 root 473: || (GET_CODE (i1src) == REG
474: && (!flag_combine_regs
1.1.1.9 root 475: || FUNCTION_VALUE_REGNO_P (REGNO (i1src))))
1.1.1.2 root 476: || GET_CODE (i1src) == CALL
1.1.1.9 root 477: || find_reg_note (i3, REG_INC, i1dest)
478: || find_reg_note (i2, REG_INC, i1dest)
1.1 root 479: || use_crosses_set_p (i1src, INSN_CUID (i1))))
480: return 0;
1.1.1.16 root 481: if (GET_CODE (i1src) == ASM_OPERANDS && MEM_VOLATILE_P (i1src))
482: return 0;
1.1.1.15 root 483: /* Don't substitute for a register intended as a clobberable operand. */
484: if (GET_CODE (PATTERN (i3)) == PARALLEL)
485: for (i = 0; i < XVECLEN (PATTERN (i3), 0); i++)
486: if (GET_CODE (XVECEXP (PATTERN (i3), 0, i)) == CLOBBER
487: && XEXP (XVECEXP (PATTERN (i3), 0, i), 0) == i1dest)
488: return 0;
489: }
490:
491: /* If it is better that two different modes keep two different pseudos,
492: avoid combining them. */
493: if (GET_CODE (PATTERN (i3)) == SET)
494: {
495: rtx i3dest = SET_DEST (PATTERN (i3));
496: while (GET_CODE (i3dest) == SUBREG
497: || GET_CODE (i3dest) == STRICT_LOW_PART
498: || GET_CODE (i3dest) == SIGN_EXTRACT
499: || GET_CODE (i3dest) == ZERO_EXTRACT)
500: i3dest = SUBREG_REG (i3dest);
501:
502: if (SET_SRC (PATTERN (i3)) == i2dest
503: && GET_CODE (i3dest) == REG
504: && ! MODES_TIEABLE_P (GET_MODE (i2dest), GET_MODE (i3dest)))
505: return 0;
1.1 root 506: }
507:
1.1.1.14 root 508: /* If I2 contains anything volatile, reject, unless nothing
509: volatile comes between it and I3. */
510: if (volatile_refs_p (PATTERN (i2)))
511: {
512: rtx insn;
513: for (insn = NEXT_INSN (i2); insn != i3; insn = NEXT_INSN (insn))
514: if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN
515: || GET_CODE (insn) == JUMP_INSN)
516: if (volatile_refs_p (PATTERN (insn)))
517: return 0;
518: }
519: /* Likewise for I1; nothing volatile can come between it and I3,
520: except optionally I2. */
521: if (i1 && volatile_refs_p (PATTERN (i1)))
522: {
523: rtx insn;
524: rtx end = (volatile_refs_p (PATTERN (i2)) ? i2 : i3);
525: for (insn = NEXT_INSN (i1); insn != end; insn = NEXT_INSN (insn))
526: if (GET_CODE (insn) == INSN || GET_CODE (insn) == CALL_INSN
527: || GET_CODE (insn) == JUMP_INSN)
528: if (volatile_refs_p (PATTERN (insn)))
529: return 0;
530: }
531:
1.1 root 532: /* If I1 or I2 contains an autoincrement or autodecrement,
1.1.1.13 root 533: make sure that register is not used between there and I3,
534: and not already used in I3 either.
1.1 root 535: Also insist that I3 not be a jump; if it were one
536: and the incremented register were spilled, we would lose. */
1.1.1.5 root 537: for (link = REG_NOTES (i2); link; link = XEXP (link, 1))
538: if (REG_NOTE_KIND (link) == REG_INC
539: && (GET_CODE (i3) == JUMP_INSN
540: || reg_used_between_p (XEXP (link, 0), i2, i3)
1.1.1.13 root 541: || reg_mentioned_p (XEXP (link, 0), PATTERN (i3))))
1.1.1.5 root 542: return 0;
1.1 root 543:
1.1.1.5 root 544: if (i1)
545: for (link = REG_NOTES (i1); link; link = XEXP (link, 1))
546: if (REG_NOTE_KIND (link) == REG_INC
547: && (GET_CODE (i3) == JUMP_INSN
548: || reg_used_between_p (XEXP (link, 0), i1, i3)
1.1.1.13 root 549: || reg_mentioned_p (XEXP (link, 0), PATTERN (i3))))
550: return 0;
551:
552: /* If I3 has an inc, then give up if I1 or I2 uses the reg that is inc'd,
553: EXCEPT in one case: I3 has a post-inc in an output operand. */
554: if (!(GET_CODE (PATTERN (i3)) == SET
555: && GET_CODE (SET_SRC (PATTERN (i3))) == REG
556: && GET_CODE (SET_DEST (PATTERN (i3))) == MEM
557: && (GET_CODE (XEXP (SET_DEST (PATTERN (i3)), 0)) == POST_INC
558: || GET_CODE (XEXP (SET_DEST (PATTERN (i3)), 0)) == POST_DEC)))
559: /* It's not the exception. */
560: for (link = REG_NOTES (i3); link; link = XEXP (link, 1))
561: if (REG_NOTE_KIND (link) == REG_INC
562: && (reg_mentioned_p (XEXP (link, 0), PATTERN (i2))
563: || (i1 != 0
564: && reg_mentioned_p (XEXP (link, 0), PATTERN (i1)))))
1.1.1.5 root 565: return 0;
1.1 root 566:
1.1.1.19! root 567: /* Make sure that I1DEST is not used between I2 and I3. */
! 568: if (i1 && reg_used_between_p (i1dest, i2, i3))
! 569: return 0;
! 570:
1.1.1.11 root 571: /* Don't combine an insn I1 or I2 that follows a CC0-setting insn.
572: An insn that uses CC0 must not be separated from the one that sets it.
573: It would be more logical to test whether CC0 occurs inside I1 or I2,
574: but that would be much slower, and this ought to be equivalent. */
575: temp = PREV_INSN (i2);
576: while (temp && GET_CODE (temp) == NOTE)
577: temp = PREV_INSN (temp);
578: if (temp && GET_CODE (temp) == INSN && sets_cc0_p (PATTERN (temp)))
579: return 0;
580: if (i1)
581: {
582: temp = PREV_INSN (i2);
583: while (temp && GET_CODE (temp) == NOTE)
584: temp = PREV_INSN (temp);
585: if (temp && GET_CODE (temp) == INSN && sets_cc0_p (PATTERN (temp)))
586: return 0;
587: }
588:
1.1 root 589: /* See if the SETs in i1 or i2 need to be kept around in the merged
590: instruction: whenever the value set there is still needed past i3. */
591: added_sets_2 = (GET_CODE (i2dest) != CC0
592: && ! dead_or_set_p (i3, i2dest));
593: if (i1)
594: added_sets_1 = ! (dead_or_set_p (i3, i1dest)
595: || dead_or_set_p (i2, i1dest));
596:
597: combine_merges++;
598:
599: undobuf.num_undo = 0;
600: undobuf.storage = 0;
601:
602: /* Substitute in the latest insn for the regs set by the earlier ones. */
603:
1.1.1.2 root 604: maxreg = max_reg_num ();
605:
1.1 root 606: subst_insn = i3;
1.1.1.2 root 607: n_occurrences = 0; /* `subst' counts here */
608:
1.1 root 609: newpat = subst (PATTERN (i3), i2dest, i2src);
610: /* Record whether i2's body now appears within i3's body. */
1.1.1.2 root 611: i2_is_used = n_occurrences;
1.1 root 612:
613: if (i1)
1.1.1.2 root 614: {
615: n_occurrences = 0;
616: newpat = subst (newpat, i1dest, i1src);
617: }
1.1 root 618:
619: if (GET_CODE (PATTERN (i3)) == SET
620: && SET_DEST (PATTERN (i3)) == cc0_rtx
1.1.1.2 root 621: && (GET_CODE (SET_SRC (PATTERN (i3))) == AND
622: || GET_CODE (SET_SRC (PATTERN (i3))) == LSHIFTRT)
1.1 root 623: && next_insn_tests_no_inequality (i3))
624: simplify_set_cc0_and (i3);
625:
1.1.1.2 root 626: if (max_reg_num () != maxreg)
627: abort ();
628:
1.1 root 629: /* If the actions of the earler insns must be kept
630: in addition to substituting them into the latest one,
631: we must make a new PARALLEL for the latest insn
632: to hold additional the SETs. */
633:
634: if (added_sets_1 || added_sets_2)
635: {
636: combine_extras++;
637:
638: /* Arrange to free later what we allocate now
639: if we don't accept this combination. */
640: if (!undobuf.storage)
641: undobuf.storage = (char *) oballoc (0);
642:
643: if (GET_CODE (newpat) == PARALLEL)
644: {
1.1.1.2 root 645: rtvec old = XVEC (newpat, 0);
1.1 root 646: total_sets = XVECLEN (newpat, 0) + added_sets_1 + added_sets_2;
1.1.1.2 root 647: newpat = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (total_sets));
648: bcopy (&old->elem[0], &XVECEXP (newpat, 0, 0),
649: sizeof (old->elem[0]) * old->num_elem);
1.1 root 650: }
651: else
652: {
1.1.1.2 root 653: rtx old = newpat;
1.1 root 654: total_sets = 1 + added_sets_1 + added_sets_2;
1.1.1.2 root 655: newpat = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (total_sets));
656: XVECEXP (newpat, 0, 0) = old;
1.1 root 657: }
658: if (added_sets_1)
659: {
660: XVECEXP (newpat, 0, --total_sets) = PATTERN (i1);
661: }
662: if (added_sets_2)
663: {
664: /* If there is no I1, use I2's body as is. */
665: if (i1 == 0
666: /* If I2 was stuck into I3, then anything within it has
667: already had I1 substituted into it when that was done to I3. */
668: || i2_is_used)
669: {
670: XVECEXP (newpat, 0, --total_sets) = PATTERN (i2);
671: }
672: else
673: XVECEXP (newpat, 0, --total_sets)
674: = subst (PATTERN (i2), i1dest, i1src);
675: }
676: }
677:
1.1.1.2 root 678: /* Fail if an autoincrement side-effect has been duplicated. */
679: if ((i2_is_used > 1 && find_reg_note (i2, REG_INC, 0) != 0)
680: || (i1 != 0 && n_occurrences > 1 && find_reg_note (i1, REG_INC, 0) != 0))
681: {
682: undo_all ();
683: return 0;
684: }
685:
1.1 root 686: /* Is the result of combination a valid instruction? */
687: insn_code_number = recog (newpat, i3);
688:
1.1.1.11 root 689: if (insn_code_number >= 0
690: /* Is the result a reasonable ASM_OPERANDS? */
1.1.1.13 root 691: || (check_asm_operands (newpat) && ! added_sets_1 && ! added_sets_2))
1.1 root 692: {
693: /* Yes. Install it. */
694: register int regno;
695: INSN_CODE (i3) = insn_code_number;
696: PATTERN (i3) = newpat;
1.1.1.2 root 697: /* If anything was substituted more than once,
698: copy it to avoid invalid shared rtl structure. */
699: copy_substitutions ();
700: /* The data flowing into I2 now flows into I3.
701: But we cannot always move all of I2's LOG_LINKS into I3,
702: since they must go to a setting of a REG from the
703: first use following. If I2 was the first use following a set,
704: I3 is now a use, but it is not the first use
705: if some instruction between I2 and I3 is also a use.
706: Here, for simplicity, we move all the links only if
707: there are no real insns between I2 and I3.
708: Otherwise, we move only links that correspond to regs
709: that used to die in I2. They are always safe to move. */
710: add_links (i3, i2, adjacent_insns_p (i2, i3));
1.1 root 711: /* Most REGs that previously died in I2 now die in I3. */
712: move_deaths (i2src, INSN_CUID (i2), i3);
713: if (GET_CODE (i2dest) == REG)
714: {
715: /* If the reg formerly set in I2 died only once and that was in I3,
716: zero its use count so it won't make `reload' do any work. */
717: regno = REGNO (i2dest);
718: if (! added_sets_2)
1.1.1.2 root 719: {
720: reg_n_sets[regno]--;
721: /* Used to check && regno_dead_p (regno, i3) also here. */
722: if (reg_n_sets[regno] == 0
723: && ! (basic_block_live_at_start[0][regno / HOST_BITS_PER_INT]
724: & (1 << (regno % HOST_BITS_PER_INT))))
725: reg_n_refs[regno] = 0;
726: }
1.1 root 727: /* If a ref to REGNO was substituted into I3 from I2,
728: then it still dies there if it previously did.
729: Otherwise either REGNO never did die in I3 so remove_death is safe
730: or this entire life of REGNO is gone so remove its death. */
731: if (!added_sets_2
732: && ! reg_mentioned_p (i2dest, PATTERN (i3)))
733: remove_death (regno, i3);
734: }
735: /* Any registers previously autoincremented in I2
736: are now incremented in I3. */
737: add_incs (i3, REG_NOTES (i2));
738: if (i1)
739: {
740: /* Likewise, merge the info from I1 and get rid of it. */
1.1.1.2 root 741: add_links (i3, i1,
742: adjacent_insns_p (i1, i2) && adjacent_insns_p (i2, i3));
1.1 root 743: move_deaths (i1src, INSN_CUID (i1), i3);
744: if (GET_CODE (i1dest) == REG)
745: {
746: regno = REGNO (i1dest);
747: if (! added_sets_1)
1.1.1.2 root 748: {
749: reg_n_sets[regno]--;
750: /* Used to also check && regno_dead_p (regno, i3) here. */
751:
752: if (reg_n_sets[regno] == 0
753: && ! (basic_block_live_at_start[0][regno / HOST_BITS_PER_INT]
754: & (1 << (regno % HOST_BITS_PER_INT))))
755:
756: reg_n_refs[regno] = 0;
757: }
1.1 root 758: /* If a ref to REGNO was substituted into I3 from I1,
759: then it still dies there if it previously did.
760: Else either REGNO never did die in I3 so remove_death is safe
761: or this entire life of REGNO is gone so remove its death. */
762: if (! added_sets_1
763: && ! reg_mentioned_p (i1dest, PATTERN (i3)))
764: remove_death (regno, i3);
765: }
766: add_incs (i3, REG_NOTES (i1));
767: LOG_LINKS (i1) = 0;
768: PUT_CODE (i1, NOTE);
769: NOTE_LINE_NUMBER (i1) = NOTE_INSN_DELETED;
770: NOTE_SOURCE_FILE (i1) = 0;
771: }
1.1.1.2 root 772: /* Get rid of I2. */
773: LOG_LINKS (i2) = 0;
774: PUT_CODE (i2, NOTE);
775: NOTE_LINE_NUMBER (i2) = NOTE_INSN_DELETED;
776: NOTE_SOURCE_FILE (i2) = 0;
1.1 root 777:
778: combine_successes++;
779: return 1;
780: }
781:
782: /* Failure: change I3 back the way it was. */
783: undo_all ();
784:
785: return 0;
786: }
787:
788: /* Undo all the modifications recorded in undobuf. */
789:
790: static void
791: undo_all ()
792: {
793: register int i;
794: if (undobuf.num_undo > MAX_UNDO)
795: undobuf.num_undo = MAX_UNDO;
796: for (i = undobuf.num_undo - 1; i >= 0; i--)
797: *undobuf.undo[i].where = undobuf.undo[i].old_contents;
798: if (undobuf.storage)
799: obfree (undobuf.storage);
800: undobuf.num_undo = 0;
801: undobuf.storage = 0;
802: }
803:
1.1.1.2 root 804: /* If this insn had more than one substitution,
805: copy all but one, so that no invalid shared substructure is introduced. */
806:
807: static void
808: copy_substitutions ()
809: {
810: register int i;
811: if (undobuf.num_undo > 1)
812: {
813: for (i = undobuf.num_undo - 1; i >= 1; i--)
1.1.1.12 root 814: if (! undobuf.undo[i].is_int)
815: *undobuf.undo[i].where = copy_rtx (*undobuf.undo[i].where);
1.1.1.2 root 816: }
817: }
818:
1.1 root 819: /* Throughout X, replace FROM with TO, and return the result.
820: The result is TO if X is FROM;
821: otherwise the result is X, but its contents may have been modified.
822: If they were modified, a record was made in undobuf so that
823: undo_all will (among other things) return X to its original state.
824:
825: If the number of changes necessary is too much to record to undo,
826: the excess changes are not made, so the result is invalid.
827: The changes already made can still be undone.
828: undobuf.num_undo is incremented for such changes, so by testing that
1.1.1.2 root 829: the caller can tell whether the result is valid.
830:
831: `n_occurrences' is incremented each time FROM is replaced. */
1.1 root 832:
833: static rtx
834: subst (x, from, to)
835: register rtx x, from, to;
836: {
837: register char *fmt;
838: register int len, i;
839: register enum rtx_code code;
1.1.1.2 root 840: char was_replaced[2];
1.1 root 841:
1.1.1.2 root 842: #define SUBST(INTO, NEWVAL) \
843: do { if (undobuf.num_undo < MAX_UNDO) \
844: { \
845: undobuf.undo[undobuf.num_undo].where = &INTO; \
846: undobuf.undo[undobuf.num_undo].old_contents = INTO; \
1.1.1.12 root 847: undobuf.undo[undobuf.num_undo].is_int = 0; \
1.1.1.2 root 848: INTO = NEWVAL; \
849: } \
850: undobuf.num_undo++; } while (0)
851:
1.1.1.11 root 852: #define SUBST_INT(INTO, NEWVAL) \
853: do { if (undobuf.num_undo < MAX_UNDO) \
854: { \
855: struct undo_int *u = (struct undo_int *)&undobuf.undo[undobuf.num_undo];\
856: u->where = &INTO; \
857: u->old_contents = INTO; \
1.1.1.12 root 858: u->is_int = 1; \
1.1.1.11 root 859: INTO = NEWVAL; \
860: } \
861: undobuf.num_undo++; } while (0)
862:
1.1.1.2 root 863: /* FAKE_EXTEND_SAFE_P (MODE, FROM) is 1 if (subreg:MODE FROM 0) is a safe
864: replacement for (zero_extend:MODE FROM) or (sign_extend:MODE FROM).
1.1.1.6 root 865: If it is 0, that cannot be done. We can now do this for any MEM
866: because (SUBREG (MEM...)) is guaranteed to cause the MEM to be reloaded.
867: If not for that, MEM's would very rarely be safe. */
1.1.1.2 root 868:
1.1.1.9 root 869: /* Reject MODEs bigger than a word, because we might not be able
870: to reference a two-register group starting with an arbitrary register
871: (and currently gen_lowpart might crash for a SUBREG). */
872:
1.1.1.7 root 873: #define FAKE_EXTEND_SAFE_P(MODE, FROM) \
1.1.1.9 root 874: (GET_MODE_SIZE (MODE) <= UNITS_PER_WORD \
875: && (GET_CODE (FROM) == REG || GET_CODE (FROM) == SUBREG \
876: || GET_CODE (FROM) == MEM))
1.1 root 877:
878: if (x == from)
879: return to;
880:
1.1.1.2 root 881: /* It is possible to have a subexpression appear twice in the insn.
882: Suppose that FROM is a register that appears within TO.
883: Then, after that subexpression has been scanned once by `subst',
884: the second time it is scanned, TO may be found. If we were
885: to scan TO here, we would find FROM within it and create a
886: self-referent rtl structure which is completely wrong. */
887: if (x == to)
888: return to;
889:
1.1 root 890: code = GET_CODE (x);
891:
892: /* A little bit of algebraic simplification here. */
893: switch (code)
894: {
895: /* This case has no effect except to speed things up. */
896: case REG:
897: case CONST_INT:
898: case CONST:
899: case SYMBOL_REF:
900: case LABEL_REF:
901: case PC:
902: case CC0:
903: return x;
1.1.1.2 root 904: }
905:
906: was_replaced[0] = 0;
907: was_replaced[1] = 0;
908:
909: len = GET_RTX_LENGTH (code);
910: fmt = GET_RTX_FORMAT (code);
911:
912: /* Don't replace FROM where it is being stored in rather than used. */
913: if (code == SET && SET_DEST (x) == from)
914: fmt = "ie";
915: if (code == SET && GET_CODE (SET_DEST (x)) == SUBREG
916: && SUBREG_REG (SET_DEST (x)) == from)
917: fmt = "ie";
918:
919: for (i = 0; i < len; i++)
920: {
921: if (fmt[i] == 'E')
922: {
923: register int j;
924: for (j = XVECLEN (x, i) - 1; j >= 0; j--)
925: {
926: register rtx new;
927: if (XVECEXP (x, i, j) == from)
928: new = to, n_occurrences++;
929: else
930: new = subst (XVECEXP (x, i, j), from, to);
931: if (new != XVECEXP (x, i, j))
932: SUBST (XVECEXP (x, i, j), new);
933: }
934: }
935: else if (fmt[i] == 'e')
936: {
937: register rtx new;
938:
939: if (XEXP (x, i) == from)
940: {
941: new = to;
942: n_occurrences++;
943: if (i < 2)
944: was_replaced[i] = 1;
945: }
946: else
947: new = subst (XEXP (x, i), from, to);
948:
949: if (new != XEXP (x, i))
950: SUBST (XEXP (x, i), new);
951: }
952: }
953:
954: /* A little bit of algebraic simplification here. */
955: switch (code)
956: {
957: case SUBREG:
958: /* Changing mode twice with SUBREG => just change it once,
959: or not at all if changing back to starting mode. */
960: if (SUBREG_REG (x) == to
1.1.1.11 root 961: && GET_CODE (to) == SUBREG)
1.1.1.2 root 962: {
963: if (GET_MODE (x) == GET_MODE (SUBREG_REG (to)))
1.1.1.11 root 964: if (SUBREG_WORD (x) == 0 && SUBREG_WORD (to) == 0)
965: return SUBREG_REG (to);
1.1.1.2 root 966: SUBST (SUBREG_REG (x), SUBREG_REG (to));
1.1.1.11 root 967: if (SUBREG_WORD (to) != 0)
968: SUBST_INT (SUBREG_WORD (x), SUBREG_WORD (x) + SUBREG_WORD (to));
1.1.1.2 root 969: }
1.1.1.4 root 970: if (SUBREG_REG (x) == to
971: && (GET_CODE (to) == SIGN_EXTEND || GET_CODE (to) == ZERO_EXTEND)
1.1.1.14 root 972: && subreg_lowpart_p (x))
973: {
974: /* (subreg (sign_extend X)) is X, if it has same mode as X. */
975: if (GET_MODE (x) == GET_MODE (XEXP (to, 0)))
976: return XEXP (to, 0);
977: /* (subreg (sign_extend X)), if it has a mode wider than X,
978: can be done with (sign_extend X). */
979: if (GET_MODE_SIZE (GET_MODE (x)) > GET_MODE_SIZE (GET_MODE (XEXP (to, 0))))
980: {
981: if (!undobuf.storage)
982: undobuf.storage = (char *) oballoc (0);
983: return gen_rtx (GET_CODE (to), GET_MODE (x), XEXP (to, 0));
984: }
985: /* Extend and then truncate smaller than it was to start with:
986: no need to extend. */
987: if (GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (GET_MODE (XEXP (to, 0))))
988: {
989: SUBST (XEXP (x, 0), XEXP (to, 0));
990: }
991: }
1.1.1.11 root 992: /* (subreg:A (mem:B X) N) becomes a modified MEM.
1.1.1.15 root 993: If we can't do that safely, then it becomes something nonsensical
994: so that this combination won't take place.
1.1.1.11 root 995: This avoids producing any (subreg (mem))s except in the special
996: paradoxical case where gen_lowpart_for_combine makes them. */
997: if (SUBREG_REG (x) == to
998: && GET_CODE (to) == MEM)
999: {
1.1.1.12 root 1000: int endian_offset = 0;
1.1.1.15 root 1001: /* Don't combine this if mode A is wider than B. */
1002: if (GET_MODE_SIZE (GET_MODE (x)) > GET_MODE_SIZE (GET_MODE (to)))
1003: return gen_rtx (CLOBBER, VOIDmode, const0_rtx);
1004: /* Don't change the mode of the MEM
1005: if that would change the meaning of the address. */
1006: if (mode_dependent_address_p (XEXP (to, 0)))
1007: return gen_rtx (CLOBBER, VOIDmode, const0_rtx);
1.1.1.12 root 1008: #ifdef BYTES_BIG_ENDIAN
1009: if (GET_MODE_SIZE (GET_MODE (x)) < UNITS_PER_WORD)
1010: endian_offset += UNITS_PER_WORD - GET_MODE_SIZE (GET_MODE (x));
1011: if (GET_MODE_SIZE (GET_MODE (to)) < UNITS_PER_WORD)
1012: endian_offset -= UNITS_PER_WORD - GET_MODE_SIZE (GET_MODE (to));
1013: #endif
1.1.1.11 root 1014: if (!undobuf.storage)
1015: undobuf.storage = (char *) oballoc (0);
1016: /* Note if the plus_constant doesn't make a valid address
1017: then this combination won't be accepted. */
1018: return gen_rtx (MEM, GET_MODE (x),
1019: plus_constant (XEXP (to, 0),
1.1.1.12 root 1020: (SUBREG_WORD (x) * UNITS_PER_WORD
1021: + endian_offset)));
1.1.1.11 root 1022: }
1.1.1.2 root 1023: break;
1.1 root 1024:
1025: case NOT:
1.1.1.4 root 1026: /* (not (minus X 1)) can become (neg X). */
1027: if (was_replaced[0]
1028: && ((GET_CODE (to) == PLUS && INTVAL (XEXP (to, 1)) == -1)
1029: || (GET_CODE (to) == MINUS && XEXP (to, 1) == const1_rtx)))
1.1.1.11 root 1030: {
1031: if (!undobuf.storage)
1032: undobuf.storage = (char *) oballoc (0);
1033: return gen_rtx (NEG, GET_MODE (to), XEXP (to, 0));
1034: }
1.1.1.4 root 1035: /* Don't let substitution introduce double-negatives. */
1036: if (was_replaced[0]
1.1.1.14 root 1037: && GET_CODE (to) == code)
1038: return XEXP (to, 0);
1.1.1.4 root 1039: break;
1040:
1.1 root 1041: case NEG:
1.1.1.4 root 1042: /* (neg (minus X Y)) can become (minus Y X). */
1043: if (was_replaced[0] && GET_CODE (to) == MINUS)
1.1.1.11 root 1044: {
1045: if (!undobuf.storage)
1046: undobuf.storage = (char *) oballoc (0);
1.1.1.14 root 1047: return gen_rtx (MINUS, GET_MODE (to),
1048: XEXP (to, 1), XEXP (to, 0));
1.1.1.11 root 1049: }
1.1 root 1050: /* Don't let substitution introduce double-negatives. */
1.1.1.2 root 1051: if (was_replaced[0]
1.1 root 1052: && GET_CODE (to) == code)
1053: return XEXP (to, 0);
1054: break;
1055:
1.1.1.2 root 1056: case FLOAT_TRUNCATE:
1057: /* (float_truncate:SF (float_extend:DF foo:SF)) = foo:SF. */
1058: if (was_replaced[0]
1059: && GET_CODE (to) == FLOAT_EXTEND
1060: && GET_MODE (XEXP (to, 0)) == GET_MODE (x))
1061: return XEXP (to, 0);
1062: break;
1063:
1.1.1.15 root 1064: #if 0
1065: case COMPARE:
1066: /* -x>0 if 0>x. */
1067: if (GET_CODE (XEXP (x, 0)) == NEG && XEXP (x, 1) == const0_rtx)
1068: {
1069: SUBST (XEXP (x, 1), XEXP (XEXP (x, 0), 0));
1070: SUBST (XEXP (x, 0), const0_rtx);
1071: }
1072: if (GET_CODE (XEXP (x, 1)) == NEG && XEXP (x, 0) == const0_rtx)
1073: {
1074: SUBST (XEXP (x, 0), XEXP (XEXP (x, 1), 0));
1075: SUBST (XEXP (x, 1), const0_rtx);
1076: }
1077: break;
1078: #endif
1079:
1.1 root 1080: case PLUS:
1.1.1.15 root 1081: #if 0 /* Turned off for caution: turn it on after 1.36. */
1082: /* Identify constant sums as such. */
1083: if ((was_replaced[0] || was_replaced[1])
1084: && CONSTANT_P (XEXP (x, 0))
1085: && CONSTANT_P (XEXP (x, 1)))
1086: {
1087: if (!undobuf.storage)
1088: undobuf.storage = (char *) oballoc (0);
1089: return gen_rtx (CONST, GET_MODE (x), x);
1090: }
1091: #endif
1.1 root 1092: /* In (plus <foo> (ashift <bar> <n>))
1093: change the shift to a multiply so we can recognize
1094: scaled indexed addresses. */
1.1.1.2 root 1095: if ((was_replaced[0]
1096: || was_replaced[1])
1.1 root 1097: && GET_CODE (to) == ASHIFT
1.1.1.2 root 1098: && GET_CODE (XEXP (to, 1)) == CONST_INT
1099: && INTVAL (XEXP (to, 1)) < HOST_BITS_PER_INT)
1100: {
1101: rtx temp;
1102: if (!undobuf.storage)
1103: undobuf.storage = (char *) oballoc (0);
1104: temp = gen_rtx (MULT, GET_MODE (to),
1105: XEXP (to, 0),
1106: gen_rtx (CONST_INT, VOIDmode,
1107: 1 << INTVAL (XEXP (to, 1))));
1108: if (was_replaced[0])
1109: SUBST (XEXP (x, 0), temp);
1110: else
1111: SUBST (XEXP (x, 1), temp);
1112: }
1113: /* (plus X (neg Y)) becomes (minus X Y). */
1114: if (GET_CODE (XEXP (x, 1)) == NEG)
1115: {
1116: if (!undobuf.storage)
1117: undobuf.storage = (char *) oballoc (0);
1118: return gen_rtx (MINUS, GET_MODE (x),
1119: XEXP (x, 0), XEXP (XEXP (x, 1), 0));
1120: }
1121: /* (plus (neg X) Y) becomes (minus Y X). */
1122: if (GET_CODE (XEXP (x, 0)) == NEG)
1.1 root 1123: {
1124: if (!undobuf.storage)
1125: undobuf.storage = (char *) oballoc (0);
1.1.1.2 root 1126: return gen_rtx (MINUS, GET_MODE (x),
1127: XEXP (x, 1), XEXP (XEXP (x, 0), 0));
1128: }
1129: /* (plus (plus x c1) c2) => (plus x c1+c2) */
1130: if (GET_CODE (XEXP (x, 1)) == CONST_INT
1131: && GET_CODE (XEXP (x, 0)) == PLUS
1132: && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
1133: {
1134: int sum = (INTVAL (XEXP (x, 1))
1135: + INTVAL (XEXP (XEXP (x, 0), 1)));
1136: if (sum == 0)
1137: return XEXP (XEXP (x, 0), 0);
1138: if (!undobuf.storage)
1139: undobuf.storage = (char *) oballoc (0);
1140: SUBST (XEXP (x, 1), gen_rtx (CONST_INT, VOIDmode, sum));
1141: SUBST (XEXP (x, 0), XEXP (XEXP (x, 0), 0));
1142: break;
1.1 root 1143: }
1144: /* If we have something (putative index) being added to a sum,
1145: associate it so that any constant term is outermost.
1146: That's because that's the way indexed addresses are
1147: now supposed to appear. */
1.1.1.2 root 1148: if (((was_replaced[0] && GET_CODE (XEXP (x, 1)) == PLUS)
1149: || (was_replaced[1] && GET_CODE (XEXP (x, 0)) == PLUS))
1.1 root 1150: ||
1.1.1.2 root 1151: ((was_replaced[0] || was_replaced[1])
1152: && GET_CODE (to) == PLUS))
1.1 root 1153: {
1154: rtx offset = 0, base, index;
1.1.1.2 root 1155: if (GET_CODE (to) != PLUS)
1.1 root 1156: {
1.1.1.2 root 1157: index = to;
1158: base = was_replaced[0] ? XEXP (x, 1) : XEXP (x, 0);
1.1 root 1159: }
1160: else
1161: {
1.1.1.2 root 1162: index = was_replaced[0] ? XEXP (x, 1) : XEXP (x, 0);
1163: base = to;
1.1 root 1164: }
1165: if (CONSTANT_ADDRESS_P (XEXP (base, 0)))
1166: {
1167: offset = XEXP (base, 0);
1168: base = XEXP (base, 1);
1169: }
1170: else if (CONSTANT_ADDRESS_P (XEXP (base, 1)))
1171: {
1172: offset = XEXP (base, 1);
1173: base = XEXP (base, 0);
1174: }
1175: if (offset != 0)
1176: {
1177: if (!undobuf.storage)
1178: undobuf.storage = (char *) oballoc (0);
1.1.1.2 root 1179: if (GET_CODE (offset) == CONST_INT)
1180: return plus_constant (gen_rtx (PLUS, GET_MODE (index),
1181: base, index),
1182: INTVAL (offset));
1183: if (GET_CODE (index) == CONST_INT)
1184: return plus_constant (gen_rtx (PLUS, GET_MODE (offset),
1185: base, offset),
1186: INTVAL (index));
1187: return gen_rtx (PLUS, GET_MODE (index),
1.1 root 1188: gen_rtx (PLUS, GET_MODE (index),
1.1.1.2 root 1189: base, index),
1190: offset);
1.1 root 1191: }
1192: }
1193: break;
1194:
1195: case EQ:
1196: case NE:
1197: /* If comparing a subreg against zero, discard the subreg. */
1.1.1.2 root 1198: if (was_replaced[0]
1.1 root 1199: && GET_CODE (to) == SUBREG
1200: && SUBREG_WORD (to) == 0
1201: && XEXP (x, 1) == const0_rtx)
1.1.1.2 root 1202: SUBST (XEXP (x, 0), SUBREG_REG (to));
1.1 root 1203:
1204: /* If comparing a ZERO_EXTRACT against zero,
1205: canonicalize to a SIGN_EXTRACT,
1206: since the two are equivalent here. */
1.1.1.2 root 1207: if (was_replaced[0]
1208: && GET_CODE (to) == ZERO_EXTRACT
1.1 root 1209: && XEXP (x, 1) == const0_rtx)
1210: {
1211: if (!undobuf.storage)
1212: undobuf.storage = (char *) oballoc (0);
1.1.1.2 root 1213: SUBST (XEXP (x, 0),
1214: gen_rtx (SIGN_EXTRACT, GET_MODE (to),
1215: XEXP (to, 0), XEXP (to, 1),
1216: XEXP (to, 2)));
1.1 root 1217: }
1.1.1.17 root 1218: #ifndef BITS_BIG_ENDIAN
1.1 root 1219: /* If we are putting (ASHIFT 1 x) into (EQ (AND ... y) 0),
1220: arrange to return (EQ (SIGN_EXTRACT y 1 x) 0),
1221: which is what jump-on-bit instructions are written with. */
1222: else if (XEXP (x, 1) == const0_rtx
1223: && GET_CODE (XEXP (x, 0)) == AND
1.1.1.2 root 1224: && (XEXP (XEXP (x, 0), 0) == to
1225: || XEXP (XEXP (x, 0), 1) == to)
1226: && GET_CODE (to) == ASHIFT
1227: && XEXP (to, 0) == const1_rtx)
1.1 root 1228: {
1229: register rtx y = XEXP (XEXP (x, 0),
1.1.1.2 root 1230: XEXP (XEXP (x, 0), 0) == to);
1.1 root 1231: if (!undobuf.storage)
1232: undobuf.storage = (char *) oballoc (0);
1.1.1.2 root 1233: SUBST (XEXP (x, 0),
1234: gen_rtx (SIGN_EXTRACT, GET_MODE (to),
1235: y,
1236: const1_rtx, XEXP (to, 1)));
1.1 root 1237: }
1.1.1.17 root 1238: #endif /* not BITS_BIG_ENDIAN */
1.1.1.15 root 1239: /* Negation is a no-op before equality test against zero. */
1240: if (GET_CODE (XEXP (x, 0)) == NEG && XEXP (x, 1) == const0_rtx)
1241: {
1242: SUBST (XEXP (x, 0), XEXP (XEXP (x, 0), 0));
1243: }
1244: if (GET_CODE (XEXP (x, 1)) == NEG && XEXP (x, 0) == const0_rtx)
1245: {
1246: SUBST (XEXP (x, 1), XEXP (XEXP (x, 1), 0));
1247: }
1.1 root 1248: break;
1249:
1250: case ZERO_EXTEND:
1.1.1.7 root 1251: /* Nested zero-extends are equivalent to just one. */
1.1.1.2 root 1252: if (was_replaced[0]
1.1 root 1253: && GET_CODE (to) == ZERO_EXTEND)
1.1.1.2 root 1254: SUBST (XEXP (x, 0), XEXP (to, 0));
1.1.1.7 root 1255: /* Zero extending a constant int can be replaced
1256: by a zero-extended constant. */
1257: if (was_replaced[0]
1258: && HOST_BITS_PER_INT >= GET_MODE_BITSIZE (GET_MODE (from))
1259: && GET_CODE (to) == CONST_INT)
1260: {
1261: int intval = INTVAL (to) & GET_MODE_MASK (GET_MODE (from));
1262: if (!undobuf.storage)
1263: undobuf.storage = (char *) oballoc (0);
1264: return gen_rtx (CONST_INT, VOIDmode, intval);
1265: }
1.1 root 1266: /* Zero-extending the result of an and with a constant can be done
1267: with a wider and. */
1.1.1.2 root 1268: if (was_replaced[0]
1.1 root 1269: && GET_CODE (to) == AND
1270: && GET_CODE (XEXP (to, 1)) == CONST_INT
1.1.1.2 root 1271: && FAKE_EXTEND_SAFE_P (GET_MODE (x), XEXP (to, 0))
1.1 root 1272: /* Avoid getting wrong result if the constant has high bits set
1273: that are irrelevant in the narrow mode where it is being used. */
1.1.1.2 root 1274: && 0 == (INTVAL (XEXP (to, 1))
1275: & ~ GET_MODE_MASK (GET_MODE (to))))
1.1 root 1276: {
1277: if (!undobuf.storage)
1278: undobuf.storage = (char *) oballoc (0);
1279: return gen_rtx (AND, GET_MODE (x),
1.1.1.2 root 1280: gen_lowpart_for_combine (GET_MODE (x), XEXP (to, 0)),
1.1 root 1281: XEXP (to, 1));
1.1.1.2 root 1282: }
1283: /* Change (zero_extend:M (subreg:N (zero_extract:M ...) 0))
1284: to (zero_extract:M ...) if the field extracted fits in mode N. */
1285: if (GET_CODE (XEXP (x, 0)) == SUBREG
1286: && GET_CODE (XEXP (XEXP (x, 0), 0)) == ZERO_EXTRACT
1287: && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == CONST_INT
1288: && (INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1))
1289: <= GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)))))
1290: {
1291: return XEXP (XEXP (x, 0), 0);
1292: }
1.1.1.7 root 1293: /* Change (zero_extend:M (subreg:N (and:M ... <const>) 0))
1294: to (and:M ...) if the significant bits fit in mode N. */
1295: if (GET_CODE (XEXP (x, 0)) == SUBREG
1296: && SUBREG_REG (XEXP (x, 0)) == to
1297: && SUBREG_WORD (XEXP (x, 0)) == 0
1298: && GET_CODE (to) == AND
1299: && GET_CODE (XEXP (to, 1)) == CONST_INT
1300: && FAKE_EXTEND_SAFE_P (GET_MODE (x), XEXP (to, 0))
1301: /* Avoid getting wrong result if the constant has high bits set
1302: that are irrelevant in the narrow mode where it is being used. */
1303: && 0 == (INTVAL (XEXP (to, 1))
1304: & ~ GET_MODE_MASK (GET_MODE (to))))
1305: {
1306: if (!undobuf.storage)
1307: undobuf.storage = (char *) oballoc (0);
1308: return gen_rtx (AND, GET_MODE (x),
1309: gen_lowpart_for_combine (GET_MODE (x), XEXP (to, 0)),
1310: XEXP (to, 1));
1311: }
1.1.1.15 root 1312: /* In (zero_extend:M (subreg:N (lshiftrt:M REG))),
1313: where REG was assigned from (zero_extend:M (any:N ...)),
1.1.1.7 root 1314: remove the outer zero extension. */
1315: if (GET_CODE (XEXP (x, 0)) == SUBREG
1316: && SUBREG_REG (XEXP (x, 0)) == to
1317: && SUBREG_WORD (XEXP (x, 0)) == 0
1318: && GET_CODE (to) == LSHIFTRT)
1319: {
1320: rtx tmp = XEXP (to, 0);
1321:
1.1.1.15 root 1322: /* See if arg of LSHIFTRT is a register whose value we can find. */
1.1.1.7 root 1323: if (GET_CODE (tmp) == REG)
1.1.1.15 root 1324: if (reg_n_sets[REGNO (tmp)] == 1
1.1.1.17 root 1325: && reg_last_set[REGNO (tmp)] != 0
1.1.1.15 root 1326: && SET_DEST (PATTERN (reg_last_set[REGNO (tmp)])) == tmp)
1.1.1.7 root 1327: tmp = SET_SRC (PATTERN (reg_last_set[REGNO (tmp)]));
1328: else
1329: break;
1330:
1331: if (GET_CODE (tmp) == ZERO_EXTEND
1332: && GET_MODE (tmp) == GET_MODE (x)
1333: && GET_MODE (XEXP (tmp, 0)) == GET_MODE (XEXP (x, 0)))
1334: return SUBREG_REG (XEXP (x, 0));
1335: }
1.1 root 1336: break;
1337:
1338: case SIGN_EXTEND:
1.1.1.7 root 1339: /* Nested sign-extends are equivalent to just one. */
1.1.1.2 root 1340: if (was_replaced[0]
1.1 root 1341: && GET_CODE (to) == SIGN_EXTEND)
1.1.1.2 root 1342: SUBST (XEXP (x, 0), XEXP (to, 0));
1.1.1.7 root 1343: /* Sign extending a constant int can be replaced
1344: by a sign-extended constant. */
1345: if (was_replaced[0]
1346: && HOST_BITS_PER_INT >= GET_MODE_BITSIZE (GET_MODE (from))
1347: && GET_CODE (to) == CONST_INT)
1348: {
1349: int intval = INTVAL (to);
1350: if (!undobuf.storage)
1351: undobuf.storage = (char *) oballoc (0);
1352: if (intval > 0
1353: && (intval & (1 << (GET_MODE_BITSIZE (GET_MODE (from)) - 1))))
1354: intval |= ~ GET_MODE_MASK (GET_MODE (from));
1355: return gen_rtx (CONST_INT, VOIDmode, intval);
1356: }
1.1 root 1357: /* Sign-extending the result of an and with a constant can be done
1358: with a wider and, provided the high bit of the constant is 0. */
1.1.1.2 root 1359: if (was_replaced[0]
1.1 root 1360: && GET_CODE (to) == AND
1361: && GET_CODE (XEXP (to, 1)) == CONST_INT
1.1.1.2 root 1362: && FAKE_EXTEND_SAFE_P (GET_MODE (x), XEXP (to, 0))
1.1 root 1363: && ((INTVAL (XEXP (to, 1))
1.1.1.2 root 1364: & (-1 << (GET_MODE_BITSIZE (GET_MODE (to)) - 1)))
1.1 root 1365: == 0))
1366: {
1367: if (!undobuf.storage)
1368: undobuf.storage = (char *) oballoc (0);
1369: return gen_rtx (AND, GET_MODE (x),
1.1.1.2 root 1370: gen_lowpart_for_combine (GET_MODE (x), XEXP (to, 0)),
1.1 root 1371: XEXP (to, 1));
1372: }
1.1.1.7 root 1373: /* hacks added by tiemann. */
1374: /* Change (sign_extend:M (subreg:N (and:M ... <const>) 0))
1375: to (and:M ...), provided the result fits in mode N,
1.1.1.16 root 1376: and the high bit of the constant is 0 in mode N. */
1.1.1.7 root 1377: if (GET_CODE (XEXP (x, 0)) == SUBREG
1378: && SUBREG_REG (XEXP (x, 0)) == to
1379: && SUBREG_WORD (XEXP (x, 0)) == 0
1380: && GET_CODE (to) == AND
1381: && GET_CODE (XEXP (to, 1)) == CONST_INT
1382: && FAKE_EXTEND_SAFE_P (GET_MODE (x), XEXP (to, 0))
1383: && ((INTVAL (XEXP (to, 1))
1.1.1.16 root 1384: & (-1 << (GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0))) - 1)))
1.1.1.7 root 1385: == 0))
1386: {
1387: if (!undobuf.storage)
1388: undobuf.storage = (char *) oballoc (0);
1389: return gen_rtx (AND, GET_MODE (x),
1390: gen_lowpart_for_combine (GET_MODE (x), XEXP (to, 0)),
1391: XEXP (to, 1));
1392: }
1.1.1.15 root 1393: /* In (sign_extend:M (subreg:N (ashiftrt:M REG))),
1394: where REG was assigned from (sign_extend:M (any:N ...)),
1.1.1.7 root 1395: remove the outer sign extension. */
1396: if (GET_CODE (XEXP (x, 0)) == SUBREG
1397: && SUBREG_REG (XEXP (x, 0)) == to
1398: && SUBREG_WORD (XEXP (x, 0)) == 0
1399: && GET_CODE (to) == ASHIFTRT)
1400: {
1401: rtx tmp = XEXP (to, 0);
1402:
1.1.1.15 root 1403: /* See if arg of LSHIFTRT is a register whose value we can find. */
1.1.1.7 root 1404: if (GET_CODE (tmp) == REG)
1.1.1.15 root 1405: if (reg_n_sets[REGNO (tmp)] == 1
1.1.1.17 root 1406: && reg_last_set[REGNO (tmp)] != 0
1.1.1.15 root 1407: && SET_DEST (PATTERN (reg_last_set[REGNO (tmp)])) == tmp)
1.1.1.7 root 1408: tmp = SET_SRC (PATTERN (reg_last_set[REGNO (tmp)]));
1409: else
1410: break;
1411:
1412: if (GET_CODE (tmp) == SIGN_EXTEND
1413: && GET_MODE (tmp) == GET_MODE (x)
1414: && GET_MODE (XEXP (tmp, 0)) == GET_MODE (XEXP (x, 0)))
1415: return SUBREG_REG (XEXP (x, 0));
1416: }
1.1 root 1417: break;
1418:
1419: case SET:
1.1.1.2 root 1420: /* In (set (zero-extract <x> <n> <y>) (and <foo> <(2**n-1) | anything>))
1.1 root 1421: the `and' can be deleted. This can happen when storing a bit
1.1.1.2 root 1422: that came from a set-flag insn followed by masking to one bit. */
1.1 root 1423: if (GET_CODE (XEXP (x, 0)) == ZERO_EXTRACT
1.1.1.2 root 1424: && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
1425: && was_replaced[1]
1.1 root 1426: && GET_CODE (to) == AND
1.1.1.2 root 1427: && GET_CODE (XEXP (to, 1)) == CONST_INT
1428: && 0 == (((1 << INTVAL (XEXP (XEXP (x, 0), 1))) - 1)
1429: & ~ INTVAL (XEXP (to, 1))))
1.1 root 1430: {
1.1.1.2 root 1431: SUBST (XEXP (x, 1), XEXP (to, 0));
1432: }
1433: /* In (set (zero-extract <x> <n> <y>)
1.1.1.14 root 1434: (subreg (and <foo> <(2**n-1) | anything>)))
1.1.1.2 root 1435: the `and' can be deleted. */
1436: if (GET_CODE (XEXP (x, 0)) == ZERO_EXTRACT
1437: && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
1438: && GET_CODE (XEXP (x, 1)) == SUBREG
1439: && SUBREG_WORD (XEXP (x, 1)) == 0
1440: && GET_CODE (SUBREG_REG (XEXP (x, 1))) == AND
1441: && GET_CODE (XEXP (SUBREG_REG (XEXP (x, 1)), 1)) == CONST_INT
1442: && 0 == (((1 << INTVAL (XEXP (XEXP (x, 0), 1))) - 1)
1443: & ~ INTVAL (XEXP (SUBREG_REG (XEXP (x, 1)), 1))))
1444: {
1445: SUBST (SUBREG_REG (XEXP (x, 1)), XEXP (SUBREG_REG (XEXP (x, 1)), 0));
1446: }
1447: /* (set (zero_extract ...) (and/or/xor (zero_extract ...) const)),
1.1.1.5 root 1448: if both zero_extracts have the same location, size and position,
1.1.1.2 root 1449: can be changed to avoid the byte extracts. */
1450: if ((GET_CODE (XEXP (x, 0)) == ZERO_EXTRACT
1451: || GET_CODE (XEXP (x, 0)) == SIGN_EXTRACT)
1452: && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
1453: && (GET_CODE (XEXP (x, 1)) == AND
1454: || GET_CODE (XEXP (x, 1)) == IOR
1455: || GET_CODE (XEXP (x, 1)) == XOR)
1.1.1.5 root 1456: && rtx_equal_p (XEXP (x, 0), XEXP (XEXP (x, 1), 0))
1.1.1.2 root 1457: && GET_CODE (XEXP (XEXP (x, 1), 0)) == GET_CODE (XEXP (x, 0))
1.1.1.14 root 1458: && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT
1459: /* zero_extract can apply to a QImode even if the bits extracted
1460: don't fit inside that byte. In such a case, we may not do this
1461: optimization, since the OR or AND insn really would need
1462: to fit in a byte. */
1463: && (INTVAL (XEXP (XEXP (x, 0), 1)) + INTVAL (XEXP (XEXP (x, 0), 2))
1464: < GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (x, 0), 0)))))
1.1.1.2 root 1465: {
1.1.1.14 root 1466: int shiftcount;
1.1.1.19! root 1467: int fieldsize;
1.1.1.15 root 1468: int newmask;
1.1.1.2 root 1469: #ifdef BITS_BIG_ENDIAN
1.1.1.14 root 1470: shiftcount
1.1.1.2 root 1471: = GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (x, 0), 0)))
1472: - INTVAL (XEXP (XEXP (x, 0), 1)) - INTVAL (XEXP (XEXP (x, 0), 2));
1473: #else
1.1.1.14 root 1474: shiftcount
1.1.1.2 root 1475: = INTVAL (XEXP (XEXP (x, 0), 2));
1476: #endif
1.1.1.19! root 1477: fieldsize = INTVAL (XEXP (XEXP (x, 0), 1));
1.1.1.15 root 1478: newmask = ((INTVAL (XEXP (XEXP (x, 1), 1)) << shiftcount)
1479: + (GET_CODE (XEXP (x, 1)) == AND
1.1.1.19! root 1480: /* For AND, preserve the bits outside this field. */
! 1481: ? ((1 << shiftcount) - 1
! 1482: + (-1 << (shiftcount + fieldsize)))
1.1.1.15 root 1483: : 0));
1484: if (GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (x, 0), 0)))
1485: < HOST_BITS_PER_INT)
1486: newmask &= (1 << GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (x, 0), 0)))) - 1;
1.1.1.2 root 1487: if (!undobuf.storage)
1488: undobuf.storage = (char *) oballoc (0);
1489: return
1490: gen_rtx (SET, VOIDmode,
1491: XEXP (XEXP (x, 0), 0),
1492: gen_rtx (GET_CODE (XEXP (x, 1)),
1493: GET_MODE (XEXP (XEXP (x, 0), 0)),
1494: XEXP (XEXP (XEXP (x, 1), 0), 0),
1.1.1.15 root 1495: gen_rtx (CONST_INT, VOIDmode, newmask)));
1.1.1.2 root 1496: }
1.1.1.13 root 1497: /* Can simplify (set (cc0) (compare (zero/sign_extend FOO) CONST))
1498: to (set (cc0) (compare FOO CONST)) if CONST fits in FOO's mode
1.1.1.12 root 1499: and we are only testing equality.
1500: In fact, this is valid for zero_extend if what follows is an
1501: unsigned comparison, and for sign_extend with a signed comparison. */
1502: if (SET_DEST (x) == cc0_rtx
1.1.1.13 root 1503: && GET_CODE (SET_SRC (x)) == COMPARE
1.1.1.12 root 1504: && (GET_CODE (XEXP (SET_SRC (x), 0)) == ZERO_EXTEND
1505: || GET_CODE (XEXP (SET_SRC (x), 0)) == SIGN_EXTEND)
1506: && next_insn_tests_no_inequality (subst_insn)
1507: && GET_CODE (XEXP (SET_SRC (x), 1)) == CONST_INT
1508: /* This is overly cautious by one bit, but saves worrying about
1509: whether it is zero-extension or sign extension. */
1510: && ((unsigned) INTVAL (XEXP (SET_SRC (x), 1))
1511: < (1 << (GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (SET_SRC (x), 0), 0))) - 1))))
1512: SUBST (XEXP (SET_SRC (x), 0), XEXP (XEXP (SET_SRC (x), 0), 0));
1.1 root 1513: break;
1514:
1515: case AND:
1516: if (GET_CODE (XEXP (x, 1)) == CONST_INT)
1517: {
1.1.1.2 root 1518: rtx tem = simplify_and_const_int (x, to);
1.1 root 1519: if (tem)
1520: return tem;
1521: }
1522: break;
1523:
1.1.1.14 root 1524: case IOR:
1525: case XOR:
1526: /* (ior (ior x c1) c2) => (ior x c1|c2); likewise for xor. */
1527: if (GET_CODE (XEXP (x, 1)) == CONST_INT
1528: && GET_CODE (XEXP (x, 0)) == code
1529: && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
1530: {
1531: int c0 = INTVAL (XEXP (x, 1));
1532: int c1 = INTVAL (XEXP (XEXP (x, 0), 1));
1533: int combined = (code == IOR ? c0 | c1 : c0 ^ c1);
1534:
1535: if (combined == 0)
1536: return XEXP (XEXP (x, 0), 0);
1537: if (!undobuf.storage)
1538: undobuf.storage = (char *) oballoc (0);
1539: SUBST (XEXP (x, 1), gen_rtx (CONST_INT, VOIDmode, combined));
1540: SUBST (XEXP (x, 0), XEXP (XEXP (x, 0), 0));
1541: break;
1542: }
1543:
1.1 root 1544: case FLOAT:
1545: /* (float (sign_extend <X>)) = (float <X>). */
1.1.1.2 root 1546: if (was_replaced[0]
1.1 root 1547: && GET_CODE (to) == SIGN_EXTEND)
1.1.1.2 root 1548: SUBST (XEXP (x, 0), XEXP (to, 0));
1.1 root 1549: break;
1550:
1551: case ZERO_EXTRACT:
1.1.1.2 root 1552: /* (ZERO_EXTRACT (TRUNCATE x)...)
1553: can become (ZERO_EXTRACT x ...). */
1554: if (was_replaced[0]
1555: && GET_CODE (to) == TRUNCATE)
1556: {
1557: #ifdef BITS_BIG_ENDIAN
1558: if (GET_CODE (XEXP (x, 2)) == CONST_INT)
1559: {
1560: if (!undobuf.storage)
1561: undobuf.storage = (char *) oballoc (0);
1562: /* On a big-endian machine, must increment the bit-number
1563: since sign bit is farther away in the pre-truncated value. */
1564: return gen_rtx (ZERO_EXTRACT, GET_MODE (x),
1565: XEXP (to, 0),
1566: XEXP (x, 1),
1567: gen_rtx (CONST_INT, VOIDmode,
1568: (INTVAL (XEXP (x, 2))
1569: + GET_MODE_BITSIZE (GET_MODE (XEXP (to, 0)))
1570: - GET_MODE_BITSIZE (GET_MODE (to)))));
1571: }
1572: #else
1573: SUBST (XEXP (x, 0), XEXP (to, 0));
1574: #endif
1575: }
1.1 root 1576: /* Extracting a single bit from the result of a shift:
1577: see which bit it was before the shift and extract that directly. */
1.1.1.2 root 1578: if (was_replaced[0]
1.1 root 1579: && (GET_CODE (to) == ASHIFTRT || GET_CODE (to) == LSHIFTRT
1580: || GET_CODE (to) == ASHIFT || GET_CODE (to) == LSHIFT)
1581: && GET_CODE (XEXP (to, 1)) == CONST_INT
1582: && XEXP (x, 1) == const1_rtx
1583: && GET_CODE (XEXP (x, 2)) == CONST_INT)
1584: {
1585: int shift = INTVAL (XEXP (to, 1));
1586: int newpos;
1587: if (GET_CODE (to) == ASHIFT || GET_CODE (to) == LSHIFT)
1588: shift = - shift;
1589: #ifdef BITS_BIG_ENDIAN
1590: shift = - shift;
1591: #endif
1592: newpos = INTVAL (XEXP (x, 2)) + shift;
1593: if (newpos >= 0 &&
1.1.1.2 root 1594: newpos < GET_MODE_BITSIZE (GET_MODE (to)))
1.1 root 1595: {
1596: if (!undobuf.storage)
1597: undobuf.storage = (char *) oballoc (0);
1598: return gen_rtx (ZERO_EXTRACT, GET_MODE (x),
1599: XEXP (to, 0), const1_rtx,
1600: gen_rtx (CONST_INT, VOIDmode, newpos));
1601: }
1602: }
1603: break;
1604:
1605: case LSHIFTRT:
1606: case ASHIFTRT:
1607: case ROTATE:
1608: case ROTATERT:
1609: #ifdef SHIFT_COUNT_TRUNCATED
1610: /* (lshift <X> (sign_extend <Y>)) = (lshift <X> <Y>) (most machines).
1611: True for all kinds of shifts and also for zero_extend. */
1.1.1.2 root 1612: if (was_replaced[1]
1.1 root 1613: && (GET_CODE (to) == SIGN_EXTEND
1.1.1.2 root 1614: || GET_CODE (to) == ZERO_EXTEND)
1615: && FAKE_EXTEND_SAFE_P (GET_MODE (to), XEXP (to, 0)))
1.1 root 1616: {
1617: if (!undobuf.storage)
1618: undobuf.storage = (char *) oballoc (0);
1.1.1.2 root 1619: SUBST (XEXP (x, 1),
1620: /* This is a perverse SUBREG, wider than its base. */
1621: gen_lowpart_for_combine (GET_MODE (to), XEXP (to, 0)));
1.1 root 1622: }
1623: #endif
1624: /* Two shifts in a row of same kind
1625: in same direction with constant counts
1626: may be combined. */
1.1.1.2 root 1627: if (was_replaced[0]
1.1 root 1628: && GET_CODE (to) == GET_CODE (x)
1629: && GET_CODE (XEXP (x, 1)) == CONST_INT
1630: && GET_CODE (XEXP (to, 1)) == CONST_INT
1631: && INTVAL (XEXP (to, 1)) > 0
1632: && INTVAL (XEXP (x, 1)) > 0
1633: && (INTVAL (XEXP (x, 1)) + INTVAL (XEXP (to, 1))
1.1.1.2 root 1634: < GET_MODE_BITSIZE (GET_MODE (x))))
1.1 root 1635: {
1636: if (!undobuf.storage)
1637: undobuf.storage = (char *) oballoc (0);
1638: return gen_rtx (GET_CODE (x), GET_MODE (x),
1639: XEXP (to, 0),
1640: gen_rtx (CONST_INT, VOIDmode,
1641: INTVAL (XEXP (x, 1))
1642: + INTVAL (XEXP (to, 1))));
1643: }
1644: break;
1645:
1646: case LSHIFT:
1647: case ASHIFT:
1648: #ifdef SHIFT_COUNT_TRUNCATED
1649: /* (lshift <X> (sign_extend <Y>)) = (lshift <X> <Y>) (most machines).
1650: True for all kinds of shifts and also for zero_extend. */
1.1.1.2 root 1651: if (was_replaced[1]
1.1 root 1652: && (GET_CODE (to) == SIGN_EXTEND
1.1.1.4 root 1653: || GET_CODE (to) == ZERO_EXTEND)
1.1.1.17 root 1654: && FAKE_EXTEND_SAFE_P (GET_MODE (to), XEXP (to, 0)))
1.1 root 1655: {
1656: if (!undobuf.storage)
1657: undobuf.storage = (char *) oballoc (0);
1.1.1.17 root 1658: SUBST (XEXP (x, 1),
1659: /* This is a perverse SUBREG, wider than its base. */
1660: gen_lowpart_for_combine (GET_MODE (to), XEXP (to, 0)));
1.1 root 1661: }
1662: #endif
1663: /* (lshift (and (lshiftrt <foo> <X>) <Y>) <X>)
1664: happens copying between bit fields in similar structures.
1665: It can be replaced by one and instruction.
1666: It does not matter whether the shifts are logical or arithmetic. */
1667: if (GET_CODE (XEXP (x, 0)) == AND
1668: && GET_CODE (XEXP (x, 1)) == CONST_INT
1669: && INTVAL (XEXP (x, 1)) > 0
1670: && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
1.1.1.2 root 1671: && XEXP (XEXP (x, 0), 0) == to
1.1 root 1672: && (GET_CODE (to) == LSHIFTRT
1673: || GET_CODE (to) == ASHIFTRT)
1674: #if 0
1675: /* I now believe this restriction is unnecessary.
1676: The outer shift will discard those bits in any case, right? */
1677:
1678: /* If inner shift is arithmetic, either it shifts left or
1679: the bits it shifts the sign into are zeroed by the and. */
1680: && (INTVAL (XEXP (x, 1)) < 0
1681: || ((unsigned) INTVAL (XEXP (XEXP (x, 0), 1))
1682: < 1 << (GET_MODE_BITSIZE (GET_MODE (x))
1683: - INTVAL (XEXP (x, 0)))))
1684: #endif
1685: && GET_CODE (XEXP (to, 1)) == CONST_INT
1686: && INTVAL (XEXP (x, 1)) == INTVAL (XEXP (to, 1)))
1687: {
1688: if (!undobuf.storage)
1689: undobuf.storage = (char *) oballoc (0);
1690: /* The constant in the new `and' is <Y> << <X>
1691: but clear out all bits that don't belong in our mode. */
1692: return gen_rtx (AND, GET_MODE (x), XEXP (to, 0),
1693: gen_rtx (CONST_INT, VOIDmode,
1694: (GET_MODE_MASK (GET_MODE (x))
1695: & ((GET_MODE_MASK (GET_MODE (x))
1696: & INTVAL (XEXP (XEXP (x, 0), 1)))
1697: << INTVAL (XEXP (x, 1))))));
1698: }
1699: /* Two shifts in a row in same direction with constant counts
1700: may be combined. */
1.1.1.2 root 1701: if (was_replaced[0]
1.1 root 1702: && (GET_CODE (to) == ASHIFT || GET_CODE (to) == LSHIFT)
1703: && GET_CODE (XEXP (x, 1)) == CONST_INT
1704: && GET_CODE (XEXP (to, 1)) == CONST_INT
1705: && INTVAL (XEXP (to, 1)) > 0
1706: && INTVAL (XEXP (x, 1)) > 0
1707: && (INTVAL (XEXP (x, 1)) + INTVAL (XEXP (to, 1))
1.1.1.2 root 1708: < GET_MODE_BITSIZE (GET_MODE (x))))
1.1 root 1709: {
1710: if (!undobuf.storage)
1711: undobuf.storage = (char *) oballoc (0);
1712: return gen_rtx (GET_CODE (x), GET_MODE (x),
1713: XEXP (to, 0),
1714: gen_rtx (CONST_INT, VOIDmode,
1715: INTVAL (XEXP (x, 1))
1716: + INTVAL (XEXP (to, 1))));
1717: }
1718: /* (ashift (ashiftrt <foo> <X>) <X>)
1719: (or, on some machines, (ashift (ashift <foo> <-X>) <X>) instead)
1720: happens if you divide by 2**N and then multiply by 2**N.
1721: It can be replaced by one `and' instruction.
1722: It does not matter whether the shifts are logical or arithmetic. */
1723: if (GET_CODE (XEXP (x, 1)) == CONST_INT
1724: && INTVAL (XEXP (x, 1)) > 0
1.1.1.2 root 1725: && was_replaced[0]
1.1 root 1726: && (((GET_CODE (to) == LSHIFTRT || GET_CODE (to) == ASHIFTRT)
1727: && GET_CODE (XEXP (to, 1)) == CONST_INT
1728: && INTVAL (XEXP (x, 1)) == INTVAL (XEXP (to, 1)))
1729: ||
1730: ((GET_CODE (to) == LSHIFT || GET_CODE (to) == ASHIFT)
1731: && GET_CODE (XEXP (to, 1)) == CONST_INT
1732: && INTVAL (XEXP (x, 1)) == - INTVAL (XEXP (to, 1)))))
1733: {
1734: if (!undobuf.storage)
1735: undobuf.storage = (char *) oballoc (0);
1.1.1.2 root 1736: /* The constant in the new `and' is -1 << <X>
1.1 root 1737: but clear out all bits that don't belong in our mode. */
1738: return gen_rtx (AND, GET_MODE (x), XEXP (to, 0),
1739: gen_rtx (CONST_INT, VOIDmode,
1740: (GET_MODE_MASK (GET_MODE (x))
1741: & (GET_MODE_MASK (GET_MODE (x))
1742: << INTVAL (XEXP (x, 1))))));
1743: }
1744:
1745: }
1746:
1747: return x;
1748: }
1749:
1750: /* This is the AND case of the function subst. */
1751:
1752: static rtx
1.1.1.2 root 1753: simplify_and_const_int (x, to)
1754: rtx x, to;
1.1 root 1755: {
1756: register rtx varop = XEXP (x, 0);
1757: register int constop = INTVAL (XEXP (x, 1));
1758:
1759: /* (and (subreg (and <foo> <constant>) 0) <constant>)
1760: results from an andsi followed by an andqi,
1761: which happens frequently when storing bit-fields
1762: on something whose result comes from an andsi. */
1763: if (GET_CODE (varop) == SUBREG
1.1.1.2 root 1764: && XEXP (varop, 0) == to
1.1 root 1765: && subreg_lowpart_p (varop)
1766: && GET_CODE (to) == AND
1767: && GET_CODE (XEXP (to, 1)) == CONST_INT
1768: /* Verify that the result of the outer `and'
1769: is not affected by any bits not defined in the inner `and'.
1770: True if the outer mode is narrower, or if the outer constant
1771: masks to zero all the bits that the inner mode doesn't have. */
1.1.1.2 root 1772: && (GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (GET_MODE (to))
1773: || (constop & ~ GET_MODE_MASK (GET_MODE (to))) == 0))
1.1 root 1774: {
1775: if (!undobuf.storage)
1776: undobuf.storage = (char *) oballoc (0);
1777: return gen_rtx (AND, GET_MODE (x),
1.1.1.2 root 1778: gen_lowpart_for_combine (GET_MODE (x), XEXP (to, 0)),
1.1 root 1779: gen_rtx (CONST_INT, VOIDmode,
1780: constop
1781: /* Remember that the bits outside that mode
1782: are not being changed, so the effect
1783: is as if they were all 1. */
1784: & INTVAL (XEXP (to, 1))));
1785: }
1.1.1.2 root 1786: /* (and:SI (zero_extract:SI ...) <constant>)
1787: results from an andsi following a byte-fetch on risc machines.
1788: When the constant includes all bits extracted, eliminate the `and'. */
1789: if (GET_CODE (varop) == ZERO_EXTRACT
1790: && GET_CODE (XEXP (varop, 1)) == CONST_INT
1791: /* The `and' must not clear any bits that the extract can give. */
1792: && (~ constop & ((1 << INTVAL (XEXP (varop, 1))) - 1)) == 0)
1793: return varop;
1.1 root 1794: /* (and (zero_extend <foo>) <constant>)
1795: often results from storing in a bit-field something
1796: that was calculated as a short. Replace with a single `and'
1797: in whose constant all bits not in <foo>'s mode are zero. */
1.1.1.2 root 1798: if (varop == to
1799: && GET_CODE (to) == ZERO_EXTEND
1800: && FAKE_EXTEND_SAFE_P (GET_MODE (x), XEXP (to, 0)))
1.1 root 1801: {
1802: if (!undobuf.storage)
1803: undobuf.storage = (char *) oballoc (0);
1804: return gen_rtx (AND, GET_MODE (x),
1.1.1.2 root 1805: /* This is a perverse SUBREG, wider than its base. */
1806: gen_lowpart_for_combine (GET_MODE (x), XEXP (to, 0)),
1.1 root 1807: gen_rtx (CONST_INT, VOIDmode,
1.1.1.2 root 1808: constop & GET_MODE_MASK (GET_MODE (XEXP (to, 0)))));
1.1 root 1809: }
1810: /* (and (sign_extend <foo>) <constant>)
1811: can be replaced with (and (subreg <foo>) <constant>)
1812: if <constant> is narrower than <foo>'s mode,
1813: or with (zero_extend <foo>) if <constant> is a mask for that mode. */
1.1.1.2 root 1814: if (varop == to
1.1 root 1815: && GET_CODE (to) == SIGN_EXTEND
1.1.1.2 root 1816: && ((unsigned) constop <= GET_MODE_MASK (GET_MODE (XEXP (to, 0))))
1817: && FAKE_EXTEND_SAFE_P (GET_MODE (x), XEXP (to, 0)))
1.1 root 1818: {
1819: if (!undobuf.storage)
1820: undobuf.storage = (char *) oballoc (0);
1.1.1.2 root 1821: if (constop == GET_MODE_MASK (GET_MODE (XEXP (to, 0))))
1.1 root 1822: return gen_rtx (ZERO_EXTEND, GET_MODE (x), XEXP (to, 0));
1823: return gen_rtx (AND, GET_MODE (x),
1.1.1.2 root 1824: /* This is a perverse SUBREG, wider than its base. */
1825: gen_lowpart_for_combine (GET_MODE (x), XEXP (to, 0)),
1.1 root 1826: XEXP (x, 1));
1827: }
1828: /* (and (and <foo> <constant>) <constant>)
1829: comes from two and instructions in a row. */
1.1.1.2 root 1830: if (varop == to
1.1 root 1831: && GET_CODE (to) == AND
1832: && GET_CODE (XEXP (to, 1)) == CONST_INT)
1833: {
1834: if (!undobuf.storage)
1835: undobuf.storage = (char *) oballoc (0);
1836: return gen_rtx (AND, GET_MODE (x),
1837: XEXP (to, 0),
1838: gen_rtx (CONST_INT, VOIDmode,
1839: constop
1840: & INTVAL (XEXP (to, 1))));
1841: }
1842: /* (and (ashiftrt (ashift FOO N) N) CONST)
1843: may be simplified to (and FOO CONST) if CONST masks off the bits
1844: changed by the two shifts. */
1845: if (GET_CODE (varop) == ASHIFTRT
1846: && GET_CODE (XEXP (varop, 1)) == CONST_INT
1.1.1.2 root 1847: && XEXP (varop, 0) == to
1.1 root 1848: && GET_CODE (to) == ASHIFT
1849: && GET_CODE (XEXP (to, 1)) == CONST_INT
1850: && INTVAL (XEXP (varop, 1)) == INTVAL (XEXP (to, 1))
1851: && ((unsigned) constop >> INTVAL (XEXP (varop, 1))) == 0)
1852: {
1853: if (!undobuf.storage)
1854: undobuf.storage = (char *) oballoc (0);
1855: /* If CONST is a mask for the low byte,
1856: change this into a zero-extend instruction
1857: from just the low byte of FOO. */
1.1.1.2 root 1858: if (constop == GET_MODE_MASK (QImode))
1.1 root 1859: {
1860: rtx temp = gen_lowpart_for_combine (QImode, XEXP (to, 0));
1.1.1.2 root 1861: if (GET_CODE (temp) != CLOBBER)
1.1 root 1862: return gen_rtx (ZERO_EXTEND, GET_MODE (x), temp);
1863: }
1864: return gen_rtx (AND, GET_MODE (x),
1865: XEXP (to, 0), XEXP (x, 1));
1866: }
1.1.1.15 root 1867: /* (and (ashiftrt (zero_extend FOO) N) CONST)
1868: may be simplified to (and (ashiftrt (subreg FOO) N) CONST)
1869: if CONST masks off the bits changed by extension. */
1870: if ((GET_CODE (varop) == ASHIFTRT || GET_CODE (varop) == LSHIFTRT)
1871: && GET_CODE (XEXP (varop, 1)) == CONST_INT
1872: && XEXP (varop, 0) == to
1873: && (GET_CODE (to) == ZERO_EXTEND || GET_CODE (to) == SIGN_EXTEND)
1874: /* Verify the and discards all the extended bits. */
1875: && (((unsigned) constop << INTVAL (XEXP (varop, 1)))
1876: >> GET_MODE_BITSIZE (GET_MODE (XEXP (to, 0)))) == 0
1877: && FAKE_EXTEND_SAFE_P (GET_MODE (x), XEXP (to, 0)))
1878: {
1879: if (!undobuf.storage)
1880: undobuf.storage = (char *) oballoc (0);
1881: SUBST (XEXP (varop, 0),
1882: gen_lowpart_for_combine (GET_MODE (x), XEXP (to, 0)));
1883: return x;
1884: }
1.1.1.2 root 1885: /* (and x const) may be converted to (zero_extend (subreg x 0)). */
1.1.1.4 root 1886: if (constop == GET_MODE_MASK (QImode)
1887: && GET_CODE (varop) == REG)
1.1.1.2 root 1888: {
1889: if (!undobuf.storage)
1890: undobuf.storage = (char *) oballoc (0);
1891: return gen_rtx (ZERO_EXTEND, GET_MODE (x),
1892: gen_rtx (SUBREG, QImode, varop, 0));
1893: }
1.1.1.4 root 1894: if (constop == GET_MODE_MASK (HImode)
1895: && GET_CODE (varop) == REG)
1.1.1.2 root 1896: {
1897: if (!undobuf.storage)
1898: undobuf.storage = (char *) oballoc (0);
1899: return gen_rtx (ZERO_EXTEND, GET_MODE (x),
1900: gen_rtx (SUBREG, HImode, varop, 0));
1901: }
1.1 root 1902: /* No simplification applies. */
1903: return 0;
1904: }
1905:
1906: /* Like gen_lowpart but for use by combine. In combine it is not possible
1907: to create any new pseudoregs. However, it is safe to create
1908: invalid memory addresses, because combine will try to recognize
1909: them and all they will do is make the combine attempt fail.
1910:
1.1.1.2 root 1911: If for some reason this cannot do its job, an rtx
1912: (clobber (const_int 0)) is returned.
1913: An insn containing that will not be recognized. */
1914:
1915: #undef gen_lowpart
1.1 root 1916:
1917: static rtx
1918: gen_lowpart_for_combine (mode, x)
1919: enum machine_mode mode;
1920: register rtx x;
1921: {
1922: if (GET_CODE (x) == SUBREG || GET_CODE (x) == REG)
1923: return gen_lowpart (mode, x);
1.1.1.9 root 1924: if (GET_MODE (x) == mode)
1.1.1.2 root 1925: return gen_rtx (CLOBBER, VOIDmode, const0_rtx);
1.1 root 1926: if (GET_CODE (x) == MEM)
1927: {
1928: register int offset = 0;
1.1.1.7 root 1929:
1.1.1.9 root 1930: /* Refuse to work on a volatile memory ref. */
1931: if (MEM_VOLATILE_P (x))
1932: return gen_rtx (CLOBBER, VOIDmode, const0_rtx);
1933:
1.1.1.7 root 1934: /* If we want to refer to something bigger than the original memref,
1935: generate a perverse subreg instead. That will force a reload
1936: of the original memref X. */
1937: if (GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (mode))
1938: return gen_rtx (SUBREG, mode, x, 0);
1939:
1.1 root 1940: #ifdef WORDS_BIG_ENDIAN
1941: offset = (max (GET_MODE_SIZE (GET_MODE (x)), UNITS_PER_WORD)
1942: - max (GET_MODE_SIZE (mode), UNITS_PER_WORD));
1943: #endif
1944: #ifdef BYTES_BIG_ENDIAN
1.1.1.2 root 1945: /* Adjust the address so that the address-after-the-data
1946: is unchanged. */
1947: offset -= (min (UNITS_PER_WORD, GET_MODE_SIZE (mode))
1948: - min (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x))));
1.1 root 1949: #endif
1950: return gen_rtx (MEM, mode, plus_constant (XEXP (x, 0),
1951: offset));
1952: }
1953: else
1.1.1.2 root 1954: return gen_rtx (CLOBBER, VOIDmode, const0_rtx);
1.1 root 1955: }
1956:
1957: /* After substitution, if the resulting pattern looks like
1.1.1.2 root 1958: (set (cc0) (and ...)) or (set (cc0) (lshiftrt ...)),
1959: this function is called to simplify the
1.1 root 1960: pattern into a bit-field operation if possible. */
1961:
1962: static void
1963: simplify_set_cc0_and (insn)
1964: rtx insn;
1965: {
1966: register rtx value = XEXP (PATTERN (insn), 1);
1967: register rtx op0 = XEXP (value, 0);
1968: register rtx op1 = XEXP (value, 1);
1969: int offset = 0;
1970: rtx var = 0;
1971: rtx bitnum = 0;
1972: int temp;
1973: int unit;
1.1.1.2 root 1974: rtx newpat;
1975:
1976: if (GET_CODE (value) == AND)
1977: {
1978: op0 = XEXP (value, 0);
1979: op1 = XEXP (value, 1);
1980: }
1981: else if (GET_CODE (value) == LSHIFTRT)
1982: {
1983: /* If there is no AND, but there is a shift that discards
1984: all but the sign bit, we can pretend that the shift result
1985: is ANDed with 1. Otherwise we cannot handle just a shift. */
1986: if (GET_CODE (XEXP (value, 1)) == CONST_INT
1987: && (INTVAL (XEXP (value, 1))
1988: == GET_MODE_BITSIZE (GET_MODE (value)) - 1))
1989: {
1990: op0 = value;
1991: op1 = const1_rtx;
1992: }
1993: else
1994: return;
1995: }
1996: else
1997: abort ();
1.1 root 1998:
1999: /* Look for a constant power of 2 or a shifted 1
2000: on either side of the AND. Set VAR to the other side.
2001: Set BITNUM to the shift count of the 1 (as an rtx).
2002: Or, if bit number is constant, set OFFSET to the bit number. */
2003:
2004: switch (GET_CODE (op0))
2005: {
2006: case CONST_INT:
2007: temp = exact_log2 (INTVAL (op0));
2008: if (temp < 0)
2009: return;
2010: offset = temp;
2011: var = op1;
2012: break;
2013:
2014: case ASHIFT:
2015: case LSHIFT:
2016: if (XEXP (op0, 0) == const1_rtx)
2017: {
2018: bitnum = XEXP (op0, 1);
2019: var = op1;
2020: }
2021: }
2022: if (var == 0)
2023: switch (GET_CODE (op1))
2024: {
2025: case CONST_INT:
2026: temp = exact_log2 (INTVAL (op1));
2027: if (temp < 0)
2028: return;
2029: offset = temp;
2030: var = op0;
2031: break;
2032:
2033: case ASHIFT:
2034: case LSHIFT:
2035: if (XEXP (op1, 0) == const1_rtx)
2036: {
2037: bitnum = XEXP (op1, 1);
2038: var = op0;
2039: }
2040: }
2041:
2042: /* If VAR is 0, we didn't find something recognizable. */
2043: if (var == 0)
2044: return;
2045:
2046: if (!undobuf.storage)
2047: undobuf.storage = (char *) oballoc (0);
2048:
2049: /* If the bit position is currently exactly 0,
2050: extract a right-shift from the variable portion. */
2051: if (offset == 0
2052: && (GET_CODE (var) == ASHIFTRT || GET_CODE (var) == LSHIFTRT))
2053: {
2054: bitnum = XEXP (var, 1);
2055: var = XEXP (var, 0);
2056: }
2057:
1.1.1.2 root 2058: if (GET_CODE (var) == SUBREG && SUBREG_WORD (var) == 0)
2059: var = SUBREG_REG (var);
2060:
2061: /* Note that BITNUM and OFFSET are always little-endian thru here
2062: even on a big-endian machine. */
2063:
1.1 root 2064: #ifdef BITS_BIG_ENDIAN
1.1.1.2 root 2065: unit = GET_MODE_BITSIZE (GET_MODE (var)) - 1;
1.1 root 2066:
2067: if (bitnum != 0)
2068: bitnum = gen_rtx (MINUS, SImode,
2069: gen_rtx (CONST_INT, VOIDmode, unit), bitnum);
2070: else
2071: offset = unit - offset;
2072: #endif
2073:
2074: if (bitnum == 0)
2075: bitnum = gen_rtx (CONST_INT, VOIDmode, offset);
2076:
1.1.1.2 root 2077: newpat = gen_rtx (SET, VOIDmode, cc0_rtx,
2078: gen_rtx (ZERO_EXTRACT, VOIDmode, var, const1_rtx, bitnum));
2079: if (recog (newpat, insn) >= 0)
1.1 root 2080: {
1.1.1.2 root 2081: if (undobuf.num_undo < MAX_UNDO)
2082: {
2083: undobuf.undo[undobuf.num_undo].where = &XEXP (PATTERN (insn), 1);
2084: undobuf.undo[undobuf.num_undo].old_contents = value;
2085: XEXP (PATTERN (insn), 1) = XEXP (newpat, 1);
2086: }
2087: undobuf.num_undo++;
1.1 root 2088: }
2089: }
2090:
2091: /* Update the records of when each REG was most recently set or killed
2092: for the things done by INSN. This is the last thing done in processing
2093: INSN in the combiner loop.
2094:
2095: We update reg_last_set, reg_last_death, and also the similar information
2096: mem_last_set (which insn most recently modified memory)
2097: and last_call_cuid (which insn was the most recent subroutine call). */
2098:
2099: static void
2100: record_dead_and_set_regs (insn)
2101: rtx insn;
2102: {
2103: register rtx link;
2104: for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
2105: {
1.1.1.2 root 2106: if (REG_NOTE_KIND (link) == REG_DEAD)
1.1 root 2107: reg_last_death[REGNO (XEXP (link, 0))] = insn;
1.1.1.2 root 2108: else if (REG_NOTE_KIND (link) == REG_INC)
1.1 root 2109: reg_last_set[REGNO (XEXP (link, 0))] = insn;
2110: }
2111:
2112: if (GET_CODE (insn) == CALL_INSN)
2113: last_call_cuid = mem_last_set = INSN_CUID (insn);
2114:
2115: if (GET_CODE (PATTERN (insn)) == PARALLEL)
2116: {
2117: register int i;
2118: for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
2119: {
2120: register rtx elt = XVECEXP (PATTERN (insn), 0, i);
2121: register enum rtx_code code = GET_CODE (elt);
2122: if (code == SET || code == CLOBBER)
2123: {
1.1.1.15 root 2124: rtx dest = XEXP (elt, 0);
2125: while (GET_CODE (dest) == SUBREG
2126: || GET_CODE (dest) == STRICT_LOW_PART
2127: || GET_CODE (dest) == SIGN_EXTRACT
2128: || GET_CODE (dest) == ZERO_EXTRACT)
2129: dest = XEXP (dest, 0);
2130:
2131: if (GET_CODE (dest) == REG)
2132: reg_last_set[REGNO (dest)] = insn;
2133: else if (GET_CODE (dest) == MEM)
1.1 root 2134: mem_last_set = INSN_CUID (insn);
2135: }
2136: }
2137: }
2138: else if (GET_CODE (PATTERN (insn)) == SET
2139: || GET_CODE (PATTERN (insn)) == CLOBBER)
2140: {
1.1.1.15 root 2141: register rtx dest = XEXP (PATTERN (insn), 0);
2142:
2143: while (GET_CODE (dest) == SUBREG
2144: || GET_CODE (dest) == STRICT_LOW_PART
2145: || GET_CODE (dest) == SIGN_EXTRACT
2146: || GET_CODE (dest) == ZERO_EXTRACT)
2147: dest = XEXP (dest, 0);
2148:
2149: if (GET_CODE (dest) == REG)
2150: reg_last_set[REGNO (dest)] = insn;
2151: else if (GET_CODE (dest) == MEM)
1.1 root 2152: mem_last_set = INSN_CUID (insn);
2153: }
2154: }
2155:
2156: /* Return nonzero if expression X refers to a REG or to memory
2157: that is set in an instruction more recent than FROM_CUID. */
2158:
2159: static int
2160: use_crosses_set_p (x, from_cuid)
2161: register rtx x;
2162: int from_cuid;
2163: {
2164: register char *fmt;
2165: register int i;
2166: register enum rtx_code code = GET_CODE (x);
2167:
2168: if (code == REG)
2169: {
2170: register int regno = REGNO (x);
1.1.1.10 root 2171: #ifdef PUSH_ROUNDING
2172: /* Don't allow uses of the stack pointer to be moved,
2173: because we don't know whether the move crosses a push insn. */
2174: if (regno == STACK_POINTER_REGNUM)
2175: return 1;
2176: #endif
1.1 root 2177: return (reg_last_set[regno]
2178: && INSN_CUID (reg_last_set[regno]) > from_cuid);
2179: }
2180:
2181: if (code == MEM && mem_last_set > from_cuid)
2182: return 1;
2183:
2184: fmt = GET_RTX_FORMAT (code);
2185:
1.1.1.9 root 2186: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1.1 root 2187: {
2188: if (fmt[i] == 'E')
2189: {
2190: register int j;
2191: for (j = XVECLEN (x, i) - 1; j >= 0; j--)
2192: if (use_crosses_set_p (XVECEXP (x, i, j), from_cuid))
2193: return 1;
2194: }
2195: else if (fmt[i] == 'e'
2196: && use_crosses_set_p (XEXP (x, i), from_cuid))
2197: return 1;
2198: }
2199: return 0;
2200: }
2201:
2202: /* Return nonzero if reg REGNO is marked as dying in INSN. */
2203:
2204: int
2205: regno_dead_p (regno, insn)
2206: int regno;
2207: rtx insn;
2208: {
2209: register rtx link;
2210:
2211: for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
1.1.1.2 root 2212: if ((REG_NOTE_KIND (link) == REG_DEAD
2213: || REG_NOTE_KIND (link) == REG_INC)
2214: && REGNO (XEXP (link, 0)) == regno)
1.1 root 2215: return 1;
2216:
2217: return 0;
2218: }
2219:
2220: /* Return nonzero if J is the first insn following I,
2221: not counting labels, line numbers, etc.
2222: We assume that J follows I. */
2223:
2224: static int
2225: adjacent_insns_p (i, j)
2226: rtx i, j;
2227: {
2228: register rtx insn;
2229: for (insn = NEXT_INSN (i); insn != j; insn = NEXT_INSN (insn))
2230: if (GET_CODE (insn) == INSN
2231: || GET_CODE (insn) == CALL_INSN
2232: || GET_CODE (insn) == JUMP_INSN)
2233: return 0;
2234: return 1;
2235: }
2236:
1.1.1.11 root 2237: /* Check that X is an insn-body for an `asm' with operands
2238: and that the operands mentioned in it are legitimate. */
2239:
2240: static int
2241: check_asm_operands (x)
2242: rtx x;
2243: {
2244: int noperands = asm_noperands (x);
2245: rtx *operands;
2246: int i;
2247:
2248: if (noperands < 0)
2249: return 0;
2250: if (noperands == 0)
2251: return 1;
2252:
2253: operands = (rtx *) alloca (noperands * sizeof (rtx));
2254: decode_asm_operands (x, operands, 0, 0, 0);
2255:
2256: for (i = 0; i < noperands; i++)
2257: if (!general_operand (operands[i], VOIDmode))
2258: return 0;
2259:
2260: return 1;
2261: }
2262:
1.1.1.2 root 2263: /* Concatenate the list of logical links of OINSN
1.1 root 2264: into INSN's list of logical links.
1.1.1.2 root 2265: Modifies OINSN destructively.
2266:
2267: If ALL_LINKS is nonzero, move all the links that OINSN has.
2268: Otherwise, move only those that point to insns that set regs
2269: that die in the insn OINSN.
2270: Other links are clobbered so that they are no longer effective. */
1.1 root 2271:
2272: static void
1.1.1.2 root 2273: add_links (insn, oinsn, all_links)
2274: rtx insn, oinsn;
2275: int all_links;
1.1 root 2276: {
1.1.1.2 root 2277: register rtx links = LOG_LINKS (oinsn);
2278: if (! all_links)
2279: {
2280: rtx tail;
2281: for (tail = links; tail; tail = XEXP (tail, 1))
2282: {
2283: rtx target = XEXP (tail, 0);
2284: if (GET_CODE (target) != INSN
2285: || GET_CODE (PATTERN (target)) != SET
2286: || GET_CODE (SET_DEST (PATTERN (target))) != REG
2287: || ! dead_or_set_p (oinsn, SET_DEST (PATTERN (target))))
2288: /* OINSN is going to become a NOTE
2289: so a link pointing there will have no effect. */
2290: XEXP (tail, 0) = oinsn;
2291: }
2292: }
1.1 root 2293: if (LOG_LINKS (insn) == 0)
2294: LOG_LINKS (insn) = links;
2295: else
2296: {
2297: register rtx next, prev = LOG_LINKS (insn);
2298: while (next = XEXP (prev, 1))
2299: prev = next;
2300: XEXP (prev, 1) = links;
2301: }
2302: }
1.1.1.7 root 2303:
2304: /* Delete any LOG_LINKS of INSN which point at OINSN. */
2305:
2306: static void
2307: remove_links (insn, oinsn)
2308: rtx insn, oinsn;
2309: {
2310: register rtx next = LOG_LINKS (insn), prev = 0;
2311: while (next)
2312: {
2313: if (XEXP (next, 0) == oinsn)
2314: {
2315: if (prev)
2316: XEXP (prev, 1) = XEXP (next, 1);
2317: else
2318: LOG_LINKS (insn) = XEXP (next, 1);
2319: }
2320: else
2321: prev = next;
2322: next = XEXP (next, 1);
2323: }
2324: }
1.1 root 2325:
2326: /* Concatenate the any elements of the list of reg-notes INCS
2327: which are of type REG_INC
2328: into INSN's list of reg-notes. */
2329:
2330: static void
2331: add_incs (insn, incs)
2332: rtx insn, incs;
2333: {
2334: register rtx tail;
2335:
2336: for (tail = incs; tail; tail = XEXP (tail, 1))
1.1.1.2 root 2337: if (REG_NOTE_KIND (tail) == REG_INC)
1.1 root 2338: REG_NOTES (insn)
2339: = gen_rtx (EXPR_LIST, REG_INC, XEXP (tail, 0), REG_NOTES (insn));
2340: }
1.1.1.7 root 2341:
2342: /* Remove register number REGNO from the dead registers list of INSN. */
2343:
2344: void
2345: remove_death (regno, insn)
2346: int regno;
2347: rtx insn;
2348: {
2349: register rtx link, next;
2350: while ((link = REG_NOTES (insn))
2351: && REG_NOTE_KIND (link) == REG_DEAD
2352: && REGNO (XEXP (link, 0)) == regno)
2353: REG_NOTES (insn) = XEXP (link, 1);
2354:
2355: if (link)
2356: while (next = XEXP (link, 1))
2357: {
2358: if (REG_NOTE_KIND (next) == REG_DEAD
2359: && REGNO (XEXP (next, 0)) == regno)
2360: XEXP (link, 1) = XEXP (next, 1);
2361: else
2362: link = next;
2363: }
2364: }
1.1 root 2365:
2366: /* For each register (hardware or pseudo) used within expression X,
2367: if its death is in an instruction with cuid
2368: between FROM_CUID (inclusive) and TO_INSN (exclusive),
2369: mark it as dead in TO_INSN instead.
2370:
2371: This is done when X is being merged by combination into TO_INSN. */
2372:
2373: static void
2374: move_deaths (x, from_cuid, to_insn)
2375: rtx x;
2376: int from_cuid;
2377: rtx to_insn;
2378: {
2379: register char *fmt;
2380: register int len, i;
2381: register enum rtx_code code = GET_CODE (x);
2382:
2383: if (code == REG)
2384: {
2385: register rtx where_dead = reg_last_death[REGNO (x)];
2386:
2387: if (where_dead && INSN_CUID (where_dead) >= from_cuid
2388: && INSN_CUID (where_dead) < INSN_CUID (to_insn))
2389: {
2390: remove_death (REGNO (x), reg_last_death[REGNO (x)]);
1.1.1.19! root 2391: if (! dead_or_partially_set_p (to_insn, x))
1.1 root 2392: REG_NOTES (to_insn)
2393: = gen_rtx (EXPR_LIST, REG_DEAD, x, REG_NOTES (to_insn));
2394: }
2395: return;
2396: }
2397:
2398: len = GET_RTX_LENGTH (code);
2399: fmt = GET_RTX_FORMAT (code);
2400:
2401: for (i = 0; i < len; i++)
2402: {
2403: if (fmt[i] == 'E')
2404: {
2405: register int j;
2406: for (j = XVECLEN (x, i) - 1; j >= 0; j--)
2407: move_deaths (XVECEXP (x, i, j), from_cuid, to_insn);
2408: }
2409: else if (fmt[i] == 'e')
2410: move_deaths (XEXP (x, i), from_cuid, to_insn);
2411: }
2412: }
2413:
1.1.1.7 root 2414: /* Like move_deaths, but deaths are moving both forward
2415: (from FROM_CUID to TO_INSN), and backwards
2416: (from FROM_INSN to TO_INSN). This is what happens
2417: when an insn is removed after applying the distributive law. */
2418:
2419: static void
2420: move_deaths_2 (x, from_cuid, from_insn, to_insn)
2421: rtx x;
2422: int from_cuid;
2423: rtx from_insn, to_insn;
2424: {
2425: register char *fmt;
2426: register int len, i;
2427: register enum rtx_code code = GET_CODE (x);
2428:
2429: if (code == REG)
2430: {
2431: register rtx where_dead = reg_last_death[REGNO (x)];
2432:
2433: if (where_dead && INSN_CUID (where_dead) >= from_cuid
2434: && INSN_CUID (where_dead) < INSN_CUID (to_insn))
2435: {
2436: remove_death (REGNO (x), reg_last_death[REGNO (x)]);
2437: if (! dead_or_set_p (to_insn, x))
2438: REG_NOTES (to_insn)
2439: = gen_rtx (EXPR_LIST, REG_DEAD, x, REG_NOTES (to_insn));
2440: }
2441: /* Can't use where_dead for from_insn because it has
2442: not been computed yet. */
2443: else if (dead_or_set_p (from_insn, x))
2444: {
2445: remove_death (REGNO (x), from_insn);
2446: if (! dead_or_set_p (to_insn, x))
2447: REG_NOTES (to_insn)
2448: = gen_rtx (EXPR_LIST, REG_DEAD, x, REG_NOTES (to_insn));
2449: }
2450: return;
2451: }
2452:
2453: len = GET_RTX_LENGTH (code);
2454: fmt = GET_RTX_FORMAT (code);
2455:
2456: for (i = 0; i < len; i++)
2457: {
2458: if (fmt[i] == 'E')
2459: {
2460: register int j;
2461: for (j = XVECLEN (x, i) - 1; j >= 0; j--)
2462: move_deaths_2 (XVECEXP (x, i, j), from_cuid, from_insn, to_insn);
2463: }
2464: else if (fmt[i] == 'e')
2465: move_deaths_2 (XEXP (x, i), from_cuid, from_insn, to_insn);
2466: }
2467: }
2468:
2469: /* The distrib combiner rewrites groups of insns so that optimizations
2470: can be more easily recognized. The front-end does not know how to
2471: group certain kinds of operations for efficient execution, and the
2472: resulting code can be quite poor. For example, on a machine without
2473: bitfield instructions, bitfield references look like
2474:
2475: (and (lshiftrt ... n) m)
2476:
2477: When combining two bitfield operations, such as with ||, this can
2478: yield code like
2479:
2480: (set z
2481: (or (and (lshiftrt x n) 1)
2482: (and (lshiftrt y n) 1)))
2483:
2484: which can be more efficiently executed as
2485:
2486: (set z
2487: (lshiftrt (and (or x y)
2488: (1 << m)) n))
2489:
2490: From there, the combiner attempts to rewrite the insns,
2491: keeping flow information accurate for later passes,
2492: and reducing the total number of insns executed.
2493:
2494: This function returns the point at which we should try
2495: looking for more simplifications. This will be before
2496: INSN if the call succeeds. We do not need to fear
2497: infinite loops, since this function is guaranteed to
2498: eliminate at least one (non-note) instruction if it returns
2499: successfully. */
2500:
2501: static rtx
2502: try_distrib (insn, xprev1, xprev2)
2503: rtx insn, xprev1, xprev2;
2504: {
2505: rtx pat = PATTERN (insn);
2506: rtx prev1, prev2, pat1, pat2, src1, src2;
2507: rtx to_prev, to_insn;
2508: enum rtx_code code;
1.1.1.9 root 2509: int insn_code_number, prev_code_number, regno;
1.1.1.7 root 2510: rtx new_insn_pat, new_prev_pat;
2511:
2512: distrib_attempts++;
2513:
2514: /* ??? Need to implement a test that PREV2 and PREV1
2515: are completely independent. Right now their
2516: recognition ability is sufficiently limited that
2517: it should not be necessary, but better safe than sorry. */
2518:
2519: /* Let PREV1 be the later of the two insns, and PREV2 the earlier. */
2520: if (INSN_CUID (xprev1) > INSN_CUID (xprev2))
2521: {
2522: prev1 = xprev1;
2523: prev2 = xprev2;
2524: }
2525: else
2526: {
2527: prev1 = xprev2;
2528: prev2 = xprev1;
2529: }
2530:
2531: pat1 = PATTERN (prev1);
2532: pat2 = PATTERN (prev2);
2533:
2534: /* First, see if INSN, PREV1, and PREV2 have patterns we can expect
2535: to simplify. */
2536:
2537: if (GET_CODE (pat) != SET
2538: || GET_CODE (pat1) != SET
2539: || GET_CODE (pat2) != SET)
2540: return 0;
2541:
2542: code = GET_CODE (SET_SRC (pat));
2543: src1 = SET_SRC (pat1);
2544: src2 = SET_SRC (pat2);
2545:
1.1.1.8 root 2546: if (GET_CODE (SET_DEST (pat1)) != REG
2547: || GET_CODE (SET_DEST (pat2)) != REG)
2548: return 0;
2549:
1.1.1.7 root 2550: switch (code)
2551: {
2552: default:
2553: return 0;
2554:
2555: case IOR:
2556: case AND:
2557: case XOR:
2558: case PLUS:
2559: ;
2560: }
2561:
1.1.1.8 root 2562: /* Insns PREV1 and PREV2 must provide the two operands of the arithmetic
2563: that is done in INSN. */
2564: if (! ((XEXP (SET_SRC (pat), 0) == SET_DEST (pat1)
2565: && XEXP (SET_SRC (pat), 1) == SET_DEST (pat2))
2566: ||
2567: (XEXP (SET_SRC (pat), 0) == SET_DEST (pat2)
2568: && XEXP (SET_SRC (pat), 1) == SET_DEST (pat1))))
2569: return 0;
2570:
2571: /* They must not be used in any other way in INSN.
2572: In particular, they must not be used in a result memory address. */
2573: if (reg_mentioned_p (SET_DEST (pat1), SET_DEST (pat))
2574: || reg_mentioned_p (SET_DEST (pat2), SET_DEST (pat)))
2575: return 0;
2576:
2577: /* Give up if the two operands' modes don't match. */
1.1.1.7 root 2578: if (GET_MODE (src1) != GET_MODE (src2))
2579: return 0;
2580:
2581: /* PREV1 and PREV2 must compute the same operation.
2582: Actually, there are other cases that could be handled,
2583: but are not implemented. For example:
2584:
2585: (set (reg:SI 94)
2586: (and:SI (reg:SI 73)
2587: (const_int 223)))
2588:
2589: (set (reg:SI 95)
2590: (zero_extend:SI (subreg:QI (reg:SI 91) 0)))
2591:
2592: (set (reg:SI 96)
2593: (ior:SI (reg:SI 94)
2594: (reg:SI 95)))
2595:
2596: In this case, we know that because (reg:SI 94) has
2597: been anded with 223, there is no need to zero_extend
2598: (reg:SI 91), and we could eliminate (reg:SI 95). */
2599:
2600: if (GET_CODE (src1) != GET_CODE (src2))
2601: return 0;
2602:
2603: /* The SETs in PREV1 and PREV2 do not need to be kept around. */
2604:
2605: undobuf.num_undo = 0;
2606: undobuf.storage = 0;
2607:
2608: /* Substitute in the latest insn for the regs set by the earlier ones. */
2609: subst_insn = insn;
2610: n_occurrences = 0; /* `subst' counts here */
2611:
2612: switch (GET_CODE (src1))
2613: {
1.1.1.14 root 2614: /* case XOR: Does not distribute through anything! */
1.1.1.7 root 2615: case LSHIFTRT:
2616: case ASHIFTRT:
1.1.1.9 root 2617: /* Right-shift can't distribute through addition
2618: since the round-off would happen differently. */
2619: case AND:
2620: case IOR:
2621: /* Boolean ops don't distribute through addition. */
1.1.1.7 root 2622: if (code == PLUS)
2623: return 0;
1.1.1.18 root 2624: goto do_distrib;
1.1.1.7 root 2625:
2626: case LSHIFT:
2627: case ASHIFT:
1.1.1.9 root 2628: /* Left shifts are multiplication; they distribute through
2629: addition. Also, since they work bitwise, they
2630: distribute through boolean operations. */
1.1.1.18 root 2631: #ifdef NEGATIVE_SHIFT_COUNTS
2632: /* Negative count is really a right-shift. */
2633: if (NEGATIVE_SHIFT_COUNTS
2634: && code == PLUS
2635: && !(GET_CODE (XEXP (src1, 1))
2636: == CONST_INT && INTVAL (XEXP (src1, 1)) >= 0))
2637: return 0;
2638: #endif
1.1.1.9 root 2639: goto do_distrib;
2640:
2641: case MULT:
2642: /* Multiplication distributes through addition only. */
2643: if (code != PLUS)
2644: return 0;
2645:
2646: do_distrib:
1.1.1.7 root 2647: if (GET_CODE (XEXP (src1, 1)) != CONST_INT
2648: || GET_CODE (XEXP (src2, 1)) != CONST_INT
2649: || INTVAL (XEXP (src1, 1)) != INTVAL (XEXP (src2, 1)))
2650: return 0;
1.1.1.16 root 2651:
2652: /* Give up if we would move a use of a reg across an alteration.
2653: Note this is unnecessarily conservative, since a problem really
2654: happens only if this reg is set *between* PREV2 and PREV1
2655: But this test is easier. */
2656: if (use_crosses_set_p (XEXP (src2, 0), INSN_CUID (prev2)))
2657: return 0;
2658:
2659: /* Try changing (+ (* x c) (* y c)) to (* (+ x y) c). */
1.1.1.7 root 2660: to_prev = gen_rtx (code, GET_MODE (src1),
2661: XEXP (src1, 0), XEXP (src2, 0));
2662: to_insn = gen_rtx (GET_CODE (src1), GET_MODE (src1), SET_DEST (pat1), XEXP (src1, 1));
2663: break;
2664:
2665: case ZERO_EXTEND:
2666: case SIGN_EXTEND:
1.1.1.9 root 2667: /* Extension can't distribute through addition;
2668: the carries could be changed. */
2669: if (code == PLUS)
2670: return 0;
1.1.1.7 root 2671: {
2672: rtx inner1 = XEXP (src1, 0), inner2 = XEXP (src2, 0);
2673: int subreg_needed = 0;
2674:
1.1.1.16 root 2675: /* Try changing (& (extend x) (extend y)) to (extend (& x y)). */
1.1.1.7 root 2676: /* But keep extend insns together with their subregs. */
2677: if (GET_CODE (inner1) == SUBREG)
1.1.1.16 root 2678: {
2679: if (SUBREG_WORD (inner1) != 0)
2680: return 0;
2681: else
2682: {
2683: subreg_needed = 1;
2684: inner1 = SUBREG_REG (inner1);
2685: }
2686: }
1.1.1.7 root 2687:
2688: if (GET_CODE (inner2) == SUBREG)
1.1.1.16 root 2689: {
2690: if (SUBREG_WORD (inner2) != 0)
2691: return 0;
2692: else
2693: {
2694: subreg_needed = 1;
2695: inner2 = SUBREG_REG (inner2);
2696: }
2697: }
2698:
2699: /* Give up if we would move a use of a reg across an alteration.
2700: Note this is unnecessarily conservative, since a problem really
2701: happens only if this reg is set *between* PREV2 and PREV1
2702: But this test is easier. */
2703: if (use_crosses_set_p (inner2, INSN_CUID (prev2)))
2704: return 0;
1.1.1.7 root 2705:
2706: to_prev = gen_rtx (code, GET_MODE (src1), inner1, inner2);
2707: to_insn = gen_rtx (GET_CODE (src1), GET_MODE (src1),
2708: subreg_needed
2709: ? gen_rtx (SUBREG, GET_MODE (XEXP (src1, 0)),
2710: SET_DEST (pat1), 0)
2711: : SET_DEST (pat1));
2712: }
2713: break;
2714:
2715: default:
2716: return 0;
2717: }
2718:
2719: /* Are the results of this "substitution" a valid instruction? */
2720:
2721: new_insn_pat = subst (PATTERN (insn), SET_SRC (PATTERN (insn)), to_insn);
2722: distrib_merges_1++;
2723:
2724: insn_code_number = recog (new_insn_pat, insn);
2725: if (insn_code_number < 0)
2726: {
2727: undo_all ();
2728: return 0;
2729: }
2730:
2731: subst_insn = prev1;
2732: new_prev_pat = subst (pat1, src1, to_prev);
2733: distrib_merges_2++;
2734:
2735: prev_code_number = recog (new_prev_pat, prev1);
2736: if (prev_code_number < 0)
2737: {
2738: undo_all ();
2739: return 0;
2740: }
2741:
2742: /* Everything worked; install the new patterns. */
2743: INSN_CODE (insn) = insn_code_number;
2744: PATTERN (insn) = new_insn_pat;
2745:
2746: INSN_CODE (prev1) = prev_code_number;
2747: PATTERN (prev1) = new_prev_pat;
2748:
2749: /* Need to change LOG_LINKS around...PREV1 now gets
2750: whatever flowed into PREV2. PREV2 is going to
2751: become a NOTE, so we clear out its LOG_LINKS. */
2752: remove_links (insn, prev2);
2753: add_links (prev1, prev2, adjacent_insns_p (prev2, prev1));
2754:
2755: /* Registers which died in PREV2 now die in PREV1.
2756: Also, registers born in PREV2 dying in INSN now die in PREV1. */
2757: move_deaths_2 (src2, INSN_CUID (prev2), insn, prev1);
2758:
2759: regno = REGNO (SET_DEST (pat2));
2760:
2761: reg_n_sets[regno]--;
2762: if (reg_n_sets[regno] == 0
2763: && ! (basic_block_live_at_start[0][regno / HOST_BITS_PER_INT]
2764: & (1 << (regno % HOST_BITS_PER_INT))))
2765: reg_n_refs[regno] = 0;
2766: remove_death (regno, insn);
2767:
2768: PUT_CODE (prev2, NOTE);
2769: NOTE_LINE_NUMBER (prev2) = NOTE_INSN_DELETED;
2770: NOTE_SOURCE_FILE (prev2) = 0;
2771:
2772: distrib_successes++;
2773: return prev1;
2774: }
2775:
1.1.1.2 root 2776: void
1.1 root 2777: dump_combine_stats (file)
1.1.1.15 root 2778: FILE *file;
1.1 root 2779: {
2780: fprintf
2781: (file,
1.1.1.7 root 2782: ";; Combiner statistics: %d attempts, %d substitutions (%d requiring new space),\n;; %d successes.\n\n",
2783: combine_attempts, combine_merges, combine_extras, combine_successes);
2784: fprintf
2785: (file,
2786: ";; Distributer statistics: %d attempts, %d:%d substitutions,\n;; %d successes.\n\n",
2787: distrib_attempts, distrib_merges_1,
2788: distrib_merges_2, distrib_successes);
1.1 root 2789: }
2790:
1.1.1.2 root 2791: void
1.1 root 2792: dump_combine_total_stats (file)
1.1.1.15 root 2793: FILE *file;
1.1 root 2794: {
2795: fprintf
2796: (file,
2797: "\n;; Combiner totals: %d attempts, %d substitutions (%d requiring new space),\n;; %d successes.\n",
2798: total_attempts, total_merges, total_extras, total_successes);
1.1.1.7 root 2799: fprintf
2800: (file,
2801: "\n;; Distributer totals: %d attempts, %d:%d substitutions,\n;; %d successes.\n",
2802: total_distrib_attempts, total_distrib_merges_1,
2803: total_distrib_merges_2, total_distrib_successes);
1.1 root 2804: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.