예제 #1
0
int32_t
OMR::X86::I386::CodeGenerator::getMaximumNumberOfGPRsAllowedAcrossEdge(TR::Node *node)
   {
   // TODO: Currently, lookupEvaluator doesn't deal properly with different
   // glRegDeps on different cases of a lookupswitch.
   //
   static const char *enableLookupswitch = feGetEnv("TR_enableGRAAcrossLookupSwitch");
   if (!enableLookupswitch && node->getOpCode().getOpCodeValue()==TR::lookup)
      return 1;

   if (node->getOpCode().getOpCodeValue()==TR::table)
      {
      // 1 for jump table base reg, which is not apparent in the trees
      // 1 for ebp when it is needed for the VMThread
      //
      return self()->getNumberOfGlobalGPRs() - 2;
      }

   if (node->getOpCode().isIf())
      {
      // we run out of all but one/two registers in these cases
      //
      if (node->getFirstChild()->getType().isInt64())
         {
         if (node->getOpCode().isBranch())
            {
            TR::Node *firstChild = node->getFirstChild();
            TR::Node *secondChild = node->getSecondChild();
            int extraRegsAvailable = 0;


            if(firstChild->getOpCodeValue() == TR::d2l ||
               secondChild->getOpCodeValue() == TR::d2l)
               {
               return 1;
               }

            if ((firstChild->getReferenceCount() == 1 &&
                firstChild->getOpCode().isLoadVarDirect()) ||
                (secondChild->getReferenceCount() == 1 &&
                 firstChild->getOpCode().isLoadVarDirect()))
               extraRegsAvailable += 0; // TODO: put it back to 2 when looking at GRA, GRA pushes allocation of 8 registers

            return 2 + extraRegsAvailable;
            }
         else
            {
            // TR_lcmpXX opcodes take up 5 regs
            //
            return 1;
            }
         }

      // we run out of all but one register in these cases....last time I tried....
      //

      if (node->getFirstChild()->getOpCodeValue() == TR::instanceof)
         {
         if (!TR::TreeEvaluator::instanceOfOrCheckCastNeedSuperTest(node->getFirstChild(), self())  &&
             TR::TreeEvaluator::instanceOfOrCheckCastNeedEqualityTest(node->getFirstChild(), self()))
            return self()->getNumberOfGlobalGPRs() - 4; // ebp plus three other regs if vft masking is enabled
         else
            return 0;
         }

      // All other conditional branches, we usually need one reg for the compare and possibly one for the vmthread
      //return getNumberOfGlobalGPRs() - 1 - (node->isVMThreadRequired()? 1 : 0);
      // vmThread required might be set on a node after GRA has ran
      return self()->getNumberOfGlobalGPRs() - 2;
      }

   return INT_MAX;
   }