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