[committed] Fix PR rtl-optimization/32296

John David Anglin dave@hiauly1.hia.nrc.ca
Sat Jun 30 16:38:00 GMT 2007


The PA port had two ways of generating returns.  The original of this
predates my involvement.

A trivial return could be emitted if the constraints for the "return"
pattern were satisfied.  However, the dataflow merge eliminated the
constraint check.  As a result, the "trivial" return was used in
circumstances where the return pointer was used elsewhere in the
function.

The second way a return could be generated was in the "epilogue"
expander.  The expander checks whether a full epilogue is needed
or not.  In situations where a full epilogue is needed, the expander
emitted a "return_internal".  Now, "return" and "return_internal"
generate the same code.  We had a different pattern for non-trivial
epilogues to avoid confusing jump and reorg.

I don't know the full history as to why things were done this way
but it strikes me as overly complex.  I think this approach  was used
to try to reserve the return pointer register for returns.

The enclosed change simplifies return handling on the PA.  I've
deleted the trivial "return" pattern and now all returns are emitted
by the "epilogue" expander.  This resolves the problem reported in
PR 32296.

Looked at some generated code and we still get trivial returns.

With this change, bootstrap is restored for all languages except
Ada on hppa2.0w-hp-hpux* and hppa-unknown-linux-gnu.  Unfortunately,
hppa64-hp-hpux11.11 still doesn't bootstrap.  However, the problem
doesn't appear related to return generation.

There don't appear to be any regressions in C test results.  The
situation for other languages is less clear but I don't think the
problems are return related.

Dave
-- 
J. David Anglin                                  dave.anglin@nrc-cnrc.gc.ca
National Research Council of Canada              (613) 990-0752 (FAX: 952-6602)

2007-06-30  John David Anglin  <dave.anglin@nrc-cnrc.gc.ca>

	rtl-optimization/32296
	* pa.md (return): Delete pattern.
	(return_internal): Remove "(const_int 1)" from pattern.
	(epilogue): Use return_internal pattern for trivial returns.
	* pa-protos.h (hppa_can_use_return_insn_p): Delete declaration.
	* pa.c (hppa_can_use_return_insn_p): Delete function.  Include "df.h".

Index: config/pa/pa.md
===================================================================
--- config/pa/pa.md	(revision 126137)
+++ config/pa/pa.md	(working copy)
@@ -7343,28 +7343,10 @@
 
 ;; Unconditional and other jump instructions.
 
-;; This can only be used in a leaf function, so we do
-;; not need to use the PIC register when generating PIC code.
-(define_insn "return"
-  [(return)
-   (use (reg:SI 2))
-   (const_int 0)]
-  "hppa_can_use_return_insn_p ()"
-  "*
-{
-  if (TARGET_PA_20)
-    return \"bve%* (%%r2)\";
-  return \"bv%* %%r0(%%r2)\";
-}"
-  [(set_attr "type" "branch")
-   (set_attr "length" "4")])
-
-;; Emit a different pattern for functions which have non-trivial
-;; epilogues so as not to confuse jump and reorg.
+;; This is used for most returns.
 (define_insn "return_internal"
   [(return)
-   (use (reg:SI 2))
-   (const_int 1)]
+   (use (reg:SI 2))]
   ""
   "*
 {
@@ -7406,14 +7388,16 @@
   ""
   "
 {
-  /* Try to use the trivial return first.  Else use the full
-     epilogue.  */
-  if (hppa_can_use_return_insn_p ())
-    emit_jump_insn (gen_return ());
+  rtx x;
+
+  /* Try to use the trivial return first.  Else use the full epilogue.  */
+  if (reload_completed
+      && !frame_pointer_needed
+      && !df_regs_ever_live_p (2)
+      && (compute_frame_size (get_frame_size (), 0) ? 0 : 1))
+    x = gen_return_internal ();
   else
     {
-      rtx x;
-
       hppa_expand_epilogue ();
 
       /* EH returns bypass the normal return stub.  Thus, we must do an
@@ -7426,9 +7410,8 @@
 	x = gen_return_external_pic ();
       else
 	x = gen_return_internal ();
-
-      emit_jump_insn (x);
     }
+  emit_jump_insn (x);
   DONE;
 }")
 
Index: config/pa/pa-protos.h
===================================================================
--- config/pa/pa-protos.h	(revision 126137)
+++ config/pa/pa-protos.h	(working copy)
@@ -144,7 +144,6 @@
 extern int cint_ok_for_move (HOST_WIDE_INT);
 extern void hppa_expand_prologue (void);
 extern void hppa_expand_epilogue (void);
-extern int hppa_can_use_return_insn_p (void);
 extern int ior_mask_p (unsigned HOST_WIDE_INT);
 extern void compute_zdepdi_operands (unsigned HOST_WIDE_INT,
 				     unsigned *);
Index: config/pa/pa.c
===================================================================
--- config/pa/pa.c	(revision 126137)
+++ config/pa/pa.c	(working copy)
@@ -47,6 +47,7 @@
 #include "tm_p.h"
 #include "target.h"
 #include "target-def.h"
+#include "df.h"
 
 /* Return nonzero if there is a bypass for the output of 
    OUT_INSN and the fp store IN_INSN.  */
@@ -4403,22 +4404,6 @@
   return saved_rp;
 }
 
-/* This is only valid once reload has completed because it depends on
-   knowing exactly how much (if any) frame there is and...
-
-   It's only valid if there is no frame marker to de-allocate and...
-
-   It's only valid if %r2 hasn't been saved into the caller's frame
-   (we're not profiling and %r2 isn't live anywhere).  */
-int
-hppa_can_use_return_insn_p (void)
-{
-  return (reload_completed
-	  && (compute_frame_size (get_frame_size (), 0) ? 0 : 1)
-	  && ! df_regs_ever_live_p (2)
-	  && ! frame_pointer_needed);
-}
-
 void
 emit_bcond_fp (enum rtx_code code, rtx operand0)
 {



More information about the Gcc-patches mailing list