Using leaf_function_p in a backend is dangerous as it incorrectly returns false...
authorWilco Dijkstra <wdijkstr@arm.com>
Thu, 15 Dec 2016 17:51:46 +0000 (17:51 +0000)
committerWilco Dijkstra <wilco@gcc.gnu.org>
Thu, 15 Dec 2016 17:51:46 +0000 (17:51 +0000)
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
gcc/config/arm/arm.c
gcc/config/arm/arm.h

index 8520be03585d15c96ac7ef90a915ec87d4051021..0d31d0d7a8df57e14561fbe4d724f028d81aae6d 100644 (file)
@@ -1,3 +1,12 @@
+2016-12-15  Wilco Dijkstra  <wdijkstr@arm.com>
+
+       * 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  <jakub@redhat.com>
 
        * doc/extend.texi: Clean up @xref{...} uses.
index f068796dbae5fd39ea523d7cbb2ff83e5f87c773..899c001bf89753fcba8d88cedcb6cb482563946b 100644 (file)
@@ -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
index 4582d2e7f3eee5a32b16fd7bab2c2ba03f17a07e..8c62038aaa6479591e66d03b38aa101031ea119d 100644 (file)
@@ -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 \