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