python-dataproperty: bump version to 0.17.0
[buildroot-gz.git] / package / gcc / 6.3.0 / 870-xtensa-Fix-PR-target-78118.patch
blob0598c76c2f4fe6dbc0c8bd6a24e3ecf81f6a437d
1 From 0d2556fa652cc85b3d042e862a38dd07d454175a Mon Sep 17 00:00:00 2001
2 From: Max Filippov <jcmvbkbc@gmail.com>
3 Date: Wed, 26 Oct 2016 08:02:51 +0000
4 Subject: [PATCH 1/2] xtensa: Fix PR target/78118
6 It started failing after the following commit: 32e90dc6a0cda45 ("PR
7 rtl-optimization/61047").
9 The change that made xtensa backend go ICE looks completely unrelated,
10 and indeed, the issue is caused by the side effect of
11 compute_frame_size() function call hidden in the
12 INITIAL_ELIMINATION_OFFSET macro. This call updates the value of the
13 xtensa_current_frame_size static variable, used in "return" instruction
14 predicate. Prior to the change the value of xtensa_current_frame_size was
15 set to 0 after the end of epilogue generation, which enabled the "return"
16 instruction for the CALL0 ABI, but after the change the additional
17 INITIAL_ELIMINATION_OFFSET calls make xtensa_current_frame_size non-zero
18 and "return" pattern unavailable.
20 Get rid of the global xtensa_current_frame_size and
21 xtensa_callee_save_size variables by moving them into the
22 machine_function structure. Implement predicate for the "return" pattern
23 as a function. Don't communicate completion of epilogue generation
24 through zeroing of xtensa_current_frame_size, add explicit epilogue_done
25 variable to the machine_function structure. Don't update stack frame
26 layout after the completion of reload.
28 2016-10-26 Max Filippov <jcmvbkbc@gmail.com>
29 gcc/
30 * config/xtensa/xtensa-protos.h
31 (xtensa_use_return_instruction_p): New prototype.
32 * config/xtensa/xtensa.c (xtensa_current_frame_size,
33 xtensa_callee_save_size): Remove.
34 (struct machine_function): Add new fields: current_frame_size,
35 callee_save_size, frame_laid_out and epilogue_done.
36 (compute_frame_size, xtensa_expand_prologue,
37 xtensa_expand_epilogue): Replace xtensa_callee_save_size with
38 cfun->machine->callee_save_size and xtensa_current_frame_size
39 with cfun->machine->current_frame_size.
40 (compute_frame_size): Update cfun->machine->frame_laid_out and
41 don't update frame layout after reload completion.
42 (xtensa_expand_epilogue): Set cfun->machine->epilogue_done
43 instead of zeroing xtensa_current_frame_size.
44 (xtensa_use_return_instruction_p): New function.
45 * config/xtensa/xtensa.h (xtensa_current_frame_size): Remove
46 declaration.
47 (INITIAL_ELIMINATION_OFFSET): Use return value of
48 compute_frame_size instead of xtensa_current_frame_size value.
49 * config/xtensa/xtensa.md ("return" pattern): Use new predicate
50 function xtensa_use_return_instruction_p instead of inline code.
52 Signed-off-by: Max Filippov <jcmvbkbc@gmail.com>
53 ---
54 Backported from: r241748
56 gcc/config/xtensa/xtensa-protos.h | 1 +
57 gcc/config/xtensa/xtensa.c | 82 ++++++++++++++++++++++++---------------
58 gcc/config/xtensa/xtensa.h | 6 +--
59 gcc/config/xtensa/xtensa.md | 2 +-
60 4 files changed, 55 insertions(+), 36 deletions(-)
62 diff --git a/gcc/config/xtensa/xtensa-protos.h b/gcc/config/xtensa/xtensa-protos.h
63 index f2ca526..873557f 100644
64 --- a/gcc/config/xtensa/xtensa-protos.h
65 +++ b/gcc/config/xtensa/xtensa-protos.h
66 @@ -68,6 +68,7 @@ extern rtx xtensa_return_addr (int, rtx);
67 extern void xtensa_setup_frame_addresses (void);
68 extern int xtensa_dbx_register_number (int);
69 extern long compute_frame_size (int);
70 +extern bool xtensa_use_return_instruction_p (void);
71 extern void xtensa_expand_prologue (void);
72 extern void xtensa_expand_epilogue (void);
73 extern void order_regs_for_local_alloc (void);
74 diff --git a/gcc/config/xtensa/xtensa.c b/gcc/config/xtensa/xtensa.c
75 index 64d089b..e49f784 100644
76 --- a/gcc/config/xtensa/xtensa.c
77 +++ b/gcc/config/xtensa/xtensa.c
78 @@ -78,11 +78,6 @@ enum internal_test
79 can support a given mode. */
80 char xtensa_hard_regno_mode_ok[(int) MAX_MACHINE_MODE][FIRST_PSEUDO_REGISTER];
82 -/* Current frame size calculated by compute_frame_size. */
83 -unsigned xtensa_current_frame_size;
84 -/* Callee-save area size in the current frame calculated by compute_frame_size. */
85 -int xtensa_callee_save_size;
87 /* Largest block move to handle in-line. */
88 #define LARGEST_MOVE_RATIO 15
90 @@ -94,6 +89,13 @@ struct GTY(()) machine_function
91 bool vararg_a7;
92 rtx vararg_a7_copy;
93 rtx_insn *set_frame_ptr_insn;
94 + /* Current frame size calculated by compute_frame_size. */
95 + unsigned current_frame_size;
96 + /* Callee-save area size in the current frame calculated by
97 + compute_frame_size. */
98 + int callee_save_size;
99 + bool frame_laid_out;
100 + bool epilogue_done;
103 /* Vector, indexed by hard register number, which contains 1 for a
104 @@ -2628,24 +2630,29 @@ compute_frame_size (int size)
106 int regno;
108 + if (reload_completed && cfun->machine->frame_laid_out)
109 + return cfun->machine->current_frame_size;
111 /* Add space for the incoming static chain value. */
112 if (cfun->static_chain_decl != NULL)
113 size += (1 * UNITS_PER_WORD);
115 - xtensa_callee_save_size = 0;
116 + cfun->machine->callee_save_size = 0;
117 for (regno = 0; regno < FIRST_PSEUDO_REGISTER; ++regno)
119 if (xtensa_call_save_reg(regno))
120 - xtensa_callee_save_size += UNITS_PER_WORD;
121 + cfun->machine->callee_save_size += UNITS_PER_WORD;
124 - xtensa_current_frame_size =
125 + cfun->machine->current_frame_size =
126 XTENSA_STACK_ALIGN (size
127 - + xtensa_callee_save_size
128 + + cfun->machine->callee_save_size
129 + crtl->outgoing_args_size
130 + (WINDOW_SIZE * UNITS_PER_WORD));
131 - xtensa_callee_save_size = XTENSA_STACK_ALIGN (xtensa_callee_save_size);
132 - return xtensa_current_frame_size;
133 + cfun->machine->callee_save_size =
134 + XTENSA_STACK_ALIGN (cfun->machine->callee_save_size);
135 + cfun->machine->frame_laid_out = true;
136 + return cfun->machine->current_frame_size;
140 @@ -2696,6 +2703,7 @@ xtensa_expand_prologue (void)
142 int regno;
143 HOST_WIDE_INT offset = 0;
144 + int callee_save_size = cfun->machine->callee_save_size;
146 /* -128 is a limit of single addi instruction. */
147 if (total_size > 0 && total_size <= 128)
148 @@ -2709,7 +2717,7 @@ xtensa_expand_prologue (void)
149 add_reg_note (insn, REG_FRAME_RELATED_EXPR, note_rtx);
150 offset = total_size - UNITS_PER_WORD;
152 - else if (xtensa_callee_save_size)
153 + else if (callee_save_size)
155 /* 1020 is maximal s32i offset, if the frame is bigger than that
156 * we move sp to the end of callee-saved save area, save and then
157 @@ -2717,13 +2725,13 @@ xtensa_expand_prologue (void)
158 if (total_size > 1024)
160 insn = emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
161 - GEN_INT (-xtensa_callee_save_size)));
162 + GEN_INT (-callee_save_size)));
163 RTX_FRAME_RELATED_P (insn) = 1;
164 note_rtx = gen_rtx_SET (stack_pointer_rtx,
165 plus_constant (Pmode, stack_pointer_rtx,
166 - -xtensa_callee_save_size));
167 + -callee_save_size));
168 add_reg_note (insn, REG_FRAME_RELATED_EXPR, note_rtx);
169 - offset = xtensa_callee_save_size - UNITS_PER_WORD;
170 + offset = callee_save_size - UNITS_PER_WORD;
172 else
174 @@ -2759,13 +2767,13 @@ xtensa_expand_prologue (void)
176 rtx tmp_reg = gen_rtx_REG (Pmode, A9_REG);
177 emit_move_insn (tmp_reg, GEN_INT (total_size -
178 - xtensa_callee_save_size));
179 + callee_save_size));
180 insn = emit_insn (gen_subsi3 (stack_pointer_rtx,
181 stack_pointer_rtx, tmp_reg));
182 RTX_FRAME_RELATED_P (insn) = 1;
183 note_rtx = gen_rtx_SET (stack_pointer_rtx,
184 plus_constant (Pmode, stack_pointer_rtx,
185 - xtensa_callee_save_size -
186 + callee_save_size -
187 total_size));
188 add_reg_note (insn, REG_FRAME_RELATED_EXPR, note_rtx);
190 @@ -2833,21 +2841,21 @@ xtensa_expand_epilogue (void)
191 int regno;
192 HOST_WIDE_INT offset;
194 - if (xtensa_current_frame_size > (frame_pointer_needed ? 127 : 1024))
195 + if (cfun->machine->current_frame_size > (frame_pointer_needed ? 127 : 1024))
197 rtx tmp_reg = gen_rtx_REG (Pmode, A9_REG);
198 - emit_move_insn (tmp_reg, GEN_INT (xtensa_current_frame_size -
199 - xtensa_callee_save_size));
200 + emit_move_insn (tmp_reg, GEN_INT (cfun->machine->current_frame_size -
201 + cfun->machine->callee_save_size));
202 emit_insn (gen_addsi3 (stack_pointer_rtx, frame_pointer_needed ?
203 hard_frame_pointer_rtx : stack_pointer_rtx,
204 tmp_reg));
205 - offset = xtensa_callee_save_size - UNITS_PER_WORD;
206 + offset = cfun->machine->callee_save_size - UNITS_PER_WORD;
208 else
210 if (frame_pointer_needed)
211 emit_move_insn (stack_pointer_rtx, hard_frame_pointer_rtx);
212 - offset = xtensa_current_frame_size - UNITS_PER_WORD;
213 + offset = cfun->machine->current_frame_size - UNITS_PER_WORD;
216 /* Prevent reordering of saved a0 update and loading it back from
217 @@ -2867,16 +2875,16 @@ xtensa_expand_epilogue (void)
221 - if (xtensa_current_frame_size > 0)
222 + if (cfun->machine->current_frame_size > 0)
224 if (frame_pointer_needed || /* always reachable with addi */
225 - xtensa_current_frame_size > 1024 ||
226 - xtensa_current_frame_size <= 127)
227 + cfun->machine->current_frame_size > 1024 ||
228 + cfun->machine->current_frame_size <= 127)
230 - if (xtensa_current_frame_size <= 127)
231 - offset = xtensa_current_frame_size;
232 + if (cfun->machine->current_frame_size <= 127)
233 + offset = cfun->machine->current_frame_size;
234 else
235 - offset = xtensa_callee_save_size;
236 + offset = cfun->machine->callee_save_size;
238 emit_insn (gen_addsi3 (stack_pointer_rtx,
239 stack_pointer_rtx,
240 @@ -2885,7 +2893,8 @@ xtensa_expand_epilogue (void)
241 else
243 rtx tmp_reg = gen_rtx_REG (Pmode, A9_REG);
244 - emit_move_insn (tmp_reg, GEN_INT (xtensa_current_frame_size));
245 + emit_move_insn (tmp_reg,
246 + GEN_INT (cfun->machine->current_frame_size));
247 emit_insn (gen_addsi3 (stack_pointer_rtx, stack_pointer_rtx,
248 tmp_reg));
250 @@ -2896,11 +2905,22 @@ xtensa_expand_epilogue (void)
251 stack_pointer_rtx,
252 EH_RETURN_STACKADJ_RTX));
254 - xtensa_current_frame_size = 0;
255 - xtensa_callee_save_size = 0;
256 + cfun->machine->epilogue_done = true;
257 emit_jump_insn (gen_return ());
260 +bool
261 +xtensa_use_return_instruction_p (void)
263 + if (!reload_completed)
264 + return false;
265 + if (TARGET_WINDOWED_ABI)
266 + return true;
267 + if (compute_frame_size (get_frame_size ()) == 0)
268 + return true;
269 + return cfun->machine->epilogue_done;
272 void
273 xtensa_set_return_address (rtx address, rtx scratch)
275 diff --git a/gcc/config/xtensa/xtensa.h b/gcc/config/xtensa/xtensa.h
276 index 82e9900..58eb1b2 100644
277 --- a/gcc/config/xtensa/xtensa.h
278 +++ b/gcc/config/xtensa/xtensa.h
279 @@ -23,8 +23,6 @@ along with GCC; see the file COPYING3. If not see
281 /* External variables defined in xtensa.c. */
283 -extern unsigned xtensa_current_frame_size;
285 /* Macros used in the machine description to select various Xtensa
286 configuration options. */
287 #ifndef XCHAL_HAVE_MUL32_HIGH
288 @@ -477,14 +475,14 @@ enum reg_class
289 /* Specify the initial difference between the specified pair of registers. */
290 #define INITIAL_ELIMINATION_OFFSET(FROM, TO, OFFSET) \
291 do { \
292 - compute_frame_size (get_frame_size ()); \
293 + long frame_size = compute_frame_size (get_frame_size ()); \
294 switch (FROM) \
296 case FRAME_POINTER_REGNUM: \
297 (OFFSET) = 0; \
298 break; \
299 case ARG_POINTER_REGNUM: \
300 - (OFFSET) = xtensa_current_frame_size; \
301 + (OFFSET) = frame_size; \
302 break; \
303 default: \
304 gcc_unreachable (); \
305 diff --git a/gcc/config/xtensa/xtensa.md b/gcc/config/xtensa/xtensa.md
306 index db54a12..fcdb6c8 100644
307 --- a/gcc/config/xtensa/xtensa.md
308 +++ b/gcc/config/xtensa/xtensa.md
309 @@ -1663,7 +1663,7 @@
310 (define_insn "return"
311 [(return)
312 (use (reg:SI A0_REG))]
313 - "(TARGET_WINDOWED_ABI || !xtensa_current_frame_size) && reload_completed"
314 + "xtensa_use_return_instruction_p ()"
316 return TARGET_WINDOWED_ABI ?
317 (TARGET_DENSITY ? "retw.n" : "retw") :
319 2.1.4