diff mbox

[ARC] Handle complex PIC move patterns.

Message ID 1488297598-1887-1-git-send-email-claziss@synopsys.com
State New
Headers show

Commit Message

Claudiu Zissulescu Feb. 28, 2017, 3:59 p.m. UTC
Hi,

fwprop step is placing in the REG_EQUIV notes constant pic unspecs
expressions.  Then, loop may use these notes for optimizations
rezulting in complex patterns that are not supported by the current
implementation.

The patch adds handling of complex PIC addresses having MINUS or UNARY
operations.

Ok to apply?
Claudiu

gcc/
2017-02-28  Claudiu Zissulescu  <claziss@synopsys.com>

	* config/arc/arc.c (arc_legitimize_pic_address): Handle PIC
	expressions with MINUS and UNARY ops.

gcc/testsuite
2017-02-28  Claudiu Zissulescu  <claziss@synopsys.com>

	* gcc.target/arc/pr9001090948.c: New file.
---
 gcc/config/arc/arc.c                        | 49 ++++++++++++++++++++++++++++-
 gcc/testsuite/gcc.target/arc/pr9001090948.c | 25 +++++++++++++++
 2 files changed, 73 insertions(+), 1 deletion(-)
 create mode 100644 gcc/testsuite/gcc.target/arc/pr9001090948.c

Comments

Andrew Burgess March 3, 2017, 5:22 p.m. UTC | #1
* Claudiu Zissulescu <Claudiu.Zissulescu@synopsys.com> [2017-02-28 16:59:58 +0100]:

> Hi,
> 
> fwprop step is placing in the REG_EQUIV notes constant pic unspecs
> expressions.  Then, loop may use these notes for optimizations
> rezulting in complex patterns that are not supported by the current
> implementation.
> 
> The patch adds handling of complex PIC addresses having MINUS or UNARY
> operations.
> 
> Ok to apply?
> Claudiu

There's a couple of spelling mistakes I've marked inline, but
otherwise, this seems sensible.

Thanks,
Andrew



> 
> gcc/
> 2017-02-28  Claudiu Zissulescu  <claziss@synopsys.com>
> 
> 	* config/arc/arc.c (arc_legitimize_pic_address): Handle PIC
> 	expressions with MINUS and UNARY ops.
> 
> gcc/testsuite
> 2017-02-28  Claudiu Zissulescu  <claziss@synopsys.com>
> 
> 	* gcc.target/arc/pr9001090948.c: New file.
> ---
>  gcc/config/arc/arc.c                        | 49 ++++++++++++++++++++++++++++-
>  gcc/testsuite/gcc.target/arc/pr9001090948.c | 25 +++++++++++++++
>  2 files changed, 73 insertions(+), 1 deletion(-)
>  create mode 100644 gcc/testsuite/gcc.target/arc/pr9001090948.c
> 
> diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
> index 508a9a6..3b94d7c 100644
> --- a/gcc/config/arc/arc.c
> +++ b/gcc/config/arc/arc.c
> @@ -5024,8 +5024,55 @@ arc_legitimize_pic_address (rtx orig, rtx oldx)
>  	      /* Check that the unspec is one of the ones we generate?  */
>  	      return orig;
>  	    }
> +	  /* fwprop is placing in the REG_EQUIV notes constant pic
> +	     unspecs expressions.  Then, loop may use these notes for
> +	     optimizations rezulting in complex patterns that are not

s/rezulting/resulting/


> +	     supported by the current implementation. The following
> +	     two if-cases are simplifying the complex patters in

s/patters in/patterns to/

> +	     simpler ones.  */
> +	  else if (GET_CODE (addr) == MINUS)
> +	    {
> +	      rtx op0 = XEXP (addr, 0);
> +	      rtx op1 = XEXP (addr, 1);
> +	      gcc_assert (oldx);
> +	      gcc_assert (GET_CODE (op1) == UNSPEC);
> +
> +	      emit_move_insn (oldx,
> +			      gen_rtx_CONST (SImode,
> +					     arc_legitimize_pic_address (op1,
> +									 NULL_RTX)));
> +	      emit_insn (gen_rtx_SET (oldx, gen_rtx_MINUS (SImode, op0, oldx)));
> +	      return oldx;
> +
> +	    }
> +	  else if (GET_CODE (addr) != PLUS)
> +	    {
> +	      rtx tmp = XEXP (addr, 0);
> +	      enum rtx_code code = GET_CODE (addr);
> +
> +	      /* It only works for UNARY operations.  */
> +	      gcc_assert (UNARY_P (addr));
> +	      gcc_assert (GET_CODE (tmp) == UNSPEC);
> +	      gcc_assert (oldx);
> +
> +	      emit_move_insn
> +		(oldx,
> +		 gen_rtx_CONST (SImode,
> +				arc_legitimize_pic_address (tmp,
> +							    NULL_RTX)));
> +
> +	      emit_insn (gen_rtx_SET (oldx,
> +				      gen_rtx_fmt_ee (code, SImode,
> +						      oldx, const0_rtx)));
> +
> +	      return oldx;
> +	    }
>  	  else
> -	    gcc_assert (GET_CODE (addr) == PLUS);
> +	    {
> +	      gcc_assert (GET_CODE (addr) == PLUS);
> +	      if (GET_CODE (XEXP (addr, 0)) == UNSPEC)
> +		return orig;
> +	    }
>  	}
>  
>        if (GET_CODE (addr) == PLUS)
> diff --git a/gcc/testsuite/gcc.target/arc/pr9001090948.c b/gcc/testsuite/gcc.target/arc/pr9001090948.c
> new file mode 100644
> index 0000000..103f4ae
> --- /dev/null
> +++ b/gcc/testsuite/gcc.target/arc/pr9001090948.c
> @@ -0,0 +1,25 @@
> +/* { dg-do compile } */
> +/* { dg-skip-if "ARC600 doesn't support pic" { arc6xx } } */
> +/* { dg-options "-Os -fPIC" } */
> +#include <stdio.h>
> +#include <string.h>
> +
> +char *
> +strip_trail (const char str[], size_t n)
> +{
> +  static char buf[1025];
> +  int j;
> +
> +  strncpy (buf, str, n);
> +  buf[n] = '\0';
> +
> +  for (j = strlen (buf) - 1; j >= 0; j--)
> +    {
> +      if (buf[j] != ' ')
> +        break;
> +
> +      buf[j] = '\0';
> +    }
> +
> +  return buf;
> +}
> -- 
> 1.9.1
>
diff mbox

Patch

diff --git a/gcc/config/arc/arc.c b/gcc/config/arc/arc.c
index 508a9a6..3b94d7c 100644
--- a/gcc/config/arc/arc.c
+++ b/gcc/config/arc/arc.c
@@ -5024,8 +5024,55 @@  arc_legitimize_pic_address (rtx orig, rtx oldx)
 	      /* Check that the unspec is one of the ones we generate?  */
 	      return orig;
 	    }
+	  /* fwprop is placing in the REG_EQUIV notes constant pic
+	     unspecs expressions.  Then, loop may use these notes for
+	     optimizations rezulting in complex patterns that are not
+	     supported by the current implementation. The following
+	     two if-cases are simplifying the complex patters in
+	     simpler ones.  */
+	  else if (GET_CODE (addr) == MINUS)
+	    {
+	      rtx op0 = XEXP (addr, 0);
+	      rtx op1 = XEXP (addr, 1);
+	      gcc_assert (oldx);
+	      gcc_assert (GET_CODE (op1) == UNSPEC);
+
+	      emit_move_insn (oldx,
+			      gen_rtx_CONST (SImode,
+					     arc_legitimize_pic_address (op1,
+									 NULL_RTX)));
+	      emit_insn (gen_rtx_SET (oldx, gen_rtx_MINUS (SImode, op0, oldx)));
+	      return oldx;
+
+	    }
+	  else if (GET_CODE (addr) != PLUS)
+	    {
+	      rtx tmp = XEXP (addr, 0);
+	      enum rtx_code code = GET_CODE (addr);
+
+	      /* It only works for UNARY operations.  */
+	      gcc_assert (UNARY_P (addr));
+	      gcc_assert (GET_CODE (tmp) == UNSPEC);
+	      gcc_assert (oldx);
+
+	      emit_move_insn
+		(oldx,
+		 gen_rtx_CONST (SImode,
+				arc_legitimize_pic_address (tmp,
+							    NULL_RTX)));
+
+	      emit_insn (gen_rtx_SET (oldx,
+				      gen_rtx_fmt_ee (code, SImode,
+						      oldx, const0_rtx)));
+
+	      return oldx;
+	    }
 	  else
-	    gcc_assert (GET_CODE (addr) == PLUS);
+	    {
+	      gcc_assert (GET_CODE (addr) == PLUS);
+	      if (GET_CODE (XEXP (addr, 0)) == UNSPEC)
+		return orig;
+	    }
 	}
 
       if (GET_CODE (addr) == PLUS)
diff --git a/gcc/testsuite/gcc.target/arc/pr9001090948.c b/gcc/testsuite/gcc.target/arc/pr9001090948.c
new file mode 100644
index 0000000..103f4ae
--- /dev/null
+++ b/gcc/testsuite/gcc.target/arc/pr9001090948.c
@@ -0,0 +1,25 @@ 
+/* { dg-do compile } */
+/* { dg-skip-if "ARC600 doesn't support pic" { arc6xx } } */
+/* { dg-options "-Os -fPIC" } */
+#include <stdio.h>
+#include <string.h>
+
+char *
+strip_trail (const char str[], size_t n)
+{
+  static char buf[1025];
+  int j;
+
+  strncpy (buf, str, n);
+  buf[n] = '\0';
+
+  for (j = strlen (buf) - 1; j >= 0; j--)
+    {
+      if (buf[j] != ' ')
+        break;
+
+      buf[j] = '\0';
+    }
+
+  return buf;
+}