diff options
author | Segher Boessenkool <segher@kernel.crashing.org> | 2016-10-28 16:39:28 +0200 |
---|---|---|
committer | Segher Boessenkool <segher@gcc.gnu.org> | 2016-10-28 16:39:28 +0200 |
commit | 64f6e1e1589654b04fb9c0ac2fd20d010ccfdedb (patch) | |
tree | 32410170d71a2ec4dfcafe368b6e6f93cbd4ae0e /gcc/function.h | |
parent | f663d9ad6eaa6ff32676981461e865f96cb7c151 (diff) | |
download | gcc-64f6e1e1589654b04fb9c0ac2fd20d010ccfdedb.zip gcc-64f6e1e1589654b04fb9c0ac2fd20d010ccfdedb.tar.gz gcc-64f6e1e1589654b04fb9c0ac2fd20d010ccfdedb.tar.bz2 |
sched: Do not mix prologue and epilogue insns
This patch makes scheduling not reorder prologue insns relative to
epilogue insns and vice versa. This fixes PR78029.
The problem in that PR:
We have two insns, in this order:
(insn/f 300 299 267 8 (set (reg:DI 65 lr)
(reg:DI 0 0)) 579 {*movdi_internal64}
(expr_list:REG_DEAD (reg:DI 0 0)
(expr_list:REG_CFA_RESTORE (reg:DI 65 lr)
(nil))))
...
(insn/f 310 268 134 8 (set (mem/c:DI (plus:DI (reg/f:DI 1 1)
(const_int 144 [0x90])) [6 S8 A8])
(reg:DI 0 0)) 579 {*movdi_internal64}
(expr_list:REG_DEAD (reg:DI 0 0)
(expr_list:REG_CFA_OFFSET (set (mem/c:DI (plus:DI (reg/f:DI 1 1)
(const_int 144 [0x90])) [6 S8 A8])
(reg:DI 65 lr))
(nil))))
and sched swaps them (when compiling for power6, it tries to put memory
stores together, so insn 310 is moved up past 300 to go together with
some other store). But the REG_CFA_RESTORE and REG_CFA_OFFSET cannot be
swapped (they both say where the orig value of LR now lives).
PR rtl-optimization/78029
* function.c (prologue_contains, epilogue_contains): New functions.
(record_prologue_seq, record_epilogue_seq): New functions.
* function.h (prologue_contains, epilogue_contains,
record_prologue_seq, record_epilogue_seq): New declarations.
* sched-deps.c (sched_analyze_insn): Make dependencies to prevent
mixing prologue and epilogue insns.
(init_deps): Initialize the new fields in struct deps_desc.
* sched-int.h (struct deps_desc): New fields last_prologue,
last_epilogue, and last_logue_was_epilogue.
* shrink-wrap.c (emit_common_heads_for_components): Record all
emitted prologue and epilogue insns.
(emit_common_tails_for_components): Ditto.
(insert_prologue_epilogue_for_components): Ditto.
From-SVN: r241650
Diffstat (limited to 'gcc/function.h')
-rw-r--r-- | gcc/function.h | 4 |
1 files changed, 4 insertions, 0 deletions
diff --git a/gcc/function.h b/gcc/function.h index 590a490..e854c7f 100644 --- a/gcc/function.h +++ b/gcc/function.h @@ -628,7 +628,11 @@ extern void clobber_return_register (void); extern void expand_function_end (void); extern rtx get_arg_pointer_save_area (void); extern void maybe_copy_prologue_epilogue_insn (rtx, rtx); +extern int prologue_contains (const_rtx); +extern int epilogue_contains (const_rtx); extern int prologue_epilogue_contains (const_rtx); +extern void record_prologue_seq (rtx_insn *); +extern void record_epilogue_seq (rtx_insn *); extern void emit_return_into_block (bool simple_p, basic_block bb); extern void set_return_jump_label (rtx_insn *); extern bool active_insn_between (rtx_insn *head, rtx_insn *tail); |