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