+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
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
&& 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
/* 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