comparison gcc/config/riscv/riscv-sr.c @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents
children
comparison
equal deleted inserted replaced
131:84e7813d76e9 145:1830386684a0
1 /* This file is part of GCC.
2
3 GCC is free software; you can redistribute it and/or modify
4 it under the terms of the GNU General Public License as published by
5 the Free Software Foundation; either version 3, or (at your option)
6 any later version.
7
8 GCC is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY; without even the implied warranty of
10 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 GNU General Public License for more details.
12
13 You should have received a copy of the GNU General Public License
14 along with GCC; see the file COPYING3. If not see
15 <http://www.gnu.org/licenses/>. */
16
17 /* This file contains code aimed at optimizing function generated with the
18 use of '-msave-restore. The goal is to identify cases where the call
19 out to the save/restore routines are sub-optimal, and remove the calls
20 in this case.
21
22 As GCC currently makes the choice between using or not using
23 save/restore early on (during the gimple expand pass) once we have
24 selected to use save/restore we are stuck with it. */
25
26 #define IN_TARGET_CODE 1
27
28 #include "config.h"
29 #include "system.h"
30 #include "coretypes.h"
31 #include "tm.h"
32 #include "rtl.h"
33 #include "function.h"
34 #include "memmodel.h"
35 #include "emit-rtl.h"
36 #include "target.h"
37 #include "basic-block.h"
38 #include "bitmap.h"
39 #include "df.h"
40 #include "tree.h"
41 #include "expr.h"
42 #include "cfg.h"
43
44 /* This file should be included last. */
45 #include "hard-reg-set.h"
46
47 /* Look in the function prologue for a call to the save stub. Ensure that
48 the instruction is as we expect (see detail below) and if the
49 instruction matches return a pointer to it. Otherwise, return NULL.
50
51 We expect the function prologue to look like this:
52
53 (note NOTE_INSN_BASIC_BLOCK)
54 (insn (parallel [
55 (unspec_volatile [
56 (const_int 2 [0x2])
57 ] UNSPECV_GPR_SAVE)
58 (clobber (reg:SI 5 t0))
59 (clobber (reg:SI 6 t1))])
60 (note NOTE_INSN_PROLOGUE_END)
61
62 Between the NOTE_INSN_BASIC_BLOCK and the GPR_SAVE insn we might find
63 other notes of type NOTE_INSN_DELETED and/or NOTE_INSN_FUNCTION_BEG.
64
65 The parameter BODY is updated to point to the first instruction after
66 the NOTE_INSN_PROLOGUE_END or will be updated to NULL if the prologue
67 end note was not found. */
68
69 static rtx_insn *
70 riscv_sr_match_prologue (rtx_insn **body)
71 {
72 rtx_insn *insn, *bb_note;
73 *body = NULL;
74
75 /* Find the prologue end note. */
76 for (insn = get_insns (); insn != NULL; insn = NEXT_INSN (insn))
77 if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_PROLOGUE_END)
78 {
79 *body = NEXT_INSN (insn);
80 break;
81 }
82
83 /* If we don't have the prologue end note and at least one instruction
84 before it, then this function doesn't have the structure we expect. */
85 if (insn == NULL
86 || PREV_INSN (insn) == NULL)
87 return NULL;
88
89 /* The INSN is the end of prologue note, before this we expect to find
90 one real instruction which makes the prologue, and before that we
91 expect to find some number of notes for deleted instructions, the
92 beginning of the function, and finally a basicblock beginning. The
93 following loop checks that this assumption is true. */
94 for (bb_note = PREV_INSN (PREV_INSN (insn));
95 bb_note != NULL;
96 bb_note = PREV_INSN (bb_note))
97 {
98 if (!NOTE_P (bb_note))
99 return NULL;
100 if (NOTE_KIND (bb_note) == NOTE_INSN_BASIC_BLOCK)
101 break;
102 if (NOTE_KIND (bb_note) != NOTE_INSN_DELETED
103 && NOTE_KIND (bb_note) != NOTE_INSN_FUNCTION_BEG)
104 return NULL;
105 }
106 if (bb_note == NULL)
107 return NULL;
108
109 /* Set INSN to point to the actual interesting prologue instruction. */
110 insn = PREV_INSN (insn);
111 if (INSN_P (insn)
112 && INSN_CODE (insn) == CODE_FOR_gpr_save
113 /* Check this is a call to _riscv_save_0. */
114 && GET_CODE (PATTERN (insn)) == PARALLEL
115 && GET_CODE (XVECEXP (PATTERN (insn), 0, 0)) == UNSPEC_VOLATILE
116 && (GET_CODE (XVECEXP (XVECEXP (PATTERN (insn), 0, 0), 0, 0))
117 == CONST_INT)
118 && INTVAL (XVECEXP (XVECEXP (PATTERN (insn), 0, 0), 0, 0)) == 2)
119 return insn;
120
121 return NULL;
122 }
123
124 /* Find the first instruction in the epilogue of the current function, and
125 return a pointer to that instruction if, and only if, the epilogue has
126 the correct structure that would allow us to optimize out the call to
127 _riscv_restore_0. */
128
129 static rtx_insn *
130 riscv_sr_match_epilogue (void)
131 {
132 /* Find the first instruction in the epilogue. */
133 rtx_insn *insn, *start;
134 for (insn = get_insns (); insn != NULL; insn = NEXT_INSN (insn))
135 if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_EPILOGUE_BEG)
136 {
137 insn = NEXT_INSN (insn);
138 break;
139 }
140 if (insn == NULL)
141 return NULL;
142
143 /* At this point INSN is the first instruction in the epilogue. A
144 standard epilogue (of the form we expect to handle) consists of the
145 following instructions:
146
147 1. A stack_tiesi or stack_tiedi (for RV32 and RV64 respectively),
148
149 2. An optional use instruction for the register holding the return
150 value. This will be missing in functions with no return value,
151
152 3. A gpr_restore instruction, and
153
154 4. A jump instruction of type gpr_restore_return. */
155 start = insn;
156 if (INSN_CODE (insn) != CODE_FOR_stack_tiesi
157 && INSN_CODE (insn) != CODE_FOR_stack_tiedi)
158 return NULL;
159
160 insn = NEXT_INSN (insn);
161 if (INSN_P (insn) && GET_CODE (PATTERN (insn)) == USE)
162 insn = NEXT_INSN (insn);
163
164 if (!INSN_P (insn) || INSN_CODE (insn) != CODE_FOR_gpr_restore)
165 return NULL;
166
167 insn = NEXT_INSN (insn);
168 if (!INSN_P (insn) || INSN_CODE (insn) != CODE_FOR_gpr_restore_return)
169 return NULL;
170
171 return start;
172 }
173
174 /* Helper for riscv_remove_unneeded_save_restore_calls. If we match the
175 prologue instructions but not the epilogue then we might have the case
176 where the epilogue has been optimized out due to a call to a no-return
177 function. In this case we might be able to remove the prologue too -
178 that's what this function does. PROLOGUE is the matched prolgoue
179 instruction, by the time this function returns the progloue instruction
180 may have been removed. */
181
182 static void
183 check_for_no_return_call (rtx_insn *prologue)
184 {
185 /* Check to see if we have the following pattern:
186
187 PROLOGUE instruction
188 NOTE_INSN_PROLOGUE_END
189 A no-return call instruction
190
191 If we do, then we can remove the prologue instruction safely. Remember
192 that we've already confirmed by this point that the prologue is a call
193 to riscv_save_0. */
194
195 if (dump_file)
196 fprintf (dump_file,
197 "Prologue matched, checking for no-return epilogue.\n");
198
199 rtx_insn *tmp = NEXT_INSN (prologue);
200 if (!NOTE_P (tmp) || NOTE_KIND (tmp) != NOTE_INSN_PROLOGUE_END)
201 return;
202
203 /* Skip any extra notes in here, they're most likely just debug. */
204 do
205 {
206 tmp = NEXT_INSN (tmp);
207 }
208 while (tmp != NULL && NOTE_P (tmp));
209
210 if (tmp == NULL || !INSN_P (tmp))
211 return;
212
213 bool noreturn_p = find_reg_note (tmp, REG_NORETURN, NULL_RTX) != NULL_RTX;
214 if (!CALL_P (tmp) || !noreturn_p)
215 return;
216
217 if (dump_file)
218 fprintf (dump_file,
219 "Prologue call to riscv_save_0 followed by noreturn call, "
220 "removing prologue.\n");
221 remove_insn (prologue);
222 }
223
224 /* Entry point called from riscv_reorg to remove some unneeded calls to
225 the save and restore stubs. This should only be called when
226 -msave-restore is in use.
227
228 We identify some simple cases where the function looks like this:
229
230 call t0,__riscv_save_0
231 <other-code>
232 call foo
233 tail __riscv_restore_0
234
235 And transform it into something like this:
236
237 <other-code>
238 tail foo
239
240 In the above examples, what can appear in <other-code> is pretty
241 restricted; only caller saved registers can be touched, this prevents
242 any additional calls (as they would write to 'ra'). */
243
244 void
245 riscv_remove_unneeded_save_restore_calls (void)
246 {
247 /* Will point to the first instruction of the function body, after the
248 prologue end note. */
249 rtx_insn *body = NULL;
250
251 /* Should only be called with -msave-restore is in use. */
252 gcc_assert (TARGET_SAVE_RESTORE);
253
254 /* Match the expected prologue and epilogue patterns. If either of these
255 fail to match then we abandon our attempt to optimize this function. */
256 rtx_insn *prologue_matched = riscv_sr_match_prologue (&body);
257 if (prologue_matched == NULL || body == NULL)
258 return;
259
260 rtx_insn *epilogue_matched = riscv_sr_match_epilogue ();
261 if (epilogue_matched == NULL)
262 {
263 check_for_no_return_call (prologue_matched);
264 return;
265 }
266
267 if (dump_file)
268 fprintf (dump_file,
269 "Could be a candidate for save/restore removal\n");
270
271 /* We want to check which registers this function uses. */
272 df_analyze ();
273
274 int call_count = 0;
275 bool good_use = true;
276 int epilogue_count = 0;
277
278 /* Now examine all of the instructions that make up this function, we're
279 looking for call instructions and also double checking register usage
280 while we're at it (see comments below). */
281 basic_block bb;
282 FOR_EACH_BB_FN (bb, cfun)
283 {
284 rtx_insn *insn;
285
286 FOR_BB_INSNS (bb, insn)
287 {
288 if (dump_file)
289 fprintf (dump_file,
290 "Block %d, Insn %d\n", bb->index, INSN_UID (insn));
291
292 /* If we scan the epilogue we will fall foul of our register
293 usage check below (due to it's use of the return address), so
294 once we spot we're at the epilogue, just skip the rest of this
295 block. Scanning the prologue instructions again (if they
296 match the expected pattern) is harmless. */
297 if (NOTE_P (insn)
298 && NOTE_KIND (insn) == NOTE_INSN_EPILOGUE_BEG)
299 {
300 ++epilogue_count;
301 break;
302 }
303
304 if (!INSN_P (insn))
305 continue;
306
307 if (CALL_P (insn))
308 ++call_count;
309 else
310 {
311 df_ref use;
312
313 FOR_EACH_INSN_USE (use, insn)
314 {
315 /* If the function makes use of any registers that are
316 callee saved then we should be saving them in this
317 function, which would suggest that a call to the save
318 and restore functions is required. This would seem to
319 indicate that something has gone wrong above, as we
320 should only get here if we are saving zero registers.
321
322 The one exception to this rule is the return address
323 register used within a call instruction. We can
324 optimize a single call within a function (by making it
325 a tail call), so we skip call instructions here. */
326 if (!call_used_regs[DF_REF_REGNO (use)])
327 {
328 if (dump_file)
329 fprintf (dump_file,
330 "Found unsupported use of callee saved "
331 "register in instruction %d\n",
332 INSN_UID (insn));
333 good_use = false;
334 break;
335 }
336 }
337 if (!good_use)
338 break;
339 }
340 }
341 }
342
343 /* If we used any registers that would indicate a need for a call to a
344 save/restore stub then don't optimize. */
345 if (!good_use)
346 return;
347
348 /* If this function has multiple epilogues, then for now we don't try to
349 optimize it. */
350 if (epilogue_count != 1)
351 return;
352
353 /* We can only optimize functions containing a single call, any more
354 would require us to add instructions to store the return address on
355 the stack (and restore it before we return). We could do this in the
356 future, but for now we don't. A single call can be transformed into
357 a tail call reasonably easily. */
358 if (call_count > 1)
359 {
360 if (dump_file)
361 fprintf (dump_file,
362 "Found too many call instructions\n");
363 return;
364 }
365
366 rtx_insn *epilogue_begin_note = PREV_INSN (epilogue_matched);
367 gcc_assert (NOTE_P (epilogue_begin_note)
368 && NOTE_KIND (epilogue_begin_note) == NOTE_INSN_EPILOGUE_BEG);
369
370 df_finish_pass (false);
371
372 /* Find the first instruction before the function epilogue. */
373 rtx_insn *insn_before_epilogue;
374 for (insn_before_epilogue = PREV_INSN (epilogue_begin_note);
375 NOTE_P (insn_before_epilogue);
376 insn_before_epilogue = PREV_INSN (insn_before_epilogue))
377 ;
378
379 /* Leaf functions will not generate calls to the save/restore stubs, so
380 there's no need for this optimization there. We know this function
381 has no more than 1 call (checked above). To convert this single call
382 into a tail call we rely on the call being the last thing before the
383 epilogue. */
384 if (GET_CODE (insn_before_epilogue) != CALL_INSN)
385 return;
386
387 /* The last instruction in this block, just before the epilogue is a
388 call. We can potentially change this call into a tail call. */
389 rtx_insn *call = insn_before_epilogue;
390
391 /* Transform call in insn to a sibcall, this will only be done if the
392 last thing in the function is a call. */
393 rtx callpat = PATTERN (call);
394 gcc_assert (GET_CODE (callpat) == PARALLEL);
395
396 /* Extract from CALLPAT the information we need to build the sibcall. */
397 rtx target_call = NULL;
398 rtx tmp_rtx = XVECEXP (callpat, 0, 0);
399 rtx set_target = NULL;
400 switch (GET_CODE (tmp_rtx))
401 {
402 case CALL:
403 target_call = tmp_rtx;
404 break;
405
406 case SET:
407 {
408 set_target = XEXP (tmp_rtx, 0);
409 tmp_rtx = XEXP (tmp_rtx, 1);
410 if (GET_CODE (tmp_rtx) != CALL)
411 return;
412 target_call = tmp_rtx;
413 break;
414 }
415
416 default:
417 return;
418 }
419
420 rtx target_mem = XEXP (target_call, 0);
421 if (GET_CODE (target_mem) != MEM)
422 return;
423
424 rtx target = XEXP (target_mem, 0);
425 if (GET_CODE (target) != SYMBOL_REF && GET_CODE (target) != REG)
426 return;
427
428 /* The sibcall instructions can only use a specific subset of
429 registers, we're about to (possibly) move a call through a
430 register from the function body and make it a sibcall. If we're
431 not using an appropriate register then we can't make this change.
432
433 Maybe in some future iteration we could actually scan the
434 function, find a suitable sibcall register, and switch over the
435 registers. But we don't do that yet. */
436 if (GET_CODE (target) == REG
437 && !SIBCALL_REG_P (REGNO (target)))
438 return;
439
440 rtx sibcall = NULL;
441 if (set_target != NULL)
442 sibcall
443 = gen_sibcall_value_internal (set_target, target, const0_rtx);
444 else
445 sibcall = gen_sibcall_internal (target, const0_rtx);
446
447 rtx_insn *before_call = PREV_INSN (call);
448 remove_insn (call);
449 rtx_insn *insn = emit_call_insn_after_setloc (sibcall, before_call,
450 INSN_LOCATION (call));
451 REG_NOTES (insn) = REG_NOTES (call);
452 SIBLING_CALL_P (insn) = 1;
453
454 /* Now update the prologue and epilogue to take account of the
455 changes within the function body. */
456 remove_insn (prologue_matched);
457 remove_insn (NEXT_INSN (NEXT_INSN (NEXT_INSN (epilogue_matched))));
458 remove_insn (NEXT_INSN (NEXT_INSN (epilogue_matched)));
459 remove_insn (NEXT_INSN (epilogue_matched));
460 remove_insn (epilogue_matched);
461
462 if (dump_file)
463 fprintf (dump_file,
464 "Save/restore successfully removed\n");
465 }