void TR_OutlinedInstructions::assignRegistersOnOutlinedPath(TR_RegisterKinds kindsToBeAssigned, TR::X86VFPSaveInstruction *vfpSaveInstruction) { if (hasBeenRegisterAssigned()) { TR_ASSERT(0, "these registers should not have been assigned already"); return; } // Register assign the outlined instructions. // _cg->doBackwardsRegisterAssignment(kindsToBeAssigned, _appendInstruction); // Ensure correct VFP state at the start of the outlined instruction sequence. // generateVFPRestoreInstruction(comp()->getAppendInstruction(), vfpSaveInstruction, _cg); // Link in the helper stream into the mainline code. // TR::Instruction *appendInstruction = comp()->getAppendInstruction(); appendInstruction->setNext(_firstInstruction); _firstInstruction->setPrev(appendInstruction); comp()->setAppendInstruction(_appendInstruction); setHasBeenRegisterAssigned(true); }
void TR_PPCOutOfLineCodeSection::assignRegisters(TR_RegisterKinds kindsToBeAssigned) { TR::Compilation* comp = _cg->comp(); if (hasBeenRegisterAssigned()) return; // nested internal control flow assert: _cg->setInternalControlFlowSafeNestingDepth(_cg->internalControlFlowNestingDepth()); // Create a dependency list on the first instruction in this stream that captures all current real register associations. // This is necessary to get the register assigner back into its original state before the helper stream was processed. _cg->incOutOfLineColdPathNestedDepth(); // This prevents the OOL entry label from resetting all register's startOfranges during RA _cg->toggleIsInOOLSection(); TR::RegisterDependencyConditions *liveRealRegDeps = _cg->machine()->createCondForLiveAndSpilledGPRs(true, _cg->getSpilledRegisterList()); if (liveRealRegDeps) _firstInstruction->setDependencyConditions(liveRealRegDeps); _cg->toggleIsInOOLSection(); // toggle it back because swapInstructionListsWithCompilation() also calls toggle... // Register assign the helper dispatch instructions. swapInstructionListsWithCompilation(); _cg->doRegisterAssignment(kindsToBeAssigned); swapInstructionListsWithCompilation(); _cg->decOutOfLineColdPathNestedDepth(); // Returning to mainline, reset this counter _cg->setInternalControlFlowSafeNestingDepth(0); // Link in the helper stream into the mainline code. // We will end up with the OOL items attached at the bottom of the instruction stream TR::Instruction *appendInstruction = _cg->getAppendInstruction(); appendInstruction->setNext(_firstInstruction); _firstInstruction->setPrev(appendInstruction); _cg->setAppendInstruction(_appendInstruction); setHasBeenRegisterAssigned(true); }
void TR_OutlinedInstructions::assignRegisters(TR_RegisterKinds kindsToBeAssigned, TR::X86VFPSaveInstruction *vfpSaveInstruction) { if (hasBeenRegisterAssigned()) return; // nested internal control flow assert: _cg->setInternalControlFlowSafeNestingDepth(_cg->internalControlFlowNestingDepth()); // Create a dependency list on the first instruction in this stream that captures all // current real register associations. This is necessary to get the register assigner // back into its original state before the helper stream was processed. // TR::RegisterDependencyConditions *liveRealRegDeps = _cg->machine()->createDepCondForLiveGPRs(); _firstInstruction->setDependencyConditions(liveRealRegDeps); #if 0 // If the outlined section jumps back to a section that's expecting a certain register // state then add register dependencies on the exit branch to set that state. // if (_postDependencyMergeList) { TR::RegisterDependencyConditions *mergeDeps = _postDependencyMergeList->clone(_cg); TR_ASSERT(_appendInstruction->getDependencyConditions() == NULL, "unexpected reg deps on OOL append instruction"); _appendInstruction->setDependencyConditions(mergeDeps); TR_X86RegisterDependencyGroup *depGroup = mergeDeps->getPostConditions(); for (int32_t i=0; i<mergeDeps->getNumPostConditions(); i++) { TR::RegisterDependency *dependency = depGroup->getRegisterDependency(i); TR::Register *virtReg = dependency->getRegister(); virtReg->incTotalUseCount(); virtReg->incFutureUseCount(); #ifdef DEBUG // Ensure all register dependencies have been assigned. // TR_ASSERT(dependency->getRealRegister() != TR::RealRegister::NoReg, "unassigned merge dep register"); TR_ASSERT(virtReg->getAssignedRealRegister() == _cg->machine()->getX86RealRegister(dependency->getRealRegister()), "unexpected(?) register assignment"); #endif } } #endif // TODO:AMD64: Fix excessive register assignment exchanges in outlined instruction dispatch. // Ensure correct VFP state at the start of the outlined instruction sequence. // generateVFPRestoreInstruction(comp()->getAppendInstruction(), vfpSaveInstruction, _cg); // Link in the helper stream into the mainline code. // TR::Instruction *appendInstruction = comp()->getAppendInstruction(); appendInstruction->setNext(_firstInstruction); _firstInstruction->setPrev(appendInstruction); comp()->setAppendInstruction(_appendInstruction); // Register assign the helper dispatch instructions. // _cg->doBackwardsRegisterAssignment(kindsToBeAssigned, _appendInstruction, appendInstruction); // Returning to mainline, reset this counter _cg->setInternalControlFlowSafeNestingDepth(0); setHasBeenRegisterAssigned(true); }