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());
}
Exemplo n.º 2
0
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);
    }
}