This is the mail archive of the mailing list for the GCC project.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[PATCH: PR target/38570] remove redundant push {lr} for -mthumb

This patch is to fix the bug PR target/38570. In thumb mode if the lr register
is not clobbered, we can skip the push {lr} prologue. But if there is a jump
in the function, the reload pass can't decide if it is a far jump (lr is used
in a far jump), so it always treats the jump as far jump and prevent this

The fix first compute the maximum possible function length, if the length is
not large enough far jump is not necessary, and we can do this optimization

2009-05-04  Carrot Wei  <>

        PR target/38570
        * config/arm/arm.c: There is no far jump if a function is not large

This patch was applied to trunk GCC and tested on the arm emulator with newlib.
No new failures.


Index: arm.c
--- arm.c       (revision 146995)
+++ arm.c       (working copy)
@@ -398,6 +398,8 @@ static bool arm_allocate_stack_slots_for
 #define TARGET_ASM_OUTPUT_DWARF_DTPREL arm_output_dwarf_dtprel

 struct gcc_target targetm = TARGET_INITIALIZER;

 /* Obstack for minipool constant handling.  */
@@ -17212,6 +17214,17 @@ thumb_shiftable_const (unsigned HOST_WID
   return 0;

+/* Computes the maximum possible function length. */
+static int
+estimate_function_length (void)
+  rtx insn;
+  int length = 0;
+  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
+    length += get_attr_length(insn);
+  return length;
 /* Returns nonzero if the current function contains,
    or might contain a far jump.  */
 static int
@@ -17230,6 +17243,16 @@ thumb_far_jump_used_p (void)
   if (cfun->machine->far_jump_used)
     return 1;

+  /* In reload pass we haven't got the exact jump instruction length,
+     but we can get a reasonable estimation based on the maximum
+     possible function length. */
+  if (!reload_completed)
+    {
+      int function_length = estimate_function_length();
+      if (function_length < SHORTEST_FAR_JUMP_LENGTH)
+        return 0;
+    }
   /* If this function is not being called from the prologue/epilogue
      generation code then it must be being called from the

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]