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