|
|
1.1 root 1: /* Analyze RTL for C-Compiler
2: Copyright (C) 1987, 1988, 1991, 1992, 1993 Free Software Foundation, Inc.
3:
4: This file is part of GNU CC.
5:
6: GNU CC is free software; you can redistribute it and/or modify
7: it under the terms of the GNU General Public License as published by
8: the Free Software Foundation; either version 2, or (at your option)
9: any later version.
10:
11: GNU CC is distributed in the hope that it will be useful,
12: but WITHOUT ANY WARRANTY; without even the implied warranty of
13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14: GNU General Public License for more details.
15:
16: You should have received a copy of the GNU General Public License
17: along with GNU CC; see the file COPYING. If not, write to
18: the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19:
20:
21: #include "config.h"
22: #include "rtl.h"
23:
24: void note_stores ();
25: int reg_set_p ();
26:
27: /* Bit flags that specify the machine subtype we are compiling for.
28: Bits are tested using macros TARGET_... defined in the tm.h file
29: and set by `-m...' switches. Must be defined in rtlanal.c. */
30:
31: int target_flags;
32:
33: /* Return 1 if the value of X is unstable
34: (would be different at a different point in the program).
35: The frame pointer, arg pointer, etc. are considered stable
36: (within one function) and so is anything marked `unchanging'. */
37:
38: int
39: rtx_unstable_p (x)
40: rtx x;
41: {
42: register RTX_CODE code = GET_CODE (x);
43: register int i;
44: register char *fmt;
45:
46: if (code == MEM)
47: return ! RTX_UNCHANGING_P (x);
48:
49: if (code == QUEUED)
50: return 1;
51:
52: if (code == CONST || code == CONST_INT)
53: return 0;
54:
55: if (code == REG)
56: return ! (REGNO (x) == FRAME_POINTER_REGNUM
57: || REGNO (x) == HARD_FRAME_POINTER_REGNUM
58: || REGNO (x) == ARG_POINTER_REGNUM
59: || RTX_UNCHANGING_P (x));
60:
61: fmt = GET_RTX_FORMAT (code);
62: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
63: if (fmt[i] == 'e')
64: if (rtx_unstable_p (XEXP (x, i)))
65: return 1;
66: return 0;
67: }
68:
69: /* Return 1 if X has a value that can vary even between two
70: executions of the program. 0 means X can be compared reliably
71: against certain constants or near-constants.
72: The frame pointer and the arg pointer are considered constant. */
73:
74: int
75: rtx_varies_p (x)
76: rtx x;
77: {
78: register RTX_CODE code = GET_CODE (x);
79: register int i;
80: register char *fmt;
81:
82: switch (code)
83: {
84: case MEM:
85: case QUEUED:
86: return 1;
87:
88: case CONST:
89: case CONST_INT:
90: case CONST_DOUBLE:
91: case SYMBOL_REF:
92: case LABEL_REF:
93: return 0;
94:
95: case REG:
96: /* Note that we have to test for the actual rtx used for the frame
97: and arg pointers and not just the register number in case we have
98: eliminated the frame and/or arg pointer and are using it
99: for pseudos. */
100: return ! (x == frame_pointer_rtx || x == hard_frame_pointer_rtx
101: || x == arg_pointer_rtx);
102:
103: case LO_SUM:
104: /* The operand 0 of a LO_SUM is considered constant
105: (in fact is it related specifically to operand 1). */
106: return rtx_varies_p (XEXP (x, 1));
107: }
108:
109: fmt = GET_RTX_FORMAT (code);
110: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
111: if (fmt[i] == 'e')
112: if (rtx_varies_p (XEXP (x, i)))
113: return 1;
114: return 0;
115: }
116:
117: /* Return 0 if the use of X as an address in a MEM can cause a trap. */
118:
119: int
120: rtx_addr_can_trap_p (x)
121: register rtx x;
122: {
123: register enum rtx_code code = GET_CODE (x);
124:
125: switch (code)
126: {
127: case SYMBOL_REF:
128: case LABEL_REF:
129: /* SYMBOL_REF is problematic due to the possible presence of
130: a #pragma weak, but to say that loads from symbols can trap is
131: *very* costly. It's not at all clear what's best here. For
132: now, we ignore the impact of #pragma weak. */
133: return 0;
134:
135: case REG:
136: /* As in rtx_varies_p, we have to use the actual rtx, not reg number. */
137: return ! (x == frame_pointer_rtx || x == hard_frame_pointer_rtx
138: || x == stack_pointer_rtx || x == arg_pointer_rtx);
139:
140: case CONST:
141: return rtx_addr_can_trap_p (XEXP (x, 0));
142:
143: case PLUS:
144: /* An address is assumed not to trap if it is an address that can't
145: trap plus a constant integer. */
146: return (rtx_addr_can_trap_p (XEXP (x, 0))
147: || GET_CODE (XEXP (x, 1)) != CONST_INT);
148:
149: case LO_SUM:
150: return rtx_addr_can_trap_p (XEXP (x, 1));
151: }
152:
153: /* If it isn't one of the case above, it can cause a trap. */
154: return 1;
155: }
156:
157: /* Return 1 if X refers to a memory location whose address
158: cannot be compared reliably with constant addresses,
159: or if X refers to a BLKmode memory object. */
160:
161: int
162: rtx_addr_varies_p (x)
163: rtx x;
164: {
165: register enum rtx_code code;
166: register int i;
167: register char *fmt;
168:
169: if (x == 0)
170: return 0;
171:
172: code = GET_CODE (x);
173: if (code == MEM)
174: return GET_MODE (x) == BLKmode || rtx_varies_p (XEXP (x, 0));
175:
176: fmt = GET_RTX_FORMAT (code);
177: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
178: if (fmt[i] == 'e')
179: if (rtx_addr_varies_p (XEXP (x, i)))
180: return 1;
181: return 0;
182: }
183:
184: /* Return the value of the integer term in X, if one is apparent;
185: otherwise return 0.
186: Only obvious integer terms are detected.
187: This is used in cse.c with the `related_value' field.*/
188:
189: HOST_WIDE_INT
190: get_integer_term (x)
191: rtx x;
192: {
193: if (GET_CODE (x) == CONST)
194: x = XEXP (x, 0);
195:
196: if (GET_CODE (x) == MINUS
197: && GET_CODE (XEXP (x, 1)) == CONST_INT)
198: return - INTVAL (XEXP (x, 1));
199: if (GET_CODE (x) == PLUS
200: && GET_CODE (XEXP (x, 1)) == CONST_INT)
201: return INTVAL (XEXP (x, 1));
202: return 0;
203: }
204:
205: /* If X is a constant, return the value sans apparent integer term;
206: otherwise return 0.
207: Only obvious integer terms are detected. */
208:
209: rtx
210: get_related_value (x)
211: rtx x;
212: {
213: if (GET_CODE (x) != CONST)
214: return 0;
215: x = XEXP (x, 0);
216: if (GET_CODE (x) == PLUS
217: && GET_CODE (XEXP (x, 1)) == CONST_INT)
218: return XEXP (x, 0);
219: else if (GET_CODE (x) == MINUS
220: && GET_CODE (XEXP (x, 1)) == CONST_INT)
221: return XEXP (x, 0);
222: return 0;
223: }
224:
225: /* Nonzero if register REG appears somewhere within IN.
226: Also works if REG is not a register; in this case it checks
227: for a subexpression of IN that is Lisp "equal" to REG. */
228:
229: int
230: reg_mentioned_p (reg, in)
231: register rtx reg, in;
232: {
233: register char *fmt;
234: register int i;
235: register enum rtx_code code;
236:
237: if (in == 0)
238: return 0;
239:
240: if (reg == in)
241: return 1;
242:
243: if (GET_CODE (in) == LABEL_REF)
244: return reg == XEXP (in, 0);
245:
246: code = GET_CODE (in);
247:
248: switch (code)
249: {
250: /* Compare registers by number. */
251: case REG:
252: return GET_CODE (reg) == REG && REGNO (in) == REGNO (reg);
253:
254: /* These codes have no constituent expressions
255: and are unique. */
256: case SCRATCH:
257: case CC0:
258: case PC:
259: return 0;
260:
261: case CONST_INT:
262: return GET_CODE (reg) == CONST_INT && INTVAL (in) == INTVAL (reg);
263:
264: case CONST_DOUBLE:
265: /* These are kept unique for a given value. */
266: return 0;
267: }
268:
269: if (GET_CODE (reg) == code && rtx_equal_p (reg, in))
270: return 1;
271:
272: fmt = GET_RTX_FORMAT (code);
273:
274: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
275: {
276: if (fmt[i] == 'E')
277: {
278: register int j;
279: for (j = XVECLEN (in, i) - 1; j >= 0; j--)
280: if (reg_mentioned_p (reg, XVECEXP (in, i, j)))
281: return 1;
282: }
283: else if (fmt[i] == 'e'
284: && reg_mentioned_p (reg, XEXP (in, i)))
285: return 1;
286: }
287: return 0;
288: }
289:
290: /* Return 1 if in between BEG and END, exclusive of BEG and END, there is
291: no CODE_LABEL insn. */
292:
293: int
294: no_labels_between_p (beg, end)
295: rtx beg, end;
296: {
297: register rtx p;
298: for (p = NEXT_INSN (beg); p != end; p = NEXT_INSN (p))
299: if (GET_CODE (p) == CODE_LABEL)
300: return 0;
301: return 1;
302: }
303:
304: /* Nonzero if register REG is used in an insn between
305: FROM_INSN and TO_INSN (exclusive of those two). */
306:
307: int
308: reg_used_between_p (reg, from_insn, to_insn)
309: rtx reg, from_insn, to_insn;
310: {
311: register rtx insn;
312:
313: if (from_insn == to_insn)
314: return 0;
315:
316: for (insn = NEXT_INSN (from_insn); insn != to_insn; insn = NEXT_INSN (insn))
317: if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
318: && reg_overlap_mentioned_p (reg, PATTERN (insn)))
319: return 1;
320: return 0;
321: }
322:
323: /* Nonzero if the old value of X, a register, is referenced in BODY. If X
324: is entirely replaced by a new value and the only use is as a SET_DEST,
325: we do not consider it a reference. */
326:
327: int
328: reg_referenced_p (x, body)
329: rtx x;
330: rtx body;
331: {
332: int i;
333:
334: switch (GET_CODE (body))
335: {
336: case SET:
337: if (reg_overlap_mentioned_p (x, SET_SRC (body)))
338: return 1;
339:
340: /* If the destination is anything other than CC0, PC, a REG or a SUBREG
341: of a REG that occupies all of the REG, the insn references X if
342: it is mentioned in the destination. */
343: if (GET_CODE (SET_DEST (body)) != CC0
344: && GET_CODE (SET_DEST (body)) != PC
345: && GET_CODE (SET_DEST (body)) != REG
346: && ! (GET_CODE (SET_DEST (body)) == SUBREG
347: && GET_CODE (SUBREG_REG (SET_DEST (body))) == REG
348: && (((GET_MODE_SIZE (GET_MODE (SUBREG_REG (SET_DEST (body))))
349: + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)
350: == ((GET_MODE_SIZE (GET_MODE (SET_DEST (body)))
351: + (UNITS_PER_WORD - 1)) / UNITS_PER_WORD)))
352: && reg_overlap_mentioned_p (x, SET_DEST (body)))
353: return 1;
354: break;
355:
356: case ASM_OPERANDS:
357: for (i = ASM_OPERANDS_INPUT_LENGTH (body) - 1; i >= 0; i--)
358: if (reg_overlap_mentioned_p (x, ASM_OPERANDS_INPUT (body, i)))
359: return 1;
360: break;
361:
362: case CALL:
363: case USE:
364: return reg_overlap_mentioned_p (x, body);
365:
366: case TRAP_IF:
367: return reg_overlap_mentioned_p (x, TRAP_CONDITION (body));
368:
369: case UNSPEC:
370: case UNSPEC_VOLATILE:
371: case PARALLEL:
372: for (i = XVECLEN (body, 0) - 1; i >= 0; i--)
373: if (reg_referenced_p (x, XVECEXP (body, 0, i)))
374: return 1;
375: break;
376: }
377:
378: return 0;
379: }
380:
381: /* Nonzero if register REG is referenced in an insn between
382: FROM_INSN and TO_INSN (exclusive of those two). Sets of REG do
383: not count. */
384:
385: int
386: reg_referenced_between_p (reg, from_insn, to_insn)
387: rtx reg, from_insn, to_insn;
388: {
389: register rtx insn;
390:
391: if (from_insn == to_insn)
392: return 0;
393:
394: for (insn = NEXT_INSN (from_insn); insn != to_insn; insn = NEXT_INSN (insn))
395: if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
396: && reg_referenced_p (reg, PATTERN (insn)))
397: return 1;
398: return 0;
399: }
400:
401: /* Nonzero if register REG is set or clobbered in an insn between
402: FROM_INSN and TO_INSN (exclusive of those two). */
403:
404: int
405: reg_set_between_p (reg, from_insn, to_insn)
406: rtx reg, from_insn, to_insn;
407: {
408: register rtx insn;
409:
410: if (from_insn == to_insn)
411: return 0;
412:
413: for (insn = NEXT_INSN (from_insn); insn != to_insn; insn = NEXT_INSN (insn))
414: if (GET_RTX_CLASS (GET_CODE (insn)) == 'i'
415: && reg_set_p (reg, insn))
416: return 1;
417: return 0;
418: }
419:
420: /* Internals of reg_set_between_p. */
421:
422: static rtx reg_set_reg;
423: static int reg_set_flag;
424:
425: void
426: reg_set_p_1 (x)
427: rtx x;
428: {
429: /* We don't want to return 1 if X is a MEM that contains a register
430: within REG_SET_REG. */
431:
432: if ((GET_CODE (x) != MEM)
433: && reg_overlap_mentioned_p (reg_set_reg, x))
434: reg_set_flag = 1;
435: }
436:
437: int
438: reg_set_p (reg, insn)
439: rtx reg, insn;
440: {
441: rtx body = insn;
442:
443: /* We can be passed an insn or part of one. If we are passed an insn,
444: check if a side-effect of the insn clobbers REG. */
445: if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
446: {
447: if (FIND_REG_INC_NOTE (insn, reg)
448: || (GET_CODE (insn) == CALL_INSN
449: /* We'd like to test call_used_regs here, but rtlanal.c can't
450: reference that variable due to its use in genattrtab. So
451: we'll just be more conservative. */
452: && ((GET_CODE (reg) == REG
453: && REGNO (reg) < FIRST_PSEUDO_REGISTER)
454: || GET_CODE (reg) == MEM)))
455: return 1;
456:
457: body = PATTERN (insn);
458: }
459:
460: reg_set_reg = reg;
461: reg_set_flag = 0;
462: note_stores (body, reg_set_p_1);
463: return reg_set_flag;
464: }
465:
466: /* Similar to reg_set_between_p, but check all registers in X. Return 0
467: only if none of them are modified between START and END. Return 1 if
468: X contains a MEM; this routine does not perform any memory aliasing. */
469:
470: int
471: modified_between_p (x, start, end)
472: rtx x;
473: rtx start, end;
474: {
475: enum rtx_code code = GET_CODE (x);
476: char *fmt;
477: int i, j;
478:
479: switch (code)
480: {
481: case CONST_INT:
482: case CONST_DOUBLE:
483: case CONST:
484: case SYMBOL_REF:
485: case LABEL_REF:
486: return 0;
487:
488: case PC:
489: case CC0:
490: return 1;
491:
492: case MEM:
493: /* If the memory is not constant, assume it is modified. If it is
494: constant, we still have to check the address. */
495: if (! RTX_UNCHANGING_P (x))
496: return 1;
497: break;
498:
499: case REG:
500: return reg_set_between_p (x, start, end);
501: }
502:
503: fmt = GET_RTX_FORMAT (code);
504: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
505: {
506: if (fmt[i] == 'e' && modified_between_p (XEXP (x, i), start, end))
507: return 1;
508:
509: if (fmt[i] == 'E')
510: for (j = XVECLEN (x, i) - 1; j >= 0; j--)
511: if (modified_between_p (XVECEXP (x, i, j), start, end))
512: return 1;
513: }
514:
515: return 0;
516: }
517:
518: /* Similar to reg_set_p, but check all registers in X. Return 0 only if none
519: of them are modified in INSN. Return 1 if X contains a MEM; this routine
520: does not perform any memory aliasing. */
521:
522: int
523: modified_in_p (x, insn)
524: rtx x;
525: rtx insn;
526: {
527: enum rtx_code code = GET_CODE (x);
528: char *fmt;
529: int i, j;
530:
531: switch (code)
532: {
533: case CONST_INT:
534: case CONST_DOUBLE:
535: case CONST:
536: case SYMBOL_REF:
537: case LABEL_REF:
538: return 0;
539:
540: case PC:
541: case CC0:
542: return 1;
543:
544: case MEM:
545: /* If the memory is not constant, assume it is modified. If it is
546: constant, we still have to check the address. */
547: if (! RTX_UNCHANGING_P (x))
548: return 1;
549: break;
550:
551: case REG:
552: return reg_set_p (x, insn);
553: }
554:
555: fmt = GET_RTX_FORMAT (code);
556: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
557: {
558: if (fmt[i] == 'e' && modified_in_p (XEXP (x, i), insn))
559: return 1;
560:
561: if (fmt[i] == 'E')
562: for (j = XVECLEN (x, i) - 1; j >= 0; j--)
563: if (modified_in_p (XVECEXP (x, i, j), insn))
564: return 1;
565: }
566:
567: return 0;
568: }
569:
570: /* Given an INSN, return a SET expression if this insn has only a single SET.
571: It may also have CLOBBERs, USEs, or SET whose output
572: will not be used, which we ignore. */
573:
574: rtx
575: single_set (insn)
576: rtx insn;
577: {
578: rtx set;
579: int i;
580:
581: if (GET_RTX_CLASS (GET_CODE (insn)) != 'i')
582: return 0;
583:
584: if (GET_CODE (PATTERN (insn)) == SET)
585: return PATTERN (insn);
586:
587: else if (GET_CODE (PATTERN (insn)) == PARALLEL)
588: {
589: for (i = 0, set = 0; i < XVECLEN (PATTERN (insn), 0); i++)
590: if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET
591: && (! find_reg_note (insn, REG_UNUSED,
592: SET_DEST (XVECEXP (PATTERN (insn), 0, i)))
593: || side_effects_p (XVECEXP (PATTERN (insn), 0, i))))
594: {
595: if (set)
596: return 0;
597: else
598: set = XVECEXP (PATTERN (insn), 0, i);
599: }
600: return set;
601: }
602:
603: return 0;
604: }
605:
606: /* Return the last thing that X was assigned from before *PINSN. Verify that
607: the object is not modified up to VALID_TO. If it was, if we hit
608: a partial assignment to X, or hit a CODE_LABEL first, return X. If we
609: found an assignment, update *PINSN to point to it. */
610:
611: rtx
612: find_last_value (x, pinsn, valid_to)
613: rtx x;
614: rtx *pinsn;
615: rtx valid_to;
616: {
617: rtx p;
618:
619: for (p = PREV_INSN (*pinsn); p && GET_CODE (p) != CODE_LABEL;
620: p = PREV_INSN (p))
621: if (GET_RTX_CLASS (GET_CODE (p)) == 'i')
622: {
623: rtx set = single_set (p);
624: rtx note = find_reg_note (p, REG_EQUAL, NULL_RTX);
625:
626: if (set && rtx_equal_p (x, SET_DEST (set)))
627: {
628: rtx src = SET_SRC (set);
629:
630: if (note && GET_CODE (XEXP (note, 0)) != EXPR_LIST)
631: src = XEXP (note, 0);
632:
633: if (! modified_between_p (src, PREV_INSN (p), valid_to)
634: /* Reject hard registers because we don't usually want
635: to use them; we'd rather use a pseudo. */
636: && ! (GET_CODE (src) == REG
637: && REGNO (src) < FIRST_PSEUDO_REGISTER))
638: {
639: *pinsn = p;
640: return src;
641: }
642: }
643:
644: /* If set in non-simple way, we don't have a value. */
645: if (reg_set_p (x, p))
646: break;
647: }
648:
649: return x;
650: }
651:
652: /* Return nonzero if register in range [REGNO, ENDREGNO)
653: appears either explicitly or implicitly in X
654: other than being stored into.
655:
656: References contained within the substructure at LOC do not count.
657: LOC may be zero, meaning don't ignore anything. */
658:
659: int
660: refers_to_regno_p (regno, endregno, x, loc)
661: int regno, endregno;
662: rtx x;
663: rtx *loc;
664: {
665: register int i;
666: register RTX_CODE code;
667: register char *fmt;
668:
669: repeat:
670: /* The contents of a REG_NONNEG note is always zero, so we must come here
671: upon repeat in case the last REG_NOTE is a REG_NONNEG note. */
672: if (x == 0)
673: return 0;
674:
675: code = GET_CODE (x);
676:
677: switch (code)
678: {
679: case REG:
680: i = REGNO (x);
681:
682: /* If we modifying the stack, frame, or argument pointer, it will
683: clobber a virtual register. In fact, we could be more precise,
684: but it isn't worth it. */
685: if ((i == STACK_POINTER_REGNUM
686: #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
687: || i == ARG_POINTER_REGNUM
688: #endif
689: || i == FRAME_POINTER_REGNUM)
690: && regno >= FIRST_VIRTUAL_REGISTER && regno <= LAST_VIRTUAL_REGISTER)
691: return 1;
692:
693: return (endregno > i
694: && regno < i + (i < FIRST_PSEUDO_REGISTER
695: ? HARD_REGNO_NREGS (i, GET_MODE (x))
696: : 1));
697:
698: case SUBREG:
699: /* If this is a SUBREG of a hard reg, we can see exactly which
700: registers are being modified. Otherwise, handle normally. */
701: if (GET_CODE (SUBREG_REG (x)) == REG
702: && REGNO (SUBREG_REG (x)) < FIRST_PSEUDO_REGISTER)
703: {
704: int inner_regno = REGNO (SUBREG_REG (x)) + SUBREG_WORD (x);
705: int inner_endregno
706: = inner_regno + (inner_regno < FIRST_PSEUDO_REGISTER
707: ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1);
708:
709: return endregno > inner_regno && regno < inner_endregno;
710: }
711: break;
712:
713: case CLOBBER:
714: case SET:
715: if (&SET_DEST (x) != loc
716: /* Note setting a SUBREG counts as referring to the REG it is in for
717: a pseudo but not for hard registers since we can
718: treat each word individually. */
719: && ((GET_CODE (SET_DEST (x)) == SUBREG
720: && loc != &SUBREG_REG (SET_DEST (x))
721: && GET_CODE (SUBREG_REG (SET_DEST (x))) == REG
722: && REGNO (SUBREG_REG (SET_DEST (x))) >= FIRST_PSEUDO_REGISTER
723: && refers_to_regno_p (regno, endregno,
724: SUBREG_REG (SET_DEST (x)), loc))
725: || (GET_CODE (SET_DEST (x)) != REG
726: && refers_to_regno_p (regno, endregno, SET_DEST (x), loc))))
727: return 1;
728:
729: if (code == CLOBBER || loc == &SET_SRC (x))
730: return 0;
731: x = SET_SRC (x);
732: goto repeat;
733: }
734:
735: /* X does not match, so try its subexpressions. */
736:
737: fmt = GET_RTX_FORMAT (code);
738: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
739: {
740: if (fmt[i] == 'e' && loc != &XEXP (x, i))
741: {
742: if (i == 0)
743: {
744: x = XEXP (x, 0);
745: goto repeat;
746: }
747: else
748: if (refers_to_regno_p (regno, endregno, XEXP (x, i), loc))
749: return 1;
750: }
751: else if (fmt[i] == 'E')
752: {
753: register int j;
754: for (j = XVECLEN (x, i) - 1; j >=0; j--)
755: if (loc != &XVECEXP (x, i, j)
756: && refers_to_regno_p (regno, endregno, XVECEXP (x, i, j), loc))
757: return 1;
758: }
759: }
760: return 0;
761: }
762:
763: /* Nonzero if modifying X will affect IN. If X is a register or a SUBREG,
764: we check if any register number in X conflicts with the relevant register
765: numbers. If X is a constant, return 0. If X is a MEM, return 1 iff IN
766: contains a MEM (we don't bother checking for memory addresses that can't
767: conflict because we expect this to be a rare case. */
768:
769: int
770: reg_overlap_mentioned_p (x, in)
771: rtx x, in;
772: {
773: int regno, endregno;
774:
775: if (GET_CODE (x) == SUBREG)
776: {
777: regno = REGNO (SUBREG_REG (x));
778: if (regno < FIRST_PSEUDO_REGISTER)
779: regno += SUBREG_WORD (x);
780: }
781: else if (GET_CODE (x) == REG)
782: regno = REGNO (x);
783: else if (CONSTANT_P (x))
784: return 0;
785: else if (GET_CODE (x) == MEM)
786: {
787: char *fmt;
788: int i;
789:
790: if (GET_CODE (in) == MEM)
791: return 1;
792:
793: fmt = GET_RTX_FORMAT (GET_CODE (in));
794:
795: for (i = GET_RTX_LENGTH (GET_CODE (in)) - 1; i >= 0; i--)
796: if (fmt[i] == 'e' && reg_overlap_mentioned_p (x, XEXP (in, i)))
797: return 1;
798:
799: return 0;
800: }
801: else if (GET_CODE (x) == SCRATCH || GET_CODE (x) == PC
802: || GET_CODE (x) == CC0)
803: return reg_mentioned_p (x, in);
804: else
805: abort ();
806:
807: endregno = regno + (regno < FIRST_PSEUDO_REGISTER
808: ? HARD_REGNO_NREGS (regno, GET_MODE (x)) : 1);
809:
810: return refers_to_regno_p (regno, endregno, in, NULL_PTR);
811: }
812:
813: /* Used for communications between the next few functions. */
814:
815: static int reg_set_last_unknown;
816: static rtx reg_set_last_value;
817: static int reg_set_last_first_regno, reg_set_last_last_regno;
818:
819: /* Called via note_stores from reg_set_last. */
820:
821: static void
822: reg_set_last_1 (x, pat)
823: rtx x;
824: rtx pat;
825: {
826: int first, last;
827:
828: /* If X is not a register, or is not one in the range we care
829: about, ignore. */
830: if (GET_CODE (x) != REG)
831: return;
832:
833: first = REGNO (x);
834: last = first + (first < FIRST_PSEUDO_REGISTER
835: ? HARD_REGNO_NREGS (first, GET_MODE (x)) : 1);
836:
837: if (first >= reg_set_last_last_regno
838: || last <= reg_set_last_first_regno)
839: return;
840:
841: /* If this is a CLOBBER or is some complex LHS, or doesn't modify
842: exactly the registers we care about, show we don't know the value. */
843: if (GET_CODE (pat) == CLOBBER || SET_DEST (pat) != x
844: || first != reg_set_last_first_regno
845: || last != reg_set_last_last_regno)
846: reg_set_last_unknown = 1;
847: else
848: reg_set_last_value = SET_SRC (pat);
849: }
850:
851: /* Return the last value to which REG was set prior to INSN. If we can't
852: find it easily, return 0.
853:
854: We only return a REG, SUBREG, or constant because it is too hard to
855: check if a MEM remains unchanged. */
856:
857: rtx
858: reg_set_last (x, insn)
859: rtx x;
860: rtx insn;
861: {
862: rtx orig_insn = insn;
863:
864: reg_set_last_first_regno = REGNO (x);
865:
866: reg_set_last_last_regno
867: = reg_set_last_first_regno
868: + (reg_set_last_first_regno < FIRST_PSEUDO_REGISTER
869: ? HARD_REGNO_NREGS (reg_set_last_first_regno, GET_MODE (x)) : 1);
870:
871: reg_set_last_unknown = 0;
872: reg_set_last_value = 0;
873:
874: /* Scan backwards until reg_set_last_1 changed one of the above flags.
875: Stop when we reach a label or X is a hard reg and we reach a
876: CALL_INSN (if reg_set_last_last_regno is a hard reg).
877:
878: If we find a set of X, ensure that its SET_SRC remains unchanged. */
879:
880: /* We compare with <= here, because reg_set_last_last_regno
881: is actually the number of the first reg *not* in X. */
882: for (;
883: insn && GET_CODE (insn) != CODE_LABEL
884: && ! (GET_CODE (insn) == CALL_INSN
885: && reg_set_last_last_regno <= FIRST_PSEUDO_REGISTER);
886: insn = PREV_INSN (insn))
887: if (GET_RTX_CLASS (GET_CODE (insn)) == 'i')
888: {
889: note_stores (PATTERN (insn), reg_set_last_1);
890: if (reg_set_last_unknown)
891: return 0;
892: else if (reg_set_last_value)
893: {
894: if (CONSTANT_P (reg_set_last_value)
895: || ((GET_CODE (reg_set_last_value) == REG
896: || GET_CODE (reg_set_last_value) == SUBREG)
897: && ! reg_set_between_p (reg_set_last_value,
898: NEXT_INSN (insn), orig_insn)))
899: return reg_set_last_value;
900: else
901: return 0;
902: }
903: }
904:
905: return 0;
906: }
907:
908: /* This is 1 until after reload pass. */
909: int rtx_equal_function_value_matters;
910:
911: /* Return 1 if X and Y are identical-looking rtx's.
912: This is the Lisp function EQUAL for rtx arguments. */
913:
914: int
915: rtx_equal_p (x, y)
916: rtx x, y;
917: {
918: register int i;
919: register int j;
920: register enum rtx_code code;
921: register char *fmt;
922:
923: if (x == y)
924: return 1;
925: if (x == 0 || y == 0)
926: return 0;
927:
928: code = GET_CODE (x);
929: /* Rtx's of different codes cannot be equal. */
930: if (code != GET_CODE (y))
931: return 0;
932:
933: /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent.
934: (REG:SI x) and (REG:HI x) are NOT equivalent. */
935:
936: if (GET_MODE (x) != GET_MODE (y))
937: return 0;
938:
939: /* REG, LABEL_REF, and SYMBOL_REF can be compared nonrecursively. */
940:
941: if (code == REG)
942: /* Until rtl generation is complete, don't consider a reference to the
943: return register of the current function the same as the return from a
944: called function. This eases the job of function integration. Once the
945: distinction is no longer needed, they can be considered equivalent. */
946: return (REGNO (x) == REGNO (y)
947: && (! rtx_equal_function_value_matters
948: || REG_FUNCTION_VALUE_P (x) == REG_FUNCTION_VALUE_P (y)));
949: else if (code == LABEL_REF)
950: return XEXP (x, 0) == XEXP (y, 0);
951: else if (code == SYMBOL_REF)
952: return XSTR (x, 0) == XSTR (y, 0);
953: else if (code == SCRATCH || code == CONST_DOUBLE)
954: return 0;
955:
956: /* Compare the elements. If any pair of corresponding elements
957: fail to match, return 0 for the whole things. */
958:
959: fmt = GET_RTX_FORMAT (code);
960: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
961: {
962: switch (fmt[i])
963: {
964: case 'w':
965: if (XWINT (x, i) != XWINT (y, i))
966: return 0;
967: break;
968:
969: case 'n':
970: case 'i':
971: if (XINT (x, i) != XINT (y, i))
972: return 0;
973: break;
974:
975: case 'V':
976: case 'E':
977: /* Two vectors must have the same length. */
978: if (XVECLEN (x, i) != XVECLEN (y, i))
979: return 0;
980:
981: /* And the corresponding elements must match. */
982: for (j = 0; j < XVECLEN (x, i); j++)
983: if (rtx_equal_p (XVECEXP (x, i, j), XVECEXP (y, i, j)) == 0)
984: return 0;
985: break;
986:
987: case 'e':
988: if (rtx_equal_p (XEXP (x, i), XEXP (y, i)) == 0)
989: return 0;
990: break;
991:
992: case 'S':
993: case 's':
994: if (strcmp (XSTR (x, i), XSTR (y, i)))
995: return 0;
996: break;
997:
998: case 'u':
999: /* These are just backpointers, so they don't matter. */
1000: break;
1001:
1002: case '0':
1003: break;
1004:
1005: /* It is believed that rtx's at this level will never
1006: contain anything but integers and other rtx's,
1007: except for within LABEL_REFs and SYMBOL_REFs. */
1008: default:
1009: abort ();
1010: }
1011: }
1012: return 1;
1013: }
1014:
1015: /* Call FUN on each register or MEM that is stored into or clobbered by X.
1016: (X would be the pattern of an insn).
1017: FUN receives two arguments:
1018: the REG, MEM, CC0 or PC being stored in or clobbered,
1019: the SET or CLOBBER rtx that does the store.
1020:
1021: If the item being stored in or clobbered is a SUBREG of a hard register,
1022: the SUBREG will be passed. */
1023:
1024: void
1025: note_stores (x, fun)
1026: register rtx x;
1027: void (*fun) ();
1028: {
1029: if ((GET_CODE (x) == SET || GET_CODE (x) == CLOBBER))
1030: {
1031: register rtx dest = SET_DEST (x);
1032: while ((GET_CODE (dest) == SUBREG
1033: && (GET_CODE (SUBREG_REG (dest)) != REG
1034: || REGNO (SUBREG_REG (dest)) >= FIRST_PSEUDO_REGISTER))
1035: || GET_CODE (dest) == ZERO_EXTRACT
1036: || GET_CODE (dest) == SIGN_EXTRACT
1037: || GET_CODE (dest) == STRICT_LOW_PART)
1038: dest = XEXP (dest, 0);
1039: (*fun) (dest, x);
1040: }
1041: else if (GET_CODE (x) == PARALLEL)
1042: {
1043: register int i;
1044: for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
1045: {
1046: register rtx y = XVECEXP (x, 0, i);
1047: if (GET_CODE (y) == SET || GET_CODE (y) == CLOBBER)
1048: {
1049: register rtx dest = SET_DEST (y);
1050: while ((GET_CODE (dest) == SUBREG
1051: && (GET_CODE (SUBREG_REG (dest)) != REG
1052: || (REGNO (SUBREG_REG (dest))
1053: >= FIRST_PSEUDO_REGISTER)))
1054: || GET_CODE (dest) == ZERO_EXTRACT
1055: || GET_CODE (dest) == SIGN_EXTRACT
1056: || GET_CODE (dest) == STRICT_LOW_PART)
1057: dest = XEXP (dest, 0);
1058: (*fun) (dest, y);
1059: }
1060: }
1061: }
1062: }
1063:
1064: /* Return nonzero if X's old contents don't survive after INSN.
1065: This will be true if X is (cc0) or if X is a register and
1066: X dies in INSN or because INSN entirely sets X.
1067:
1068: "Entirely set" means set directly and not through a SUBREG,
1069: ZERO_EXTRACT or SIGN_EXTRACT, so no trace of the old contents remains.
1070: Likewise, REG_INC does not count.
1071:
1072: REG may be a hard or pseudo reg. Renumbering is not taken into account,
1073: but for this use that makes no difference, since regs don't overlap
1074: during their lifetimes. Therefore, this function may be used
1075: at any time after deaths have been computed (in flow.c).
1076:
1077: If REG is a hard reg that occupies multiple machine registers, this
1078: function will only return 1 if each of those registers will be replaced
1079: by INSN. */
1080:
1081: int
1082: dead_or_set_p (insn, x)
1083: rtx insn;
1084: rtx x;
1085: {
1086: register int regno, last_regno;
1087: register int i;
1088:
1089: /* Can't use cc0_rtx below since this file is used by genattrtab.c. */
1090: if (GET_CODE (x) == CC0)
1091: return 1;
1092:
1093: if (GET_CODE (x) != REG)
1094: abort ();
1095:
1096: regno = REGNO (x);
1097: last_regno = (regno >= FIRST_PSEUDO_REGISTER ? regno
1098: : regno + HARD_REGNO_NREGS (regno, GET_MODE (x)) - 1);
1099:
1100: for (i = regno; i <= last_regno; i++)
1101: if (! dead_or_set_regno_p (insn, i))
1102: return 0;
1103:
1104: return 1;
1105: }
1106:
1107: /* Utility function for dead_or_set_p to check an individual register. Also
1108: called from flow.c. */
1109:
1110: int
1111: dead_or_set_regno_p (insn, test_regno)
1112: rtx insn;
1113: int test_regno;
1114: {
1115: int regno, endregno;
1116: rtx link;
1117:
1118: /* See if there is a death note for something that includes TEST_REGNO. */
1119: for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
1120: {
1121: if (REG_NOTE_KIND (link) != REG_DEAD || GET_CODE (XEXP (link, 0)) != REG)
1122: continue;
1123:
1124: regno = REGNO (XEXP (link, 0));
1125: endregno = (regno >= FIRST_PSEUDO_REGISTER ? regno + 1
1126: : regno + HARD_REGNO_NREGS (regno,
1127: GET_MODE (XEXP (link, 0))));
1128:
1129: if (test_regno >= regno && test_regno < endregno)
1130: return 1;
1131: }
1132:
1133: if (GET_CODE (PATTERN (insn)) == SET)
1134: {
1135: rtx dest = SET_DEST (PATTERN (insn));
1136:
1137: /* A value is totally replaced if it is the destination or the
1138: destination is a SUBREG of REGNO that does not change the number of
1139: words in it. */
1140: if (GET_CODE (dest) == SUBREG
1141: && (((GET_MODE_SIZE (GET_MODE (dest))
1142: + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
1143: == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest)))
1144: + UNITS_PER_WORD - 1) / UNITS_PER_WORD)))
1145: dest = SUBREG_REG (dest);
1146:
1147: if (GET_CODE (dest) != REG)
1148: return 0;
1149:
1150: regno = REGNO (dest);
1151: endregno = (regno >= FIRST_PSEUDO_REGISTER ? regno + 1
1152: : regno + HARD_REGNO_NREGS (regno, GET_MODE (dest)));
1153:
1154: return (test_regno >= regno && test_regno < endregno);
1155: }
1156: else if (GET_CODE (PATTERN (insn)) == PARALLEL)
1157: {
1158: register int i;
1159:
1160: for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
1161: {
1162: rtx body = XVECEXP (PATTERN (insn), 0, i);
1163:
1164: if (GET_CODE (body) == SET || GET_CODE (body) == CLOBBER)
1165: {
1166: rtx dest = SET_DEST (body);
1167:
1168: if (GET_CODE (dest) == SUBREG
1169: && (((GET_MODE_SIZE (GET_MODE (dest))
1170: + UNITS_PER_WORD - 1) / UNITS_PER_WORD)
1171: == ((GET_MODE_SIZE (GET_MODE (SUBREG_REG (dest)))
1172: + UNITS_PER_WORD - 1) / UNITS_PER_WORD)))
1173: dest = SUBREG_REG (dest);
1174:
1175: if (GET_CODE (dest) != REG)
1176: continue;
1177:
1178: regno = REGNO (dest);
1179: endregno = (regno >= FIRST_PSEUDO_REGISTER ? regno + 1
1180: : regno + HARD_REGNO_NREGS (regno, GET_MODE (dest)));
1181:
1182: if (test_regno >= regno && test_regno < endregno)
1183: return 1;
1184: }
1185: }
1186: }
1187:
1188: return 0;
1189: }
1190:
1191: /* Return the reg-note of kind KIND in insn INSN, if there is one.
1192: If DATUM is nonzero, look for one whose datum is DATUM. */
1193:
1194: rtx
1195: find_reg_note (insn, kind, datum)
1196: rtx insn;
1197: enum reg_note kind;
1198: rtx datum;
1199: {
1200: register rtx link;
1201:
1202: for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
1203: if (REG_NOTE_KIND (link) == kind
1204: && (datum == 0 || datum == XEXP (link, 0)))
1205: return link;
1206: return 0;
1207: }
1208:
1209: /* Return the reg-note of kind KIND in insn INSN which applies to register
1210: number REGNO, if any. Return 0 if there is no such reg-note. Note that
1211: the REGNO of this NOTE need not be REGNO if REGNO is a hard register;
1212: it might be the case that the note overlaps REGNO. */
1213:
1214: rtx
1215: find_regno_note (insn, kind, regno)
1216: rtx insn;
1217: enum reg_note kind;
1218: int regno;
1219: {
1220: register rtx link;
1221:
1222: for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
1223: if (REG_NOTE_KIND (link) == kind
1224: /* Verify that it is a register, so that scratch and MEM won't cause a
1225: problem here. */
1226: && GET_CODE (XEXP (link, 0)) == REG
1227: && REGNO (XEXP (link, 0)) <= regno
1228: && ((REGNO (XEXP (link, 0))
1229: + (REGNO (XEXP (link, 0)) >= FIRST_PSEUDO_REGISTER ? 1
1230: : HARD_REGNO_NREGS (REGNO (XEXP (link, 0)),
1231: GET_MODE (XEXP (link, 0)))))
1232: > regno))
1233: return link;
1234: return 0;
1235: }
1236:
1237: /* Remove register note NOTE from the REG_NOTES of INSN. */
1238:
1239: void
1240: remove_note (insn, note)
1241: register rtx note;
1242: register rtx insn;
1243: {
1244: register rtx link;
1245:
1246: if (REG_NOTES (insn) == note)
1247: {
1248: REG_NOTES (insn) = XEXP (note, 1);
1249: return;
1250: }
1251:
1252: for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
1253: if (XEXP (link, 1) == note)
1254: {
1255: XEXP (link, 1) = XEXP (note, 1);
1256: return;
1257: }
1258:
1259: abort ();
1260: }
1261:
1262: /* Nonzero if X contains any volatile instructions. These are instructions
1263: which may cause unpredictable machine state instructions, and thus no
1264: instructions should be moved or combined across them. This includes
1265: only volatile asms and UNSPEC_VOLATILE instructions. */
1266:
1267: int
1268: volatile_insn_p (x)
1269: rtx x;
1270: {
1271: register RTX_CODE code;
1272:
1273: code = GET_CODE (x);
1274: switch (code)
1275: {
1276: case LABEL_REF:
1277: case SYMBOL_REF:
1278: case CONST_INT:
1279: case CONST:
1280: case CONST_DOUBLE:
1281: case CC0:
1282: case PC:
1283: case REG:
1284: case SCRATCH:
1285: case CLOBBER:
1286: case ASM_INPUT:
1287: case ADDR_VEC:
1288: case ADDR_DIFF_VEC:
1289: case CALL:
1290: case MEM:
1291: return 0;
1292:
1293: case UNSPEC_VOLATILE:
1294: /* case TRAP_IF: This isn't clear yet. */
1295: return 1;
1296:
1297: case ASM_OPERANDS:
1298: if (MEM_VOLATILE_P (x))
1299: return 1;
1300: }
1301:
1302: /* Recursively scan the operands of this expression. */
1303:
1304: {
1305: register char *fmt = GET_RTX_FORMAT (code);
1306: register int i;
1307:
1308: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1309: {
1310: if (fmt[i] == 'e')
1311: {
1312: if (volatile_refs_p (XEXP (x, i)))
1313: return 1;
1314: }
1315: if (fmt[i] == 'E')
1316: {
1317: register int j;
1318: for (j = 0; j < XVECLEN (x, i); j++)
1319: if (volatile_refs_p (XVECEXP (x, i, j)))
1320: return 1;
1321: }
1322: }
1323: }
1324: return 0;
1325: }
1326:
1327: /* Nonzero if X contains any volatile memory references
1328: UNSPEC_VOLATILE operations or volatile ASM_OPERANDS expressions. */
1329:
1330: int
1331: volatile_refs_p (x)
1332: rtx x;
1333: {
1334: register RTX_CODE code;
1335:
1336: code = GET_CODE (x);
1337: switch (code)
1338: {
1339: case LABEL_REF:
1340: case SYMBOL_REF:
1341: case CONST_INT:
1342: case CONST:
1343: case CONST_DOUBLE:
1344: case CC0:
1345: case PC:
1346: case REG:
1347: case SCRATCH:
1348: case CLOBBER:
1349: case ASM_INPUT:
1350: case ADDR_VEC:
1351: case ADDR_DIFF_VEC:
1352: return 0;
1353:
1354: case CALL:
1355: case UNSPEC_VOLATILE:
1356: /* case TRAP_IF: This isn't clear yet. */
1357: return 1;
1358:
1359: case MEM:
1360: case ASM_OPERANDS:
1361: if (MEM_VOLATILE_P (x))
1362: return 1;
1363: }
1364:
1365: /* Recursively scan the operands of this expression. */
1366:
1367: {
1368: register char *fmt = GET_RTX_FORMAT (code);
1369: register int i;
1370:
1371: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1372: {
1373: if (fmt[i] == 'e')
1374: {
1375: if (volatile_refs_p (XEXP (x, i)))
1376: return 1;
1377: }
1378: if (fmt[i] == 'E')
1379: {
1380: register int j;
1381: for (j = 0; j < XVECLEN (x, i); j++)
1382: if (volatile_refs_p (XVECEXP (x, i, j)))
1383: return 1;
1384: }
1385: }
1386: }
1387: return 0;
1388: }
1389:
1390: /* Similar to above, except that it also rejects register pre- and post-
1391: incrementing. */
1392:
1393: int
1394: side_effects_p (x)
1395: rtx x;
1396: {
1397: register RTX_CODE code;
1398:
1399: code = GET_CODE (x);
1400: switch (code)
1401: {
1402: case LABEL_REF:
1403: case SYMBOL_REF:
1404: case CONST_INT:
1405: case CONST:
1406: case CONST_DOUBLE:
1407: case CC0:
1408: case PC:
1409: case REG:
1410: case SCRATCH:
1411: case ASM_INPUT:
1412: case ADDR_VEC:
1413: case ADDR_DIFF_VEC:
1414: return 0;
1415:
1416: case CLOBBER:
1417: /* Reject CLOBBER with a non-VOID mode. These are made by combine.c
1418: when some combination can't be done. If we see one, don't think
1419: that we can simplify the expression. */
1420: return (GET_MODE (x) != VOIDmode);
1421:
1422: case PRE_INC:
1423: case PRE_DEC:
1424: case POST_INC:
1425: case POST_DEC:
1426: case CALL:
1427: case UNSPEC_VOLATILE:
1428: /* case TRAP_IF: This isn't clear yet. */
1429: return 1;
1430:
1431: case MEM:
1432: case ASM_OPERANDS:
1433: if (MEM_VOLATILE_P (x))
1434: return 1;
1435: }
1436:
1437: /* Recursively scan the operands of this expression. */
1438:
1439: {
1440: register char *fmt = GET_RTX_FORMAT (code);
1441: register int i;
1442:
1443: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1444: {
1445: if (fmt[i] == 'e')
1446: {
1447: if (side_effects_p (XEXP (x, i)))
1448: return 1;
1449: }
1450: if (fmt[i] == 'E')
1451: {
1452: register int j;
1453: for (j = 0; j < XVECLEN (x, i); j++)
1454: if (side_effects_p (XVECEXP (x, i, j)))
1455: return 1;
1456: }
1457: }
1458: }
1459: return 0;
1460: }
1461:
1462: /* Return nonzero if evaluating rtx X might cause a trap. */
1463:
1464: int
1465: may_trap_p (x)
1466: rtx x;
1467: {
1468: int i;
1469: enum rtx_code code;
1470: char *fmt;
1471:
1472: if (x == 0)
1473: return 0;
1474: code = GET_CODE (x);
1475: switch (code)
1476: {
1477: /* Handle these cases quickly. */
1478: case CONST_INT:
1479: case CONST_DOUBLE:
1480: case SYMBOL_REF:
1481: case LABEL_REF:
1482: case CONST:
1483: case PC:
1484: case CC0:
1485: case REG:
1486: case SCRATCH:
1487: return 0;
1488:
1489: /* Conditional trap can trap! */
1490: case UNSPEC_VOLATILE:
1491: case TRAP_IF:
1492: return 1;
1493:
1494: /* Memory ref can trap unless it's a static var or a stack slot. */
1495: case MEM:
1496: return rtx_addr_can_trap_p (XEXP (x, 0));
1497:
1498: /* Division by a non-constant might trap. */
1499: case DIV:
1500: case MOD:
1501: case UDIV:
1502: case UMOD:
1503: if (! CONSTANT_P (XEXP (x, 1)))
1504: return 1;
1505: /* This was const0_rtx, but by not using that,
1506: we can link this file into other programs. */
1507: if (GET_CODE (XEXP (x, 1)) == CONST_INT && INTVAL (XEXP (x, 1)) == 0)
1508: return 1;
1509: default:
1510: /* Any floating arithmetic may trap. */
1511: if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
1512: return 1;
1513: }
1514:
1515: fmt = GET_RTX_FORMAT (code);
1516: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1517: {
1518: if (fmt[i] == 'e')
1519: {
1520: if (may_trap_p (XEXP (x, i)))
1521: return 1;
1522: }
1523: else if (fmt[i] == 'E')
1524: {
1525: register int j;
1526: for (j = 0; j < XVECLEN (x, i); j++)
1527: if (may_trap_p (XVECEXP (x, i, j)))
1528: return 1;
1529: }
1530: }
1531: return 0;
1532: }
1533:
1534: /* Return nonzero if X contains a comparison that is not either EQ or NE,
1535: i.e., an inequality. */
1536:
1537: int
1538: inequality_comparisons_p (x)
1539: rtx x;
1540: {
1541: register char *fmt;
1542: register int len, i;
1543: register enum rtx_code code = GET_CODE (x);
1544:
1545: switch (code)
1546: {
1547: case REG:
1548: case SCRATCH:
1549: case PC:
1550: case CC0:
1551: case CONST_INT:
1552: case CONST_DOUBLE:
1553: case CONST:
1554: case LABEL_REF:
1555: case SYMBOL_REF:
1556: return 0;
1557:
1558: case LT:
1559: case LTU:
1560: case GT:
1561: case GTU:
1562: case LE:
1563: case LEU:
1564: case GE:
1565: case GEU:
1566: return 1;
1567: }
1568:
1569: len = GET_RTX_LENGTH (code);
1570: fmt = GET_RTX_FORMAT (code);
1571:
1572: for (i = 0; i < len; i++)
1573: {
1574: if (fmt[i] == 'e')
1575: {
1576: if (inequality_comparisons_p (XEXP (x, i)))
1577: return 1;
1578: }
1579: else if (fmt[i] == 'E')
1580: {
1581: register int j;
1582: for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1583: if (inequality_comparisons_p (XVECEXP (x, i, j)))
1584: return 1;
1585: }
1586: }
1587:
1588: return 0;
1589: }
1590:
1591: /* Replace any occurrence of FROM in X with TO.
1592:
1593: Note that copying is not done so X must not be shared unless all copies
1594: are to be modified. */
1595:
1596: rtx
1597: replace_rtx (x, from, to)
1598: rtx x, from, to;
1599: {
1600: register int i, j;
1601: register char *fmt;
1602:
1603: if (x == from)
1604: return to;
1605:
1606: /* Allow this function to make replacements in EXPR_LISTs. */
1607: if (x == 0)
1608: return 0;
1609:
1610: fmt = GET_RTX_FORMAT (GET_CODE (x));
1611: for (i = GET_RTX_LENGTH (GET_CODE (x)) - 1; i >= 0; i--)
1612: {
1613: if (fmt[i] == 'e')
1614: XEXP (x, i) = replace_rtx (XEXP (x, i), from, to);
1615: else if (fmt[i] == 'E')
1616: for (j = XVECLEN (x, i) - 1; j >= 0; j--)
1617: XVECEXP (x, i, j) = replace_rtx (XVECEXP (x, i, j), from, to);
1618: }
1619:
1620: return x;
1621: }
1622:
1623: /* Throughout the rtx X, replace many registers according to REG_MAP.
1624: Return the replacement for X (which may be X with altered contents).
1625: REG_MAP[R] is the replacement for register R, or 0 for don't replace.
1626: NREGS is the length of REG_MAP; regs >= NREGS are not mapped.
1627:
1628: We only support REG_MAP entries of REG or SUBREG. Also, hard registers
1629: should not be mapped to pseudos or vice versa since validate_change
1630: is not called.
1631:
1632: If REPLACE_DEST is 1, replacements are also done in destinations;
1633: otherwise, only sources are replaced. */
1634:
1635: rtx
1636: replace_regs (x, reg_map, nregs, replace_dest)
1637: rtx x;
1638: rtx *reg_map;
1639: int nregs;
1640: int replace_dest;
1641: {
1642: register enum rtx_code code;
1643: register int i;
1644: register char *fmt;
1645:
1646: if (x == 0)
1647: return x;
1648:
1649: code = GET_CODE (x);
1650: switch (code)
1651: {
1652: case SCRATCH:
1653: case PC:
1654: case CC0:
1655: case CONST_INT:
1656: case CONST_DOUBLE:
1657: case CONST:
1658: case SYMBOL_REF:
1659: case LABEL_REF:
1660: return x;
1661:
1662: case REG:
1663: /* Verify that the register has an entry before trying to access it. */
1664: if (REGNO (x) < nregs && reg_map[REGNO (x)] != 0)
1665: return reg_map[REGNO (x)];
1666: return x;
1667:
1668: case SUBREG:
1669: /* Prevent making nested SUBREGs. */
1670: if (GET_CODE (SUBREG_REG (x)) == REG && REGNO (SUBREG_REG (x)) < nregs
1671: && reg_map[REGNO (SUBREG_REG (x))] != 0
1672: && GET_CODE (reg_map[REGNO (SUBREG_REG (x))]) == SUBREG)
1673: {
1674: rtx map_val = reg_map[REGNO (SUBREG_REG (x))];
1675: rtx map_inner = SUBREG_REG (map_val);
1676:
1677: if (GET_MODE (x) == GET_MODE (map_inner))
1678: return map_inner;
1679: else
1680: {
1681: /* We cannot call gen_rtx here since we may be linked with
1682: genattrtab.c. */
1683: /* Let's try clobbering the incoming SUBREG and see
1684: if this is really safe. */
1685: SUBREG_REG (x) = map_inner;
1686: SUBREG_WORD (x) += SUBREG_WORD (map_val);
1687: return x;
1688: #if 0
1689: rtx new = rtx_alloc (SUBREG);
1690: PUT_MODE (new, GET_MODE (x));
1691: SUBREG_REG (new) = map_inner;
1692: SUBREG_WORD (new) = SUBREG_WORD (x) + SUBREG_WORD (map_val);
1693: #endif
1694: }
1695: }
1696: break;
1697:
1698: case SET:
1699: if (replace_dest)
1700: SET_DEST (x) = replace_regs (SET_DEST (x), reg_map, nregs, 0);
1701:
1702: else if (GET_CODE (SET_DEST (x)) == MEM
1703: || GET_CODE (SET_DEST (x)) == STRICT_LOW_PART)
1704: /* Even if we are not to replace destinations, replace register if it
1705: is CONTAINED in destination (destination is memory or
1706: STRICT_LOW_PART). */
1707: XEXP (SET_DEST (x), 0) = replace_regs (XEXP (SET_DEST (x), 0),
1708: reg_map, nregs, 0);
1709: else if (GET_CODE (SET_DEST (x)) == ZERO_EXTRACT)
1710: /* Similarly, for ZERO_EXTRACT we replace all operands. */
1711: break;
1712:
1713: SET_SRC (x) = replace_regs (SET_SRC (x), reg_map, nregs, 0);
1714: return x;
1715: }
1716:
1717: fmt = GET_RTX_FORMAT (code);
1718: for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
1719: {
1720: if (fmt[i] == 'e')
1721: XEXP (x, i) = replace_regs (XEXP (x, i), reg_map, nregs, replace_dest);
1722: if (fmt[i] == 'E')
1723: {
1724: register int j;
1725: for (j = 0; j < XVECLEN (x, i); j++)
1726: XVECEXP (x, i, j) = replace_regs (XVECEXP (x, i, j), reg_map,
1727: nregs, replace_dest);
1728: }
1729: }
1730: return x;
1731: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.