Пример #1
0
ControlFlowGraph::BlockPointerVector
	ControlFlowGraph::reverse_topological_sequence() {
	typedef std::set<iterator, BlockSetCompare> BlockSet;
	typedef std::queue<iterator> Queue;
	
	report("Creating reverse topological order traversal");
	BlockSet visited;
	BlockPointerVector sequence;
	Queue queue;
	
	queue.push(get_exit_block());

	while (sequence.size() != size()) {
		if(queue.empty()) {
			for (pointer_iterator block = sequence.begin();
				block != sequence.end(); ++block) {
				for (pointer_iterator pred = (*block)->predecessors.begin();
					pred != (*block)->predecessors.end(); ++pred) {
					
					if (visited.count(*pred) == 0) {
						queue.push(*pred);
						break;
					}		
				}
				if(!queue.empty()) {
					break;
				}
			}
			
			if(queue.empty()) break; // The remaining blocks are unreachable
		}
		
		iterator current = queue.front();
		queue.pop();
		if(!visited.insert(current).second) continue;
		sequence.push_back(current);
		report(" Adding block " << current->label());

		for (pointer_iterator block = current->predecessors.begin();
			block != current->predecessors.end(); ++block) {
			bool noDependencies = true;
		
			for (pointer_iterator successor = (*block)->successors.begin(); 
				successor != (*block)->successors.end(); ++successor) {
				if (visited.count(*successor) == 0) {
					noDependencies = false;
					break;
				}
			}
			
			if(noDependencies) {
				queue.push(*block);
			}
		}
	}

	return sequence;
}
Пример #2
0
PostdominatorTree::BlockPointerVector
PostdominatorTree::getPostDominanceFrontier(block_iterator block)
{
    BlockPointerVector frontierBlocks;

    auto& frontier = frontiers[blocksToIndex[block]];

    for(auto blockId : frontier)
    {
        frontierBlocks.push_back(blocks[blockId]);
    }

    return frontierBlocks;
}
Пример #3
0
ControlFlowGraph::BlockPointerVector ControlFlowGraph::pre_order_sequence() {
	typedef std::unordered_set<iterator> BlockSet;
	typedef std::stack<iterator> Stack;
	
	BlockSet visited;
	BlockPointerVector sequence;
	Stack stack;
	
	if (!empty()) {
		stack.push(get_entry_block());
		visited.insert(get_entry_block());
	}
	
	while (!stack.empty()) {
		iterator current = stack.top();
		stack.pop();
		
		sequence.push_back(current);
		
		// favor the fallthrough
		iterator fallthrough = end();
		
		if (current->has_fallthrough_edge()) {
			edge_iterator fallthroughEdge 	
				= sequence.back()->get_fallthrough_edge();
			
			if (visited.insert(fallthroughEdge->tail).second) {
				fallthrough = fallthroughEdge->tail;
			}
		}
		
		for (pointer_iterator block = current->successors.begin(); 
			block != current->successors.end(); ++block) {
			if (visited.insert(*block).second) {
				stack.push(*block);
			}
		}
		
		if (fallthrough != end()) {
			stack.push(fallthrough);
		}
	}
	
	return sequence;
}
Пример #4
0
ControlFlowGraph::BlockPointerVector ControlFlowGraph::post_order_sequence() {
	typedef std::unordered_set<iterator> BlockSet;
	typedef std::stack<iterator> Stack;
	
	report("Creating post order traversal");
	BlockSet visited;
	BlockPointerVector sequence;
	Stack stack;
	
	if (!empty()) {
		for (pointer_iterator 
			block = get_entry_block()->successors.begin(); 
			block != get_entry_block()->successors.end(); ++block) {
			if (visited.insert(*block).second) {
				stack.push(*block);
			}
		}
	}
	
	while (!stack.empty()) {
		iterator current = stack.top();

		bool one = false;
		for (pointer_iterator block = current->successors.begin(); 
			block != current->successors.end(); ++block) {
			if (visited.insert(*block).second) {
				stack.push(*block);
				one = true;
			}
		}
		
		if(!one) {
			stack.pop();
			sequence.push_back(current);
			report(" Adding block " << current->label());
		}
	}

	report(" Adding block " << get_entry_block()->label());
	sequence.push_back(get_entry_block());

	return sequence;
}
Пример #5
0
/*!
	\brief performs a topological sort to maximize reconvergence opportunities and ensure forward progress
*/
ir::ControlFlowGraph::BlockPointerVector ir::HammockGraph::topological_sequence() {
	
	typedef ir::ControlFlowGraph::BlockPointerVector BlockPointerVector;
	
	std::set< int > scheduled;
	BlockPointerVector sequence;

	schedule_hammock(sequence, scheduled, domTree.blocksToIndex[ domTree.blocks[0] ],
		domTree.blocksToIndex[ pdomTree.blocks[0] ]);
	
	// tests:
	// are all blocks scheduled exactly once?
	// is the entry node the first block?
	// are hammocks scheduled correctly?
	
	report("schedule:");
	for (BlockPointerVector::iterator bb_it = sequence.begin(); bb_it != sequence.end(); ++bb_it) {
		report("  " << (*bb_it)->label);
	}
	
	return sequence;
}
Пример #6
0
ControlFlowGraph::BlockPointerVector ControlFlowGraph::executable_sequence() {
	typedef std::unordered_set<iterator> BlockSet;
	BlockPointerVector sequence;
	BlockSet unscheduled;

	for(iterator i = begin(); i != end(); ++i)
	{
		unscheduled.insert(i);
	}

	report("Getting executable sequence.");

	sequence.push_back(get_entry_block());
	unscheduled.erase(get_entry_block());
	report(" added " << get_entry_block()->label());

	while (!unscheduled.empty()) {
		if (sequence.back()->has_fallthrough_edge()) {
			edge_iterator fallthroughEdge 	
				= sequence.back()->get_fallthrough_edge();
			if (unscheduled.count(fallthroughEdge->tail) != 0) {
				sequence.push_back(fallthroughEdge->tail);
				unscheduled.erase(fallthroughEdge->tail);
			}
		}
		else {
			// find a new block, favor branch targets over random blocks
			iterator next = *unscheduled.begin();
			
			for(edge_pointer_iterator edge = sequence.back()->out_edges.begin();
				edge != sequence.back()->out_edges.end(); ++edge)
			{
				if(unscheduled.count((*edge)->tail) != 0)
				{
					next = (*edge)->tail;
				}
			}
			
			// rewind through fallthrough edges to find the beginning of the 
			// next chain of fall throughs
			report("  restarting at " << next->label());
			bool rewinding = true;
			while (rewinding) {
				rewinding = false;
				for (edge_pointer_iterator edge = next->in_edges.begin(); 
					edge != next->in_edges.end(); ++edge) {
					if ((*edge)->type == Edge::FallThrough) {
						assertM(unscheduled.count((*edge)->head) != 0, 
							(*edge)->head->label() 
							<< " has multiple fallthrough branches.");
						next = (*edge)->head;
						report("   rewinding to " << next->label() );
						rewinding = true;
						break;
					}
				}
			}
			sequence.push_back(next);
			unscheduled.erase(next);
		}
		
		report(" added " << sequence.back()->label());
	}

	return sequence;
}