annotate gcc/combine-stack-adj.c @ 158:494b0b89df80 default tip

...
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Mon, 25 May 2020 18:13:55 +0900
parents 1830386684a0
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
1 /* Combine stack adjustments.
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
2 Copyright (C) 1987-2020 Free Software Foundation, Inc.
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
3
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
4 This file is part of GCC.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
5
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
6 GCC is free software; you can redistribute it and/or modify it under
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
7 the terms of the GNU General Public License as published by the Free
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
8 Software Foundation; either version 3, or (at your option) any later
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
9 version.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
10
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
11 GCC is distributed in the hope that it will be useful, but WITHOUT ANY
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
14 for more details.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
15
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
16 You should have received a copy of the GNU General Public License
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
17 along with GCC; see the file COPYING3. If not see
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
18 <http://www.gnu.org/licenses/>. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
19
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
20 /* Track stack adjustments and stack memory references. Attempt to
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
21 reduce the number of stack adjustments by back-propagating across
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
22 the memory references.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
23
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
24 This is intended primarily for use with targets that do not define
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
25 ACCUMULATE_OUTGOING_ARGS. It is of significantly more value to
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
26 targets that define PREFERRED_STACK_BOUNDARY more aligned than
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
27 STACK_BOUNDARY (e.g. x86), or if not all registers can be pushed
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
28 (e.g. x86 fp regs) which would ordinarily have to be implemented
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
29 as a sub/mov pair due to restrictions in calls.c.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
30
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
31 Propagation stops when any of the insns that need adjusting are
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
32 (a) no longer valid because we've exceeded their range, (b) a
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
33 non-trivial push instruction, or (c) a call instruction.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
34
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
35 Restriction B is based on the assumption that push instructions
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
36 are smaller or faster. If a port really wants to remove all
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
37 pushes, it should have defined ACCUMULATE_OUTGOING_ARGS. The
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
38 one exception that is made is for an add immediately followed
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
39 by a push. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
40
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
41 #include "config.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
42 #include "system.h"
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
43 #include "coretypes.h"
111
kono
parents: 67
diff changeset
44 #include "backend.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
45 #include "rtl.h"
111
kono
parents: 67
diff changeset
46 #include "df.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
47 #include "insn-config.h"
111
kono
parents: 67
diff changeset
48 #include "memmodel.h"
kono
parents: 67
diff changeset
49 #include "emit-rtl.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
50 #include "recog.h"
111
kono
parents: 67
diff changeset
51 #include "cfgrtl.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
52 #include "tree-pass.h"
111
kono
parents: 67
diff changeset
53 #include "rtl-iter.h"
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
54
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
55
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
56 /* This structure records two kinds of stack references between stack
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
57 adjusting instructions: stack references in memory addresses for
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
58 regular insns and all stack references for debug insns. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
59
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
60 struct csa_reflist
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
61 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
62 HOST_WIDE_INT sp_offset;
111
kono
parents: 67
diff changeset
63 rtx_insn *insn;
kono
parents: 67
diff changeset
64 rtx *ref;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
65 struct csa_reflist *next;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
66 };
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
67
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
68 static int stack_memref_p (rtx);
111
kono
parents: 67
diff changeset
69 static rtx single_set_for_csa (rtx_insn *);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
70 static void free_csa_reflist (struct csa_reflist *);
111
kono
parents: 67
diff changeset
71 static struct csa_reflist *record_one_stack_ref (rtx_insn *, rtx *,
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
72 struct csa_reflist *);
111
kono
parents: 67
diff changeset
73 static int try_apply_stack_adjustment (rtx_insn *, struct csa_reflist *,
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
74 HOST_WIDE_INT, HOST_WIDE_INT);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
75 static void combine_stack_adjustments_for_block (basic_block);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
76
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
77
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
78 /* Main entry point for stack adjustment combination. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
79
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
80 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
81 combine_stack_adjustments (void)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
82 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
83 basic_block bb;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
84
111
kono
parents: 67
diff changeset
85 FOR_EACH_BB_FN (bb, cfun)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
86 combine_stack_adjustments_for_block (bb);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
87 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
88
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
89 /* Recognize a MEM of the form (sp) or (plus sp const). */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
90
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
91 static int
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
92 stack_memref_p (rtx x)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
93 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
94 if (!MEM_P (x))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
95 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
96 x = XEXP (x, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
97
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
98 if (x == stack_pointer_rtx)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
99 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
100 if (GET_CODE (x) == PLUS
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
101 && XEXP (x, 0) == stack_pointer_rtx
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
102 && CONST_INT_P (XEXP (x, 1)))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
103 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
104
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
105 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
106 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
107
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
108 /* Recognize either normal single_set or the hack in i386.md for
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
109 tying fp and sp adjustments. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
110
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
111 static rtx
111
kono
parents: 67
diff changeset
112 single_set_for_csa (rtx_insn *insn)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
113 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
114 int i;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
115 rtx tmp = single_set (insn);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
116 if (tmp)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
117 return tmp;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
118
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
119 if (!NONJUMP_INSN_P (insn)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
120 || GET_CODE (PATTERN (insn)) != PARALLEL)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
121 return NULL_RTX;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
122
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
123 tmp = PATTERN (insn);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
124 if (GET_CODE (XVECEXP (tmp, 0, 0)) != SET)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
125 return NULL_RTX;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
126
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
127 for (i = 1; i < XVECLEN (tmp, 0); ++i)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
128 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
129 rtx this_rtx = XVECEXP (tmp, 0, i);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
130
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
131 /* The special case is allowing a no-op set. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
132 if (GET_CODE (this_rtx) == SET
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
133 && SET_SRC (this_rtx) == SET_DEST (this_rtx))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
134 ;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
135 else if (GET_CODE (this_rtx) != CLOBBER
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
136 && GET_CODE (this_rtx) != USE)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
137 return NULL_RTX;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
138 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
139
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
140 return XVECEXP (tmp, 0, 0);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
141 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
142
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
143 /* Free the list of csa_reflist nodes. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
144
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
145 static void
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
146 free_csa_reflist (struct csa_reflist *reflist)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
147 {
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
148 struct csa_reflist *next;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
149 for (; reflist ; reflist = next)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
150 {
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
151 next = reflist->next;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
152 free (reflist);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
153 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
154 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
155
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
156 /* Create a new csa_reflist node from the given stack reference.
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
157 It is already known that the reference is either a MEM satisfying the
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
158 predicate stack_memref_p or a REG representing the stack pointer. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
159
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
160 static struct csa_reflist *
111
kono
parents: 67
diff changeset
161 record_one_stack_ref (rtx_insn *insn, rtx *ref, struct csa_reflist *next_reflist)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
162 {
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
163 struct csa_reflist *ml;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
164
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
165 ml = XNEW (struct csa_reflist);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
166
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
167 if (REG_P (*ref) || XEXP (*ref, 0) == stack_pointer_rtx)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
168 ml->sp_offset = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
169 else
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
170 ml->sp_offset = INTVAL (XEXP (XEXP (*ref, 0), 1));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
171
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
172 ml->insn = insn;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
173 ml->ref = ref;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
174 ml->next = next_reflist;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
175
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
176 return ml;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
177 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
178
111
kono
parents: 67
diff changeset
179 /* We only know how to adjust the CFA; no other frame-related changes
kono
parents: 67
diff changeset
180 may appear in any insn to be deleted. */
kono
parents: 67
diff changeset
181
kono
parents: 67
diff changeset
182 static bool
kono
parents: 67
diff changeset
183 no_unhandled_cfa (rtx_insn *insn)
kono
parents: 67
diff changeset
184 {
kono
parents: 67
diff changeset
185 if (!RTX_FRAME_RELATED_P (insn))
kono
parents: 67
diff changeset
186 return true;
kono
parents: 67
diff changeset
187
kono
parents: 67
diff changeset
188 /* No CFA notes at all is a legacy interpretation like
kono
parents: 67
diff changeset
189 FRAME_RELATED_EXPR, and is context sensitive within
kono
parents: 67
diff changeset
190 the prologue state machine. We can't handle that here. */
kono
parents: 67
diff changeset
191 bool has_cfa_adjust = false;
kono
parents: 67
diff changeset
192
kono
parents: 67
diff changeset
193 for (rtx link = REG_NOTES (insn); link; link = XEXP (link, 1))
kono
parents: 67
diff changeset
194 switch (REG_NOTE_KIND (link))
kono
parents: 67
diff changeset
195 {
kono
parents: 67
diff changeset
196 default:
kono
parents: 67
diff changeset
197 break;
kono
parents: 67
diff changeset
198 case REG_CFA_ADJUST_CFA:
kono
parents: 67
diff changeset
199 has_cfa_adjust = true;
kono
parents: 67
diff changeset
200 break;
kono
parents: 67
diff changeset
201
kono
parents: 67
diff changeset
202 case REG_FRAME_RELATED_EXPR:
kono
parents: 67
diff changeset
203 case REG_CFA_DEF_CFA:
kono
parents: 67
diff changeset
204 case REG_CFA_OFFSET:
kono
parents: 67
diff changeset
205 case REG_CFA_REGISTER:
kono
parents: 67
diff changeset
206 case REG_CFA_EXPRESSION:
kono
parents: 67
diff changeset
207 case REG_CFA_RESTORE:
kono
parents: 67
diff changeset
208 case REG_CFA_SET_VDRAP:
kono
parents: 67
diff changeset
209 case REG_CFA_WINDOW_SAVE:
kono
parents: 67
diff changeset
210 case REG_CFA_FLUSH_QUEUE:
kono
parents: 67
diff changeset
211 case REG_CFA_TOGGLE_RA_MANGLE:
kono
parents: 67
diff changeset
212 return false;
kono
parents: 67
diff changeset
213 }
kono
parents: 67
diff changeset
214
kono
parents: 67
diff changeset
215 return has_cfa_adjust;
kono
parents: 67
diff changeset
216 }
kono
parents: 67
diff changeset
217
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
218 /* Attempt to apply ADJUST to the stack adjusting insn INSN, as well
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
219 as each of the memories and stack references in REFLIST. Return true
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
220 on success. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
221
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
222 static int
111
kono
parents: 67
diff changeset
223 try_apply_stack_adjustment (rtx_insn *insn, struct csa_reflist *reflist,
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
224 HOST_WIDE_INT new_adjust, HOST_WIDE_INT delta)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
225 {
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
226 struct csa_reflist *ml;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
227 rtx set;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
228
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
229 set = single_set_for_csa (insn);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
230 if (MEM_P (SET_DEST (set)))
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
231 validate_change (insn, &SET_DEST (set),
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
232 replace_equiv_address (SET_DEST (set), stack_pointer_rtx),
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
233 1);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
234 else
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
235 validate_change (insn, &XEXP (SET_SRC (set), 1), GEN_INT (new_adjust), 1);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
236
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
237 for (ml = reflist; ml ; ml = ml->next)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
238 {
111
kono
parents: 67
diff changeset
239 rtx new_addr = plus_constant (Pmode, stack_pointer_rtx,
kono
parents: 67
diff changeset
240 ml->sp_offset - delta);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
241 rtx new_val;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
242
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
243 if (MEM_P (*ml->ref))
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
244 new_val = replace_equiv_address_nv (*ml->ref, new_addr);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
245 else if (GET_MODE (*ml->ref) == GET_MODE (stack_pointer_rtx))
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
246 new_val = new_addr;
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
247 else
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
248 new_val = lowpart_subreg (GET_MODE (*ml->ref), new_addr,
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
249 GET_MODE (new_addr));
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
250 validate_change (ml->insn, ml->ref, new_val, 1);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
251 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
252
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
253 if (apply_change_group ())
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
254 {
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
255 /* Succeeded. Update our knowledge of the stack references. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
256 for (ml = reflist; ml ; ml = ml->next)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
257 ml->sp_offset -= delta;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
258
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
259 return 1;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
260 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
261 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
262 return 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
263 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
264
111
kono
parents: 67
diff changeset
265 /* For non-debug insns, record all stack memory references in INSN
kono
parents: 67
diff changeset
266 and return true if there were no other (unrecorded) references to the
kono
parents: 67
diff changeset
267 stack pointer. For debug insns, record all stack references regardless
kono
parents: 67
diff changeset
268 of context and unconditionally return true. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
269
111
kono
parents: 67
diff changeset
270 static bool
kono
parents: 67
diff changeset
271 record_stack_refs (rtx_insn *insn, struct csa_reflist **reflist)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
272 {
111
kono
parents: 67
diff changeset
273 subrtx_ptr_iterator::array_type array;
kono
parents: 67
diff changeset
274 FOR_EACH_SUBRTX_PTR (iter, array, &PATTERN (insn), NONCONST)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
275 {
111
kono
parents: 67
diff changeset
276 rtx *loc = *iter;
kono
parents: 67
diff changeset
277 rtx x = *loc;
kono
parents: 67
diff changeset
278 switch (GET_CODE (x))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
279 {
111
kono
parents: 67
diff changeset
280 case MEM:
kono
parents: 67
diff changeset
281 if (!reg_mentioned_p (stack_pointer_rtx, x))
kono
parents: 67
diff changeset
282 iter.skip_subrtxes ();
kono
parents: 67
diff changeset
283 /* We are not able to handle correctly all possible memrefs
kono
parents: 67
diff changeset
284 containing stack pointer, so this check is necessary. */
kono
parents: 67
diff changeset
285 else if (stack_memref_p (x))
kono
parents: 67
diff changeset
286 {
kono
parents: 67
diff changeset
287 *reflist = record_one_stack_ref (insn, loc, *reflist);
kono
parents: 67
diff changeset
288 iter.skip_subrtxes ();
kono
parents: 67
diff changeset
289 }
kono
parents: 67
diff changeset
290 /* Try harder for DEBUG_INSNs, handle e.g.
kono
parents: 67
diff changeset
291 (mem (mem (sp + 16) + 4). */
kono
parents: 67
diff changeset
292 else if (!DEBUG_INSN_P (insn))
kono
parents: 67
diff changeset
293 return false;
kono
parents: 67
diff changeset
294 break;
kono
parents: 67
diff changeset
295
kono
parents: 67
diff changeset
296 case REG:
kono
parents: 67
diff changeset
297 /* ??? We want be able to handle non-memory stack pointer
kono
parents: 67
diff changeset
298 references later. For now just discard all insns referring to
kono
parents: 67
diff changeset
299 stack pointer outside mem expressions. We would probably
kono
parents: 67
diff changeset
300 want to teach validate_replace to simplify expressions first.
kono
parents: 67
diff changeset
301
kono
parents: 67
diff changeset
302 We can't just compare with STACK_POINTER_RTX because the
kono
parents: 67
diff changeset
303 reference to the stack pointer might be in some other mode.
kono
parents: 67
diff changeset
304 In particular, an explicit clobber in an asm statement will
kono
parents: 67
diff changeset
305 result in a QImode clobber.
kono
parents: 67
diff changeset
306
kono
parents: 67
diff changeset
307 In DEBUG_INSNs, we want to replace all occurrences, otherwise
kono
parents: 67
diff changeset
308 they will cause -fcompare-debug failures. */
kono
parents: 67
diff changeset
309 if (REGNO (x) == STACK_POINTER_REGNUM)
kono
parents: 67
diff changeset
310 {
kono
parents: 67
diff changeset
311 if (!DEBUG_INSN_P (insn))
kono
parents: 67
diff changeset
312 return false;
kono
parents: 67
diff changeset
313 *reflist = record_one_stack_ref (insn, loc, *reflist);
kono
parents: 67
diff changeset
314 }
kono
parents: 67
diff changeset
315 break;
kono
parents: 67
diff changeset
316
kono
parents: 67
diff changeset
317 default:
kono
parents: 67
diff changeset
318 break;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
319 }
111
kono
parents: 67
diff changeset
320 }
kono
parents: 67
diff changeset
321 return true;
kono
parents: 67
diff changeset
322 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
323
111
kono
parents: 67
diff changeset
324 /* If INSN has a REG_ARGS_SIZE note, move it to LAST.
kono
parents: 67
diff changeset
325 AFTER is true iff LAST follows INSN in the instruction stream. */
kono
parents: 67
diff changeset
326
kono
parents: 67
diff changeset
327 static void
kono
parents: 67
diff changeset
328 maybe_move_args_size_note (rtx_insn *last, rtx_insn *insn, bool after)
kono
parents: 67
diff changeset
329 {
kono
parents: 67
diff changeset
330 rtx note, last_note;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
331
111
kono
parents: 67
diff changeset
332 note = find_reg_note (insn, REG_ARGS_SIZE, NULL_RTX);
kono
parents: 67
diff changeset
333 if (note == NULL)
kono
parents: 67
diff changeset
334 return;
kono
parents: 67
diff changeset
335
kono
parents: 67
diff changeset
336 last_note = find_reg_note (last, REG_ARGS_SIZE, NULL_RTX);
kono
parents: 67
diff changeset
337 if (last_note)
kono
parents: 67
diff changeset
338 {
kono
parents: 67
diff changeset
339 /* The ARGS_SIZE notes are *not* cumulative. They represent an
kono
parents: 67
diff changeset
340 absolute value, and the "most recent" note wins. */
kono
parents: 67
diff changeset
341 if (!after)
kono
parents: 67
diff changeset
342 XEXP (last_note, 0) = XEXP (note, 0);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
343 }
111
kono
parents: 67
diff changeset
344 else
kono
parents: 67
diff changeset
345 add_reg_note (last, REG_ARGS_SIZE, XEXP (note, 0));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
346 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
347
111
kono
parents: 67
diff changeset
348 /* Merge any REG_CFA_ADJUST_CFA note from SRC into DST.
kono
parents: 67
diff changeset
349 AFTER is true iff DST follows SRC in the instruction stream. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
350
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
351 static void
111
kono
parents: 67
diff changeset
352 maybe_merge_cfa_adjust (rtx_insn *dst, rtx_insn *src, bool after)
kono
parents: 67
diff changeset
353 {
kono
parents: 67
diff changeset
354 rtx snote = NULL, dnote = NULL;
kono
parents: 67
diff changeset
355 rtx sexp, dexp;
kono
parents: 67
diff changeset
356 rtx exp1, exp2;
kono
parents: 67
diff changeset
357
kono
parents: 67
diff changeset
358 if (RTX_FRAME_RELATED_P (src))
kono
parents: 67
diff changeset
359 snote = find_reg_note (src, REG_CFA_ADJUST_CFA, NULL_RTX);
kono
parents: 67
diff changeset
360 if (snote == NULL)
kono
parents: 67
diff changeset
361 return;
kono
parents: 67
diff changeset
362 sexp = XEXP (snote, 0);
kono
parents: 67
diff changeset
363
kono
parents: 67
diff changeset
364 if (RTX_FRAME_RELATED_P (dst))
kono
parents: 67
diff changeset
365 dnote = find_reg_note (dst, REG_CFA_ADJUST_CFA, NULL_RTX);
kono
parents: 67
diff changeset
366 if (dnote == NULL)
kono
parents: 67
diff changeset
367 {
kono
parents: 67
diff changeset
368 add_reg_note (dst, REG_CFA_ADJUST_CFA, sexp);
kono
parents: 67
diff changeset
369 return;
kono
parents: 67
diff changeset
370 }
kono
parents: 67
diff changeset
371 dexp = XEXP (dnote, 0);
kono
parents: 67
diff changeset
372
kono
parents: 67
diff changeset
373 gcc_assert (GET_CODE (sexp) == SET);
kono
parents: 67
diff changeset
374 gcc_assert (GET_CODE (dexp) == SET);
kono
parents: 67
diff changeset
375
kono
parents: 67
diff changeset
376 if (after)
kono
parents: 67
diff changeset
377 exp1 = dexp, exp2 = sexp;
kono
parents: 67
diff changeset
378 else
kono
parents: 67
diff changeset
379 exp1 = sexp, exp2 = dexp;
kono
parents: 67
diff changeset
380
kono
parents: 67
diff changeset
381 SET_SRC (exp1) = simplify_replace_rtx (SET_SRC (exp1), SET_DEST (exp2),
kono
parents: 67
diff changeset
382 SET_SRC (exp2));
kono
parents: 67
diff changeset
383 XEXP (dnote, 0) = exp1;
kono
parents: 67
diff changeset
384 }
kono
parents: 67
diff changeset
385
kono
parents: 67
diff changeset
386 /* Return the next (or previous) active insn within BB. */
kono
parents: 67
diff changeset
387
kono
parents: 67
diff changeset
388 static rtx_insn *
kono
parents: 67
diff changeset
389 prev_active_insn_bb (basic_block bb, rtx_insn *insn)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
390 {
111
kono
parents: 67
diff changeset
391 for (insn = PREV_INSN (insn);
kono
parents: 67
diff changeset
392 insn != PREV_INSN (BB_HEAD (bb));
kono
parents: 67
diff changeset
393 insn = PREV_INSN (insn))
kono
parents: 67
diff changeset
394 if (active_insn_p (insn))
kono
parents: 67
diff changeset
395 return insn;
kono
parents: 67
diff changeset
396 return NULL;
kono
parents: 67
diff changeset
397 }
kono
parents: 67
diff changeset
398
kono
parents: 67
diff changeset
399 static rtx_insn *
kono
parents: 67
diff changeset
400 next_active_insn_bb (basic_block bb, rtx_insn *insn)
kono
parents: 67
diff changeset
401 {
kono
parents: 67
diff changeset
402 for (insn = NEXT_INSN (insn);
kono
parents: 67
diff changeset
403 insn != NEXT_INSN (BB_END (bb));
kono
parents: 67
diff changeset
404 insn = NEXT_INSN (insn))
kono
parents: 67
diff changeset
405 if (active_insn_p (insn))
kono
parents: 67
diff changeset
406 return insn;
kono
parents: 67
diff changeset
407 return NULL;
kono
parents: 67
diff changeset
408 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
409
111
kono
parents: 67
diff changeset
410 /* If INSN has a REG_ARGS_SIZE note, if possible move it to PREV. Otherwise
kono
parents: 67
diff changeset
411 search for a nearby candidate within BB where we can stick the note. */
kono
parents: 67
diff changeset
412
kono
parents: 67
diff changeset
413 static void
kono
parents: 67
diff changeset
414 force_move_args_size_note (basic_block bb, rtx_insn *prev, rtx_insn *insn)
kono
parents: 67
diff changeset
415 {
kono
parents: 67
diff changeset
416 rtx note;
kono
parents: 67
diff changeset
417 rtx_insn *test, *next_candidate, *prev_candidate;
kono
parents: 67
diff changeset
418
kono
parents: 67
diff changeset
419 /* If PREV exists, tail-call to the logic in the other function. */
kono
parents: 67
diff changeset
420 if (prev)
kono
parents: 67
diff changeset
421 {
kono
parents: 67
diff changeset
422 maybe_move_args_size_note (prev, insn, false);
kono
parents: 67
diff changeset
423 return;
kono
parents: 67
diff changeset
424 }
kono
parents: 67
diff changeset
425
kono
parents: 67
diff changeset
426 /* First, make sure there's anything that needs doing. */
kono
parents: 67
diff changeset
427 note = find_reg_note (insn, REG_ARGS_SIZE, NULL_RTX);
kono
parents: 67
diff changeset
428 if (note == NULL)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
429 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
430
111
kono
parents: 67
diff changeset
431 /* We need to find a spot between the previous and next exception points
kono
parents: 67
diff changeset
432 where we can place the note and "properly" deallocate the arguments. */
kono
parents: 67
diff changeset
433 next_candidate = prev_candidate = NULL;
kono
parents: 67
diff changeset
434
kono
parents: 67
diff changeset
435 /* It is often the case that we have insns in the order:
kono
parents: 67
diff changeset
436 call
kono
parents: 67
diff changeset
437 add sp (previous deallocation)
kono
parents: 67
diff changeset
438 sub sp (align for next arglist)
kono
parents: 67
diff changeset
439 push arg
kono
parents: 67
diff changeset
440 and the add/sub cancel. Therefore we begin by searching forward. */
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
441
111
kono
parents: 67
diff changeset
442 test = insn;
kono
parents: 67
diff changeset
443 while ((test = next_active_insn_bb (bb, test)) != NULL)
kono
parents: 67
diff changeset
444 {
kono
parents: 67
diff changeset
445 /* Found an existing note: nothing to do. */
kono
parents: 67
diff changeset
446 if (find_reg_note (test, REG_ARGS_SIZE, NULL_RTX))
kono
parents: 67
diff changeset
447 return;
kono
parents: 67
diff changeset
448 /* Found something that affects unwinding. Stop searching. */
kono
parents: 67
diff changeset
449 if (CALL_P (test) || !insn_nothrow_p (test))
kono
parents: 67
diff changeset
450 break;
kono
parents: 67
diff changeset
451 if (next_candidate == NULL)
kono
parents: 67
diff changeset
452 next_candidate = test;
kono
parents: 67
diff changeset
453 }
kono
parents: 67
diff changeset
454
kono
parents: 67
diff changeset
455 test = insn;
kono
parents: 67
diff changeset
456 while ((test = prev_active_insn_bb (bb, test)) != NULL)
kono
parents: 67
diff changeset
457 {
kono
parents: 67
diff changeset
458 rtx tnote;
kono
parents: 67
diff changeset
459 /* Found a place that seems logical to adjust the stack. */
kono
parents: 67
diff changeset
460 tnote = find_reg_note (test, REG_ARGS_SIZE, NULL_RTX);
kono
parents: 67
diff changeset
461 if (tnote)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
462 {
111
kono
parents: 67
diff changeset
463 XEXP (tnote, 0) = XEXP (note, 0);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
464 return;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
465 }
111
kono
parents: 67
diff changeset
466 if (prev_candidate == NULL)
kono
parents: 67
diff changeset
467 prev_candidate = test;
kono
parents: 67
diff changeset
468 /* Found something that affects unwinding. Stop searching. */
kono
parents: 67
diff changeset
469 if (CALL_P (test) || !insn_nothrow_p (test))
kono
parents: 67
diff changeset
470 break;
kono
parents: 67
diff changeset
471 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
472
111
kono
parents: 67
diff changeset
473 if (prev_candidate)
kono
parents: 67
diff changeset
474 test = prev_candidate;
kono
parents: 67
diff changeset
475 else if (next_candidate)
kono
parents: 67
diff changeset
476 test = next_candidate;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
477 else
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
478 {
111
kono
parents: 67
diff changeset
479 /* ??? We *must* have a place, lest we ICE on the lost adjustment.
kono
parents: 67
diff changeset
480 Options are: dummy clobber insn, nop, or prevent the removal of
kono
parents: 67
diff changeset
481 the sp += 0 insn. */
kono
parents: 67
diff changeset
482 /* TODO: Find another way to indicate to the dwarf2 code that we
kono
parents: 67
diff changeset
483 have not in fact lost an adjustment. */
kono
parents: 67
diff changeset
484 test = emit_insn_before (gen_rtx_CLOBBER (VOIDmode, const0_rtx), insn);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
485 }
111
kono
parents: 67
diff changeset
486 add_reg_note (test, REG_ARGS_SIZE, XEXP (note, 0));
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
487 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
488
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
489 /* Subroutine of combine_stack_adjustments, called for each basic block. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
490
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
491 static void
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
492 combine_stack_adjustments_for_block (basic_block bb)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
493 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
494 HOST_WIDE_INT last_sp_adjust = 0;
111
kono
parents: 67
diff changeset
495 rtx_insn *last_sp_set = NULL;
kono
parents: 67
diff changeset
496 rtx_insn *last2_sp_set = NULL;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
497 struct csa_reflist *reflist = NULL;
111
kono
parents: 67
diff changeset
498 rtx_insn *insn, *next;
kono
parents: 67
diff changeset
499 rtx set;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
500 bool end_of_block = false;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
501
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
502 for (insn = BB_HEAD (bb); !end_of_block ; insn = next)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
503 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
504 end_of_block = insn == BB_END (bb);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
505 next = NEXT_INSN (insn);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
506
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
507 if (! INSN_P (insn))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
508 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
509
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
510 set = single_set_for_csa (insn);
111
kono
parents: 67
diff changeset
511 if (set && find_reg_note (insn, REG_STACK_CHECK, NULL_RTX))
kono
parents: 67
diff changeset
512 set = NULL_RTX;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
513 if (set)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
514 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
515 rtx dest = SET_DEST (set);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
516 rtx src = SET_SRC (set);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
517
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
518 /* Find constant additions to the stack pointer. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
519 if (dest == stack_pointer_rtx
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
520 && GET_CODE (src) == PLUS
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
521 && XEXP (src, 0) == stack_pointer_rtx
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
522 && CONST_INT_P (XEXP (src, 1)))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
523 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
524 HOST_WIDE_INT this_adjust = INTVAL (XEXP (src, 1));
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
525
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
526 /* If we've not seen an adjustment previously, record
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
527 it now and continue. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
528 if (! last_sp_set)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
529 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
530 last_sp_set = insn;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
531 last_sp_adjust = this_adjust;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
532 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
533 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
534
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
535 /* If not all recorded refs can be adjusted, or the
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
536 adjustment is now too large for a constant addition,
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
537 we cannot merge the two stack adjustments.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
538
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
539 Also we need to be careful to not move stack pointer
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
540 such that we create stack accesses outside the allocated
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
541 area. We can combine an allocation into the first insn,
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
542 or a deallocation into the second insn. We cannot
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
543 combine an allocation followed by a deallocation.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
544
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
545 The only somewhat frequent occurrence of the later is when
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
546 a function allocates a stack frame but does not use it.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
547 For this case, we would need to analyze rtl stream to be
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
548 sure that allocated area is really unused. This means not
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
549 only checking the memory references, but also all registers
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
550 or global memory references possibly containing a stack
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
551 frame address.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
552
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
553 Perhaps the best way to address this problem is to teach
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
554 gcc not to allocate stack for objects never used. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
555
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
556 /* Combine an allocation into the first instruction. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
557 if (STACK_GROWS_DOWNWARD ? this_adjust <= 0 : this_adjust >= 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
558 {
111
kono
parents: 67
diff changeset
559 if (no_unhandled_cfa (insn)
kono
parents: 67
diff changeset
560 && try_apply_stack_adjustment (last_sp_set, reflist,
kono
parents: 67
diff changeset
561 last_sp_adjust
kono
parents: 67
diff changeset
562 + this_adjust,
kono
parents: 67
diff changeset
563 this_adjust))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
564 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
565 /* It worked! */
111
kono
parents: 67
diff changeset
566 maybe_move_args_size_note (last_sp_set, insn, false);
kono
parents: 67
diff changeset
567 maybe_merge_cfa_adjust (last_sp_set, insn, false);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
568 delete_insn (insn);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
569 last_sp_adjust += this_adjust;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
570 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
571 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
572 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
573
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
574 /* Otherwise we have a deallocation. Do not combine with
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
575 a previous allocation. Combine into the second insn. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
576 else if (STACK_GROWS_DOWNWARD
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
577 ? last_sp_adjust >= 0 : last_sp_adjust <= 0)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
578 {
111
kono
parents: 67
diff changeset
579 if (no_unhandled_cfa (last_sp_set)
kono
parents: 67
diff changeset
580 && try_apply_stack_adjustment (insn, reflist,
kono
parents: 67
diff changeset
581 last_sp_adjust
kono
parents: 67
diff changeset
582 + this_adjust,
kono
parents: 67
diff changeset
583 -last_sp_adjust))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
584 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
585 /* It worked! */
111
kono
parents: 67
diff changeset
586 maybe_move_args_size_note (insn, last_sp_set, true);
kono
parents: 67
diff changeset
587 maybe_merge_cfa_adjust (insn, last_sp_set, true);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
588 delete_insn (last_sp_set);
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
589 last_sp_set = insn;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
590 last_sp_adjust += this_adjust;
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
591 free_csa_reflist (reflist);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
592 reflist = NULL;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
593 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
594 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
595 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
596
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
597 /* Combination failed. Restart processing from here. If
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
598 deallocation+allocation conspired to cancel, we can
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
599 delete the old deallocation insn. */
111
kono
parents: 67
diff changeset
600 if (last_sp_set)
kono
parents: 67
diff changeset
601 {
kono
parents: 67
diff changeset
602 if (last_sp_adjust == 0 && no_unhandled_cfa (last_sp_set))
kono
parents: 67
diff changeset
603 {
kono
parents: 67
diff changeset
604 maybe_move_args_size_note (insn, last_sp_set, true);
kono
parents: 67
diff changeset
605 maybe_merge_cfa_adjust (insn, last_sp_set, true);
kono
parents: 67
diff changeset
606 delete_insn (last_sp_set);
kono
parents: 67
diff changeset
607 }
kono
parents: 67
diff changeset
608 else
kono
parents: 67
diff changeset
609 last2_sp_set = last_sp_set;
kono
parents: 67
diff changeset
610 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
611 free_csa_reflist (reflist);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
612 reflist = NULL;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
613 last_sp_set = insn;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
614 last_sp_adjust = this_adjust;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
615 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
616 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
617
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
618 /* Find a store with pre-(dec|inc)rement or pre-modify of exactly
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
619 the previous adjustment and turn it into a simple store. This
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
620 is equivalent to anticipating the stack adjustment so this must
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
621 be an allocation. */
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
622 if (MEM_P (dest)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
623 && ((STACK_GROWS_DOWNWARD
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
624 ? (GET_CODE (XEXP (dest, 0)) == PRE_DEC
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
625 && known_eq (last_sp_adjust,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
626 GET_MODE_SIZE (GET_MODE (dest))))
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
627 : (GET_CODE (XEXP (dest, 0)) == PRE_INC
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
628 && known_eq (-last_sp_adjust,
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
629 GET_MODE_SIZE (GET_MODE (dest)))))
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
630 || ((STACK_GROWS_DOWNWARD
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
631 ? last_sp_adjust >= 0 : last_sp_adjust <= 0)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
632 && GET_CODE (XEXP (dest, 0)) == PRE_MODIFY
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
633 && GET_CODE (XEXP (XEXP (dest, 0), 1)) == PLUS
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
634 && XEXP (XEXP (XEXP (dest, 0), 1), 0)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
635 == stack_pointer_rtx
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
636 && GET_CODE (XEXP (XEXP (XEXP (dest, 0), 1), 1))
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
637 == CONST_INT
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
638 && INTVAL (XEXP (XEXP (XEXP (dest, 0), 1), 1))
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
639 == -last_sp_adjust))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
640 && XEXP (XEXP (dest, 0), 0) == stack_pointer_rtx
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
641 && !reg_mentioned_p (stack_pointer_rtx, src)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
642 && memory_address_p (GET_MODE (dest), stack_pointer_rtx)
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
643 && try_apply_stack_adjustment (insn, reflist, 0,
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
644 -last_sp_adjust))
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
645 {
111
kono
parents: 67
diff changeset
646 if (last2_sp_set)
kono
parents: 67
diff changeset
647 maybe_move_args_size_note (last2_sp_set, last_sp_set, false);
kono
parents: 67
diff changeset
648 else
kono
parents: 67
diff changeset
649 maybe_move_args_size_note (insn, last_sp_set, true);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
650 delete_insn (last_sp_set);
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
651 free_csa_reflist (reflist);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
652 reflist = NULL;
111
kono
parents: 67
diff changeset
653 last_sp_set = NULL;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
654 last_sp_adjust = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
655 continue;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
656 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
657 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
658
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
659 if (!CALL_P (insn) && last_sp_set
111
kono
parents: 67
diff changeset
660 && record_stack_refs (insn, &reflist))
kono
parents: 67
diff changeset
661 continue;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
662
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
663 /* Otherwise, we were not able to process the instruction.
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
664 Do not continue collecting data across such a one. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
665 if (last_sp_set
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
666 && (CALL_P (insn)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
667 || reg_mentioned_p (stack_pointer_rtx, PATTERN (insn))))
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
668 {
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
669 if (last_sp_set && last_sp_adjust == 0)
111
kono
parents: 67
diff changeset
670 {
kono
parents: 67
diff changeset
671 force_move_args_size_note (bb, last2_sp_set, last_sp_set);
kono
parents: 67
diff changeset
672 delete_insn (last_sp_set);
kono
parents: 67
diff changeset
673 }
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
674 free_csa_reflist (reflist);
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
675 reflist = NULL;
111
kono
parents: 67
diff changeset
676 last2_sp_set = NULL;
kono
parents: 67
diff changeset
677 last_sp_set = NULL;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
678 last_sp_adjust = 0;
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
679 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
680 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
681
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
682 if (last_sp_set && last_sp_adjust == 0)
111
kono
parents: 67
diff changeset
683 {
kono
parents: 67
diff changeset
684 force_move_args_size_note (bb, last2_sp_set, last_sp_set);
kono
parents: 67
diff changeset
685 delete_insn (last_sp_set);
kono
parents: 67
diff changeset
686 }
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
687
55
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
688 if (reflist)
77e2b8dfacca update it from 4.4.3 to 4.5.0
ryoma <e075725@ie.u-ryukyu.ac.jp>
parents: 0
diff changeset
689 free_csa_reflist (reflist);
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
690 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
691
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
692 static unsigned int
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
693 rest_of_handle_stack_adjustments (void)
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
694 {
111
kono
parents: 67
diff changeset
695 df_note_add_problem ();
kono
parents: 67
diff changeset
696 df_analyze ();
kono
parents: 67
diff changeset
697 combine_stack_adjustments ();
kono
parents: 67
diff changeset
698 return 0;
kono
parents: 67
diff changeset
699 }
kono
parents: 67
diff changeset
700
kono
parents: 67
diff changeset
701 namespace {
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
702
111
kono
parents: 67
diff changeset
703 const pass_data pass_data_stack_adjustments =
kono
parents: 67
diff changeset
704 {
kono
parents: 67
diff changeset
705 RTL_PASS, /* type */
kono
parents: 67
diff changeset
706 "csa", /* name */
kono
parents: 67
diff changeset
707 OPTGROUP_NONE, /* optinfo_flags */
kono
parents: 67
diff changeset
708 TV_COMBINE_STACK_ADJUST, /* tv_id */
kono
parents: 67
diff changeset
709 0, /* properties_required */
kono
parents: 67
diff changeset
710 0, /* properties_provided */
kono
parents: 67
diff changeset
711 0, /* properties_destroyed */
kono
parents: 67
diff changeset
712 0, /* todo_flags_start */
kono
parents: 67
diff changeset
713 TODO_df_finish, /* todo_flags_finish */
kono
parents: 67
diff changeset
714 };
kono
parents: 67
diff changeset
715
kono
parents: 67
diff changeset
716 class pass_stack_adjustments : public rtl_opt_pass
kono
parents: 67
diff changeset
717 {
kono
parents: 67
diff changeset
718 public:
kono
parents: 67
diff changeset
719 pass_stack_adjustments (gcc::context *ctxt)
kono
parents: 67
diff changeset
720 : rtl_opt_pass (pass_data_stack_adjustments, ctxt)
kono
parents: 67
diff changeset
721 {}
kono
parents: 67
diff changeset
722
kono
parents: 67
diff changeset
723 /* opt_pass methods: */
kono
parents: 67
diff changeset
724 virtual bool gate (function *);
kono
parents: 67
diff changeset
725 virtual unsigned int execute (function *)
kono
parents: 67
diff changeset
726 {
kono
parents: 67
diff changeset
727 return rest_of_handle_stack_adjustments ();
kono
parents: 67
diff changeset
728 }
kono
parents: 67
diff changeset
729
kono
parents: 67
diff changeset
730 }; // class pass_stack_adjustments
kono
parents: 67
diff changeset
731
kono
parents: 67
diff changeset
732 bool
kono
parents: 67
diff changeset
733 pass_stack_adjustments::gate (function *)
kono
parents: 67
diff changeset
734 {
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
735 /* This is kind of a heuristic. We need to run combine_stack_adjustments
67
f6334be47118 update gcc from gcc-4.6-20100522 to gcc-4.6-20110318
nobuyasu <dimolto@cr.ie.u-ryukyu.ac.jp>
parents: 55
diff changeset
736 even for machines with possibly nonzero TARGET_RETURN_POPS_ARGS
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
737 and ACCUMULATE_OUTGOING_ARGS. We expect that only ports having
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
738 push instructions will have popping returns. */
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
739 #ifndef PUSH_ROUNDING
111
kono
parents: 67
diff changeset
740 if (ACCUMULATE_OUTGOING_ARGS)
kono
parents: 67
diff changeset
741 return false;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
742 #endif
111
kono
parents: 67
diff changeset
743 return flag_combine_stack_adjustments;
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
744 }
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
745
111
kono
parents: 67
diff changeset
746 } // anon namespace
kono
parents: 67
diff changeset
747
kono
parents: 67
diff changeset
748 rtl_opt_pass *
kono
parents: 67
diff changeset
749 make_pass_stack_adjustments (gcc::context *ctxt)
0
a06113de4d67 first commit
kent <kent@cr.ie.u-ryukyu.ac.jp>
parents:
diff changeset
750 {
111
kono
parents: 67
diff changeset
751 return new pass_stack_adjustments (ctxt);
kono
parents: 67
diff changeset
752 }