Example #1
0
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);
        }
    }
}
Example #2
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();
        }
    }
}
Example #3
0
void SSABuilder::deconvertSSA(ControlFlowGraph* fg,OpndManager& opndManager) {
    const Nodes& nodes = fg->getNodes();
    Nodes::const_iterator niter;
    for(niter = nodes.begin(); niter != nodes.end(); ++niter) {
        Node* node = *niter;
        Inst *headInst = (Inst*)node->getFirstInst();
        for (Inst *inst = headInst->getNextInst(); inst != NULL; ) {
            Inst *nextInst = inst->getNextInst();
            if (inst->isPhi()) {
                inst->unlink();
            } else {
                for (U_32 i = 0; i < inst->getNumSrcOperands(); i++) {
                    Opnd *opnd = inst->getSrc(i);
                    if (opnd->isSsaVarOpnd()) {
                        SsaVarOpnd *ssa = (SsaVarOpnd *)opnd;
                        VarOpnd *var = ssa->getVar();
                        inst->setSrc(i,var);
                    } else if (opnd->isVarOpnd()) {
                    }
                }
                Opnd *dst = inst->getDst();
                if (dst->isSsaVarOpnd()) {
                    SsaVarOpnd *ssa = (SsaVarOpnd *)dst;
                    inst->setDst(ssa->getVar()); 
                } 
            }
            inst = nextInst;
        }
    }
}
Example #4
0
bool SSABuilder::phiInstsOnRightPositionsInBB(Node* node) {
    Inst* inst = (Inst*)node->getSecondInst();
    if(inst && !inst->isPhi()) {
        // try the next one (third)
        inst = inst->getNextInst();
    }
    // skip all phis
    while ( inst!=NULL && inst->isPhi() ) {
        inst = inst->getNextInst();
    }
    // 'true' only if there is no any other phis in the node
    while ( inst!=NULL ) {
        if(inst->isPhi()) {
            return false;
        }
        inst = inst->getNextInst();
    }
    return true;
} 
Example #5
0
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);
        }
    }
}
Example #6
0
//
// traverse dominator tree and rename variables
//
void SSABuilder::renameNode(RenameStack *renameStack, DominatorNode* dt,
                            const StlVectorSet<VarOpnd *> *whatVars)
{
    if (dt == NULL) return;
    Node* node = dt->getNode();

    Inst* head = (Inst*)node->getFirstInst();
#ifdef DEBUG_SSA
    std::ostream &cout = Log::out();
    if (Log::isEnabled()) {
        cout << "renameNode "; FlowGraph::printLabel(cout, node); cout << std::endl;
    }
#endif
    for (Inst* i = head->getNextInst(); i != NULL; i = i->getNextInst()) {
        if (!i->isPhi()) {
            // replace src with ssa opnd
            U_32 nSrcs = i->getNumSrcOperands();
            for (U_32 j = 0; j < nSrcs; j++) {
                Opnd *srcj = i->getSrc(j);
                VarOpnd *srcjVar = (srcj->isSsaVarOpnd()
                                    ? srcj->asSsaVarOpnd()->getVar()
                                    : srcj->asVarOpnd());
                if (!(srcjVar && !srcjVar->isAddrTaken()))
                    continue;
                if (whatVars && !whatVars->has(srcjVar)) continue;
                SsaVarOpnd* ssa = renameStack->lookup(srcjVar);
                assert(ssa);
                i->setSrc(j,ssa);
            }
        }

        // for both Phi and non-Phi
        // we replace any non-ssa dst with a new ssa opnd
        // and record it in the RenameStack map
        Opnd* dst = i->getDst();
        VarOpnd *theVar = dst->asVarOpnd();

        if (theVar && (!theVar->isAddrTaken())
            && !(whatVars && !whatVars->has(theVar))) {

            SsaVarOpnd* ssaDst = opndManager.createSsaVarOpnd((VarOpnd*)dst);
#ifdef DEBUG_SSA
            if (Log::isEnabled()) {
                cout << "SSA "; ssaDst->print(cout); cout << ::std::endl;
            }
#endif
            renameStack->insert((VarOpnd*)dst, ssaDst);
            i->setDst(ssaDst);
#ifdef DEBUG_SSA
            if (Log::isEnabled()) {
                i->print(cout); cout << ::std::endl;
            }
#endif
            // record stVar inst
        } else if (dst->isSsaVarOpnd()) {
            SsaVarOpnd* ssaDst = dst->asSsaVarOpnd();
            theVar = ssaDst->getVar();
            if (whatVars && !whatVars->has(theVar))
                continue;
#ifdef DEBUG_SSA
            if (Log::isEnabled()) {
                cout << "SSA "; ssaDst->print(cout); cout << ::std::endl;
            }
#endif
            renameStack->insert(ssaDst->getVar(), ssaDst);
#ifdef DEBUG_SSA
            if (Log::isEnabled()) {
                i->print(cout); cout << ::std::endl;
            }
#endif
        }
    }

    // add var sources to following phi instructions
    const Edges& edges = node->getOutEdges();
    Edges::const_iterator 
        eiter = edges.begin(),
        eend = edges.end();
    for(eiter = edges.begin(); eiter != eend; ++eiter) {
        Edge* e = *eiter;
        Node* succ = e->getTargetNode();
        // Phi insts are inserted to the beginning of the block
        // if succ does not have phi insts, then we can skip  it
        Inst *phi = (Inst*)succ->getSecondInst();
        if (phi==NULL || !phi->isPhi()) continue;

        // node is jth predecessor for succ
        
        
        // replace jth var of phi insts
        Inst* nextphi = phi->getNextInst();
        for (;phi!=NULL && phi->isPhi(); phi = nextphi) {
            nextphi = phi->getNextInst();
            // get var 
            Opnd *theopnd = phi->getDst();
            VarOpnd *thevar = theopnd->asVarOpnd();

            if (!thevar) {
                SsaVarOpnd *theSsaVar = theopnd->asSsaVarOpnd();
                assert(theSsaVar);

#ifdef DEBUG_SSA
                if (Log::isEnabled()) {
                    Log::out() << "case 2" << ::std::endl;
                }
#endif
                thevar = theSsaVar->getVar();
            }

            if (whatVars && !whatVars->has(thevar)) continue;

            SsaVarOpnd* ssa = renameStack->lookup((VarOpnd*)thevar);

            if (ssa != NULL) {
#ifdef DEBUG_SSA
                if (Log::isEnabled()) {
                    cout << "redge";
//                    cout << (I_32)j;
                    cout << " with ssa "; ssa->print(cout); cout << ::std::endl;
                }
#endif
                addPhiSrc((PhiInst*)phi,ssa);
            } else {
#ifdef DEBUG_SSA
                if (Log::isEnabled()) {
                    cout << "no source for phi of var ";
                    thevar->print(cout);
                    cout << ::std::endl;
                }
#endif
                // if ssa is NULL, then the phi must be a dead phi inst
                // (no more use of var afterwards). it will be removed.
            }
        }
    }
}
Example #7
0
// rename vars to make un-overlapping live ranges of a variable into
// different variables.
void SSABuilder::splitSsaWebs(ControlFlowGraph* fg,OpndManager& opndManager) {
    U_32 numSsaOpnds = opndManager.getNumSsaOpnds();
    MemoryManager localMM("SSABuilder::splitSsaWebs::memManager");
    SsaVarClique *cliques = new (localMM) SsaVarClique[numSsaOpnds];
    
    const Nodes& nodes = fg->getNodes();
    Nodes::const_iterator niter;
    for(niter = nodes.begin(); niter != nodes.end(); ++niter) {
        Node* node = *niter;
        Inst *headInst = (Inst*)node->getFirstInst();
        for (Inst *inst = headInst->getNextInst(); inst != NULL; ) {
            Inst *nextInst = inst->getNextInst();
            if (inst->isPhi()) {
                // do something
                VarOpnd *var0 = 0;
                SsaVarClique *clique = 0;
                for (U_32 i = 0; i < inst->getNumSrcOperands(); i++) {
                    Opnd *opnd = inst->getSrc(i);
                    if (opnd->isSsaVarOpnd()) {
                        SsaVarOpnd *ssa = (SsaVarOpnd *)opnd;
                        U_32 id = ssa->getId();
                        if (var0) {
                            assert(ssa->getVar()==var0);
                            cliques[id].link(clique);
                        } else {
                            var0 = ssa->getVar();
                            clique = &cliques[id];
                        }
                    }
                }
                Opnd *dst = inst->getDst();
                if (dst->isSsaVarOpnd()) {
                    SsaVarOpnd *ssa = (SsaVarOpnd *)dst;
                    ssa->getVar();
                    U_32 id = ssa->getId();
                    if (var0) {
                        assert(ssa->getVar()==var0);
                        cliques[id].link(clique);
                    } else {
                        var0 = ssa->getVar();
                        clique = &cliques[id];
                    }
                }
            }
            inst = nextInst;
        }
    }
    U_32 numvars = opndManager.getNumVarOpnds();
    bool *used = new (localMM) bool[numvars];
    for (U_32 i=0; i<numvars; i++) {
        used[i] = false;
    }

    for(niter = nodes.begin(); niter != nodes.end(); ++niter) {
        Node* node = *niter;
        Inst *headInst = (Inst*)node->getFirstInst();
        for (Inst *inst = headInst->getNextInst(); inst != NULL; ) {
            Inst *nextInst = inst->getNextInst();

            for (U_32 i = 0; i < inst->getNumSrcOperands(); i++) {
                Opnd *opnd = inst->getSrc(i);
                if (opnd->isSsaVarOpnd()) {
                    SsaVarOpnd *ssa = (SsaVarOpnd *)opnd;
                    VarOpnd *var = ssa->getVar();
                    U_32 id=ssa->getId();
                    SsaVarClique *clique = &cliques[id];
                    clique = clique->getRoot();
                    VarOpnd *cvar = clique->var;
                    if (cvar == 0) {
                        U_32 varId = var->getId();
                        if (used[varId]) {
                            cvar = opndManager.createVarOpnd(var->getType(),
                                                             var->isPinned());
                        } else {
                            cvar = var;
                            used[varId] = true;
                        }
                        clique->var = cvar;
                    }
                    if (cvar != var) {
                        ssa->setVar(cvar);
                    }
                }
            }
            Opnd *dst = inst->getDst();
            if (dst->isSsaVarOpnd()) {
                SsaVarOpnd *ssa = (SsaVarOpnd *)dst;
                VarOpnd *var = ssa->getVar();
                U_32 id=ssa->getId();

                SsaVarClique *clique = &cliques[id];
                clique = clique->getRoot();
                VarOpnd *cvar = clique->var;
                if (cvar == 0) {
                    U_32 varId = var->getId();
                    if (used[varId]) {
                        cvar = opndManager.createVarOpnd(var->getType(),
                                                         var->isPinned());
                    } else {
                        cvar = var;
                        used[varId] = true;
                    }
                    clique->var = cvar;
                }
                if (cvar != var) {
                    ssa->setVar(cvar);
                }
            } 
            
            inst = nextInst;
        }
    }
}