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); } }
static void callbackAfter(CONTEXT *ctx, THREADID threadId) { Inst *inst; if (!analysisTrigger.getState()) /* Analysis locked */ return; /* Update the current context handler */ ap.updateCurrentCtxH(new PINContextHandler(ctx, threadId)); /* Get the last instruction */ inst = ap.getLastInstruction(); /* Update statistics */ ap.incNumberOfBranchesTaken(inst->isBranch()); /* Python callback after instruction processing */ processingPyConf.callbackAfter(inst, &ap); }