Message ID | 1488297598-1887-1-git-send-email-claziss@synopsys.com |
---|---|
State | New |
Headers | show |
* 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 --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; +}