|
|
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;
82:
83: /* Number of attempts that got as far as substitution in this function. */
84:
85: static int combine_merges;
86:
87: /* Number of instructions combined with added SETs in this function. */
88:
89: static int combine_extras;
90:
91: /* Number of instructions combined in this function. */
92:
93: static int combine_successes;
94:
95: /* Totals over entire compilation. */
96:
97: static int total_attempts, total_merges, total_extras, total_successes;
98:
99:
100: /* Vector mapping INSN_UIDs to cuids.
101: The cuids are like uids but increase monononically always.
102: Combine always uses cuids so that it can compare them.
103: But actually renumbering the uids, which we used to do,
104: proves to be a bad idea because it makes it hard to compare
105: the dumps produced by earlier passes with those from later passes. */
106:
107: static short *uid_cuid;
108:
109: /* Get the cuid of an insn. */
110:
111: #define INSN_CUID(INSN) (uid_cuid[INSN_UID (INSN)])
112:
113:
114: /* Record last point of death of (hard or pseudo) register n. */
115:
116: static rtx *reg_last_death;
117:
118: /* Record last point of modification of (hard or pseudo) register n. */
119:
120: static rtx *reg_last_set;
121:
122: /* Record the cuid of the last insn that invalidated memory
123: (anything that writes memory, and subroutine calls). */
124:
125: static int mem_last_set;
126:
127: /* Record the cuid of the last CALL_INSN
128: so we can tell whether a potential combination crosses any calls. */
129:
130: static int last_call_cuid;
131:
132: /* When `subst' is called, this is the insn that is being modified
133: (by combining in a previous insn). The PATTERN of this insn
134: is still the old pattern partially modified and it should not be
135: looked at, but this may be used to examine the successors of the insn
136: to judge whether a simplification is valid. */
137:
138: static rtx subst_insn;
139:
140: /* Record one modification to rtl structure
141: to be undone by storing old_contents into *where. */
142:
143: struct undo
144: {
145: rtx *where;
146: rtx old_contents;
147: };
148:
149: /* Record a bunch of changes to be undone, up to MAX_UNDO of them.
150: num_undo says how many are currently recorded.
151: storage is nonzero if we must undo the allocation of new storage.
152: The value of storage is what to pass to obfree. */
153:
154: #define MAX_UNDO 10
155:
156: struct undobuf
157: {
158: int num_undo;
159: char *storage;
160: struct undo undo[MAX_UNDO];
161: };
162:
163: static struct undobuf undobuf;
164:
1.1.1.2 root 165: /* Number of times the pseudo being substituted for
166: was found and replaced. */
167:
168: static int n_occurrences;
169:
1.1 root 170: static void move_deaths ();
1.1.1.4 root 171: void remove_death ();
1.1 root 172: static void record_dead_and_set_regs ();
173: int regno_dead_p ();
174: static int use_crosses_set_p ();
1.1.1.4 root 175: static int try_combine ();
1.1 root 176: static rtx subst ();
177: static void undo_all ();
1.1.1.2 root 178: static void copy_substitutions ();
1.1 root 179: static void add_links ();
180: static void add_incs ();
1.1.1.2 root 181: static int insn_has_inc_p ();
1.1 root 182: static int adjacent_insns_p ();
183: static rtx simplify_and_const_int ();
184: static rtx gen_lowpart_for_combine ();
185: static void simplify_set_cc0_and ();
186:
187: /* Main entry point for combiner. F is the first insn of the function.
188: NREGS is the first unused pseudo-reg number. */
189:
190: void
191: combine_instructions (f, nregs)
192: rtx f;
193: int nregs;
194: {
195: register rtx insn;
196: register int i;
197: register rtx links, nextlinks;
198: rtx prev;
199:
200: combine_attempts = 0;
201: combine_merges = 0;
202: combine_extras = 0;
203: combine_successes = 0;
204:
205: reg_last_death = (rtx *) alloca (nregs * sizeof (rtx));
206: reg_last_set = (rtx *) alloca (nregs * sizeof (rtx));
207: bzero (reg_last_death, nregs * sizeof (rtx));
208: bzero (reg_last_set, nregs * sizeof (rtx));
209:
210: init_recog ();
211:
212: /* Compute maximum uid value so uid_cuid can be allocated. */
213:
214: for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
215: if (INSN_UID (insn) > i)
216: i = INSN_UID (insn);
217:
218: uid_cuid = (short *) alloca ((i + 1) * sizeof (short));
219:
220: /* Compute the mapping from uids to cuids.
221: Cuids are numbers assigned to insns, like uids,
222: except that cuids increase monotonically through the code. */
223:
224: for (insn = f, i = 0; insn; insn = NEXT_INSN (insn))
225: INSN_CUID (insn) = ++i;
226:
227: /* Now scan all the insns in forward order. */
228:
229: last_call_cuid = 0;
230: mem_last_set = 0;
231: prev = 0;
232:
233: for (insn = f; insn; insn = NEXT_INSN (insn))
234: {
235: if (GET_CODE (insn) == INSN
236: || GET_CODE (insn) == CALL_INSN
237: || GET_CODE (insn) == JUMP_INSN)
238: {
239: retry:
240: /* Try this insn with each insn it links back to. */
241:
242: for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
243: if (try_combine (insn, XEXP (links, 0), 0))
244: goto retry;
245:
246: /* Try each sequence of three linked insns ending with this one. */
247:
248: for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
249: if (GET_CODE (XEXP (links, 0)) != NOTE)
250: for (nextlinks = LOG_LINKS (XEXP (links, 0)); nextlinks;
251: nextlinks = XEXP (nextlinks, 1))
252: if (try_combine (insn, XEXP (links, 0), XEXP (nextlinks, 0)))
253: goto retry;
254:
255: /* Try to combine a jump insn that uses CC0
256: with a preceding insn that sets CC0, and maybe with its
257: logical predecessor as well.
258: This is how we make decrement-and-branch insns.
259: We need this special code because data flow connections
260: via CC0 do not get entered in LOG_LINKS. */
261:
262: if (GET_CODE (insn) == JUMP_INSN
263: && prev != 0
264: && GET_CODE (prev) == INSN
265: && GET_CODE (PATTERN (prev)) == SET
266: && GET_CODE (SET_DEST (PATTERN (prev))) == CC0)
267: {
268: if (try_combine (insn, prev, 0))
269: goto retry;
270:
271: if (GET_CODE (prev) != NOTE)
272: for (nextlinks = LOG_LINKS (prev); nextlinks;
273: nextlinks = XEXP (nextlinks, 1))
274: if (try_combine (insn, prev, XEXP (nextlinks, 0)))
275: goto retry;
276: }
277: #if 0
278: /* Turned off because on 68020 it takes four insns to make
279: something like (a[b / 32] & (1 << (31 - (b % 32)))) != 0
280: that could actually be optimized, and that's an unlikely piece of code. */
281: /* If an insn gets or sets a bit field, try combining it
282: with two different insns whose results it uses. */
283: if (GET_CODE (insn) == INSN
284: && GET_CODE (PATTERN (insn)) == SET
285: && (GET_CODE (SET_DEST (PATTERN (insn))) == ZERO_EXTRACT
286: || GET_CODE (SET_DEST (PATTERN (insn))) == SIGN_EXTRACT
287: || GET_CODE (SET_SRC (PATTERN (insn))) == ZERO_EXTRACT
288: || GET_CODE (SET_SRC (PATTERN (insn))) == SIGN_EXTRACT))
289: {
290: for (links = LOG_LINKS (insn); links; links = XEXP (links, 1))
291: if (GET_CODE (XEXP (links, 0)) != NOTE)
292: for (nextlinks = XEXP (links, 1); nextlinks;
293: nextlinks = XEXP (nextlinks, 1))
294: if (try_combine (insn, XEXP (links, 0), XEXP (nextlinks, 0)))
295: goto retry;
296: }
297: #endif
298: record_dead_and_set_regs (insn);
299: prev = insn;
300: }
301: else if (GET_CODE (insn) != NOTE)
302: prev = 0;
303: }
304: total_attempts += combine_attempts;
305: total_merges += combine_merges;
306: total_extras += combine_extras;
307: total_successes += combine_successes;
308: }
309:
310: /* Try to combine the insns I1 and I2 into I3.
311: Here I1 appears earlier than I2, which is earlier than I3.
312: I1 can be zero; then we combine just I2 into I3.
313:
314: Return 1 if successful; if that happens, I1 and I2 are pseudo-deleted
315: by turning them into NOTEs, and I3 is modified.
316: Return 0 if the combination does not work. Then nothing is changed. */
317:
318: static int
319: try_combine (i3, i2, i1)
320: register rtx i3, i2, i1;
321: {
322: register rtx newpat;
323: int added_sets_1 = 0;
324: int added_sets_2 = 0;
325: int total_sets;
326: int i2_is_used;
327: register rtx link;
328: int insn_code_number;
329: int recog_flags = 0;
330: rtx i2dest, i2src;
331: rtx i1dest, i1src;
1.1.1.2 root 332: int maxreg;
1.1 root 333:
334: combine_attempts++;
335:
336: /* Don't combine with something already used up by combination. */
337:
338: if (GET_CODE (i2) == NOTE
339: || (i1 && GET_CODE (i1) == NOTE))
340: return 0;
341:
342: /* Don't combine across a CALL_INSN, because that would possibly
343: change whether the life span of some REGs crosses calls or not,
344: and it is a pain to update that information. */
345:
346: if (INSN_CUID (i2) < last_call_cuid
347: || (i1 && INSN_CUID (i1) < last_call_cuid))
348: return 0;
349:
350: /* Can combine only if previous insn is a SET of a REG, a SUBREG or CC0.
351: That REG must be either set or dead by the final instruction
352: (so that we can safely forget about setting it).
353: Also test use_crosses_set_p to make sure that the value
354: that is to be substituted for the register
355: does not use any registers whose values alter in between.
356: Do not try combining with moves from one register to another
357: since it is better to let them be tied by register allocation.
1.1.1.2 root 358: (There is a switch to permit such combination; except the insns
359: that copy a function value into another register are never combined
360: because moving that too far away from the function call could cause
361: something else to be stored in that register in the interim.)
1.1 root 362:
363: A set of a SUBREG is considered as if it were a set from
364: SUBREG. Thus, (SET (SUBREG:X (REG:Y...)) (something:X...))
365: is handled by substituting (SUBREG:Y (something:X...)) for (REG:Y...). */
366:
367: if (GET_CODE (PATTERN (i2)) != SET)
368: return 0;
369: i2dest = SET_DEST (PATTERN (i2));
370: i2src = SET_SRC (PATTERN (i2));
371: if (GET_CODE (i2dest) == SUBREG)
372: {
373: i2dest = SUBREG_REG (i2dest);
374: i2src = gen_rtx (SUBREG, GET_MODE (i2dest), i2src, 0);
375: }
1.1.1.4 root 376: /* Don't eliminate a store in the stack pointer. */
377: if (i2dest == stack_pointer_rtx)
378: return 0;
1.1 root 379: if (GET_CODE (i2dest) != CC0
380: && (GET_CODE (i2dest) != REG
1.1.1.2 root 381: || (GET_CODE (i2src) == REG
382: && (!flag_combine_regs
1.1.1.5 ! root 383: /* Don't substitute a function value reg for any other. */
! 384: || FUNCTION_VALUE_REGNO_P (REGNO (i2src))
! 385: /* Don't substitute a different reg into an increment. */
! 386: || find_reg_note (i3, REG_INC, i2dest)))
1.1.1.2 root 387: || GET_CODE (i2src) == CALL
1.1 root 388: || use_crosses_set_p (i2src, INSN_CUID (i2))))
389: return 0;
390:
391: if (i1 != 0)
392: {
393: if (GET_CODE (PATTERN (i1)) != SET)
394: return 0;
395: i1dest = SET_DEST (PATTERN (i1));
396: i1src = SET_SRC (PATTERN (i1));
397: if (GET_CODE (i1dest) == SUBREG)
398: {
399: i1dest = SUBREG_REG (i1dest);
400: i1src = gen_rtx (SUBREG, GET_MODE (i1dest), i1src, 0);
401: }
1.1.1.4 root 402: if (i1dest == stack_pointer_rtx)
403: return 0;
1.1 root 404: if (GET_CODE (i1dest) != CC0
405: && (GET_CODE (i1dest) != REG
1.1.1.2 root 406: || (GET_CODE (i1src) == REG
407: && (!flag_combine_regs
1.1.1.5 ! root 408: || FUNCTION_VALUE_REGNO_P (REGNO (i1src))
! 409: || find_reg_note (i3, REG_INC, i1dest)
! 410: || find_reg_note (i2, REG_INC, i1dest)))
1.1.1.2 root 411: || GET_CODE (i1src) == CALL
1.1 root 412: || use_crosses_set_p (i1src, INSN_CUID (i1))))
413: return 0;
414: }
415:
416: /* If I1 or I2 contains an autoincrement or autodecrement,
417: make sure that register is not used between there and I3.
418: Also insist that I3 not be a jump; if it were one
419: and the incremented register were spilled, we would lose. */
1.1.1.5 ! root 420: for (link = REG_NOTES (i2); link; link = XEXP (link, 1))
! 421: if (REG_NOTE_KIND (link) == REG_INC
! 422: && (GET_CODE (i3) == JUMP_INSN
! 423: || reg_used_between_p (XEXP (link, 0), i2, i3)
! 424: || reg_mentioned_p (XEXP (link, 0), i3)))
! 425: return 0;
1.1 root 426:
1.1.1.5 ! root 427: if (i1)
! 428: for (link = REG_NOTES (i1); link; link = XEXP (link, 1))
! 429: if (REG_NOTE_KIND (link) == REG_INC
! 430: && (GET_CODE (i3) == JUMP_INSN
! 431: || reg_used_between_p (XEXP (link, 0), i1, i3)
! 432: || reg_mentioned_p (XEXP (link, 0), i3)))
! 433: return 0;
1.1 root 434:
435: /* See if the SETs in i1 or i2 need to be kept around in the merged
436: instruction: whenever the value set there is still needed past i3. */
437: added_sets_2 = (GET_CODE (i2dest) != CC0
438: && ! dead_or_set_p (i3, i2dest));
439: if (i1)
440: added_sets_1 = ! (dead_or_set_p (i3, i1dest)
441: || dead_or_set_p (i2, i1dest));
442:
443: combine_merges++;
444:
445: undobuf.num_undo = 0;
446: undobuf.storage = 0;
447:
448: /* Substitute in the latest insn for the regs set by the earlier ones. */
449:
1.1.1.2 root 450: maxreg = max_reg_num ();
451:
1.1 root 452: subst_insn = i3;
1.1.1.2 root 453: n_occurrences = 0; /* `subst' counts here */
454:
1.1 root 455: newpat = subst (PATTERN (i3), i2dest, i2src);
456: /* Record whether i2's body now appears within i3's body. */
1.1.1.2 root 457: i2_is_used = n_occurrences;
1.1 root 458:
459: if (i1)
1.1.1.2 root 460: {
461: n_occurrences = 0;
462: newpat = subst (newpat, i1dest, i1src);
463: }
1.1 root 464:
465: if (GET_CODE (PATTERN (i3)) == SET
466: && SET_DEST (PATTERN (i3)) == cc0_rtx
1.1.1.2 root 467: && (GET_CODE (SET_SRC (PATTERN (i3))) == AND
468: || GET_CODE (SET_SRC (PATTERN (i3))) == LSHIFTRT)
1.1 root 469: && next_insn_tests_no_inequality (i3))
470: simplify_set_cc0_and (i3);
471:
1.1.1.2 root 472: if (max_reg_num () != maxreg)
473: abort ();
474:
1.1 root 475: /* If the actions of the earler insns must be kept
476: in addition to substituting them into the latest one,
477: we must make a new PARALLEL for the latest insn
478: to hold additional the SETs. */
479:
480: if (added_sets_1 || added_sets_2)
481: {
482: combine_extras++;
483:
484: /* Arrange to free later what we allocate now
485: if we don't accept this combination. */
486: if (!undobuf.storage)
487: undobuf.storage = (char *) oballoc (0);
488:
489: if (GET_CODE (newpat) == PARALLEL)
490: {
1.1.1.2 root 491: rtvec old = XVEC (newpat, 0);
1.1 root 492: total_sets = XVECLEN (newpat, 0) + added_sets_1 + added_sets_2;
1.1.1.2 root 493: newpat = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (total_sets));
494: bcopy (&old->elem[0], &XVECEXP (newpat, 0, 0),
495: sizeof (old->elem[0]) * old->num_elem);
1.1 root 496: }
497: else
498: {
1.1.1.2 root 499: rtx old = newpat;
1.1 root 500: total_sets = 1 + added_sets_1 + added_sets_2;
1.1.1.2 root 501: newpat = gen_rtx (PARALLEL, VOIDmode, rtvec_alloc (total_sets));
502: XVECEXP (newpat, 0, 0) = old;
1.1 root 503: }
504: if (added_sets_1)
505: {
506: XVECEXP (newpat, 0, --total_sets) = PATTERN (i1);
507: }
508: if (added_sets_2)
509: {
510: /* If there is no I1, use I2's body as is. */
511: if (i1 == 0
512: /* If I2 was stuck into I3, then anything within it has
513: already had I1 substituted into it when that was done to I3. */
514: || i2_is_used)
515: {
516: XVECEXP (newpat, 0, --total_sets) = PATTERN (i2);
517: }
518: else
519: XVECEXP (newpat, 0, --total_sets)
520: = subst (PATTERN (i2), i1dest, i1src);
521: }
522: }
523:
1.1.1.2 root 524: /* Fail if an autoincrement side-effect has been duplicated. */
525: if ((i2_is_used > 1 && find_reg_note (i2, REG_INC, 0) != 0)
526: || (i1 != 0 && n_occurrences > 1 && find_reg_note (i1, REG_INC, 0) != 0))
527: {
528: undo_all ();
529: return 0;
530: }
531:
1.1 root 532: /* Is the result of combination a valid instruction? */
533: insn_code_number = recog (newpat, i3);
534:
535: if (insn_code_number >= 0)
536: {
537: /* Yes. Install it. */
538: register int regno;
539: INSN_CODE (i3) = insn_code_number;
540: PATTERN (i3) = newpat;
1.1.1.2 root 541: /* If anything was substituted more than once,
542: copy it to avoid invalid shared rtl structure. */
543: copy_substitutions ();
544: /* The data flowing into I2 now flows into I3.
545: But we cannot always move all of I2's LOG_LINKS into I3,
546: since they must go to a setting of a REG from the
547: first use following. If I2 was the first use following a set,
548: I3 is now a use, but it is not the first use
549: if some instruction between I2 and I3 is also a use.
550: Here, for simplicity, we move all the links only if
551: there are no real insns between I2 and I3.
552: Otherwise, we move only links that correspond to regs
553: that used to die in I2. They are always safe to move. */
554: add_links (i3, i2, adjacent_insns_p (i2, i3));
1.1 root 555: /* Most REGs that previously died in I2 now die in I3. */
556: move_deaths (i2src, INSN_CUID (i2), i3);
557: if (GET_CODE (i2dest) == REG)
558: {
559: /* If the reg formerly set in I2 died only once and that was in I3,
560: zero its use count so it won't make `reload' do any work. */
561: regno = REGNO (i2dest);
562: if (! added_sets_2)
1.1.1.2 root 563: {
564: reg_n_sets[regno]--;
565: /* Used to check && regno_dead_p (regno, i3) also here. */
566: if (reg_n_sets[regno] == 0
567: && ! (basic_block_live_at_start[0][regno / HOST_BITS_PER_INT]
568: & (1 << (regno % HOST_BITS_PER_INT))))
569: reg_n_refs[regno] = 0;
570: }
1.1 root 571: /* If a ref to REGNO was substituted into I3 from I2,
572: then it still dies there if it previously did.
573: Otherwise either REGNO never did die in I3 so remove_death is safe
574: or this entire life of REGNO is gone so remove its death. */
575: if (!added_sets_2
576: && ! reg_mentioned_p (i2dest, PATTERN (i3)))
577: remove_death (regno, i3);
578: }
579: /* Any registers previously autoincremented in I2
580: are now incremented in I3. */
581: add_incs (i3, REG_NOTES (i2));
582: if (i1)
583: {
584: /* Likewise, merge the info from I1 and get rid of it. */
1.1.1.2 root 585: add_links (i3, i1,
586: adjacent_insns_p (i1, i2) && adjacent_insns_p (i2, i3));
1.1 root 587: move_deaths (i1src, INSN_CUID (i1), i3);
588: if (GET_CODE (i1dest) == REG)
589: {
590: regno = REGNO (i1dest);
591: if (! added_sets_1)
1.1.1.2 root 592: {
593: reg_n_sets[regno]--;
594: /* Used to also check && regno_dead_p (regno, i3) here. */
595:
596: if (reg_n_sets[regno] == 0
597: && ! (basic_block_live_at_start[0][regno / HOST_BITS_PER_INT]
598: & (1 << (regno % HOST_BITS_PER_INT))))
599:
600: reg_n_refs[regno] = 0;
601: }
1.1 root 602: /* If a ref to REGNO was substituted into I3 from I1,
603: then it still dies there if it previously did.
604: Else 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_1
607: && ! reg_mentioned_p (i1dest, PATTERN (i3)))
608: remove_death (regno, i3);
609: }
610: add_incs (i3, REG_NOTES (i1));
611: LOG_LINKS (i1) = 0;
612: PUT_CODE (i1, NOTE);
613: NOTE_LINE_NUMBER (i1) = NOTE_INSN_DELETED;
614: NOTE_SOURCE_FILE (i1) = 0;
615: }
1.1.1.2 root 616: /* Get rid of I2. */
617: LOG_LINKS (i2) = 0;
618: PUT_CODE (i2, NOTE);
619: NOTE_LINE_NUMBER (i2) = NOTE_INSN_DELETED;
620: NOTE_SOURCE_FILE (i2) = 0;
1.1 root 621:
622: combine_successes++;
623: return 1;
624: }
625:
626: /* Failure: change I3 back the way it was. */
627: undo_all ();
628:
629: return 0;
630: }
631:
632: /* Undo all the modifications recorded in undobuf. */
633:
634: static void
635: undo_all ()
636: {
637: register int i;
638: if (undobuf.num_undo > MAX_UNDO)
639: undobuf.num_undo = MAX_UNDO;
640: for (i = undobuf.num_undo - 1; i >= 0; i--)
641: *undobuf.undo[i].where = undobuf.undo[i].old_contents;
642: if (undobuf.storage)
643: obfree (undobuf.storage);
644: undobuf.num_undo = 0;
645: undobuf.storage = 0;
646: }
647:
1.1.1.2 root 648: /* If this insn had more than one substitution,
649: copy all but one, so that no invalid shared substructure is introduced. */
650:
651: static void
652: copy_substitutions ()
653: {
654: register int i;
655: if (undobuf.num_undo > 1)
656: {
657: for (i = undobuf.num_undo - 1; i >= 1; i--)
658: *undobuf.undo[i].where = copy_rtx (*undobuf.undo[i].where);
659: }
660: }
661:
1.1 root 662: /* Throughout X, replace FROM with TO, and return the result.
663: The result is TO if X is FROM;
664: otherwise the result is X, but its contents may have been modified.
665: If they were modified, a record was made in undobuf so that
666: undo_all will (among other things) return X to its original state.
667:
668: If the number of changes necessary is too much to record to undo,
669: the excess changes are not made, so the result is invalid.
670: The changes already made can still be undone.
671: undobuf.num_undo is incremented for such changes, so by testing that
1.1.1.2 root 672: the caller can tell whether the result is valid.
673:
674: `n_occurrences' is incremented each time FROM is replaced. */
1.1 root 675:
676: static rtx
677: subst (x, from, to)
678: register rtx x, from, to;
679: {
680: register char *fmt;
681: register int len, i;
682: register enum rtx_code code;
1.1.1.2 root 683: char was_replaced[2];
1.1 root 684:
1.1.1.2 root 685: #define SUBST(INTO, NEWVAL) \
686: do { if (undobuf.num_undo < MAX_UNDO) \
687: { \
688: undobuf.undo[undobuf.num_undo].where = &INTO; \
689: undobuf.undo[undobuf.num_undo].old_contents = INTO; \
690: INTO = NEWVAL; \
691: } \
692: undobuf.num_undo++; } while (0)
693:
694: /* FAKE_EXTEND_SAFE_P (MODE, FROM) is 1 if (subreg:MODE FROM 0) is a safe
695: replacement for (zero_extend:MODE FROM) or (sign_extend:MODE FROM).
696: If it is 0, that cannot be done because it might cause a badly aligned
697: memory reference. */
698:
1.1.1.3 root 699: /* Now we never do this for memory refs, because of the danger of
700: turning a reference to the last byte on a page into a page-crossing
701: reference that could get a spurious fault. It could be done safely
702: for certain cases but it's hard to check for them. */
703: #if 0
1.1.1.2 root 704: #define FAKE_EXTEND_SAFE_P(MODE, FROM) \
705: (GET_CODE (FROM) == REG || \
706: (GET_CODE (FROM) == MEM \
707: && offsetable_address_p ((MODE), XEXP ((FROM), 0)) \
708: && ! mode_dependent_address_p ((XEXP ((FROM), 0)))))
709: #else
710: #define FAKE_EXTEND_SAFE_P(MODE, FROM) (GET_CODE (FROM) == REG)
711: #endif
1.1 root 712:
713: if (x == from)
714: return to;
715:
1.1.1.2 root 716: /* It is possible to have a subexpression appear twice in the insn.
717: Suppose that FROM is a register that appears within TO.
718: Then, after that subexpression has been scanned once by `subst',
719: the second time it is scanned, TO may be found. If we were
720: to scan TO here, we would find FROM within it and create a
721: self-referent rtl structure which is completely wrong. */
722: if (x == to)
723: return to;
724:
1.1 root 725: code = GET_CODE (x);
726:
727: /* A little bit of algebraic simplification here. */
728: switch (code)
729: {
730: /* This case has no effect except to speed things up. */
731: case REG:
732: case CONST_INT:
733: case CONST:
734: case SYMBOL_REF:
735: case LABEL_REF:
736: case PC:
737: case CC0:
738: return x;
1.1.1.2 root 739: }
740:
741: was_replaced[0] = 0;
742: was_replaced[1] = 0;
743:
744: len = GET_RTX_LENGTH (code);
745: fmt = GET_RTX_FORMAT (code);
746:
747: /* Don't replace FROM where it is being stored in rather than used. */
748: if (code == SET && SET_DEST (x) == from)
749: fmt = "ie";
750: if (code == SET && GET_CODE (SET_DEST (x)) == SUBREG
751: && SUBREG_REG (SET_DEST (x)) == from)
752: fmt = "ie";
753:
754: for (i = 0; i < len; i++)
755: {
756: if (fmt[i] == 'E')
757: {
758: register int j;
759: for (j = XVECLEN (x, i) - 1; j >= 0; j--)
760: {
761: register rtx new;
762: if (XVECEXP (x, i, j) == from)
763: new = to, n_occurrences++;
764: else
765: new = subst (XVECEXP (x, i, j), from, to);
766: if (new != XVECEXP (x, i, j))
767: SUBST (XVECEXP (x, i, j), new);
768: }
769: }
770: else if (fmt[i] == 'e')
771: {
772: register rtx new;
773:
774: if (XEXP (x, i) == from)
775: {
776: new = to;
777: n_occurrences++;
778: if (i < 2)
779: was_replaced[i] = 1;
780: }
781: else
782: new = subst (XEXP (x, i), from, to);
783:
784: if (new != XEXP (x, i))
785: SUBST (XEXP (x, i), new);
786: }
787: }
788:
789: /* A little bit of algebraic simplification here. */
790: switch (code)
791: {
792: case SUBREG:
793: /* Changing mode twice with SUBREG => just change it once,
794: or not at all if changing back to starting mode. */
795: if (SUBREG_REG (x) == to
796: && GET_CODE (to) == SUBREG
797: && SUBREG_WORD (x) == 0
798: && SUBREG_WORD (to) == 0)
799: {
800: if (GET_MODE (x) == GET_MODE (SUBREG_REG (to)))
801: return SUBREG_REG (to);
802: SUBST (SUBREG_REG (x), SUBREG_REG (to));
803: }
1.1.1.4 root 804: /* (subreg (sign_extend X)) is X, if it has same mode as X. */
805: if (SUBREG_REG (x) == to
806: && (GET_CODE (to) == SIGN_EXTEND || GET_CODE (to) == ZERO_EXTEND)
807: && SUBREG_WORD (x) == 0
808: && GET_MODE (x) == GET_MODE (XEXP (to, 0)))
809: return XEXP (to, 0);
1.1.1.2 root 810: break;
1.1 root 811:
812: case NOT:
1.1.1.4 root 813: /* (not (minus X 1)) can become (neg X). */
814: if (was_replaced[0]
815: && ((GET_CODE (to) == PLUS && INTVAL (XEXP (to, 1)) == -1)
816: || (GET_CODE (to) == MINUS && XEXP (to, 1) == const1_rtx)))
817: return gen_rtx (NEG, GET_MODE (to), XEXP (to, 0));
818: /* Don't let substitution introduce double-negatives. */
819: if (was_replaced[0]
820: && GET_CODE (to) == code)
821: return XEXP (to, 0);
822: break;
823:
1.1 root 824: case NEG:
1.1.1.4 root 825: /* (neg (minus X Y)) can become (minus Y X). */
826: if (was_replaced[0] && GET_CODE (to) == MINUS)
827: return gen_rtx (MINUS, GET_MODE (to),
828: XEXP (to, 1), XEXP (to, 0));
1.1 root 829: /* Don't let substitution introduce double-negatives. */
1.1.1.2 root 830: if (was_replaced[0]
1.1 root 831: && GET_CODE (to) == code)
832: return XEXP (to, 0);
833: break;
834:
1.1.1.2 root 835: case FLOAT_TRUNCATE:
836: /* (float_truncate:SF (float_extend:DF foo:SF)) = foo:SF. */
837: if (was_replaced[0]
838: && GET_CODE (to) == FLOAT_EXTEND
839: && GET_MODE (XEXP (to, 0)) == GET_MODE (x))
840: return XEXP (to, 0);
841: break;
842:
1.1 root 843: case PLUS:
844: /* In (plus <foo> (ashift <bar> <n>))
845: change the shift to a multiply so we can recognize
846: scaled indexed addresses. */
1.1.1.2 root 847: if ((was_replaced[0]
848: || was_replaced[1])
1.1 root 849: && GET_CODE (to) == ASHIFT
1.1.1.2 root 850: && GET_CODE (XEXP (to, 1)) == CONST_INT
851: && INTVAL (XEXP (to, 1)) < HOST_BITS_PER_INT)
852: {
853: rtx temp;
854: if (!undobuf.storage)
855: undobuf.storage = (char *) oballoc (0);
856: temp = gen_rtx (MULT, GET_MODE (to),
857: XEXP (to, 0),
858: gen_rtx (CONST_INT, VOIDmode,
859: 1 << INTVAL (XEXP (to, 1))));
860: if (was_replaced[0])
861: SUBST (XEXP (x, 0), temp);
862: else
863: SUBST (XEXP (x, 1), temp);
864: }
865: /* (plus X (neg Y)) becomes (minus X Y). */
866: if (GET_CODE (XEXP (x, 1)) == NEG)
867: {
868: if (!undobuf.storage)
869: undobuf.storage = (char *) oballoc (0);
870: return gen_rtx (MINUS, GET_MODE (x),
871: XEXP (x, 0), XEXP (XEXP (x, 1), 0));
872: }
873: /* (plus (neg X) Y) becomes (minus Y X). */
874: if (GET_CODE (XEXP (x, 0)) == NEG)
1.1 root 875: {
876: if (!undobuf.storage)
877: undobuf.storage = (char *) oballoc (0);
1.1.1.2 root 878: return gen_rtx (MINUS, GET_MODE (x),
879: XEXP (x, 1), XEXP (XEXP (x, 0), 0));
880: }
881: /* (plus (plus x c1) c2) => (plus x c1+c2) */
882: if (GET_CODE (XEXP (x, 1)) == CONST_INT
883: && GET_CODE (XEXP (x, 0)) == PLUS
884: && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT)
885: {
886: int sum = (INTVAL (XEXP (x, 1))
887: + INTVAL (XEXP (XEXP (x, 0), 1)));
888: if (sum == 0)
889: return XEXP (XEXP (x, 0), 0);
890: if (!undobuf.storage)
891: undobuf.storage = (char *) oballoc (0);
892: SUBST (XEXP (x, 1), gen_rtx (CONST_INT, VOIDmode, sum));
893: SUBST (XEXP (x, 0), XEXP (XEXP (x, 0), 0));
894: break;
1.1 root 895: }
896: /* If we have something (putative index) being added to a sum,
897: associate it so that any constant term is outermost.
898: That's because that's the way indexed addresses are
899: now supposed to appear. */
1.1.1.2 root 900: if (((was_replaced[0] && GET_CODE (XEXP (x, 1)) == PLUS)
901: || (was_replaced[1] && GET_CODE (XEXP (x, 0)) == PLUS))
1.1 root 902: ||
1.1.1.2 root 903: ((was_replaced[0] || was_replaced[1])
904: && GET_CODE (to) == PLUS))
1.1 root 905: {
906: rtx offset = 0, base, index;
1.1.1.2 root 907: if (GET_CODE (to) != PLUS)
1.1 root 908: {
1.1.1.2 root 909: index = to;
910: base = was_replaced[0] ? XEXP (x, 1) : XEXP (x, 0);
1.1 root 911: }
912: else
913: {
1.1.1.2 root 914: index = was_replaced[0] ? XEXP (x, 1) : XEXP (x, 0);
915: base = to;
1.1 root 916: }
917: if (CONSTANT_ADDRESS_P (XEXP (base, 0)))
918: {
919: offset = XEXP (base, 0);
920: base = XEXP (base, 1);
921: }
922: else if (CONSTANT_ADDRESS_P (XEXP (base, 1)))
923: {
924: offset = XEXP (base, 1);
925: base = XEXP (base, 0);
926: }
927: if (offset != 0)
928: {
929: if (!undobuf.storage)
930: undobuf.storage = (char *) oballoc (0);
1.1.1.2 root 931: if (GET_CODE (offset) == CONST_INT)
932: return plus_constant (gen_rtx (PLUS, GET_MODE (index),
933: base, index),
934: INTVAL (offset));
935: if (GET_CODE (index) == CONST_INT)
936: return plus_constant (gen_rtx (PLUS, GET_MODE (offset),
937: base, offset),
938: INTVAL (index));
939: return gen_rtx (PLUS, GET_MODE (index),
1.1 root 940: gen_rtx (PLUS, GET_MODE (index),
1.1.1.2 root 941: base, index),
942: offset);
1.1 root 943: }
944: }
945: break;
946:
947: case MINUS:
948: /* Can simplify (minus:VOIDmode (zero/sign_extend FOO) CONST)
949: (which is a compare instruction, not a subtract instruction)
950: to (minus FOO CONST) if CONST fits in FOO's mode
951: and we are only testing equality.
952: In fact, this is valid for zero_extend if what follows is an
953: unsigned comparison, and for sign_extend with a signed comparison. */
954: if (GET_MODE (x) == VOIDmode
1.1.1.2 root 955: && was_replaced[0]
1.1 root 956: && (GET_CODE (to) == ZERO_EXTEND || GET_CODE (to) == SIGN_EXTEND)
957: && next_insn_tests_no_inequality (subst_insn)
958: && GET_CODE (XEXP (x, 1)) == CONST_INT
1.1.1.2 root 959: /* This is overly cautious by one bit, but saves worrying about
960: whether it is zero-extension or sign extension. */
1.1 root 961: && ((unsigned) INTVAL (XEXP (x, 1))
1.1.1.2 root 962: < (1 << (GET_MODE_BITSIZE (GET_MODE (XEXP (to, 0))) - 1))))
963: SUBST (XEXP (x, 0), XEXP (to, 0));
1.1 root 964: break;
965:
966: case EQ:
967: case NE:
968: /* If comparing a subreg against zero, discard the subreg. */
1.1.1.2 root 969: if (was_replaced[0]
1.1 root 970: && GET_CODE (to) == SUBREG
971: && SUBREG_WORD (to) == 0
972: && XEXP (x, 1) == const0_rtx)
1.1.1.2 root 973: SUBST (XEXP (x, 0), SUBREG_REG (to));
1.1 root 974:
975: /* If comparing a ZERO_EXTRACT against zero,
976: canonicalize to a SIGN_EXTRACT,
977: since the two are equivalent here. */
1.1.1.2 root 978: if (was_replaced[0]
979: && GET_CODE (to) == ZERO_EXTRACT
1.1 root 980: && XEXP (x, 1) == const0_rtx)
981: {
982: if (!undobuf.storage)
983: undobuf.storage = (char *) oballoc (0);
1.1.1.2 root 984: SUBST (XEXP (x, 0),
985: gen_rtx (SIGN_EXTRACT, GET_MODE (to),
986: XEXP (to, 0), XEXP (to, 1),
987: XEXP (to, 2)));
1.1 root 988: }
989: /* If we are putting (ASHIFT 1 x) into (EQ (AND ... y) 0),
990: arrange to return (EQ (SIGN_EXTRACT y 1 x) 0),
991: which is what jump-on-bit instructions are written with. */
992: else if (XEXP (x, 1) == const0_rtx
993: && GET_CODE (XEXP (x, 0)) == AND
1.1.1.2 root 994: && (XEXP (XEXP (x, 0), 0) == to
995: || XEXP (XEXP (x, 0), 1) == to)
996: && GET_CODE (to) == ASHIFT
997: && XEXP (to, 0) == const1_rtx)
1.1 root 998: {
999: register rtx y = XEXP (XEXP (x, 0),
1.1.1.2 root 1000: XEXP (XEXP (x, 0), 0) == to);
1.1 root 1001: if (!undobuf.storage)
1002: undobuf.storage = (char *) oballoc (0);
1.1.1.2 root 1003: SUBST (XEXP (x, 0),
1004: gen_rtx (SIGN_EXTRACT, GET_MODE (to),
1005: y,
1006: const1_rtx, XEXP (to, 1)));
1.1 root 1007: }
1008:
1009: break;
1010:
1011: case ZERO_EXTEND:
1.1.1.2 root 1012: if (was_replaced[0]
1.1 root 1013: && GET_CODE (to) == ZERO_EXTEND)
1.1.1.2 root 1014: SUBST (XEXP (x, 0), XEXP (to, 0));
1.1 root 1015: /* Zero-extending the result of an and with a constant can be done
1016: with a wider and. */
1.1.1.2 root 1017: if (was_replaced[0]
1.1 root 1018: && GET_CODE (to) == AND
1019: && GET_CODE (XEXP (to, 1)) == CONST_INT
1.1.1.2 root 1020: && FAKE_EXTEND_SAFE_P (GET_MODE (x), XEXP (to, 0))
1.1 root 1021: /* Avoid getting wrong result if the constant has high bits set
1022: that are irrelevant in the narrow mode where it is being used. */
1.1.1.2 root 1023: && 0 == (INTVAL (XEXP (to, 1))
1024: & ~ GET_MODE_MASK (GET_MODE (to))))
1.1 root 1025: {
1026: if (!undobuf.storage)
1027: undobuf.storage = (char *) oballoc (0);
1028: return gen_rtx (AND, GET_MODE (x),
1.1.1.2 root 1029: gen_lowpart_for_combine (GET_MODE (x), XEXP (to, 0)),
1.1 root 1030: XEXP (to, 1));
1.1.1.2 root 1031: }
1032: /* Change (zero_extend:M (subreg:N (zero_extract:M ...) 0))
1033: to (zero_extract:M ...) if the field extracted fits in mode N. */
1034: if (GET_CODE (XEXP (x, 0)) == SUBREG
1035: && GET_CODE (XEXP (XEXP (x, 0), 0)) == ZERO_EXTRACT
1036: && GET_CODE (XEXP (XEXP (XEXP (x, 0), 0), 1)) == CONST_INT
1037: && (INTVAL (XEXP (XEXP (XEXP (x, 0), 0), 1))
1038: <= GET_MODE_BITSIZE (GET_MODE (XEXP (x, 0)))))
1039: {
1040: return XEXP (XEXP (x, 0), 0);
1041: }
1.1 root 1042: break;
1043:
1044: case SIGN_EXTEND:
1.1.1.2 root 1045: if (was_replaced[0]
1.1 root 1046: && GET_CODE (to) == SIGN_EXTEND)
1.1.1.2 root 1047: SUBST (XEXP (x, 0), XEXP (to, 0));
1.1 root 1048: /* Sign-extending the result of an and with a constant can be done
1049: with a wider and, provided the high bit of the constant is 0. */
1.1.1.2 root 1050: if (was_replaced[0]
1.1 root 1051: && GET_CODE (to) == AND
1052: && GET_CODE (XEXP (to, 1)) == CONST_INT
1.1.1.2 root 1053: && FAKE_EXTEND_SAFE_P (GET_MODE (x), XEXP (to, 0))
1.1 root 1054: && ((INTVAL (XEXP (to, 1))
1.1.1.2 root 1055: & (-1 << (GET_MODE_BITSIZE (GET_MODE (to)) - 1)))
1.1 root 1056: == 0))
1057: {
1058: if (!undobuf.storage)
1059: undobuf.storage = (char *) oballoc (0);
1060: return gen_rtx (AND, GET_MODE (x),
1.1.1.2 root 1061: gen_lowpart_for_combine (GET_MODE (x), XEXP (to, 0)),
1.1 root 1062: XEXP (to, 1));
1063: }
1064: break;
1065:
1066: case SET:
1.1.1.2 root 1067: /* In (set (zero-extract <x> <n> <y>) (and <foo> <(2**n-1) | anything>))
1.1 root 1068: the `and' can be deleted. This can happen when storing a bit
1.1.1.2 root 1069: that came from a set-flag insn followed by masking to one bit. */
1.1 root 1070: if (GET_CODE (XEXP (x, 0)) == ZERO_EXTRACT
1.1.1.2 root 1071: && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
1072: && was_replaced[1]
1.1 root 1073: && GET_CODE (to) == AND
1.1.1.2 root 1074: && GET_CODE (XEXP (to, 1)) == CONST_INT
1075: && 0 == (((1 << INTVAL (XEXP (XEXP (x, 0), 1))) - 1)
1076: & ~ INTVAL (XEXP (to, 1))))
1.1 root 1077: {
1.1.1.2 root 1078: SUBST (XEXP (x, 1), XEXP (to, 0));
1079: }
1080: /* In (set (zero-extract <x> <n> <y>)
1081: (subreg (and <foo> <(2**n-1) | anything>)))
1082: the `and' can be deleted. */
1083: if (GET_CODE (XEXP (x, 0)) == ZERO_EXTRACT
1084: && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
1085: && GET_CODE (XEXP (x, 1)) == SUBREG
1086: && SUBREG_WORD (XEXP (x, 1)) == 0
1087: && GET_CODE (SUBREG_REG (XEXP (x, 1))) == AND
1088: && GET_CODE (XEXP (SUBREG_REG (XEXP (x, 1)), 1)) == CONST_INT
1089: && 0 == (((1 << INTVAL (XEXP (XEXP (x, 0), 1))) - 1)
1090: & ~ INTVAL (XEXP (SUBREG_REG (XEXP (x, 1)), 1))))
1091: {
1092: SUBST (SUBREG_REG (XEXP (x, 1)), XEXP (SUBREG_REG (XEXP (x, 1)), 0));
1093: }
1094: /* (set (zero_extract ...) (and/or/xor (zero_extract ...) const)),
1.1.1.5 ! root 1095: if both zero_extracts have the same location, size and position,
1.1.1.2 root 1096: can be changed to avoid the byte extracts. */
1097: if ((GET_CODE (XEXP (x, 0)) == ZERO_EXTRACT
1098: || GET_CODE (XEXP (x, 0)) == SIGN_EXTRACT)
1099: && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
1100: && (GET_CODE (XEXP (x, 1)) == AND
1101: || GET_CODE (XEXP (x, 1)) == IOR
1102: || GET_CODE (XEXP (x, 1)) == XOR)
1.1.1.5 ! root 1103: && rtx_equal_p (XEXP (x, 0), XEXP (XEXP (x, 1), 0))
1.1.1.2 root 1104: && GET_CODE (XEXP (XEXP (x, 1), 0)) == GET_CODE (XEXP (x, 0))
1105: && GET_CODE (XEXP (XEXP (x, 1), 1)) == CONST_INT)
1106: {
1107: #ifdef BITS_BIG_ENDIAN
1108: int shiftcount
1109: = GET_MODE_BITSIZE (GET_MODE (XEXP (XEXP (x, 0), 0)))
1110: - INTVAL (XEXP (XEXP (x, 0), 1)) - INTVAL (XEXP (XEXP (x, 0), 2));
1111: #else
1112: int shiftcount
1113: = INTVAL (XEXP (XEXP (x, 0), 2));
1114: #endif
1115: if (!undobuf.storage)
1116: undobuf.storage = (char *) oballoc (0);
1117: return
1118: gen_rtx (SET, VOIDmode,
1119: XEXP (XEXP (x, 0), 0),
1120: gen_rtx (GET_CODE (XEXP (x, 1)),
1121: GET_MODE (XEXP (XEXP (x, 0), 0)),
1122: XEXP (XEXP (XEXP (x, 1), 0), 0),
1123: gen_rtx (CONST_INT, VOIDmode,
1124: (INTVAL (XEXP (XEXP (x, 1), 1))
1125: << shiftcount)
1126: + (GET_CODE (XEXP (x, 1)) == AND
1127: ? (1 << shiftcount) - 1
1128: : 0))));
1129: }
1.1 root 1130: break;
1131:
1132: case AND:
1133: if (GET_CODE (XEXP (x, 1)) == CONST_INT)
1134: {
1.1.1.2 root 1135: rtx tem = simplify_and_const_int (x, to);
1.1 root 1136: if (tem)
1137: return tem;
1138: }
1139: break;
1140:
1141: case FLOAT:
1142: /* (float (sign_extend <X>)) = (float <X>). */
1.1.1.2 root 1143: if (was_replaced[0]
1.1 root 1144: && GET_CODE (to) == SIGN_EXTEND)
1.1.1.2 root 1145: SUBST (XEXP (x, 0), XEXP (to, 0));
1.1 root 1146: break;
1147:
1148: case ZERO_EXTRACT:
1.1.1.2 root 1149: /* (ZERO_EXTRACT (TRUNCATE x)...)
1150: can become (ZERO_EXTRACT x ...). */
1151: if (was_replaced[0]
1152: && GET_CODE (to) == TRUNCATE)
1153: {
1154: #ifdef BITS_BIG_ENDIAN
1155: if (GET_CODE (XEXP (x, 2)) == CONST_INT)
1156: {
1157: if (!undobuf.storage)
1158: undobuf.storage = (char *) oballoc (0);
1159: /* On a big-endian machine, must increment the bit-number
1160: since sign bit is farther away in the pre-truncated value. */
1161: return gen_rtx (ZERO_EXTRACT, GET_MODE (x),
1162: XEXP (to, 0),
1163: XEXP (x, 1),
1164: gen_rtx (CONST_INT, VOIDmode,
1165: (INTVAL (XEXP (x, 2))
1166: + GET_MODE_BITSIZE (GET_MODE (XEXP (to, 0)))
1167: - GET_MODE_BITSIZE (GET_MODE (to)))));
1168: }
1169: #else
1170: SUBST (XEXP (x, 0), XEXP (to, 0));
1171: #endif
1172: }
1.1 root 1173: /* Extracting a single bit from the result of a shift:
1174: see which bit it was before the shift and extract that directly. */
1.1.1.2 root 1175: if (was_replaced[0]
1.1 root 1176: && (GET_CODE (to) == ASHIFTRT || GET_CODE (to) == LSHIFTRT
1177: || GET_CODE (to) == ASHIFT || GET_CODE (to) == LSHIFT)
1178: && GET_CODE (XEXP (to, 1)) == CONST_INT
1179: && XEXP (x, 1) == const1_rtx
1180: && GET_CODE (XEXP (x, 2)) == CONST_INT)
1181: {
1182: int shift = INTVAL (XEXP (to, 1));
1183: int newpos;
1184: if (GET_CODE (to) == ASHIFT || GET_CODE (to) == LSHIFT)
1185: shift = - shift;
1186: #ifdef BITS_BIG_ENDIAN
1187: shift = - shift;
1188: #endif
1189: newpos = INTVAL (XEXP (x, 2)) + shift;
1190: if (newpos >= 0 &&
1.1.1.2 root 1191: newpos < GET_MODE_BITSIZE (GET_MODE (to)))
1.1 root 1192: {
1193: if (!undobuf.storage)
1194: undobuf.storage = (char *) oballoc (0);
1195: return gen_rtx (ZERO_EXTRACT, GET_MODE (x),
1196: XEXP (to, 0), const1_rtx,
1197: gen_rtx (CONST_INT, VOIDmode, newpos));
1198: }
1199: }
1200: break;
1201:
1202: case LSHIFTRT:
1203: case ASHIFTRT:
1204: case ROTATE:
1205: case ROTATERT:
1206: #ifdef SHIFT_COUNT_TRUNCATED
1207: /* (lshift <X> (sign_extend <Y>)) = (lshift <X> <Y>) (most machines).
1208: True for all kinds of shifts and also for zero_extend. */
1.1.1.2 root 1209: if (was_replaced[1]
1.1 root 1210: && (GET_CODE (to) == SIGN_EXTEND
1.1.1.2 root 1211: || GET_CODE (to) == ZERO_EXTEND)
1212: && FAKE_EXTEND_SAFE_P (GET_MODE (to), XEXP (to, 0)))
1.1 root 1213: {
1214: if (!undobuf.storage)
1215: undobuf.storage = (char *) oballoc (0);
1.1.1.2 root 1216: SUBST (XEXP (x, 1),
1217: /* This is a perverse SUBREG, wider than its base. */
1218: gen_lowpart_for_combine (GET_MODE (to), XEXP (to, 0)));
1.1 root 1219: }
1220: #endif
1221: /* Two shifts in a row of same kind
1222: in same direction with constant counts
1223: may be combined. */
1.1.1.2 root 1224: if (was_replaced[0]
1.1 root 1225: && GET_CODE (to) == GET_CODE (x)
1226: && GET_CODE (XEXP (x, 1)) == CONST_INT
1227: && GET_CODE (XEXP (to, 1)) == CONST_INT
1228: && INTVAL (XEXP (to, 1)) > 0
1229: && INTVAL (XEXP (x, 1)) > 0
1230: && (INTVAL (XEXP (x, 1)) + INTVAL (XEXP (to, 1))
1.1.1.2 root 1231: < GET_MODE_BITSIZE (GET_MODE (x))))
1.1 root 1232: {
1233: if (!undobuf.storage)
1234: undobuf.storage = (char *) oballoc (0);
1235: return gen_rtx (GET_CODE (x), GET_MODE (x),
1236: XEXP (to, 0),
1237: gen_rtx (CONST_INT, VOIDmode,
1238: INTVAL (XEXP (x, 1))
1239: + INTVAL (XEXP (to, 1))));
1240: }
1241: break;
1242:
1243: case LSHIFT:
1244: case ASHIFT:
1245: #ifdef SHIFT_COUNT_TRUNCATED
1246: /* (lshift <X> (sign_extend <Y>)) = (lshift <X> <Y>) (most machines).
1247: True for all kinds of shifts and also for zero_extend. */
1.1.1.2 root 1248: if (was_replaced[1]
1.1 root 1249: && (GET_CODE (to) == SIGN_EXTEND
1.1.1.4 root 1250: || GET_CODE (to) == ZERO_EXTEND)
1251: && GET_CODE (to) == REG)
1.1 root 1252: {
1253: if (!undobuf.storage)
1254: undobuf.storage = (char *) oballoc (0);
1.1.1.2 root 1255: SUBST (XEXP (x, 1), gen_rtx (SUBREG, GET_MODE (to), XEXP (to, 0), 0));
1.1 root 1256: }
1257: #endif
1258: /* (lshift (and (lshiftrt <foo> <X>) <Y>) <X>)
1259: happens copying between bit fields in similar structures.
1260: It can be replaced by one and instruction.
1261: It does not matter whether the shifts are logical or arithmetic. */
1262: if (GET_CODE (XEXP (x, 0)) == AND
1263: && GET_CODE (XEXP (x, 1)) == CONST_INT
1264: && INTVAL (XEXP (x, 1)) > 0
1265: && GET_CODE (XEXP (XEXP (x, 0), 1)) == CONST_INT
1.1.1.2 root 1266: && XEXP (XEXP (x, 0), 0) == to
1.1 root 1267: && (GET_CODE (to) == LSHIFTRT
1268: || GET_CODE (to) == ASHIFTRT)
1269: #if 0
1270: /* I now believe this restriction is unnecessary.
1271: The outer shift will discard those bits in any case, right? */
1272:
1273: /* If inner shift is arithmetic, either it shifts left or
1274: the bits it shifts the sign into are zeroed by the and. */
1275: && (INTVAL (XEXP (x, 1)) < 0
1276: || ((unsigned) INTVAL (XEXP (XEXP (x, 0), 1))
1277: < 1 << (GET_MODE_BITSIZE (GET_MODE (x))
1278: - INTVAL (XEXP (x, 0)))))
1279: #endif
1280: && GET_CODE (XEXP (to, 1)) == CONST_INT
1281: && INTVAL (XEXP (x, 1)) == INTVAL (XEXP (to, 1)))
1282: {
1283: if (!undobuf.storage)
1284: undobuf.storage = (char *) oballoc (0);
1285: /* The constant in the new `and' is <Y> << <X>
1286: but clear out all bits that don't belong in our mode. */
1287: return gen_rtx (AND, GET_MODE (x), XEXP (to, 0),
1288: gen_rtx (CONST_INT, VOIDmode,
1289: (GET_MODE_MASK (GET_MODE (x))
1290: & ((GET_MODE_MASK (GET_MODE (x))
1291: & INTVAL (XEXP (XEXP (x, 0), 1)))
1292: << INTVAL (XEXP (x, 1))))));
1293: }
1294: /* Two shifts in a row in same direction with constant counts
1295: may be combined. */
1.1.1.2 root 1296: if (was_replaced[0]
1.1 root 1297: && (GET_CODE (to) == ASHIFT || GET_CODE (to) == LSHIFT)
1298: && GET_CODE (XEXP (x, 1)) == CONST_INT
1299: && GET_CODE (XEXP (to, 1)) == CONST_INT
1300: && INTVAL (XEXP (to, 1)) > 0
1301: && INTVAL (XEXP (x, 1)) > 0
1302: && (INTVAL (XEXP (x, 1)) + INTVAL (XEXP (to, 1))
1.1.1.2 root 1303: < GET_MODE_BITSIZE (GET_MODE (x))))
1.1 root 1304: {
1305: if (!undobuf.storage)
1306: undobuf.storage = (char *) oballoc (0);
1307: return gen_rtx (GET_CODE (x), GET_MODE (x),
1308: XEXP (to, 0),
1309: gen_rtx (CONST_INT, VOIDmode,
1310: INTVAL (XEXP (x, 1))
1311: + INTVAL (XEXP (to, 1))));
1312: }
1313: /* (ashift (ashiftrt <foo> <X>) <X>)
1314: (or, on some machines, (ashift (ashift <foo> <-X>) <X>) instead)
1315: happens if you divide by 2**N and then multiply by 2**N.
1316: It can be replaced by one `and' instruction.
1317: It does not matter whether the shifts are logical or arithmetic. */
1318: if (GET_CODE (XEXP (x, 1)) == CONST_INT
1319: && INTVAL (XEXP (x, 1)) > 0
1.1.1.2 root 1320: && was_replaced[0]
1.1 root 1321: && (((GET_CODE (to) == LSHIFTRT || GET_CODE (to) == ASHIFTRT)
1322: && GET_CODE (XEXP (to, 1)) == CONST_INT
1323: && INTVAL (XEXP (x, 1)) == INTVAL (XEXP (to, 1)))
1324: ||
1325: ((GET_CODE (to) == LSHIFT || GET_CODE (to) == ASHIFT)
1326: && GET_CODE (XEXP (to, 1)) == CONST_INT
1327: && INTVAL (XEXP (x, 1)) == - INTVAL (XEXP (to, 1)))))
1328: {
1329: if (!undobuf.storage)
1330: undobuf.storage = (char *) oballoc (0);
1.1.1.2 root 1331: /* The constant in the new `and' is -1 << <X>
1.1 root 1332: but clear out all bits that don't belong in our mode. */
1333: return gen_rtx (AND, GET_MODE (x), XEXP (to, 0),
1334: gen_rtx (CONST_INT, VOIDmode,
1335: (GET_MODE_MASK (GET_MODE (x))
1336: & (GET_MODE_MASK (GET_MODE (x))
1337: << INTVAL (XEXP (x, 1))))));
1338: }
1339:
1340: }
1341:
1342: return x;
1343: }
1344:
1345: /* This is the AND case of the function subst. */
1346:
1347: static rtx
1.1.1.2 root 1348: simplify_and_const_int (x, to)
1349: rtx x, to;
1.1 root 1350: {
1351: register rtx varop = XEXP (x, 0);
1352: register int constop = INTVAL (XEXP (x, 1));
1353:
1354: /* (and (subreg (and <foo> <constant>) 0) <constant>)
1355: results from an andsi followed by an andqi,
1356: which happens frequently when storing bit-fields
1357: on something whose result comes from an andsi. */
1358: if (GET_CODE (varop) == SUBREG
1.1.1.2 root 1359: && XEXP (varop, 0) == to
1.1 root 1360: && subreg_lowpart_p (varop)
1361: && GET_CODE (to) == AND
1362: && GET_CODE (XEXP (to, 1)) == CONST_INT
1363: /* Verify that the result of the outer `and'
1364: is not affected by any bits not defined in the inner `and'.
1365: True if the outer mode is narrower, or if the outer constant
1366: masks to zero all the bits that the inner mode doesn't have. */
1.1.1.2 root 1367: && (GET_MODE_SIZE (GET_MODE (x)) < GET_MODE_SIZE (GET_MODE (to))
1368: || (constop & ~ GET_MODE_MASK (GET_MODE (to))) == 0))
1.1 root 1369: {
1370: if (!undobuf.storage)
1371: undobuf.storage = (char *) oballoc (0);
1372: return gen_rtx (AND, GET_MODE (x),
1.1.1.2 root 1373: gen_lowpart_for_combine (GET_MODE (x), XEXP (to, 0)),
1.1 root 1374: gen_rtx (CONST_INT, VOIDmode,
1375: constop
1376: /* Remember that the bits outside that mode
1377: are not being changed, so the effect
1378: is as if they were all 1. */
1379: & INTVAL (XEXP (to, 1))));
1380: }
1.1.1.2 root 1381: /* (and:SI (zero_extract:SI ...) <constant>)
1382: results from an andsi following a byte-fetch on risc machines.
1383: When the constant includes all bits extracted, eliminate the `and'. */
1384: if (GET_CODE (varop) == ZERO_EXTRACT
1385: && GET_CODE (XEXP (varop, 1)) == CONST_INT
1386: /* The `and' must not clear any bits that the extract can give. */
1387: && (~ constop & ((1 << INTVAL (XEXP (varop, 1))) - 1)) == 0)
1388: return varop;
1.1 root 1389: /* (and (zero_extend <foo>) <constant>)
1390: often results from storing in a bit-field something
1391: that was calculated as a short. Replace with a single `and'
1392: in whose constant all bits not in <foo>'s mode are zero. */
1.1.1.2 root 1393: if (varop == to
1394: && GET_CODE (to) == ZERO_EXTEND
1395: && FAKE_EXTEND_SAFE_P (GET_MODE (x), XEXP (to, 0)))
1.1 root 1396: {
1397: if (!undobuf.storage)
1398: undobuf.storage = (char *) oballoc (0);
1399: return gen_rtx (AND, GET_MODE (x),
1.1.1.2 root 1400: /* This is a perverse SUBREG, wider than its base. */
1401: gen_lowpart_for_combine (GET_MODE (x), XEXP (to, 0)),
1.1 root 1402: gen_rtx (CONST_INT, VOIDmode,
1.1.1.2 root 1403: constop & GET_MODE_MASK (GET_MODE (XEXP (to, 0)))));
1.1 root 1404: }
1405: /* (and (sign_extend <foo>) <constant>)
1406: can be replaced with (and (subreg <foo>) <constant>)
1407: if <constant> is narrower than <foo>'s mode,
1408: or with (zero_extend <foo>) if <constant> is a mask for that mode. */
1.1.1.2 root 1409: if (varop == to
1.1 root 1410: && GET_CODE (to) == SIGN_EXTEND
1.1.1.2 root 1411: && ((unsigned) constop <= GET_MODE_MASK (GET_MODE (XEXP (to, 0))))
1412: && FAKE_EXTEND_SAFE_P (GET_MODE (x), XEXP (to, 0)))
1.1 root 1413: {
1414: if (!undobuf.storage)
1415: undobuf.storage = (char *) oballoc (0);
1.1.1.2 root 1416: if (constop == GET_MODE_MASK (GET_MODE (XEXP (to, 0))))
1.1 root 1417: return gen_rtx (ZERO_EXTEND, GET_MODE (x), XEXP (to, 0));
1418: return gen_rtx (AND, GET_MODE (x),
1.1.1.2 root 1419: /* This is a perverse SUBREG, wider than its base. */
1420: gen_lowpart_for_combine (GET_MODE (x), XEXP (to, 0)),
1.1 root 1421: XEXP (x, 1));
1422: }
1423: /* (and (and <foo> <constant>) <constant>)
1424: comes from two and instructions in a row. */
1.1.1.2 root 1425: if (varop == to
1.1 root 1426: && GET_CODE (to) == AND
1427: && GET_CODE (XEXP (to, 1)) == CONST_INT)
1428: {
1429: if (!undobuf.storage)
1430: undobuf.storage = (char *) oballoc (0);
1431: return gen_rtx (AND, GET_MODE (x),
1432: XEXP (to, 0),
1433: gen_rtx (CONST_INT, VOIDmode,
1434: constop
1435: & INTVAL (XEXP (to, 1))));
1436: }
1437: /* (and (ashiftrt (ashift FOO N) N) CONST)
1438: may be simplified to (and FOO CONST) if CONST masks off the bits
1439: changed by the two shifts. */
1440: if (GET_CODE (varop) == ASHIFTRT
1441: && GET_CODE (XEXP (varop, 1)) == CONST_INT
1.1.1.2 root 1442: && XEXP (varop, 0) == to
1.1 root 1443: && GET_CODE (to) == ASHIFT
1444: && GET_CODE (XEXP (to, 1)) == CONST_INT
1445: && INTVAL (XEXP (varop, 1)) == INTVAL (XEXP (to, 1))
1446: && ((unsigned) constop >> INTVAL (XEXP (varop, 1))) == 0)
1447: {
1448: if (!undobuf.storage)
1449: undobuf.storage = (char *) oballoc (0);
1450: /* If CONST is a mask for the low byte,
1451: change this into a zero-extend instruction
1452: from just the low byte of FOO. */
1.1.1.2 root 1453: if (constop == GET_MODE_MASK (QImode))
1.1 root 1454: {
1455: rtx temp = gen_lowpart_for_combine (QImode, XEXP (to, 0));
1.1.1.2 root 1456: if (GET_CODE (temp) != CLOBBER)
1.1 root 1457: return gen_rtx (ZERO_EXTEND, GET_MODE (x), temp);
1458: }
1459: return gen_rtx (AND, GET_MODE (x),
1460: XEXP (to, 0), XEXP (x, 1));
1461: }
1.1.1.2 root 1462: /* (and x const) may be converted to (zero_extend (subreg x 0)). */
1.1.1.4 root 1463: if (constop == GET_MODE_MASK (QImode)
1464: && GET_CODE (varop) == REG)
1.1.1.2 root 1465: {
1466: if (!undobuf.storage)
1467: undobuf.storage = (char *) oballoc (0);
1468: return gen_rtx (ZERO_EXTEND, GET_MODE (x),
1469: gen_rtx (SUBREG, QImode, varop, 0));
1470: }
1.1.1.4 root 1471: if (constop == GET_MODE_MASK (HImode)
1472: && GET_CODE (varop) == REG)
1.1.1.2 root 1473: {
1474: if (!undobuf.storage)
1475: undobuf.storage = (char *) oballoc (0);
1476: return gen_rtx (ZERO_EXTEND, GET_MODE (x),
1477: gen_rtx (SUBREG, HImode, varop, 0));
1478: }
1.1 root 1479: /* No simplification applies. */
1480: return 0;
1481: }
1482:
1483: /* Like gen_lowpart but for use by combine. In combine it is not possible
1484: to create any new pseudoregs. However, it is safe to create
1485: invalid memory addresses, because combine will try to recognize
1486: them and all they will do is make the combine attempt fail.
1487:
1.1.1.2 root 1488: If for some reason this cannot do its job, an rtx
1489: (clobber (const_int 0)) is returned.
1490: An insn containing that will not be recognized. */
1491:
1492: #undef gen_lowpart
1.1 root 1493:
1494: static rtx
1495: gen_lowpart_for_combine (mode, x)
1496: enum machine_mode mode;
1497: register rtx x;
1498: {
1499: if (GET_CODE (x) == SUBREG || GET_CODE (x) == REG)
1500: return gen_lowpart (mode, x);
1.1.1.2 root 1501: if (GET_MODE (x) == mode || x->volatil)
1502: return gen_rtx (CLOBBER, VOIDmode, const0_rtx);
1.1 root 1503: if (GET_CODE (x) == MEM)
1504: {
1505: register int offset = 0;
1506: #ifdef WORDS_BIG_ENDIAN
1507: offset = (max (GET_MODE_SIZE (GET_MODE (x)), UNITS_PER_WORD)
1508: - max (GET_MODE_SIZE (mode), UNITS_PER_WORD));
1509: #endif
1510: #ifdef BYTES_BIG_ENDIAN
1.1.1.2 root 1511: /* Adjust the address so that the address-after-the-data
1512: is unchanged. */
1513: offset -= (min (UNITS_PER_WORD, GET_MODE_SIZE (mode))
1514: - min (UNITS_PER_WORD, GET_MODE_SIZE (GET_MODE (x))));
1.1 root 1515: #endif
1516: return gen_rtx (MEM, mode, plus_constant (XEXP (x, 0),
1517: offset));
1518: }
1519: else
1.1.1.2 root 1520: return gen_rtx (CLOBBER, VOIDmode, const0_rtx);
1.1 root 1521: }
1522:
1523: /* After substitution, if the resulting pattern looks like
1.1.1.2 root 1524: (set (cc0) (and ...)) or (set (cc0) (lshiftrt ...)),
1525: this function is called to simplify the
1.1 root 1526: pattern into a bit-field operation if possible. */
1527:
1528: static void
1529: simplify_set_cc0_and (insn)
1530: rtx insn;
1531: {
1532: register rtx value = XEXP (PATTERN (insn), 1);
1533: register rtx op0 = XEXP (value, 0);
1534: register rtx op1 = XEXP (value, 1);
1535: int offset = 0;
1536: rtx var = 0;
1537: rtx bitnum = 0;
1538: int temp;
1539: int unit;
1.1.1.2 root 1540: rtx newpat;
1541:
1542: if (GET_CODE (value) == AND)
1543: {
1544: op0 = XEXP (value, 0);
1545: op1 = XEXP (value, 1);
1546: }
1547: else if (GET_CODE (value) == LSHIFTRT)
1548: {
1549: /* If there is no AND, but there is a shift that discards
1550: all but the sign bit, we can pretend that the shift result
1551: is ANDed with 1. Otherwise we cannot handle just a shift. */
1552: if (GET_CODE (XEXP (value, 1)) == CONST_INT
1553: && (INTVAL (XEXP (value, 1))
1554: == GET_MODE_BITSIZE (GET_MODE (value)) - 1))
1555: {
1556: op0 = value;
1557: op1 = const1_rtx;
1558: }
1559: else
1560: return;
1561: }
1562: else
1563: abort ();
1.1 root 1564:
1565: /* Look for a constant power of 2 or a shifted 1
1566: on either side of the AND. Set VAR to the other side.
1567: Set BITNUM to the shift count of the 1 (as an rtx).
1568: Or, if bit number is constant, set OFFSET to the bit number. */
1569:
1570: switch (GET_CODE (op0))
1571: {
1572: case CONST_INT:
1573: temp = exact_log2 (INTVAL (op0));
1574: if (temp < 0)
1575: return;
1576: offset = temp;
1577: var = op1;
1578: break;
1579:
1580: case ASHIFT:
1581: case LSHIFT:
1582: if (XEXP (op0, 0) == const1_rtx)
1583: {
1584: bitnum = XEXP (op0, 1);
1585: var = op1;
1586: }
1587: }
1588: if (var == 0)
1589: switch (GET_CODE (op1))
1590: {
1591: case CONST_INT:
1592: temp = exact_log2 (INTVAL (op1));
1593: if (temp < 0)
1594: return;
1595: offset = temp;
1596: var = op0;
1597: break;
1598:
1599: case ASHIFT:
1600: case LSHIFT:
1601: if (XEXP (op1, 0) == const1_rtx)
1602: {
1603: bitnum = XEXP (op1, 1);
1604: var = op0;
1605: }
1606: }
1607:
1608: /* If VAR is 0, we didn't find something recognizable. */
1609: if (var == 0)
1610: return;
1611:
1612: if (!undobuf.storage)
1613: undobuf.storage = (char *) oballoc (0);
1614:
1615: /* If the bit position is currently exactly 0,
1616: extract a right-shift from the variable portion. */
1617: if (offset == 0
1618: && (GET_CODE (var) == ASHIFTRT || GET_CODE (var) == LSHIFTRT))
1619: {
1620: bitnum = XEXP (var, 1);
1621: var = XEXP (var, 0);
1622: }
1623:
1.1.1.2 root 1624: if (GET_CODE (var) == SUBREG && SUBREG_WORD (var) == 0)
1625: var = SUBREG_REG (var);
1626:
1627: /* Note that BITNUM and OFFSET are always little-endian thru here
1628: even on a big-endian machine. */
1629:
1.1 root 1630: #ifdef BITS_BIG_ENDIAN
1.1.1.2 root 1631: unit = GET_MODE_BITSIZE (GET_MODE (var)) - 1;
1.1 root 1632:
1633: if (bitnum != 0)
1634: bitnum = gen_rtx (MINUS, SImode,
1635: gen_rtx (CONST_INT, VOIDmode, unit), bitnum);
1636: else
1637: offset = unit - offset;
1638: #endif
1639:
1640: if (bitnum == 0)
1641: bitnum = gen_rtx (CONST_INT, VOIDmode, offset);
1642:
1.1.1.2 root 1643: newpat = gen_rtx (SET, VOIDmode, cc0_rtx,
1644: gen_rtx (ZERO_EXTRACT, VOIDmode, var, const1_rtx, bitnum));
1645: if (recog (newpat, insn) >= 0)
1.1 root 1646: {
1.1.1.2 root 1647: if (undobuf.num_undo < MAX_UNDO)
1648: {
1649: undobuf.undo[undobuf.num_undo].where = &XEXP (PATTERN (insn), 1);
1650: undobuf.undo[undobuf.num_undo].old_contents = value;
1651: XEXP (PATTERN (insn), 1) = XEXP (newpat, 1);
1652: }
1653: undobuf.num_undo++;
1.1 root 1654: }
1655: }
1656:
1657: /* Update the records of when each REG was most recently set or killed
1658: for the things done by INSN. This is the last thing done in processing
1659: INSN in the combiner loop.
1660:
1661: We update reg_last_set, reg_last_death, and also the similar information
1662: mem_last_set (which insn most recently modified memory)
1663: and last_call_cuid (which insn was the most recent subroutine call). */
1664:
1665: static void
1666: record_dead_and_set_regs (insn)
1667: rtx insn;
1668: {
1669: register rtx link;
1670: for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
1671: {
1.1.1.2 root 1672: if (REG_NOTE_KIND (link) == REG_DEAD)
1.1 root 1673: reg_last_death[REGNO (XEXP (link, 0))] = insn;
1.1.1.2 root 1674: else if (REG_NOTE_KIND (link) == REG_INC)
1.1 root 1675: reg_last_set[REGNO (XEXP (link, 0))] = insn;
1676: }
1677:
1678: if (GET_CODE (insn) == CALL_INSN)
1679: last_call_cuid = mem_last_set = INSN_CUID (insn);
1680:
1681: if (GET_CODE (PATTERN (insn)) == PARALLEL)
1682: {
1683: register int i;
1684: for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
1685: {
1686: register rtx elt = XVECEXP (PATTERN (insn), 0, i);
1687: register enum rtx_code code = GET_CODE (elt);
1688: if (code == SET || code == CLOBBER)
1689: {
1690: if (GET_CODE (XEXP (elt, 0)) == REG)
1691: reg_last_set[REGNO (XEXP (elt, 0))] = insn;
1.1.1.2 root 1692: if (GET_CODE (XEXP (elt, 0)) == SUBREG
1693: && GET_CODE (SUBREG_REG (XEXP (elt, 0))) == REG)
1694: reg_last_set[REGNO (SUBREG_REG (XEXP (elt, 0)))] = insn;
1.1 root 1695: else if (GET_CODE (XEXP (elt, 0)) == MEM)
1696: mem_last_set = INSN_CUID (insn);
1697: }
1698: }
1699: }
1700: else if (GET_CODE (PATTERN (insn)) == SET
1701: || GET_CODE (PATTERN (insn)) == CLOBBER)
1702: {
1703: register rtx x = XEXP (PATTERN (insn), 0);
1704: if (GET_CODE (x) == REG)
1705: reg_last_set[REGNO (x)] = insn;
1.1.1.2 root 1706: if (GET_CODE (x) == SUBREG
1707: && GET_CODE (SUBREG_REG (x)) == REG)
1708: reg_last_set[REGNO (SUBREG_REG (x))] = insn;
1.1 root 1709: else if (GET_CODE (x) == MEM)
1710: mem_last_set = INSN_CUID (insn);
1711: }
1712: }
1713:
1714: /* Return nonzero if expression X refers to a REG or to memory
1715: that is set in an instruction more recent than FROM_CUID. */
1716:
1717: static int
1718: use_crosses_set_p (x, from_cuid)
1719: register rtx x;
1720: int from_cuid;
1721: {
1722: register char *fmt;
1723: register int i;
1724: register enum rtx_code code = GET_CODE (x);
1725:
1726: if (code == REG)
1727: {
1728: register int regno = REGNO (x);
1729: return (reg_last_set[regno]
1730: && INSN_CUID (reg_last_set[regno]) > from_cuid);
1731: }
1732:
1733: if (code == MEM && mem_last_set > from_cuid)
1734: return 1;
1735:
1736: fmt = GET_RTX_FORMAT (code);
1737:
1738: for (i = GET_RTX_LENGTH (code); i >= 0; i--)
1739: {
1740: if (fmt[i] == 'E')
1741: {
1742: register int j;
1743: for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1744: if (use_crosses_set_p (XVECEXP (x, i, j), from_cuid))
1745: return 1;
1746: }
1747: else if (fmt[i] == 'e'
1748: && use_crosses_set_p (XEXP (x, i), from_cuid))
1749: return 1;
1750: }
1751: return 0;
1752: }
1753:
1754: /* Return nonzero if reg REGNO is marked as dying in INSN. */
1755:
1756: int
1757: regno_dead_p (regno, insn)
1758: int regno;
1759: rtx insn;
1760: {
1761: register rtx link;
1762:
1763: for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
1.1.1.2 root 1764: if ((REG_NOTE_KIND (link) == REG_DEAD
1765: || REG_NOTE_KIND (link) == REG_INC)
1766: && REGNO (XEXP (link, 0)) == regno)
1.1 root 1767: return 1;
1768:
1769: return 0;
1770: }
1771:
1772: /* Remove register number REGNO from the dead registers list of INSN. */
1773:
1.1.1.4 root 1774: void
1.1 root 1775: remove_death (regno, insn)
1776: int regno;
1777: rtx insn;
1778: {
1779: register rtx link, next;
1780: while ((link = REG_NOTES (insn))
1.1.1.2 root 1781: && REG_NOTE_KIND (link) == REG_DEAD
1782: && REGNO (XEXP (link, 0)) == regno)
1.1 root 1783: REG_NOTES (insn) = XEXP (link, 1);
1784:
1785: if (link)
1786: while (next = XEXP (link, 1))
1787: {
1.1.1.2 root 1788: if (REG_NOTE_KIND (next) == REG_DEAD
1789: && REGNO (XEXP (next, 0)) == regno)
1.1 root 1790: XEXP (link, 1) = XEXP (next, 1);
1791: else
1792: link = next;
1793: }
1794: }
1795:
1796: /* Return nonzero if J is the first insn following I,
1797: not counting labels, line numbers, etc.
1798: We assume that J follows I. */
1799:
1800: static int
1801: adjacent_insns_p (i, j)
1802: rtx i, j;
1803: {
1804: register rtx insn;
1805: for (insn = NEXT_INSN (i); insn != j; insn = NEXT_INSN (insn))
1806: if (GET_CODE (insn) == INSN
1807: || GET_CODE (insn) == CALL_INSN
1808: || GET_CODE (insn) == JUMP_INSN)
1809: return 0;
1810: return 1;
1811: }
1812:
1.1.1.2 root 1813: /* Concatenate the list of logical links of OINSN
1.1 root 1814: into INSN's list of logical links.
1.1.1.2 root 1815: Modifies OINSN destructively.
1816:
1817: If ALL_LINKS is nonzero, move all the links that OINSN has.
1818: Otherwise, move only those that point to insns that set regs
1819: that die in the insn OINSN.
1820: Other links are clobbered so that they are no longer effective. */
1.1 root 1821:
1822: static void
1.1.1.2 root 1823: add_links (insn, oinsn, all_links)
1824: rtx insn, oinsn;
1825: int all_links;
1.1 root 1826: {
1.1.1.2 root 1827: register rtx links = LOG_LINKS (oinsn);
1828: if (! all_links)
1829: {
1830: rtx tail;
1831: for (tail = links; tail; tail = XEXP (tail, 1))
1832: {
1833: rtx target = XEXP (tail, 0);
1834: if (GET_CODE (target) != INSN
1835: || GET_CODE (PATTERN (target)) != SET
1836: || GET_CODE (SET_DEST (PATTERN (target))) != REG
1837: || ! dead_or_set_p (oinsn, SET_DEST (PATTERN (target))))
1838: /* OINSN is going to become a NOTE
1839: so a link pointing there will have no effect. */
1840: XEXP (tail, 0) = oinsn;
1841: }
1842: }
1.1 root 1843: if (LOG_LINKS (insn) == 0)
1844: LOG_LINKS (insn) = links;
1845: else
1846: {
1847: register rtx next, prev = LOG_LINKS (insn);
1848: while (next = XEXP (prev, 1))
1849: prev = next;
1850: XEXP (prev, 1) = links;
1851: }
1852: }
1853:
1854: /* Concatenate the any elements of the list of reg-notes INCS
1855: which are of type REG_INC
1856: into INSN's list of reg-notes. */
1857:
1858: static void
1859: add_incs (insn, incs)
1860: rtx insn, incs;
1861: {
1862: register rtx tail;
1863:
1864: for (tail = incs; tail; tail = XEXP (tail, 1))
1.1.1.2 root 1865: if (REG_NOTE_KIND (tail) == REG_INC)
1.1 root 1866: REG_NOTES (insn)
1867: = gen_rtx (EXPR_LIST, REG_INC, XEXP (tail, 0), REG_NOTES (insn));
1868: }
1869:
1870: /* For each register (hardware or pseudo) used within expression X,
1871: if its death is in an instruction with cuid
1872: between FROM_CUID (inclusive) and TO_INSN (exclusive),
1873: mark it as dead in TO_INSN instead.
1874:
1875: This is done when X is being merged by combination into TO_INSN. */
1876:
1877: static void
1878: move_deaths (x, from_cuid, to_insn)
1879: rtx x;
1880: int from_cuid;
1881: rtx to_insn;
1882: {
1883: register char *fmt;
1884: register int len, i;
1885: register enum rtx_code code = GET_CODE (x);
1886:
1887: if (code == REG)
1888: {
1889: register rtx where_dead = reg_last_death[REGNO (x)];
1890:
1891: if (where_dead && INSN_CUID (where_dead) >= from_cuid
1892: && INSN_CUID (where_dead) < INSN_CUID (to_insn))
1893: {
1894: remove_death (REGNO (x), reg_last_death[REGNO (x)]);
1895: if (! dead_or_set_p (to_insn, x))
1896: REG_NOTES (to_insn)
1897: = gen_rtx (EXPR_LIST, REG_DEAD, x, REG_NOTES (to_insn));
1898: }
1899: return;
1900: }
1901:
1902: len = GET_RTX_LENGTH (code);
1903: fmt = GET_RTX_FORMAT (code);
1904:
1905: for (i = 0; i < len; i++)
1906: {
1907: if (fmt[i] == 'E')
1908: {
1909: register int j;
1910: for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1911: move_deaths (XVECEXP (x, i, j), from_cuid, to_insn);
1912: }
1913: else if (fmt[i] == 'e')
1914: move_deaths (XEXP (x, i), from_cuid, to_insn);
1915: }
1916: }
1917:
1.1.1.2 root 1918: void
1.1 root 1919: dump_combine_stats (file)
1920: char *file;
1921: {
1922: fprintf
1923: (file,
1924: ";; Combiner statistics: %d attempts, %d substitutions (%d requiring new space),\n;; %d successes.\n\n"
1925: , combine_attempts, combine_merges, combine_extras, combine_successes);
1926: }
1927:
1.1.1.2 root 1928: void
1.1 root 1929: dump_combine_total_stats (file)
1930: char *file;
1931: {
1932: fprintf
1933: (file,
1934: "\n;; Combiner totals: %d attempts, %d substitutions (%d requiring new space),\n;; %d successes.\n",
1935: total_attempts, total_merges, total_extras, total_successes);
1936: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.