diff options
author | Yiran Wang <yiran@google.com> | 2015-06-15 14:09:08 -0700 |
---|---|---|
committer | Yiran Wang <yiran@google.com> | 2015-06-15 15:23:11 -0700 |
commit | 2c58169824949d3a597d9fa81931e001ef9b1bd0 (patch) | |
tree | 85da8d94e9a74c744f754df21a8a8e7e3e64be1c | |
parent | 00eea35e8107e50c4a5f569385646ae09f4e47fc (diff) | |
download | toolchain_gcc-2c58169824949d3a597d9fa81931e001ef9b1bd0.tar.gz toolchain_gcc-2c58169824949d3a597d9fa81931e001ef9b1bd0.tar.bz2 toolchain_gcc-2c58169824949d3a597d9fa81931e001ef9b1bd0.zip |
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/ChangeLog | 5 | ||||
-rw-r--r-- | gcc-4.9/gcc/ira.c | 12 | ||||
-rw-r--r-- | gcc-4.9/gcc/testsuite/ChangeLog | 5 | ||||
-rw-r--r-- | gcc-4.9/gcc/testsuite/gcc.dg/pr63762.c | 77 |
4 files changed, 98 insertions, 1 deletions
diff --git a/gcc-4.9/ChangeLog b/gcc-4.9/ChangeLog index b52689522..1a00eae06 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 4d91d2196..c0e8a0d23 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 1881e179b..4eefcba93 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 000000000..df110676e --- /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; +} |