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(); } } }
OMR::ARM::RegisterDependencyConditions::RegisterDependencyConditions( TR::Node *node, uint32_t extranum, TR::Instruction **cursorPtr, TR::CodeGenerator *cg) { List<TR::Register> regList(cg->trMemory()); TR::Instruction *cursor = (cursorPtr == NULL ? NULL : *cursorPtr); int32_t totalNum = node->getNumChildren() + extranum; int32_t i; cg->comp()->incVisitCount(); int32_t numLongs = 0; // // Pre-compute how many longs are global register candidates // for (i = 0; i < node->getNumChildren(); ++i) { TR::Node *child = node->getChild(i); TR::Register *reg = child->getRegister(); if (reg!=NULL /* && reg->getKind()==TR_GPR */) { if (child->getHighGlobalRegisterNumber() > -1) numLongs++; } } totalNum = totalNum + numLongs; _preConditions = TR_ARMRegisterDependencyGroup::create(totalNum, cg->trMemory()); _postConditions = TR_ARMRegisterDependencyGroup::create(totalNum, cg->trMemory()); _numPreConditions = totalNum; _addCursorForPre = 0; _numPostConditions = totalNum; _addCursorForPost = 0; // First, handle dependencies that match current association for (i=0; i<node->getNumChildren(); i++) { TR::Node *child = node->getChild(i); TR::Register *reg = child->getRegister(); TR::Register *highReg = NULL; TR::RealRegister::RegNum regNum = (TR::RealRegister::RegNum)cg->getGlobalRegister(child->getGlobalRegisterNumber()); TR::RealRegister::RegNum highRegNum; if (child->getHighGlobalRegisterNumber() > -1) { highRegNum = (TR::RealRegister::RegNum)cg->getGlobalRegister(child->getHighGlobalRegisterNumber()); TR::RegisterPair *regPair = reg->getRegisterPair(); TR_ASSERT(regPair, "assertion failure"); highReg = regPair->getHighOrder(); reg = regPair->getLowOrder(); if (highReg->getAssociation() != highRegNum || reg->getAssociation() != regNum) continue; } else if (reg->getAssociation() != regNum) continue; TR_ASSERT(!regList.find(reg) && (!highReg || !regList.find(highReg)), "Should not happen\n"); addPreCondition(reg, regNum); addPostCondition(reg, regNum); regList.add(reg); if (highReg) { addPreCondition(highReg, highRegNum); addPostCondition(highReg, highRegNum); regList.add(highReg); } } // Second pass to handle dependencies for which association does not exist // or does not match for (i=0; i<node->getNumChildren(); i++) { TR::Node *child = node->getChild(i); TR::Register *reg = child->getRegister(); TR::Register *highReg = NULL; TR::Register *copyReg = NULL; TR::Register *highCopyReg = NULL; TR::RealRegister::RegNum regNum = (TR::RealRegister::RegNum)cg->getGlobalRegister(child->getGlobalRegisterNumber()); TR::RealRegister::RegNum highRegNum; if (child->getHighGlobalRegisterNumber() > -1) { highRegNum = (TR::RealRegister::RegNum)cg->getGlobalRegister(child->getHighGlobalRegisterNumber()); TR::RegisterPair *regPair = reg->getRegisterPair(); TR_ASSERT(regPair, "assertion failure"); highReg = regPair->getHighOrder(); reg = regPair->getLowOrder(); if (highReg->getAssociation() == highRegNum && reg->getAssociation() == regNum) continue; } else if (reg->getAssociation() == regNum) continue; if (regList.find(reg) || (highReg && regList.find(highReg))) { TR_ARMOpCodes opCode; TR_RegisterKinds kind = reg->getKind(); switch (kind) { case TR_GPR: opCode = ARMOp_mov; break; case TR_FPR: opCode = ARMOp_fmrs; break; default: TR_ASSERT(0, "Invalid register kind."); } if (regList.find(reg)) { bool containsInternalPointer = false; if (reg->getPinningArrayPointer()) containsInternalPointer = true; copyReg = (reg->containsCollectedReference() && !containsInternalPointer) ? cg->allocateCollectedReferenceRegister() : cg->allocateRegister(kind); if (containsInternalPointer) { copyReg->setContainsInternalPointer(); copyReg->setPinningArrayPointer(reg->getPinningArrayPointer()); } cursor = generateTrg1Src1Instruction(cg, opCode, node, copyReg, reg, cursor); reg = copyReg; } if (highReg && regList.find(highReg)) { bool containsInternalPointer = false; if (highReg->getPinningArrayPointer()) containsInternalPointer = true; highCopyReg = (highReg->containsCollectedReference() && !containsInternalPointer) ? cg->allocateCollectedReferenceRegister() : cg->allocateRegister(kind); if (containsInternalPointer) { highCopyReg->setContainsInternalPointer(); highCopyReg->setPinningArrayPointer(highReg->getPinningArrayPointer()); } cursor = generateTrg1Src1Instruction(cg, opCode, node, highCopyReg, highReg, cursor); highReg = highCopyReg; } } reg->setAssociation(regNum); addPreCondition(reg, regNum); addPostCondition(reg, regNum); if (copyReg != NULL) cg->stopUsingRegister(copyReg); else regList.add(reg); if (highReg) { highReg->setAssociation(highRegNum); addPreCondition(highReg, highRegNum); addPostCondition(highReg, highRegNum); if (highCopyReg != NULL) cg->stopUsingRegister(highCopyReg); else regList.add(highReg); } } if (cursor != NULL && cursorPtr != NULL) *cursorPtr = cursor; }