From a3038e190b271744d0b5e2e83d389864fed4d54e Mon Sep 17 00:00:00 2001 From: Wilco Dijkstra Date: Thu, 15 Dec 2016 17:51:46 +0000 Subject: [PATCH] Using leaf_function_p in a backend is dangerous as it incorrectly returns false... Using leaf_function_p in a backend is dangerous as it incorrectly returns false if it is called while in a sequence (for example during prolog/epilog generation). Replace all uses with crtl->is_leaf as this is now initialized early enough in ira.c. This typically causes no code generation differences unless there was a bug due to leaf_function_p returning the wrong value. gcc/ * config/arm/arm.h (TARGET_BACKTRACE): Use crtl->is_leaf. * config/arm/arm.c (arm_option_check_internal): Improve comment. (thumb_force_lr_save): Use crtl->is_leaf. (arm_get_frame_offsets): Remove comment. Use crtl->is_leaf. (thumb_far_jump_used_p): Remove comment. (arm_frame_pointer_required): Use crtl->is_leaf. From-SVN: r243720 --- gcc/ChangeLog | 9 +++++++++ gcc/config/arm/arm.c | 25 ++++--------------------- gcc/config/arm/arm.h | 2 +- 3 files changed, 14 insertions(+), 22 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 8520be0..0d31d0d 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2016-12-15 Wilco Dijkstra + + * config/arm/arm.h (TARGET_BACKTRACE): Use crtl->is_leaf. + * config/arm/arm.c (arm_option_check_internal): Improve comment. + (thumb_force_lr_save): Use crtl->is_leaf. + (arm_get_frame_offsets): Remove comment. Use crtl->is_leaf. + (thumb_far_jump_used_p): Remove comment. + (arm_frame_pointer_required): Use crtl->is_leaf. + 2016-12-15 Jakub Jelinek * doc/extend.texi: Clean up @xref{...} uses. diff --git a/gcc/config/arm/arm.c b/gcc/config/arm/arm.c index f068796..899c001 100644 --- a/gcc/config/arm/arm.c +++ b/gcc/config/arm/arm.c @@ -2828,8 +2828,7 @@ arm_option_check_internal (struct gcc_options *opts) && !bitmap_bit_p (arm_active_target.isa, isa_bit_notm)) error ("target CPU does not support ARM mode"); - /* TARGET_BACKTRACE calls leaf_function_p, which causes a crash if done - from here where no function is being compiled currently. */ + /* TARGET_BACKTRACE cannot be used here as crtl->is_leaf is not set yet. */ if ((TARGET_TPCS_FRAME || TARGET_TPCS_LEAF_FRAME) && TARGET_ARM_P (flags)) warning (0, "enabling backtrace support is only meaningful when compiling for the Thumb"); @@ -20587,7 +20586,7 @@ static bool thumb_force_lr_save (void) { return !cfun->machine->lr_save_eliminated - && (!leaf_function_p () + && (!crtl->is_leaf || thumb_far_jump_used_p () || df_regs_ever_live_p (LR_REGNUM)); } @@ -20692,7 +20691,6 @@ arm_get_frame_offsets (void) { struct arm_stack_offsets *offsets; unsigned long func_type; - int leaf; int saved; int core_saved; HOST_WIDE_INT frame_size; @@ -20700,16 +20698,6 @@ arm_get_frame_offsets (void) offsets = &cfun->machine->stack_offsets; - /* We need to know if we are a leaf function. Unfortunately, it - is possible to be called after start_sequence has been called, - which causes get_insns to return the insns for the sequence, - not the function, which will cause leaf_function_p to return - the incorrect result. - - to know about leaf functions once reload has completed, and the - frame size cannot be changed after that time, so we can safely - use the cached value. */ - if (reload_completed) return offsets; @@ -20717,8 +20705,6 @@ arm_get_frame_offsets (void) into an offset once we have determined the size of preceding data. */ frame_size = ROUND_UP_WORD (get_frame_size ()); - leaf = leaf_function_p (); - /* Space for variadic functions. */ offsets->saved_args = crtl->args.pretend_args_size; @@ -20772,7 +20758,7 @@ arm_get_frame_offsets (void) /* A leaf function does not need any stack alignment if it has nothing on the stack. */ - if (leaf && frame_size == 0 + if (crtl->is_leaf && frame_size == 0 /* However if it calls alloca(), we have a dynamically allocated block of BIGGEST_ALIGNMENT on stack, so still do stack alignment. */ && ! cfun->calls_alloca) @@ -24125,9 +24111,6 @@ thumb_far_jump_used_p (void) bool far_jump = false; unsigned int func_size = 0; - /* This test is only important for leaf functions. */ - /* assert (!leaf_function_p ()); */ - /* If we have already decided that far jumps may be used, do not bother checking again, and always return true even if it turns out that they are not being used. Once we have made @@ -27679,7 +27662,7 @@ arm_frame_pointer_required (void) return true; /* The frame pointer is required for non-leaf APCS frames. */ - if (TARGET_ARM && TARGET_APCS_FRAME && !leaf_function_p ()) + if (TARGET_ARM && TARGET_APCS_FRAME && !crtl->is_leaf) return true; /* If we are probing the stack in the prologue, we will have a faulting diff --git a/gcc/config/arm/arm.h b/gcc/config/arm/arm.h index 4582d2e..8c62038 100644 --- a/gcc/config/arm/arm.h +++ b/gcc/config/arm/arm.h @@ -131,7 +131,7 @@ extern tree arm_fp16_type_node; #define TARGET_IWMMXT_ABI (TARGET_32BIT && arm_abi == ARM_ABI_IWMMXT) #define TARGET_ARM (! TARGET_THUMB) #define TARGET_EITHER 1 /* (TARGET_ARM | TARGET_THUMB) */ -#define TARGET_BACKTRACE (leaf_function_p () \ +#define TARGET_BACKTRACE (crtl->is_leaf \ ? TARGET_TPCS_LEAF_FRAME \ : TARGET_TPCS_FRAME) #define TARGET_AAPCS_BASED \ -- 2.7.4