aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlan Modra <amodra@gmail.com>2016-05-05 07:02:27 +0930
committerAlan Modra <amodra@gcc.gnu.org>2016-05-05 07:02:27 +0930
commit662fa3ba61d4fd0bc56803bc4d3866bced62bdc6 (patch)
tree44aeb019b93c79e5dbdc5b9ab47e47b7ffd759cc
parentfdab73dc76d4551c652a3f3d686e765e637c95d9 (diff)
downloadgcc-662fa3ba61d4fd0bc56803bc4d3866bced62bdc6.zip
gcc-662fa3ba61d4fd0bc56803bc4d3866bced62bdc6.tar.gz
gcc-662fa3ba61d4fd0bc56803bc4d3866bced62bdc6.tar.bz2
[RS6000] out-of-line exit register restore funcs
* config/rs6000/rs6000.c (rs6000_savres_strategy): Don't use out-of-line gpr restore for one or two regs if that would add a save of lr. From-SVN: r235907
-rw-r--r--gcc/ChangeLog6
-rw-r--r--gcc/config/rs6000/rs6000.c24
2 files changed, 21 insertions, 9 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 772dd37..629ee45 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,9 @@
+2016-05-05 Alan Modra <amodra@gmail.com>
+
+ * config/rs6000/rs6000.c (rs6000_savres_strategy): Don't use
+ out-of-line gpr restore for one or two regs if that would add
+ a save of lr.
+
2016-05-04 Uros Bizjak <ubizjak@gmail.com>
PR target/70873
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c
index fb522fb..77092fa 100644
--- a/gcc/config/rs6000/rs6000.c
+++ b/gcc/config/rs6000/rs6000.c
@@ -23422,6 +23422,15 @@ rs6000_savres_strategy (rs6000_stack_t *info,
}
}
+ /* info->lr_save_p isn't yet set if the only reason lr needs to be
+ saved is an out-of-line save or restore. Set up the value for
+ the next test (excluding out-of-line gprs). */
+ bool lr_save_p = (info->lr_save_p
+ || !(strategy & SAVE_INLINE_FPRS)
+ || !(strategy & SAVE_INLINE_VRS)
+ || !(strategy & REST_INLINE_FPRS)
+ || !(strategy & REST_INLINE_VRS));
+
if (TARGET_MULTIPLE
&& !TARGET_POWERPC64
&& !(TARGET_SPE_ABI && info->spe_64bit_regs_used)
@@ -23431,15 +23440,6 @@ rs6000_savres_strategy (rs6000_stack_t *info,
since the store-multiple instruction will always be smaller. */
strategy |= SAVE_INLINE_GPRS | SAVE_MULTIPLE;
- /* info->lr_save_p isn't yet set if the only reason lr needs to be
- saved is an out-of-line save or restore. Set up the value for
- the next test (excluding out-of-line gprs). */
- bool lr_save_p = (info->lr_save_p
- || !(strategy & SAVE_INLINE_FPRS)
- || !(strategy & SAVE_INLINE_VRS)
- || !(strategy & REST_INLINE_FPRS)
- || !(strategy & REST_INLINE_VRS));
-
/* The situation is more complicated with load multiple. We'd
prefer to use the out-of-line routines for restores, since the
"exit" out-of-line routines can handle the restore of LR and the
@@ -23452,6 +23452,12 @@ rs6000_savres_strategy (rs6000_stack_t *info,
strategy |= REST_INLINE_GPRS | REST_MULTIPLE;
}
+ /* Using the "exit" out-of-line routine does not improve code size
+ if using it would require lr to be saved and if only saving one
+ or two gprs. */
+ else if (!lr_save_p && info->first_gp_reg_save > 29)
+ strategy |= SAVE_INLINE_GPRS | REST_INLINE_GPRS;
+
/* We can only use load multiple or the out-of-line routines to
restore gprs if we've saved all the registers from
first_gp_reg_save. Otherwise, we risk loading garbage.