void CfgCodeSelector::genTrueEdge(Node* tailNode, Node* headNode, double prob) { assert(tailNode->isBlockNode() && headNode->isBlockNode()); Inst* inst = (Inst*)tailNode->getLastInst(); assert(inst!=NULL && inst->hasKind(Inst::Kind_BranchInst)); BranchInst* br = (BranchInst*)inst; br->setTrueTarget(headNode); irManager.getFlowGraph()->addEdge(tailNode, headNode, prob); }
void CfgCodeSelector::fixNodeInfo() { MemoryManager tmpMM("Ia32CS:fixNodeInfoMM"); ControlFlowGraph* fg = irManager.getFlowGraph(); Nodes nodes(tmpMM); fg->getNodes(nodes); //copy nodes -> loop creates new ones, so we can't use reference to cfg->getNodes() for (Nodes::const_iterator it = nodes.begin(), end = nodes.end(); it!=end; ++it) { Node* node = *it; // connect throw nodes added during inst code selection to corresponding dispatch or unwind nodes if (node->isBlockNode()){ Inst * lastInst = (Inst*)node->getLastInst(); if (lastInst) { Inst * prevInst = lastInst->getPrevInst(); if(prevInst && prevInst->getKind() == Inst::Kind_BranchInst) { Edge * ftEdge = node->getFalseEdge(); Edge * dbEdge = node->getTrueEdge(); assert(ftEdge && dbEdge); Node* newBB = fg->createBlockNode(); Node* nextFT = ftEdge->getTargetNode(); Node* nextDB = dbEdge->getTargetNode(); fg->removeEdge(ftEdge); fg->removeEdge(dbEdge); newBB->appendInst(irManager.newBranchInst(lastInst->getMnemonic(), nextDB, nextFT)); lastInst->unlink(); //now fix prev branch successors BranchInst* prevBranch = (BranchInst*)prevInst; assert(prevBranch->getTrueTarget() == NULL && prevBranch->getFalseTarget() == NULL); prevBranch->setTrueTarget(lastInst->getMnemonic() == Mnemonic_JZ? nextFT : nextDB); prevBranch->setFalseTarget(newBB); fg->addEdge(node, lastInst->getMnemonic() == Mnemonic_JZ? nextFT : nextDB, 0); fg->addEdge(node, newBB, 0); fg->addEdge(newBB, nextDB, 0); fg->addEdge(newBB, nextFT, 0); } } if (node->getOutDegree() == 0){ // throw node assert(node->getInDegree()==1); Node* bbIn = node->getInEdges().front()->getSourceNode(); assert(bbIn!=NULL); Node * target=bbIn->getExceptionEdgeTarget(); assert(target!=NULL); fg->addEdge(node, target, 1.0); } // fixup empty catch blocks otherwise respective catchEdges will be lost // There is no [catchBlock]-->[catchHandler] edge. Catch block will be removed // as an empty one and exception handling will be incorrect if (node->isCatchBlock() && node->isEmpty()) { assert(node->getInDegree()==1); Edge* catchEdge = node->getInEdges().front(); assert(catchEdge->getSourceNode()->isDispatchNode()); assert(node->getOutDegree()==1); Node* succ = node->getUnconditionalEdgeTarget(); while( succ->isEmpty() && (succ->getOutDegree() == 1) ) { succ = succ->getUnconditionalEdgeTarget(); } assert(succ && ((Inst*)succ->getFirstInst())->hasKind(Inst::Kind_CatchPseudoInst)); fg->replaceEdgeTarget(catchEdge,succ,true/*keepOldBody*/); } } } }