summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHyung-Kyu Choi <hk0110.choi@samsung.com>2017-05-31 14:14:59 +0900
committerHyung-Kyu Choi <hk0110.choi@samsung.com>2017-05-31 15:52:36 +0900
commit8d209134fb20150c15cf08755d8a12d8654a8ebf (patch)
tree18c7bba053066ce3cf2c2e371aa8efe9dfb9caad
parentf72202cfbb6414f1767f973797c167e77cb82923 (diff)
downloadcoreclr-8d209134fb20150c15cf08755d8a12d8654a8ebf.tar.gz
coreclr-8d209134fb20150c15cf08755d8a12d8654a8ebf.tar.bz2
coreclr-8d209134fb20150c15cf08755d8a12d8654a8ebf.zip
[RyuJIT/ARM32] Update restoring TYP_DOUBLE interval
- Introduce findAnotherHalfRegRec() - Restore TYP_DOUBLE interval to valid double register Signed-off-by: Hyung-Kyu Choi <hk0110.choi@samsung.com>
-rw-r--r--src/jit/lsra.cpp56
-rw-r--r--src/jit/lsra.h1
2 files changed, 42 insertions, 15 deletions
diff --git a/src/jit/lsra.cpp b/src/jit/lsra.cpp
index c2a5fcf88a..b46fb94278 100644
--- a/src/jit/lsra.cpp
+++ b/src/jit/lsra.cpp
@@ -6457,19 +6457,10 @@ void LinearScan::unassignPhysReg(RegRecord* regRec, RefPosition* spillRefPositio
// Update second half RegRecord of a double register for TYP_DOUBLE
if (regRec->assignedInterval->registerType == TYP_DOUBLE)
{
- assert(isFloatRegType(regRec->registerType));
- assert(genIsValidDoubleReg(regRec->regNum));
+ RegRecord* anotherHalfRegRec = findAnotherHalfRegRec(regRec);
- // Because nextRegRec was defined only when assignedInterval is TYP_DOUBLE,
- // we should compute nextRegRec when nextRegRec is not defined yet.
- if (nextRegRec == nullptr)
- {
- nextRegNum = REG_NEXT(regRec->regNum);
- nextRegRec = getRegisterRecord(nextRegNum);
- }
-
- nextRegRec->assignedInterval = nextRegRec->previousInterval;
- nextRegRec->previousInterval = nullptr;
+ anotherHalfRegRec->assignedInterval = regRec->assignedInterval;
+ anotherHalfRegRec->previousInterval = nullptr;
}
#endif // _TARGET_ARM_
@@ -6651,6 +6642,42 @@ bool LinearScan::isSecondHalfReg(RegRecord* regRec, Interval* interval)
return false;
}
+
+//------------------------------------------------------------------------------------------
+// findAnotherHalfRegRec: Find another half RegRecord which forms same ARM32 double register
+//
+// Arguments:
+// regRec - A float RegRecord
+//
+// Assumptions:
+// None
+//
+// Return Value:
+// A RegRecord which forms same double register with regRec
+//
+RegRecord* LinearScan::findAnotherHalfRegRec(RegRecord* regRec)
+{
+ regNumber anotherHalfRegNum;
+ RegRecord* anotherHalfRegRec;
+
+ assert(genIsValidFloatReg(regRec->regNum));
+
+ // Find another half register for TYP_DOUBLE interval,
+ // following same logic in canRestorePreviousInterval().
+ if (genIsValidDoubleReg(regRec->regNum))
+ {
+ anotherHalfRegNum = REG_NEXT(regRec->regNum);
+ assert(!genIsValidDoubleReg(anotherHalfRegNum));
+ }
+ else
+ {
+ anotherHalfRegNum = REG_PREV(regRec->regNum);
+ assert(genIsValidDoubleReg(anotherHalfRegNum));
+ }
+ anotherHalfRegRec = getRegisterRecord(anotherHalfRegNum);
+
+ return anotherHalfRegRec;
+}
#endif
//--------------------------------------------------------------------------------------
@@ -6675,10 +6702,9 @@ bool LinearScan::canRestorePreviousInterval(RegRecord* regRec, Interval* assigne
#ifdef _TARGET_ARM_
if (retVal && regRec->previousInterval->registerType == TYP_DOUBLE)
{
- regNumber nextRegNum = REG_NEXT(regRec->regNum);
- RegRecord* nextRegRec = getRegisterRecord(nextRegNum);
+ RegRecord* anotherHalfRegRec = findAnotherHalfRegRec(regRec);
- retVal = retVal && nextRegRec->assignedInterval == nullptr;
+ retVal = retVal && anotherHalfRegRec->assignedInterval == nullptr;
}
#endif
diff --git a/src/jit/lsra.h b/src/jit/lsra.h
index aab034b2e4..b660048ce4 100644
--- a/src/jit/lsra.h
+++ b/src/jit/lsra.h
@@ -696,6 +696,7 @@ private:
#ifdef _TARGET_ARM_
bool isSecondHalfReg(RegRecord* regRec, Interval* interval);
+ RegRecord* findAnotherHalfRegRec(RegRecord* regRec);
#endif
bool canRestorePreviousInterval(RegRecord* regRec, Interval* assignedInterval);