public inbox for gcc-patches@gcc.gnu.org
 help / color / mirror / Atom feed
* [google] remove redundant push {lr} for -mthumb (issue4441050)
@ 2011-04-19 10:01 Guozhi Wei
  2011-04-19 10:20 ` Richard Guenther
  2011-04-19 13:26 ` Richard Earnshaw
  0 siblings, 2 replies; 7+ messages in thread
From: Guozhi Wei @ 2011-04-19 10:01 UTC (permalink / raw)
  To: reply, dougkwan, gcc-patches

Reload pass tries to determine the stack frame, so it needs to check the
push/pop lr optimization opportunity. One of the criteria is if there is any
far jump inside the function. Unfortunately at this time gcc can't decide each
instruction's length and basic block layout, so it can't know the offset of
a jump. To be conservative it assumes every jump is a far jump. So any jump
in a function will prevent this push/pop lr optimization.

To enable the push/pop lr optimization in reload pass, I compute the possible
maximum length of the function body. If the length is not large enough, far
jump is not necessary, so we can safely do push/pop lr optimization.

Tested on arm qemu with options -march=armv5te -mthumb, without regression.

This patch is for google/main.

2011-04-19  Guozhi Wei  <carrot@google.com>

	Google ref 40255.
	* gcc/config/arm/arm.c (SHORTEST_FAR_JUMP_LENGTH): New constant.
	(estimate_function_length): New function.
	(thumb_far_jump_used_p): No far jump is needed in short function.

Index: gcc/config/arm/arm.c
===================================================================
--- gcc/config/arm/arm.c	(revision 172689)
+++ gcc/config/arm/arm.c	(working copy)
@@ -592,7 +592,9 @@ static const struct default_options arm_
   arm_preferred_rename_class
 
 struct gcc_target targetm = TARGET_INITIALIZER;
-\f
+
+#define SHORTEST_FAR_JUMP_LENGTH 2040
+
 /* Obstack for minipool constant handling.  */
 static struct obstack minipool_obstack;
 static char *         minipool_startobj;
@@ -20298,6 +20300,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
@@ -20316,6 +20329,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
      INITIAL_ELIMINATION_OFFSET macro.  */

--
This patch is available for review at http://codereview.appspot.com/4441050

^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2011-04-20  9:17 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2011-04-19 10:01 [google] remove redundant push {lr} for -mthumb (issue4441050) Guozhi Wei
2011-04-19 10:20 ` Richard Guenther
2011-04-19 10:25   ` Carrot Wei
2011-04-19 13:26 ` Richard Earnshaw
2011-04-20  9:17   ` Carrot Wei
2011-04-20  9:27     ` Richard Earnshaw
2011-04-20 11:00       ` Carrot Wei

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).