void OMR::Power::RegisterDependencyConditions::bookKeepingRegisterUses(TR::Instruction *instr, TR::CodeGenerator *cg) { // *this swipeable for debugging purposes TR::Register *virtReg; TR::RealRegister::RegNum regNum; TR::RegisterDependencyConditions *assoc; int numAssoc = 0; if (instr->getOpCodeValue() == TR::InstOpCode::assocreg) return; // Don't track associations or emit assocregs in outlined code // Register assigner can save/restore associations across outlined sections properly, however no such mechanism exists for instruction selection // so we don't want these associations to clobber the associations that were set in main line code, which are more important // TODO: Fix this by saving/restoring the associations in swapInstructionListsWithCompilation() bool isOOL = cg->getIsInOOLSection(); TR::Machine *machine = cg->machine(); assoc = !isOOL ? new (cg->trHeapMemory()) TR::RegisterDependencyConditions(0,_addCursorForPre, cg->trMemory()) : 0; for (int i = 0; i < _addCursorForPre; i++) { virtReg = _preConditions->getRegisterDependency(i)->getRegister(); regNum = _preConditions->getRegisterDependency(i)->getRealRegister(); if (!isOOL) { // Add to the association condition when the association is changed // from one virtual register to another if (machine->getVirtualAssociatedWithReal(regNum) != virtReg && machine->getVirtualAssociatedWithReal(regNum) != 0) { assoc->addPostCondition(machine->getVirtualAssociatedWithReal(regNum), regNum); numAssoc++; } // Keep track of the virtual register map to real registers! machine->setVirtualAssociatedWithReal(regNum, virtReg); } instr->useRegister(virtReg); if (!isOOL) { cg->setRealRegisterAssociation(virtReg, regNum); if (_preConditions->getRegisterDependency(i)->getExcludeGPR0()) cg->addRealRegisterInterference(virtReg, TR::RealRegister::gr0); } } if (numAssoc > 0) { // Emit an AssocRegs instruction to track the previous association assoc->setNumPostConditions(numAssoc, cg->trMemory()); generateDepInstruction(cg, TR::InstOpCode::assocreg, instr->getNode(), assoc, instr->getPrev()); } for (int j = 0; j < _addCursorForPost; j++) { virtReg = _postConditions->getRegisterDependency(j)->getRegister(); regNum = _postConditions->getRegisterDependency(j)->getRealRegister(); instr->useRegister(virtReg); if (!isOOL) { cg->setRealRegisterAssociation(virtReg, regNum); if (_postConditions->getRegisterDependency(j)->getExcludeGPR0()) cg->addRealRegisterInterference(virtReg, TR::RealRegister::gr0); } } }
void OMR::X86::Instruction::assignRegisters(TR_RegisterKinds kindsToBeAssigned) { if (!self()->getDependencyConditions()) { // Fast path when there are no dependency conditions. // return; } if (self()->getOpCodeValue() != ASSOCREGS) { self()->aboutToAssignRegDeps(); if ((self()->cg()->getAssignmentDirection() == self()->cg()->Backward)) { self()->getDependencyConditions()->assignPostConditionRegisters(self(), kindsToBeAssigned, self()->cg()); self()->getDependencyConditions()->assignPreConditionRegisters(self(), kindsToBeAssigned, self()->cg()); } else { self()->getDependencyConditions()->assignPreConditionRegisters(self()->getPrev(), kindsToBeAssigned, self()->cg()); self()->getDependencyConditions()->assignPostConditionRegisters(self(), kindsToBeAssigned, self()->cg()); } } else if ((self()->getOpCodeValue() == ASSOCREGS) && self()->cg()->enableRegisterAssociations()) { if (kindsToBeAssigned & TR_GPR_Mask) { TR::Machine *machine = self()->cg()->machine(); // First traverse the existing associations and remove them // so that they don't interfere with the new ones // for (int i = TR::RealRegister::FirstGPR; i <= TR::RealRegister::LastAssignableGPR; ++i) { // Skip non-assignable registers // if (machine->getX86RealRegister((TR::RealRegister::RegNum)i)->getState() == TR::RealRegister::Locked) continue; TR::Register *virtReg = machine->getVirtualAssociatedWithReal((TR::RealRegister::RegNum)i); if (virtReg) { virtReg->setAssociation(TR::RealRegister::NoReg); } } // Next loop through and set up the new associations (both on the machine // and by associating the virtual registers with their real dependencies) // TR_X86RegisterDependencyGroup *depGroup = self()->getDependencyConditions()->getPostConditions(); for (int j = 0; j < self()->getDependencyConditions()->getNumPostConditions(); ++j) { TR::RegisterDependency *dep = depGroup->getRegisterDependency(j); machine->setVirtualAssociatedWithReal(dep->getRealRegister(), dep->getRegister()); } machine->setGPRWeightsFromAssociations(); } } }