From: Hyung-Kyu Choi Date: Mon, 19 Jun 2017 17:47:37 +0000 (+0900) Subject: [RyuJIT/ARM32] Update LinearScan::resolveLocalRef() for ARM32 (dotnet/coreclr#12194) X-Git-Tag: submit/tizen/20210909.063632~11030^2~6925^2~390 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=fd1dd98fa1f6666b7f7c282df21992e4252dcbd9;p=platform%2Fupstream%2Fdotnet%2Fruntime.git [RyuJIT/ARM32] Update LinearScan::resolveLocalRef() for ARM32 (dotnet/coreclr#12194) Update LinearScan::resolveLocalRef() - Always update two float register consisting a double register - Use helper function for ARM32 double register - Use stronger assertion condition Introduce updateAssignedInterval() to update assigned interval of ARM32 register considering register type. Commit migrated from https://github.com/dotnet/coreclr/commit/f6ce70eb9b6cb08b4ca0fb91692d284a1d37e37b --- diff --git a/src/coreclr/src/jit/lsra.cpp b/src/coreclr/src/jit/lsra.cpp index e1adcd7..f496315 100644 --- a/src/coreclr/src/jit/lsra.cpp +++ b/src/coreclr/src/jit/lsra.cpp @@ -6719,7 +6719,7 @@ regNumber LinearScan::rotateBlockStartLocation(Interval* interval, regNumber tar #ifdef _TARGET_ARM_ //-------------------------------------------------------------------------------------- -// isSecondHalfReg: Test if recRec is second half of double reigster +// isSecondHalfReg: Test if recRec is second half of double register // which is assigned to an interval. // // Arguments: @@ -8012,6 +8012,40 @@ void LinearScan::allocateRegisters() #endif // DEBUG } +#ifdef _TARGET_ARM_ +//----------------------------------------------------------------------------- +// updateAssignedInterval: Update assigned interval of register for ARM32 +// considering register type. When register type is TYP_DOUBLE, update +// two float registers consisting a double register. +// +// Arguments: +// reg - register to be updated +// interval - interval to be assigned +// regType - regsiter type +// +// Return Value: +// None +// +// Assumptions: +// When "regType" is TYP_DOUBLE, "reg" should be a even-numbered float register, +// i.e. lower half of double register. +// +void LinearScan::updateAssignedInterval(RegRecord* reg, Interval* interval, RegisterType regType) +{ + reg->assignedInterval = interval; + + // Update overlapping floating point register for TYP_DOUBLE + if (regType == TYP_DOUBLE) + { + assert(genIsValidDoubleReg(reg->regNum)); + + RegRecord* anotherHalfReg = findAnotherHalfRegRec(reg); + + anotherHalfReg->assignedInterval = interval; + } +} +#endif + // LinearScan::resolveLocalRef // Description: // Update the graph for a local reference. @@ -8087,7 +8121,11 @@ void LinearScan::resolveLocalRef(BasicBlock* block, GenTreePtr treeNode, RefPosi varDsc->lvRegNum = REG_STK; if (interval->assignedReg != nullptr && interval->assignedReg->assignedInterval == interval) { +#ifdef _TARGET_ARM_ + updateAssignedInterval(interval->assignedReg, nullptr, interval->registerType); +#else interval->assignedReg->assignedInterval = nullptr; +#endif } interval->assignedReg = nullptr; interval->physReg = REG_NA; @@ -8115,7 +8153,11 @@ void LinearScan::resolveLocalRef(BasicBlock* block, GenTreePtr treeNode, RefPosi RegRecord* oldRegRecord = getRegisterRecord(oldAssignedReg); if (oldRegRecord->assignedInterval == interval) { - oldRegRecord->assignedInterval = nullptr; +#ifdef _TARGET_ARM_ + updateAssignedInterval(oldRegRecord, nullptr, interval->registerType); +#else + oldRegRecord->assignedInterval = nullptr; +#endif } } } @@ -8266,27 +8308,25 @@ void LinearScan::resolveLocalRef(BasicBlock* block, GenTreePtr treeNode, RefPosi RegRecord* physRegRecord = getRegisterRecord(homeReg); if (spillAfter || currentRefPosition->lastUse) { - physRegRecord->assignedInterval = nullptr; - interval->assignedReg = nullptr; - interval->physReg = REG_NA; - interval->isActive = false; + interval->isActive = false; + interval->assignedReg = nullptr; + interval->physReg = REG_NA; + +#ifdef _TARGET_ARM_ + updateAssignedInterval(physRegRecord, nullptr, interval->registerType); +#else + physRegRecord->assignedInterval = nullptr; +#endif } else { - interval->isActive = true; - physRegRecord->assignedInterval = interval; - interval->assignedReg = physRegRecord; -#ifdef _TARGET_ARM_ - // Update overlapping floating point register for TYP_DOUBLE - if (interval->registerType == TYP_DOUBLE) - { - assert(isFloatRegType(physRegRecord->registerType)); + interval->isActive = true; + interval->assignedReg = physRegRecord; - regNumber nextRegNum = REG_NEXT(physRegRecord->regNum); - RegRecord* nextPhysRegRecord = getRegisterRecord(nextRegNum); - - nextPhysRegRecord->assignedInterval = interval; - } +#ifdef _TARGET_ARM_ + updateAssignedInterval(physRegRecord, interval, interval->registerType); +#else + physRegRecord->assignedInterval = interval; #endif } } @@ -10052,7 +10092,7 @@ void LinearScan::resolveEdge(BasicBlock* fromBlock, tempRegFlt = getTempRegForResolution(fromBlock, toBlock, TYP_FLOAT); } #else - tempRegFlt = getTempRegForResolution(fromBlock, toBlock, TYP_FLOAT); + tempRegFlt = getTempRegForResolution(fromBlock, toBlock, TYP_FLOAT); #endif } diff --git a/src/coreclr/src/jit/lsra.h b/src/coreclr/src/jit/lsra.h index 3ef17f0..14a986f 100644 --- a/src/coreclr/src/jit/lsra.h +++ b/src/coreclr/src/jit/lsra.h @@ -697,6 +697,7 @@ private: #ifdef _TARGET_ARM_ bool isSecondHalfReg(RegRecord* regRec, Interval* interval); RegRecord* findAnotherHalfRegRec(RegRecord* regRec); + void updateAssignedInterval(RegRecord* reg, Interval* interval, RegisterType regType); #endif bool canRestorePreviousInterval(RegRecord* regRec, Interval* assignedInterval);