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