예제 #1
0
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);
         }
      }
   }
예제 #2
0
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();
         }
      }
   }