void SSABuilder::clearPhiSrcs(Node *node, const StlVectorSet<VarOpnd *> *whatVars) { Inst* phi = (Inst*)node->getSecondInst(); if (whatVars) { for (;phi!=NULL && phi->isPhi(); phi = phi->getNextInst()) { Opnd *dstOp = phi->getDst(); VarOpnd *varOpnd = dstOp->asVarOpnd(); if (!varOpnd) { SsaVarOpnd *ssaOpnd = dstOp->asSsaVarOpnd(); assert(ssaOpnd); varOpnd = ssaOpnd->getVar(); } if (whatVars->has(varOpnd)) { PhiInst *phiInst = phi->asPhiInst(); assert(phiInst); phiInst->setNumSrcs(0); } } } else { for (;phi!=NULL && phi->isPhi(); phi = phi->getNextInst()) { PhiInst *phiInst = phi->asPhiInst(); assert(phiInst); phiInst->setNumSrcs(0); } } }
void SSABuilder::checkForTrivialPhis2(Node *node, const StlVectorSet<VarOpnd *> *lookatVars, StlVector<VarOpnd *> *changedVars, StlVector<Opnd *> *removedVars) { // Check that phi insts can start from the second or third position only // and goes in a row assert(phiInstsOnRightPositionsInBB(node)); Inst* phi = (Inst*)node->getSecondInst(); if(phi && !phi->isPhi()) { // try the next one (third) phi = phi->getNextInst(); } Inst *nextphi = NULL; #ifdef DEBUG_SSA if (Log::isEnabled()) { Log::out() << "Checking node " << (int)node->getId() << " for trivial phis2" << ::std::endl; } #endif for (;phi->isPhi(); phi = nextphi) { nextphi = phi->getNextInst(); #ifdef _DEBUG PhiInst *phiInst = phi->asPhiInst(); assert(phiInst); #endif U_32 nSrcs = phi->getNumSrcOperands(); if (nSrcs <= 1) { // phi must be trivial #ifdef DEBUG_SSA ::std::ostream &cout = Log::out(); if (Log::isEnabled()) { cout << "removing trivial2 instruction "; phi->print(cout); cout << ::std::endl; } #endif Opnd *dstOp = phi->getDst(); VarOpnd *varOp = dstOp->asVarOpnd(); if (!varOp) { SsaVarOpnd *ssaOp = dstOp->asSsaVarOpnd(); assert(ssaOp); varOp = ssaOp->getVar(); } assert(!lookatVars || (lookatVars->has(varOp))); changedVars->push_back(varOp); removedVars->push_back(dstOp); phi->unlink(); } } }
void SSABuilder::clearPhiSrcs2(Node *node, const StlVectorSet<VarOpnd *> *whatVars, StlVector<VarOpnd *> *changedVars, const StlVectorSet<Opnd *> *removedVars, StlVector<Node *> &scratchNodeList) { bool needPreds = true; StlVector<Node *> &preds = scratchNodeList; Inst* inst = (Inst*)node->getSecondInst(); for (;inst!=NULL && inst->isPhi(); inst = inst->getNextInst()) { Opnd *dstOp =inst->getDst(); VarOpnd *varOpnd = 0; if (whatVars) { varOpnd = dstOp->asVarOpnd(); if (!varOpnd) { SsaVarOpnd *ssaOpnd = dstOp->asSsaVarOpnd(); assert(ssaOpnd); varOpnd = ssaOpnd->getVar(); } if (!whatVars->has(varOpnd)) continue; } bool changed=false; U_32 numSrcs = inst->getNumSrcOperands(); for (U_32 i=0; i<numSrcs; ++i) { Opnd *thisOpnd = inst->getSrc(i); if (!(removedVars && removedVars->has(thisOpnd))) { // need to test whether need to remove if (needPreds) { needPreds = false; const Edges& edges2 = node->getInEdges(); preds.clear(); preds.reserve(edges2.size()); Edges::const_iterator eiter2; for(eiter2 = edges2.begin(); eiter2 != edges2.end(); ++eiter2){ preds.push_back((*eiter2)->getSourceNode()); } } DominatorTree &domTree = frontier.getDominator(); Inst *thisOpndInst = thisOpnd->getInst(); Node *thisOpndInstNode = thisOpndInst->getNode(); if (thisOpndInstNode) { // the operand's source instruction was not already dead. StlVector<Node *>::const_iterator predIter = preds.begin(), predEnd = preds.end(); bool foundDom = false; for ( ; predIter != predEnd; ++predIter) { Node *predNode = *predIter; if (domTree.dominates(thisOpndInstNode, predNode)) { // we found it, leave this operand alone. foundDom = true; break; } } if (foundDom) continue; // leave operand alone. } } // remove this operand; if (i < numSrcs-1) { inst->setSrc(i, inst->getSrc(numSrcs-1)); --i; // re-examine this operand, which is now the last } --numSrcs; // we deleted one operand PhiInst *phiInst = inst->asPhiInst(); assert(phiInst); phiInst->setNumSrcs(numSrcs); changed = true; } if (changed) { // note the changed var; if (!varOpnd) { varOpnd = dstOp->asVarOpnd(); if (!varOpnd) { SsaVarOpnd *ssaOpnd = dstOp->asSsaVarOpnd(); assert(ssaOpnd); varOpnd = ssaOpnd->getVar(); } } changedVars->push_back(varOpnd); } } }