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