void BottomUpLayout::linearizeCfgImpl() { assert(irManager->getFlowGraph()->isEdgeProfileConsistent()); StlVector<Edge*> sortedEdges(mm); const Nodes& nodes = irManager->getFlowGraph()->getNodes(); sortedEdges.reserve(nodes.size() * 3); for (Nodes::const_iterator it = nodes.begin(), end = nodes.end(); it!=end; ++it) { Node* node = *it; const Edges& edges = node->getOutEdges(); sortedEdges.insert(sortedEdges.end(), edges.begin(), edges.end()); } //GCC 3.4 passes NULLs to comparator if usual std::sort is used here.. std::stable_sort(sortedEdges.begin(), sortedEdges.end(), edge_comparator()); for(StlVector<Edge*>::const_iterator it = sortedEdges.begin(), itEnd = sortedEdges.end(); it!=itEnd; it++) { Edge* edge = *it; layoutEdge(edge); } //create one-block-chains from blocks that was not laid out //these blocks are dispatch successors or are blocks connected by in/out edges to already laid out chains for (Nodes::const_iterator it = nodes.begin(), end = nodes.end(); it!=end; ++it) { Node* node = *it; if (node->isBlockNode()) { BasicBlock* block = (BasicBlock*)node; if (block->getLayoutSucc() == NULL && !lastInChain[block->getDfNum()]) { firstInChain[block->getDfNum()] = true; lastInChain[block->getDfNum()] = true; } } } combineChains(); }
void BottomUpLayout::layoutEdge(Edge *edge) { Node* tailNode = edge->getSourceNode(); Node* headNode = edge->getTargetNode(); if (!headNode->isBlockNode() || !tailNode->isBlockNode()) { return; } if (headNode == irManager->getFlowGraph()->getEntryNode()) { //prolog node should be first in layout return; } if (tailNode == headNode) { return; //backedge to self } BasicBlock* tailBlock = (BasicBlock*)tailNode; if (tailBlock->getLayoutSucc()!=NULL) { return; //tailBlock is layout predecessor for another successor } BasicBlock* headBlock = (BasicBlock*)headNode; if (prevInLayoutBySuccessorId[headBlock->getDfNum()]!=NULL) { return; // head was already laid out (in other chain) } if (lastInChain[tailBlock->getDfNum()] && firstInChain[headBlock->getDfNum()]) { BasicBlock* tailOfHeadChain = headBlock; while (tailOfHeadChain->getLayoutSucc()!=NULL) { tailOfHeadChain = tailOfHeadChain->getLayoutSucc(); } if (tailOfHeadChain == tailBlock) { return; // layout must be acyclic } } tailBlock->setLayoutSucc(headBlock); prevInLayoutBySuccessorId[headBlock->getDfNum()] = tailBlock; BasicBlock* tailPred = prevInLayoutBySuccessorId[tailBlock->getDfNum()]; if (tailPred) { assert(lastInChain[tailBlock->getDfNum()]); lastInChain[tailBlock->getDfNum()] = false; } else { firstInChain[tailBlock->getDfNum()] = true; }// here we have valid first firstInChain[headBlock->getDfNum()] = false; BasicBlock* newLast = headBlock; while (newLast->getLayoutSucc()!=NULL) { newLast = newLast->getLayoutSucc(); } lastInChain[newLast->getDfNum()] = true; }