Skip to content

Commit

Permalink
AArch64: Enhance findBestFreeRegister to use register associations
Browse files Browse the repository at this point in the history
This commit changes `OMR::ARM64::Machine::findBestFreeRegister`
to use register associations for a better decision.

Signed-off-by: Akira Saitoh <saiaki@jp.ibm.com>
  • Loading branch information
Akira Saitoh committed Sep 3, 2020
1 parent 50b3ca6 commit 512a817
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 10 deletions.
53 changes: 47 additions & 6 deletions compiler/aarch64/codegen/OMRMachine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,14 @@ OMR::ARM64::Machine::Machine(TR::CodeGenerator *cg) :
self()->clearRegisterAssociations();
}

TR::RealRegister *OMR::ARM64::Machine::findBestFreeRegister(TR_RegisterKinds rk,
bool considerUnlatched)
// `currentInstruction` argument will be required when we implement live register analysis
TR::RealRegister *OMR::ARM64::Machine::findBestFreeRegister(TR::Instruction *currentInstruction,
TR_RegisterKinds rk,
bool considerUnlatched,
TR::Register *virtualReg)
{
uint32_t preference = (virtualReg != NULL) ? virtualReg->getAssociation() : 0;

int32_t first;
int32_t last;

Expand All @@ -70,6 +75,36 @@ TR::RealRegister *OMR::ARM64::Machine::findBestFreeRegister(TR_RegisterKinds rk,

uint32_t bestWeightSoFar = 0xffffffff;
TR::RealRegister *freeRegister = NULL;
TR::RealRegister *bestRegister = NULL;

/****************************************************************************************************************/
/* STEP 1 Register Associations */
/****************************************************************************************************************/
// Register Associations are best effort. If you really need to map a virtual to a real, use register pre/post dependency conditions.

// Check if the preferred register is free
if ((preference != 0) && (_registerFile[preference] != NULL) &&
((_registerFile[preference]->getState() == TR::RealRegister::Free) ||
(considerUnlatched && (_registerFile[preference]->getState() == TR::RealRegister::Unlatched))))
{
bestRegister = _registerFile[preference];

if (bestRegister->getState() == TR::RealRegister::Unlatched)
{
bestRegister->setAssignedRegister(NULL);
bestRegister->setState(TR::RealRegister::Free);
}

self()->cg()->traceRegisterAssignment("BEST FREE REG by pref for %R is %R", virtualReg, bestRegister);

return bestRegister;
}

/*******************************************************************************************************************/
/* STEP 2 Good 'ol linear search */
/****************************************************************************************************************/
// If no association or assoc fails, find any other free register

for (int32_t i = first; i <= last; i++)
{
if ((_registerFile[i]->getState() == TR::RealRegister::Free ||
Expand All @@ -86,6 +121,12 @@ TR::RealRegister *OMR::ARM64::Machine::findBestFreeRegister(TR_RegisterKinds rk,
freeRegister->setAssignedRegister(NULL);
freeRegister->setState(TR::RealRegister::Free);
}

if (freeRegister != NULL)
self()->cg()->traceRegisterAssignment("BEST FREE REG for %R is %R", virtualReg, freeRegister);
else
self()->cg()->traceRegisterAssignment("BEST FREE REG for %R is NULL (could not find one)", virtualReg);

return freeRegister;
}

Expand Down Expand Up @@ -301,7 +342,7 @@ TR::RealRegister *OMR::ARM64::Machine::reverseSpillState(TR::Instruction *curren

if (targetRegister == NULL)
{
targetRegister = self()->findBestFreeRegister(rk);
targetRegister = self()->findBestFreeRegister(currentInstruction, rk, false, spilledRegister);
if (targetRegister == NULL)
{
targetRegister = self()->freeBestRegister(currentInstruction, spilledRegister, NULL);
Expand Down Expand Up @@ -485,7 +526,7 @@ TR::RealRegister *OMR::ARM64::Machine::assignOneRegister(TR::Instruction *curren
}
else
{
assignedRegister = self()->findBestFreeRegister(rk, true);
assignedRegister = self()->findBestFreeRegister(currentInstruction, rk, true, virtualRegister);
if (assignedRegister == NULL)
{
cg->setRegisterAssignmentFlag(TR_RegisterSpilled);
Expand Down Expand Up @@ -635,7 +676,7 @@ void OMR::ARM64::Machine::coerceRegisterAssignment(TR::Instruction *currentInstr
#endif
if (!currentAssignedRegister || needTemp)
{
spareReg = self()->findBestFreeRegister(rk);
spareReg = self()->findBestFreeRegister(currentInstruction, rk, false, currentTargetVirtual);
self()->cg()->setRegisterAssignmentFlag(TR_IndirectCoercion);
if (spareReg == NULL)
{
Expand Down Expand Up @@ -686,7 +727,7 @@ void OMR::ARM64::Machine::coerceRegisterAssignment(TR::Instruction *currentInstr
currentTargetVirtual->getRegisterName(comp));
#endif
if (!currentAssignedRegister || needTemp)
spareReg = self()->findBestFreeRegister(rk);
spareReg = self()->findBestFreeRegister(currentInstruction, rk, false, currentTargetVirtual);

self()->cg()->setRegisterAssignmentFlag(TR_IndirectCoercion);
if (currentAssignedRegister)
Expand Down
18 changes: 17 additions & 1 deletion compiler/aarch64/codegen/OMRMachine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -62,14 +62,30 @@ class OMR_EXTENSIBLE Machine : public OMR::Machine
*/
Machine(TR::CodeGenerator *cg);

/**
* @brief Finds the best free register
* @param[in] currentInstruction : current instruction
* @param[in] rk : register kind
* @param[in] considerUnlatched : consider unlatched state or not
* @param[in] virtualReg : virtual register
* @return Free RealRegister
*/
TR::RealRegister *findBestFreeRegister(TR::Instruction *currentInstruction,
TR_RegisterKinds rk,
bool considerUnlatched = false,
TR::Register *virtualReg = NULL);

/**
* @brief Finds the best free register
* @param[in] rk : register kind
* @param[in] considerUnlatched : consider unlatched state or not
* @return Free RealRegister
*/
TR::RealRegister *findBestFreeRegister(TR_RegisterKinds rk,
bool considerUnlatched = false);
bool considerUnlatched = false)
{
return findBestFreeRegister(NULL, rk, considerUnlatched);
}

/**
* @brief Frees the best register
Expand Down
4 changes: 2 additions & 2 deletions compiler/aarch64/codegen/OMRMemoryReference.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -669,7 +669,7 @@ void OMR::ARM64::MemoryReference::assignRegisters(TR::Instruction *currentInstru
{
if (_baseRegister->getTotalUseCount() == _baseRegister->getFutureUseCount())
{
if ((assignedBaseRegister = machine->findBestFreeRegister(TR_GPR, true)) == NULL)
if ((assignedBaseRegister = machine->findBestFreeRegister(currentInstruction, TR_GPR, true, _baseRegister)) == NULL)
{
assignedBaseRegister = machine->freeBestRegister(currentInstruction, _baseRegister);
}
Expand Down Expand Up @@ -701,7 +701,7 @@ void OMR::ARM64::MemoryReference::assignRegisters(TR::Instruction *currentInstru
{
if (_indexRegister->getTotalUseCount() == _indexRegister->getFutureUseCount())
{
if ((assignedIndexRegister = machine->findBestFreeRegister(TR_GPR, false)) == NULL)
if ((assignedIndexRegister = machine->findBestFreeRegister(currentInstruction, TR_GPR, false, _indexRegister)) == NULL)
{
assignedIndexRegister = machine->freeBestRegister(currentInstruction, _indexRegister);
}
Expand Down
2 changes: 1 addition & 1 deletion compiler/aarch64/codegen/OMRRegisterDependency.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -475,7 +475,7 @@ void TR_ARM64RegisterDependencyGroup::assignRegisters(
{
if (virtReg->getTotalUseCount() == virtReg->getFutureUseCount())
{
if ((assignedRegister = machine->findBestFreeRegister(virtReg->getKind(), true)) == NULL)
if ((assignedRegister = machine->findBestFreeRegister(currentInstruction, virtReg->getKind(), true, virtReg)) == NULL)
{
assignedRegister = machine->freeBestRegister(currentInstruction, virtReg, NULL);
}
Expand Down

0 comments on commit 512a817

Please sign in to comment.