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