void TR_ExpressionsSimplification::tranformStoreMotionCandidate(TR::TreeTop *treeTop, bool *isPreheaderBlockInvalid) { TR::Node *node = treeTop->getNode(); TR_ASSERT(node->getOpCode().isStore() && !node->getSymbol()->isStatic() && !node->getSymbol()->holdsMonitoredObject(), "node %p was expected to be a non-static non-monitored object store and was not.", node); // this candidate should be valid, either direct or indirect if (trace()) comp()->getDebug()->print(comp()->getOutFile(), node, 0, true); TR::Block *entryBlock = _currentRegion->getEntryBlock(); TR::Block *preheaderBlock = findPredecessorBlock(entryBlock); if (!preheaderBlock) { if (trace()) traceMsg(comp(), "Fail to find a place to put the hoist code in\n"); *isPreheaderBlockInvalid = true; return; } // Earlier post-dominance test ensures that the loop is executed as least once, or is canonicalized. // but to be safe we still perform on canonicalized loops only. if (_currentRegion->isCanonicalizedLoop()) // make sure that the loop is canonicalized, in which case the preheader is { // executed in its first iteration and is protected. if (performTransformation(comp(), "%sMove out loop-invariant store [%p] to block_%d\n", OPT_DETAILS, node, preheaderBlock->getNumber())) { TR::Node *newNode = node->duplicateTree(); transformNode(newNode, preheaderBlock); TR::TransformUtil::removeTree(comp(), treeTop); } } else { if (trace()) traceMsg(comp(), "No canonicalized loop for this candidate\n"); } }
bool TR_ExpressionsSimplification::tranformSummationReductionCandidate(TR::TreeTop *treeTop, LoopInfo *loopInfo, bool *isPreheaderBlockInvalid) { TR::Node *node = treeTop->getNode(); TR::Node *opNode = node->getFirstChild(); TR::Node *expNode = NULL; int32_t expChildNumber = 0; bool removeOnly = false; bool replaceWithNewNode = false; if (opNode->getOpCodeValue() == TR::iadd || opNode->getOpCodeValue() == TR::isub) { if (opNode->getSecondChild()->getOpCode().hasSymbolReference() && node->getSymbolReference() == opNode->getSecondChild()->getSymbolReference()) { expChildNumber = 0; expNode = opNode->getFirstChild(); } else { expChildNumber = 1; expNode = opNode->getSecondChild(); } expNode = iaddisubSimplifier(expNode, loopInfo); replaceWithNewNode = true; } else if (opNode->getOpCodeValue() == TR::ixor || opNode->getOpCodeValue() == TR::ineg) { expNode = ixorinegSimplifier(opNode, loopInfo, &removeOnly); } if (expNode) { if (trace()) comp()->getDebug()->print(comp()->getOutFile(), expNode, 0, true); TR::Block *entryBlock = _currentRegion->getEntryBlock(); TR::Block *preheaderBlock = findPredecessorBlock(entryBlock); if (!preheaderBlock) { if (trace()) traceMsg(comp(), "Fail to find a place to put the hoist code in\n"); *isPreheaderBlockInvalid = true; return true; } if (loopInfo->getNumIterations() > 0 || // make sure that the loop is going to be executed at least once _currentRegion->isCanonicalizedLoop()) // or that the loop is canonicalized, in which case the preheader is { // executed in its first iteration and is protected. if (performTransformation(comp(), "%sMove out loop-invariant node [%p] to block_%d\n", OPT_DETAILS, node, preheaderBlock->getNumber())) { if (!(removeOnly)) { TR::Node *newNode = node->duplicateTree(); if (replaceWithNewNode) newNode->getFirstChild()->setAndIncChild(expChildNumber, expNode); transformNode(newNode, preheaderBlock); } TR::TransformUtil::removeTree(comp(), treeTop); } } } return (expNode != NULL); }