aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRichard Sandiford <richard.sandiford@arm.com>2019-09-30 18:36:11 +0000
committerRichard Sandiford <rsandifo@gcc.gnu.org>2019-09-30 18:36:11 +0000
commit2f00786128f190a4ad7a0819a84026cd8be19ad4 (patch)
tree77d073fc875526d85db3c49a3a2cfcd3033cdb04 /gcc
parent021f65807164b2770e8f113b0f85b1bb193020ef (diff)
downloadgcc-2f00786128f190a4ad7a0819a84026cd8be19ad4.zip
gcc-2f00786128f190a4ad7a0819a84026cd8be19ad4.tar.gz
gcc-2f00786128f190a4ad7a0819a84026cd8be19ad4.tar.bz2
[x86] Cache result of expensive_function_p between frame layouts
ix86_compute_frame_layout sets use_fast_prologue_epilogue if the function isn't more expensive than a certain threshold, where the threshold depends on the number of saved registers. However, the RA is allowed to insert and delete instructions as it goes along, which can change whether this threshold is crossed or not. I hit this with an RA change I'm working on. Rematerialisation was able to remove an instruction and avoid a spill, which happened to bring the size of the function below the threshold. But since nothing legitimately frame-related had changed, there was no need for the RA to lay out the frame again. We then failed the final sanity check in lra_eliminate. 2019-09-30 Richard Sandiford <richard.sandiford@arm.com> gcc/ * config/i386/i386.h (ix86_frame::expensive_p): New field. (ix86_frame::expensive_count): Likewise. * config/i386/i386.c (ix86_compute_frame_layout): Make the choice of use_fast_prologue_epilogue robust against incidental changes in function size. From-SVN: r276361
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog8
-rw-r--r--gcc/config/i386/i386.c19
-rw-r--r--gcc/config/i386/i386.h5
3 files changed, 29 insertions, 3 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 28296d5..f665a5c 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,11 @@
+2019-09-30 Richard Sandiford <richard.sandiford@arm.com>
+
+ * config/i386/i386.h (ix86_frame::expensive_p): New field.
+ (ix86_frame::expensive_count): Likewise.
+ * config/i386/i386.c (ix86_compute_frame_layout): Make the choice
+ of use_fast_prologue_epilogue robust against incidental changes
+ in function size.
+
2019-09-30 Ilya Leoshkevich <iii@linux.ibm.com>
PR target/77918
diff --git a/gcc/config/i386/i386.c b/gcc/config/i386/i386.c
index 8af4bc5..083e228 100644
--- a/gcc/config/i386/i386.c
+++ b/gcc/config/i386/i386.c
@@ -5877,7 +5877,14 @@ ix86_compute_frame_layout (void)
case function is known to be outside hot spot (this is known with
feedback only). Weight the size of function by number of registers
to save as it is cheap to use one or two push instructions but very
- slow to use many of them. */
+ slow to use many of them.
+
+ Calling this hook multiple times with the same frame requirements
+ must produce the same layout, since the RA might otherwise be
+ unable to reach a fixed point or might fail its final sanity checks.
+ This means that once we've assumed that a function does or doesn't
+ have a particular size, we have to stick to that assumption
+ regardless of how the function has changed since. */
if (count)
count = (count - 1) * FAST_PROLOGUE_INSN_COUNT;
if (node->frequency < NODE_FREQUENCY_NORMAL
@@ -5885,8 +5892,14 @@ ix86_compute_frame_layout (void)
&& node->frequency < NODE_FREQUENCY_HOT))
m->use_fast_prologue_epilogue = false;
else
- m->use_fast_prologue_epilogue
- = !expensive_function_p (count);
+ {
+ if (count != frame->expensive_count)
+ {
+ frame->expensive_count = count;
+ frame->expensive_p = expensive_function_p (count);
+ }
+ m->use_fast_prologue_epilogue = !frame->expensive_p;
+ }
}
frame->save_regs_using_mov
diff --git a/gcc/config/i386/i386.h b/gcc/config/i386/i386.h
index 9fe1f45..4e37336 100644
--- a/gcc/config/i386/i386.h
+++ b/gcc/config/i386/i386.h
@@ -2643,6 +2643,11 @@ struct GTY(()) ix86_frame
/* When save_regs_using_mov is set, emit prologue using
move instead of push instructions. */
bool save_regs_using_mov;
+
+ /* Assume without checking that:
+ EXPENSIVE_P = expensive_function_p (EXPENSIVE_COUNT). */
+ bool expensive_p;
+ int expensive_count;
};
/* Machine specific frame tracking during prologue/epilogue generation. All