Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 24 additions & 1 deletion compiler/codegen/ScratchRegisterManager.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,13 @@ TR::Register *TR_ScratchRegisterManager::findOrCreateScratchRegister(TR_Register
if (msr->_reg->getKind() == rk && !(msr->_state & msrAllocated))
{
msr->_state |= msrAllocated;
// in addScratchRegistersToDependencyList, we only want to add donated registers that
// have been used. We cannot check this using the msrAllocated bit because that may be
// unset in reclaimScratchRegister
if (msr->_state & msrDonated)
{
msr->_state |= msrUsedDonated;
}
return msr->_reg;
}

Expand Down Expand Up @@ -117,7 +124,23 @@ void TR_ScratchRegisterManager::addScratchRegistersToDependencyList(

while (msr)
{
deps->unionNoRegPostCondition(msr->_reg, _cg);
/*
* To use a Scratch Register Manager inside ICF, we need to use donated registers.
* For non-donated regiters, we always want to add them to the dependency list, even if they are not marked as allocated,
* since they may have been reclaimed. The non-donated registers in the msr list are used at least once.
*
* However for donated registers, we only want to add them if they are actually used. They will still be in the MSR list
* even if they have never been used.
*/
if ((msr->_state & msrDonated) && (msr->_state & msrUsedDonated))
{
deps->unionNoRegPostCondition(msr->_reg, _cg);
}
else if (!(msr->_state & msrDonated))
{
deps->unionNoRegPostCondition(msr->_reg, _cg);
}

msr = iterator.getNext();
}
}
Expand Down
7 changes: 4 additions & 3 deletions compiler/codegen/ScratchRegisterManager.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -33,9 +33,10 @@ namespace TR { class RegisterDependencyConditions; }

enum TR_ManagedScratchRegisterStates
{
msrUnassigned = 0x00, // no register associated
msrAllocated = 0x01, // register has been allocated
msrDonated = 0x02 // register was donated to the list (not allocated)
msrUnassigned = 0x00, // no register associated
msrAllocated = 0x01, // register has been allocated
msrDonated = 0x02, // register was donated to the list (not allocated)
msrUsedDonated = 0x04 // register was donated to the list has been used at least once
};

class TR_ManagedScratchRegister
Expand Down