Exemplo n.º 1
0
// Process the structure recursively
//
int32_t
TR_ExpressionsSimplification::perform(TR_Structure * str)
   {
   if (trace())
      traceMsg(comp(), "Analyzing root Structure : %p\n", str);

   TR_RegionStructure *region;

   // Only regions can be simplified
   //
   if (!(region = str->asRegion()))
      return 0;

   TR_RegionStructure::Cursor it(*region);

   for (TR_StructureSubGraphNode *node = it.getCurrent();
        node != 0;
        node = it.getNext())
      {
      // Too strict
      /*
      if ((node->getPredecessors().size() == 1))
         {
         TR::CFGEdge *edge = node->getPredecessors().front();
         TR_StructureSubGraphNode *pred = toStructureSubGraphNode(edge->getFrom());
         TR_BlockStructure *b = pred->getStructure()->asBlock();
         if (b && pred->getSuccessors().size() == 1))
            perform(node->getStructure());
         }
      */
      perform(node->getStructure());
      }

   // debug only
   //
   /*
   if (region->isNaturalLoop() &&
          (region->getParent()  &&
            !region->getParent()->asRegion()->isCanonicalizedLoop()))
      {
      traceMsg(comp(), "Loop not canonicalized %x\n", region);
      }
   */

   TR::Block *entryBlock = region->getEntryBlock();
   if (region->isNaturalLoop() && !entryBlock->isCold() &&
          (region->getParent() /* &&
            region->getParent()->asRegion()->isCanonicalizedLoop() */))
         {
         if (trace())
           traceMsg(comp(), "Found candidate non cold loop %p for expression elimination\n", region);

         findAndSimplifyInvariantLoopExpressions(region);
         }

   return 1;  // Need to specify the cost
   }
Exemplo n.º 2
0
static void computeInvarianceOfAllStructures(TR::Compilation *comp, TR_Structure * s)
   {
   TR_RegionStructure *region = s->asRegion();

   if (region)
      {
      TR_StructureSubGraphNode *node;
      TR_RegionStructure::Cursor si(*region);
      for (node = si.getCurrent(); node != NULL; node = si.getNext())
         computeInvarianceOfAllStructures(comp, node->getStructure());

      region->resetInvariance();
      if (region->isNaturalLoop() /*|| region->containsInternalCycles() */)
         {
         region->computeInvariantExpressions();
         }
      }
   }
Exemplo n.º 3
0
TR_ExpressionsSimplification::LoopInfo*
TR_ExpressionsSimplification::findLoopInfo(TR_RegionStructure* region)
   {
   ListIterator<TR::CFGEdge> exitEdges(&region->getExitEdges());

   if (region->getExitEdges().getSize() != 1)
      {
      if (trace())
         traceMsg(comp(), "Region with more than 1 exit edges can't be handled\n");
      return 0;
      }

   TR_StructureSubGraphNode* exitNode = toStructureSubGraphNode(exitEdges.getFirst()->getFrom());

   if (!exitNode->getStructure()->asBlock())
      {
      if (trace())
         traceMsg(comp(), "The exit block can't be found\n");
      return 0;
      }

   TR::Block *exitBlock = exitNode->getStructure()->asBlock()->getBlock();
   TR::Node *lastTreeInExitBlock = exitBlock->getLastRealTreeTop()->getNode();

   if (trace())
      {
      traceMsg(comp(), "The exit block is %d\n", exitBlock->getNumber());
      traceMsg(comp(), "The branch node is %p\n", lastTreeInExitBlock);
      }


   if (!lastTreeInExitBlock->getOpCode().isBranch())
      {
      if (trace())
         traceMsg(comp(), "The branch node couldn't be found\n");
      return 0;
      }

   if (lastTreeInExitBlock->getNumChildren() < 2)
      {
      if (trace())
         traceMsg(comp(), "The branch node has less than 2 children\n");
      return 0;
      }

   TR::Node *firstChildOfLastTree = lastTreeInExitBlock->getFirstChild();
   TR::Node *secondChildOfLastTree = lastTreeInExitBlock->getSecondChild();

   if (!firstChildOfLastTree->getOpCode().hasSymbolReference())
      {
      if (trace())
         traceMsg(comp(), "The branch node's first child node %p - its opcode does not have a symbol reference\n", firstChildOfLastTree);
      return 0;
      }

   TR::SymbolReference *firstChildSymRef = firstChildOfLastTree->getSymbolReference();

   if (trace())
      traceMsg(comp(), "Symbol Reference: %p Symbol: %p\n", firstChildSymRef, firstChildSymRef->getSymbol());

   // Locate the induction variable that matches with the exit node symbol
   //
   TR_InductionVariable *indVar = region->findMatchingIV(firstChildSymRef);
   if (!indVar) return 0;

   if (!indVar->getIncr()->asIntConst())
      {
      if (trace())
         traceMsg(comp(), "Increment is not a constant\n");
      return 0;
      }

   int32_t increment = indVar->getIncr()->getLowInt();

   _visitCount = comp()->incVisitCount();
   bool indVarWrittenAndUsedUnexpectedly = false;
   if (firstChildOfLastTree->getReferenceCount() > 1)
      {
      TR::TreeTop *cursorTreeTopInExitBlock = exitBlock->getEntry();
      TR::TreeTop *exitTreeTopInExitBlock = exitBlock->getExit();

      bool loadSeen = false;
      while (cursorTreeTopInExitBlock != exitTreeTopInExitBlock)
         {
         TR::Node *cursorNode = cursorTreeTopInExitBlock->getNode();
         if (checkForLoad(cursorNode, firstChildOfLastTree))
            loadSeen = true;

         if (!cursorNode->getOpCode().isStore() &&
             (cursorNode->getNumChildren() > 0))
           cursorNode = cursorNode->getFirstChild();

         if (cursorNode->getOpCode().isStore() &&
             (cursorNode->getSymbolReference() == firstChildSymRef))
            {
            indVarWrittenAndUsedUnexpectedly = true;
            if ((cursorNode->getFirstChild() == firstChildOfLastTree) ||
                !loadSeen)
               indVarWrittenAndUsedUnexpectedly = false;
            else
               break;
            }

         cursorTreeTopInExitBlock = cursorTreeTopInExitBlock->getNextTreeTop();
         }
      }

   if (indVarWrittenAndUsedUnexpectedly)
      {
      return 0;
      }

   int32_t lowerBound;
   int32_t upperBound = 0;
   TR::Node *bound = 0;
   bool equals = false;

   switch(lastTreeInExitBlock->getOpCodeValue())
      {
      case TR::ificmplt:
      case TR::ificmpgt:
         equals = true;
      case TR::ificmple:
      case TR::ificmpge:
         if (!(indVar->getEntry() && indVar->getEntry()->asIntConst()))
            {
            if (trace())
               traceMsg(comp(), "Entry value is not a constant\n");
            return 0;
            }
         lowerBound = indVar->getEntry()->getLowInt();

         if (secondChildOfLastTree->getOpCode().isLoadConst())
            {
            upperBound = secondChildOfLastTree->getInt();
            }
         else if (secondChildOfLastTree->getOpCode().isLoadVar())
            {
            bound = secondChildOfLastTree;
            }
         else
            {
            if (trace())
               traceMsg(comp(), "Second child is not a const or a load\n");
            return 0;
            }
         return new (trStackMemory()) LoopInfo(bound, lowerBound, upperBound, increment, equals);


      default:
         if (trace())
            traceMsg(comp(), "The condition has not been implemeted\n");
         return 0;
      }

   return 0;
   }