aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorYiran Wang <yiran@google.com>2015-06-15 14:09:08 -0700
committerYiran Wang <yiran@google.com>2015-06-15 15:23:11 -0700
commit2c58169824949d3a597d9fa81931e001ef9b1bd0 (patch)
tree85da8d94e9a74c744f754df21a8a8e7e3e64be1c
parent00eea35e8107e50c4a5f569385646ae09f4e47fc (diff)
downloadtoolchain_gcc-2c58169824949d3a597d9fa81931e001ef9b1bd0.zip
toolchain_gcc-2c58169824949d3a597d9fa81931e001ef9b1bd0.tar.gz
toolchain_gcc-2c58169824949d3a597d9fa81931e001ef9b1bd0.tar.bz2
Update register class information when register assigned by IRA.
The update is necessary so that LRA is able to detect the conflict between these regisers and LRA registers. The change is a back-port from GCC 5.0 r217783, and please refer to gcc bug 63762 for some details. That bug report has an example, which is about VFP register file, but the issue applies to ARM integer register file too, with the same mechanism. The change is mainly about Thumb, although theoretically not limitted to. Change-Id: I1fedb410ae5ca39f168dab874f310d7337ab9bcc
-rw-r--r--gcc-4.9/ChangeLog5
-rw-r--r--gcc-4.9/gcc/ira.c12
-rw-r--r--gcc-4.9/gcc/testsuite/ChangeLog5
-rw-r--r--gcc-4.9/gcc/testsuite/gcc.dg/pr63762.c77
4 files changed, 98 insertions, 1 deletions
diff --git a/gcc-4.9/ChangeLog b/gcc-4.9/ChangeLog
index b526895..1a00eae 100644
--- a/gcc-4.9/ChangeLog
+++ b/gcc-4.9/ChangeLog
@@ -1,3 +1,8 @@
+2014-11-19 Renlin Li <Renlin.Li@arm.com>
+
+ PR middle-end/63762
+ * ira.c (ira): Update preferred class.
+
2014-07-26 Uros Bizjak <ubizjak@gmail.com>
PR target/47230
diff --git a/gcc-4.9/gcc/ira.c b/gcc-4.9/gcc/ira.c
index 4d91d21..c0e8a0d 100644
--- a/gcc-4.9/gcc/ira.c
+++ b/gcc-4.9/gcc/ira.c
@@ -5347,7 +5347,17 @@ ira (FILE *f)
ira_allocno_iterator ai;
FOR_EACH_ALLOCNO (a, ai)
- ALLOCNO_REGNO (a) = REGNO (ALLOCNO_EMIT_DATA (a)->reg);
+ {
+ int old_regno = ALLOCNO_REGNO (a);
+ int new_regno = REGNO (ALLOCNO_EMIT_DATA (a)->reg);
+
+ ALLOCNO_REGNO (a) = new_regno;
+
+ if (old_regno != new_regno)
+ setup_reg_classes (new_regno, reg_preferred_class (old_regno),
+ reg_alternate_class (old_regno),
+ reg_allocno_class (old_regno));
+ }
}
else
{
diff --git a/gcc-4.9/gcc/testsuite/ChangeLog b/gcc-4.9/gcc/testsuite/ChangeLog
index 1881e17..4eefcba 100644
--- a/gcc-4.9/gcc/testsuite/ChangeLog
+++ b/gcc-4.9/gcc/testsuite/ChangeLog
@@ -1,3 +1,8 @@
+2014-11-19 Renlin Li <Renlin.Li@arm.com>
+
+ PR middle-end/63762
+ * gcc.dg/pr63762.c: New test.
+
2014-10-29 Kyrylo Tkachov <kyrylo.tkachov@arm.com>
* gcc.target/aarch64/madd_after_asm_1.c: New test.
diff --git a/gcc-4.9/gcc/testsuite/gcc.dg/pr63762.c b/gcc-4.9/gcc/testsuite/gcc.dg/pr63762.c
new file mode 100644
index 0000000..df11067
--- /dev/null
+++ b/gcc-4.9/gcc/testsuite/gcc.dg/pr63762.c
@@ -0,0 +1,77 @@
+/* PR middle-end/63762 */
+/* { dg-do assemble } */
+/* { dg-options "-O2" } */
+
+#include <stdlib.h>
+
+void *astFree ();
+void *astMalloc ();
+void astNegate (void *);
+int astGetNegated (void *);
+void astGetRegionBounds (void *, double *, double *);
+int astResampleF (void *, ...);
+
+extern int astOK;
+
+int
+MaskF (int inside, int ndim, const int lbnd[], const int ubnd[],
+ float in[], float val)
+{
+
+ void *used_region;
+ float *c, *d, *out, *tmp_out;
+ double *lbndgd, *ubndgd;
+ int *lbndg, *ubndg, idim, ipix, nax, nin, nout, npix, npixg, result = 0;
+ if (!astOK) return result;
+ lbndg = astMalloc (sizeof (int)*(size_t) ndim);
+ ubndg = astMalloc (sizeof (int)*(size_t) ndim);
+ lbndgd = astMalloc (sizeof (double)*(size_t) ndim);
+ ubndgd = astMalloc (sizeof (double)*(size_t) ndim);
+ if (astOK)
+ {
+ astGetRegionBounds (used_region, lbndgd, ubndgd);
+ npix = 1;
+ npixg = 1;
+ for (idim = 0; idim < ndim; idim++)
+ {
+ lbndg[ idim ] = lbnd[ idim ];
+ ubndg[ idim ] = ubnd[ idim ];
+ npix *= (ubnd[ idim ] - lbnd[ idim ] + 1);
+ if (npixg >= 0) npixg *= (ubndg[ idim ] - lbndg[ idim ] + 1);
+ }
+ if (npixg <= 0 && astOK)
+ {
+ if ((inside != 0) == (astGetNegated( used_region ) != 0))
+ {
+ c = in;
+ for (ipix = 0; ipix < npix; ipix++) *(c++) = val;
+ result = npix;
+ }
+ }
+ else if (npixg > 0 && astOK)
+ {
+ if ((inside != 0) == (astGetNegated (used_region) != 0))
+ {
+ tmp_out = astMalloc (sizeof (float)*(size_t) npix);
+ if (tmp_out)
+ {
+ c = tmp_out;
+ for (ipix = 0; ipix < npix; ipix++) *(c++) = val;
+ result = npix - npixg;
+ }
+ out = tmp_out;
+ }
+ else
+ {
+ tmp_out = NULL;
+ out = in;
+ }
+ if (inside) astNegate (used_region);
+ result += astResampleF (used_region, ndim, lbnd, ubnd, in, NULL,
+ NULL, NULL, 0, 0.0, 100, val, ndim,
+ lbnd, ubnd, lbndg, ubndg, out, NULL);
+ if (inside) astNegate (used_region);
+ }
+ }
+ return result;
+}