void ReversePostOrderTraversal::analyze(Function& function) { typedef util::LargeSet<BasicBlock*> BlockSet; typedef std::stack<BasicBlock*> BlockStack; order.clear(); BlockSet visited; BlockStack stack; auto cfgAnalysis = getAnalysis("ControlFlowGraph"); auto cfg = static_cast<ControlFlowGraph*>(cfgAnalysis); report("Creating reverse post order traversal over function '" + function.name() + "'"); // reverse post order is reversed topological order stack.push(&*function.entry_block()); while(order.size() != function.size()) { if(stack.empty()) { for(auto block : order) { auto successors = cfg->getSuccessors(*block); for(auto successor : successors) { if(visited.insert(successor).second) { stack.push(successor); break; } } if(!stack.empty()) break; } } assertM(!stack.empty(), (function.size() - order.size()) << " blocks are not connected."); while(!stack.empty()) { BasicBlock* top = stack.top(); stack.pop(); auto successors = cfg->getSuccessors(*top); for(auto successor : successors) { assert(successor != nullptr); auto predecessors = cfg->getPredecessors(*successor); bool allPredecessorsVisited = true; for(auto predecessor : predecessors) { if(visited.count(predecessor) == 0) { allPredecessorsVisited = false; break; } } if(!allPredecessorsVisited) continue; if(visited.insert(successor).second) { stack.push(successor); } } order.push_back(top); report(" " << top->name()); } } // reverse the order std::reverse(order.begin(), order.end()); }
BTree::Iterator BTree::insert(Key key) { BlockStack path; keepTracingToLeaf(key, path); if (getHeaderFromNode(path.top())->entry_count >= maximumEntryPerLeaf()) { Iterator ret = end(); Length split_offset = getHeaderFromNode(path.top())->entry_count / 2; Block new_node = splitLeaf(path.top(), split_offset); Key split_key = makeKey( getKeyFromLeafEntry(getFirstEntryInLeaf(new_node)).start(), _key_size ); if (maximumEntryPerLeaf() > 1 && _less(getPointerOfKey(key), getPointerOfKey(split_key)) ) { ret = insertInLeaf(path.top(), key); } else { ret = insertInLeaf(new_node, key); } path.pop(); while (!path.empty() && getHeaderFromNode(path.top())->entry_count >= maximumEntryPerNode()) { Block node_to_insert = std::move(new_node); auto index_to_insert = node_to_insert.index(); auto split_offset = getHeaderFromNode(path.top())->entry_count / 2; new_node = splitNode(path.top(), split_offset); if (_less(getPointerOfKey(split_key), getKeyFromNodeEntry(getFirstEntryInNode(new_node)).start())) { insertInNode(path.top(), split_key, index_to_insert); } else { insertInNode(new_node, split_key, index_to_insert); } split_key = makeKey( getKeyFromNodeEntry(getFirstEntryInNode(new_node)).start(), _key_size ); path.pop(); } if (path.empty()) { _root = newRoot(split_key, _root, new_node); } else { insertInNode(path.top(), split_key, new_node.index()); } return std::move(ret); } else { return insertInLeaf(path.top(), key); } }