@@ -3856,9 +3856,37 @@ void LinearScan::processKills(RefPosition* killRefPosition)
3856
3856
RefPosition* nextKill = killRefPosition->nextRefPosition;
3857
3857
3858
3858
regMaskTP killedRegs = killRefPosition->getKilledRegisters();
3859
- while (killedRegs.IsNonEmpty())
3859
+
3860
+ freeKilledRegs(killRefPosition, killedRegs.getLow(), nextKill, REG_LOW_BASE);
3861
+
3862
+ #ifdef HAS_MORE_THAN_64_REGISTERS
3863
+ freeKilledRegs(killRefPosition, killedRegs.getHigh(), nextKill, REG_HIGH_BASE);
3864
+ #endif
3865
+
3866
+ regsBusyUntilKill &= ~killRefPosition->getKilledRegisters();
3867
+ INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_KILL_REGS, nullptr, REG_NA, nullptr, NONE,
3868
+ killRefPosition->getKilledRegisters()));
3869
+ }
3870
+
3871
+ //------------------------------------------------------------------------
3872
+ // freeKilledRegs: Handle registers that are being killed.
3873
+ //
3874
+ // Arguments:
3875
+ // killRefPosition - The RefPosition for the kill
3876
+ // killedRegs - Registers to kill
3877
+ // nextKill - The RefPosition for next kill
3878
+ // regBase - `0` or `64` based on the `killedRegs` being processed
3879
+ //
3880
+ void LinearScan::freeKilledRegs(RefPosition* killRefPosition,
3881
+ regMaskSmall killedRegs,
3882
+ RefPosition* nextKill,
3883
+ int regBase)
3884
+ {
3885
+
3886
+ while (killedRegs != RBM_NONE)
3860
3887
{
3861
- regNumber killedReg = genFirstRegNumFromMaskAndToggle(killedRegs);
3888
+ regNumber killedReg = (regNumber)(BitOperations::BitScanForward(killedRegs) + regBase);
3889
+ killedRegs ^= genSingleTypeRegMask(killedReg);
3862
3890
RegRecord* regRecord = getRegisterRecord(killedReg);
3863
3891
Interval* assignedInterval = regRecord->assignedInterval;
3864
3892
if (assignedInterval != nullptr)
@@ -3874,10 +3902,6 @@ void LinearScan::processKills(RefPosition* killRefPosition)
3874
3902
: regRecord->recentRefPosition->nextRefPosition;
3875
3903
updateNextFixedRef(regRecord, regNextRefPos, nextKill);
3876
3904
}
3877
-
3878
- regsBusyUntilKill &= ~killRefPosition->getKilledRegisters();
3879
- INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_KILL_REGS, nullptr, REG_NA, nullptr, NONE,
3880
- killRefPosition->getKilledRegisters()));
3881
3905
}
3882
3906
3883
3907
//------------------------------------------------------------------------
@@ -4555,14 +4579,35 @@ void LinearScan::processBlockStartLocations(BasicBlock* currentBlock)
4555
4579
}
4556
4580
}
4557
4581
#else
4582
+
4558
4583
regMaskTP deadCandidates = ~liveRegs;
4559
4584
4560
4585
// Only focus on actual registers present
4561
4586
deadCandidates &= actualRegistersMask;
4587
+ handleDeadCandidates(deadCandidates.getLow(), REG_LOW_BASE, inVarToRegMap);
4588
+ #ifdef HAS_MORE_THAN_64_REGISTERS
4589
+ handleDeadCandidates(deadCandidates.getHigh(), REG_HIGH_BASE, inVarToRegMap);
4590
+ #endif // HAS_MORE_THAN_64_REGISTERS
4591
+ #endif // TARGET_ARM
4592
+ }
4562
4593
4563
- while (deadCandidates.IsNonEmpty())
4594
+ //------------------------------------------------------------------------
4595
+ // handleDeadCandidates: Handle registers thata re assigned to local variables.
4596
+ //
4597
+ // Arguments:
4598
+ // deadCandidates - mask of registers.
4599
+ // regBase - base register number.
4600
+ // inVarToRegMap - variable to register map.
4601
+ //
4602
+ // Return Value:
4603
+ // None
4604
+ //
4605
+ void LinearScan::handleDeadCandidates(regMaskSmall deadCandidates, int regBase, VarToRegMap inVarToRegMap)
4606
+ {
4607
+ while (deadCandidates != RBM_NONE)
4564
4608
{
4565
- regNumber reg = genFirstRegNumFromMaskAndToggle(deadCandidates);
4609
+ regNumber reg = (regNumber)(BitOperations::BitScanForward(deadCandidates) + regBase);
4610
+ deadCandidates ^= genSingleTypeRegMask(reg);
4566
4611
RegRecord* physRegRecord = getRegisterRecord(reg);
4567
4612
4568
4613
makeRegAvailable(reg, physRegRecord->registerType);
@@ -4592,7 +4637,6 @@ void LinearScan::processBlockStartLocations(BasicBlock* currentBlock)
4592
4637
}
4593
4638
}
4594
4639
}
4595
- #endif // TARGET_ARM
4596
4640
}
4597
4641
4598
4642
//------------------------------------------------------------------------
@@ -4741,6 +4785,24 @@ void LinearScan::freeRegister(RegRecord* physRegRecord)
4741
4785
}
4742
4786
}
4743
4787
4788
+ //------------------------------------------------------------------------
4789
+ // LinearScan::freeRegisters: Free the registers in 'regsToFree'
4790
+ //
4791
+ // Arguments:
4792
+ // regsToFree - the mask of registers to free, separated into low and high parts.
4793
+ // regBase - `0` or `64` depending on if the registers to be freed are in the lower or higher bank.
4794
+ //
4795
+ void LinearScan::freeRegistersNoMask(SingleTypeRegSet regsToFree, int regBase)
4796
+ {
4797
+ while (regsToFree != RBM_NONE)
4798
+ {
4799
+ regNumber nextReg = (regNumber)(BitOperations::BitScanForward(regsToFree) + regBase);
4800
+ regsToFree ^= genSingleTypeRegMask(nextReg);
4801
+
4802
+ RegRecord* regRecord = getRegisterRecord(nextReg);
4803
+ freeRegister(regRecord);
4804
+ }
4805
+ }
4744
4806
//------------------------------------------------------------------------
4745
4807
// LinearScan::freeRegisters: Free the registers in 'regsToFree'
4746
4808
//
@@ -4756,20 +4818,26 @@ void LinearScan::freeRegisters(regMaskTP regsToFree)
4756
4818
4757
4819
INDEBUG(dumpLsraAllocationEvent(LSRA_EVENT_FREE_REGS));
4758
4820
makeRegsAvailable(regsToFree);
4821
+ #ifdef TARGET_ARM
4759
4822
while (regsToFree.IsNonEmpty())
4760
4823
{
4761
4824
regNumber nextReg = genFirstRegNumFromMaskAndToggle(regsToFree);
4762
4825
4763
4826
RegRecord* regRecord = getRegisterRecord(nextReg);
4764
- #ifdef TARGET_ARM
4765
4827
if (regRecord->assignedInterval != nullptr && (regRecord->assignedInterval->registerType == TYP_DOUBLE))
4766
4828
{
4767
4829
assert(genIsValidDoubleReg(nextReg));
4768
4830
regsToFree.RemoveRegNumFromMask(regNumber(nextReg + 1));
4769
4831
}
4770
- #endif
4771
4832
freeRegister(regRecord);
4772
4833
}
4834
+ #else
4835
+ freeRegistersNoMask(regsToFree.getLow(), REG_LOW_BASE);
4836
+ #ifdef HAS_MORE_THAN_64_REGISTERS
4837
+ freeRegistersNoMask(regsToFree.getHigh(), REG_HIGH_BASE);
4838
+ #endif
4839
+
4840
+ #endif
4773
4841
}
4774
4842
4775
4843
//------------------------------------------------------------------------
0 commit comments