コード例 #1
0
void findLoopsToUnroll(MemoryManager& tmpMM, IRManager& irm, UnrollInfos& result, const UnrollFlags& flags) {

    ControlFlowGraph& fg = irm.getFlowGraph();
    LoopTree* lt = fg.getLoopTree();

    //find all loop exits
    Edges loopExits(tmpMM);
    const Nodes& nodes = fg.getNodes();
    for (Nodes::const_iterator it = nodes.begin(), end = nodes.end(); it!=end; ++it) {
       Node* node = *it;
        LoopNode* loopNode = lt->getLoopNode(node, false);
        if (loopNode == NULL) {
            continue; //node not in a loop
        }
        if (!flags.unrollParentLoops && loopNode->getChild()!=NULL) {
            continue; //skip parent loops
        }
        const Edges& edges = node->getOutEdges();
        for (Edges::const_iterator ite = edges.begin(), ende = edges.end(); ite!=ende; ++ite) {
           Edge* edge = *ite;
            if (lt->isLoopExit(edge)) {
                loopExits.push_back(edge);
            }
        }
    }
   
    //filter out all edges except branches
    for (Edges::iterator ite = loopExits.begin(), ende = loopExits.end(); ite!=ende; ++ite) {
       Edge* edge = *ite;
        if (edge->isDispatchEdge() || edge->isUnconditionalEdge() || edge->isCatchEdge()) {
            *ite = NULL;
            continue;
        }
        Inst* lastInst = (Inst*)edge->getSourceNode()->getLastInst();
        if (lastInst->isSwitch()) {
            *ite = NULL;
            continue;
        }
        assert(lastInst->isBranch());
        assert(edge->isFalseEdge() || edge->isTrueEdge());
    }
    loopExits.erase(std::remove(loopExits.begin(), loopExits.end(), (Edge*)NULL), loopExits.end());

    // analyze every loop exit and prepare unroll info
    for (Edges::const_iterator ite = loopExits.begin(), ende = loopExits.end(); ite!=ende; ++ite) {
        Edge* edge = *ite;
        Node* sourceNode = edge->getSourceNode();
        Inst* lastInst = (Inst*)sourceNode->getLastInst();
        assert(lastInst->isBranch());
        LoopUnrollInfo* info = prepareUnrollInfo(tmpMM, lt, lastInst->asBranchInst());
        if (info == NULL) {
            continue;
        }
        if (Log::isEnabled()) {
            info->print(Log::out());
            Log::out()<<std::endl;
        }
        result.push_back(info);
    }
}