This is the mail archive of the gcc-patches@gcc.gnu.org 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, MIPS] relax-pic-calls and complex return types


This is for the problem I reported in PR43764.  Using -mabicalls with
the mipsisa32r2-sde-elf toolchain on a function returning complex
results in an ICE.  The -mrelax-pic-calls code is trying to modify
patterns that contain a CALL rtx, but it only modifies the first one,
and complex return values have two CALL rtx because the result is return
in two discontiguous registers.

This patch is a simple solution to that problem.
mips_call_expr_from_insn was modified to have a parameter passed by
address that we can store the second CALL rtx in.  Then the caller
modifies the second CALL rtx same as the first one if it exists.

This was tested using the mipsisa32r2-sde-elf toolchain on the
simulator, with -mabicalls and -G0.  With the patch, there are 50 fewer
ICEs in the gcc testsuite, and 10 fewer ICEs in the g++ testsuite.  The
toolchain went from 75 ICEs total to 15.  There were no new regressions.

OK?

Jim

2010-04-24  James E. Wilson  <wilson@codesourcery.com>

	PR target/43764
	* mips.c (mips_call_expr_from_insn): New arg second_call.  Set it.
	(mips_annotate_pic_calls): Pass new arg to mips_call_expr_from_insn.
	Use it.

Index: mips.c
===================================================================
--- mips.c	(revision 158495)
+++ mips.c	(working copy)
@@ -14007,23 +14025,35 @@ r10k_insert_cache_barriers (void)
 }
 
 /* If INSN is a call, return the underlying CALL expr.  Return NULL_RTX
-   otherwise.  */
+   otherwise.  If INSN has two call rtx, then store the second one in
+   SECOND_CALL.  */
 
 static rtx
-mips_call_expr_from_insn (rtx insn)
+mips_call_expr_from_insn (rtx insn, rtx *second_call)
 {
   rtx x;
+  rtx x2;
 
   if (!CALL_P (insn))
     return NULL_RTX;
 
   x = PATTERN (insn);
   if (GET_CODE (x) == PARALLEL)
-    x = XVECEXP (x, 0, 0);
+    {
+      /* Calls returning complex values have two CALL rtx.  Look for the second
+	 one here, and return it via the SECOND_CALL arg.  */
+      x2 = XVECEXP (x, 0, 1);
+      if (GET_CODE (x2) == SET)
+	x2 = XEXP (x2, 1);
+      if (GET_CODE (x2) == CALL)
+	*second_call = x2;
+
+      x = XVECEXP (x, 0, 0);
+    }
   if (GET_CODE (x) == SET)
     x = XEXP (x, 1);
-
   gcc_assert (GET_CODE (x) == CALL);
+
   return x;
 }
 
@@ -14155,9 +14185,10 @@ mips_annotate_pic_calls (void)
   FOR_EACH_BB (bb)
     FOR_BB_INSNS (bb, insn)
     {
-      rtx call, reg, symbol;
+      rtx call, reg, symbol, second_call;
 
-      call = mips_call_expr_from_insn (insn);
+      second_call = 0;
+      call = mips_call_expr_from_insn (insn, &second_call);
       if (!call)
 	continue;
       gcc_assert (MEM_P (XEXP (call, 0)));
@@ -14167,7 +14198,11 @@ mips_annotate_pic_calls (void)
 
       symbol = mips_find_pic_call_symbol (insn, reg);
       if (symbol)
-	mips_annotate_pic_call_expr (call, symbol);
+	{
+	  mips_annotate_pic_call_expr (call, symbol);
+	  if (second_call)
+	    mips_annotate_pic_call_expr (second_call, symbol);
+	}
     }
 }
 

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