Example #1
0
// TODO: Try to combine the 2 layoutParm functions.
int32_t
TR::AMD64SystemLinkage::layoutParm(
      TR::ParameterSymbol *parmSymbol,
      int32_t &dataCursor,
      uint16_t &intReg,
      uint16_t &floatReg,
      TR::parmLayoutResult &layoutResult)
   {
   //AMD64 SysV ABI:  if the size of an object is larger than four eightbytes, or it contains unaligned fields, it has class MEMORY.
   if (parmSymbol->getSize() > 4*AMD64_STACK_SLOT_SIZE) goto LAYOUT_ON_STACK;

   if (layoutTypeInRegs(parmSymbol->getDataType(), intReg, floatReg, layoutResult))
      {
      layoutResult.abstract |= TR::parmLayoutResult::IN_LINKAGE_REG;

      if (parmSymbol->getSize() > GPR_REG_WIDTH)
         layoutResult.abstract |= TR::parmLayoutResult::IN_LINKAGE_REG_PAIR;

      if (comp()->getOption(TR_TraceCG))
         traceMsg(comp(), "layout param symbol %p in register\n", parmSymbol);

      if (!getProperties().getCallerFrameAllocatesSpaceForLinkageRegisters())
         return 0;
      }

LAYOUT_ON_STACK:
   layoutResult.abstract |= TR::parmLayoutResult::ON_STACK;
   int32_t align = layoutTypeOnStack(parmSymbol->getDataType(), dataCursor, layoutResult);
   if (comp()->getOption(TR_TraceCG))
      traceMsg(comp(), "layout param symbol %p on stack\n", parmSymbol);
   return align;
   }
Example #2
0
void TR_ReachingDefinitions::initializeGenAndKillSetInfo()
   {
   // For each block in the CFG build the gen and kill set for this analysis.
   // Go in treetop order, which guarantees that we see the correct (i.e. first)
   // evaluation point for each node.
   //
   TR::Block *block;
   int32_t   blockNum = 0;
   bool      seenException = false;
   TR_BitVector defsKilled(getNumberOfBits(), trMemory()->currentStackRegion());

   comp()->incVisitCount();
   for (TR::TreeTop *treeTop = comp()->getStartTree(); treeTop; treeTop = treeTop->getNextTreeTop())
      {
      TR::Node *node = treeTop->getNode();

      if (node->getOpCodeValue() == TR::BBStart)
         {
         block = node->getBlock();
         blockNum = block->getNumber();
         seenException  = false;
         if (traceRD())
            traceMsg(comp(), "\nNow generating gen and kill information for block_%d\n", blockNum);
         continue;
         }

#if DEBUG
      if (node->getOpCodeValue() == TR::BBEnd && traceRD())
         {
         traceMsg(comp(), "  Block %d:\n", blockNum);
         traceMsg(comp(), "     Gen set ");
         if (_regularGenSetInfo[blockNum])
            _regularGenSetInfo[blockNum]->print(comp());
         else
            traceMsg(comp(), "{}");
         traceMsg(comp(), "\n     Kill set ");
         if (_regularKillSetInfo[blockNum])
            _regularKillSetInfo[blockNum]->print(comp());
         else
            traceMsg(comp(), "{}");
         traceMsg(comp(), "\n     Exception Gen set ");
         if (_exceptionGenSetInfo[blockNum])
            _exceptionGenSetInfo[blockNum]->print(comp());
         else
            traceMsg(comp(), "{}");
         traceMsg(comp(), "\n     Exception Kill set ");
         if (_exceptionKillSetInfo[blockNum])
            _exceptionKillSetInfo[blockNum]->print(comp());
         else
            traceMsg(comp(), "{}");
         continue;
         }
#endif

      initializeGenAndKillSetInfoForNode(node, defsKilled, seenException, blockNum, NULL);

      if (!seenException && treeHasChecks(treeTop))
         seenException = true;
      }
   }
Example #3
0
bool TR_LocalLiveRangeReduction::verifyRefInfo(List<TR::Node> *verifier,List<TR::Node> *refList)
   {

   ListIterator<TR::Node> listIt(refList);
   TR::Node *node = NULL;
   for ( node = listIt.getFirst(); node != NULL; node = listIt.getNext())
      {
      if (verifier->find(node))
    	 verifier->remove(node);
      else
    	 {
    	 if (trace())
    	    traceMsg(comp(),"LocalLiveRangeReduction:node %p should not have beed in the List\n",node);
    	 return false;
    	 }
      }

   if (!verifier->isEmpty())
      {
      if (trace())
    	 traceMsg(comp(),"LocalLiveRangeReduction: there are nodes that should have been in the List\n");
      return false;
      }
   return true;

   }
Example #4
0
void
TR::AMD64SystemLinkage::setUpStackSizeForCallNode(TR::Node* node)
   {
   const TR::X86LinkageProperties     &properties = getProperties();
   uint16_t intReg = 0, floatReg = 0;
   // AMD64 SysV ABI: The end of the input argument area shall be aligned on a 16 (32, if __m256 is passed on stack) byte boundary. In other words, the value (%rsp + 8) is always a multiple of 16 (32) when control is transferred to the function entry point.
   int32_t alignment = AMD64_DEFAULT_STACK_ALIGNMENT;
   int32_t sizeOfOutGoingArgs = 0;

   if (comp()->getOption(TR_TraceCG))
      traceMsg(comp(), "setUpStackSizeForCallNode for call node %p\n", node);

   for (int32_t i= node->getFirstArgumentIndex(); i<node->getNumChildren(); ++i)
      {
      TR::parmLayoutResult fakeParm;
      TR::Node *parmNode = node->getChild(i);
      int32_t parmAlign = layoutParm(parmNode, sizeOfOutGoingArgs, intReg, floatReg, fakeParm);
      if (parmAlign == 32)
         alignment = 32;
      }

   if (sizeOfOutGoingArgs > cg()->getLargestOutgoingArgSize())
      {
      cg()->setLargestOutgoingArgSize(sizeOfOutGoingArgs);
      if (comp()->getOption(TR_TraceCG))
         traceMsg(comp(), "setUpStackSizeForCallNode setLargestOutgoingArgSize %d(for call node %p)\n", sizeOfOutGoingArgs, node);
      }

   if (alignment > _properties.getOutgoingArgAlignment())
      {
      _properties.setOutgoingArgAlignment(alignment);
      if (comp()->getOption(TR_TraceCG))
         traceMsg(comp(), "setUpStackSizeForCallNode setOutgoingArgAlignment %d(for call node %p)\n", alignment, node);
      }
   }
void TR_ExpressionsSimplification::setStoreMotionCandidates(TR::Node *node, TR::TreeTop *tt)
   {
   // Must be a store node, of any type but not holding a monitor object
   //
   if (node->getOpCode().isStore() &&
       !node->getSymbol()->isStatic() &&
       !node->getSymbol()->holdsMonitoredObject())
      {
      if (trace())
         traceMsg(comp(), "Node %p: The opcode is a non-static, non-monitor object store\n", node);

      for (int32_t i = 0; i < node->getNumChildren(); i++)
         {
         if (!_currentRegion->isExprInvariant(node->getChild(i)))
            {
            if (trace())
               traceMsg(comp(), "Node %p: The store is not loop-invariant due to child %p\n", node, node->getChild(i));
            return;
            }
         }
      // If store's operands are loop-invariant
      if (trace())
         {
         traceMsg(comp(), "Node %p: The store's operands are all loop-invariant, adding candidate\n", node);
         traceMsg(comp(), "Node %p:   - value of isExprInvariant for the store itself is %s\n", node, _currentRegion->isExprInvariant(node) ? "true" : "false");
         }
      _candidateTTs->add(tt);
      }
   }
Example #6
0
void TR_LocalLiveRangeReduction::printRefInfo(TR_TreeRefInfo *treeRefInfo)
   {
   if (trace())
      {
      TR::Node *n;
      ListIterator<TR::Node> lit(treeRefInfo->getFirstRefNodesList());
      traceMsg(comp(),"[%p]:F={",treeRefInfo->getTreeTop()->getNode());
      for (n = lit.getFirst(); n != NULL; n = lit.getNext())
    	 traceMsg(comp(),"%p  ",n);

      traceMsg(comp(),"},M={");
      lit.set(treeRefInfo->getMidRefNodesList());
      for (n = lit.getFirst(); n != NULL; n = lit.getNext())
    	 traceMsg(comp(),"%p  ",n);

      traceMsg(comp(),"},L={");
      lit.set(treeRefInfo->getLastRefNodesList());
      for (n = lit.getFirst(); n != NULL; n = lit.getNext())
    	 traceMsg(comp(),"%p  ",n);

      traceMsg(comp(),"}\n");

      if (treeRefInfo->getUseSym() && treeRefInfo->getDefSym())
    	 {
    	 traceMsg(comp(),"[%p]:use = ",treeRefInfo->getTreeTop()->getNode());
    	 treeRefInfo->getUseSym()->print(comp());

    	 traceMsg(comp(),"  def = ");
    	 treeRefInfo->getDefSym()->print(comp());
    	 traceMsg(comp(),"\n");
    	 }
      }
   }
Example #7
0
const int32_t TR_LoadExtensions::setExtensionPreference(TR::Node* load, TR::Node* conversion)
   {
   int32_t result;

   if (conversion->isZeroExtension() || conversion->getOpCode().isUnsigned())
      {
      if (trace())
         {
         traceMsg(comp(), "\t\tCounting unsigned load %s [%p] under %s [%p]\n", 
            load->getOpCode().getName(), 
            load, 
            conversion->getOpCode().getName(), 
            conversion);
         }

      // i.e. TR::bu2i || TR::iu2l
      result = --(*loadExtensionPreference)[load];
      }
   else
      {
      if (trace())
         {
         traceMsg(comp(), "\t\tCounting signed load %s [%p] under %s [%p]\n", 
            load->getOpCode().getName(), 
            load, 
            conversion->getOpCode().getName(), 
            conversion);
         }

      // i.e. TR::i2l || TR::b2i
      result = ++(*loadExtensionPreference)[load];
      }

   return result;
   }
void TR_RegisterAnticipatability::analyzeTreeTopsInBlockStructure(TR_BlockStructure *blockStructure)
   {
   int32_t blockNum = blockStructure->getBlock()->getNumber();
   // save the outSetInfo for later use
   //
   copyFromInto(_regularInfo, _outSetInfo[blockNum]);

   // now compose the exception info into the outSet
   // for this block
   //
   compose(_regularInfo, _exceptionInfo);
   compose(_outSetInfo[blockNum], _exceptionInfo);

   // compute the _inSet = _outSet + RUSE
   //
   *_regularInfo |= *_registerUsageInfo[blockNum];
   *_exceptionInfo |= *_registerUsageInfo[blockNum]; //FIXME: is this too conservative?

   if (comp()->getOption(TR_TraceShrinkWrapping))
      {
      traceMsg(comp(), "Normal info of block_%d : ", blockNum);
      _regularInfo->print(comp());
      traceMsg(comp(), "\n");
      }
   }
Example #9
0
void
TR::RegDepCopyRemoval::makeFreshCopy(TR_GlobalRegisterNumber reg)
   {
   RegDepInfo &dep = getRegDepInfo(reg);
   if (!performTransformation(comp(),
         "%schange %s in GlRegDeps n%un to an explicit copy of n%un\n",
         optDetailString(),
         registerName(reg),
         _regDeps->getGlobalIndex(),
         dep.value->getGlobalIndex()))
      return;

   // Split the block at fallthrough if necessary to avoid putting copies
   // between branches and BBEnd.
   TR::Node *curNode = _treetop->getNode();
   if (curNode->getOpCodeValue() == TR::BBEnd)
      {
      TR::Block *curBlock = curNode->getBlock();
      if (curBlock->getLastRealTreeTop() != curBlock->getLastNonControlFlowTreeTop())
         {
         TR::Block *fallthrough = curBlock->getNextBlock();
         fallthrough = curBlock->splitEdge(curBlock, fallthrough, comp());
         TR_ASSERT(curBlock->getNextBlock() == fallthrough, "bad block placement from splitEdge\n");
         fallthrough->setIsExtensionOfPreviousBlock();
         _treetop = fallthrough->getExit();
         TR::Node *newNode = _treetop->getNode();
         newNode->setChild(0, _regDeps);
         newNode->setNumChildren(1);
         curNode->setNumChildren(0);
         if (trace())
            traceMsg(comp(), "\tsplit fallthrough edge to insert copy, created block_%d\n", fallthrough->getNumber());
         }
      }

   // Make and insert the copy
   TR::Node *copyNode = NULL;
   if (dep.value->getOpCode().isLoadConst())
      {
      // No need to depend on the other register.
      // TODO heuristic for whether this is really better than a reg-reg move?
      generateRegcopyDebugCounter("const-remat");
      copyNode = TR::Node::create(dep.value->getOpCodeValue(), 0);
      copyNode->setConstValue(dep.value->getConstValue());
      }
   else
      {
      generateRegcopyDebugCounter("fresh-copy");
      copyNode = TR::Node::create(TR::PassThrough, 1, dep.value);
      copyNode->setCopyToNewVirtualRegister();
      }

   TR::Node *copyTreetopNode = TR::Node::create(TR::treetop, 1, copyNode);
   _treetop->insertBefore(TR::TreeTop::create(comp(), copyTreetopNode));
   if (trace())
      traceMsg(comp(), "\tcopy is n%un\n", copyNode->getGlobalIndex());

   updateSingleRegDep(reg, copyNode);
   }
Example #10
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
   }
Example #11
0
void createGuardSiteForRemovedGuard(TR::Compilation *comp, TR::Node *ifNode)
   {
#ifdef J9_PROJECT_SPECIFIC
   if (comp->cg()->needGuardSitesEvenWhenGuardRemoved() && ifNode->isTheVirtualGuardForAGuardedInlinedCall())
      {
      TR_VirtualGuard *virtualGuard = comp->findVirtualGuardInfo(ifNode);

      if (virtualGuard->getKind() == TR_HCRGuard)
         {
         if (comp->getOption(TR_TraceReloCG))
            traceMsg(comp, "createGuardSiteForRemovedGuard: removing HCRGuard, no need to add AOTNOPsite, node %p\n", ifNode);
         return;
         }

      if (virtualGuard->getKind() == TR_BreakpointGuard)
         {
         if (comp->getOption(TR_TraceReloCG))
            traceMsg(comp, "createGuardSiteForRemovedGuard: removing BreakpointGuard, no need to add AOTNOPsite, node %p\n", ifNode);
         return;
         }

      TR_VirtualGuardKind removedGuardKind;
      switch (virtualGuard->getKind())
         {
         case TR_ProfiledGuard:
            removedGuardKind = TR_RemovedProfiledGuard;
            TR_ASSERT(ifNode->isProfiledGuard(), "guard for profiled guard has unexpected kind");
            break;
         case TR_InterfaceGuard:
            removedGuardKind = TR_RemovedInterfaceGuard;
            TR_ASSERT(ifNode->isInterfaceGuard(), "guard for interface guard has unexpected kind");
            break;
         case TR_NonoverriddenGuard:
         case TR_DirectMethodGuard:
            removedGuardKind = TR_RemovedNonoverriddenGuard;
            TR_ASSERT(ifNode->isNonoverriddenGuard(), "guard for nonoverridden guard has unexpected kind");
            break;
         default:
            TR_ASSERT(false, "removed virtual guard type %d on node %p not supported yet.", virtualGuard->getKind(), ifNode);
            break;
         };

      TR_AOTGuardSite *site = comp->addAOTNOPSite();
      site->setLocation(NULL);
      site->setType(removedGuardKind);
      site->setGuard(virtualGuard);
      site->setNode(NULL);

      if (comp->getOption(TR_TraceAll))
         traceMsg(comp, "createGuardSiteForRemovedGuard: removedGuardKind %d, removedGurad %p, _callNode %p, _guardNode %p, _thisClass %p, _calleeIndex %d, _byteCodeIndex %d, addedAOTNopSite %p\n",
                     removedGuardKind, virtualGuard, virtualGuard->getCallNode(), virtualGuard->getGuardNode(), virtualGuard->getThisClass(),
                     virtualGuard->getCalleeIndex(), virtualGuard->getByteCodeIndex(), site);
      }
#endif
   }
Example #12
0
void TR_LocalLiveRangeReduction::printOnVerifyError(TR_TreeRefInfo *optRefInfo,TR_TreeRefInfo *verifier )
   {
   if (trace())
      {
      traceMsg(comp(),"from opt:");
      printRefInfo(optRefInfo);
      traceMsg(comp(),"verifyer:");
      printRefInfo(verifier);
      comp()->dumpMethodTrees("For verifying\n");
      comp()->incVisitCount();
      }
   }
Example #13
0
void
TR_ExpressionsSimplification::removeCandidate(TR::Node *node, TR::TreeTop* tt)
   {
   if (node->getVisitCount() == _visitCount)
      return;

   node->setVisitCount(_visitCount);

   if (trace())
      traceMsg(comp(), "Looking at Node [%p]\n", node);

   ListIterator<TR::TreeTop> candidateTTs(_candidateTTs);
   for (TR::TreeTop *candidateTT = candidateTTs.getFirst(); candidateTT; candidateTT = candidateTTs.getNext())
      {
      if (tt != candidateTT &&
          node->getOpCode().hasSymbolReference() &&
          candidateTT->getNode()->mayKill(true).contains(node->getSymbolReference(), comp()))
         {
         if (trace())
            traceMsg(comp(), "Removing candidate %p which has aliases in the loop\n", candidateTT->getNode());

         _candidateTTs->remove(candidateTT);
         continue;
         }
      }

   bool hasSupportedChildren = true;

   // Process the children as well
   //
   for (int32_t i = 0; i < node->getNumChildren(); i++)
      {
      removeCandidate(node->getChild(i), tt);
      // candidates child expressions must be invariant and supported. Here we determine if they are supported.
      if (!_supportedExpressions->get(node->getChild(i)->getGlobalIndex()))
         {
         hasSupportedChildren = false;
         }
      }

   if (hasSupportedChildren && isSupportedNodeForExpressionSimplification(node))
      {
       _supportedExpressions->set(node->getGlobalIndex());
      }
   else
      {
      if (trace())
         traceMsg(comp(), "  Node %p is unsupported expression because %s\n", node,
               !hasSupportedChildren ? "it has unsupported children" : "it is itself unsupported");
      }
   }
Example #14
0
void
TR::AMD64ABILinkage::mapIncomingParms(
      TR::ResolvedMethodSymbol *method,
      uint32_t &stackIndex)
   {
   ListIterator<TR::ParameterSymbol> parameterIterator(&method->getParameterList());
   TR::ParameterSymbol *parmCursor = parameterIterator.getFirst();

   if (!parmCursor) return;

   if (parmCursor->getLinkageRegisterIndex() < 0)
      {
      copyLinkageInfoToParameterSymbols();
      }

   // 1st: handle parameters which are passed through stack
   //
   TR::X86SystemLinkage::mapIncomingParms(method);

   // 2nd: handle parameters which are passed through linkage registers, but are
   // not assigned any register after RA (or say, by their first usage point,
   // a MOV is needed to load it from stack to register).
   //
   // AMD64 SysV ABI says that: a parameter is placed either in registers or
   // pushed on the stack, but can't take both.  So, for parms passed through
   // linkage registers but don't have physical registers assigned after RA,
   // we will allocate stack space in local variable region.
   //
   for (parmCursor = parameterIterator.getFirst(); parmCursor; parmCursor = parameterIterator.getNext())
      {
      if ((parmCursor->getLinkageRegisterIndex() >= 0) && (parmCursor->getAllocatedIndex() < 0 || hasToBeOnStack(parmCursor)))
         {
         uint32_t align = getAlignment(parmCursor->getDataType());
         uint32_t alignMinus1 = (align <= AMD64_STACK_SLOT_SIZE) ? (AMD64_STACK_SLOT_SIZE - 1) : (align - 1);
         uint32_t pos = -stackIndex;
         pos += parmCursor->getSize();
         pos = (pos + alignMinus1) & (~alignMinus1);
         stackIndex = -pos;
         parmCursor->setParameterOffset(stackIndex);

         if (comp()->getOption(TR_TraceCG))
            traceMsg(comp(), "mapIncomingParms setParameterOffset %d for param symbol (reg param without home location) %p, hasToBeOnStack() %d\n", parmCursor->getParameterOffset(), parmCursor, hasToBeOnStack(parmCursor));
         }
      else if (parmCursor->getLinkageRegisterIndex() >=0 && parmCursor->getAllocatedIndex() >= 0)
         {
         //parmCursor->setDontHaveStackSlot(0); // this is a hack , so as we could print stack layout table in createPrologue
         if (comp()->getOption(TR_TraceCG))
            traceMsg(comp(), "mapIncomingParms no need to set parm %p, for it has got register %d assigned\n", parmCursor, parmCursor->getAllocatedIndex());
         }
      }
   }
Example #15
0
void TR::ValidateLivenessBoundaries::updateNodeState(TR::Node *node,
                                                     TR::NodeSideTable<TR::NodeState>  &nodeStates,
                                                     TR::LiveNodeWindow &liveNodes)
   {
   TR::NodeState &state = nodeStates[node];
   if (node->getReferenceCount() == state._futureReferenceCount)
      {
      /* First occurrence -- do some bookkeeping */
      if (node->getReferenceCount() == 0)
         {
         TR::checkILCondition(node, node->getOpCode().isTreeTop(), comp(),
                              "Only nodes with isTreeTop opcodes can have refcount == 0");
         }
      else
         {
         liveNodes.add(node);
         }
      }

   if (liveNodes.contains(node))
      {
      TR::checkILCondition(node, state._futureReferenceCount >= 1, comp(),
                           "Node already has reference count 0");
      if (--state._futureReferenceCount == 0)
         {
         liveNodes.remove(node);
         }
      }
   else
      {
      TR::checkILCondition(node, node->getOpCode().isTreeTop(), comp(),
                           "Node has already gone dead");
      }

   if (TR::isILValidationLoggingEnabled(comp()))
      {
      if (!liveNodes.isEmpty())
         {
         traceMsg(comp(), "    -- Live nodes: {");
         char *separator = "";
         for (TR::LiveNodeWindow::Iterator lnwi(liveNodes); lnwi.currentNode(); ++lnwi)
            {
            traceMsg(comp(), "%sn%dn", separator,
                     lnwi.currentNode()->getGlobalIndex());
            separator = ", ";
            }
         traceMsg(comp(), "}\n");
         }
      }
   }
Example #16
0
void
TR_ExpressionsSimplification::removeUncertainBlocks(TR_RegionStructure* region, List<TR::Block> *candidateBlocksList)
   {
   // Examine the top region block first
   //
   TR::Block *entryBlock = _currentRegion->getEntryBlock();
   ListIterator<TR::Block> blocks;
   blocks.set(candidateBlocksList);

   if (trace())
      traceMsg(comp(), "Number of blocks %d, entry block number %d\n", candidateBlocksList->getSize(), entryBlock->getNumber());

   for (TR::Block *block = blocks.getFirst(); block; block = blocks.getNext())
      {
      TR::CFGNode *cfgNode = block;
      if (!(cfgNode->getExceptionSuccessors().empty()) || blockHasCalls(block, comp()))
         {
         if (trace())
            traceMsg(comp(), "An exception can be thrown from block_%d. Removing all the blocks, since we cannot know the number of iterations.\n", block->getNumber());
         candidateBlocksList->deleteAll();
         break;
         }
      }

   TR_PostDominators postDominators(comp());
   if (postDominators.isValid())
      {
	  postDominators.findControlDependents();
      for (TR::Block *block = blocks.getFirst(); block; block = blocks.getNext())
         {
         if (postDominators.dominates(block, entryBlock) == 0)
            {
            candidateBlocksList->remove(block);
            if (trace())
               traceMsg(comp(), "Block_%d is not guaranteed to be executed at least once. Removing it from the list.\n", block->getNumber());
            }
         }
      }
   else
      {
	  if (trace())
	     traceMsg(comp(), "There is no post dominators information. Removing all the blocks.\n");
	  for (TR::Block *block = blocks.getFirst(); block; block = blocks.getNext())
	     {
	     candidateBlocksList->remove(block);
	     if (trace())
	        traceMsg(comp(), "Block_%d is removed from the list\n", block->getNumber());
	     }
      }
   }
Example #17
0
void TR::ILValidator::updateNodeState(Location &newLocation)
   {
   TR::Node  *node = newLocation.currentNode();
   NodeState &state = _nodeStates[node];
   if (node->getReferenceCount() == state._futureReferenceCount)
      {
      // First occurrence -- do some bookkeeping
      //
      if (node->getReferenceCount() == 0)
         {
         validityRule(newLocation, node->getOpCode().isTreeTop(), "Only nodes with isTreeTop opcodes can have refcount == 0");
         }
      else
         {
         _liveNodes.add(node);
         }
      }

   if (_liveNodes.contains(node))
      {
      validityRule(newLocation, state._futureReferenceCount >= 1, "Node already has reference count 0");
      if (--state._futureReferenceCount == 0)
         {
         _liveNodes.remove(node);
         }
      }
   else
      {
      validityRule(newLocation, node->getOpCode().isTreeTop(), "Node has already gone dead");
      }

   if (isLoggingEnabled())
      {
      static const char *traceLiveNodesDuringValidation = feGetEnv("TR_traceLiveNodesDuringValidation");
      if (traceLiveNodesDuringValidation && !_liveNodes.isEmpty())
         {
         traceMsg(comp(), "    -- Live nodes: {");
         char *separator = "";
         for (LiveNodeWindow::Iterator lnwi(_liveNodes); lnwi.currentNode(); ++lnwi)
            {
            traceMsg(comp(), "%sn%dn", separator, lnwi.currentNode()->getGlobalIndex());
            separator = ", ";
            }
         traceMsg(comp(), "}\n");
         }
      }

   }
Example #18
0
TR::Register* OMR::X86::TreeEvaluator::SIMDloadEvaluator(TR::Node* node, TR::CodeGenerator* cg)
   {
   TR::MemoryReference* tempMR = generateX86MemoryReference(node, cg);
   tempMR = ConvertToPatchableMemoryReference(tempMR, node, cg);
   TR::Register* resultReg = cg->allocateRegister(TR_VRF);

   TR_X86OpCodes opCode = BADIA32Op;
   switch (node->getSize())
      {
      case 16:
         opCode = MOVDQURegMem;
         break;
      default:
         if (cg->comp()->getOption(TR_TraceCG))
            traceMsg(cg->comp(), "Unsupported fill size: Node = %p\n", node);
         TR_ASSERT(false, "Unsupported fill size");
         break;
      }

   TR::Instruction* instr = generateRegMemInstruction(opCode, node, resultReg, tempMR, cg);
   if (node->getOpCode().isIndirect())
      cg->setImplicitExceptionPoint(instr);
   node->setRegister(resultReg);
   tempMR->decNodeReferenceCounts(cg);
   return resultReg;
   }
Example #19
0
TR::Node *
TR_ExpressionsSimplification::ixorinegSimplifier(TR::Node *node, LoopInfo* loopInfo, bool *removeOnly)
   {
   TR::Node *newNode = 0;
   *removeOnly = false;

   if (loopInfo->getBoundaryNode())
      {
      if (trace())
         traceMsg(comp(), "Loop has a non constant boundary, but this case is not taken care of\n");
      }
   else
      {
      if (loopInfo->getNumIterations() > 0)
         {
         newNode = node;
         if (loopInfo->getNumIterations() % 2 == 0)
            {
            *removeOnly = true;
            }
         }
      }

   return newNode;
   }
Example #20
0
TR::Register* OMR::X86::TreeEvaluator::SIMDstoreEvaluator(TR::Node* node, TR::CodeGenerator* cg)
   {
   TR::Node* valueNode = node->getChild(node->getOpCode().isIndirect() ? 1 : 0);
   TR::MemoryReference* tempMR = generateX86MemoryReference(node, cg);
   tempMR = ConvertToPatchableMemoryReference(tempMR, node, cg);
   TR::Register* valueReg = cg->evaluate(valueNode);

   TR_X86OpCodes opCode = BADIA32Op;
   switch (node->getSize())
      {
      case 16:
         opCode = MOVDQUMemReg;
         break;
      default:
         if (cg->comp()->getOption(TR_TraceCG))
            traceMsg(cg->comp(), "Unsupported fill size: Node = %p\n", node);
         TR_ASSERT(false, "Unsupported fill size");
         break;
      }

   TR::Instruction* instr = generateMemRegInstruction(opCode, node, tempMR, valueReg, cg);

   cg->decReferenceCount(valueNode);
   tempMR->decNodeReferenceCounts(cg);
   if (node->getOpCode().isIndirect())
      cg->setImplicitExceptionPoint(instr);
   return NULL;
   }
Example #21
0
void
TR::RegDepCopyRemoval::selectNodesToReuse(TR::NodeChecklist &usedNodes)
   {
   for (TR_GlobalRegisterNumber reg = _regBegin; reg < _regEnd; reg++)
      {
      RegDepInfo &dep = getRegDepInfo(reg);
      if (dep.state != REGDEP_UNDECIDED)
         continue;

      NodeChoice &prevChoice = getNodeChoice(reg);
      if (dep.value != prevChoice.original)
         continue; // can't reuse

      // Reuse our previous choice!
      if (trace())
         traceMsg(comp(), "\t%s: prefer to reuse previous choice n%un\n", registerName(reg), prevChoice.selected->getGlobalIndex());

      TR_ASSERT(!usedNodes.contains(prevChoice.selected), "attempted to reuse the same node more than once\n");
      if (prevChoice.selected == dep.value)
         {
         dep.state = REGDEP_NODE_ORIGINAL;
         usedNodes.add(dep.value);
         }
      else
         {
         dep.state = REGDEP_NODE_REUSE_COPY;
         }
      }
   }
void CTraceMsgLog::TraceMessage(int level, CString str)
{
	CString traceMsg(_T(""));
	switch(level)
	{
	case MSGINFO:
		traceMsg.Append(_T("[INFO] "));
		break;

	case MSGERROR:
		traceMsg.Append(_T("[ERR] "));
		break;

	case JAVASCRIPT_ALERT:
		traceMsg.Append(_T("[JAVASCRIPT ALERT] "));
		break;

	default:
		traceMsg.Append(_T("[DEBUG] "));
		break;
	}
	//
	traceMsg.Append(str);
	//
	TraceMessage(traceMsg);
}
Example #23
0
int32_t TR_AsyncCheckInsertion::insertReturnAsyncChecks(TR::Optimization *opt, const char *counterPrefix)
   {
   TR::Compilation * const comp = opt->comp();
   if (opt->trace())
      traceMsg(comp, "Inserting return asyncchecks (%s)\n", counterPrefix);

   int numAsyncChecksInserted = 0;
   for (TR::TreeTop *treeTop = comp->getStartTree();
        treeTop;
        /* nothing */ )
      {
      TR::Block *block = treeTop->getNode()->getBlock();
      if (block->getLastRealTreeTop()->getNode()->getOpCode().isReturn()
          && performTransformation(comp,
               "%sInserting return asynccheck (%s) in block_%d\n",
               opt->optDetailString(),
               counterPrefix,
               block->getNumber()))
         {
         insertAsyncCheck(block, comp, counterPrefix);
         numAsyncChecksInserted++;
         }

      treeTop = block->getExit()->getNextRealTreeTop();
      }
   return numAsyncChecksInserted;
   }
Example #24
0
void
OMR::CodeGenPhase::performEmitSnippetsPhase(TR::CodeGenerator * cg, TR::CodeGenPhase * phase)
   {
   TR::Compilation * comp = cg->comp();
   phase->reportPhase(EmitSnippetsPhase);

   TR::LexicalMemProfiler mp("Emit Snippets", comp->phaseMemProfiler());
   LexicalTimer pt("Emit Snippets", comp->phaseTimer());

   cg->emitSnippets();

   if (comp->getOption(TR_EnableOSR))
      {
      comp->getOSRCompilationData()->checkOSRLimits();
      comp->getOSRCompilationData()->compressInstruction2SharedSlotMap();
      }

   if (comp->getOption(TR_TraceCG) || comp->getOptions()->getTraceCGOption(TR_TraceCGPostBinaryEncoding))
      {
      diagnostic("\nbuffer start = %8x, code start = %8x, buffer length = %d", cg->getBinaryBufferStart(), cg->getCodeStart(), cg->getEstimatedCodeLength());
      diagnostic("\n");
      const char * title = "Post Binary Instructions";

      comp->getDebug()->dumpMethodInstrs(comp->getOutFile(), title, false, true);

      traceMsg(comp,"<snippets>");
      comp->getDebug()->print(comp->getOutFile(), cg->getSnippetList());
      traceMsg(comp,"\n</snippets>\n");

      auto iterator = cg->getSnippetList().begin();
      int32_t estimatedSnippetStart = cg->getEstimatedSnippetStart();
      while (iterator != cg->getSnippetList().end())
         {
         estimatedSnippetStart += (*iterator)->getLength(estimatedSnippetStart);
         ++iterator;
         }
      int32_t snippetLength = estimatedSnippetStart - cg->getEstimatedSnippetStart();

      diagnostic("\nAmount of code memory allocated for this function        = %d"
                  "\nAmount of code memory consumed for this function         = %d"
                  "\nAmount of snippet code memory consumed for this function = %d\n\n",
                  cg->getEstimatedCodeLength(),
                  cg->getCodeLength(),
                  snippetLength);
      }
   }
Example #25
0
int32_t
TR::IA32SystemLinkage::layoutParm(TR::ParameterSymbol *parmSymbol, int32_t &dataCursor, uint16_t &intReg, uint16_t &floatReg, TR::parmLayoutResult &layoutResult)
   {
   layoutResult.abstract |= TR::parmLayoutResult::ON_STACK;
   int32_t align = layoutTypeOnStack(parmSymbol->getDataType(), dataCursor, layoutResult);
   if (comp()->getOption(TR_TraceCG))
      traceMsg(comp(), "layout param symbol %p on stack\n", parmSymbol);
   return align;
   }
Example #26
0
 void setMaxNestingDepth(int16_t f)
    {
    if (f > SHRT_MAX-1)
       {
       TR_ASSERT(0, "max nesting depth must be less than or equal to SHRT_MAX-1");
       traceMsg(comp(), "max nesting depth must be less than or equal to SHRT_MAX-1");
       throw TR::CompilationException();
       }
    _maxNestingDepth = f;
    }
Example #27
0
void
TR_ReachabilityAnalysis::traverse(blocknum_t blockNum, int32_t depth, blocknum_t *stack, blocknum_t *depthMap, TR_BitVector *result)
   {
   //
   // This is DeRemer and Penello's "digraph" algorithm
   //
   bool trace = comp()->getOption(TR_TraceReachability);

   // Initialize state for this block
   //
   stack[depth++] = blockNum;
   depthMap[blockNum] = depth;
   bool value = isOrigin(getBlock(blockNum));
   if (trace)
      traceMsg(comp(), "  traverse %sblock_%d depth %d\n", value? "origin ":"", blockNum, depth);
   result->setTo(blockNum, value);

   // Recursively propagate from inputs
   //
   propagateInputs(blockNum, depth, stack, depthMap, result);

   // Propagate result around the strongly connected component that includes blockNum
   //
   if (depthMap[blockNum] == depth)
      {
      while(1)
         {
         blocknum_t top = stack[--depth];
         depthMap[top] = INT_MAX;
         if (top == blockNum)
            {
            break;
            }
         else
            {
            if (trace)
               traceMsg(comp(), "    Loop: propagate block_%d to block_%d\n", blockNum, top);
            result->setTo(top, result->isSet(blockNum));
            }
         }
      }
   }
Example #28
0
void
TR_ReachabilityAnalysis::propagateOneInput(blocknum_t inputBlockNum, blocknum_t blockNum, int32_t depth, blocknum_t *stack, blocknum_t *depthMap, TR_BitVector *result)
   {
   if (inputBlockNum == blockNum)
      return;
   if (depthMap[inputBlockNum] == 0)
      traverse(inputBlockNum, depth, stack, depthMap, result);
   depthMap[blockNum] = std::min(depthMap[blockNum], depthMap[inputBlockNum]);
   if (result->isSet(inputBlockNum))
      {
      if (comp()->getOption(TR_TraceReachability))
         traceMsg(comp(), "    Propagate block_%d to block_%d\n", blockNum, inputBlockNum);
      result->set(blockNum);
      }
   else
      {
      if (comp()->getOption(TR_TraceReachability))
         traceMsg(comp(), "    No change to block_%d from block_%d\n", blockNum, inputBlockNum);
      }
   }
Example #29
0
LexicalXmlTag::LexicalXmlTag(TR::CodeGenerator * cg): cg(cg)
   {
   TR::Compilation *comp = cg->comp();
   if (comp->getOption(TR_TraceOptDetails) || comp->getOption(TR_TraceCG))
      {
      const char *hotnessString = comp->getHotnessName(comp->getMethodHotness());
      traceMsg(comp, "<codegen\n"
              "\tmethod=\"%s\"\n"
               "\thotness=\"%s\">\n",
               comp->signature(), hotnessString);
      }
   }
void CTraceMsgLog::TraceWithMemory(CString str)
{
	CString traceMsg(L"[IN3_TRACE]");
	//
	// @ note
	// memory °ü·Ã string ¸¸µéÀð.
	//
	traceMsg.Append(str);
	traceMsg.Append(str);
	traceMsg.Append(L"\r\n");
	TRACE(traceMsg);
}