Add diclaimer of copyright to _osname() manual page.
[unix-history] / gnu / usr.bin / gcc1 / cc1 / rtlanal.c
CommitLineData
15637ed4
RG
1/* Analyze RTL for C-Compiler
2 Copyright (C) 1987, 1988 Free Software Foundation, Inc.
3
4This file is part of GNU CC.
5
6GNU CC is free software; you can redistribute it and/or modify
7it under the terms of the GNU General Public License as published by
8the Free Software Foundation; either version 1, or (at your option)
9any later version.
10
11GNU CC is distributed in the hope that it will be useful,
12but WITHOUT ANY WARRANTY; without even the implied warranty of
13MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14GNU General Public License for more details.
15
16You should have received a copy of the GNU General Public License
17along with GNU CC; see the file COPYING. If not, write to
18the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
19
20
21#include "config.h"
22#include "rtl.h"
23
24extern void note_stores ();
25static int reg_set_p ();
26\f
27/* Return 1 if the value of X is unstable
28 (would be different at a different point in the program).
29 The frame pointer, arg pointer, etc. are considered stable
30 (within one function) and so is anything marked `unchanging'. */
31
32int
33rtx_unstable_p (x)
34 rtx x;
35{
36 register RTX_CODE code = GET_CODE (x);
37 register int i;
38 register char *fmt;
39
40 if (code == MEM)
41 return ! RTX_UNCHANGING_P (x);
42
43 if (code == QUEUED)
44 return 1;
45
46 if (code == CONST || code == CONST_INT)
47 return 0;
48
49 if (code == REG)
50 return ! (REGNO (x) == FRAME_POINTER_REGNUM
51 || REGNO (x) == ARG_POINTER_REGNUM
52 || RTX_UNCHANGING_P (x));
53
54 fmt = GET_RTX_FORMAT (code);
55 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
56 if (fmt[i] == 'e')
57 if (rtx_unstable_p (XEXP (x, i)))
58 return 1;
59 return 0;
60}
61
62/* Return 1 if X has a value that can vary even between two
63 executions of the program. 0 means X can be compared reliably
64 against certain constants or near-constants.
65 The frame pointer and the arg pointer are considered constant. */
66
67int
68rtx_varies_p (x)
69 rtx x;
70{
71 register RTX_CODE code = GET_CODE (x);
72 register int i;
73 register char *fmt;
74
75 if (code == MEM)
76 return 1;
77
78 if (code == QUEUED)
79 return 1;
80
81 if (code == CONST || code == CONST_INT)
82 return 0;
83
84 if (code == REG)
85 return ! (REGNO (x) == FRAME_POINTER_REGNUM
86 || REGNO (x) == ARG_POINTER_REGNUM);
87
88 fmt = GET_RTX_FORMAT (code);
89 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
90 if (fmt[i] == 'e')
91 if (rtx_varies_p (XEXP (x, i)))
92 return 1;
93 return 0;
94}
95
96/* Return 1 if X refers to a memory location whose address
97 cannot be compared reliably with constant addresses,
98 or if X refers to a BLKmode memory object. */
99
100int
101rtx_addr_varies_p (x)
102 rtx x;
103{
104 register enum rtx_code code;
105 register int i;
106 register char *fmt;
107
108 if (x == 0)
109 return 0;
110
111 code = GET_CODE (x);
112 if (code == MEM)
113 return GET_MODE (x) == BLKmode || rtx_varies_p (XEXP (x, 0));
114
115 fmt = GET_RTX_FORMAT (code);
116 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
117 if (fmt[i] == 'e')
118 if (rtx_addr_varies_p (XEXP (x, i)))
119 return 1;
120 return 0;
121}
122\f
123/* Nonzero if register REG appears somewhere within IN.
124 Also works if REG is not a register; in this case it checks
125 for a subexpression of IN that is Lisp "equal" to REG. */
126
127int
128reg_mentioned_p (reg, in)
129 register rtx reg, in;
130{
131 register char *fmt;
132 register int i;
133 register enum rtx_code code;
134
135 if (in == 0)
136 return 0;
137
138 if (reg == in)
139 return 1;
140
141 code = GET_CODE (in);
142
143 switch (code)
144 {
145 /* Compare registers by number. */
146 case REG:
147 return GET_CODE (reg) == REG && REGNO (in) == REGNO (reg);
148
149 /* These codes have no constituent expressions
150 and are unique. */
151 case CC0:
152 case PC:
153 return 0;
154
155 case CONST_INT:
156 return GET_CODE (reg) == CONST_INT && INTVAL (in) == INTVAL (reg);
157 }
158
159 if (GET_CODE (reg) == code && rtx_equal_p (reg, in))
160 return 1;
161
162 fmt = GET_RTX_FORMAT (code);
163
164 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
165 {
166 if (fmt[i] == 'E')
167 {
168 register int j;
169 for (j = XVECLEN (in, i) - 1; j >= 0; j--)
170 if (reg_mentioned_p (reg, XVECEXP (in, i, j)))
171 return 1;
172 }
173 else if (fmt[i] == 'e'
174 && reg_mentioned_p (reg, XEXP (in, i)))
175 return 1;
176 }
177 return 0;
178}
179
180/* Nonzero if register REG is used in an insn between
181 FROM_INSN and TO_INSN (exclusive of those two). */
182
183int
184reg_used_between_p (reg, from_insn, to_insn)
185 rtx reg, from_insn, to_insn;
186{
187 register rtx insn;
188 register RTX_CODE code;
189 for (insn = NEXT_INSN (from_insn); insn != to_insn; insn = NEXT_INSN (insn))
190 if (((code = GET_CODE (insn)) == INSN
191 || code == JUMP_INSN || code == CALL_INSN)
192 && reg_mentioned_p (reg, PATTERN (insn)))
193 return 1;
194 return 0;
195}
196
197/* Nonzero if register REG is set or clobbered in an insn between
198 FROM_INSN and TO_INSN (exclusive of those two).
199 Does not notice increments, only SET and CLOBBER. */
200
201int
202reg_set_between_p (reg, from_insn, to_insn)
203 rtx reg, from_insn, to_insn;
204{
205 register rtx insn;
206 register RTX_CODE code;
207 for (insn = NEXT_INSN (from_insn); insn != to_insn; insn = NEXT_INSN (insn))
208 if (((code = GET_CODE (insn)) == INSN
209 || code == JUMP_INSN || code == CALL_INSN)
210 && reg_set_p (reg, PATTERN (insn)))
211 return 1;
212 return 0;
213}
214
215/* Internals of reg_set_between_p. */
216
217static rtx reg_set_reg;
218static int reg_set_flag;
219
220static void
221reg_set_p_1 (x)
222 rtx x;
223{
224 if (reg_overlap_mentioned_p (reg_set_reg, x))
225 reg_set_flag = 1;
226}
227
228static int
229reg_set_p (reg, insn)
230 rtx reg, insn;
231{
232 reg_set_reg = reg;
233 reg_set_flag = 0;
234 note_stores (insn, reg_set_p_1);
235 return reg_set_flag;
236}
237\f
238/* Return nonzero if hard register in range [REGNO, ENDREGNO)
239 appears either explicitly or implicitly in X
240 other than being stored into.
241
242 References contained within the substructure at LOC do not count.
243 LOC may be zero, meaning don't ignore anything. */
244
245int
246refers_to_regno_p (regno, endregno, x, loc)
247 int regno, endregno;
248 rtx x;
249 rtx *loc;
250{
251 register int i;
252 register RTX_CODE code;
253 register char *fmt;
254
255 repeat:
256 code = GET_CODE (x);
257 if (code == REG)
258 {
259 i = REGNO (x);
260 return (endregno > i && regno < i + HARD_REGNO_NREGS (i, GET_MODE (x)));
261 }
262
263 if (code == SET)
264 {
265 /* Note setting a SUBREG counts as referring to the REG it is in! */
266 if (GET_CODE (SET_DEST (x)) != REG
267 && refers_to_regno_p (regno, endregno, SET_DEST (x), loc))
268 return 1;
269 if (loc == &SET_SRC (x))
270 return 0;
271 x = SET_SRC (x);
272 goto repeat;
273 }
274
275 if (code == CLOBBER)
276 {
277 if (GET_CODE (SET_DEST (x)) != REG
278 && refers_to_regno_p (regno, endregno, SET_DEST (x), loc))
279 return 1;
280 return 0;
281 }
282
283 /* X does not match, so try its subexpressions. */
284
285 fmt = GET_RTX_FORMAT (code);
286 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
287 {
288 if (fmt[i] == 'e' && loc != &XEXP (x, i))
289 {
290 if (i == 0)
291 {
292 x = XEXP (x, 0);
293 goto repeat;
294 }
295 else
296 if (refers_to_regno_p (regno, endregno, XEXP (x, i), loc))
297 return 1;
298 }
299 else if (fmt[i] == 'E')
300 {
301 register int j;
302 for (j = XVECLEN (x, i) - 1; j >=0; j--)
303 if (loc != &XVECEXP (x, i, j)
304 && refers_to_regno_p (regno, endregno, XVECEXP (x, i, j), loc))
305 return 1;
306 }
307 }
308 return 0;
309}
310
311/* Nonzero if X contains any reg that overlaps hard register REG. */
312
313int
314reg_overlap_mentioned_p (reg, x)
315 rtx reg, x;
316{
317 int regno = REGNO (reg);
318 int endregno = regno + HARD_REGNO_NREGS (regno, GET_MODE (reg));
319 return refers_to_regno_p (regno, endregno, x, 0);
320}
321\f
322/* This is 1 until after reload pass. */
323int rtx_equal_function_value_matters;
324
325/* Return 1 if X and Y are identical-looking rtx's.
326 This is the Lisp function EQUAL for rtx arguments. */
327
328int
329rtx_equal_p (x, y)
330 rtx x, y;
331{
332 register int i;
333 register int j;
334 register enum rtx_code code;
335 register char *fmt;
336
337 if (x == y)
338 return 1;
339 if (x == 0 || y == 0)
340 return 0;
341
342 code = GET_CODE (x);
343 /* Rtx's of different codes cannot be equal. */
344 if (code != GET_CODE (y))
345 return 0;
346
347 /* (MULT:SI x y) and (MULT:HI x y) are NOT equivalent.
348 (REG:SI x) and (REG:HI x) are NOT equivalent. */
349
350 if (GET_MODE (x) != GET_MODE (y))
351 return 0;
352
353 /* These three types of rtx's can be compared nonrecursively. */
354 /* Until the end of reload,
355 don't consider the a reference to the return register of the current
356 function the same as the return from a called function. This eases
357 the job of function integration. Once the distinction no longer
358 matters, the insn will be deleted. */
359 if (code == REG)
360 return (REGNO (x) == REGNO (y)
361 && (! rtx_equal_function_value_matters
362 || REG_FUNCTION_VALUE_P (x) == REG_FUNCTION_VALUE_P (y)));
363 if (code == LABEL_REF)
364 return XEXP (x, 0) == XEXP (y, 0);
365 if (code == SYMBOL_REF)
366 return XSTR (x, 0) == XSTR (y, 0);
367
368 /* Compare the elements. If any pair of corresponding elements
369 fail to match, return 0 for the whole things. */
370
371 fmt = GET_RTX_FORMAT (code);
372 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
373 {
374 switch (fmt[i])
375 {
376 case 'i':
377 if (XINT (x, i) != XINT (y, i))
378 return 0;
379 break;
380
381 case 'E':
382 /* Two vectors must have the same length. */
383 if (XVECLEN (x, i) != XVECLEN (y, i))
384 return 0;
385
386 /* And the corresponding elements must match. */
387 for (j = 0; j < XVECLEN (x, i); j++)
388 if (rtx_equal_p (XVECEXP (x, i, j), XVECEXP (y, i, j)) == 0)
389 return 0;
390 break;
391
392 case 'e':
393 if (rtx_equal_p (XEXP (x, i), XEXP (y, i)) == 0)
394 return 0;
395 break;
396
397 case 's':
398 if (strcmp (XSTR (x, i), XSTR (y, i)))
399 return 0;
400 break;
401
402 case 'u':
403 /* These are just backpointers, so they don't matter. */
404 break;
405
406 case '0':
407 break;
408
409 /* It is believed that rtx's at this level will never
410 contain anything but integers and other rtx's,
411 except for within LABEL_REFs and SYMBOL_REFs. */
412 default:
413 abort ();
414 }
415 }
416 return 1;
417}
418\f
419/* Call FUN on each register or MEM that is stored into or clobbered by X.
420 (X would be the pattern of an insn).
421 FUN receives two arguments:
422 the REG, MEM, CC0 or PC being stored in or clobbered,
423 the SET or CLOBBER rtx that does the store. */
424
425void
426note_stores (x, fun)
427 register rtx x;
428 void (*fun) ();
429{
430 if ((GET_CODE (x) == SET || GET_CODE (x) == CLOBBER))
431 {
432 register rtx dest = SET_DEST (x);
433 while (GET_CODE (dest) == SUBREG
434 || GET_CODE (dest) == ZERO_EXTRACT
435 || GET_CODE (dest) == SIGN_EXTRACT
436 || GET_CODE (dest) == STRICT_LOW_PART)
437 dest = XEXP (dest, 0);
438 (*fun) (dest, x);
439 }
440 else if (GET_CODE (x) == PARALLEL)
441 {
442 register int i;
443 for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
444 {
445 register rtx y = XVECEXP (x, 0, i);
446 if (GET_CODE (y) == SET || GET_CODE (y) == CLOBBER)
447 {
448 register rtx dest = SET_DEST (y);
449 while (GET_CODE (dest) == SUBREG
450 || GET_CODE (dest) == ZERO_EXTRACT
451 || GET_CODE (dest) == SIGN_EXTRACT
452 || GET_CODE (dest) == STRICT_LOW_PART)
453 dest = XEXP (dest, 0);
454 (*fun) (dest, XVECEXP (x, 0, i));
455 }
456 }
457 }
458}
459\f
460/* Return nonzero if register REG's old contents don't survive after INSN.
461 This can be because REG dies in INSN or because INSN entirely sets REG.
462
463 "Entirely set" means set directly and not through a SUBREG,
464 ZERO_EXTRACT or SIGN_EXTRACT, so no trace of the old contents remains.
465
466 REG may be a hard or pseudo reg. Renumbering is not taken into account,
467 but for this use that makes no difference, since regs don't overlap
468 during their lifetimes. Therefore, this function may be used
469 at any time after deaths have been computed (in flow.c). */
470
471int
472dead_or_set_p (insn, reg)
473 rtx insn;
474 rtx reg;
475{
476 register rtx link;
477 register int regno = REGNO (reg);
478
479 for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
480 if ((REG_NOTE_KIND (link) == REG_DEAD
481 || REG_NOTE_KIND (link) == REG_INC)
482 && REGNO (XEXP (link, 0)) == regno)
483 return 1;
484
485 if (GET_CODE (PATTERN (insn)) == SET)
486 return (GET_CODE (SET_DEST (PATTERN (insn))) == REG
487 && REGNO (SET_DEST (PATTERN (insn))) == regno);
488 else if (GET_CODE (PATTERN (insn)) == PARALLEL)
489 {
490 register int i;
491 for (i = XVECLEN (PATTERN (insn), 0) - 1; i >= 0; i--)
492 {
493 if (GET_CODE (XVECEXP (PATTERN (insn), 0, i)) == SET
494 && GET_CODE (SET_DEST (XVECEXP (PATTERN (insn), 0, i))) == REG
495 && REGNO (SET_DEST (XVECEXP (PATTERN (insn), 0, i))) == regno)
496 return 1;
497 }
498 }
499 return 0;
500}
501
502/* Return the reg-note of kind KIND in insn INSN, if there is one.
503 If DATUM is nonzero, look for one whose datum is DATUM. */
504
505rtx
506find_reg_note (insn, kind, datum)
507 rtx insn;
508 enum reg_note kind;
509 rtx datum;
510{
511 register rtx link;
512
513 for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
514 if (REG_NOTE_KIND (link) == kind
515 && (datum == 0 || datum == XEXP (link, 0)))
516 return link;
517 return 0;
518}
519
520/* Return the reg-note of kind KIND in insn INSN which applies to register
521 number REGNO, if any. Return 0 if there is no such reg-note. */
522
523rtx
524find_regno_note (insn, kind, regno)
525 rtx insn;
526 enum reg_note kind;
527 int regno;
528{
529 register rtx link;
530
531 for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
532 if (REG_NOTE_KIND (link) == kind
533 && REGNO (XEXP (link, 0)) == regno)
534 return link;
535 return 0;
536}
537\f
538/* Nonzero if FROM precedes TO with no intervening labels. */
539
540int
541no_labels_between (from, to)
542 register rtx from, to;
543{
544 register rtx p = to;
545
546 while (1)
547 {
548 p = PREV_INSN (p);
549 if (p == 0)
550 return 0;
551 if (p == from)
552 return 1;
553 if (GET_CODE (p) == CODE_LABEL)
554 return 0;
555 }
556}
557\f
558/* Nonzero if X contains any volatile memory references
559 or volatile ASM_OPERANDS expressions. */
560
561int
562volatile_refs_p (x)
563 rtx x;
564{
565 register RTX_CODE code;
566
567 code = GET_CODE (x);
568 switch (code)
569 {
570 case LABEL_REF:
571 case SYMBOL_REF:
572 case CONST_INT:
573 case CONST:
574 case CONST_DOUBLE:
575 case CC0:
576 case PC:
577 case REG:
578 case CLOBBER:
579 case ASM_INPUT:
580 case ADDR_VEC:
581 case ADDR_DIFF_VEC:
582 return 0;
583
584 case CALL:
585 return 1;
586
587 case MEM:
588 case ASM_OPERANDS:
589 if (MEM_VOLATILE_P (x))
590 return 1;
591 }
592
593 /* Recursively scan the operands of this expression. */
594
595 {
596 register char *fmt = GET_RTX_FORMAT (code);
597 register int i;
598
599 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
600 {
601 if (fmt[i] == 'e')
602 {
603 if (volatile_refs_p (XEXP (x, i)))
604 return 1;
605 }
606 if (fmt[i] == 'E')
607 {
608 register int j;
609 for (j = 0; j < XVECLEN (x, i); j++)
610 if (volatile_refs_p (XVECEXP (x, i, j)))
611 return 1;
612 }
613 }
614 }
615 return 0;
616}
617\f
618/* Return nonzero if evaluating rtx X might cause a trap. */
619
620int
621may_trap_p (x)
622 rtx x;
623{
624 int i;
625 enum rtx_code code;
626 char *fmt;
627
628 if (x == 0)
629 return 0;
630 code = GET_CODE (x);
631 switch (code)
632 {
633 /* Handle these cases fast. */
634 case CONST_INT:
635 case CONST_DOUBLE:
636 case SYMBOL_REF:
637 case LABEL_REF:
638 case CONST:
639 case PC:
640 case CC0:
641 case REG:
642 return 0;
643
644 /* Memory ref can trap unless it's a static var or a stack slot. */
645 case MEM:
646 return rtx_varies_p (XEXP (x, 0));
647
648 /* Division by a non-constant might trap. */
649 case DIV:
650 case MOD:
651 case UDIV:
652 case UMOD:
653 if (! CONSTANT_P (XEXP (x, 1))
654 && GET_CODE (XEXP (x, 1)) != CONST_DOUBLE)
655 return 1;
656 if (XEXP (x, 1) == const0_rtx)
657 return 1;
658 default:
659 /* Any floating arithmetic may trap. */
660 if (GET_MODE_CLASS (GET_MODE (x)) == MODE_FLOAT)
661 return 1;
662 }
663
664 fmt = GET_RTX_FORMAT (code);
665 for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
666 {
667 if (fmt[i] == 'e')
668 {
669 if (may_trap_p (XEXP (x, i)))
670 return 1;
671 }
672 else if (fmt[i] == 'E')
673 {
674 register int j;
675 for (j = 0; j < XVECLEN (x, i); j++)
676 if (may_trap_p (XVECEXP (x, i, j)))
677 return 1;
678 }
679 }
680 return 0;
681}