// Process an edge in the CFG for DAG building. void BallLarusDag::buildEdge(BLBlockNodeMap& inDag, std::stack<BallLarusNode*>& dfsStack, BallLarusNode* currentNode, BasicBlock* succBB, unsigned duplicateCount) { BallLarusNode* succNode = inDag[succBB]; if(succNode && succNode->getColor() == BallLarusNode::BLACK) { // visited node and forward edge addEdge(currentNode, succNode, duplicateCount); } else if(succNode && succNode->getColor() == BallLarusNode::GRAY) { // visited node and back edge DEBUG(dbgs() << "Backedge detected.\n"); addBackedge(currentNode, succNode, duplicateCount); } else { BallLarusNode* childNode; // not visited node and forward edge if(succNode) // an unvisited node that is child of a gray node childNode = succNode; else { // an unvisited node that is a child of a an unvisted node childNode = addNode(succBB); inDag[succBB] = childNode; } addEdge(currentNode, childNode, duplicateCount); dfsStack.push(childNode); } }
// Processes one node and its imediate edges for building the DAG. void BallLarusDag::buildNode(BLBlockNodeMap& inDag, BLNodeStack& dfsStack) { BallLarusNode* currentNode = dfsStack.top(); BasicBlock* currentBlock = currentNode->getBlock(); if(currentNode->getColor() != BallLarusNode::WHITE) { // we have already visited this node dfsStack.pop(); currentNode->setColor(BallLarusNode::BLACK); } else { // are there any external procedure calls? if( ProcessEarlyTermination ) { for( BasicBlock::iterator bbCurrent = currentNode->getBlock()->begin(), bbEnd = currentNode->getBlock()->end(); bbCurrent != bbEnd; bbCurrent++ ) { Instruction& instr = *bbCurrent; if( instr.getOpcode() == Instruction::Call ) { BallLarusEdge* callEdge = addEdge(currentNode, getExit(), 0); callEdge->setType(BallLarusEdge::CALLEDGE_PHONY); break; } } } TerminatorInst* terminator = currentNode->getBlock()->getTerminator(); if(isa<ReturnInst>(terminator) || isa<UnreachableInst>(terminator) || isa<UnwindInst>(terminator)) addEdge(currentNode, getExit(),0); currentNode->setColor(BallLarusNode::GRAY); inDag[currentBlock] = currentNode; BasicBlock* oldSuccessor = 0; unsigned duplicateNumber = 0; // iterate through this node's successors for(succ_iterator successor = succ_begin(currentBlock), succEnd = succ_end(currentBlock); successor != succEnd; oldSuccessor = *successor, ++successor ) { BasicBlock* succBB = *successor; // is this edge a duplicate? if (oldSuccessor == succBB) duplicateNumber++; else duplicateNumber = 0; buildEdge(inDag, dfsStack, currentNode, succBB, duplicateNumber); } } }