Example #1
0
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);
   }
Example #2
0
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);
   }
Example #3
0
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);
   }