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