aboutsummaryrefslogtreecommitdiff
path: root/gcc/sched-int.h
diff options
context:
space:
mode:
authorSegher Boessenkool <segher@kernel.crashing.org>2016-10-28 16:39:28 +0200
committerSegher Boessenkool <segher@gcc.gnu.org>2016-10-28 16:39:28 +0200
commit64f6e1e1589654b04fb9c0ac2fd20d010ccfdedb (patch)
tree32410170d71a2ec4dfcafe368b6e6f93cbd4ae0e /gcc/sched-int.h
parentf663d9ad6eaa6ff32676981461e865f96cb7c151 (diff)
downloadgcc-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/sched-int.h')
-rw-r--r--gcc/sched-int.h11
1 files changed, 11 insertions, 0 deletions
diff --git a/gcc/sched-int.h b/gcc/sched-int.h
index b4a7f92..d067b43 100644
--- a/gcc/sched-int.h
+++ b/gcc/sched-int.h
@@ -537,6 +537,17 @@ struct deps_desc
/* The last insn bearing REG_ARGS_SIZE that we've seen. */
rtx_insn *last_args_size;
+ /* A list of all prologue insns we have seen without intervening epilogue
+ insns, and one of all epilogue insns we have seen without intervening
+ prologue insns. This is used to prevent mixing prologue and epilogue
+ insns. See PR78029. */
+ rtx_insn_list *last_prologue;
+ rtx_insn_list *last_epilogue;
+
+ /* Whether the last *logue insn was an epilogue insn or a prologue insn
+ instead. */
+ bool last_logue_was_epilogue;
+
/* The maximum register number for the following arrays. Before reload
this is max_reg_num; after reload it is FIRST_PSEUDO_REGISTER. */
int max_reg;